@vaadin/date-picker 25.3.0-alpha2 → 25.3.0-dev.3a3c2d7d2a
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/custom-elements.json +192 -1
- package/package.json +13 -13
- package/src/styles/vaadin-date-picker-overlay-content-base-styles.js +12 -0
- package/src/vaadin-date-picker-mixin.d.ts +28 -0
- package/src/vaadin-date-picker-mixin.js +142 -2
- package/src/vaadin-date-picker-overlay-content-mixin.js +130 -3
- package/src/vaadin-date-picker-overlay-content.js +4 -1
- package/src/vaadin-date-picker.d.ts +1 -1
- package/src/vaadin-date-picker.js +3 -0
- package/src/vaadin-disabled-dates-controller.d.ts +66 -0
- package/src/vaadin-disabled-dates-controller.js +241 -0
- package/src/vaadin-month-calendar-mixin.js +44 -2
- package/web-types.json +13 -2
- package/web-types.lit.json +9 -2
package/custom-elements.json
CHANGED
|
@@ -513,6 +513,16 @@
|
|
|
513
513
|
"package": "@vaadin/a11y-base/src/tabindex-mixin.js"
|
|
514
514
|
}
|
|
515
515
|
},
|
|
516
|
+
{
|
|
517
|
+
"kind": "field",
|
|
518
|
+
"name": "disabledDatesProvider",
|
|
519
|
+
"privacy": "public",
|
|
520
|
+
"type": {
|
|
521
|
+
"text": "function(DatePickerDateRange): Array<DatePickerDate> | Promise<Array<DatePickerDate>> | undefined"
|
|
522
|
+
},
|
|
523
|
+
"description": "A batch function that is consulted for a range of dates that the calendar is about\nto render. It receives a `DatePickerDateRange` object (`{ start, end }` of\n`DatePickerDate`) and returns, or resolves with, an array of `DatePickerDate` objects\nthat should be disabled within that range.\n\nUnlike `isDateDisabled`, which is called once per date, this function is called for a\nrange of dates at a time, and again as the calendar renders further dates. The size of\nthe range is decided by the calendar and may span multiple months. It may return a\n`Promise`, in which case the affected dates render in a non-selectable pending state\nuntil it resolves.\n\nDates disabled by this function are combined with `min`, `max` and `isDateDisabled`:\na date is disabled if it is out of the min/max range, or `isDateDisabled` returns\n`true`, or it is included in this function's result.\n\nKeep a stable reference to the function. Assigning a new function resets the internal\ncache and re-fetches every visible range.",
|
|
524
|
+
"attribute": "disabled-dates-provider"
|
|
525
|
+
},
|
|
516
526
|
{
|
|
517
527
|
"kind": "field",
|
|
518
528
|
"name": "i18n",
|
|
@@ -895,6 +905,16 @@
|
|
|
895
905
|
},
|
|
896
906
|
"attribute": "calendars"
|
|
897
907
|
},
|
|
908
|
+
{
|
|
909
|
+
"kind": "field",
|
|
910
|
+
"name": "disabledDatesProvider",
|
|
911
|
+
"privacy": "public",
|
|
912
|
+
"type": {
|
|
913
|
+
"text": "function(DatePickerDateRange): Array<DatePickerDate> | Promise<Array<DatePickerDate>> | undefined"
|
|
914
|
+
},
|
|
915
|
+
"description": "A batch function that is consulted for a range of dates the calendar is about to render\nand returns, or resolves with, an array of `DatePickerDate` objects to disable.",
|
|
916
|
+
"attribute": "disabled-dates-provider"
|
|
917
|
+
},
|
|
898
918
|
{
|
|
899
919
|
"kind": "field",
|
|
900
920
|
"name": "enteredDate",
|
|
@@ -982,6 +1002,16 @@
|
|
|
982
1002
|
"description": "Input label",
|
|
983
1003
|
"attribute": "label"
|
|
984
1004
|
},
|
|
1005
|
+
{
|
|
1006
|
+
"kind": "field",
|
|
1007
|
+
"name": "loading",
|
|
1008
|
+
"privacy": "public",
|
|
1009
|
+
"type": {
|
|
1010
|
+
"text": "boolean"
|
|
1011
|
+
},
|
|
1012
|
+
"description": "Reflected while data is being loaded, so the overlay can show a loading spinner.\nCurrently set while the disabled dates provider is resolving.",
|
|
1013
|
+
"attribute": "loading"
|
|
1014
|
+
},
|
|
985
1015
|
{
|
|
986
1016
|
"kind": "field",
|
|
987
1017
|
"name": "maxDate",
|
|
@@ -1125,6 +1155,14 @@
|
|
|
1125
1155
|
"description": "Input label",
|
|
1126
1156
|
"fieldName": "label"
|
|
1127
1157
|
},
|
|
1158
|
+
{
|
|
1159
|
+
"name": "loading",
|
|
1160
|
+
"type": {
|
|
1161
|
+
"text": "boolean"
|
|
1162
|
+
},
|
|
1163
|
+
"description": "Reflected while data is being loaded, so the overlay can show a loading spinner.\nCurrently set while the disabled dates provider is resolving.",
|
|
1164
|
+
"fieldName": "loading"
|
|
1165
|
+
},
|
|
1128
1166
|
{
|
|
1129
1167
|
"name": "scroll-duration",
|
|
1130
1168
|
"type": {
|
|
@@ -1683,7 +1721,7 @@
|
|
|
1683
1721
|
"declarations": [
|
|
1684
1722
|
{
|
|
1685
1723
|
"kind": "class",
|
|
1686
|
-
"description": "`<vaadin-date-picker>` is an input field that allows to enter a date by typing or by selecting from a calendar overlay.\n\n```html\n<vaadin-date-picker label=\"Birthday\"></vaadin-date-picker>\n```\n\n```js\ndatePicker.value = '2016-03-02';\n```\n\nWhen the selected `value` is changed, a `value-changed` event is triggered.\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n-------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`week-numbers` | Set when week numbers are shown in the calendar\n\n### Internal components\n\nIn addition to `<vaadin-date-picker>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-date-picker-overlay-content>`\n- `<vaadin-date-picker-month-scroller>`\n- `<vaadin-date-picker-year-scroller>`\n- `<vaadin-date-picker-year>`\n- `<vaadin-month-calendar>`\n\nIn order to style the overlay content, use `<vaadin-date-picker-overlay-content>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`years-toggle-button` | Fullscreen mode years scroller toggle\n`toolbar` | Toolbar with slotted buttons\n\nThe following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:\n\nAttribute | Description\n----------------|-------------------------------------------------\n`desktop` | Set when the overlay content is in desktop mode\n`fullscreen` | Set when the overlay content is in fullscreen mode\n`years-visible` | Set when the year scroller is visible in fullscreen mode\n\nIn order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`month-header` | Month title\n`weekdays` | Weekday container\n`weekday` | Weekday element\n`week-numbers` | Week numbers container\n`week-number` | Week number element\n`date` | Date element\n`disabled` | Disabled date element\n`focused` | Focused date element\n`selected` | Selected date element\n`today` | Date element corresponding to the current day\n`past` | Date element corresponding to the date in the past\n`future` | Date element corresponding to the date in the future\n\nIn order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`year-number` | Year number\n`year-separator` | Year separator\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Change events\n\nDepending on the nature of the value change that the user attempts to commit e.g. by pressing Enter,\nthe component can fire either a `change` event or an `unparsable-change` event:\n\nValue change | Event\n:------------------------|:------------------\nempty => parsable | change\nempty => unparsable | unparsable-change\nparsable => empty | change\nparsable => parsable | change\nparsable => unparsable | change\nunparsable => empty | unparsable-change\nunparsable => parsable | change\nunparsable => unparsable | unparsable-change",
|
|
1724
|
+
"description": "`<vaadin-date-picker>` is an input field that allows to enter a date by typing or by selecting from a calendar overlay.\n\n```html\n<vaadin-date-picker label=\"Birthday\"></vaadin-date-picker>\n```\n\n```js\ndatePicker.value = '2016-03-02';\n```\n\nWhen the selected `value` is changed, a `value-changed` event is triggered.\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n-------------------------------|----------------------------|---------\n`--vaadin-field-default-width` | Default width of the field | `12em`\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n---------------------|----------------\n`label` | The label element\n`input-field` | The element that wraps prefix, value and buttons\n`field-button` | Set on both clear and toggle buttons\n`clear-button` | The clear button\n`error-message` | The error message element\n`helper-text` | The helper text element wrapper\n`required-indicator` | The `required` state indicator element\n`toggle-button` | The toggle button\n`backdrop` | Backdrop of the overlay\n`overlay` | The overlay container\n`content` | The overlay content\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n---------------------|---------------------------------\n`disabled` | Set when the element is disabled\n`has-value` | Set when the element has a value\n`has-label` | Set when the element has a label\n`has-helper` | Set when the element has helper text or slot\n`has-error-message` | Set when the element has an error message\n`has-tooltip` | Set when the element has a slotted tooltip\n`invalid` | Set when the element is invalid\n`focused` | Set when the element is focused\n`focus-ring` | Set when the element is keyboard focused\n`readonly` | Set when the element is readonly\n`opened` | Set when the overlay is opened\n`week-numbers` | Set when week numbers are shown in the calendar\n\n### Internal components\n\nIn addition to `<vaadin-date-picker>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-date-picker-overlay-content>`\n- `<vaadin-date-picker-month-scroller>`\n- `<vaadin-date-picker-year-scroller>`\n- `<vaadin-date-picker-year>`\n- `<vaadin-month-calendar>`\n\nIn order to style the overlay content, use `<vaadin-date-picker-overlay-content>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`years-toggle-button` | Fullscreen mode years scroller toggle\n`toolbar` | Toolbar with slotted buttons\n`loader` | Loading spinner shown while data is being loaded, for example while the disabled dates provider resolves\n\nThe following state attributes are available on the `<vaadin-date-picker-overlay-content>` element:\n\nAttribute | Description\n----------------|-------------------------------------------------\n`desktop` | Set when the overlay content is in desktop mode\n`fullscreen` | Set when the overlay content is in fullscreen mode\n`years-visible` | Set when the year scroller is visible in fullscreen mode\n`loading` | Set while data is being loaded, for example while the disabled dates provider resolves\n\nIn order to style the month calendar, use `<vaadin-month-calendar>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`month-header` | Month title\n`weekdays` | Weekday container\n`weekday` | Weekday element\n`week-numbers` | Week numbers container\n`week-number` | Week number element\n`date` | Date element\n`disabled` | Disabled date element\n`pending` | Date element in a month whose disabled dates provider result is still loading\n`focused` | Focused date element\n`selected` | Selected date element\n`today` | Date element corresponding to the current day\n`past` | Date element corresponding to the date in the past\n`future` | Date element corresponding to the date in the future\n\nIn order to style year scroller elements, use `<vaadin-date-picker-year>` shadow DOM parts:\n\nPart name | Description\n----------------------|--------------------\n`year-number` | Year number\n`year-separator` | Year separator\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.\n\n### Change events\n\nDepending on the nature of the value change that the user attempts to commit e.g. by pressing Enter,\nthe component can fire either a `change` event or an `unparsable-change` event:\n\nValue change | Event\n:------------------------|:------------------\nempty => parsable | change\nempty => unparsable | unparsable-change\nparsable => empty | change\nparsable => parsable | change\nparsable => unparsable | change\nunparsable => empty | unparsable-change\nunparsable => parsable | change\nunparsable => unparsable | unparsable-change",
|
|
1687
1725
|
"name": "DatePicker",
|
|
1688
1726
|
"members": [
|
|
1689
1727
|
{
|
|
@@ -1830,6 +1868,20 @@
|
|
|
1830
1868
|
"package": "@vaadin/a11y-base/src/tabindex-mixin.js"
|
|
1831
1869
|
}
|
|
1832
1870
|
},
|
|
1871
|
+
{
|
|
1872
|
+
"kind": "field",
|
|
1873
|
+
"name": "disabledDatesProvider",
|
|
1874
|
+
"privacy": "public",
|
|
1875
|
+
"type": {
|
|
1876
|
+
"text": "function(DatePickerDateRange): Array<DatePickerDate> | Promise<Array<DatePickerDate>> | undefined"
|
|
1877
|
+
},
|
|
1878
|
+
"description": "A batch function that is consulted for a range of dates that the calendar is about\nto render. It receives a `DatePickerDateRange` object (`{ start, end }` of\n`DatePickerDate`) and returns, or resolves with, an array of `DatePickerDate` objects\nthat should be disabled within that range.\n\nUnlike `isDateDisabled`, which is called once per date, this function is called for a\nrange of dates at a time, and again as the calendar renders further dates. The size of\nthe range is decided by the calendar and may span multiple months. It may return a\n`Promise`, in which case the affected dates render in a non-selectable pending state\nuntil it resolves.\n\nDates disabled by this function are combined with `min`, `max` and `isDateDisabled`:\na date is disabled if it is out of the min/max range, or `isDateDisabled` returns\n`true`, or it is included in this function's result.\n\nKeep a stable reference to the function. Assigning a new function resets the internal\ncache and re-fetches every visible range.",
|
|
1879
|
+
"attribute": "disabled-dates-provider",
|
|
1880
|
+
"inheritedFrom": {
|
|
1881
|
+
"name": "DatePickerMixin",
|
|
1882
|
+
"module": "src/vaadin-date-picker-mixin.js"
|
|
1883
|
+
}
|
|
1884
|
+
},
|
|
1833
1885
|
{
|
|
1834
1886
|
"kind": "field",
|
|
1835
1887
|
"name": "errorMessage",
|
|
@@ -2517,6 +2569,145 @@
|
|
|
2517
2569
|
}
|
|
2518
2570
|
]
|
|
2519
2571
|
},
|
|
2572
|
+
{
|
|
2573
|
+
"kind": "javascript-module",
|
|
2574
|
+
"path": "src/vaadin-disabled-dates-controller.js",
|
|
2575
|
+
"declarations": [
|
|
2576
|
+
{
|
|
2577
|
+
"kind": "class",
|
|
2578
|
+
"description": "A reactive controller that resolves the dates disabled by the date-picker's\n`disabledDatesProvider`. It calls the provider once for a range of months\n(never one date at a time), caches the resolved months so scrolling back and\nforth does not re-fetch them, and prefetches a buffer of months around the\nrequested range. While any request is in flight, #loading is `true`\nso the overlay can show a spinner.\n\nThe provider may return an array synchronously or a `Promise`, so results\nfrom a server (Flow) or a remote availability service can be awaited.",
|
|
2579
|
+
"name": "DisabledDatesController",
|
|
2580
|
+
"members": [
|
|
2581
|
+
{
|
|
2582
|
+
"kind": "method",
|
|
2583
|
+
"name": "ensureRangeLoaded",
|
|
2584
|
+
"parameters": [
|
|
2585
|
+
{
|
|
2586
|
+
"name": "startDate",
|
|
2587
|
+
"type": {
|
|
2588
|
+
"text": "Date"
|
|
2589
|
+
}
|
|
2590
|
+
},
|
|
2591
|
+
{
|
|
2592
|
+
"name": "endDate",
|
|
2593
|
+
"type": {
|
|
2594
|
+
"text": "Date"
|
|
2595
|
+
}
|
|
2596
|
+
}
|
|
2597
|
+
],
|
|
2598
|
+
"description": "Ensures the provider has been consulted for the inclusive range between the\ngiven dates, expanded by a prefetch buffer of months on each side. Months\nthat are already loaded or in flight are skipped, and consecutive missing\nmonths are grouped into a single provider call."
|
|
2599
|
+
},
|
|
2600
|
+
{
|
|
2601
|
+
"kind": "field",
|
|
2602
|
+
"name": "host",
|
|
2603
|
+
"default": "host"
|
|
2604
|
+
},
|
|
2605
|
+
{
|
|
2606
|
+
"kind": "method",
|
|
2607
|
+
"name": "hostDisconnected"
|
|
2608
|
+
},
|
|
2609
|
+
{
|
|
2610
|
+
"kind": "method",
|
|
2611
|
+
"name": "isDateBlocked",
|
|
2612
|
+
"parameters": [
|
|
2613
|
+
{
|
|
2614
|
+
"name": "date",
|
|
2615
|
+
"type": {
|
|
2616
|
+
"text": "Date"
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
],
|
|
2620
|
+
"description": "Whether the given date cannot be selected yet: it is disabled by the\nprovider, or its month has not been resolved so its state is still unknown.\nReturns `false` when no provider is set. Used to block selection and to\nrender dates as non-selectable while their month is loading.",
|
|
2621
|
+
"return": {
|
|
2622
|
+
"type": {
|
|
2623
|
+
"text": "boolean"
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
},
|
|
2627
|
+
{
|
|
2628
|
+
"kind": "method",
|
|
2629
|
+
"name": "isDateDisabled",
|
|
2630
|
+
"parameters": [
|
|
2631
|
+
{
|
|
2632
|
+
"name": "date",
|
|
2633
|
+
"type": {
|
|
2634
|
+
"text": "Date"
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
],
|
|
2638
|
+
"description": "Whether the given date is disabled by the provider. Only returns `true` for\ndates in an already-resolved month.",
|
|
2639
|
+
"return": {
|
|
2640
|
+
"type": {
|
|
2641
|
+
"text": "boolean"
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
},
|
|
2645
|
+
{
|
|
2646
|
+
"kind": "method",
|
|
2647
|
+
"name": "isMonthLoaded",
|
|
2648
|
+
"parameters": [
|
|
2649
|
+
{
|
|
2650
|
+
"name": "date",
|
|
2651
|
+
"type": {
|
|
2652
|
+
"text": "Date"
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
],
|
|
2656
|
+
"description": "Whether the month containing the given date has been fully resolved.",
|
|
2657
|
+
"return": {
|
|
2658
|
+
"type": {
|
|
2659
|
+
"text": "boolean"
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
},
|
|
2663
|
+
{
|
|
2664
|
+
"kind": "field",
|
|
2665
|
+
"name": "loading",
|
|
2666
|
+
"description": "Whether any month range is currently being fetched.",
|
|
2667
|
+
"return": {
|
|
2668
|
+
"type": {
|
|
2669
|
+
"text": "boolean"
|
|
2670
|
+
}
|
|
2671
|
+
},
|
|
2672
|
+
"readonly": true
|
|
2673
|
+
},
|
|
2674
|
+
{
|
|
2675
|
+
"kind": "field",
|
|
2676
|
+
"name": "provider",
|
|
2677
|
+
"type": {
|
|
2678
|
+
"text": "null"
|
|
2679
|
+
},
|
|
2680
|
+
"default": "null"
|
|
2681
|
+
},
|
|
2682
|
+
{
|
|
2683
|
+
"kind": "method",
|
|
2684
|
+
"name": "reset",
|
|
2685
|
+
"description": "Clears the cache and invalidates any in-flight requests."
|
|
2686
|
+
},
|
|
2687
|
+
{
|
|
2688
|
+
"kind": "method",
|
|
2689
|
+
"name": "setProvider",
|
|
2690
|
+
"parameters": [
|
|
2691
|
+
{
|
|
2692
|
+
"name": "provider"
|
|
2693
|
+
}
|
|
2694
|
+
],
|
|
2695
|
+
"description": "Sets the provider function and clears the cache. Passing the same provider\nagain is a no-op, so the cache survives unrelated re-renders — callers\nshould therefore keep a stable provider reference rather than passing a new\nfunction on every update, which would otherwise reset the cache and\nre-fetch every visible range."
|
|
2696
|
+
}
|
|
2697
|
+
]
|
|
2698
|
+
}
|
|
2699
|
+
],
|
|
2700
|
+
"exports": [
|
|
2701
|
+
{
|
|
2702
|
+
"kind": "js",
|
|
2703
|
+
"name": "DisabledDatesController",
|
|
2704
|
+
"declaration": {
|
|
2705
|
+
"name": "DisabledDatesController",
|
|
2706
|
+
"module": "src/vaadin-disabled-dates-controller.js"
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
]
|
|
2710
|
+
},
|
|
2520
2711
|
{
|
|
2521
2712
|
"kind": "javascript-module",
|
|
2522
2713
|
"path": "src/vaadin-month-calendar-mixin.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/date-picker",
|
|
3
|
-
"version": "25.3.0-
|
|
3
|
+
"version": "25.3.0-dev.3a3c2d7d2a",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -35,21 +35,21 @@
|
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
38
|
-
"@vaadin/a11y-base": "25.3.0-
|
|
39
|
-
"@vaadin/button": "25.3.0-
|
|
40
|
-
"@vaadin/component-base": "25.3.0-
|
|
41
|
-
"@vaadin/field-base": "25.3.0-
|
|
42
|
-
"@vaadin/input-container": "25.3.0-
|
|
43
|
-
"@vaadin/overlay": "25.3.0-
|
|
44
|
-
"@vaadin/vaadin-themable-mixin": "25.3.0-
|
|
38
|
+
"@vaadin/a11y-base": "25.3.0-dev.3a3c2d7d2a",
|
|
39
|
+
"@vaadin/button": "25.3.0-dev.3a3c2d7d2a",
|
|
40
|
+
"@vaadin/component-base": "25.3.0-dev.3a3c2d7d2a",
|
|
41
|
+
"@vaadin/field-base": "25.3.0-dev.3a3c2d7d2a",
|
|
42
|
+
"@vaadin/input-container": "25.3.0-dev.3a3c2d7d2a",
|
|
43
|
+
"@vaadin/overlay": "25.3.0-dev.3a3c2d7d2a",
|
|
44
|
+
"@vaadin/vaadin-themable-mixin": "25.3.0-dev.3a3c2d7d2a",
|
|
45
45
|
"lit": "^3.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@vaadin/aura": "25.3.0-
|
|
49
|
-
"@vaadin/chai-plugins": "25.3.0-
|
|
50
|
-
"@vaadin/test-runner-commands": "25.3.0-
|
|
48
|
+
"@vaadin/aura": "25.3.0-dev.3a3c2d7d2a",
|
|
49
|
+
"@vaadin/chai-plugins": "25.3.0-dev.3a3c2d7d2a",
|
|
50
|
+
"@vaadin/test-runner-commands": "25.3.0-dev.3a3c2d7d2a",
|
|
51
51
|
"@vaadin/testing-helpers": "^2.0.0",
|
|
52
|
-
"@vaadin/vaadin-lumo-styles": "25.3.0-
|
|
52
|
+
"@vaadin/vaadin-lumo-styles": "25.3.0-dev.3a3c2d7d2a",
|
|
53
53
|
"sinon": "^22.0.0"
|
|
54
54
|
},
|
|
55
55
|
"customElements": "custom-elements.json",
|
|
@@ -57,5 +57,5 @@
|
|
|
57
57
|
"web-types.json",
|
|
58
58
|
"web-types.lit.json"
|
|
59
59
|
],
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "ac506ca7800c23e05da55863c56bcedf12812d37"
|
|
61
61
|
}
|
|
@@ -17,6 +17,7 @@ export const overlayContentStyles = css`
|
|
|
17
17
|
height: 100%;
|
|
18
18
|
outline: none;
|
|
19
19
|
overflow: hidden;
|
|
20
|
+
position: relative;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
:host([desktop]) {
|
|
@@ -49,6 +50,17 @@ export const overlayContentStyles = css`
|
|
|
49
50
|
display: none !important;
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
/* Loading spinner shown while data is being loaded (currently while the disabled dates provider
|
|
54
|
+
resolves). Positioned over the month scroller, which paints its own transformed layers, so
|
|
55
|
+
grid stacking is not enough. */
|
|
56
|
+
[part='loader'] {
|
|
57
|
+
position: absolute;
|
|
58
|
+
z-index: 1;
|
|
59
|
+
inset-block-start: var(--vaadin-date-picker-month-header-font-size, 0.9375rem);
|
|
60
|
+
inset-inline: 0;
|
|
61
|
+
margin-inline: auto;
|
|
62
|
+
}
|
|
63
|
+
|
|
52
64
|
::slotted([slot='months']) {
|
|
53
65
|
--vaadin-infinite-scroller-item-height: round(
|
|
54
66
|
var(--vaadin-date-picker-month-header-font-size, 0.9375rem) + 0.75rem +
|
|
@@ -18,6 +18,17 @@ export interface DatePickerDate {
|
|
|
18
18
|
year: number;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
export interface DatePickerDateRange {
|
|
22
|
+
/**
|
|
23
|
+
* The first date of the range (inclusive).
|
|
24
|
+
*/
|
|
25
|
+
start: DatePickerDate;
|
|
26
|
+
/**
|
|
27
|
+
* The last date of the range (inclusive).
|
|
28
|
+
*/
|
|
29
|
+
end: DatePickerDate;
|
|
30
|
+
}
|
|
31
|
+
|
|
21
32
|
export interface DatePickerI18n {
|
|
22
33
|
/**
|
|
23
34
|
* An array with the full names of months starting
|
|
@@ -236,6 +247,23 @@ export declare class DatePickerMixinClass {
|
|
|
236
247
|
*/
|
|
237
248
|
isDateDisabled: (date: DatePickerDate) => boolean;
|
|
238
249
|
|
|
250
|
+
/**
|
|
251
|
+
* A batch function that is consulted for a range of dates that the calendar is about to
|
|
252
|
+
* render. It receives a `DatePickerDateRange` object and returns, or resolves with, an array
|
|
253
|
+
* of `DatePickerDate` objects that should be disabled within that range.
|
|
254
|
+
*
|
|
255
|
+
* Unlike `isDateDisabled`, which is called once per date, this function is called for a range
|
|
256
|
+
* of dates at a time, and again as the calendar renders further dates. The size of the range
|
|
257
|
+
* is decided by the calendar and may span multiple months. It may return a `Promise`, in which
|
|
258
|
+
* case the affected dates render in a non-selectable pending state until it resolves.
|
|
259
|
+
*
|
|
260
|
+
* Dates disabled by this function are combined with `min`, `max` and `isDateDisabled`.
|
|
261
|
+
*
|
|
262
|
+
* Keep a stable reference to the function. Assigning a new function resets the internal cache
|
|
263
|
+
* and re-fetches every visible range.
|
|
264
|
+
*/
|
|
265
|
+
disabledDatesProvider: (range: DatePickerDateRange) => DatePickerDate[] | Promise<DatePickerDate[]>;
|
|
266
|
+
|
|
239
267
|
/**
|
|
240
268
|
* Opens the dropdown.
|
|
241
269
|
*/
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
getClosestDate,
|
|
22
22
|
parseDate,
|
|
23
23
|
} from './vaadin-date-picker-helper.js';
|
|
24
|
+
import { DisabledDatesController } from './vaadin-disabled-dates-controller.js';
|
|
24
25
|
|
|
25
26
|
export const datePickerI18nDefaults = Object.freeze({
|
|
26
27
|
monthNames: [
|
|
@@ -208,6 +209,31 @@ export const DatePickerMixin = (subclass) =>
|
|
|
208
209
|
type: Function,
|
|
209
210
|
},
|
|
210
211
|
|
|
212
|
+
/**
|
|
213
|
+
* A batch function that is consulted for a range of dates that the calendar is about
|
|
214
|
+
* to render. It receives a `DatePickerDateRange` object (`{ start, end }` of
|
|
215
|
+
* `DatePickerDate`) and returns, or resolves with, an array of `DatePickerDate` objects
|
|
216
|
+
* that should be disabled within that range.
|
|
217
|
+
*
|
|
218
|
+
* Unlike `isDateDisabled`, which is called once per date, this function is called for a
|
|
219
|
+
* range of dates at a time, and again as the calendar renders further dates. The size of
|
|
220
|
+
* the range is decided by the calendar and may span multiple months. It may return a
|
|
221
|
+
* `Promise`, in which case the affected dates render in a non-selectable pending state
|
|
222
|
+
* until it resolves.
|
|
223
|
+
*
|
|
224
|
+
* Dates disabled by this function are combined with `min`, `max` and `isDateDisabled`:
|
|
225
|
+
* a date is disabled if it is out of the min/max range, or `isDateDisabled` returns
|
|
226
|
+
* `true`, or it is included in this function's result.
|
|
227
|
+
*
|
|
228
|
+
* Keep a stable reference to the function. Assigning a new function resets the internal
|
|
229
|
+
* cache and re-fetches every visible range.
|
|
230
|
+
*
|
|
231
|
+
* @type {function(DatePickerDateRange): Array<DatePickerDate> | Promise<Array<DatePickerDate>> | undefined}
|
|
232
|
+
*/
|
|
233
|
+
disabledDatesProvider: {
|
|
234
|
+
type: Function,
|
|
235
|
+
},
|
|
236
|
+
|
|
211
237
|
/**
|
|
212
238
|
* The earliest date that can be selected. All earlier dates will be disabled.
|
|
213
239
|
* @type {Date | undefined}
|
|
@@ -261,7 +287,8 @@ export const DatePickerMixin = (subclass) =>
|
|
|
261
287
|
return [
|
|
262
288
|
'_selectedDateChanged(_selectedDate, __effectiveI18n)',
|
|
263
289
|
'_focusedDateChanged(_focusedDate, __effectiveI18n)',
|
|
264
|
-
'__updateOverlayContent(_overlayContent, __effectiveI18n, label, _minDate, _maxDate, _focusedDate, _selectedDate, showWeekNumbers, isDateDisabled, __enteredDate)',
|
|
290
|
+
'__updateOverlayContent(_overlayContent, __effectiveI18n, label, _minDate, _maxDate, _focusedDate, _selectedDate, showWeekNumbers, isDateDisabled, disabledDatesProvider, __enteredDate)',
|
|
291
|
+
'__disabledDatesProviderChanged(disabledDatesProvider)',
|
|
265
292
|
'__updateOverlayContentTheme(_overlayContent, _theme)',
|
|
266
293
|
'__updateOverlayContentFullScreen(_overlayContent, _fullscreen)',
|
|
267
294
|
];
|
|
@@ -437,6 +464,13 @@ export const DatePickerMixin = (subclass) =>
|
|
|
437
464
|
|
|
438
465
|
this.addController(new VirtualKeyboardController(this));
|
|
439
466
|
|
|
467
|
+
// Owns the cache of dates resolved by `disabledDatesProvider`. It lives on the date-picker
|
|
468
|
+
// rather than the overlay content so validation works even when the overlay is never opened.
|
|
469
|
+
// The open overlay reads the same controller to render months and show the loading spinner.
|
|
470
|
+
this._disabledDatesController = new DisabledDatesController(this, () => this.__onDisabledDatesChanged());
|
|
471
|
+
this.addController(this._disabledDatesController);
|
|
472
|
+
this._disabledDatesController.setProvider(this.disabledDatesProvider);
|
|
473
|
+
|
|
440
474
|
this._overlayElement = this.$.overlay;
|
|
441
475
|
}
|
|
442
476
|
|
|
@@ -578,7 +612,9 @@ export const DatePickerMixin = (subclass) =>
|
|
|
578
612
|
const inputValue = this._inputElementValue;
|
|
579
613
|
const inputValid = !inputValue || (!!this._selectedDate && inputValue === this.__formatDate(this._selectedDate));
|
|
580
614
|
const isDateValid =
|
|
581
|
-
!this._selectedDate ||
|
|
615
|
+
!this._selectedDate ||
|
|
616
|
+
(dateAllowed(this._selectedDate, this._minDate, this._maxDate, this.isDateDisabled) &&
|
|
617
|
+
!this.__isDateDisabledByProvider(this._selectedDate));
|
|
582
618
|
|
|
583
619
|
let inputValidity = true;
|
|
584
620
|
if (this.inputElement && this.inputElement.checkValidity) {
|
|
@@ -588,6 +624,93 @@ export const DatePickerMixin = (subclass) =>
|
|
|
588
624
|
return inputValid && isDateValid && inputValidity;
|
|
589
625
|
}
|
|
590
626
|
|
|
627
|
+
/**
|
|
628
|
+
* Returns true if the given date is known to be disabled by `disabledDatesProvider`. The
|
|
629
|
+
* result comes from the controller's cache of already-loaded ranges. The month containing a
|
|
630
|
+
* selected date is loaded on demand (see `_selectedDateChanged`), so a value typed while the
|
|
631
|
+
* overlay is closed is re-validated once the provider answers (see `__onDisabledDatesChanged`).
|
|
632
|
+
* Until then the date is treated as allowed, matching the overlay's rendering.
|
|
633
|
+
* @private
|
|
634
|
+
*/
|
|
635
|
+
__isDateDisabledByProvider(date) {
|
|
636
|
+
const controller = this._disabledDatesController;
|
|
637
|
+
return !!controller && !!controller.provider && controller.isDateDisabled(date);
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/** @private */
|
|
641
|
+
__disabledDatesProviderChanged(disabledDatesProvider) {
|
|
642
|
+
// The controller is created in `ready()`; `setProvider` is called there for the initial value.
|
|
643
|
+
if (this._disabledDatesController) {
|
|
644
|
+
this._disabledDatesController.setProvider(disabledDatesProvider);
|
|
645
|
+
this.__ensureSelectedDateLoaded();
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Asks the controller to resolve the month containing the selected date, so that a value set
|
|
651
|
+
* or typed while the overlay is closed can be validated against the provider without opening
|
|
652
|
+
* the overlay. When the month resolves, `__onDisabledDatesChanged` re-runs validation.
|
|
653
|
+
* @private
|
|
654
|
+
*/
|
|
655
|
+
__ensureSelectedDateLoaded() {
|
|
656
|
+
const controller = this._disabledDatesController;
|
|
657
|
+
if (controller?.provider && this._selectedDate && !controller.isMonthLoaded(this._selectedDate)) {
|
|
658
|
+
this.__awaitingProviderValidation = true;
|
|
659
|
+
controller.ensureRangeLoaded(this._selectedDate, this._selectedDate);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/** @private */
|
|
664
|
+
__onDisabledDatesChanged() {
|
|
665
|
+
const controller = this._disabledDatesController;
|
|
666
|
+
// Push the new loading and cache state to the open overlay so it re-renders the months and
|
|
667
|
+
// updates the spinner. When the overlay is closed there is nothing to update.
|
|
668
|
+
if (this._overlayContent) {
|
|
669
|
+
this._overlayContent.loading = controller.loading;
|
|
670
|
+
this._overlayContent._disabledDatesVersion += 1;
|
|
671
|
+
}
|
|
672
|
+
// Re-validate once the month containing the selected value has resolved, so a value typed
|
|
673
|
+
// while the picker was closed (autoOpenDisabled) is rejected as soon as the provider answers.
|
|
674
|
+
if (this.__awaitingProviderValidation && this._selectedDate && controller.isMonthLoaded(this._selectedDate)) {
|
|
675
|
+
this.__awaitingProviderValidation = false;
|
|
676
|
+
this._requestValidation();
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
this.__adjustInitialFocusForProvider();
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* Moves the overlay's initial focus off a date the provider turns out to disable, once the
|
|
684
|
+
* provider has answered for that month. Only touches the auto-picked initial date and only
|
|
685
|
+
* while the user has not navigated away, so disabled dates the user focuses on purpose (which
|
|
686
|
+
* stay keyboard-focusable) are left alone.
|
|
687
|
+
* @private
|
|
688
|
+
*/
|
|
689
|
+
__adjustInitialFocusForProvider() {
|
|
690
|
+
const content = this._overlayContent;
|
|
691
|
+
const controller = this._disabledDatesController;
|
|
692
|
+
const initial = this.__initialFocusDate;
|
|
693
|
+
if (!content || !initial || !controller.provider) {
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
// The user has moved focus; stop trying to adjust the initial date.
|
|
697
|
+
if (!dateEquals(content.focusedDate, initial)) {
|
|
698
|
+
this.__initialFocusDate = null;
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
// Wait until the provider has answered for the initial month.
|
|
702
|
+
if (!controller.isMonthLoaded(initial)) {
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
this.__initialFocusDate = null;
|
|
706
|
+
if (controller.isDateDisabled(initial)) {
|
|
707
|
+
const closest = content.__closestSelectableDate(initial);
|
|
708
|
+
if (closest) {
|
|
709
|
+
content.focusDate(closest);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
591
714
|
/**
|
|
592
715
|
* Override method inherited from `FocusMixin`
|
|
593
716
|
* to not call `_setFocused(true)` when focus
|
|
@@ -771,6 +894,10 @@ export const DatePickerMixin = (subclass) =>
|
|
|
771
894
|
this._applyInputValue(selectedDate);
|
|
772
895
|
}
|
|
773
896
|
|
|
897
|
+
// Preload the provider's answer for the selected month so the value can be validated even
|
|
898
|
+
// when the overlay is never opened.
|
|
899
|
+
this.__ensureSelectedDateLoaded();
|
|
900
|
+
|
|
774
901
|
this.value = this._formatISO(selectedDate);
|
|
775
902
|
this._ignoreFocusedDateChange = true;
|
|
776
903
|
this._focusedDate = selectedDate;
|
|
@@ -842,9 +969,13 @@ export const DatePickerMixin = (subclass) =>
|
|
|
842
969
|
selectedDate,
|
|
843
970
|
showWeekNumbers,
|
|
844
971
|
isDateDisabled,
|
|
972
|
+
disabledDatesProvider,
|
|
845
973
|
enteredDate,
|
|
846
974
|
) {
|
|
847
975
|
if (overlayContent) {
|
|
976
|
+
// Share the date-picker's controller so the overlay renders from the same cache that
|
|
977
|
+
// validation uses. Assigned before the other properties, which trigger `__updateCalendars`.
|
|
978
|
+
overlayContent._disabledDatesController = this._disabledDatesController;
|
|
848
979
|
overlayContent.i18n = effectiveI18n;
|
|
849
980
|
overlayContent.label = label;
|
|
850
981
|
overlayContent.minDate = minDate;
|
|
@@ -853,6 +984,7 @@ export const DatePickerMixin = (subclass) =>
|
|
|
853
984
|
overlayContent.selectedDate = selectedDate;
|
|
854
985
|
overlayContent.showWeekNumbers = showWeekNumbers;
|
|
855
986
|
overlayContent.isDateDisabled = isDateDisabled;
|
|
987
|
+
overlayContent.disabledDatesProvider = disabledDatesProvider;
|
|
856
988
|
overlayContent.enteredDate = enteredDate;
|
|
857
989
|
}
|
|
858
990
|
}
|
|
@@ -901,6 +1033,12 @@ export const DatePickerMixin = (subclass) =>
|
|
|
901
1033
|
content.focusedDate = scrollFocusDate;
|
|
902
1034
|
this._ignoreFocusedDateChange = false;
|
|
903
1035
|
|
|
1036
|
+
// When opening without a selected value, remember the auto-picked initial date so it can be
|
|
1037
|
+
// moved off a provider-disabled date once the provider answers (see __onDisabledDatesChanged).
|
|
1038
|
+
// A date the user selected themselves is left in place even if the provider disables it.
|
|
1039
|
+
this.__initialFocusDate = this._selectedDate ? null : scrollFocusDate;
|
|
1040
|
+
this.__adjustInitialFocusForProvider();
|
|
1041
|
+
|
|
904
1042
|
window.addEventListener('scroll', this._boundOnScroll, true);
|
|
905
1043
|
|
|
906
1044
|
if (this._focusOverlayOnOpen) {
|
|
@@ -964,6 +1102,8 @@ export const DatePickerMixin = (subclass) =>
|
|
|
964
1102
|
|
|
965
1103
|
/** @protected */
|
|
966
1104
|
_onOverlayClosed() {
|
|
1105
|
+
this.__initialFocusDate = null;
|
|
1106
|
+
|
|
967
1107
|
// Reset `aria-hidden` state.
|
|
968
1108
|
if (this.__showOthers) {
|
|
969
1109
|
this.__showOthers();
|