Skip to content

Commit 0dcec75

Browse files
author
Sara Dahan
committed
chore(label-group): apply the reqeasted changes
1 parent 37a1cb6 commit 0dcec75

File tree

6 files changed

+113
-47
lines changed

6 files changed

+113
-47
lines changed

.changeset/yummy-eagles-itch.md

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,13 @@
22
"@patternfly/elements": minor
33
---
44

5-
Introduced `<pf-label-group>` with add-label functionality.
5+
✨ Added `<pf-label-group>`.
6+
67

78
A label group displays multiple labels together, helping users visualize related categories, filters, or items.
89
Each label can be removed individually, and the entire group can also be cleared at once.
910
The element automatically handles overflow for long lists of labels and supports both horizontal and vertical layouts.
1011

11-
This release adds support for **adding new labels** dynamically through different modes:
12-
13-
- `none`: No add-label UI.
14-
- `autoNoEdit`: Automatically adds a new label without user input.
15-
- `fromList`: Shows a dropdown list of predefined labels to choose from.
16-
- `customForm`: Opens a custom form for entering a new label's text, color, icon, and dismissable option.
17-
1812
Use this when you need to show multiple tags, filters, or categorized items that users can remove, add, or adjust dynamically.
1913
Avoid using it for single, standalone labels — consider using `<pf-label>` instead.
2014

