From 6daa3549aef64d746fdd03030321d8681277b06d Mon Sep 17 00:00:00 2001 From: Andrei Fateev Date: Fri, 17 Jul 2026 11:47:54 +0200 Subject: [PATCH 1/3] docs: add code examples for Menu, Notifications and Paginator --- .../pages/menu-page/menu-page.component.html | 37 ++- .../pages/menu-page/menu-page.component.scss | 9 - .../pages/menu-page/menu-page.component.ts | 11 +- .../app/pages/menu-page/menu-page.examples.ts | 281 ++++++++++++++++++ .../notification-page.component.html | 155 ++++++---- .../notification-page.component.scss | 25 +- .../notification-page.component.ts | 10 +- .../notification-page.examples.ts | 190 ++++++++++++ .../paginator-page.component.html | 5 +- .../paginator-page.component.ts | 10 +- .../paginator-page/paginator-page.examples.ts | 7 + 11 files changed, 647 insertions(+), 93 deletions(-) create mode 100644 projects/composition/src/app/pages/menu-page/menu-page.examples.ts create mode 100644 projects/composition/src/app/pages/notification-page/notification-page.examples.ts create mode 100644 projects/composition/src/app/pages/paginator-page/paginator-page.examples.ts diff --git a/projects/composition/src/app/pages/menu-page/menu-page.component.html b/projects/composition/src/app/pages/menu-page/menu-page.component.html index 02877be5b..50f7846e1 100644 --- a/projects/composition/src/app/pages/menu-page/menu-page.component.html +++ b/projects/composition/src/app/pages/menu-page/menu-page.component.html @@ -1,6 +1,9 @@ - + diff --git a/projects/composition/src/app/pages/menu-page/menu-page.component.scss b/projects/composition/src/app/pages/menu-page/menu-page.component.scss index 6c16cd938..86007e80d 100644 --- a/projects/composition/src/app/pages/menu-page/menu-page.component.scss +++ b/projects/composition/src/app/pages/menu-page/menu-page.component.scss @@ -1,12 +1,3 @@ -.menu-group { - gap: 2rem; - margin-left: 0.5rem; - margin-right: 0.5rem; - margin-bottom: 0.5rem; - display: flex; - flex-direction: column; -} - .my-menu-content { display: flex; flex-direction: column; diff --git a/projects/composition/src/app/pages/menu-page/menu-page.component.ts b/projects/composition/src/app/pages/menu-page/menu-page.component.ts index b084029ca..6f363ff94 100644 --- a/projects/composition/src/app/pages/menu-page/menu-page.component.ts +++ b/projects/composition/src/app/pages/menu-page/menu-page.component.ts @@ -1,16 +1,23 @@ import { Component } from '@angular/core'; import { CpsButtonComponent, CpsMenuComponent, CpsMenuItem } from 'cps-ui-kit'; import { ComponentDocsViewerComponent } from '../../components/component-docs-viewer/component-docs-viewer.component'; - +import { CodeExampleComponent } from '../../components/code-example/code-example.component'; import ComponetnData from '../../api-data/cps-menu.json'; +import { menuExamples } from './menu-page.examples'; @Component({ selector: 'app-menu-page', - imports: [CpsMenuComponent, CpsButtonComponent, ComponentDocsViewerComponent], + imports: [ + CpsMenuComponent, + CpsButtonComponent, + ComponentDocsViewerComponent, + CodeExampleComponent + ], templateUrl: './menu-page.component.html', styleUrls: ['./menu-page.component.scss'], host: { class: 'composition-page' } }) export class MenuPageComponent { + readonly examples = menuExamples; items: CpsMenuItem[] = [ { title: 'First item', diff --git a/projects/composition/src/app/pages/menu-page/menu-page.examples.ts b/projects/composition/src/app/pages/menu-page/menu-page.examples.ts new file mode 100644 index 000000000..55bbc394a --- /dev/null +++ b/projects/composition/src/app/pages/menu-page/menu-page.examples.ts @@ -0,0 +1,281 @@ +const menuItemsTs = ` +items: CpsMenuItem[] = [ + { + title: 'First item', + desc: 'First item description', + icon: 'remove', + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + title: 'Second item', + desc: 'Second item is disabled', + icon: 'bell', + disabled: true, + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + title: 'Third item', + icon: 'browse', + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + title: 'Fourth item', + desc: 'Fourth item description', + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + title: 'Fifth item', + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + ariaLabel: 'Sixth item is loading', + loading: true + }, + { + title: 'Go google', + url: 'https://google.com', + target: '_blank' + } +]; + +doConsoleLog(event: any) { + console.log(event.item.title + ' clicked'); +}`; + +const itemsWithoutIconsTs = ` +itemsWithoutIcons: CpsMenuItem[] = [ + { + title: 'First item', + desc: 'First item description', + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + title: 'Second item', + desc: 'Second item is disabled', + disabled: true, + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + title: 'Third item', + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + title: 'Fourth item', + desc: 'Fourth item description', + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + title: 'Fifth item', + action: (event: any) => { + this.doConsoleLog(event); + } + }, + { + ariaLabel: 'Sixth item is loading', + loading: true + }, + { + title: 'Go google', + url: 'https://google.com', + target: '_blank' + } +]; + +doConsoleLog(event: any) { + console.log(event.item.title + ' clicked'); +}`; + +export const menuExamples: Record = { + standardMenu: { + html: ` + + + +`, + ts: ` +${menuItemsTs.trim()} + +isStandardMenuOpen = false;` + }, + + standardMenuNoHeader: { + html: ` + + + +`, + ts: ` +${menuItemsTs.trim()} + +isStandardMenuNoHeaderOpen = false;` + }, + + compressedMenu: { + html: ` + + + +`, + ts: ` +${menuItemsTs.trim()} + +isCompressedMenuOpen = false;` + }, + + compressedMenuNoIcons: { + html: ` + + + +`, + ts: ` +${itemsWithoutIconsTs.trim()} + +isCompressedMenuNoIconsOpen = false;` + }, + + arbitraryContentMenu: { + html: ` + +
+ Provide your own content here + kitten + Google + Bing +
+
+ +`, + ts: ` +isArbitraryMenuOpen = false;` + }, + + openOnFocusMenu: { + html: ` + + + +`, + ts: ` +${menuItemsTs.trim()} + +isFocusMenuOpen = false; + +onFocusMenuFocusOut(event: FocusEvent, menu: CpsMenuComponent) { + if (!menu.container?.contains(event.relatedTarget as Node)) { + menu.hide(); + } +}` + }, + + openOnHoverMenu: { + html: ` + + + +`, + ts: ` +${menuItemsTs.trim()} + +isHoverMenuOpen = false; + +onMenuLeave(event: MouseEvent | FocusEvent, menu: CpsMenuComponent) { + const rel = event.relatedTarget as Node; + if ( + !menu.container?.contains(rel) && + !(menu.target as HTMLElement)?.contains(rel) + ) { + menu.hide(); + } +}` + } +}; diff --git a/projects/composition/src/app/pages/notification-page/notification-page.component.html b/projects/composition/src/app/pages/notification-page/notification-page.component.html index 27df269db..d3aa739e8 100644 --- a/projects/composition/src/app/pages/notification-page/notification-page.component.html +++ b/projects/composition/src/app/pages/notification-page/notification-page.component.html @@ -1,65 +1,108 @@ -
-
-
Basic notifications
-
- - - - -
-
-
-
Configured notifications
-
- - - - -
-
+

Basic notifications

+ + + + + + + + + + + + + + + + +

Configured notifications

+ + + + + + + + + + + + + + + + + -
+
diff --git a/projects/composition/src/app/pages/notification-page/notification-page.component.scss b/projects/composition/src/app/pages/notification-page/notification-page.component.scss index 443b20a59..e9710b475 100644 --- a/projects/composition/src/app/pages/notification-page/notification-page.component.scss +++ b/projects/composition/src/app/pages/notification-page/notification-page.component.scss @@ -1,23 +1,10 @@ :host { - .notification-btns-group { - gap: 1.875rem; - margin-left: 0.5rem; - margin-right: 0.5rem; - margin-bottom: 0.5rem; - display: flex; - flex-direction: column; - - &-title { - font-size: 1.5rem; - color: var(--cps-color-depth); - border-bottom: 0.0625rem solid lightgrey; - margin-bottom: 0.75rem; - padding-bottom: 0.5rem; - font-weight: 600; - } + .section-title { + color: var(--cps-color-depth); + margin-top: 0; } - .notification-btns-last-group { - padding-bottom: 0.75rem; - border-bottom: 0.0625rem solid lightgrey; + + .section-title:not(:first-child) { + margin-top: 3rem; } } diff --git a/projects/composition/src/app/pages/notification-page/notification-page.component.ts b/projects/composition/src/app/pages/notification-page/notification-page.component.ts index 46eeec9f6..8be79e67e 100644 --- a/projects/composition/src/app/pages/notification-page/notification-page.component.ts +++ b/projects/composition/src/app/pages/notification-page/notification-page.component.ts @@ -5,19 +5,25 @@ import { CpsNotificationPosition, CpsNotificationService } from 'cps-ui-kit'; - import ServiceData from '../../api-data/cps-notification.json'; import { ServiceDocsViewerComponent } from '../../components/service-docs-viewer/service-docs-viewer.component'; +import { CodeExampleComponent } from '../../components/code-example/code-example.component'; +import { notificationExamples } from './notification-page.examples'; @Component({ selector: 'app-notification-page', - imports: [CpsButtonComponent, ServiceDocsViewerComponent], + imports: [ + CpsButtonComponent, + ServiceDocsViewerComponent, + CodeExampleComponent + ], templateUrl: './notification-page.component.html', styleUrls: ['./notification-page.component.scss'], host: { class: 'composition-page' } }) export class NotificationPageComponent { serviceData = ServiceData; + readonly examples = notificationExamples; // eslint-disable-next-line no-useless-constructor constructor(private _notifService: CpsNotificationService) {} diff --git a/projects/composition/src/app/pages/notification-page/notification-page.examples.ts b/projects/composition/src/app/pages/notification-page/notification-page.examples.ts new file mode 100644 index 000000000..8643efe73 --- /dev/null +++ b/projects/composition/src/app/pages/notification-page/notification-page.examples.ts @@ -0,0 +1,190 @@ +const notifServiceTs = `private readonly _notifService = inject(CpsNotificationService);`; + +export const notificationExamples: Record< + string, + { html: string; ts?: string } +> = { + infoNotification: { + html: ` +`, + ts: ` +${notifServiceTs} + +counter = 0; + +showInfoNotification() { + this._notifService.info(\`Notification message \${this.counter}\`); + this.counter += 1; +}` + }, + + errorNotification: { + html: ` +`, + ts: ` +${notifServiceTs} + +counter = 0; + +showErrorNotification() { + this._notifService.error(\`Notification message \${this.counter}\`); + this.counter += 1; +}` + }, + + successNotification: { + html: ` +`, + ts: ` +${notifServiceTs} + +counter = 0; + +showSuccessNotification() { + this._notifService.success(\`Notification message \${this.counter}\`); + this.counter += 1; +}` + }, + + warningNotification: { + html: ` +`, + ts: ` +${notifServiceTs} + +counter = 0; + +showWarningNotification() { + this._notifService.warning(\`Notification message \${this.counter}\`); + this.counter += 1; +}` + }, + + infoNotificationWithDetails: { + html: ` +`, + ts: ` +${notifServiceTs} + +counter = 0; + +showInfoNotificationWithDetails() { + this._notifService.info( + \`Notification message \${this.counter}\`, + 'Notification details', + { position: CpsNotificationPosition.BOTTOM } + ); + this.counter += 1; +}` + }, + + errorRightMax3Notification: { + html: ` +`, + ts: ` +${notifServiceTs} + +counter = 0; + +showErrorRightWithMax3Notification() { + this._notifService.error( + \`Notification message \${this.counter}\`, + 'Http failure response for https://my-long-url/epic/fail: 404 Not Found Error', + { + position: CpsNotificationPosition.RIGHT, + maxWidth: '28rem', + maxAmount: 3 + } + ); + this.counter += 1; +}` + }, + + bottomLeftPersistentOutlinedSuccessNotification: { + html: ` +`, + ts: ` +${notifServiceTs} + +counter = 0; + +showOutlinedBottomLeftPersistentSuccessNotification() { + this._notifService.success(\`Notification message \${this.counter}\`, '', { + timeout: 0, + position: CpsNotificationPosition.BOTTOMLEFT, + appearance: CpsNotificationAppearance.OUTLINED + }); + this.counter += 1; +}` + }, + + bottomRightOutlinedWarningNotification: { + html: ` +`, + ts: ` +${notifServiceTs} + +counter = 0; + +showOutlinedBottomRight2sTimeoutWarningNotification() { + this._notifService.warning( + \`Notification message \${this.counter}\`, + 'Notifications details', + { + timeout: 2000, + position: CpsNotificationPosition.BOTTOMRIGHT, + appearance: CpsNotificationAppearance.OUTLINED + } + ); + this.counter += 1; +}` + }, + + clearAllNotifications: { + html: ` + +`, + ts: ` +${notifServiceTs} + +clearNotifications(): void { + this._notifService.clear(); +}` + } +}; diff --git a/projects/composition/src/app/pages/paginator-page/paginator-page.component.html b/projects/composition/src/app/pages/paginator-page/paginator-page.component.html index 9064e056c..9989bdaa8 100644 --- a/projects/composition/src/app/pages/paginator-page/paginator-page.component.html +++ b/projects/composition/src/app/pages/paginator-page/paginator-page.component.html @@ -1,4 +1,7 @@ - + + + + diff --git a/projects/composition/src/app/pages/paginator-page/paginator-page.component.ts b/projects/composition/src/app/pages/paginator-page/paginator-page.component.ts index 8b8b4cca4..d71c78978 100644 --- a/projects/composition/src/app/pages/paginator-page/paginator-page.component.ts +++ b/projects/composition/src/app/pages/paginator-page/paginator-page.component.ts @@ -1,16 +1,22 @@ import { Component } from '@angular/core'; import { CpsPaginatorComponent } from 'cps-ui-kit'; import { ComponentDocsViewerComponent } from '../../components/component-docs-viewer/component-docs-viewer.component'; - +import { CodeExampleComponent } from '../../components/code-example/code-example.component'; import ComponentData from '../../api-data/cps-paginator.json'; +import { paginatorExamples } from './paginator-page.examples'; @Component({ selector: 'app-paginator-page', - imports: [CpsPaginatorComponent, ComponentDocsViewerComponent], + imports: [ + CpsPaginatorComponent, + ComponentDocsViewerComponent, + CodeExampleComponent + ], templateUrl: './paginator-page.component.html', styleUrls: ['./paginator-page.component.scss'], host: { class: 'composition-page' } }) export class PaginatorPageComponent { componentData = ComponentData; + readonly examples = paginatorExamples; } diff --git a/projects/composition/src/app/pages/paginator-page/paginator-page.examples.ts b/projects/composition/src/app/pages/paginator-page/paginator-page.examples.ts new file mode 100644 index 000000000..4e1a72ea4 --- /dev/null +++ b/projects/composition/src/app/pages/paginator-page/paginator-page.examples.ts @@ -0,0 +1,7 @@ +export const paginatorExamples: Record = + { + basicUsage: { + html: ` +` + } + }; From 82d213b058f5a92b82508b21ff50a130730d9cc4 Mon Sep 17 00:00:00 2001 From: Andrei Fateev Date: Fri, 17 Jul 2026 12:15:39 +0200 Subject: [PATCH 2/3] address feedback --- .../src/app/pages/menu-page/menu-page.component.ts | 4 ++-- .../notification-page/notification-page.component.ts | 8 ++++---- .../pages/notification-page/notification-page.examples.ts | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/projects/composition/src/app/pages/menu-page/menu-page.component.ts b/projects/composition/src/app/pages/menu-page/menu-page.component.ts index 6f363ff94..15fdea22d 100644 --- a/projects/composition/src/app/pages/menu-page/menu-page.component.ts +++ b/projects/composition/src/app/pages/menu-page/menu-page.component.ts @@ -2,7 +2,7 @@ import { Component } from '@angular/core'; import { CpsButtonComponent, CpsMenuComponent, CpsMenuItem } from 'cps-ui-kit'; import { ComponentDocsViewerComponent } from '../../components/component-docs-viewer/component-docs-viewer.component'; import { CodeExampleComponent } from '../../components/code-example/code-example.component'; -import ComponetnData from '../../api-data/cps-menu.json'; +import ComponentData from '../../api-data/cps-menu.json'; import { menuExamples } from './menu-page.examples'; @Component({ selector: 'app-menu-page', @@ -113,7 +113,7 @@ export class MenuPageComponent { } ]; - componentData = ComponetnData; + componentData = ComponentData; isStandardMenuOpen = false; isStandardMenuNoHeaderOpen = false; diff --git a/projects/composition/src/app/pages/notification-page/notification-page.component.ts b/projects/composition/src/app/pages/notification-page/notification-page.component.ts index 8be79e67e..ae6debe42 100644 --- a/projects/composition/src/app/pages/notification-page/notification-page.component.ts +++ b/projects/composition/src/app/pages/notification-page/notification-page.component.ts @@ -1,4 +1,4 @@ -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { CpsButtonComponent, CpsNotificationAppearance, @@ -22,10 +22,10 @@ import { notificationExamples } from './notification-page.examples'; host: { class: 'composition-page' } }) export class NotificationPageComponent { + private readonly _notifService = inject(CpsNotificationService); + serviceData = ServiceData; readonly examples = notificationExamples; - // eslint-disable-next-line no-useless-constructor - constructor(private _notifService: CpsNotificationService) {} counter = 0; showSuccessNotification() { @@ -69,7 +69,7 @@ export class NotificationPageComponent { showOutlinedBottomRight2sTimeoutWarningNotification() { this._notifService.warning( `Notification message ${this.counter}`, - 'Notifications details', + 'Notification details', { timeout: 2000, position: CpsNotificationPosition.BOTTOMRIGHT, diff --git a/projects/composition/src/app/pages/notification-page/notification-page.examples.ts b/projects/composition/src/app/pages/notification-page/notification-page.examples.ts index 8643efe73..cd412acaf 100644 --- a/projects/composition/src/app/pages/notification-page/notification-page.examples.ts +++ b/projects/composition/src/app/pages/notification-page/notification-page.examples.ts @@ -161,7 +161,7 @@ counter = 0; showOutlinedBottomRight2sTimeoutWarningNotification() { this._notifService.warning( \`Notification message \${this.counter}\`, - 'Notifications details', + 'Notification details', { timeout: 2000, position: CpsNotificationPosition.BOTTOMRIGHT, From cd0b67f85ac8f1a50a1f40bb6301656f79f7d489 Mon Sep 17 00:00:00 2001 From: Andrei Fateev Date: Fri, 17 Jul 2026 12:22:06 +0200 Subject: [PATCH 3/3] fix pw tests --- playwright/fixtures/composition-components.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/playwright/fixtures/composition-components.ts b/playwright/fixtures/composition-components.ts index 15501f27b..750f3e4ba 100644 --- a/playwright/fixtures/composition-components.ts +++ b/playwright/fixtures/composition-components.ts @@ -150,7 +150,10 @@ export const components: ComponentEntry[] = [ group: 'Menu', setup: async (page) => { await page.waitForSelector('.example-content'); - await page.locator('.example-content cps-button').first().click(); + await page + .locator('.example-content cps-button:not(.code-example__copy)') + .first() + .click(); } }, { @@ -160,7 +163,10 @@ export const components: ComponentEntry[] = [ group: 'Menu', setup: async (page) => { await page.waitForSelector('.example-content'); - await page.locator('.example-content cps-button').nth(2).click(); + await page + .locator('.example-content cps-button:not(.code-example__copy)') + .nth(2) + .click(); } }, { @@ -170,7 +176,7 @@ export const components: ComponentEntry[] = [ setup: async (page) => { await page.waitForSelector('.example-content'); const buttons = page - .locator('.example-content cps-button') + .locator('.example-content cps-button:not(.code-example__copy)') .filter({ hasNotText: /clear all/i }); const count = await buttons.count(); for (let i = 0; i < count; i++) {