diff --git a/packages/angular-test-app/src/preview-examples/group-context-menu.ts b/packages/angular-test-app/src/preview-examples/group-context-menu.ts index 26b0f0c0bbc..f0f1a22846b 100644 --- a/packages/angular-test-app/src/preview-examples/group-context-menu.ts +++ b/packages/angular-test-app/src/preview-examples/group-context-menu.ts @@ -13,10 +13,10 @@ import { Component } from '@angular/core'; selector: 'app-group-context-menu', template: ` -
+ -
+ diff --git a/packages/angular/src/components.ts b/packages/angular/src/components.ts index 426c0c0091a..fb8a5b82b18 100644 --- a/packages/angular/src/components.ts +++ b/packages/angular/src/components.ts @@ -664,6 +664,25 @@ export class IxGroup { } +export declare interface IxGroupContextMenu extends Components.IxGroupContextMenu {} + +@ProxyCmp({ + defineCustomElementFn: undefined +}) +@Component({ + selector: 'ix-group-context-menu', + changeDetection: ChangeDetectionStrategy.OnPush, + template: '' +}) +export class IxGroupContextMenu { + protected el: HTMLElement; + constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { + c.detach(); + this.el = r.nativeElement; + } +} + + export declare interface IxGroupDropdownItem extends Components.IxGroupDropdownItem {} @ProxyCmp({ diff --git a/packages/angular/src/declare-components.ts b/packages/angular/src/declare-components.ts index 20e138e2f75..237d07cc8ee 100644 --- a/packages/angular/src/declare-components.ts +++ b/packages/angular/src/declare-components.ts @@ -26,6 +26,7 @@ export const DIRECTIVES = [ d.IxFlipTile, d.IxFlipTileContent, d.IxGroup, + d.IxGroupContextMenu, d.IxGroupDropdownItem, d.IxGroupItem, d.IxIcon, diff --git a/packages/core/component-doc.json b/packages/core/component-doc.json index 37673bb633b..741366074a3 100644 --- a/packages/core/component-doc.json +++ b/packages/core/component-doc.json @@ -2252,11 +2252,11 @@ "dependents": [ "ix-breadcrumb", "ix-date-picker", - "ix-group", "ix-menu", "ix-menu-avatar", "ix-select", - "ix-split-button" + "ix-split-button", + "my-component" ], "dependencies": [], "dependencyGraph": { @@ -2266,9 +2266,6 @@ "ix-date-picker": [ "ix-dropdown" ], - "ix-group": [ - "ix-dropdown" - ], "ix-menu": [ "ix-dropdown" ], @@ -2280,6 +2277,9 @@ ], "ix-split-button": [ "ix-dropdown" + ], + "my-component": [ + "ix-dropdown" ] }, "props": [ @@ -2575,7 +2575,8 @@ "ix-menu-avatar-item", "ix-select", "ix-select-item", - "ix-split-button-item" + "ix-split-button-item", + "my-component" ], "dependencies": [ "ix-icon" @@ -2601,6 +2602,9 @@ ], "ix-split-button-item": [ "ix-dropdown-item" + ], + "my-component": [ + "ix-dropdown-item" ] }, "props": [ @@ -3224,25 +3228,31 @@ "docs": "", "docsTags": [], "encapsulation": "scoped", - "dependents": [], + "dependents": [ + "my-component" + ], "dependencies": [ "ix-icon", - "ix-icon-button", - "ix-dropdown", + "ix-group-context-menu", "ix-group-item" ], "dependencyGraph": { "ix-group": [ "ix-icon", - "ix-icon-button", - "ix-dropdown", + "ix-group-context-menu", "ix-group-item" ], + "ix-group-context-menu": [ + "ix-icon-button" + ], "ix-icon-button": [ "ix-icon" ], "ix-group-item": [ "ix-icon" + ], + "my-component": [ + "ix-group" ] }, "props": [ @@ -3404,6 +3414,44 @@ } ] }, + { + "dirPath": "./src/components/group", + "filePath": "./src/components/group/group-context-menu.tsx", + "fileName": "group-context-menu.tsx", + "readmePath": "./src/components/group/readme.md", + "usagesDir": "./src/components/group/usage", + "tag": "ix-group-context-menu", + "readme": "\n\n# ix-group\n", + "overview": "", + "usage": {}, + "docs": "", + "docsTags": [], + "encapsulation": "scoped", + "dependents": [ + "ix-group" + ], + "dependencies": [ + "ix-icon-button" + ], + "dependencyGraph": { + "ix-group-context-menu": [ + "ix-icon-button" + ], + "ix-icon-button": [ + "ix-icon" + ], + "ix-group": [ + "ix-group-context-menu" + ] + }, + "props": [], + "methods": [], + "events": [], + "styles": [], + "slots": [], + "parts": [], + "listeners": [] + }, { "dirPath": "./src/components/group-dropdown-item", "filePath": "./src/components/group-dropdown-item/group-dropdown-item.tsx", @@ -3484,7 +3532,8 @@ "docsTags": [], "encapsulation": "scoped", "dependents": [ - "ix-group" + "ix-group", + "my-component" ], "dependencies": [ "ix-icon" @@ -3495,6 +3544,9 @@ ], "ix-group": [ "ix-group-item" + ], + "my-component": [ + "ix-group-item" ] }, "props": [ @@ -3830,7 +3882,7 @@ "ix-drawer", "ix-expanding-search", "ix-flip-tile", - "ix-group", + "ix-group-context-menu", "ix-map-navigation", "ix-map-navigation-overlay", "ix-menu-about", @@ -3861,7 +3913,7 @@ "ix-flip-tile": [ "ix-icon-button" ], - "ix-group": [ + "ix-group-context-menu": [ "ix-icon-button" ], "ix-map-navigation": [ @@ -9166,8 +9218,37 @@ "docsTags": [], "encapsulation": "scoped", "dependents": [], - "dependencies": [], - "dependencyGraph": {}, + "dependencies": [ + "ix-group", + "ix-dropdown", + "ix-dropdown-item", + "ix-group-item" + ], + "dependencyGraph": { + "my-component": [ + "ix-group", + "ix-dropdown", + "ix-dropdown-item", + "ix-group-item" + ], + "ix-group": [ + "ix-icon", + "ix-group-context-menu", + "ix-group-item" + ], + "ix-group-context-menu": [ + "ix-icon-button" + ], + "ix-icon-button": [ + "ix-icon" + ], + "ix-group-item": [ + "ix-icon" + ], + "ix-dropdown-item": [ + "ix-icon" + ] + }, "props": [], "methods": [], "events": [], diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index 80b9b5a365f..2fe6e1cd144 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -581,6 +581,8 @@ export namespace Components { */ "suppressHeaderSelection": boolean; } + interface IxGroupContextMenu { + } interface IxGroupDropdownItem { /** * Group dropdown icon @@ -1768,6 +1770,12 @@ declare global { prototype: HTMLIxGroupElement; new (): HTMLIxGroupElement; }; + interface HTMLIxGroupContextMenuElement extends Components.IxGroupContextMenu, HTMLStencilElement { + } + var HTMLIxGroupContextMenuElement: { + prototype: HTMLIxGroupContextMenuElement; + new (): HTMLIxGroupContextMenuElement; + }; interface HTMLIxGroupDropdownItemElement extends Components.IxGroupDropdownItem, HTMLStencilElement { } var HTMLIxGroupDropdownItemElement: { @@ -2039,6 +2047,7 @@ declare global { "ix-flip-tile": HTMLIxFlipTileElement; "ix-flip-tile-content": HTMLIxFlipTileContentElement; "ix-group": HTMLIxGroupElement; + "ix-group-context-menu": HTMLIxGroupContextMenuElement; "ix-group-dropdown-item": HTMLIxGroupDropdownItemElement; "ix-group-item": HTMLIxGroupItemElement; "ix-icon": HTMLIxIconElement; @@ -2733,6 +2742,8 @@ declare namespace LocalJSX { */ "suppressHeaderSelection"?: boolean; } + interface IxGroupContextMenu { + } interface IxGroupDropdownItem { /** * Group dropdown icon @@ -3707,6 +3718,7 @@ declare namespace LocalJSX { "ix-flip-tile": IxFlipTile; "ix-flip-tile-content": IxFlipTileContent; "ix-group": IxGroup; + "ix-group-context-menu": IxGroupContextMenu; "ix-group-dropdown-item": IxGroupDropdownItem; "ix-group-item": IxGroupItem; "ix-icon": IxIcon; @@ -3778,6 +3790,7 @@ declare module "@stencil/core" { "ix-flip-tile": LocalJSX.IxFlipTile & JSXBase.HTMLAttributes; "ix-flip-tile-content": LocalJSX.IxFlipTileContent & JSXBase.HTMLAttributes; "ix-group": LocalJSX.IxGroup & JSXBase.HTMLAttributes; + "ix-group-context-menu": LocalJSX.IxGroupContextMenu & JSXBase.HTMLAttributes; "ix-group-dropdown-item": LocalJSX.IxGroupDropdownItem & JSXBase.HTMLAttributes; "ix-group-item": LocalJSX.IxGroupItem & JSXBase.HTMLAttributes; "ix-icon": LocalJSX.IxIcon & JSXBase.HTMLAttributes; diff --git a/packages/core/src/components/group/group-context-menu.scss b/packages/core/src/components/group/group-context-menu.scss new file mode 100644 index 00000000000..9179a36a4a1 --- /dev/null +++ b/packages/core/src/components/group/group-context-menu.scss @@ -0,0 +1,25 @@ +/* + * SPDX-FileCopyrightText: 2022 Siemens AG + * + * SPDX-License-Identifier: MIT + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +:host { + display: block; + position: relative; + margin-block-start: 0.3125rem; + margin-inline-end: 0.3125rem; + margin-inline-start: auto; + + ix-icon-button { + &::after { + display: none; + } + } + + .hide { + visibility: collapse; + } +} diff --git a/packages/core/src/components/group/group-context-menu.tsx b/packages/core/src/components/group/group-context-menu.tsx new file mode 100644 index 00000000000..b52c451136a --- /dev/null +++ b/packages/core/src/components/group/group-context-menu.tsx @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2022 Siemens AG + * + * SPDX-License-Identifier: MIT + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { Component, Element, h, Host, State } from '@stencil/core'; + +@Component({ + tag: 'ix-group-context-menu', + styleUrl: './group-context-menu.scss', + scoped: true, +}) +export class GroupContextMenu { + @Element() host!: HTMLIxGroupContextMenuElement; + + @State() showContextMenu = false; + + private observer!: MutationObserver; + + get dropdownElement() { + return this.host.querySelector('ix-dropdown'); + } + + get groupDropdownItem() { + return this.host.querySelectorAll('ix-group-dropdown-item'); + } + + private configureDropdown(triggerElement: HTMLElement) { + this.dropdownElement.positioningStrategy = 'fixed'; + this.dropdownElement.trigger = triggerElement; + } + + componentWillRender() { + this.showContextMenu = !!this.dropdownElement; + } + + disconnectedCallback() { + this.observer.disconnect(); + } + + render() { + return ( + + + this.dropdownElement ? this.configureDropdown(ref) : null + } + size="24" + ghost={true} + icon="context-menu" + > + + + ); + } +} diff --git a/packages/core/src/components/group/group.scss b/packages/core/src/components/group/group.scss index 4c0950d1724..0bdc5b9e060 100644 --- a/packages/core/src/components/group/group.scss +++ b/packages/core/src/components/group/group.scss @@ -21,20 +21,6 @@ max-width: 19.75rem; border-color: var(--theme-group-item--border-color); - .group-header-context-button { - display: block; - position: relative; - margin-top: 5px; - margin-right: 5px; - margin-left: auto; - - ix-icon-button { - &::after { - display: none; - } - } - } - .group-header { height: 4rem; min-height: 4rem; diff --git a/packages/core/src/components/group/group.tsx b/packages/core/src/components/group/group.tsx index 3988e2a1330..dbaf7e884ce 100644 --- a/packages/core/src/components/group/group.tsx +++ b/packages/core/src/components/group/group.tsx @@ -228,17 +228,9 @@ export class Group { -
- (this.dropdownTriggerRef = ref)} - size="24" - ghost={true} - icon="context-menu" - > - - - -
+ + +
-## Properties - -| Property | Attribute | Description | Type | Default | -| ------------------------- | --------------------------- | ------------------------------------------------------------------------------ | --------- | ----------- | -| `collapsed` | `collapsed` | Whether the group is collapsed or expanded. Defaults to true. | `boolean` | `true` | -| `expandOnHeaderClick` | `expand-on-header-click` | Expand the group if the header is clicked | `boolean` | `false` | -| `header` | `header` | Group header | `string` | `undefined` | -| `index` | `index` | The index of the selected group entry. If undefined no group item is selected. | `number` | `undefined` | -| `selected` | `selected` | Whether the group is selected. | `boolean` | `undefined` | -| `subHeader` | `sub-header` | Group header subtitle | `string` | `undefined` | -| `suppressHeaderSelection` | `suppress-header-selection` | Prevent header from being selectable | `boolean` | `false` | - - -## Events - -| Event | Description | Type | -| ------------------ | ------------------------------------- | ---------------------- | -| `collapsedChanged` | Group collapsed | `CustomEvent` | -| `selectGroup` | Emits when whole group gets selected. | `CustomEvent` | -| `selectItem` | Emits when group item gets selected. | `CustomEvent` | - - ---------------------------------------------- diff --git a/packages/core/src/components/group/test/context-menu/index.html b/packages/core/src/components/group/test/context-menu/index.html new file mode 100644 index 00000000000..e17c64ca290 --- /dev/null +++ b/packages/core/src/components/group/test/context-menu/index.html @@ -0,0 +1,29 @@ + + + + + + + Stencil Component Starter + + + + + + + + + Test + Test + Test + + + + diff --git a/packages/core/src/components/group/test/group.e2e.ts b/packages/core/src/components/group/test/group.e2e.ts index 36785ae7419..06b3bb1e965 100644 --- a/packages/core/src/components/group/test/group.e2e.ts +++ b/packages/core/src/components/group/test/group.e2e.ts @@ -17,4 +17,14 @@ regressionTest.describe('group', () => { maxDiffPixelRatio: 0.05, }); }); + + regressionTest('with context menu', async ({ page }) => { + await page.goto('group/test/context-menu'); + await page.locator('ix-icon-button').click(); + expect(await page.screenshot({ fullPage: true })).toMatchSnapshot({ + maxDiffPixelRatio: 0.05, + }); + }); + + // ix-icon-button }); diff --git a/packages/core/src/components/group/test/group.e2e.ts-snapshots/group-with-context-menu-1-chromium---theme-classic-dark-linux.png b/packages/core/src/components/group/test/group.e2e.ts-snapshots/group-with-context-menu-1-chromium---theme-classic-dark-linux.png new file mode 100644 index 00000000000..829e9550105 Binary files /dev/null and b/packages/core/src/components/group/test/group.e2e.ts-snapshots/group-with-context-menu-1-chromium---theme-classic-dark-linux.png differ diff --git a/packages/core/src/components/group/test/group.e2e.ts-snapshots/group-with-context-menu-1-chromium---theme-classic-light-linux.png b/packages/core/src/components/group/test/group.e2e.ts-snapshots/group-with-context-menu-1-chromium---theme-classic-light-linux.png new file mode 100644 index 00000000000..6b59d04ee28 Binary files /dev/null and b/packages/core/src/components/group/test/group.e2e.ts-snapshots/group-with-context-menu-1-chromium---theme-classic-light-linux.png differ diff --git a/packages/core/src/components/my-component/my-component.tsx b/packages/core/src/components/my-component/my-component.tsx index e8e54b43cf1..1987e07526f 100644 --- a/packages/core/src/components/my-component/my-component.tsx +++ b/packages/core/src/components/my-component/my-component.tsx @@ -17,30 +17,17 @@ import { Component, h, Host } from '@stencil/core'; export class MyComponent { render() { return ( - - { - r.indeterminate = true; - }} - /> - - - - - - - - - - + + + + + + + + Test + Test + Test + ); } diff --git a/packages/documentation/docs/controls/group.md b/packages/documentation/docs/controls/group.md index 79c08d5db35..28dd10e8feb 100644 --- a/packages/documentation/docs/controls/group.md +++ b/packages/documentation/docs/controls/group.md @@ -71,6 +71,15 @@ import SourceAngularGroupContext from './../auto-generated/previews/angular/grou ### Group with context menu +:::note + +Please note that there is an issue with the slot rendering that can only be fixed with the next major version of Siemens iX. +Luckily there exists a workaround for rendering context menus inside the group component. + +::: + +To show a context menu place an `ix-dropdown` with `slot="dropdown"` combined with `ix-dropdown-item`'s inside the `ix-group-tag` tag. + diff --git a/packages/documentation/src/css/custom.css b/packages/documentation/src/css/custom.css index 36d8f8d3a9c..61e8226ed67 100644 --- a/packages/documentation/src/css/custom.css +++ b/packages/documentation/src/css/custom.css @@ -43,6 +43,11 @@ body { --bs-alert-bg: var(--theme-color-alarm) !important; } +.theme-admonition-note { + background-color: var(--theme-color-7) !important; + color: var(--theme-color-inv-std-text); +} + .theme-admonition-caution { background-color: var(--theme-color-warning) !important; color: var(--theme-color-inv-std-text); @@ -130,7 +135,6 @@ aside { background-color: #000028; } - .dropdown__menu { box-shadow: var(--theme-box-shadow-lvl-1) !important; } diff --git a/packages/html-test-app/src/preview-examples/group-context-menu.html b/packages/html-test-app/src/preview-examples/group-context-menu.html index 75e8c3e3e00..86bc52fe076 100644 --- a/packages/html-test-app/src/preview-examples/group-context-menu.html +++ b/packages/html-test-app/src/preview-examples/group-context-menu.html @@ -12,10 +12,10 @@ -
- - -
+ + + + diff --git a/packages/react-test-app/src/preview-examples/group-context-menu.tsx b/packages/react-test-app/src/preview-examples/group-context-menu.tsx index 6b6826da560..88e6c5ea4f4 100644 --- a/packages/react-test-app/src/preview-examples/group-context-menu.tsx +++ b/packages/react-test-app/src/preview-examples/group-context-menu.tsx @@ -7,16 +7,21 @@ * LICENSE file in the root directory of this source tree. */ -import { IxGroup, IxGroupDropdownItem, IxGroupItem } from '@siemens/ix-react'; +import { + IxDropdown, + IxDropdownItem, + IxGroup, + IxGroupItem, +} from '@siemens/ix-react'; import React from 'react'; export const GroupContextMenu: React.FC = () => { return ( -
- - -
+ + + + diff --git a/packages/react/src/components.ts b/packages/react/src/components.ts index c39aabf272e..0500bb5761f 100644 --- a/packages/react/src/components.ts +++ b/packages/react/src/components.ts @@ -32,6 +32,7 @@ export const IxFilterChip = /*@__PURE__*/createReactComponent('ix-flip-tile'); export const IxFlipTileContent = /*@__PURE__*/createReactComponent('ix-flip-tile-content'); export const IxGroup = /*@__PURE__*/createReactComponent('ix-group'); +export const IxGroupContextMenu = /*@__PURE__*/createReactComponent('ix-group-context-menu'); export const IxGroupDropdownItem = /*@__PURE__*/createReactComponent('ix-group-dropdown-item'); export const IxGroupItem = /*@__PURE__*/createReactComponent('ix-group-item'); export const IxIcon = /*@__PURE__*/createReactComponent('ix-icon');