@breadstone/mosaik-elements-foundation 0.1.35 → 0.1.36
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/Controls/Components/Inputs/Calendar/CalendarElement.d.ts +1 -1
- package/Controls/Components/Inputs/Calendar/CalendarElement.d.ts.map +1 -1
- package/Controls/Components/Inputs/Calendar/CalendarElement.js +1 -1
- package/Controls/Components/Inputs/Calendar/CalendarElement.js.map +1 -1
- package/Controls/Components/Inputs/Calendar/Views/Abstracts/CalendarViewBase.d.ts +1 -1
- package/Controls/Components/Inputs/Calendar/Views/Abstracts/CalendarViewBase.d.ts.map +1 -1
- package/Controls/Components/Inputs/Calendar/Views/Abstracts/CalendarViewBase.js +1 -1
- package/Controls/Components/Inputs/Calendar/Views/Abstracts/CalendarViewBase.js.map +1 -1
- package/Controls/Components/Inputs/Calendar/intl2/CalendarElementIntl.d.ts +101 -0
- package/Controls/Components/Inputs/Calendar/intl2/CalendarElementIntl.d.ts.map +1 -0
- package/Controls/Components/Inputs/Calendar/intl2/CalendarElementIntl.js +168 -0
- package/Controls/Components/Inputs/Calendar/intl2/CalendarElementIntl.js.map +1 -0
- package/Controls/Components/Inputs/FileUpload/FileUploadElement.d.ts +1 -1
- package/Controls/Components/Inputs/FileUpload/FileUploadElement.d.ts.map +1 -1
- package/Controls/Components/Inputs/FileUpload/FileUploadElement.js +1 -1
- package/Controls/Components/Inputs/FileUpload/FileUploadElement.js.map +1 -1
- package/Controls/Components/Inputs/FileUpload/intl2/FileUploadElementIntl.d.ts +24 -0
- package/Controls/Components/Inputs/FileUpload/intl2/FileUploadElementIntl.d.ts.map +1 -0
- package/Controls/Components/Inputs/FileUpload/intl2/FileUploadElementIntl.js +38 -0
- package/Controls/Components/Inputs/FileUpload/intl2/FileUploadElementIntl.js.map +1 -0
- package/Controls/Components/Inputs/RichTextBox/RichTextBoxElement.d.ts +1 -1
- package/Controls/Components/Inputs/RichTextBox/RichTextBoxElement.d.ts.map +1 -1
- package/Controls/Components/Inputs/RichTextBox/RichTextBoxElement.js +1 -1
- package/Controls/Components/Inputs/RichTextBox/RichTextBoxElement.js.map +1 -1
- package/Controls/Components/Inputs/RichTextBox/RichTextBoxToolboxElement.d.ts +1 -1
- package/Controls/Components/Inputs/RichTextBox/RichTextBoxToolboxElement.d.ts.map +1 -1
- package/Controls/Components/Inputs/RichTextBox/RichTextBoxToolboxElement.js +1 -1
- package/Controls/Components/Inputs/RichTextBox/RichTextBoxToolboxElement.js.map +1 -1
- package/Controls/Components/Inputs/RichTextBox/intl2/RichTextBoxElementIntl.d.ts +47 -0
- package/Controls/Components/Inputs/RichTextBox/intl2/RichTextBoxElementIntl.d.ts.map +1 -0
- package/Controls/Components/Inputs/RichTextBox/intl2/RichTextBoxElementIntl.js +76 -0
- package/Controls/Components/Inputs/RichTextBox/intl2/RichTextBoxElementIntl.js.map +1 -0
- package/Controls/Components/Media/Chat/ChatElement.d.ts +1 -1
- package/Controls/Components/Media/Chat/ChatElement.d.ts.map +1 -1
- package/Controls/Components/Media/Chat/ChatElement.js +1 -1
- package/Controls/Components/Media/Chat/ChatElement.js.map +1 -1
- package/Controls/Components/Media/Chat/ChatInheritanceContext.d.ts +1 -1
- package/Controls/Components/Media/Chat/ChatInheritanceContext.d.ts.map +1 -1
- package/Controls/Components/Media/Chat/intl2/ChatElementIntl.d.ts +23 -0
- package/Controls/Components/Media/Chat/intl2/ChatElementIntl.d.ts.map +1 -0
- package/Controls/Components/Media/Chat/intl2/ChatElementIntl.js +37 -0
- package/Controls/Components/Media/Chat/intl2/ChatElementIntl.js.map +1 -0
- package/Controls/Components/Misc/CookieConsent/CookiesConsentElement.d.ts +1 -1
- package/Controls/Components/Misc/CookieConsent/CookiesConsentElement.d.ts.map +1 -1
- package/Controls/Components/Misc/CookieConsent/CookiesConsentElement.js +1 -1
- package/Controls/Components/Misc/CookieConsent/CookiesConsentElement.js.map +1 -1
- package/Controls/Components/Misc/CookieConsent/intl2/CookiesConsentElementIntl.d.ts +42 -0
- package/Controls/Components/Misc/CookieConsent/intl2/CookiesConsentElementIntl.d.ts.map +1 -0
- package/Controls/Components/Misc/CookieConsent/intl2/CookiesConsentElementIntl.js +66 -0
- package/Controls/Components/Misc/CookieConsent/intl2/CookiesConsentElementIntl.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownAnchorElement.d.ts +66 -0
- package/Controls/Components/Primitives/Dropdown/DropdownAnchorElement.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownAnchorElement.js +91 -0
- package/Controls/Components/Primitives/Dropdown/DropdownAnchorElement.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownAnchorElementTemplate.d.ts +9 -0
- package/Controls/Components/Primitives/Dropdown/DropdownAnchorElementTemplate.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownAnchorElementTemplate.js +14 -0
- package/Controls/Components/Primitives/Dropdown/DropdownAnchorElementTemplate.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownElement.d.ts +536 -0
- package/Controls/Components/Primitives/Dropdown/DropdownElement.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownElement.js +1450 -0
- package/Controls/Components/Primitives/Dropdown/DropdownElement.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownElementTemplate.d.ts +9 -0
- package/Controls/Components/Primitives/Dropdown/DropdownElementTemplate.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownElementTemplate.js +29 -0
- package/Controls/Components/Primitives/Dropdown/DropdownElementTemplate.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownPanelElement.d.ts +66 -0
- package/Controls/Components/Primitives/Dropdown/DropdownPanelElement.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownPanelElement.js +91 -0
- package/Controls/Components/Primitives/Dropdown/DropdownPanelElement.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownPanelElementTemplate.d.ts +9 -0
- package/Controls/Components/Primitives/Dropdown/DropdownPanelElementTemplate.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/DropdownPanelElementTemplate.js +14 -0
- package/Controls/Components/Primitives/Dropdown/DropdownPanelElementTemplate.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownAnchorElementProps.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownAnchorElementProps.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownAnchorElementProps.js +5 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownAnchorElementProps.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownElementProps.d.ts +118 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownElementProps.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownElementProps.js +34 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownElementProps.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownPanelElementProps.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownPanelElementProps.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownPanelElementProps.js +5 -0
- package/Controls/Components/Primitives/Dropdown/IDropdownPanelElementProps.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Cosmopolitan.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Cosmopolitan.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Cosmopolitan.js +48 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Cosmopolitan.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Joy.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Joy.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Joy.js +48 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Joy.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Memphis.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Memphis.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Memphis.js +48 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownAnchorElement.Memphis.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Cosmopolitan.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Cosmopolitan.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Cosmopolitan.js +116 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Cosmopolitan.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Joy.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Joy.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Joy.js +116 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Joy.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Memphis.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Memphis.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Memphis.js +116 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownElement.Memphis.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Cosmopolitan.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Cosmopolitan.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Cosmopolitan.js +48 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Cosmopolitan.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Joy.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Joy.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Joy.js +48 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Joy.js.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Memphis.d.ts +6 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Memphis.d.ts.map +1 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Memphis.js +48 -0
- package/Controls/Components/Primitives/Dropdown/Themes/DropdownPanelElement.Memphis.js.map +1 -0
- package/Controls/Directives/DateAgo/DateAgoDirective.js +1 -1
- package/Controls/Directives/DateAgo/DateAgoDirective.js.map +1 -1
- package/Controls/Directives/DateAgo/intl2/DateAgoIntl.d.ts +45 -0
- package/Controls/Directives/DateAgo/intl2/DateAgoIntl.d.ts.map +1 -0
- package/Controls/Directives/DateAgo/intl2/DateAgoIntl.js +106 -0
- package/Controls/Directives/DateAgo/intl2/DateAgoIntl.js.map +1 -0
- package/Controls/Directives/TimeAgo/TimeAgoDirective.js +1 -1
- package/Controls/Directives/TimeAgo/TimeAgoDirective.js.map +1 -1
- package/Controls/Directives/TimeAgo/intl2/TimeAgoIntl.d.ts +52 -0
- package/Controls/Directives/TimeAgo/intl2/TimeAgoIntl.d.ts.map +1 -0
- package/Controls/Directives/TimeAgo/intl2/TimeAgoIntl.js +125 -0
- package/Controls/Directives/TimeAgo/intl2/TimeAgoIntl.js.map +1 -0
- package/Controls/Types/DropdownChangeReason.d.ts +24 -0
- package/Controls/Types/DropdownChangeReason.d.ts.map +1 -0
- package/Controls/Types/DropdownChangeReason.js +21 -0
- package/Controls/Types/DropdownChangeReason.js.map +1 -0
- package/Controls/Types/DropdownTrigger.d.ts +29 -0
- package/Controls/Types/DropdownTrigger.d.ts.map +1 -0
- package/Controls/Types/DropdownTrigger.js +26 -0
- package/Controls/Types/DropdownTrigger.js.map +1 -0
- package/Controls/events/OpenCloseEvents.d.ts +23 -1
- package/Controls/events/OpenCloseEvents.d.ts.map +1 -1
- package/Controls/events/index.d.ts +1 -1
- package/Controls/events/index.d.ts.map +1 -1
- package/Index.d.ts +17 -11
- package/Index.d.ts.map +1 -1
- package/Index.js +16 -11
- package/Index.js.map +1 -1
- package/custom-elements.json +1788 -5
- package/package.json +3 -3
|
@@ -0,0 +1,1450 @@
|
|
|
1
|
+
// #region Imports
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var DropdownElement_1;
|
|
12
|
+
import { HTMLElementEventEmitter, on } from '@breadstone/mosaik-elements';
|
|
13
|
+
import { CssLength } from '@breadstone/mosaik-themes';
|
|
14
|
+
import { autoUpdate, computePosition, flip, offset as floatingOffset, platform, shift } from '@floating-ui/dom';
|
|
15
|
+
import { AnimationPlayer } from '../../../../Animations/AnimationPlayer';
|
|
16
|
+
import { fadeIn, fadeOut } from '../../../../Animations/Presets/Fade';
|
|
17
|
+
import { Emit } from '../../../../events/Decorators/EmitDecorator';
|
|
18
|
+
import { Animatable } from '../../../Behaviors/Animatable';
|
|
19
|
+
import { Disableable } from '../../../Behaviors/Disableable';
|
|
20
|
+
import { IDropDownableProps } from '../../../Behaviors/DropDownable';
|
|
21
|
+
import { Themeable } from '../../../Behaviors/Themeable';
|
|
22
|
+
import { ClickOutsideController } from '../../../Controllers/ClickOutsideController';
|
|
23
|
+
import { Attribute } from '../../../Decorators/AttributeDecorator';
|
|
24
|
+
import { Component } from '../../../Decorators/ComponentDecorator';
|
|
25
|
+
import { Watch } from '../../../Decorators/WatchDecorator';
|
|
26
|
+
import { DropdownChangeReason } from '../../../Types/DropdownChangeReason';
|
|
27
|
+
import { DropdownTrigger } from '../../../Types/DropdownTrigger';
|
|
28
|
+
import { Placement } from '../../../Types/Placement';
|
|
29
|
+
import { Strategy } from '../../../Types/Strategy';
|
|
30
|
+
import { CustomElement } from '../../Abstracts/CustomElement';
|
|
31
|
+
import { dropdownElementTemplate } from './DropdownElementTemplate';
|
|
32
|
+
import { IDropdownElementProps } from './IDropdownElementProps';
|
|
33
|
+
import { dropdownElementCosmopolitanStyle } from './Themes/DropdownElement.Cosmopolitan';
|
|
34
|
+
import { dropdownElementJoyStyle } from './Themes/DropdownElement.Joy';
|
|
35
|
+
import { dropdownElementMemphisStyle } from './Themes/DropdownElement.Memphis';
|
|
36
|
+
// #endregion
|
|
37
|
+
/**
|
|
38
|
+
* Dropdown - A generic anchored floating-content primitive for building dropdowns, popovers, menus, and floating panels.
|
|
39
|
+
*
|
|
40
|
+
* @description
|
|
41
|
+
* MosaicDropdown is a lower-level generic primitive that can be used to build every kind of anchored dropdown,
|
|
42
|
+
* popover-like panel, menu surface, filter panel, user menu, contextual action panel or custom floating-content surface.
|
|
43
|
+
* It owns only the dropdown lifecycle, trigger behavior, open state, native positioning, outside interaction handling,
|
|
44
|
+
* focus restoration, keyboard close behavior, event dispatching and animation orchestration.
|
|
45
|
+
* The semantic meaning of the projected content belongs to the projected content itself.
|
|
46
|
+
*
|
|
47
|
+
* The component supports two equivalent authoring styles:
|
|
48
|
+
* 1. Direct slot projection: Place any element with `slot="anchor"` and any element with `slot="panel"`.
|
|
49
|
+
* 2. Alias elements: Use `<mosaik-dropdown-anchor>` and `<mosaik-dropdown-panel>` wrappers.
|
|
50
|
+
*
|
|
51
|
+
* @name Dropdown
|
|
52
|
+
* @element mosaik-dropdown
|
|
53
|
+
* @category Primitives
|
|
54
|
+
*
|
|
55
|
+
* @slot anchor - The anchor content that triggers the dropdown.
|
|
56
|
+
* @slot panel - The floating panel content.
|
|
57
|
+
*
|
|
58
|
+
* @csspart anchor - The anchor wrapper part.
|
|
59
|
+
* @csspart panel - The panel wrapper part.
|
|
60
|
+
*
|
|
61
|
+
* @cssprop {String} --dropdown-background-color - The background color CSS custom property.
|
|
62
|
+
* @cssprop {String} --dropdown-border-color - The border color CSS custom property.
|
|
63
|
+
* @cssprop {String} --dropdown-border-radius - The border radius CSS custom property.
|
|
64
|
+
* @cssprop {String} --dropdown-border-style - The border style CSS custom property.
|
|
65
|
+
* @cssprop {String} --dropdown-border-width - The border width CSS custom property.
|
|
66
|
+
* @cssprop {String} --dropdown-font-family - The font family CSS custom property.
|
|
67
|
+
* @cssprop {String} --dropdown-font-letter-spacing - The font letter spacing CSS custom property.
|
|
68
|
+
* @cssprop {String} --dropdown-font-line-height - The font line height CSS custom property.
|
|
69
|
+
* @cssprop {String} --dropdown-font-size - The font size CSS custom property.
|
|
70
|
+
* @cssprop {String} --dropdown-font-text-decoration - The font text decoration CSS custom property.
|
|
71
|
+
* @cssprop {String} --dropdown-font-text-transform - The font text transform CSS custom property.
|
|
72
|
+
* @cssprop {String} --dropdown-font-weight - The font weight CSS custom property.
|
|
73
|
+
* @cssprop {String} --dropdown-foreground-color - The foreground color CSS custom property.
|
|
74
|
+
* @cssprop {String} --dropdown-gap - The gap CSS custom property.
|
|
75
|
+
* @cssprop {String} --dropdown-padding-bottom - The padding bottom CSS custom property.
|
|
76
|
+
* @cssprop {String} --dropdown-padding-left - The padding left CSS custom property.
|
|
77
|
+
* @cssprop {String} --dropdown-padding-right - The padding right CSS custom property.
|
|
78
|
+
* @cssprop {String} --dropdown-padding-top - The padding top CSS custom property.
|
|
79
|
+
* @cssprop {String} --dropdown-panel-background-color - The background color of the dropdown panel.
|
|
80
|
+
* @cssprop {String} --dropdown-panel-border-color - The border color of the dropdown panel.
|
|
81
|
+
* @cssprop {String} --dropdown-panel-border-radius - The border radius of the dropdown panel.
|
|
82
|
+
* @cssprop {String} --dropdown-panel-border-style - The border style of the dropdown panel.
|
|
83
|
+
* @cssprop {String} --dropdown-panel-border-width - The border width of the dropdown panel.
|
|
84
|
+
* @cssprop {String} --dropdown-panel-box-shadow - The box shadow of the dropdown panel.
|
|
85
|
+
* @cssprop {String} --dropdown-panel-max-height - The max height of the dropdown panel.
|
|
86
|
+
* @cssprop {String} --dropdown-panel-offset - The offset between anchor and panel.
|
|
87
|
+
* @cssprop {String} --dropdown-panel-padding - The padding of the dropdown panel.
|
|
88
|
+
* @cssprop {String} --dropdown-panel-z-index - The z-index of the dropdown panel.
|
|
89
|
+
* @cssprop {String} --dropdown-shadow - The shadow CSS custom property.
|
|
90
|
+
* @cssprop {String} --dropdown-shadow-blur - The shadow blur CSS custom property.
|
|
91
|
+
* @cssprop {String} --dropdown-shadow-color - The shadow color CSS custom property.
|
|
92
|
+
* @cssprop {String} --dropdown-shadow-offset-x - The shadow offset x CSS custom property.
|
|
93
|
+
* @cssprop {String} --dropdown-shadow-offset-y - The shadow offset y CSS custom property.
|
|
94
|
+
* @cssprop {String} --dropdown-shadow-spread - The shadow spread CSS custom property.
|
|
95
|
+
* @cssprop {String} --dropdown-transition-duration - The transition duration CSS custom property.
|
|
96
|
+
* @cssprop {String} --dropdown-transition-mode - The transition mode CSS custom property.
|
|
97
|
+
* @cssprop {String} --dropdown-transition-property - The transition property CSS custom property.
|
|
98
|
+
* @cssprop {String} --dropdown-translate - The translate CSS custom property.
|
|
99
|
+
*
|
|
100
|
+
* @fires openChanged {CustomEvent<{open: boolean, reason: DropdownChangeReason}>} - Fired when the open state changes.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* Basic dropdown with menu:
|
|
104
|
+
* ```html
|
|
105
|
+
* <mosaik-dropdown placement="bottom-start">
|
|
106
|
+
* <mosaik-button slot="anchor">Actions</mosaik-button>
|
|
107
|
+
* <mosaik-menu slot="panel">
|
|
108
|
+
* <mosaik-menu-item label="Edit"></mosaik-menu-item>
|
|
109
|
+
* <mosaik-menu-item label="Duplicate"></mosaik-menu-item>
|
|
110
|
+
* <mosaik-menu-item label="Delete"></mosaik-menu-item>
|
|
111
|
+
* </mosaik-menu>
|
|
112
|
+
* </mosaik-dropdown>
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* Dropdown with alias elements:
|
|
117
|
+
* ```html
|
|
118
|
+
* <mosaik-dropdown placement="bottom-end">
|
|
119
|
+
* <mosaik-dropdown-anchor>
|
|
120
|
+
* <mosaik-avatar user-id="current"></mosaik-avatar>
|
|
121
|
+
* </mosaik-dropdown-anchor>
|
|
122
|
+
* <mosaik-dropdown-panel>
|
|
123
|
+
* <mosaik-card>Account details</mosaik-card>
|
|
124
|
+
* </mosaik-dropdown-panel>
|
|
125
|
+
* </mosaik-dropdown>
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* Controlled dropdown:
|
|
130
|
+
* ```html
|
|
131
|
+
* <mosaik-dropdown .open="${this.isOpen}" trigger="manual">
|
|
132
|
+
* <mosaik-button slot="anchor">Toggle</mosaik-button>
|
|
133
|
+
* <div slot="panel">Panel content</div>
|
|
134
|
+
* </mosaik-dropdown>
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* @public
|
|
138
|
+
*/
|
|
139
|
+
let DropdownElement = class DropdownElement extends Themeable(Animatable(Disableable(CustomElement))) {
|
|
140
|
+
static { DropdownElement_1 = this; }
|
|
141
|
+
// #region Fields
|
|
142
|
+
static _anchorCounter = 0;
|
|
143
|
+
_clickOutsideController;
|
|
144
|
+
_animationPlayer;
|
|
145
|
+
_openChanged;
|
|
146
|
+
_instanceId;
|
|
147
|
+
_trigger;
|
|
148
|
+
_closeOnEscape;
|
|
149
|
+
_closeOnSelect;
|
|
150
|
+
_restoreFocus;
|
|
151
|
+
_hasPopup;
|
|
152
|
+
_matchAnchorWidth;
|
|
153
|
+
_popupRole;
|
|
154
|
+
_isVisible;
|
|
155
|
+
_dropDownPlacement;
|
|
156
|
+
_dropDownStrategy;
|
|
157
|
+
_dropDownDistance;
|
|
158
|
+
_dropDownSkidding;
|
|
159
|
+
_dropDownStaysOpen;
|
|
160
|
+
_dropDownMaxHeight;
|
|
161
|
+
_dropDownHeight;
|
|
162
|
+
_dropDownWidth;
|
|
163
|
+
_dropDownMaxWidth;
|
|
164
|
+
_isDropDownOpen;
|
|
165
|
+
_anchorElement;
|
|
166
|
+
_panelElement;
|
|
167
|
+
_anchorSlot;
|
|
168
|
+
_panelSlot;
|
|
169
|
+
_hoverTimeout;
|
|
170
|
+
_focusTimeout;
|
|
171
|
+
_clickSubscription;
|
|
172
|
+
_anchorMouseEnterSubscription;
|
|
173
|
+
_anchorMouseLeaveSubscription;
|
|
174
|
+
_anchorFocusInSubscription;
|
|
175
|
+
_anchorFocusOutSubscription;
|
|
176
|
+
_panelClickSubscription;
|
|
177
|
+
_panelKeydownSubscription;
|
|
178
|
+
_panelMouseEnterSubscription;
|
|
179
|
+
_panelMouseLeaveSubscription;
|
|
180
|
+
_positioningCleanup;
|
|
181
|
+
// #endregion
|
|
182
|
+
// #region Ctor
|
|
183
|
+
/**
|
|
184
|
+
* @public
|
|
185
|
+
*/
|
|
186
|
+
constructor() {
|
|
187
|
+
super();
|
|
188
|
+
this._trigger = IDropdownElementProps.DEFAULTS.trigger;
|
|
189
|
+
this._closeOnEscape = IDropdownElementProps.DEFAULTS.closeOnEscape;
|
|
190
|
+
this._closeOnSelect = IDropdownElementProps.DEFAULTS.closeOnSelect;
|
|
191
|
+
this._restoreFocus = IDropdownElementProps.DEFAULTS.restoreFocus;
|
|
192
|
+
this._matchAnchorWidth = IDropdownElementProps.DEFAULTS.matchAnchorWidth;
|
|
193
|
+
this._popupRole = '';
|
|
194
|
+
this._isVisible = false;
|
|
195
|
+
this._dropDownPlacement = IDropDownableProps.DEFAULTS.dropDownPlacement;
|
|
196
|
+
this._dropDownStrategy = IDropDownableProps.DEFAULTS.dropDownStrategy;
|
|
197
|
+
this._dropDownDistance = IDropDownableProps.DEFAULTS.dropDownDistance;
|
|
198
|
+
this._dropDownSkidding = IDropDownableProps.DEFAULTS.dropDownSkidding;
|
|
199
|
+
this._dropDownStaysOpen = IDropDownableProps.DEFAULTS.dropDownStaysOpen;
|
|
200
|
+
this._dropDownMaxHeight = IDropDownableProps.DEFAULTS.dropDownMaxHeight;
|
|
201
|
+
this._dropDownHeight = IDropDownableProps.DEFAULTS.dropDownHeight;
|
|
202
|
+
this._dropDownWidth = IDropDownableProps.DEFAULTS.dropDownWidth;
|
|
203
|
+
this._dropDownMaxWidth = IDropDownableProps.DEFAULTS.dropDownMaxWidth;
|
|
204
|
+
this._isDropDownOpen = IDropDownableProps.DEFAULTS.isDropDownOpen;
|
|
205
|
+
this._anchorElement = null;
|
|
206
|
+
this._panelElement = null;
|
|
207
|
+
this._anchorSlot = null;
|
|
208
|
+
this._panelSlot = null;
|
|
209
|
+
this._hoverTimeout = null;
|
|
210
|
+
this._focusTimeout = null;
|
|
211
|
+
this._clickSubscription = null;
|
|
212
|
+
this._anchorMouseEnterSubscription = null;
|
|
213
|
+
this._anchorMouseLeaveSubscription = null;
|
|
214
|
+
this._anchorFocusInSubscription = null;
|
|
215
|
+
this._anchorFocusOutSubscription = null;
|
|
216
|
+
this._panelClickSubscription = null;
|
|
217
|
+
this._panelKeydownSubscription = null;
|
|
218
|
+
this._panelMouseEnterSubscription = null;
|
|
219
|
+
this._panelMouseLeaveSubscription = null;
|
|
220
|
+
this._positioningCleanup = null;
|
|
221
|
+
this._instanceId = this.constructor._anchorCounter++;
|
|
222
|
+
this._animationPlayer = new AnimationPlayer();
|
|
223
|
+
this._openChanged = new HTMLElementEventEmitter(this, 'openChanged');
|
|
224
|
+
this._clickOutsideController = new ClickOutsideController(this, {
|
|
225
|
+
skipInitial: true,
|
|
226
|
+
callback: () => this.onClickedOutside()
|
|
227
|
+
});
|
|
228
|
+
// REMARK: This is a workaround for the issue with the docs generation.
|
|
229
|
+
Object.assign(this, { maxHeight: '200px' });
|
|
230
|
+
}
|
|
231
|
+
// #endregion
|
|
232
|
+
// #region Properties
|
|
233
|
+
/**
|
|
234
|
+
* Returns the `is` property.
|
|
235
|
+
* The `is` property represents natural name of this element.
|
|
236
|
+
*
|
|
237
|
+
* @public
|
|
238
|
+
* @static
|
|
239
|
+
* @readonly
|
|
240
|
+
*/
|
|
241
|
+
static get is() {
|
|
242
|
+
return 'mosaik-dropdown';
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Gets the unique anchor ID for this instance.
|
|
246
|
+
*
|
|
247
|
+
* @public
|
|
248
|
+
* @readonly
|
|
249
|
+
*/
|
|
250
|
+
get _anchorId() {
|
|
251
|
+
return `mosaik-dropdown-anchor-${this._instanceId}`;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Gets the unique panel ID for this instance.
|
|
255
|
+
*
|
|
256
|
+
* @public
|
|
257
|
+
* @readonly
|
|
258
|
+
*/
|
|
259
|
+
get _panelId() {
|
|
260
|
+
return `mosaik-dropdown-panel-${this._instanceId}`;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Gets the anchor name CSS custom property for CSS Anchor Positioning.
|
|
264
|
+
*
|
|
265
|
+
* @public
|
|
266
|
+
* @readonly
|
|
267
|
+
*/
|
|
268
|
+
get _anchorName() {
|
|
269
|
+
return `--dropdown-anchor-${this._instanceId}`;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Gets the current popup role based on the hasPopup property.
|
|
273
|
+
*
|
|
274
|
+
* @public
|
|
275
|
+
* @readonly
|
|
276
|
+
*/
|
|
277
|
+
get popupRole() {
|
|
278
|
+
return this._popupRole;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Gets whether the panel is currently visible.
|
|
282
|
+
* This is separate from `open` to allow exit animations to complete before hiding.
|
|
283
|
+
*
|
|
284
|
+
* @public
|
|
285
|
+
* @readonly
|
|
286
|
+
*/
|
|
287
|
+
get isVisible() {
|
|
288
|
+
return this._isVisible;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Gets the animation target element.
|
|
292
|
+
* Animations are applied to the panel element.
|
|
293
|
+
*
|
|
294
|
+
* @public
|
|
295
|
+
* @override
|
|
296
|
+
* @readonly
|
|
297
|
+
*/
|
|
298
|
+
get animationTarget() {
|
|
299
|
+
return this._panelElement ?? this;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Gets or sets the `dropDownPlacement` property.
|
|
303
|
+
*
|
|
304
|
+
* @public
|
|
305
|
+
* @attr drop-down-placement
|
|
306
|
+
*/
|
|
307
|
+
get dropDownPlacement() {
|
|
308
|
+
return this._dropDownPlacement;
|
|
309
|
+
}
|
|
310
|
+
set dropDownPlacement(value) {
|
|
311
|
+
if (this._dropDownPlacement !== value) {
|
|
312
|
+
this._dropDownPlacement = value;
|
|
313
|
+
this.requestUpdate('dropDownPlacement');
|
|
314
|
+
this.requestUpdate('placement');
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Gets or sets the `dropDownStrategy` property.
|
|
319
|
+
*
|
|
320
|
+
* @public
|
|
321
|
+
* @attr drop-down-strategy
|
|
322
|
+
*/
|
|
323
|
+
get dropDownStrategy() {
|
|
324
|
+
return this._dropDownStrategy;
|
|
325
|
+
}
|
|
326
|
+
set dropDownStrategy(value) {
|
|
327
|
+
if (this._dropDownStrategy !== value) {
|
|
328
|
+
this._dropDownStrategy = value;
|
|
329
|
+
this.requestUpdate('dropDownStrategy');
|
|
330
|
+
this.requestUpdate('strategy');
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Gets or sets the `dropDownDistance` property.
|
|
335
|
+
*
|
|
336
|
+
* @public
|
|
337
|
+
* @attr drop-down-distance
|
|
338
|
+
*/
|
|
339
|
+
get dropDownDistance() {
|
|
340
|
+
return this._dropDownDistance;
|
|
341
|
+
}
|
|
342
|
+
set dropDownDistance(value) {
|
|
343
|
+
if (this._dropDownDistance !== value) {
|
|
344
|
+
this._dropDownDistance = value;
|
|
345
|
+
this.requestUpdate('dropDownDistance');
|
|
346
|
+
this.requestUpdate('offset');
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Gets or sets the `dropDownSkidding` property.
|
|
351
|
+
*
|
|
352
|
+
* @public
|
|
353
|
+
* @attr drop-down-skidding
|
|
354
|
+
*/
|
|
355
|
+
get dropDownSkidding() {
|
|
356
|
+
return this._dropDownSkidding;
|
|
357
|
+
}
|
|
358
|
+
set dropDownSkidding(value) {
|
|
359
|
+
if (this._dropDownSkidding !== value) {
|
|
360
|
+
this._dropDownSkidding = value;
|
|
361
|
+
this.requestUpdate('dropDownSkidding');
|
|
362
|
+
this.requestUpdate('skidding');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Gets or sets the `dropDownStaysOpen` property.
|
|
367
|
+
*
|
|
368
|
+
* @public
|
|
369
|
+
* @attr drop-down-stays-open
|
|
370
|
+
*/
|
|
371
|
+
get dropDownStaysOpen() {
|
|
372
|
+
return this._dropDownStaysOpen;
|
|
373
|
+
}
|
|
374
|
+
set dropDownStaysOpen(value) {
|
|
375
|
+
if (this._dropDownStaysOpen !== value) {
|
|
376
|
+
this._dropDownStaysOpen = value;
|
|
377
|
+
this.requestUpdate('dropDownStaysOpen');
|
|
378
|
+
this.requestUpdate('closeOnOutsideClick');
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Gets or sets the `dropDownMaxHeight` property.
|
|
383
|
+
*
|
|
384
|
+
* @public
|
|
385
|
+
* @attr drop-down-max-height
|
|
386
|
+
*/
|
|
387
|
+
get dropDownMaxHeight() {
|
|
388
|
+
return this._dropDownMaxHeight;
|
|
389
|
+
}
|
|
390
|
+
set dropDownMaxHeight(value) {
|
|
391
|
+
if (this._dropDownMaxHeight !== value) {
|
|
392
|
+
this._dropDownMaxHeight = value;
|
|
393
|
+
this.requestUpdate('dropDownMaxHeight');
|
|
394
|
+
this.requestUpdate('maxHeight');
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Gets or sets the `dropDownHeight` property.
|
|
399
|
+
*
|
|
400
|
+
* @public
|
|
401
|
+
* @attr drop-down-height
|
|
402
|
+
*/
|
|
403
|
+
get dropDownHeight() {
|
|
404
|
+
return this._dropDownHeight;
|
|
405
|
+
}
|
|
406
|
+
set dropDownHeight(value) {
|
|
407
|
+
if (this._dropDownHeight !== value) {
|
|
408
|
+
this._dropDownHeight = value;
|
|
409
|
+
this.requestUpdate('dropDownHeight');
|
|
410
|
+
this.requestUpdate('height');
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Gets or sets the `dropDownWidth` property.
|
|
415
|
+
*
|
|
416
|
+
* @public
|
|
417
|
+
* @attr drop-down-width
|
|
418
|
+
*/
|
|
419
|
+
get dropDownWidth() {
|
|
420
|
+
return this._dropDownWidth;
|
|
421
|
+
}
|
|
422
|
+
set dropDownWidth(value) {
|
|
423
|
+
if (this._dropDownWidth !== value) {
|
|
424
|
+
this._dropDownWidth = value;
|
|
425
|
+
this.requestUpdate('dropDownWidth');
|
|
426
|
+
this.requestUpdate('width');
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Gets or sets the `dropDownMaxWidth` property.
|
|
431
|
+
*
|
|
432
|
+
* @public
|
|
433
|
+
* @attr drop-down-max-width
|
|
434
|
+
*/
|
|
435
|
+
get dropDownMaxWidth() {
|
|
436
|
+
return this._dropDownMaxWidth;
|
|
437
|
+
}
|
|
438
|
+
set dropDownMaxWidth(value) {
|
|
439
|
+
if (this._dropDownMaxWidth !== value) {
|
|
440
|
+
this._dropDownMaxWidth = value;
|
|
441
|
+
this.requestUpdate('dropDownMaxWidth');
|
|
442
|
+
this.requestUpdate('maxWidth');
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Gets or sets the `isDropDownOpen` property.
|
|
447
|
+
*
|
|
448
|
+
* @public
|
|
449
|
+
* @attr is-drop-down-open
|
|
450
|
+
*/
|
|
451
|
+
get isDropDownOpen() {
|
|
452
|
+
return this._isDropDownOpen;
|
|
453
|
+
}
|
|
454
|
+
set isDropDownOpen(value) {
|
|
455
|
+
if (this._isDropDownOpen !== value) {
|
|
456
|
+
this._isDropDownOpen = value;
|
|
457
|
+
this.requestUpdate('isDropDownOpen');
|
|
458
|
+
this.requestUpdate('open');
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Gets or sets the `placement` property.
|
|
463
|
+
*
|
|
464
|
+
* @public
|
|
465
|
+
* @attr placement
|
|
466
|
+
*/
|
|
467
|
+
get placement() {
|
|
468
|
+
return this.dropDownPlacement;
|
|
469
|
+
}
|
|
470
|
+
set placement(value) {
|
|
471
|
+
if (this.dropDownPlacement !== value) {
|
|
472
|
+
this.dropDownPlacement = value;
|
|
473
|
+
this.requestUpdate('placement');
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Gets or sets the `strategy` property.
|
|
478
|
+
*
|
|
479
|
+
* @public
|
|
480
|
+
* @attr strategy
|
|
481
|
+
*/
|
|
482
|
+
get strategy() {
|
|
483
|
+
return this.dropDownStrategy;
|
|
484
|
+
}
|
|
485
|
+
set strategy(value) {
|
|
486
|
+
if (this.dropDownStrategy !== value) {
|
|
487
|
+
this.dropDownStrategy = value;
|
|
488
|
+
this.requestUpdate('strategy');
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Gets or sets the `offset` property.
|
|
493
|
+
*
|
|
494
|
+
* @public
|
|
495
|
+
* @attr offset
|
|
496
|
+
*/
|
|
497
|
+
get offset() {
|
|
498
|
+
return this.dropDownDistance;
|
|
499
|
+
}
|
|
500
|
+
set offset(value) {
|
|
501
|
+
if (this.dropDownDistance !== value) {
|
|
502
|
+
this.dropDownDistance = value;
|
|
503
|
+
this.requestUpdate('offset');
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Gets or sets the `skidding` property.
|
|
508
|
+
*
|
|
509
|
+
* @public
|
|
510
|
+
* @attr skidding
|
|
511
|
+
*/
|
|
512
|
+
get skidding() {
|
|
513
|
+
return this.dropDownSkidding;
|
|
514
|
+
}
|
|
515
|
+
set skidding(value) {
|
|
516
|
+
if (this.dropDownSkidding !== value) {
|
|
517
|
+
this.dropDownSkidding = value;
|
|
518
|
+
this.requestUpdate('skidding');
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Gets or sets the `open` property.
|
|
523
|
+
* Supports both controlled and uncontrolled usage.
|
|
524
|
+
*
|
|
525
|
+
* @public
|
|
526
|
+
* @attr open
|
|
527
|
+
*/
|
|
528
|
+
get open() {
|
|
529
|
+
return this.isDropDownOpen;
|
|
530
|
+
}
|
|
531
|
+
set open(value) {
|
|
532
|
+
if (this.isDropDownOpen !== value) {
|
|
533
|
+
this.isDropDownOpen = value;
|
|
534
|
+
this.requestUpdate('open');
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Gets or sets the `trigger` property.
|
|
539
|
+
*
|
|
540
|
+
* @public
|
|
541
|
+
* @attr trigger
|
|
542
|
+
*/
|
|
543
|
+
get trigger() {
|
|
544
|
+
return this._trigger;
|
|
545
|
+
}
|
|
546
|
+
set trigger(value) {
|
|
547
|
+
if (this._trigger !== value) {
|
|
548
|
+
this._trigger = value;
|
|
549
|
+
this.requestUpdate('trigger');
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Gets or sets the `closeOnOutsideClick` property.
|
|
554
|
+
*
|
|
555
|
+
* @public
|
|
556
|
+
* @attr close-on-outside-click
|
|
557
|
+
*/
|
|
558
|
+
get closeOnOutsideClick() {
|
|
559
|
+
return !this.dropDownStaysOpen;
|
|
560
|
+
}
|
|
561
|
+
set closeOnOutsideClick(value) {
|
|
562
|
+
if (this.closeOnOutsideClick !== value) {
|
|
563
|
+
this.dropDownStaysOpen = !value;
|
|
564
|
+
this.requestUpdate('closeOnOutsideClick');
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Gets or sets the `closeOnEscape` property.
|
|
569
|
+
*
|
|
570
|
+
* @public
|
|
571
|
+
* @attr close-on-escape
|
|
572
|
+
*/
|
|
573
|
+
get closeOnEscape() {
|
|
574
|
+
return this._closeOnEscape;
|
|
575
|
+
}
|
|
576
|
+
set closeOnEscape(value) {
|
|
577
|
+
if (this._closeOnEscape !== value) {
|
|
578
|
+
this._closeOnEscape = value;
|
|
579
|
+
this.requestUpdate('closeOnEscape');
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Gets or sets the `closeOnSelect` property.
|
|
584
|
+
*
|
|
585
|
+
* @public
|
|
586
|
+
* @attr close-on-select
|
|
587
|
+
*/
|
|
588
|
+
get closeOnSelect() {
|
|
589
|
+
return this._closeOnSelect;
|
|
590
|
+
}
|
|
591
|
+
set closeOnSelect(value) {
|
|
592
|
+
if (this._closeOnSelect !== value) {
|
|
593
|
+
this._closeOnSelect = value;
|
|
594
|
+
this.requestUpdate('closeOnSelect');
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* Gets or sets the `restoreFocus` property.
|
|
599
|
+
*
|
|
600
|
+
* @public
|
|
601
|
+
* @attr restore-focus
|
|
602
|
+
*/
|
|
603
|
+
get restoreFocus() {
|
|
604
|
+
return this._restoreFocus;
|
|
605
|
+
}
|
|
606
|
+
set restoreFocus(value) {
|
|
607
|
+
if (this._restoreFocus !== value) {
|
|
608
|
+
this._restoreFocus = value;
|
|
609
|
+
this.requestUpdate('restoreFocus');
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Gets or sets the `hasPopup` property.
|
|
614
|
+
*
|
|
615
|
+
* @public
|
|
616
|
+
* @attr has-popup
|
|
617
|
+
*/
|
|
618
|
+
get hasPopup() {
|
|
619
|
+
return this._hasPopup;
|
|
620
|
+
}
|
|
621
|
+
set hasPopup(value) {
|
|
622
|
+
if (this._hasPopup !== value) {
|
|
623
|
+
this._hasPopup = value;
|
|
624
|
+
this._popupRole = value ?? '';
|
|
625
|
+
this.requestUpdate('hasPopup');
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Gets or sets the `matchAnchorWidth` property.
|
|
630
|
+
*
|
|
631
|
+
* @public
|
|
632
|
+
* @attr match-anchor-width
|
|
633
|
+
*/
|
|
634
|
+
get matchAnchorWidth() {
|
|
635
|
+
return this._matchAnchorWidth;
|
|
636
|
+
}
|
|
637
|
+
set matchAnchorWidth(value) {
|
|
638
|
+
if (this._matchAnchorWidth !== value) {
|
|
639
|
+
this._matchAnchorWidth = value;
|
|
640
|
+
this.requestUpdate('matchAnchorWidth');
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Gets or sets the `maxHeight` property.
|
|
645
|
+
*
|
|
646
|
+
* @public
|
|
647
|
+
* @attr max-height
|
|
648
|
+
*/
|
|
649
|
+
get maxHeight() {
|
|
650
|
+
return this.dropDownMaxHeight;
|
|
651
|
+
}
|
|
652
|
+
set maxHeight(value) {
|
|
653
|
+
if (this.dropDownMaxHeight !== value) {
|
|
654
|
+
this.dropDownMaxHeight = value;
|
|
655
|
+
this.requestUpdate('maxHeight');
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* Gets or sets the `height` property.
|
|
660
|
+
*
|
|
661
|
+
* @public
|
|
662
|
+
* @attr height
|
|
663
|
+
*/
|
|
664
|
+
get height() {
|
|
665
|
+
return this.dropDownHeight;
|
|
666
|
+
}
|
|
667
|
+
set height(value) {
|
|
668
|
+
if (this.dropDownHeight !== value) {
|
|
669
|
+
this.dropDownHeight = value;
|
|
670
|
+
this.requestUpdate('height');
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Gets or sets the `width` property.
|
|
675
|
+
*
|
|
676
|
+
* @public
|
|
677
|
+
* @attr width
|
|
678
|
+
*/
|
|
679
|
+
get width() {
|
|
680
|
+
return this.dropDownWidth;
|
|
681
|
+
}
|
|
682
|
+
set width(value) {
|
|
683
|
+
if (this.dropDownWidth !== value) {
|
|
684
|
+
this.dropDownWidth = value;
|
|
685
|
+
this.requestUpdate('width');
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Gets or sets the `maxWidth` property.
|
|
690
|
+
*
|
|
691
|
+
* @public
|
|
692
|
+
* @attr max-width
|
|
693
|
+
*/
|
|
694
|
+
get maxWidth() {
|
|
695
|
+
return this.dropDownMaxWidth;
|
|
696
|
+
}
|
|
697
|
+
set maxWidth(value) {
|
|
698
|
+
if (this.dropDownMaxWidth !== value) {
|
|
699
|
+
this.dropDownMaxWidth = value;
|
|
700
|
+
this.requestUpdate('maxWidth');
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Called when the open state changes.
|
|
705
|
+
*
|
|
706
|
+
* @public
|
|
707
|
+
* @readonly
|
|
708
|
+
* @eventProperty
|
|
709
|
+
*/
|
|
710
|
+
get openChanged() {
|
|
711
|
+
return this._openChanged;
|
|
712
|
+
}
|
|
713
|
+
// #endregion
|
|
714
|
+
// #region Methods
|
|
715
|
+
/**
|
|
716
|
+
* Opens the dropdown.
|
|
717
|
+
*
|
|
718
|
+
* @param reason - The reason for opening.
|
|
719
|
+
* @public
|
|
720
|
+
*/
|
|
721
|
+
openDropdown(reason = DropdownChangeReason.Programmatic) {
|
|
722
|
+
if (this.disabled) {
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
if (this.open) {
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
this.open = true;
|
|
729
|
+
this._openChanged.emit({ open: true, reason });
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Closes the dropdown.
|
|
733
|
+
*
|
|
734
|
+
* @param reason - The reason for closing.
|
|
735
|
+
* @public
|
|
736
|
+
*/
|
|
737
|
+
closeDropdown(reason = DropdownChangeReason.Programmatic) {
|
|
738
|
+
if (!this.open) {
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
this.open = false;
|
|
742
|
+
this._openChanged.emit({ open: false, reason });
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Toggles the dropdown.
|
|
746
|
+
*
|
|
747
|
+
* @param reason - The reason for toggling.
|
|
748
|
+
* @public
|
|
749
|
+
*/
|
|
750
|
+
toggleDropdown(reason = DropdownChangeReason.Programmatic) {
|
|
751
|
+
if (this.disabled) {
|
|
752
|
+
this.closeDropdown(DropdownChangeReason.Disabled);
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
if (this.open) {
|
|
756
|
+
this.closeDropdown(reason);
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
this.openDropdown(reason);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Updates the panel position. With native CSS Anchor Positioning,
|
|
764
|
+
* this is usually not needed but serves as an imperative escape hatch.
|
|
765
|
+
*
|
|
766
|
+
* @public
|
|
767
|
+
*/
|
|
768
|
+
updatePosition() {
|
|
769
|
+
if (!this._panelElement || !this._anchorElement) {
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
this.applyPositioning();
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* @public
|
|
776
|
+
* @override
|
|
777
|
+
*/
|
|
778
|
+
connectedCallback() {
|
|
779
|
+
super.connectedCallback();
|
|
780
|
+
// Set up anchor click handling
|
|
781
|
+
this._clickSubscription = on(this, 'click', (event) => {
|
|
782
|
+
const path = event.composedPath();
|
|
783
|
+
if (this.isAnchorEventPath(path)) {
|
|
784
|
+
this.onAnchorClick();
|
|
785
|
+
}
|
|
786
|
+
});
|
|
787
|
+
this._panelElement = this.shadowRoot?.querySelector('[part="panel"]') ?? null;
|
|
788
|
+
if (this.open) {
|
|
789
|
+
this._isVisible = true;
|
|
790
|
+
this.requestUpdate('isVisible');
|
|
791
|
+
}
|
|
792
|
+
// Set up trigger and panel event listeners after the template is available.
|
|
793
|
+
void this.updateComplete.then(() => {
|
|
794
|
+
this.onAnchorSlotChange(new Event('slotchange'));
|
|
795
|
+
this.setupAnchorListeners();
|
|
796
|
+
this.setupPanelListeners();
|
|
797
|
+
if (this.open) {
|
|
798
|
+
this._clickOutsideController.observe();
|
|
799
|
+
this.showPanel();
|
|
800
|
+
}
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* @public
|
|
805
|
+
* @override
|
|
806
|
+
*/
|
|
807
|
+
disconnectedCallback() {
|
|
808
|
+
super.disconnectedCallback();
|
|
809
|
+
this._clickSubscription?.dispose();
|
|
810
|
+
this._clickSubscription = null;
|
|
811
|
+
this._anchorMouseEnterSubscription?.dispose();
|
|
812
|
+
this._anchorMouseEnterSubscription = null;
|
|
813
|
+
this._anchorMouseLeaveSubscription?.dispose();
|
|
814
|
+
this._anchorMouseLeaveSubscription = null;
|
|
815
|
+
this._anchorFocusInSubscription?.dispose();
|
|
816
|
+
this._anchorFocusInSubscription = null;
|
|
817
|
+
this._anchorFocusOutSubscription?.dispose();
|
|
818
|
+
this._anchorFocusOutSubscription = null;
|
|
819
|
+
this._panelClickSubscription?.dispose();
|
|
820
|
+
this._panelClickSubscription = null;
|
|
821
|
+
this._panelKeydownSubscription?.dispose();
|
|
822
|
+
this._panelKeydownSubscription = null;
|
|
823
|
+
this._panelMouseEnterSubscription?.dispose();
|
|
824
|
+
this._panelMouseEnterSubscription = null;
|
|
825
|
+
this._panelMouseLeaveSubscription?.dispose();
|
|
826
|
+
this._panelMouseLeaveSubscription = null;
|
|
827
|
+
this.clearHoverTimeout();
|
|
828
|
+
this.clearFocusTimeout();
|
|
829
|
+
this._clickOutsideController.unobserve();
|
|
830
|
+
this.stopPositioning();
|
|
831
|
+
}
|
|
832
|
+
/**
|
|
833
|
+
* Handles anchor slot changes.
|
|
834
|
+
*
|
|
835
|
+
* @public
|
|
836
|
+
*/
|
|
837
|
+
onAnchorSlotChange(_event) {
|
|
838
|
+
if (!this._anchorSlot) {
|
|
839
|
+
this._anchorSlot = this.shadowRoot?.querySelector('slot[name="anchor"]') ?? null;
|
|
840
|
+
}
|
|
841
|
+
const assigned = this._anchorSlot?.assignedElements({ flatten: true }) ?? [];
|
|
842
|
+
this._anchorElement = assigned[0] ?? null;
|
|
843
|
+
if (this._anchorElement) {
|
|
844
|
+
// Apply anchor-name for CSS Anchor Positioning
|
|
845
|
+
this._anchorElement.style.setProperty('anchor-name', this._anchorName);
|
|
846
|
+
// Apply hasPopup and aria-expanded if the anchor is a button
|
|
847
|
+
this.applyAriaAttributes();
|
|
848
|
+
}
|
|
849
|
+
if (this.open) {
|
|
850
|
+
this.startPositioning();
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Handles panel slot changes.
|
|
855
|
+
*
|
|
856
|
+
* @public
|
|
857
|
+
*/
|
|
858
|
+
onPanelSlotChange(_event) {
|
|
859
|
+
if (!this._panelSlot) {
|
|
860
|
+
this._panelSlot = this.shadowRoot?.querySelector('slot[name="panel"]') ?? null;
|
|
861
|
+
}
|
|
862
|
+
this._panelElement = this.shadowRoot?.querySelector('[part="panel"]') ?? null;
|
|
863
|
+
if (this._panelElement) {
|
|
864
|
+
this.setupPanelListeners();
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
// #endregion
|
|
868
|
+
// #region Lifecycle
|
|
869
|
+
/**
|
|
870
|
+
* @protected
|
|
871
|
+
*/
|
|
872
|
+
onOpenPropertyChanged(_prev, next) {
|
|
873
|
+
if (next) {
|
|
874
|
+
if (this.disabled) {
|
|
875
|
+
this.isDropDownOpen = false;
|
|
876
|
+
this._isVisible = false;
|
|
877
|
+
this.requestUpdate('open');
|
|
878
|
+
this.requestUpdate('isVisible');
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
this._isVisible = true;
|
|
882
|
+
this.requestUpdate('isVisible');
|
|
883
|
+
void this.updateComplete.then(() => {
|
|
884
|
+
this._panelElement = this.shadowRoot?.querySelector('[part="panel"]') ?? null;
|
|
885
|
+
this.onPanelSlotChange(new Event('slotchange'));
|
|
886
|
+
this.setupPanelListeners();
|
|
887
|
+
this.showPanel();
|
|
888
|
+
this._clickOutsideController.observe();
|
|
889
|
+
this.applyAriaAttributes();
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
this._clickOutsideController.unobserve();
|
|
894
|
+
this.applyAriaAttributes();
|
|
895
|
+
void this.hidePanel();
|
|
896
|
+
// Restore focus to anchor
|
|
897
|
+
if (this._restoreFocus && this._anchorElement) {
|
|
898
|
+
this._anchorElement.focus?.();
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
/**
|
|
903
|
+
* @protected
|
|
904
|
+
*/
|
|
905
|
+
onDisabledPropertyChanged(_prev, next) {
|
|
906
|
+
if (next) {
|
|
907
|
+
this.closeDropdown(DropdownChangeReason.Disabled);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* @protected
|
|
912
|
+
*/
|
|
913
|
+
onTriggerPropertyChanged(_prev, next) {
|
|
914
|
+
this.clearHoverTimeout();
|
|
915
|
+
this.clearFocusTimeout();
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* @protected
|
|
919
|
+
*/
|
|
920
|
+
onPositioningPropertyChanged() {
|
|
921
|
+
if (this.open) {
|
|
922
|
+
this.startPositioning();
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
// #endregion
|
|
926
|
+
// #region Private Methods
|
|
927
|
+
onClickedOutside() {
|
|
928
|
+
if (this.closeOnOutsideClick) {
|
|
929
|
+
this.closeDropdown(DropdownChangeReason.OutsideClick);
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
onAnchorClick() {
|
|
933
|
+
if (this._trigger === DropdownTrigger.Click) {
|
|
934
|
+
this.toggleDropdown(DropdownChangeReason.AnchorClick);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
isAnchorEventPath(path) {
|
|
938
|
+
if (this._anchorElement && path.includes(this._anchorElement)) {
|
|
939
|
+
return true;
|
|
940
|
+
}
|
|
941
|
+
if (this._anchorSlot && path.includes(this._anchorSlot)) {
|
|
942
|
+
return true;
|
|
943
|
+
}
|
|
944
|
+
const anchorPart = this.shadowRoot?.querySelector('[part="anchor"]');
|
|
945
|
+
return Boolean(anchorPart && path.includes(anchorPart));
|
|
946
|
+
}
|
|
947
|
+
onAnchorMouseEnter() {
|
|
948
|
+
if (this._trigger === DropdownTrigger.Hover) {
|
|
949
|
+
this.clearHoverTimeout();
|
|
950
|
+
this._hoverTimeout = setTimeout(() => {
|
|
951
|
+
this.openDropdown(DropdownChangeReason.AnchorHover);
|
|
952
|
+
}, 100);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
onAnchorMouseLeave() {
|
|
956
|
+
if (this._trigger === DropdownTrigger.Hover) {
|
|
957
|
+
this.clearHoverTimeout();
|
|
958
|
+
this._hoverTimeout = setTimeout(() => {
|
|
959
|
+
this.closeDropdown(DropdownChangeReason.AnchorHover);
|
|
960
|
+
}, 100);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
onAnchorFocusIn() {
|
|
964
|
+
if (this._trigger === DropdownTrigger.Focus) {
|
|
965
|
+
this.clearFocusTimeout();
|
|
966
|
+
this.openDropdown(DropdownChangeReason.AnchorFocus);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
onAnchorFocusOut() {
|
|
970
|
+
if (this._trigger === DropdownTrigger.Focus) {
|
|
971
|
+
this._focusTimeout = setTimeout(() => {
|
|
972
|
+
// Only close if focus moved outside the dropdown
|
|
973
|
+
const activeElement = document.activeElement;
|
|
974
|
+
if (activeElement && !this.contains(activeElement)) {
|
|
975
|
+
this.closeDropdown(DropdownChangeReason.AnchorFocus);
|
|
976
|
+
}
|
|
977
|
+
}, 100);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
onPanelMouseEnter() {
|
|
981
|
+
if (this._trigger === DropdownTrigger.Hover) {
|
|
982
|
+
this.clearHoverTimeout();
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
onPanelMouseLeave() {
|
|
986
|
+
if (this._trigger === DropdownTrigger.Hover) {
|
|
987
|
+
this._hoverTimeout = setTimeout(() => {
|
|
988
|
+
this.closeDropdown(DropdownChangeReason.AnchorHover);
|
|
989
|
+
}, 100);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
onPanelClick(event) {
|
|
993
|
+
if (this._closeOnSelect) {
|
|
994
|
+
const path = event.composedPath();
|
|
995
|
+
const selectable = path.find((node) => {
|
|
996
|
+
if (!(node instanceof HTMLElement)) {
|
|
997
|
+
return false;
|
|
998
|
+
}
|
|
999
|
+
// Check for Mosaic selection events or selectable markers
|
|
1000
|
+
return node.hasAttribute('selectable') ||
|
|
1001
|
+
node.hasAttribute('force-close') ||
|
|
1002
|
+
node.tagName?.toLowerCase().includes('menu-item') ||
|
|
1003
|
+
node.getAttribute('role') === 'menuitem' ||
|
|
1004
|
+
node.getAttribute('role') === 'option';
|
|
1005
|
+
});
|
|
1006
|
+
if (selectable) {
|
|
1007
|
+
this.closeDropdown(DropdownChangeReason.Selection);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
onPanelKeydown(event) {
|
|
1012
|
+
if (event.key === 'Escape' && this._closeOnEscape) {
|
|
1013
|
+
event.preventDefault();
|
|
1014
|
+
event.stopPropagation();
|
|
1015
|
+
this.closeDropdown(DropdownChangeReason.Escape);
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
showPanel() {
|
|
1019
|
+
if (!this._panelElement) {
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
const previousVisibility = this._panelElement.style.getPropertyValue('visibility');
|
|
1023
|
+
this._panelElement.style.setProperty('visibility', 'hidden');
|
|
1024
|
+
this.showNativePopover();
|
|
1025
|
+
this.startPositioning();
|
|
1026
|
+
if (previousVisibility) {
|
|
1027
|
+
this._panelElement.style.setProperty('visibility', previousVisibility);
|
|
1028
|
+
}
|
|
1029
|
+
else {
|
|
1030
|
+
this._panelElement.style.removeProperty('visibility');
|
|
1031
|
+
}
|
|
1032
|
+
// Play enter animation
|
|
1033
|
+
const enterAnimation = this.enter ?? fadeIn;
|
|
1034
|
+
if (enterAnimation) {
|
|
1035
|
+
void this._animationPlayer.stopAll(this._panelElement).then(() => {
|
|
1036
|
+
void this._animationPlayer.play(this._panelElement, enterAnimation);
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
showNativePopover() {
|
|
1041
|
+
if (!this._panelElement) {
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
try {
|
|
1045
|
+
if (typeof this._panelElement.showPopover === 'function' && !this._panelElement.matches(':popover-open')) {
|
|
1046
|
+
this._panelElement.showPopover();
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
catch (_e) {
|
|
1050
|
+
// Fallback: just make visible via style
|
|
1051
|
+
this._panelElement.style.removeProperty('display');
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
async hidePanel() {
|
|
1055
|
+
if (!this._panelElement) {
|
|
1056
|
+
this.stopPositioning();
|
|
1057
|
+
this._isVisible = false;
|
|
1058
|
+
this.requestUpdate('isVisible');
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
// Play exit animation, then hide
|
|
1062
|
+
const exitAnimation = this.exit ?? fadeOut;
|
|
1063
|
+
if (exitAnimation) {
|
|
1064
|
+
await this._animationPlayer.stopAll(this._panelElement);
|
|
1065
|
+
await this._animationPlayer.play(this._panelElement, exitAnimation);
|
|
1066
|
+
this.hideNativePopover();
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
this.hideNativePopover();
|
|
1070
|
+
}
|
|
1071
|
+
this.stopPositioning();
|
|
1072
|
+
this._isVisible = false;
|
|
1073
|
+
this.requestUpdate('isVisible');
|
|
1074
|
+
}
|
|
1075
|
+
hideNativePopover() {
|
|
1076
|
+
if (!this._panelElement) {
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
try {
|
|
1080
|
+
if (typeof this._panelElement.hidePopover === 'function') {
|
|
1081
|
+
this._panelElement.hidePopover();
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
catch (_e) {
|
|
1085
|
+
// Fallback: hide via style
|
|
1086
|
+
this._panelElement.style.display = 'none';
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
startPositioning() {
|
|
1090
|
+
if (!this._panelElement || !this._anchorElement) {
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
this.stopPositioning();
|
|
1094
|
+
this.applyPositioning();
|
|
1095
|
+
this._positioningCleanup = autoUpdate(this._anchorElement, this._panelElement, () => {
|
|
1096
|
+
this.applyPositioning();
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
stopPositioning() {
|
|
1100
|
+
if (this._positioningCleanup) {
|
|
1101
|
+
this._positioningCleanup();
|
|
1102
|
+
this._positioningCleanup = null;
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
applyPositioning() {
|
|
1106
|
+
if (!this._panelElement || !this._anchorElement) {
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
const panel = this._panelElement;
|
|
1110
|
+
const anchor = this._anchorElement;
|
|
1111
|
+
const getOffsetParent = this.strategy === Strategy.Absolute
|
|
1112
|
+
? (element) => platform.getOffsetParent(element)
|
|
1113
|
+
: platform.getOffsetParent;
|
|
1114
|
+
panel.style.setProperty('position', this.strategy);
|
|
1115
|
+
panel.style.setProperty('right', 'auto');
|
|
1116
|
+
panel.style.setProperty('bottom', 'auto');
|
|
1117
|
+
panel.style.removeProperty('position-anchor');
|
|
1118
|
+
panel.style.removeProperty('position-area');
|
|
1119
|
+
this.applyDimensions();
|
|
1120
|
+
void computePosition(anchor, panel, {
|
|
1121
|
+
placement: this.placement,
|
|
1122
|
+
strategy: this.strategy,
|
|
1123
|
+
middleware: [
|
|
1124
|
+
floatingOffset({
|
|
1125
|
+
mainAxis: this.offset,
|
|
1126
|
+
crossAxis: this.skidding
|
|
1127
|
+
}),
|
|
1128
|
+
flip(),
|
|
1129
|
+
shift()
|
|
1130
|
+
],
|
|
1131
|
+
platform: {
|
|
1132
|
+
...platform,
|
|
1133
|
+
getOffsetParent
|
|
1134
|
+
}
|
|
1135
|
+
}).then(({ x, y }) => {
|
|
1136
|
+
panel.style.setProperty('left', `${x}px`);
|
|
1137
|
+
panel.style.setProperty('top', `${y}px`);
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
applyDimensions() {
|
|
1141
|
+
if (!this._panelElement) {
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
const panel = this._panelElement;
|
|
1145
|
+
const toCssString = (value) => {
|
|
1146
|
+
return typeof value === 'number' ? `${value}px` : String(value);
|
|
1147
|
+
};
|
|
1148
|
+
// Apply max-height
|
|
1149
|
+
if (this.maxHeight) {
|
|
1150
|
+
panel.style.setProperty('max-height', toCssString(this.maxHeight));
|
|
1151
|
+
panel.style.setProperty('overflow-y', 'auto');
|
|
1152
|
+
}
|
|
1153
|
+
// Apply fixed height
|
|
1154
|
+
if (this.height && this.height !== 'auto') {
|
|
1155
|
+
panel.style.setProperty('height', toCssString(this.height));
|
|
1156
|
+
}
|
|
1157
|
+
else {
|
|
1158
|
+
panel.style.removeProperty('height');
|
|
1159
|
+
}
|
|
1160
|
+
// Apply fixed width
|
|
1161
|
+
if (this.width && this.width !== 'auto') {
|
|
1162
|
+
panel.style.setProperty('width', toCssString(this.width));
|
|
1163
|
+
}
|
|
1164
|
+
else if (!this._matchAnchorWidth) {
|
|
1165
|
+
panel.style.removeProperty('width');
|
|
1166
|
+
}
|
|
1167
|
+
// Apply max-width
|
|
1168
|
+
if (this.maxWidth && this.maxWidth !== 'auto') {
|
|
1169
|
+
panel.style.setProperty('max-width', toCssString(this.maxWidth));
|
|
1170
|
+
}
|
|
1171
|
+
else {
|
|
1172
|
+
panel.style.removeProperty('max-width');
|
|
1173
|
+
}
|
|
1174
|
+
// Apply match-anchor-width
|
|
1175
|
+
if (this._matchAnchorWidth && this._anchorElement) {
|
|
1176
|
+
const anchorRect = this._anchorElement.getBoundingClientRect();
|
|
1177
|
+
panel.style.setProperty('width', `${anchorRect.width}px`);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
applyAriaAttributes() {
|
|
1181
|
+
if (!this._anchorElement) {
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
const anchor = this._anchorElement;
|
|
1185
|
+
// Apply hasPopup if set
|
|
1186
|
+
if (this._hasPopup) {
|
|
1187
|
+
anchor.setAttribute('aria-haspopup', this._hasPopup);
|
|
1188
|
+
}
|
|
1189
|
+
// Apply aria-expanded
|
|
1190
|
+
anchor.setAttribute('aria-expanded', this.open ? 'true' : 'false');
|
|
1191
|
+
// Apply aria-controls if panel has an ID
|
|
1192
|
+
if (this._panelElement) {
|
|
1193
|
+
anchor.setAttribute('aria-controls', this._panelId);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
setupPanelListeners() {
|
|
1197
|
+
if (!this._panelElement) {
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
// Panel click for close-on-select
|
|
1201
|
+
this._panelClickSubscription?.dispose();
|
|
1202
|
+
this._panelClickSubscription = on(this._panelElement, 'click', (event) => {
|
|
1203
|
+
this.onPanelClick(event);
|
|
1204
|
+
});
|
|
1205
|
+
// Panel keydown for escape
|
|
1206
|
+
this._panelKeydownSubscription?.dispose();
|
|
1207
|
+
this._panelKeydownSubscription = on(this._panelElement, 'keydown', (event) => {
|
|
1208
|
+
this.onPanelKeydown(event);
|
|
1209
|
+
});
|
|
1210
|
+
// Panel hover for hover trigger
|
|
1211
|
+
this._panelMouseEnterSubscription?.dispose();
|
|
1212
|
+
this._panelMouseEnterSubscription = on(this._panelElement, 'mouseenter', () => this.onPanelMouseEnter());
|
|
1213
|
+
this._panelMouseLeaveSubscription?.dispose();
|
|
1214
|
+
this._panelMouseLeaveSubscription = on(this._panelElement, 'mouseleave', () => this.onPanelMouseLeave());
|
|
1215
|
+
}
|
|
1216
|
+
setupAnchorListeners() {
|
|
1217
|
+
const anchorPart = this.shadowRoot?.querySelector('[part="anchor"]');
|
|
1218
|
+
if (!anchorPart) {
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
this._anchorMouseEnterSubscription?.dispose();
|
|
1222
|
+
this._anchorMouseEnterSubscription = on(anchorPart, 'mouseenter', () => this.onAnchorMouseEnter());
|
|
1223
|
+
this._anchorMouseLeaveSubscription?.dispose();
|
|
1224
|
+
this._anchorMouseLeaveSubscription = on(anchorPart, 'mouseleave', () => this.onAnchorMouseLeave());
|
|
1225
|
+
this._anchorFocusInSubscription?.dispose();
|
|
1226
|
+
this._anchorFocusInSubscription = on(anchorPart, 'focusin', () => this.onAnchorFocusIn());
|
|
1227
|
+
this._anchorFocusOutSubscription?.dispose();
|
|
1228
|
+
this._anchorFocusOutSubscription = on(anchorPart, 'focusout', () => this.onAnchorFocusOut());
|
|
1229
|
+
}
|
|
1230
|
+
clearHoverTimeout() {
|
|
1231
|
+
if (this._hoverTimeout !== null) {
|
|
1232
|
+
clearTimeout(this._hoverTimeout);
|
|
1233
|
+
this._hoverTimeout = null;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
clearFocusTimeout() {
|
|
1237
|
+
if (this._focusTimeout !== null) {
|
|
1238
|
+
clearTimeout(this._focusTimeout);
|
|
1239
|
+
this._focusTimeout = null;
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
};
|
|
1243
|
+
__decorate([
|
|
1244
|
+
Attribute({ type: Placement }),
|
|
1245
|
+
__metadata("design:type", String),
|
|
1246
|
+
__metadata("design:paramtypes", [String])
|
|
1247
|
+
], DropdownElement.prototype, "dropDownPlacement", null);
|
|
1248
|
+
__decorate([
|
|
1249
|
+
Attribute({ type: Strategy }),
|
|
1250
|
+
__metadata("design:type", String),
|
|
1251
|
+
__metadata("design:paramtypes", [String])
|
|
1252
|
+
], DropdownElement.prototype, "dropDownStrategy", null);
|
|
1253
|
+
__decorate([
|
|
1254
|
+
Attribute({ type: Number }),
|
|
1255
|
+
__metadata("design:type", Number),
|
|
1256
|
+
__metadata("design:paramtypes", [Number])
|
|
1257
|
+
], DropdownElement.prototype, "dropDownDistance", null);
|
|
1258
|
+
__decorate([
|
|
1259
|
+
Attribute({ type: Number }),
|
|
1260
|
+
__metadata("design:type", Number),
|
|
1261
|
+
__metadata("design:paramtypes", [Number])
|
|
1262
|
+
], DropdownElement.prototype, "dropDownSkidding", null);
|
|
1263
|
+
__decorate([
|
|
1264
|
+
Attribute({
|
|
1265
|
+
type: Boolean,
|
|
1266
|
+
useDefault: true
|
|
1267
|
+
}),
|
|
1268
|
+
__metadata("design:type", Boolean),
|
|
1269
|
+
__metadata("design:paramtypes", [Boolean])
|
|
1270
|
+
], DropdownElement.prototype, "dropDownStaysOpen", null);
|
|
1271
|
+
__decorate([
|
|
1272
|
+
Attribute({ type: String }),
|
|
1273
|
+
__metadata("design:type", Object),
|
|
1274
|
+
__metadata("design:paramtypes", [Object])
|
|
1275
|
+
], DropdownElement.prototype, "dropDownMaxHeight", null);
|
|
1276
|
+
__decorate([
|
|
1277
|
+
Attribute({ type: String }),
|
|
1278
|
+
__metadata("design:type", Object),
|
|
1279
|
+
__metadata("design:paramtypes", [Object])
|
|
1280
|
+
], DropdownElement.prototype, "dropDownHeight", null);
|
|
1281
|
+
__decorate([
|
|
1282
|
+
Attribute({ type: String }),
|
|
1283
|
+
__metadata("design:type", Object),
|
|
1284
|
+
__metadata("design:paramtypes", [Object])
|
|
1285
|
+
], DropdownElement.prototype, "dropDownWidth", null);
|
|
1286
|
+
__decorate([
|
|
1287
|
+
Attribute({ type: String }),
|
|
1288
|
+
__metadata("design:type", Object),
|
|
1289
|
+
__metadata("design:paramtypes", [Object])
|
|
1290
|
+
], DropdownElement.prototype, "dropDownMaxWidth", null);
|
|
1291
|
+
__decorate([
|
|
1292
|
+
Attribute({
|
|
1293
|
+
type: Boolean,
|
|
1294
|
+
useDefault: true
|
|
1295
|
+
}),
|
|
1296
|
+
__metadata("design:type", Boolean),
|
|
1297
|
+
__metadata("design:paramtypes", [Boolean])
|
|
1298
|
+
], DropdownElement.prototype, "isDropDownOpen", null);
|
|
1299
|
+
__decorate([
|
|
1300
|
+
Attribute({ type: Placement }),
|
|
1301
|
+
__metadata("design:type", String),
|
|
1302
|
+
__metadata("design:paramtypes", [String])
|
|
1303
|
+
], DropdownElement.prototype, "placement", null);
|
|
1304
|
+
__decorate([
|
|
1305
|
+
Attribute({ type: Strategy }),
|
|
1306
|
+
__metadata("design:type", String),
|
|
1307
|
+
__metadata("design:paramtypes", [String])
|
|
1308
|
+
], DropdownElement.prototype, "strategy", null);
|
|
1309
|
+
__decorate([
|
|
1310
|
+
Attribute({ type: Number }),
|
|
1311
|
+
__metadata("design:type", Number),
|
|
1312
|
+
__metadata("design:paramtypes", [Number])
|
|
1313
|
+
], DropdownElement.prototype, "offset", null);
|
|
1314
|
+
__decorate([
|
|
1315
|
+
Attribute({ type: Number }),
|
|
1316
|
+
__metadata("design:type", Number),
|
|
1317
|
+
__metadata("design:paramtypes", [Number])
|
|
1318
|
+
], DropdownElement.prototype, "skidding", null);
|
|
1319
|
+
__decorate([
|
|
1320
|
+
Attribute({
|
|
1321
|
+
type: Boolean,
|
|
1322
|
+
useDefault: true
|
|
1323
|
+
}),
|
|
1324
|
+
__metadata("design:type", Boolean),
|
|
1325
|
+
__metadata("design:paramtypes", [Boolean])
|
|
1326
|
+
], DropdownElement.prototype, "open", null);
|
|
1327
|
+
__decorate([
|
|
1328
|
+
Attribute({ type: DropdownTrigger }),
|
|
1329
|
+
__metadata("design:type", String),
|
|
1330
|
+
__metadata("design:paramtypes", [String])
|
|
1331
|
+
], DropdownElement.prototype, "trigger", null);
|
|
1332
|
+
__decorate([
|
|
1333
|
+
Attribute({
|
|
1334
|
+
type: Boolean,
|
|
1335
|
+
useDefault: true
|
|
1336
|
+
}),
|
|
1337
|
+
__metadata("design:type", Boolean),
|
|
1338
|
+
__metadata("design:paramtypes", [Boolean])
|
|
1339
|
+
], DropdownElement.prototype, "closeOnOutsideClick", null);
|
|
1340
|
+
__decorate([
|
|
1341
|
+
Attribute({
|
|
1342
|
+
type: Boolean,
|
|
1343
|
+
useDefault: true
|
|
1344
|
+
}),
|
|
1345
|
+
__metadata("design:type", Boolean),
|
|
1346
|
+
__metadata("design:paramtypes", [Boolean])
|
|
1347
|
+
], DropdownElement.prototype, "closeOnEscape", null);
|
|
1348
|
+
__decorate([
|
|
1349
|
+
Attribute({
|
|
1350
|
+
type: Boolean,
|
|
1351
|
+
useDefault: true
|
|
1352
|
+
}),
|
|
1353
|
+
__metadata("design:type", Boolean),
|
|
1354
|
+
__metadata("design:paramtypes", [Boolean])
|
|
1355
|
+
], DropdownElement.prototype, "closeOnSelect", null);
|
|
1356
|
+
__decorate([
|
|
1357
|
+
Attribute({
|
|
1358
|
+
type: Boolean,
|
|
1359
|
+
useDefault: true
|
|
1360
|
+
}),
|
|
1361
|
+
__metadata("design:type", Boolean),
|
|
1362
|
+
__metadata("design:paramtypes", [Boolean])
|
|
1363
|
+
], DropdownElement.prototype, "restoreFocus", null);
|
|
1364
|
+
__decorate([
|
|
1365
|
+
Attribute({ type: String }),
|
|
1366
|
+
__metadata("design:type", Object),
|
|
1367
|
+
__metadata("design:paramtypes", [Object])
|
|
1368
|
+
], DropdownElement.prototype, "hasPopup", null);
|
|
1369
|
+
__decorate([
|
|
1370
|
+
Attribute({
|
|
1371
|
+
type: Boolean,
|
|
1372
|
+
useDefault: true
|
|
1373
|
+
}),
|
|
1374
|
+
__metadata("design:type", Boolean),
|
|
1375
|
+
__metadata("design:paramtypes", [Boolean])
|
|
1376
|
+
], DropdownElement.prototype, "matchAnchorWidth", null);
|
|
1377
|
+
__decorate([
|
|
1378
|
+
Attribute({ type: String }),
|
|
1379
|
+
__metadata("design:type", Object),
|
|
1380
|
+
__metadata("design:paramtypes", [Object])
|
|
1381
|
+
], DropdownElement.prototype, "maxHeight", null);
|
|
1382
|
+
__decorate([
|
|
1383
|
+
Attribute({ type: String }),
|
|
1384
|
+
__metadata("design:type", Object),
|
|
1385
|
+
__metadata("design:paramtypes", [Object])
|
|
1386
|
+
], DropdownElement.prototype, "height", null);
|
|
1387
|
+
__decorate([
|
|
1388
|
+
Attribute({ type: String }),
|
|
1389
|
+
__metadata("design:type", Object),
|
|
1390
|
+
__metadata("design:paramtypes", [Object])
|
|
1391
|
+
], DropdownElement.prototype, "width", null);
|
|
1392
|
+
__decorate([
|
|
1393
|
+
Attribute({ type: String }),
|
|
1394
|
+
__metadata("design:type", Object),
|
|
1395
|
+
__metadata("design:paramtypes", [Object])
|
|
1396
|
+
], DropdownElement.prototype, "maxWidth", null);
|
|
1397
|
+
__decorate([
|
|
1398
|
+
Emit({ eventName: 'openChanged' }),
|
|
1399
|
+
__metadata("design:type", Object),
|
|
1400
|
+
__metadata("design:paramtypes", [])
|
|
1401
|
+
], DropdownElement.prototype, "openChanged", null);
|
|
1402
|
+
__decorate([
|
|
1403
|
+
Watch('open', { waitUntilFirstUpdate: true }),
|
|
1404
|
+
__metadata("design:type", Function),
|
|
1405
|
+
__metadata("design:paramtypes", [Boolean, Boolean]),
|
|
1406
|
+
__metadata("design:returntype", void 0)
|
|
1407
|
+
], DropdownElement.prototype, "onOpenPropertyChanged", null);
|
|
1408
|
+
__decorate([
|
|
1409
|
+
Watch('disabled', { waitUntilFirstUpdate: true }),
|
|
1410
|
+
__metadata("design:type", Function),
|
|
1411
|
+
__metadata("design:paramtypes", [Boolean, Boolean]),
|
|
1412
|
+
__metadata("design:returntype", void 0)
|
|
1413
|
+
], DropdownElement.prototype, "onDisabledPropertyChanged", null);
|
|
1414
|
+
__decorate([
|
|
1415
|
+
Watch('trigger', { waitUntilFirstUpdate: true }),
|
|
1416
|
+
__metadata("design:type", Function),
|
|
1417
|
+
__metadata("design:paramtypes", [String, String]),
|
|
1418
|
+
__metadata("design:returntype", void 0)
|
|
1419
|
+
], DropdownElement.prototype, "onTriggerPropertyChanged", null);
|
|
1420
|
+
__decorate([
|
|
1421
|
+
Watch('placement', { waitUntilFirstUpdate: true }),
|
|
1422
|
+
Watch('strategy', { waitUntilFirstUpdate: true }),
|
|
1423
|
+
Watch('offset', { waitUntilFirstUpdate: true }),
|
|
1424
|
+
Watch('skidding', { waitUntilFirstUpdate: true }),
|
|
1425
|
+
Watch('matchAnchorWidth', { waitUntilFirstUpdate: true }),
|
|
1426
|
+
Watch('maxHeight', { waitUntilFirstUpdate: true }),
|
|
1427
|
+
Watch('height', { waitUntilFirstUpdate: true }),
|
|
1428
|
+
Watch('width', { waitUntilFirstUpdate: true }),
|
|
1429
|
+
Watch('maxWidth', { waitUntilFirstUpdate: true }),
|
|
1430
|
+
__metadata("design:type", Function),
|
|
1431
|
+
__metadata("design:paramtypes", []),
|
|
1432
|
+
__metadata("design:returntype", void 0)
|
|
1433
|
+
], DropdownElement.prototype, "onPositioningPropertyChanged", null);
|
|
1434
|
+
DropdownElement = DropdownElement_1 = __decorate([
|
|
1435
|
+
Component({
|
|
1436
|
+
selector: 'mosaik-dropdown',
|
|
1437
|
+
template: dropdownElementTemplate,
|
|
1438
|
+
themes: {
|
|
1439
|
+
joy: dropdownElementJoyStyle,
|
|
1440
|
+
memphis: dropdownElementMemphisStyle,
|
|
1441
|
+
cosmopolitan: dropdownElementCosmopolitanStyle
|
|
1442
|
+
},
|
|
1443
|
+
options: {
|
|
1444
|
+
mode: 'open'
|
|
1445
|
+
}
|
|
1446
|
+
}),
|
|
1447
|
+
__metadata("design:paramtypes", [])
|
|
1448
|
+
], DropdownElement);
|
|
1449
|
+
export { DropdownElement };
|
|
1450
|
+
//# sourceMappingURL=DropdownElement.js.map
|