Skip to content

Commit c38f57d

Browse files
authored
Columns Component (#1096)
* feat: column component
1 parent f0b1079 commit c38f57d

21 files changed

+1780
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
describe('Columns', () => {
2+
before(() => {
3+
cy.visit('/columns');
4+
cy.get('.page-loader').should('not.exist', { timeout: 20000 });
5+
});
6+
7+
describe('Columns', () => {
8+
it('displays the correct number of rows in first column', () => {
9+
cy.get('ngx-column').first().as('CUT');
10+
cy.get('@CUT').find('.column').should('have.length', 1);
11+
cy.get('@CUT').find('.ngx-list__virtual-scroll__item').should('have.length', 12);
12+
});
13+
14+
it('displays correct number of columns', () => {
15+
cy.get('ngx-column').should('have.length', 3);
16+
});
17+
18+
it('displays custom content when the row is clicked', () => {
19+
cy.get('ngx-column').eq(2).as('CUT');
20+
cy.get('@CUT').find('.ngx-list__virtual-scroll__item').first().click();
21+
cy.get('.column-expanded').find('h1').should('contain.text', 'Column Test Content');
22+
});
23+
});
24+
});

projects/swimlane/ngx-ui/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## HEAD (unreleased)
44

5+
- Feature (`ngx-column`): Added a new column component
6+
57
## 49.2.1 (2025-06-18)
68

79
- Fix (`ngx-calendar`): Improved Firefox compatibility by replacing outline: auto with outline: none
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
@if (!column?.content) {
2+
<header>
3+
<h4>{{ column?.title }}</h4>
4+
</header>
5+
}
6+
<div class="column">
7+
@if (column?.children) {
8+
<section class="column-list">
9+
<div class="search">
10+
<ngx-icon fontIcon="search" class="search-icon pull-left"></ngx-icon>
11+
<button class="btn btn-link pull-right" *ngIf="searchInputValue?.length > 0" (click)="searchInputValue = ''">
12+
<ngx-icon fontIcon="x"></ngx-icon>
13+
</button>
14+
<ngx-input
15+
#searchInput
16+
name="searchInputValue"
17+
placeholder="Search"
18+
(keyup)="onInputChange($event)"
19+
[disabled]="!column.children.length"
20+
></ngx-input>
21+
</div>
22+
@if (list) {
23+
24+
<cdk-virtual-scroll-viewport #virtualScrollViewport [style.height.px]="scrollerHeight()" itemSize="40">
25+
<div
26+
*cdkVirtualFor="let child of list; index as i"
27+
class="ngx-list__virtual-scroll__item"
28+
(click)="onChildClick(child.id)"
29+
(keyup)="onChildKeyup($event, child.id)"
30+
[ngClass]="{ active: child.active }"
31+
tabindex="0"
32+
>
33+
<span>{{ child.title }}</span>
34+
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13" fill="none">
35+
<path
36+
fill-rule="evenodd"
37+
clip-rule="evenodd"
38+
d="M3.36127 1.55979C3.65416 1.26689 4.12904 1.26689 4.42193 1.55979L8.6719 5.80976C8.9648 6.10265 8.9648 6.57753 8.6719 6.87042L4.42193 11.1204C4.12904 11.4133 3.65416 11.4133 3.36127 11.1204C3.06838 10.8275 3.06838 10.3527 3.36127 10.0598L7.08094 6.34009L3.36127 2.62039C3.06838 2.32749 3.06838 1.85269 3.36127 1.55979Z"
39+
fill="#CDD2DD"
40+
/>
41+
</svg>
42+
</div>
43+
</cdk-virtual-scroll-viewport>
44+
}
45+
</section>
46+
} @if (activeChild?.content) {
47+
<section class="column-expanded" #expandedSection [ngStyle]="{ width: activeChild.content.width }">
48+
<ng-container
49+
*ngComponentOutlet="
50+
activeChild.content.component;
51+
inputs: activeChild.content.inputs ? activeChild.content.inputs : {};
52+
outputs: activeChild.content.outputs ? activeChild.content.outputs : {};
53+
module: activeChild.content.module ? activeChild.content.module : {}
54+
"
55+
></ng-container>
56+
</section>
57+
}
58+
</div>
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
@use 'colors/colors' as colors;
2+
3+
.ngx-column {
4+
display: grid;
5+
grid-template-columns: 1fr;
6+
grid-template-rows: 44px auto;
7+
grid-column-gap: 0px;
8+
grid-row-gap: 0px;
9+
10+
header {
11+
display: flex;
12+
align-items: center;
13+
height: 44px;
14+
width: 100%;
15+
padding: 6px 16px;
16+
color: colors.$color-blue-grey-250;
17+
border-bottom: 1px solid colors.$color-blue-grey-700;
18+
border-right: 1px solid colors.$color-blue-grey-700;
19+
20+
h4 {
21+
font-family: 'Source Sans Pro';
22+
font-size: 14px;
23+
font-style: normal;
24+
font-weight: 600;
25+
line-height: 18px;
26+
margin-top: 0px;
27+
margin-bottom: 0px;
28+
}
29+
}
30+
31+
.column {
32+
display: flex;
33+
min-height: 100%;
34+
width: 100%;
35+
}
36+
37+
section.column-list {
38+
min-width: 186px;
39+
overflow: hidden;
40+
padding: 6px 8px 6px 8px;
41+
border-right: 1px solid colors.$color-blue-grey-700;
42+
43+
.search {
44+
position: sticky;
45+
margin-top: 6px;
46+
margin-bottom: 0px ngx-input {
47+
margin: 0px 2px 0px 8px;
48+
}
49+
50+
.ngx-input .ngx-input-wrap .ngx-input-box-wrap .ngx-input-box {
51+
margin: 0px 0px 0px 4px;
52+
}
53+
54+
ngx-icon {
55+
color: colors.$color-blue-grey-300;
56+
margin-top: 5px;
57+
margin-left: 8px;
58+
}
59+
}
60+
61+
cdk-virtual-scroll-viewport {
62+
margin-left: 4px;
63+
margin-right: -10px;
64+
padding: 0;
65+
list-style-type: none;
66+
display: grid;
67+
gap: 4px;
68+
overflow-x: hidden;
69+
overflow-y: scroll;
70+
71+
.ngx-list__virtual-scroll__item {
72+
display: block;
73+
margin: 0;
74+
padding: 0;
75+
display: flex;
76+
justify-content: space-between;
77+
align-items: center;
78+
padding: 6px 4px 6px 4px;
79+
height: 40px;
80+
cursor: pointer;
81+
82+
span {
83+
overflow: hidden;
84+
color: colors.$color-blue-grey-150;
85+
text-overflow: ellipsis;
86+
font-family: Source Sans Pro, Open Sans, Arial, sans-serif;
87+
font-size: 14px;
88+
font-style: normal;
89+
font-weight: 400;
90+
line-height: 18px;
91+
}
92+
93+
svg {
94+
fill: colors.$color-blue-grey-100;
95+
}
96+
97+
&.active {
98+
border-radius: 6px;
99+
background-color: colors.$color-blue-grey-650;
100+
101+
span {
102+
color: colors.$color-white;
103+
}
104+
105+
svg {
106+
fill: colors.$color-white;
107+
}
108+
}
109+
}
110+
}
111+
}
112+
113+
section.column-expanded {
114+
overflow: auto;
115+
}
116+
117+
&:not(.expanded) {
118+
flex: 0 0 186px;
119+
}
120+
121+
&.expanded {
122+
flex: 1 1 0%;
123+
124+
header {
125+
border-right: none;
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)