@@ -24,4 +18,4 @@ Avoid using it for single, standalone labels — consider using `<pf-label>` ins
2418
<pf-label removable>Performance</pf-label>
2519
<pf-label removable>Networking</pf-label>
2620
</pf-label-group>
27-
21+
```

elements/pf-label-group/demo/label-group-add-label-auto.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ <h2 slot="category">group name</h2>
99
import '@patternfly/elements/pf-label-group/pf-label-group.js';
1010
import '@patternfly/elements/pf-label/pf-label.js';
1111
import '@patternfly/elements/pf-button/pf-button.js';
12-
import '@patternfly/elements/pf-modal/pf-modal.js';
12+
import '@patternfly/elements/pf-modal/pf-modal.js';
1313
import '@patternfly/elements/pf-dropdown/pf-dropdown.js';
1414
</script>

elements/pf-label-group/demo/label-group-add-label-custom-form.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ <h2 slot="category">group name</h2>
99
import '@patternfly/elements/pf-label-group/pf-label-group.js';
1010
import '@patternfly/elements/pf-label/pf-label.js';
1111
import '@patternfly/elements/pf-button/pf-button.js';
12-
import '@patternfly/elements/pf-modal/pf-modal.js';
12+
import '@patternfly/elements/pf-modal/pf-modal.js';
1313
import '@patternfly/elements/pf-dropdown/pf-dropdown.js';
1414
</script>

elements/pf-label-group/demo/label-group-add-label-from-list.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ <h2 slot="category">group name</h2>
99
import '@patternfly/elements/pf-label-group/pf-label-group.js';
1010
import '@patternfly/elements/pf-label/pf-label.js';
1111
import '@patternfly/elements/pf-button/pf-button.js';
12-
import '@patternfly/elements/pf-modal/pf-modal.js';
12+
import '@patternfly/elements/pf-modal/pf-modal.js';
1313
import '@patternfly/elements/pf-dropdown/pf-dropdown.js';
1414
</script>

elements/pf-label-group/pf-label-group.ts

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ export class PfLabelGroupExpandEvent extends Event {
2222
}
2323
}
2424

25+
/**
26+
* Event fired when the label group is removed/closed.
27+
*/
28+
export class PfLabelGroupRemoveEvent extends Event {
29+
constructor() {
30+
super('remove', { bubbles: true, cancelable: true, composed: true });
31+
}
32+
}
33+
2534
/**
2635
* A **label group** is a collection of labels that can be grouped by category
2736
* and used to represent one or more values assigned to a single attribute.
@@ -52,26 +61,25 @@ export class PfLabelGroup extends LitElement {
5261
};
5362

5463
/**
55-
* Orientation of the label group.
56-
*/
64+
* Orientation of the label group.
65+
*/
5766
@property() orientation: 'horizontal' | 'vertical' = 'horizontal';
5867

5968
/**
6069
* Accessible label for the label group when no category name is provided.
6170
* @default ''
6271
*/
6372
@property({ attribute: 'accessible-label', type: String }) accessibleLabel = '';
64-
6573
/**
66-
* Accessible label for the close button.
67-
* @default 'Close'
68-
*/
74+
* Accessible label for the close button.
75+
* @default 'Close'
76+
*/
6977
@property({ attribute: 'accessible-close-label', type: String }) accessibleCloseLabel = 'Close';
7078

7179
/**
72-
* Text for collapsed overflow label. Use `${remaining}` to indicate number of hidden labels.
73-
* @default '${remaining} more'
74-
*/
80+
* Text for collapsed overflow label. Use `${remaining}` to indicate number of hidden labels.
81+
* @default '${remaining} more'
82+
*/
7583
@property({ attribute: 'collapsed-text', type: String }) collapsedText = '${remaining} more';
7684

7785
/**
@@ -81,53 +89,53 @@ export class PfLabelGroup extends LitElement {
8189
@property({ attribute: 'expanded-text', type: String }) expandedText = 'show less';
8290

8391
/**
84-
* Number of labels to show before creating an overflow label.
85-
* @default 3
86-
*/
92+
* Number of labels to show before creating an overflow label.
93+
* @default 3
94+
*/
8795
@property({ attribute: 'num-labels', type: Number }) numLabels = 3;
8896

8997
/**
90-
* Whether the overflow labels are visible (expanded state).
91-
* @default false
92-
*/
98+
* Whether the overflow labels are visible (expanded state).
99+
* @default false
100+
*/
93101
@property({ reflect: true, type: Boolean }) open = false;
94102

95103
/**
96-
* Whether the label group can be closed.
97-
* @default true
98-
*/
104+
* Whether the label group can be closed.
105+
* @default true
106+
*/
99107
@property({ reflect: true, type: Boolean }) closeable = false;
100108

101109
/** --- ADD LABEL FUNCTIONALITY --- */
102110

103111
/**
104-
* Mode controlling how labels can be added.
105-
* - `none`: No add label functionality
106-
* - `autoNoEdit`: Adds a default label automatically
107-
* - `fromList`: Allows choosing a label from a predefined list
108-
* - `customForm`: Opens a form for custom label creation
109-
*/
112+
* Mode controlling how labels can be added.
113+
* - `none`: No add label functionality
114+
* - `autoNoEdit`: Adds a default label automatically
115+
* - `fromList`: Allows choosing a label from a predefined list
116+
* - `customForm`: Opens a form for custom label creation
117+
*/
110118
@property({ type: String, reflect: true, attribute: 'add-label-mode' })
111119
addLabelMode: 'none' | 'autoNoEdit' | 'fromList' | 'customForm' = 'none';
112120

113121
/**
114-
* Controls visibility of the label dropdown for `fromList` mode.
115-
*/
122+
* Controls visibility of the label dropdown for `fromList` mode.
123+
*/
116124
@state() showDropdown = false;
117125

118126
/**
119-
* Controls visibility of the custom label form for `customForm` mode.
120-
*/
127+
* Controls visibility of the custom label form for `customForm` mode.
128+
*/
121129
@state() showCustomForm = false;
122130

123131
/**
124-
* Text value for a new custom label.
125-
*/
132+
* Text value for a new custom label.
133+
*/
126134
@state() newLabelText = 'Text box';
127135

128136
/**
129-
* Color value for a new custom label.
130-
*/
137+
* Color value for a new custom label.
138+
*/
131139
@state() newLabelColor = 'grey';
132140

133141
/**
@@ -356,8 +364,8 @@ export class PfLabelGroup extends LitElement {
356364
}
357365

358366
/**
359-
* Handles overflow label's click event.
360-
* @param {Event} event - Click event
367+
* Handles overflow label's click event.
368+
* @param {Event} event - Click event
361369
*/
362370
async #onMoreClick(event: Event) {
363371
event.stopPropagation();
@@ -376,6 +384,7 @@ export class PfLabelGroup extends LitElement {
376384
*/
377385
#onCloseClick() {
378386
if (this.isConnected) {
387+
this.dispatchEvent(new PfLabelGroupRemoveEvent());
379388
this.remove();
380389
}
381390
}

elements/pf-label-group/test/pf-label-group.spec.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { expect, html } from '@open-wc/testing';
22
import { createFixture } from '@patternfly/pfe-tools/test/create-fixture.js';
33
import { PfLabelGroup } from '@patternfly/elements/pf-label-group/pf-label-group.js';
4+
import { PfLabel } from '@patternfly/elements/pf-label/pf-label.js';
45

56
describe('<pf-label-group>', function() {
7+
let element: PfLabelGroup;
8+
69
describe('simply instantiating', function() {
7-
let element: PfLabelGroup;
810
it('imperatively instantiates', function() {
911
expect(document.createElement('pf-label-group')).to.be.an.instanceof(PfLabelGroup);
1012
});
@@ -18,4 +20,65 @@ describe('<pf-label-group>', function() {
1820
.to.be.an.instanceOf(PfLabelGroup);
1921
});
2022
});
23+
24+
describe('basic behavior', function() {
25+
beforeEach(async function() {
26+
element = await createFixture<PfLabelGroup>(html`
27+
<pf-label-group num-labels="2">
28+
<pf-label>one</pf-label>
29+
<pf-label>two</pf-label>
30+
<pf-label>three</pf-label>
31+
<pf-label>four</pf-label>
32+
</pf-label-group>
33+
`);
34+
await element.updateComplete;
35+
});
36+
37+
it('renders an overflow label when remaining > 0', async function() {
38+
const overflow = element.shadowRoot?.querySelector('#overflow') as HTMLElement;
39+
expect(overflow).to.be.ok;
40+
expect(overflow.hidden).to.be.false;
41+
expect(overflow.textContent?.trim()).to.equal('2 more');
42+
});
43+
44+
it('hides labels beyond num-labels when closed', function() {
45+
const labels = Array.from(element.querySelectorAll('pf-label')) as PfLabel[];
46+
expect(labels.length).to.equal(4);
47+
expect(labels[0].hidden).to.be.false;
48+
expect(labels[1].hidden).to.be.false;
49+
expect(labels[2].hidden).to.be.true;
50+
expect(labels[3].hidden).to.be.true;
51+
});
52+
53+
it('toggles open on overflow click and fires expand event', async function() {
54+
const overflow = element.shadowRoot?.querySelector('#overflow') as HTMLElement;
55+
let fired = false;
56+
element.addEventListener('expand', () => (fired = true));
57+
58+
overflow.click();
59+
await element.updateComplete;
60+
61+
expect(element.open).to.be.true;
62+
expect(fired).to.be.true;
63+
expect(overflow.textContent?.trim()).to.equal('show less');
64+
65+
const labels = Array.from(element.querySelectorAll('pf-label')) as PfLabel[];
66+
expect(labels.every(l => l.hidden === false)).to.be.true;
67+
});
68+
69+
it('shows close button and dispatches remove when closeable', async function() {
70+
element.closeable = true;
71+
await element.updateComplete;
72+
73+
const btn = element.shadowRoot?.querySelector('#close-button') as HTMLElement;
74+
expect(btn).to.be.ok;
75+
let removed = false;
76+
element.addEventListener('remove', () => (removed = true));
77+
78+
btn.click();
79+
await element.updateComplete;
80+
81+
expect(removed).to.be.true;
82+
});
83+
});
2184
});

0 commit comments

Comments
 (0)