Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion playwright/cps-accessibility.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,30 @@ const components: ComponentEntry[] = [
await page.waitForSelector('cps-tree-select');
await page.locator('cps-tree-select').first().click();
}
},
{
route: '/tree-table',
name: 'Tree table',
selector: 'cps-tree-table',
states: [
'Tree table 1',
'Tree table 2',
'Tree table 3',
'Tree table 4',
'Tree table 5',
'Tree table 6',
'Tree table 7',
'Tree table 8',
'Tree table 9',
'Tree table 10'
].map((tab) => ({
label: tab,
setup: async (page: Page) => {
await page.getByRole('tab', { name: tab, exact: true }).click();
await page.waitForSelector('cps-tree-table');
}
}))
}
// { route: '/tree-table', name: 'Tree table', selector: 'cps-tree-table' }
];

type Violations = Awaited<ReturnType<AxeBuilder['analyze']>>['violations'];
Expand Down
16 changes: 16 additions & 0 deletions projects/composition/src/app/api-data/cps-button.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,22 @@
"default": "",
"description": "Aria label for the button, used for accessibility, it takes precedence over label."
},
{
"name": "ariaHaspopup",
"optional": false,
"readonly": false,
"type": "string | null",
"default": "null",
"description": "Indicates that the button controls a popup element."
},
{
"name": "ariaExpanded",
"optional": false,
"readonly": false,
"type": "boolean | null",
"default": "null",
"description": "Indicates whether the controlled popup element is expanded or collapsed."
},
{
"name": "icon",
"optional": false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,68 @@
<app-component-docs-viewer [componentData]="componentData">
<!-- Example of component's usage -->
<div class="menu-group">
<cps-menu #standardMenu [items]="items" header="Menu header"> </cps-menu>
<cps-button label="Standard menu" (clicked)="standardMenu.toggle($event)">
<cps-menu
#standardMenu
[items]="items"
header="Menu header"
(menuShown)="isStandardMenuOpen = true"
(menuHidden)="isStandardMenuOpen = false">
</cps-menu>
<cps-button
label="Standard menu"
ariaHaspopup="menu"
[ariaExpanded]="isStandardMenuOpen"
(clicked)="standardMenu.toggle($event)">
</cps-button>

<cps-menu
#standardMenuNoHeader
[items]="items"
ariaLabel="Menu with aria label">
ariaLabel="Menu with aria label"
(menuShown)="isStandardMenuNoHeaderOpen = true"
(menuHidden)="isStandardMenuNoHeaderOpen = false">
</cps-menu>
<cps-button
label="Standard menu without header"
ariaHaspopup="menu"
[ariaExpanded]="isStandardMenuNoHeaderOpen"
(clicked)="standardMenuNoHeader.toggle($event)">
</cps-button>

<cps-menu
#compressedMenu
[items]="items"
[compressed]="true"
[withArrow]="false">
[withArrow]="false"
(menuShown)="isCompressedMenuOpen = true"
(menuHidden)="isCompressedMenuOpen = false">
</cps-menu>
<cps-button
label="Compressed menu"
ariaHaspopup="menu"
[ariaExpanded]="isCompressedMenuOpen"
(clicked)="compressedMenu.toggle($event)">
</cps-button>

<cps-menu
#compressedMenuNoIcons
[items]="itemsWithoutIcons"
[compressed]="true"
[withArrow]="false">
[withArrow]="false"
(menuShown)="isCompressedMenuNoIconsOpen = true"
(menuHidden)="isCompressedMenuNoIconsOpen = false">
</cps-menu>
<cps-button
label="Compressed menu without icons"
ariaHaspopup="menu"
[ariaExpanded]="isCompressedMenuNoIconsOpen"
(clicked)="compressedMenuNoIcons.toggle($event)">
</cps-button>

<cps-menu #arbitraryMenu>
<cps-menu
#arbitraryMenu
(menuShown)="isArbitraryMenuOpen = true"
(menuHidden)="isArbitraryMenuOpen = false">
<div class="my-menu-content">
<span>Provide your own content here</span>
<img
Expand All @@ -60,12 +85,22 @@
</cps-menu>
<cps-button
label="Menu with arbitrary content"
ariaHaspopup="menu"
[ariaExpanded]="isArbitraryMenuOpen"
(clicked)="arbitraryMenu.toggle($event)">
</cps-button>

<cps-menu #focusMenu [items]="items" [focusOnShow]="false"></cps-menu>
<cps-menu
#focusMenu
[items]="items"
[focusOnShow]="false"
(menuShown)="isFocusMenuOpen = true"
(menuHidden)="isFocusMenuOpen = false">
</cps-menu>
<cps-button
label="Menu that opens on focus"
ariaHaspopup="menu"
[ariaExpanded]="isFocusMenuOpen"
(focusin)="focusMenu.show(null, $event.target)"
(focusout)="onFocusMenuFocusOut($event, focusMenu)">
</cps-button>
Expand All @@ -74,10 +109,14 @@
#hoverMenu
[items]="items"
[focusOnShow]="false"
(menuShown)="isHoverMenuOpen = true"
(menuHidden)="isHoverMenuOpen = false"
(containerMouseLeave)="onMenuLeave($event, hoverMenu)">
</cps-menu>
<cps-button
label="Menu that opens on hover"
ariaHaspopup="menu"
[ariaExpanded]="isHoverMenuOpen"
(mouseenter)="hoverMenu.show($event)"
(mouseleave)="onMenuLeave($event, hoverMenu)"
(focusin)="hoverMenu.show(null, $event.target)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ export class MenuPageComponent {

componentData = ComponetnData;

isStandardMenuOpen = false;
isStandardMenuNoHeaderOpen = false;
isCompressedMenuOpen = false;
isCompressedMenuNoIconsOpen = false;
isArbitraryMenuOpen = false;
isFocusMenuOpen = false;
isHoverMenuOpen = false;

doConsoleLog(event: any) {
console.log(event.item.title + ' clicked');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
[showColumnsToggleBtn]="true"
[filterableByColumns]="true"
[resizableColumns]="true"
scrollHeight="500px"
scrollHeight="31.25rem"
toolbarTitle="Sortable tree table with resizable columns, virtual scroller, global filter, internal columns toggle and with column filtering enabled">
<ng-template #colgroup>
<colgroup>
Expand Down Expand Up @@ -190,7 +190,7 @@
(rowsToRemove)="onRowsToRemove($event)"
[selectable]="true"
toolbarSize="small"
scrollHeight="calc(100vh - 370px)"
scrollHeight="calc(100vh - 23.125rem)"
toolbarTitle="Tree table with nested header and small toolbar">
<ng-template #nestedHeader>
<tr>
Expand Down Expand Up @@ -326,7 +326,7 @@
<cps-tree-table
[data]="[]"
toolbarTitle="Empty tree table"
emptyBodyHeight="400px">
emptyBodyHeight="25rem">
<ng-template #header>
<th cpsTTColSortable="name">Name</th>
<th cpsTTColSortable="size">Size</th>
Expand All @@ -340,15 +340,15 @@
<cps-tree-table
[data]="data"
[loading]="true"
scrollHeight="400px"
scrollHeight="25rem"
[columns]="cols"
toolbarTitle="Tree table in data loading state">
</cps-tree-table>
</cps-tab>
<cps-tab label="Tree table 10">
<cps-tree-table
[data]="treeDataWithHTML"
scrollHeight="400px"
scrollHeight="25rem"
[columns]="colsHTML"
[renderDataAsHTML]="true"
toolbarTitle="Table containing HTML">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
(click)="onClick($event)"
[attr.aria-busy]="loading ? true : null"
[attr.aria-label]="ariaLabel || label || null"
[attr.aria-haspopup]="ariaHaspopup"
[attr.aria-expanded]="ariaExpanded"
[class.loading]="loading"
[class.cps-button--key-active]="enterActive"
(keydown.enter)="onEnterKeydown()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ export class CpsButtonComponent implements OnInit, OnChanges {
*/
@Input() ariaLabel = '';

/**
* Indicates that the button controls a popup element.
* @group Props
*/
@Input() ariaHaspopup: string | null = null;

/**
* Indicates whether the controlled popup element is expanded or collapsed.
* @group Props
*/
@Input() ariaExpanded: boolean | null = null;

/**
* Name of the icon on the button.
* @group Props
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
<button
type="button"
class="cps-table-tbar-icon-btn"
aria-label="Toggle column visibility"
aria-haspopup="listbox"
[attr.aria-expanded]="isMenuOpen()"
[disabled]="disabled()"
(click)="onToggle($event)">
<cps-icon
<div class="cps-table-tbar-coltoggle-btn">
<cps-button
ariaLabel="Toggle column visibility"
ariaHaspopup="listbox"
[ariaExpanded]="isMenuOpen()"
[disabled]="disabled()"
icon="columns"
size="normal"
[color]="disabled() ? 'text-lightest' : 'prepared-lighten1'"
aria-hidden="true"></cps-icon>
</button>
type="borderless"
color="calm"
(clicked)="onToggle($event)">
</cps-button>
</div>
<cps-menu
#menu
[withArrow]="false"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
.cps-table-tbar-coltoggle-btn {
margin-right: 0.125rem;
margin-left: 0.125rem;

::ng-deep .cps-button__icon {
width: 1.5rem !important;
height: 1.5rem !important;
}
}

.cps-table-coltoggle-menu {
display: block;
max-height: 15.125rem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,14 @@ describe('TableColumnVisibilityToggleComponent', () => {
describe('host class bindings', () => {
it('should always have cps-table-tbar-coltoggle-btn class', () => {
expect(
fixture.nativeElement.classList.contains('cps-table-tbar-coltoggle-btn')
).toBe(true);
fixture.nativeElement.querySelector('.cps-table-tbar-coltoggle-btn')
).toBeTruthy();
});
});

describe('toggle button', () => {
it('should render the toggle button', () => {
const btn = fixture.nativeElement.querySelector(
'button.cps-table-tbar-icon-btn'
);
const btn = fixture.nativeElement.querySelector('cps-button');
expect(btn).toBeTruthy();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { CommonModule } from '@angular/common';
import { isEqual } from 'lodash-es';
import { CpsMenuComponent } from '../../../../cps-menu/cps-menu.component';
import { CpsIconComponent } from '../../../../cps-icon/cps-icon.component';
import { CpsButtonComponent } from '../../../../cps-button/cps-button.component';
import { generateUniqueId } from '../../../../../utils/internal/accessibility-utils';

/**
Expand All @@ -20,13 +20,10 @@ import { generateUniqueId } from '../../../../../utils/internal/accessibility-ut
*/
@Component({
selector: 'table-column-visibility-toggle',
imports: [CommonModule, CpsMenuComponent, CpsIconComponent],
imports: [CommonModule, CpsMenuComponent, CpsButtonComponent],
templateUrl: './table-column-visibility-toggle.component.html',
styleUrls: ['./table-column-visibility-toggle.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
host: {
class: 'cps-table-tbar-coltoggle-btn'
}
changeDetection: ChangeDetectionStrategy.OnPush
})
export class TableColumnVisibilityToggleComponent {
columns = input<{ [key: string]: any }[]>([]);
Expand Down
Loading
Loading