diff --git a/.changeset/clean-walls-bake.md b/.changeset/clean-walls-bake.md new file mode 100644 index 0000000000..4f95a563a4 --- /dev/null +++ b/.changeset/clean-walls-bake.md @@ -0,0 +1,6 @@ +--- +"@siemens/ix": patch +"@siemens/ix-vue": patch +--- + +fix(core/date-dropdown): show year and month dropdown diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index 5d08dfd27a..6b3ee24959 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -802,6 +802,7 @@ export namespace Components { * An optional header shown at the top of the dropdown */ "header"?: string; + "ignoreRelatedSubmenu": boolean; /** * Move dropdown along main axis of alignment */ @@ -4905,6 +4906,7 @@ declare namespace LocalJSX { * An optional header shown at the top of the dropdown */ "header"?: string; + "ignoreRelatedSubmenu"?: boolean; /** * Move dropdown along main axis of alignment */ diff --git a/packages/core/src/components/date-dropdown/date-dropdown.tsx b/packages/core/src/components/date-dropdown/date-dropdown.tsx index 9df4717b36..06dc5cf12c 100644 --- a/packages/core/src/components/date-dropdown/date-dropdown.tsx +++ b/packages/core/src/components/date-dropdown/date-dropdown.tsx @@ -298,6 +298,7 @@ export class DateDropdown { return ( { if ( diff --git a/packages/core/src/components/date-dropdown/test/date-dropdown.ct.ts b/packages/core/src/components/date-dropdown/test/date-dropdown.ct.ts index d6f71c6630..326e6dc032 100644 --- a/packages/core/src/components/date-dropdown/test/date-dropdown.ct.ts +++ b/packages/core/src/components/date-dropdown/test/date-dropdown.ct.ts @@ -216,6 +216,41 @@ test('set date from a button', async ({ mount, page }) => { await expect(button).toHaveText(/2024\/02\/17 \- 2024\/02\/27/); }); +test('select different year', async ({ mount, page }) => { + await mount(``); + const dateDropdown = page.locator(DATE_DROPDOWN_SELECTOR); + + await expect(dateDropdown).toHaveClass(/hydrated/); + await expect(dateDropdown).toBeVisible(); + + const dateDropdownTrigger = dateDropdown.getByTestId('date-dropdown-trigger'); + await dateDropdownTrigger.click(); + await expect(dateDropdownTrigger).toBeVisible(); + + const datePickerDropdown = dateDropdown.getByTestId('date-dropdown'); + await expect(datePickerDropdown).toBeVisible(); + + const datepicker = datePickerDropdown.locator('ix-date-picker'); + const yearMonthButton = datepicker.getByTestId('year-month-button'); + await yearMonthButton.click(); + + const yearMonthDropdown = datepicker.getByTestId('year-month-dropdown'); + await expect(yearMonthDropdown).toBeVisible(); + + const yearContainer = yearMonthDropdown.getByTestId('year-container'); + const year2020 = yearContainer.getByText('2020'); + + await year2020.click(); + + const monthContainer = yearMonthDropdown.getByTestId('month-container'); + const march2020 = monthContainer.getByText('March 2020'); + + await march2020.click(); + + await expect(yearMonthDropdown).not.toBeVisible(); + await expect(yearMonthButton).toHaveText('March 2020'); +}); + test('disable', async ({ mount, page }) => { await mount(``); const dateDropdown = page.locator('ix-date-dropdown'); diff --git a/packages/core/src/components/date-picker/date-picker.tsx b/packages/core/src/components/date-picker/date-picker.tsx index ce75264603..74933790d1 100644 --- a/packages/core/src/components/date-picker/date-picker.tsx +++ b/packages/core/src/components/date-picker/date-picker.tsx @@ -689,25 +689,32 @@ export class DatePicker { class="arrows" >
- (this.dropdownButtonRef = ref)}> + (this.dropdownButtonRef = ref)} + data-testid="year-month-button" + > {this.monthNames[this.selectedMonth]} {this.selectedYear}
this.infiniteScrollYears()} ref={(ref) => (this.yearContainerRef = ref)} > {this.renderYears()}
-
+
{this.monthNames.map((month, index) => (
{ - if ( - !ignoreBehaviorForIds.includes(dropdown.getId()) && - (dropdown.closeBehavior === 'inside' || - dropdown.closeBehavior === false) - ) { + const preventClosing = + dropdown.closeBehavior === 'inside' || dropdown.closeBehavior === false; + + const shouldIgnore = ignoreBehaviorForIds.includes(dropdown.getId()); + const path = this.buildComposedPath(dropdown.getId(), new Set()); + + if (ignoreBehaviorForIds.length > 0 && ignoreRelatedDropdowns) { + let skipRelatedDropdown = false; + + ignoreBehaviorForIds.forEach((id) => { + if (path.has(id)) { + skipRelatedDropdown = true; + return; + } + }); + + if (!skipRelatedDropdown) { + return; + } + } + + if (!shouldIgnore && preventClosing) { return; } @@ -128,12 +148,12 @@ class DropdownController { for (let eventTarget of eventTargets) { if (eventTarget instanceof HTMLElement) { if (eventTarget.hasAttribute('data-ix-dropdown-trigger')) { - return true; + return eventTarget; } } } - return false; + return; } private pathIncludesDropdown(eventTargets: EventTarget[]) { diff --git a/packages/core/src/components/dropdown/dropdown.tsx b/packages/core/src/components/dropdown/dropdown.tsx index 4b7b0b2866..de469c0f43 100644 --- a/packages/core/src/components/dropdown/dropdown.tsx +++ b/packages/core/src/components/dropdown/dropdown.tsx @@ -119,6 +119,9 @@ export class Dropdown implements ComponentInterface, DropdownInterface { */ @Prop() discoverAllSubmenus = false; + /** @internal */ + @Prop() ignoreRelatedSubmenu = false; + /** * Fire event after visibility of dropdown has changed */ @@ -254,7 +257,7 @@ export class Dropdown implements ComponentInterface, DropdownInterface { this.triggerElement?.dispatchEvent( new CustomEvent('ix-assign-sub-menu', { bubbles: true, - composed: false, + composed: true, cancelable: true, detail: this.localUId, }) @@ -501,16 +504,18 @@ export class Dropdown implements ComponentInterface, DropdownInterface { } private onDropdownClick(event: PointerEvent) { - if (dropdownController.pathIncludesTrigger(event.composedPath())) { + const target = dropdownController.pathIncludesTrigger(event.composedPath()); + if (target) { event.preventDefault(); - if (this.isTriggerElement(event.target as HTMLElement)) { + if (this.isTriggerElement(target)) { return; } } if (this.closeBehavior === 'inside' || this.closeBehavior === 'both') { - dropdownController.dismissAll([this.getId()]); + dropdownController.dismissAll([this.getId()], this.ignoreRelatedSubmenu); + return; } dropdownController.dismissOthers(this.getId()); diff --git a/packages/vue/src/components.ts b/packages/vue/src/components.ts index 93e807741a..da2aba35cf 100644 --- a/packages/vue/src/components.ts +++ b/packages/vue/src/components.ts @@ -367,6 +367,7 @@ export const IxDropdown = /*@__PURE__*/ defineContainer('ix-drop 'offset', 'overwriteDropdownStyle', 'discoverAllSubmenus', + 'ignoreRelatedSubmenu', 'showChanged' ]);