@govtechsg/sgds-web-component 3.26.1 → 3.27.0-rc.1
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/base/dropdown-list-element.js +9 -2
- package/base/dropdown-list-element.js.map +1 -1
- package/base/nav-element.d.ts +64 -0
- package/base/nav-element.js +263 -0
- package/base/nav-element.js.map +1 -0
- package/base/nav-profile-element.d.ts +47 -0
- package/base/nav-profile-element.js +191 -0
- package/base/nav-profile-element.js.map +1 -0
- package/base/nav-profile.js +6 -0
- package/base/nav-profile.js.map +1 -0
- package/components/Appnav/appnav-context.d.ts +6 -0
- package/components/Appnav/appnav-context.js +7 -0
- package/components/Appnav/appnav-context.js.map +1 -0
- package/components/Appnav/appnav.js +6 -0
- package/components/Appnav/appnav.js.map +1 -0
- package/components/Appnav/index.d.ts +9 -0
- package/components/Appnav/index.js +8 -0
- package/components/Appnav/index.js.map +1 -0
- package/components/Appnav/index.umd.min.js +2542 -0
- package/components/Appnav/index.umd.min.js.map +1 -0
- package/components/Appnav/sgds-appnav-profile.d.ts +17 -0
- package/components/Appnav/sgds-appnav-profile.js +31 -0
- package/components/Appnav/sgds-appnav-profile.js.map +1 -0
- package/components/Appnav/sgds-appnav.d.ts +44 -0
- package/components/Appnav/sgds-appnav.js +183 -0
- package/components/Appnav/sgds-appnav.js.map +1 -0
- package/components/Breadcrumb/index.umd.min.js +25 -25
- package/components/Breadcrumb/index.umd.min.js.map +1 -1
- package/components/Checkbox/index.umd.min.js +233 -233
- package/components/Checkbox/index.umd.min.js.map +1 -1
- package/components/Checkbox/sgds-checkbox.d.ts +1 -0
- package/components/Checkbox/sgds-checkbox.js +6 -1
- package/components/Checkbox/sgds-checkbox.js.map +1 -1
- package/components/ComboBox/index.umd.min.js +254 -254
- package/components/ComboBox/index.umd.min.js.map +1 -1
- package/components/DataTable/data-table.js +6 -0
- package/components/DataTable/data-table.js.map +1 -0
- package/components/DataTable/index.d.ts +12 -0
- package/components/DataTable/index.js +11 -0
- package/components/DataTable/index.js.map +1 -0
- package/components/DataTable/index.umd.min.js +2649 -0
- package/components/DataTable/index.umd.min.js.map +1 -0
- package/components/DataTable/sgds-data-table-cell.d.ts +15 -0
- package/components/DataTable/sgds-data-table-cell.js +32 -0
- package/components/DataTable/sgds-data-table-cell.js.map +1 -0
- package/components/DataTable/sgds-data-table-head.d.ts +28 -0
- package/components/DataTable/sgds-data-table-head.js +69 -0
- package/components/DataTable/sgds-data-table-head.js.map +1 -0
- package/components/DataTable/sgds-data-table-row.d.ts +76 -0
- package/components/DataTable/sgds-data-table-row.js +333 -0
- package/components/DataTable/sgds-data-table-row.js.map +1 -0
- package/components/DataTable/sgds-data-table.d.ts +84 -0
- package/components/DataTable/sgds-data-table.js +438 -0
- package/components/DataTable/sgds-data-table.js.map +1 -0
- package/components/Datepicker/index.umd.min.js +86 -86
- package/components/Datepicker/index.umd.min.js.map +1 -1
- package/components/Dropdown/dropdown-item.js +1 -1
- package/components/Dropdown/index.umd.min.js +5 -5
- package/components/Dropdown/index.umd.min.js.map +1 -1
- package/components/Dropdown/sgds-dropdown-item.d.ts +2 -0
- package/components/Dropdown/sgds-dropdown-item.js +8 -2
- package/components/Dropdown/sgds-dropdown-item.js.map +1 -1
- package/components/Input/index.umd.min.js +2 -2
- package/components/Input/index.umd.min.js.map +1 -1
- package/components/Input/input.js +1 -1
- package/components/Mainnav/index.d.ts +2 -0
- package/components/Mainnav/index.js +2 -0
- package/components/Mainnav/index.js.map +1 -1
- package/components/Mainnav/index.umd.min.js +339 -286
- package/components/Mainnav/index.umd.min.js.map +1 -1
- package/components/Mainnav/mainnav-dropdown.js +1 -1
- package/components/Mainnav/mainnav-item.js +1 -1
- package/components/Mainnav/mainnav.js +1 -1
- package/components/Mainnav/sgds-mainnav-profile.d.ts +15 -0
- package/components/Mainnav/sgds-mainnav-profile.js +29 -0
- package/components/Mainnav/sgds-mainnav-profile.js.map +1 -0
- package/components/Mainnav/sgds-mainnav.d.ts +8 -51
- package/components/Mainnav/sgds-mainnav.js +40 -238
- package/components/Mainnav/sgds-mainnav.js.map +1 -1
- package/components/OverflowMenu/index.umd.min.js +25 -25
- package/components/OverflowMenu/index.umd.min.js.map +1 -1
- package/components/QuantityToggle/index.umd.min.js +1 -1
- package/components/QuantityToggle/index.umd.min.js.map +1 -1
- package/components/Select/index.umd.min.js +1 -1
- package/components/Select/index.umd.min.js.map +1 -1
- package/components/Tab/index.umd.min.js +1 -1
- package/components/Tab/index.umd.min.js.map +1 -1
- package/components/Tab/tab-panel.js +1 -1
- package/components/Textarea/index.umd.min.js +1 -1
- package/components/index.d.ts +7 -0
- package/components/index.js +7 -0
- package/components/index.js.map +1 -1
- package/components/index.umd.min.js +851 -662
- package/components/index.umd.min.js.map +1 -1
- package/css/fouc.css +7 -0
- package/custom-elements.json +11304 -7831
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/index.umd.min.js +705 -511
- package/index.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/react/appnav/index.cjs.js +45 -0
- package/react/appnav/index.cjs.js.map +1 -0
- package/react/appnav/index.d.ts +4 -0
- package/react/appnav/index.js +21 -0
- package/react/appnav/index.js.map +1 -0
- package/react/appnav-profile/index.cjs.js +40 -0
- package/react/appnav-profile/index.cjs.js.map +1 -0
- package/react/appnav-profile/index.d.ts +4 -0
- package/react/appnav-profile/index.js +16 -0
- package/react/appnav-profile/index.js.map +1 -0
- package/react/base/dropdown-list-element.cjs.js +9 -2
- package/react/base/dropdown-list-element.cjs.js.map +1 -1
- package/react/base/dropdown-list-element.js +9 -2
- package/react/base/dropdown-list-element.js.map +1 -1
- package/react/base/nav-element.cjs.js +268 -0
- package/react/base/nav-element.cjs.js.map +1 -0
- package/react/base/nav-element.js +264 -0
- package/react/base/nav-element.js.map +1 -0
- package/react/base/nav-profile-element.cjs.js +196 -0
- package/react/base/nav-profile-element.cjs.js.map +1 -0
- package/react/base/nav-profile-element.js +192 -0
- package/react/base/nav-profile-element.js.map +1 -0
- package/react/base/nav-profile.cjs.js +11 -0
- package/react/base/nav-profile.cjs.js.map +1 -0
- package/react/base/nav-profile.js +7 -0
- package/react/base/nav-profile.js.map +1 -0
- package/react/components/Appnav/appnav-context.cjs.js +13 -0
- package/react/components/Appnav/appnav-context.cjs.js.map +1 -0
- package/react/components/Appnav/appnav-context.js +8 -0
- package/react/components/Appnav/appnav-context.js.map +1 -0
- package/react/components/Appnav/appnav.cjs.js +11 -0
- package/react/components/Appnav/appnav.cjs.js.map +1 -0
- package/react/components/Appnav/appnav.js +7 -0
- package/react/components/Appnav/appnav.js.map +1 -0
- package/react/components/Appnav/sgds-appnav-profile.cjs.js +37 -0
- package/react/components/Appnav/sgds-appnav-profile.cjs.js.map +1 -0
- package/react/components/Appnav/sgds-appnav-profile.js +32 -0
- package/react/components/Appnav/sgds-appnav-profile.js.map +1 -0
- package/react/components/Appnav/sgds-appnav.cjs.js +189 -0
- package/react/components/Appnav/sgds-appnav.cjs.js.map +1 -0
- package/react/components/Appnav/sgds-appnav.js +184 -0
- package/react/components/Appnav/sgds-appnav.js.map +1 -0
- package/react/components/Checkbox/sgds-checkbox.cjs.js +6 -1
- package/react/components/Checkbox/sgds-checkbox.cjs.js.map +1 -1
- package/react/components/Checkbox/sgds-checkbox.js +6 -1
- package/react/components/Checkbox/sgds-checkbox.js.map +1 -1
- package/react/components/DataTable/data-table.cjs.js +11 -0
- package/react/components/DataTable/data-table.cjs.js.map +1 -0
- package/react/components/DataTable/data-table.js +7 -0
- package/react/components/DataTable/data-table.js.map +1 -0
- package/react/components/DataTable/sgds-data-table-cell.cjs.js +38 -0
- package/react/components/DataTable/sgds-data-table-cell.cjs.js.map +1 -0
- package/react/components/DataTable/sgds-data-table-cell.js +33 -0
- package/react/components/DataTable/sgds-data-table-cell.js.map +1 -0
- package/react/components/DataTable/sgds-data-table-head.cjs.js +75 -0
- package/react/components/DataTable/sgds-data-table-head.cjs.js.map +1 -0
- package/react/components/DataTable/sgds-data-table-head.js +70 -0
- package/react/components/DataTable/sgds-data-table-head.js.map +1 -0
- package/react/components/DataTable/sgds-data-table-row.cjs.js +339 -0
- package/react/components/DataTable/sgds-data-table-row.cjs.js.map +1 -0
- package/react/components/DataTable/sgds-data-table-row.js +334 -0
- package/react/components/DataTable/sgds-data-table-row.js.map +1 -0
- package/react/components/DataTable/sgds-data-table.cjs.js +444 -0
- package/react/components/DataTable/sgds-data-table.cjs.js.map +1 -0
- package/react/components/DataTable/sgds-data-table.js +439 -0
- package/react/components/DataTable/sgds-data-table.js.map +1 -0
- package/react/components/Dropdown/dropdown-item.cjs.js +1 -1
- package/react/components/Dropdown/dropdown-item.js +1 -1
- package/react/components/Dropdown/sgds-dropdown-item.cjs.js +8 -2
- package/react/components/Dropdown/sgds-dropdown-item.cjs.js.map +1 -1
- package/react/components/Dropdown/sgds-dropdown-item.js +8 -2
- package/react/components/Dropdown/sgds-dropdown-item.js.map +1 -1
- package/react/components/Input/input.cjs.js +1 -1
- package/react/components/Input/input.js +1 -1
- package/react/components/Mainnav/mainnav-dropdown.cjs.js +1 -1
- package/react/components/Mainnav/mainnav-dropdown.js +1 -1
- package/react/components/Mainnav/mainnav-item.cjs.js +1 -1
- package/react/components/Mainnav/mainnav-item.js +1 -1
- package/react/components/Mainnav/mainnav.cjs.js +1 -1
- package/react/components/Mainnav/mainnav.js +1 -1
- package/react/components/Mainnav/sgds-mainnav-profile.cjs.js +35 -0
- package/react/components/Mainnav/sgds-mainnav-profile.cjs.js.map +1 -0
- package/react/components/Mainnav/sgds-mainnav-profile.js +30 -0
- package/react/components/Mainnav/sgds-mainnav-profile.js.map +1 -0
- package/react/components/Mainnav/sgds-mainnav.cjs.js +39 -237
- package/react/components/Mainnav/sgds-mainnav.cjs.js.map +1 -1
- package/react/components/Mainnav/sgds-mainnav.js +40 -238
- package/react/components/Mainnav/sgds-mainnav.js.map +1 -1
- package/react/components/Tab/tab-panel.cjs.js +1 -1
- package/react/components/Tab/tab-panel.js +1 -1
- package/react/data-table/index.cjs.js +44 -0
- package/react/data-table/index.cjs.js.map +1 -0
- package/react/data-table/index.d.ts +4 -0
- package/react/data-table/index.js +20 -0
- package/react/data-table/index.js.map +1 -0
- package/react/data-table-cell/index.cjs.js +40 -0
- package/react/data-table-cell/index.cjs.js.map +1 -0
- package/react/data-table-cell/index.d.ts +4 -0
- package/react/data-table-cell/index.js +16 -0
- package/react/data-table-cell/index.js.map +1 -0
- package/react/data-table-head/index.cjs.js +40 -0
- package/react/data-table-head/index.cjs.js.map +1 -0
- package/react/data-table-head/index.d.ts +4 -0
- package/react/data-table-head/index.js +16 -0
- package/react/data-table-head/index.js.map +1 -0
- package/react/data-table-row/index.cjs.js +45 -0
- package/react/data-table-row/index.cjs.js.map +1 -0
- package/react/data-table-row/index.d.ts +4 -0
- package/react/data-table-row/index.js +21 -0
- package/react/data-table-row/index.js.map +1 -0
- package/react/index.cjs.js +152 -138
- package/react/index.cjs.js.map +1 -1
- package/react/index.d.ts +7 -0
- package/react/index.js +7 -0
- package/react/index.js.map +1 -1
- package/react/mainnav-profile/index.cjs.js +40 -0
- package/react/mainnav-profile/index.cjs.js.map +1 -0
- package/react/mainnav-profile/index.d.ts +4 -0
- package/react/mainnav-profile/index.js +16 -0
- package/react/mainnav-profile/index.js.map +1 -0
- package/react/styles/form-text-control.cjs.js +1 -1
- package/react/styles/form-text-control.js +1 -1
- package/styles/form-text-control.js +1 -1
- package/themes/blue.css +11 -11
- package/themes/cyan.css +10 -10
- package/themes/gt/blue.css +11 -11
- package/themes/gt/cyan.css +10 -10
- package/themes/gt/magenta.css +11 -11
- package/themes/gt/pink.css +11 -11
- package/themes/gt/purple.css +11 -11
- package/themes/gt/red.css +11 -11
- package/themes/magenta.css +11 -11
- package/themes/pink.css +11 -11
- package/themes/purple.css +11 -11
- package/themes/red.css +11 -11
- package/themes/root.css +5 -0
- package/types/react.d.ts +146 -2
|
@@ -6,6 +6,7 @@ const TAB = "Tab";
|
|
|
6
6
|
const ARROW_DOWN = "ArrowDown";
|
|
7
7
|
const ARROW_UP = "ArrowUp";
|
|
8
8
|
const ENTER = "Enter";
|
|
9
|
+
const ESCAPE = "Escape";
|
|
9
10
|
/**
|
|
10
11
|
* @event sgds-select - Emitted when a dropdown item is selected. `event.detail.item` is the clicked `SgdsDropdownItem` element.
|
|
11
12
|
*/
|
|
@@ -83,6 +84,12 @@ class DropdownListElement extends DropdownElement {
|
|
|
83
84
|
this._setMenuItem(this.nextDropdownItemNo);
|
|
84
85
|
}
|
|
85
86
|
break;
|
|
87
|
+
case ESCAPE:
|
|
88
|
+
if (this.menuIsOpen) {
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
this.hideMenu();
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
86
93
|
case ENTER: {
|
|
87
94
|
const target = menuItems.find(item => e.composedPath().includes(item));
|
|
88
95
|
if (target) {
|
|
@@ -99,7 +106,7 @@ class DropdownListElement extends DropdownElement {
|
|
|
99
106
|
if (defaultSlot) {
|
|
100
107
|
const defaultSlotItems = (_a = this.shadowRoot.querySelector("slot#default")) === null || _a === void 0 ? void 0 : _a.assignedElements({
|
|
101
108
|
flatten: true
|
|
102
|
-
}).filter(el => !el.classList.contains("empty-menu") && !el.hasAttribute("hidden"));
|
|
109
|
+
}).filter(el => el.getAttribute("role") === "menuitem" && !el.classList.contains("empty-menu") && !el.hasAttribute("hidden"));
|
|
103
110
|
return defaultSlotItems;
|
|
104
111
|
}
|
|
105
112
|
// for case when there is no slot e.g. combobox
|
|
@@ -110,7 +117,7 @@ class DropdownListElement extends DropdownElement {
|
|
|
110
117
|
return [];
|
|
111
118
|
}
|
|
112
119
|
_getActiveMenuItems() {
|
|
113
|
-
return this._getMenuItems().filter(item => !item.disabled && !item.hidden);
|
|
120
|
+
return this._getMenuItems().filter(item => !item.disabled && !item.hidden && !item.readonly);
|
|
114
121
|
}
|
|
115
122
|
_setMenuItem(currentItemIdx) {
|
|
116
123
|
const items = this._getActiveMenuItems();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown-list-element.js","sources":["../../src/base/dropdown-list-element.ts"],"sourcesContent":["import { property, query, state } from \"lit/decorators.js\";\nimport { DropdownElement } from \"./dropdown-element\";\nimport { SgdsDropdownItem } from \"../components\";\nimport { PropertyValueMap } from \"lit\";\n\nconst TAB = \"Tab\";\nconst ARROW_DOWN = \"ArrowDown\";\nconst ARROW_UP = \"ArrowUp\";\nconst ENTER = \"Enter\";\n\n/**\n * @event sgds-select - Emitted when a dropdown item is selected. `event.detail.item` is the clicked `SgdsDropdownItem` element.\n */\nexport class DropdownListElement extends DropdownElement {\n static styles = DropdownElement.styles;\n\n /**@internal */\n @query(\"ul.dropdown-menu\")\n private menu: HTMLUListElement;\n\n /** @internal */\n @state()\n nextDropdownItemNo = 0;\n\n /** @internal */\n @state()\n prevDropdownItemNo = -1;\n\n @property({ type: Boolean, reflect: true })\n hidden = false;\n\n connectedCallback() {\n super.connectedCallback();\n this.addEventListener(\"sgds-hide\", this._resetMenu);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(\"sgds-hide\", this._resetMenu);\n }\n\n firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n this.addEventListener(\"keydown\", this._handleKeyboardMenuItemsEvent);\n }\n\n protected handleSelectSlot(e: KeyboardEvent | MouseEvent) {\n const items = this._getActiveMenuItems();\n\n const selectedItem = items.find(item => e.composedPath().includes(item));\n if (!selectedItem) return;\n\n const currentItemNo = items.indexOf(selectedItem);\n this.nextDropdownItemNo = currentItemNo + 1;\n this.prevDropdownItemNo = currentItemNo <= 0 ? items.length - 1 : currentItemNo - 1;\n\n /** Emitted event from SgdsDropdown element when a slot item is selected */\n if (!selectedItem.disabled) {\n this.emit(\"sgds-select\", { detail: { item: selectedItem } });\n if (this.close !== \"outside\") {\n this.hideMenu(); // <-- Use new API\n }\n }\n }\n\n private _resetMenu() {\n this.nextDropdownItemNo = 0;\n this.prevDropdownItemNo = -1;\n // reset the tabindex\n const items = this._getMenuItems();\n items.forEach(item => {\n const dropdownItem = item?.shadowRoot?.querySelector(\".dropdown-item\") as HTMLAnchorElement;\n dropdownItem && dropdownItem.removeAttribute(\"tabindex\");\n });\n }\n protected _handleKeyboardMenuItemsEvent(e: KeyboardEvent) {\n if (this.readonly) return;\n const menuItems = this._getActiveMenuItems();\n if (menuItems.length === 0) return;\n\n switch (e.key) {\n case ARROW_DOWN:\n e.preventDefault();\n this._setMenuItem(this.nextDropdownItemNo);\n break;\n case ARROW_UP:\n e.preventDefault();\n this._setMenuItem(this.prevDropdownItemNo);\n break;\n case TAB:\n if (!this.menuIsOpen) return;\n e.preventDefault();\n if (e.shiftKey) {\n this._setMenuItem(this.prevDropdownItemNo);\n } else {\n this._setMenuItem(this.nextDropdownItemNo);\n }\n break;\n case ENTER: {\n const target = menuItems.find(item => e.composedPath().includes(item));\n if (target) {\n this.handleSelectSlot(e);\n }\n break;\n }\n default:\n break;\n }\n }\n\n private _getMenuItems(): SgdsDropdownItem[] {\n const defaultSlot = this.shadowRoot.querySelector(\"slot#default\");\n // for case when default slot is used e.g. dropdown, mainnavdropdown\n if (defaultSlot) {\n const defaultSlotItems = (this.shadowRoot.querySelector(\"slot#default\") as HTMLSlotElement)\n ?.assignedElements({\n flatten: true\n })\n .filter(el => !el.classList.contains(\"empty-menu\") && !el.hasAttribute(\"hidden\")) as SgdsDropdownItem[];\n return defaultSlotItems;\n }\n // for case when there is no slot e.g. combobox\n if (this.menu?.hasChildNodes()) {\n const menuItems = Array.from(this.menu.children);\n return [...menuItems] as SgdsDropdownItem[];\n }\n\n return [];\n }\n\n private _getActiveMenuItems(): SgdsDropdownItem[] {\n return this._getMenuItems().filter(item => !item.disabled && !item.hidden);\n }\n private _setMenuItem(currentItemIdx: number) {\n const items = this._getActiveMenuItems();\n if (items.length === 0) return;\n\n // Use modulo for looping\n const idx = ((currentItemIdx % items.length) + items.length) % items.length;\n const activeItem = items[idx];\n this.emit(\"i-sgds-option-focus\", { detail: { option: activeItem } });\n this.nextDropdownItemNo = (idx + 1) % items.length;\n this.prevDropdownItemNo = (idx - 1 + items.length) % items.length;\n\n items.forEach(item => {\n const dropdownItem = item.shadowRoot.querySelector(\".dropdown-item\") as HTMLAnchorElement;\n dropdownItem.setAttribute(\"tabindex\", item === activeItem ? \"0\" : \"-1\");\n if (item === activeItem) dropdownItem.focus();\n });\n }\n}\n\nexport interface IDropdownListElement {\n item: SgdsDropdownItem;\n}\n"],"names":[],"mappings":";;;;AAKA,MAAM,GAAG,GAAG,KAAK,CAAC;AAClB,MAAM,UAAU,GAAG,WAAW,CAAC;AAC/B,MAAM,QAAQ,GAAG,SAAS,CAAC;AAC3B,MAAM,KAAK,GAAG,OAAO,CAAC;AAEtB;;AAEG;AACG,MAAO,mBAAoB,SAAQ,eAAe,CAAA;AAAxD,IAAA,WAAA,GAAA;;;QASE,IAAkB,CAAA,kBAAA,GAAG,CAAC,CAAC;;QAIvB,IAAkB,CAAA,kBAAA,GAAG,CAAC,CAAC,CAAC;QAGxB,IAAM,CAAA,MAAA,GAAG,KAAK,CAAC;KAyHhB;IAvHC,iBAAiB,GAAA;QACf,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;KACrD;IAED,oBAAoB,GAAA;QAClB,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;KACxD;AAED,IAAA,YAAY,CAAC,iBAAyC,EAAA;AACpD,QAAA,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;QACtC,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,6BAA6B,CAAC,CAAC;KACtE;AAES,IAAA,gBAAgB,CAAC,CAA6B,EAAA;AACtD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAEzC,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACzE,QAAA,IAAI,CAAC,YAAY;YAAE,OAAO;QAE1B,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;AAClD,QAAA,IAAI,CAAC,kBAAkB,GAAG,aAAa,GAAG,CAAC,CAAC;QAC5C,IAAI,CAAC,kBAAkB,GAAG,aAAa,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,aAAa,GAAG,CAAC,CAAC;;AAGpF,QAAA,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE;AAC1B,YAAA,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;AAC7D,YAAA,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE;AAC5B,gBAAA,IAAI,CAAC,QAAQ,EAAE,CAAC;aACjB;SACF;KACF;IAEO,UAAU,GAAA;AAChB,QAAA,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC;AAC5B,QAAA,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC;;AAE7B,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;AACnC,QAAA,KAAK,CAAC,OAAO,CAAC,IAAI,IAAG;;AACnB,YAAA,MAAM,YAAY,GAAG,CAAA,EAAA,GAAA,IAAI,aAAJ,IAAI,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAJ,IAAI,CAAE,UAAU,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,aAAa,CAAC,gBAAgB,CAAsB,CAAC;AAC5F,YAAA,YAAY,IAAI,YAAY,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;AAC3D,SAAC,CAAC,CAAC;KACJ;AACS,IAAA,6BAA6B,CAAC,CAAgB,EAAA;QACtD,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;AAC1B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;AAC7C,QAAA,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;AAEnC,QAAA,QAAQ,CAAC,CAAC,GAAG;AACX,YAAA,KAAK,UAAU;gBACb,CAAC,CAAC,cAAc,EAAE,CAAC;AACnB,gBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;gBAC3C,MAAM;AACR,YAAA,KAAK,QAAQ;gBACX,CAAC,CAAC,cAAc,EAAE,CAAC;AACnB,gBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;gBAC3C,MAAM;AACR,YAAA,KAAK,GAAG;gBACN,IAAI,CAAC,IAAI,CAAC,UAAU;oBAAE,OAAO;gBAC7B,CAAC,CAAC,cAAc,EAAE,CAAC;AACnB,gBAAA,IAAI,CAAC,CAAC,QAAQ,EAAE;AACd,oBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;iBAC5C;qBAAM;AACL,oBAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;iBAC5C;gBACD,MAAM;YACR,KAAK,KAAK,EAAE;gBACV,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvE,IAAI,MAAM,EAAE;AACV,oBAAA,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;iBAC1B;gBACD,MAAM;aACP;SAGF;KACF;IAEO,aAAa,GAAA;;QACnB,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;;QAElE,IAAI,WAAW,EAAE;AACf,YAAA,MAAM,gBAAgB,GAAG,CAAC,EAAA,GAAA,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,cAAc,CAAqB,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CACvF,gBAAgB,CAAC;AACjB,gBAAA,OAAO,EAAE,IAAI;aACd,CACA,CAAA,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAuB,CAAC;AAC1G,YAAA,OAAO,gBAAgB,CAAC;SACzB;;QAED,IAAI,CAAA,EAAA,GAAA,IAAI,CAAC,IAAI,0CAAE,aAAa,EAAE,EAAE;AAC9B,YAAA,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACjD,YAAA,OAAO,CAAC,GAAG,SAAS,CAAuB,CAAC;SAC7C;AAED,QAAA,OAAO,EAAE,CAAC;KACX;IAEO,mBAAmB,GAAA;QACzB,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;KAC5E;AACO,IAAA,YAAY,CAAC,cAAsB,EAAA;AACzC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;AACzC,QAAA,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;;AAG/B,QAAA,MAAM,GAAG,GAAG,CAAC,CAAC,cAAc,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;AAC5E,QAAA,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;AAC9B,QAAA,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;AACrE,QAAA,IAAI,CAAC,kBAAkB,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC;AACnD,QAAA,IAAI,CAAC,kBAAkB,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;AAElE,QAAA,KAAK,CAAC,OAAO,CAAC,IAAI,IAAG;YACnB,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,gBAAgB,CAAsB,CAAC;AAC1F,YAAA,YAAY,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,KAAK,UAAU,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC;YACxE,IAAI,IAAI,KAAK,UAAU;gBAAE,YAAY,CAAC,KAAK,EAAE,CAAC;AAChD,SAAC,CAAC,CAAC;KACJ;;AAvIM,mBAAA,CAAA,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;AAI/B,UAAA,CAAA;IADP,KAAK,CAAC,kBAAkB,CAAC;AACK,CAAA,EAAA,mBAAA,CAAA,SAAA,EAAA,MAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAI/B,UAAA,CAAA;AADC,IAAA,KAAK,EAAE;AACe,CAAA,EAAA,mBAAA,CAAA,SAAA,EAAA,oBAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAIvB,UAAA,CAAA;AADC,IAAA,KAAK,EAAE;AACgB,CAAA,EAAA,mBAAA,CAAA,SAAA,EAAA,oBAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAGxB,UAAA,CAAA;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAA,EAAA,mBAAA,CAAA,SAAA,EAAA,QAAA,EAAA,KAAA,CAAA,CAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"dropdown-list-element.js","sources":["../../src/base/dropdown-list-element.ts"],"sourcesContent":["import { property, query, state } from \"lit/decorators.js\";\nimport { DropdownElement } from \"./dropdown-element\";\nimport { SgdsDropdownItem } from \"../components\";\nimport { PropertyValueMap } from \"lit\";\n\nconst TAB = \"Tab\";\nconst ARROW_DOWN = \"ArrowDown\";\nconst ARROW_UP = \"ArrowUp\";\nconst ENTER = \"Enter\";\nconst ESCAPE = \"Escape\";\n\n/**\n * @event sgds-select - Emitted when a dropdown item is selected. `event.detail.item` is the clicked `SgdsDropdownItem` element.\n */\nexport class DropdownListElement extends DropdownElement {\n static styles = DropdownElement.styles;\n\n /**@internal */\n @query(\"ul.dropdown-menu\")\n private menu: HTMLUListElement;\n\n /** @internal */\n @state()\n nextDropdownItemNo = 0;\n\n /** @internal */\n @state()\n prevDropdownItemNo = -1;\n\n @property({ type: Boolean, reflect: true })\n hidden = false;\n\n connectedCallback() {\n super.connectedCallback();\n this.addEventListener(\"sgds-hide\", this._resetMenu);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener(\"sgds-hide\", this._resetMenu);\n }\n\n firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n this.addEventListener(\"keydown\", this._handleKeyboardMenuItemsEvent);\n }\n\n protected handleSelectSlot(e: KeyboardEvent | MouseEvent) {\n const items = this._getActiveMenuItems();\n\n const selectedItem = items.find(item => e.composedPath().includes(item));\n if (!selectedItem) return;\n\n const currentItemNo = items.indexOf(selectedItem);\n this.nextDropdownItemNo = currentItemNo + 1;\n this.prevDropdownItemNo = currentItemNo <= 0 ? items.length - 1 : currentItemNo - 1;\n\n /** Emitted event from SgdsDropdown element when a slot item is selected */\n if (!selectedItem.disabled) {\n this.emit(\"sgds-select\", { detail: { item: selectedItem } });\n if (this.close !== \"outside\") {\n this.hideMenu(); // <-- Use new API\n }\n }\n }\n\n private _resetMenu() {\n this.nextDropdownItemNo = 0;\n this.prevDropdownItemNo = -1;\n // reset the tabindex\n const items = this._getMenuItems();\n items.forEach(item => {\n const dropdownItem = item?.shadowRoot?.querySelector(\".dropdown-item\") as HTMLAnchorElement;\n dropdownItem && dropdownItem.removeAttribute(\"tabindex\");\n });\n }\n protected _handleKeyboardMenuItemsEvent(e: KeyboardEvent) {\n if (this.readonly) return;\n const menuItems = this._getActiveMenuItems();\n if (menuItems.length === 0) return;\n\n switch (e.key) {\n case ARROW_DOWN:\n e.preventDefault();\n this._setMenuItem(this.nextDropdownItemNo);\n break;\n case ARROW_UP:\n e.preventDefault();\n this._setMenuItem(this.prevDropdownItemNo);\n break;\n case TAB:\n if (!this.menuIsOpen) return;\n e.preventDefault();\n if (e.shiftKey) {\n this._setMenuItem(this.prevDropdownItemNo);\n } else {\n this._setMenuItem(this.nextDropdownItemNo);\n }\n break;\n case ESCAPE:\n if (this.menuIsOpen) {\n e.preventDefault();\n this.hideMenu();\n }\n break;\n case ENTER: {\n const target = menuItems.find(item => e.composedPath().includes(item));\n if (target) {\n this.handleSelectSlot(e);\n }\n break;\n }\n default:\n break;\n }\n }\n\n private _getMenuItems(): SgdsDropdownItem[] {\n const defaultSlot = this.shadowRoot.querySelector(\"slot#default\");\n // for case when default slot is used e.g. dropdown, mainnavdropdown\n if (defaultSlot) {\n const defaultSlotItems = (this.shadowRoot.querySelector(\"slot#default\") as HTMLSlotElement)\n ?.assignedElements({\n flatten: true\n })\n .filter(\n el =>\n el.getAttribute(\"role\") === \"menuitem\" && !el.classList.contains(\"empty-menu\") && !el.hasAttribute(\"hidden\")\n ) as SgdsDropdownItem[];\n return defaultSlotItems;\n }\n // for case when there is no slot e.g. combobox\n if (this.menu?.hasChildNodes()) {\n const menuItems = Array.from(this.menu.children);\n return [...menuItems] as SgdsDropdownItem[];\n }\n\n return [];\n }\n\n private _getActiveMenuItems(): SgdsDropdownItem[] {\n return this._getMenuItems().filter(item => !item.disabled && !item.hidden && !item.readonly);\n }\n private _setMenuItem(currentItemIdx: number) {\n const items = this._getActiveMenuItems();\n if (items.length === 0) return;\n\n // Use modulo for looping\n const idx = ((currentItemIdx % items.length) + items.length) % items.length;\n const activeItem = items[idx];\n this.emit(\"i-sgds-option-focus\", { detail: { option: activeItem } });\n this.nextDropdownItemNo = (idx + 1) % items.length;\n this.prevDropdownItemNo = (idx - 1 + items.length) % items.length;\n\n items.forEach(item => {\n const dropdownItem = item.shadowRoot.querySelector(\".dropdown-item\") as HTMLAnchorElement;\n dropdownItem.setAttribute(\"tabindex\", item === activeItem ? \"0\" : \"-1\");\n if (item === activeItem) dropdownItem.focus();\n });\n }\n}\n\nexport interface IDropdownListElement {\n item: SgdsDropdownItem;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { nothing, PropertyValueMap, TemplateResult } from "lit";
|
|
2
|
+
import SgdsElement from "./sgds-element";
|
|
3
|
+
import SgdsIconButton from "../components/IconButton/sgds-icon-button";
|
|
4
|
+
export type NavExpandSize = "sm" | "md" | "lg" | "xl" | "xxl" | "always" | "never";
|
|
5
|
+
export type NavTone = "default" | "brand" | "gradient-1" | "gradient-2" | "gradient-3" | "gradient-4";
|
|
6
|
+
/**
|
|
7
|
+
* Base class for navigation components (sgds-mainnav and sgds-appnav).
|
|
8
|
+
* Provides collapse/expand behavior, breakpoint handling, and animation logic.
|
|
9
|
+
* Subclasses must implement `render()` and provide their own context.
|
|
10
|
+
*/
|
|
11
|
+
export default abstract class NavElement extends SgdsElement {
|
|
12
|
+
/** @internal */
|
|
13
|
+
static dependencies: {
|
|
14
|
+
"sgds-icon-button": typeof SgdsIconButton;
|
|
15
|
+
};
|
|
16
|
+
/** Indicates if mobile menu is open or closed */
|
|
17
|
+
protected expanded: boolean;
|
|
18
|
+
/** Denotes the transition state of mobile mainnav menu opening */
|
|
19
|
+
protected expanding: boolean;
|
|
20
|
+
protected nav: HTMLElement;
|
|
21
|
+
protected navbar: HTMLElement;
|
|
22
|
+
protected header: HTMLElement;
|
|
23
|
+
protected body: HTMLElement;
|
|
24
|
+
protected navScroll: HTMLElement;
|
|
25
|
+
protected navbarEnd: HTMLElement;
|
|
26
|
+
/** The href link for brand logo */
|
|
27
|
+
brandHref: string;
|
|
28
|
+
/** @internal */
|
|
29
|
+
protected collapseId: string;
|
|
30
|
+
/** The breakpoint, below which, the Navbar will collapse. When always the Navbar will always be expanded regardless of screen size. When never, the Navbar will always be collapsed */
|
|
31
|
+
expand: NavExpandSize;
|
|
32
|
+
protected breakpointReached: boolean;
|
|
33
|
+
/** @internal Whether sgds-*-profile is slotted in the profile slot */
|
|
34
|
+
protected _hasProfileComponent: boolean;
|
|
35
|
+
connectedCallback(): void;
|
|
36
|
+
disconnectedCallback(): void;
|
|
37
|
+
firstUpdated(changedProperties: PropertyValueMap<this>): void;
|
|
38
|
+
private _handleClickOutsideBound;
|
|
39
|
+
private _handleResizeBound;
|
|
40
|
+
private _handleClickOutOfElement;
|
|
41
|
+
protected _handleSummaryClick(): void;
|
|
42
|
+
protected _handleResize(): void;
|
|
43
|
+
/** Hook for subclasses to update context providers when breakpoint state changes */
|
|
44
|
+
protected abstract _onBreakpointReached(reached: boolean): void;
|
|
45
|
+
/** Hook for subclasses to check current breakpoint context state */
|
|
46
|
+
protected abstract _isBreakpointReached(): boolean;
|
|
47
|
+
private _handleMobileNavBound;
|
|
48
|
+
protected _handleMobileNav(): Promise<void>;
|
|
49
|
+
protected _handleDesktopNav(): void;
|
|
50
|
+
private _animateToShow;
|
|
51
|
+
/** Hook for subclasses to perform actions after the mobile menu opens (e.g., focus management) */
|
|
52
|
+
protected _onMenuShown(): void;
|
|
53
|
+
private _animateToHide;
|
|
54
|
+
/** @internal */
|
|
55
|
+
handleOpenChange(): Promise<void>;
|
|
56
|
+
/** Shows the menu. For when nav is in the collapsed form */
|
|
57
|
+
show(): Promise<void>;
|
|
58
|
+
/** Hide the menu. For when nav is in the collapsed form */
|
|
59
|
+
hide(): Promise<void>;
|
|
60
|
+
/** Helper to get the expand CSS class */
|
|
61
|
+
protected _expandClass(): string;
|
|
62
|
+
/** Helper: renders the hamburger toggler icon-button. Subclasses should call this in their render(). */
|
|
63
|
+
protected _renderToggler(tone?: NavTone): TemplateResult | typeof nothing;
|
|
64
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
import { state, query, property } from 'lit/decorators.js';
|
|
4
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
|
+
import SgdsElement from './sgds-element.js';
|
|
6
|
+
import { stopAnimations, animateTo, shimKeyframesHeightAuto } from '../utils/animate.js';
|
|
7
|
+
import { setDefaultAnimation, getAnimation } from '../utils/animation-registry.js';
|
|
8
|
+
import { SM_BREAKPOINT, MD_BREAKPOINT, LG_BREAKPOINT, XL_BREAKPOINT, XXL_BREAKPOINT } from '../utils/breakpoints.js';
|
|
9
|
+
import { waitForEvent } from '../utils/event.js';
|
|
10
|
+
import genId from '../utils/generateId.js';
|
|
11
|
+
import { watch } from '../utils/watch.js';
|
|
12
|
+
import { SgdsIconButton } from '../components/IconButton/sgds-icon-button.js';
|
|
13
|
+
|
|
14
|
+
const SIZES = {
|
|
15
|
+
sm: SM_BREAKPOINT,
|
|
16
|
+
md: MD_BREAKPOINT,
|
|
17
|
+
lg: LG_BREAKPOINT,
|
|
18
|
+
xl: XL_BREAKPOINT,
|
|
19
|
+
xxl: XXL_BREAKPOINT,
|
|
20
|
+
never: Infinity,
|
|
21
|
+
always: -1
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Base class for navigation components (sgds-mainnav and sgds-appnav).
|
|
25
|
+
* Provides collapse/expand behavior, breakpoint handling, and animation logic.
|
|
26
|
+
* Subclasses must implement `render()` and provide their own context.
|
|
27
|
+
*/
|
|
28
|
+
class NavElement extends SgdsElement {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
/** Indicates if mobile menu is open or closed */
|
|
32
|
+
this.expanded = false;
|
|
33
|
+
/** Denotes the transition state of mobile mainnav menu opening */
|
|
34
|
+
this.expanding = false;
|
|
35
|
+
/** The href link for brand logo */
|
|
36
|
+
this.brandHref = "";
|
|
37
|
+
/** @internal */
|
|
38
|
+
this.collapseId = genId("nav", "collapse");
|
|
39
|
+
/** The breakpoint, below which, the Navbar will collapse. When always the Navbar will always be expanded regardless of screen size. When never, the Navbar will always be collapsed */
|
|
40
|
+
this.expand = "lg";
|
|
41
|
+
this.breakpointReached = false;
|
|
42
|
+
/** @internal Whether sgds-*-profile is slotted in the profile slot */
|
|
43
|
+
this._hasProfileComponent = false;
|
|
44
|
+
this._handleClickOutsideBound = (event) => this._handleClickOutOfElement(event, this.body);
|
|
45
|
+
this._handleResizeBound = () => this._handleResize();
|
|
46
|
+
this._handleMobileNavBound = this._handleMobileNav.bind(this);
|
|
47
|
+
}
|
|
48
|
+
connectedCallback() {
|
|
49
|
+
super.connectedCallback();
|
|
50
|
+
this._handleResize();
|
|
51
|
+
window.addEventListener("click", this._handleClickOutsideBound);
|
|
52
|
+
window.addEventListener("resize", this._handleResizeBound);
|
|
53
|
+
}
|
|
54
|
+
disconnectedCallback() {
|
|
55
|
+
super.disconnectedCallback();
|
|
56
|
+
window.removeEventListener("click", this._handleClickOutsideBound);
|
|
57
|
+
window.removeEventListener("resize", this._handleResizeBound);
|
|
58
|
+
}
|
|
59
|
+
firstUpdated(changedProperties) {
|
|
60
|
+
super.firstUpdated(changedProperties);
|
|
61
|
+
if (this.breakpointReached && this.body) {
|
|
62
|
+
this.expanded = false;
|
|
63
|
+
this.body.hidden = true;
|
|
64
|
+
this._handleMobileNav();
|
|
65
|
+
this._onBreakpointReached(true);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
_handleClickOutOfElement(e, self) {
|
|
69
|
+
if (!e.composedPath().includes(self) && !(this.header && e.composedPath().includes(this.header))) {
|
|
70
|
+
this.hide();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
_handleSummaryClick() {
|
|
74
|
+
if (this.expanded) {
|
|
75
|
+
this.hide();
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
document.body.style.overflow = "hidden";
|
|
79
|
+
this.show();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
_handleResize() {
|
|
83
|
+
const newBreakpointReachedValue = window.innerWidth < SIZES[this.expand];
|
|
84
|
+
if (newBreakpointReachedValue !== this.breakpointReached) {
|
|
85
|
+
this.requestUpdate();
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
this.body ? (this.body.hidden = true) : null;
|
|
89
|
+
this.expanding = false;
|
|
90
|
+
}
|
|
91
|
+
if (newBreakpointReachedValue) {
|
|
92
|
+
this._handleMobileNav();
|
|
93
|
+
if (!this._isBreakpointReached()) {
|
|
94
|
+
this._onBreakpointReached(true);
|
|
95
|
+
window.addEventListener("scrollend", this._handleMobileNavBound);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
this._handleDesktopNav();
|
|
100
|
+
this._onBreakpointReached(false);
|
|
101
|
+
window.removeEventListener("scrollend", this._handleMobileNavBound);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async _handleMobileNav() {
|
|
105
|
+
if (!this.nav)
|
|
106
|
+
return;
|
|
107
|
+
this.nav.appendChild(this.body);
|
|
108
|
+
await customElements.whenDefined("sgds-masthead");
|
|
109
|
+
const { bottom } = this.nav.getBoundingClientRect();
|
|
110
|
+
const navBodyPaddingY = parseFloat(getComputedStyle(this.body).paddingTop) + parseFloat(getComputedStyle(this.body).paddingBottom);
|
|
111
|
+
this.navScroll.style.maxHeight = `calc(100dvh - ${bottom}px - ${navBodyPaddingY}px)`;
|
|
112
|
+
}
|
|
113
|
+
_handleDesktopNav() {
|
|
114
|
+
var _a;
|
|
115
|
+
(_a = this.navbar) === null || _a === void 0 ? void 0 : _a.insertBefore(this.body, this.navbarEnd);
|
|
116
|
+
}
|
|
117
|
+
async _animateToShow() {
|
|
118
|
+
const sgdsShow = this.emit("sgds-show", { cancelable: true });
|
|
119
|
+
if (sgdsShow.defaultPrevented) {
|
|
120
|
+
this.expanding = false;
|
|
121
|
+
this.expanded = false;
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
await stopAnimations(this.body);
|
|
125
|
+
this.body.hidden = false;
|
|
126
|
+
const { keyframes, options } = getAnimation(this, "nav.show");
|
|
127
|
+
await animateTo(this.body, shimKeyframesHeightAuto(keyframes, this.body.scrollHeight), options);
|
|
128
|
+
this.body.style.height = "auto";
|
|
129
|
+
this._onMenuShown();
|
|
130
|
+
this.emit("sgds-after-show");
|
|
131
|
+
}
|
|
132
|
+
/** Hook for subclasses to perform actions after the mobile menu opens (e.g., focus management) */
|
|
133
|
+
_onMenuShown() {
|
|
134
|
+
// Default: no-op. Subclasses can override.
|
|
135
|
+
}
|
|
136
|
+
async _animateToHide() {
|
|
137
|
+
const sgdsHide = this.emit("sgds-hide", { cancelable: true });
|
|
138
|
+
if (sgdsHide.defaultPrevented) {
|
|
139
|
+
this.expanding = false;
|
|
140
|
+
this.expanded = true;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
await stopAnimations(this.body);
|
|
144
|
+
const { keyframes, options } = getAnimation(this, "nav.hide");
|
|
145
|
+
await animateTo(this.body, shimKeyframesHeightAuto(keyframes, this.body.scrollHeight), options);
|
|
146
|
+
this.body.hidden = true;
|
|
147
|
+
this.body.style.height = "auto";
|
|
148
|
+
this.emit("sgds-after-hide");
|
|
149
|
+
}
|
|
150
|
+
/** @internal */
|
|
151
|
+
async handleOpenChange() {
|
|
152
|
+
var _a;
|
|
153
|
+
if (this.expanding) {
|
|
154
|
+
await this._animateToShow();
|
|
155
|
+
this.expanded = true;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
(_a = this.header) === null || _a === void 0 ? void 0 : _a.focus();
|
|
159
|
+
await this._animateToHide();
|
|
160
|
+
this.expanded = false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** Shows the menu. For when nav is in the collapsed form */
|
|
164
|
+
async show() {
|
|
165
|
+
if (this.expanded)
|
|
166
|
+
return;
|
|
167
|
+
this.expanding = true;
|
|
168
|
+
return waitForEvent(this, "sgds-after-show");
|
|
169
|
+
}
|
|
170
|
+
/** Hide the menu. For when nav is in the collapsed form */
|
|
171
|
+
async hide() {
|
|
172
|
+
if (!this.expanded)
|
|
173
|
+
return;
|
|
174
|
+
this.expanding = false;
|
|
175
|
+
document.body.style.removeProperty("overflow");
|
|
176
|
+
return waitForEvent(this, "sgds-after-hide");
|
|
177
|
+
}
|
|
178
|
+
/** Helper to get the expand CSS class */
|
|
179
|
+
_expandClass() {
|
|
180
|
+
switch (this.expand) {
|
|
181
|
+
case "always":
|
|
182
|
+
return "navbar-expand";
|
|
183
|
+
case "never":
|
|
184
|
+
break;
|
|
185
|
+
default:
|
|
186
|
+
return `navbar-expand-${this.expand}`;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/** Helper: renders the hamburger toggler icon-button. Subclasses should call this in their render(). */
|
|
190
|
+
_renderToggler(tone) {
|
|
191
|
+
return html `<sgds-icon-button
|
|
192
|
+
name=${this.expanded ? "cross" : "menu"}
|
|
193
|
+
variant="ghost"
|
|
194
|
+
size="sm"
|
|
195
|
+
tone=${ifDefined(tone && tone !== "default" ? "fixed-light" : undefined)}
|
|
196
|
+
class="navbar-toggler"
|
|
197
|
+
@click=${this._handleSummaryClick}
|
|
198
|
+
aria-controls="${this.collapseId}"
|
|
199
|
+
aria-expanded="${this.expanded}"
|
|
200
|
+
.ariaLabel=${"Toggle navigation"}
|
|
201
|
+
></sgds-icon-button>`;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/** @internal */
|
|
205
|
+
NavElement.dependencies = {
|
|
206
|
+
"sgds-icon-button": SgdsIconButton
|
|
207
|
+
};
|
|
208
|
+
__decorate([
|
|
209
|
+
state()
|
|
210
|
+
], NavElement.prototype, "expanded", void 0);
|
|
211
|
+
__decorate([
|
|
212
|
+
state()
|
|
213
|
+
], NavElement.prototype, "expanding", void 0);
|
|
214
|
+
__decorate([
|
|
215
|
+
query("nav")
|
|
216
|
+
], NavElement.prototype, "nav", void 0);
|
|
217
|
+
__decorate([
|
|
218
|
+
query(".navbar")
|
|
219
|
+
], NavElement.prototype, "navbar", void 0);
|
|
220
|
+
__decorate([
|
|
221
|
+
query(".navbar-toggler")
|
|
222
|
+
], NavElement.prototype, "header", void 0);
|
|
223
|
+
__decorate([
|
|
224
|
+
query(".navbar-body")
|
|
225
|
+
], NavElement.prototype, "body", void 0);
|
|
226
|
+
__decorate([
|
|
227
|
+
query(".navbar-nav-scroll")
|
|
228
|
+
], NavElement.prototype, "navScroll", void 0);
|
|
229
|
+
__decorate([
|
|
230
|
+
query(".navbar-end")
|
|
231
|
+
], NavElement.prototype, "navbarEnd", void 0);
|
|
232
|
+
__decorate([
|
|
233
|
+
property({ type: String })
|
|
234
|
+
], NavElement.prototype, "brandHref", void 0);
|
|
235
|
+
__decorate([
|
|
236
|
+
property({ type: String })
|
|
237
|
+
], NavElement.prototype, "expand", void 0);
|
|
238
|
+
__decorate([
|
|
239
|
+
state()
|
|
240
|
+
], NavElement.prototype, "breakpointReached", void 0);
|
|
241
|
+
__decorate([
|
|
242
|
+
state()
|
|
243
|
+
], NavElement.prototype, "_hasProfileComponent", void 0);
|
|
244
|
+
__decorate([
|
|
245
|
+
watch("expanding", { waitUntilFirstUpdate: true })
|
|
246
|
+
], NavElement.prototype, "handleOpenChange", null);
|
|
247
|
+
setDefaultAnimation("nav.show", {
|
|
248
|
+
keyframes: [
|
|
249
|
+
{ height: "0", opacity: "0" },
|
|
250
|
+
{ height: "auto", opacity: "1" }
|
|
251
|
+
],
|
|
252
|
+
options: { duration: 200, easing: "ease-in-out" }
|
|
253
|
+
});
|
|
254
|
+
setDefaultAnimation("nav.hide", {
|
|
255
|
+
keyframes: [
|
|
256
|
+
{ height: "auto", opacity: "1" },
|
|
257
|
+
{ height: "0", opacity: "0" }
|
|
258
|
+
],
|
|
259
|
+
options: { duration: 200, easing: "ease-in-out" }
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
export { NavElement as default };
|
|
263
|
+
//# sourceMappingURL=nav-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nav-element.js","sources":["../../src/base/nav-element.ts"],"sourcesContent":["import { html, nothing, PropertyValueMap, TemplateResult } from \"lit\";\nimport { property, query, state } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport SgdsElement from \"./sgds-element\";\nimport { animateTo, shimKeyframesHeightAuto, stopAnimations } from \"../utils/animate\";\nimport { getAnimation, setDefaultAnimation } from \"../utils/animation-registry\";\nimport { LG_BREAKPOINT, MD_BREAKPOINT, SM_BREAKPOINT, XL_BREAKPOINT, XXL_BREAKPOINT } from \"../utils/breakpoints\";\nimport { waitForEvent } from \"../utils/event\";\nimport genId from \"../utils/generateId\";\nimport { watch } from \"../utils/watch\";\nimport SgdsIconButton from \"../components/IconButton/sgds-icon-button\";\n\nexport type NavExpandSize = \"sm\" | \"md\" | \"lg\" | \"xl\" | \"xxl\" | \"always\" | \"never\";\nexport type NavTone = \"default\" | \"brand\" | \"gradient-1\" | \"gradient-2\" | \"gradient-3\" | \"gradient-4\";\n\nconst SIZES: Record<NavExpandSize, number> = {\n sm: SM_BREAKPOINT,\n md: MD_BREAKPOINT,\n lg: LG_BREAKPOINT,\n xl: XL_BREAKPOINT,\n xxl: XXL_BREAKPOINT,\n never: Infinity,\n always: -1\n};\n\n/**\n * Base class for navigation components (sgds-mainnav and sgds-appnav).\n * Provides collapse/expand behavior, breakpoint handling, and animation logic.\n * Subclasses must implement `render()` and provide their own context.\n */\nexport default abstract class NavElement extends SgdsElement {\n /** @internal */\n static dependencies = {\n \"sgds-icon-button\": SgdsIconButton\n };\n\n /** Indicates if mobile menu is open or closed */\n @state()\n protected expanded = false;\n\n /** Denotes the transition state of mobile mainnav menu opening */\n @state()\n protected expanding = false;\n\n @query(\"nav\") protected nav!: HTMLElement;\n @query(\".navbar\") protected navbar!: HTMLElement;\n @query(\".navbar-toggler\") protected header!: HTMLElement;\n @query(\".navbar-body\") protected body!: HTMLElement;\n @query(\".navbar-nav-scroll\") protected navScroll!: HTMLElement;\n @query(\".navbar-end\") protected navbarEnd!: HTMLElement;\n\n /** The href link for brand logo */\n @property({ type: String })\n brandHref = \"\";\n\n /** @internal */\n protected collapseId = genId(\"nav\", \"collapse\");\n\n /** The breakpoint, below which, the Navbar will collapse. When always the Navbar will always be expanded regardless of screen size. When never, the Navbar will always be collapsed */\n @property({ type: String })\n expand: NavExpandSize = \"lg\";\n\n @state()\n protected breakpointReached = false;\n\n /** @internal Whether sgds-*-profile is slotted in the profile slot */\n @state()\n protected _hasProfileComponent = false;\n\n connectedCallback() {\n super.connectedCallback();\n this._handleResize();\n window.addEventListener(\"click\", this._handleClickOutsideBound);\n window.addEventListener(\"resize\", this._handleResizeBound);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n window.removeEventListener(\"click\", this._handleClickOutsideBound);\n window.removeEventListener(\"resize\", this._handleResizeBound);\n }\n\n firstUpdated(changedProperties: PropertyValueMap<this>) {\n super.firstUpdated(changedProperties);\n if (this.breakpointReached && this.body) {\n this.expanded = false;\n this.body.hidden = true;\n this._handleMobileNav();\n this._onBreakpointReached(true);\n }\n }\n\n private _handleClickOutsideBound = (event: MouseEvent) => this._handleClickOutOfElement(event, this.body);\n private _handleResizeBound = () => this._handleResize();\n\n private _handleClickOutOfElement(e: MouseEvent, self: HTMLElement) {\n if (!e.composedPath().includes(self) && !(this.header && e.composedPath().includes(this.header))) {\n this.hide();\n }\n }\n\n protected _handleSummaryClick() {\n if (this.expanded) {\n this.hide();\n } else {\n document.body.style.overflow = \"hidden\";\n this.show();\n }\n }\n\n protected _handleResize() {\n const newBreakpointReachedValue = window.innerWidth < SIZES[this.expand];\n if (newBreakpointReachedValue !== this.breakpointReached) {\n this.requestUpdate();\n } else {\n this.body ? (this.body.hidden = true) : null;\n this.expanding = false;\n }\n\n if (newBreakpointReachedValue) {\n this._handleMobileNav();\n if (!this._isBreakpointReached()) {\n this._onBreakpointReached(true);\n window.addEventListener(\"scrollend\", this._handleMobileNavBound);\n }\n } else {\n this._handleDesktopNav();\n this._onBreakpointReached(false);\n window.removeEventListener(\"scrollend\", this._handleMobileNavBound);\n }\n }\n\n /** Hook for subclasses to update context providers when breakpoint state changes */\n protected abstract _onBreakpointReached(reached: boolean): void;\n\n /** Hook for subclasses to check current breakpoint context state */\n protected abstract _isBreakpointReached(): boolean;\n\n private _handleMobileNavBound = this._handleMobileNav.bind(this);\n\n protected async _handleMobileNav() {\n if (!this.nav) return;\n this.nav.appendChild(this.body);\n await customElements.whenDefined(\"sgds-masthead\");\n\n const { bottom } = this.nav.getBoundingClientRect();\n const navBodyPaddingY =\n parseFloat(getComputedStyle(this.body).paddingTop) + parseFloat(getComputedStyle(this.body).paddingBottom);\n\n this.navScroll.style.maxHeight = `calc(100dvh - ${bottom}px - ${navBodyPaddingY}px)`;\n }\n\n protected _handleDesktopNav() {\n this.navbar?.insertBefore(this.body, this.navbarEnd);\n }\n\n private async _animateToShow() {\n const sgdsShow = this.emit(\"sgds-show\", { cancelable: true });\n if (sgdsShow.defaultPrevented) {\n this.expanding = false;\n this.expanded = false;\n return;\n }\n\n await stopAnimations(this.body);\n this.body.hidden = false;\n\n const { keyframes, options } = getAnimation(this, \"nav.show\");\n await animateTo(this.body, shimKeyframesHeightAuto(keyframes, this.body.scrollHeight), options);\n this.body.style.height = \"auto\";\n\n this._onMenuShown();\n this.emit(\"sgds-after-show\");\n }\n\n /** Hook for subclasses to perform actions after the mobile menu opens (e.g., focus management) */\n protected _onMenuShown(): void {\n // Default: no-op. Subclasses can override.\n }\n\n private async _animateToHide() {\n const sgdsHide = this.emit(\"sgds-hide\", { cancelable: true });\n if (sgdsHide.defaultPrevented) {\n this.expanding = false;\n this.expanded = true;\n return;\n }\n\n await stopAnimations(this.body);\n\n const { keyframes, options } = getAnimation(this, \"nav.hide\");\n await animateTo(this.body, shimKeyframesHeightAuto(keyframes, this.body.scrollHeight), options);\n this.body.hidden = true;\n this.body.style.height = \"auto\";\n this.emit(\"sgds-after-hide\");\n }\n\n /** @internal */\n @watch(\"expanding\", { waitUntilFirstUpdate: true })\n async handleOpenChange() {\n if (this.expanding) {\n await this._animateToShow();\n this.expanded = true;\n } else {\n this.header?.focus();\n await this._animateToHide();\n this.expanded = false;\n }\n }\n\n /** Shows the menu. For when nav is in the collapsed form */\n public async show() {\n if (this.expanded) return;\n this.expanding = true;\n return waitForEvent(this, \"sgds-after-show\");\n }\n\n /** Hide the menu. For when nav is in the collapsed form */\n public async hide() {\n if (!this.expanded) return;\n this.expanding = false;\n document.body.style.removeProperty(\"overflow\");\n return waitForEvent(this, \"sgds-after-hide\");\n }\n\n /** Helper to get the expand CSS class */\n protected _expandClass() {\n switch (this.expand) {\n case \"always\":\n return \"navbar-expand\";\n case \"never\":\n break;\n default:\n return `navbar-expand-${this.expand}`;\n }\n }\n\n /** Helper: renders the hamburger toggler icon-button. Subclasses should call this in their render(). */\n protected _renderToggler(tone?: NavTone): TemplateResult | typeof nothing {\n return html`<sgds-icon-button\n name=${this.expanded ? \"cross\" : \"menu\"}\n variant=\"ghost\"\n size=\"sm\"\n tone=${ifDefined(tone && tone !== \"default\" ? \"fixed-light\" : undefined)}\n class=\"navbar-toggler\"\n @click=${this._handleSummaryClick}\n aria-controls=\"${this.collapseId}\"\n aria-expanded=\"${this.expanded}\"\n .ariaLabel=${\"Toggle navigation\"}\n ></sgds-icon-button>`;\n }\n}\n\nsetDefaultAnimation(\"nav.show\", {\n keyframes: [\n { height: \"0\", opacity: \"0\" },\n { height: \"auto\", opacity: \"1\" }\n ],\n options: { duration: 200, easing: \"ease-in-out\" }\n});\n\nsetDefaultAnimation(\"nav.hide\", {\n keyframes: [\n { height: \"auto\", opacity: \"1\" },\n { height: \"0\", opacity: \"0\" }\n ],\n options: { duration: 200, easing: \"ease-in-out\" }\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import SgdsElement from "./sgds-element";
|
|
2
|
+
import SgdsDropdown from "../components/Dropdown/sgds-dropdown";
|
|
3
|
+
import SgdsIcon from "../components/Icon/sgds-icon";
|
|
4
|
+
/**
|
|
5
|
+
* Base class for navigation profile components (sgds-mainnav-profile and sgds-appnav-profile).
|
|
6
|
+
* Provides the full profile dropdown (desktop) and mobile panel behavior.
|
|
7
|
+
* When no dropdown items are slotted into the default slot, renders as a non-interactive
|
|
8
|
+
* read-only element (no dropdown menu, no caret icon, cursor default, not focusable by keyboard or mouse).
|
|
9
|
+
* Subclasses must consume the appropriate breakpoint context and set `_breakpointReached`.
|
|
10
|
+
*
|
|
11
|
+
* @slot avatar - Avatar element displayed in both desktop (before label) and mobile (as toggler)
|
|
12
|
+
* @slot default - Profile menu items (sgds-dropdown-item elements). When empty, the component becomes read-only.
|
|
13
|
+
*/
|
|
14
|
+
export default abstract class NavProfileElement extends SgdsElement {
|
|
15
|
+
static styles: import("lit").CSSResult[];
|
|
16
|
+
/** @internal */
|
|
17
|
+
static dependencies: {
|
|
18
|
+
"sgds-dropdown": typeof SgdsDropdown;
|
|
19
|
+
"sgds-icon": typeof SgdsIcon;
|
|
20
|
+
};
|
|
21
|
+
/** @internal Whether the breakpoint is reached (mobile mode). Subclasses set this via context consumption. */
|
|
22
|
+
protected _breakpointReached: boolean;
|
|
23
|
+
/** @internal Whether the mobile menu is open */
|
|
24
|
+
private _mobileMenuOpen;
|
|
25
|
+
/** @internal Whether dropdown items are slotted */
|
|
26
|
+
private _hasDropdownItems;
|
|
27
|
+
private _defaultSlotElements;
|
|
28
|
+
/** Primary text displayed next to the avatar in desktop (e.g. user name) */
|
|
29
|
+
label: string;
|
|
30
|
+
/** Secondary text displayed below the label in desktop (e.g. agency or role) */
|
|
31
|
+
secondaryText: string;
|
|
32
|
+
/** When true, disables the profile dropdown */
|
|
33
|
+
disabled: boolean;
|
|
34
|
+
/** Accessible label for the profile toggle button */
|
|
35
|
+
ariaLabel: string;
|
|
36
|
+
/** Controls dropdown close behavior. "default" auto-closes on item/outside click, "outside" closes only on outside click, "inside" prevents auto-close. */
|
|
37
|
+
close: "default" | "outside" | "inside";
|
|
38
|
+
/** @internal */
|
|
39
|
+
private togglerId;
|
|
40
|
+
private _handleMobileToggle;
|
|
41
|
+
private _handleClickOutside;
|
|
42
|
+
connectedCallback(): void;
|
|
43
|
+
disconnectedCallback(): void;
|
|
44
|
+
private _handleSlotChange;
|
|
45
|
+
private _handleKeydown;
|
|
46
|
+
render(): import("lit").TemplateResult<1>;
|
|
47
|
+
}
|