Skip to content

Commit e465aa7

Browse files
committed
fix(label-group): add ssr:label event for child discovery
pf-label now dispatches a bubbling `ssr:label` event from connectedCallback during SSR. pf-label-group listens for this event and increments an internal label count, so the overflow template renders correctly on the server without querySelectorAll. Assisted-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 728389f commit e465aa7

2 files changed

Lines changed: 27 additions & 6 deletions

File tree

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

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import { LitElement, html, type TemplateResult } from 'lit';
1+
import { LitElement, html, isServer, type TemplateResult } from 'lit';
22
import { customElement } from 'lit/decorators/custom-element.js';
33
import { property } from 'lit/decorators/property.js';
4+
import { state } from 'lit/decorators/state.js';
45
import { query } from 'lit/decorators/query.js';
56
import { queryAssignedNodes } from 'lit/decorators/query-assigned-nodes.js';
67
import { classMap } from 'lit/directives/class-map.js';
78

89
import { observes } from '@patternfly/pfe-core/decorators/observes.js';
910
import { RovingTabindexController } from '@patternfly/pfe-core/controllers/roving-tabindex-controller.js';
1011

11-
import { isServer } from 'lit';
12-
1312
import { PfLabel } from '../pf-label/pf-label.js';
1413

1514
import styles from './pf-label-group.css';
@@ -87,6 +86,9 @@ export class PfLabelGroup extends LitElement {
8786
/** Whether the label group can be closed. */
8887
@property({ reflect: true, type: Boolean }) closeable = false;
8988

89+
/** Label count tracked during SSR via child events. */
90+
@state() private _ssrLabelCount = 0;
91+
9092
@query('#overflow') private _overflowLabel?: PfLabel;
9193

9294
@query('#close-button') private _button?: HTMLButtonElement;
@@ -100,12 +102,19 @@ export class PfLabelGroup extends LitElement {
100102
return this.querySelectorAll<PfLabel>('pf-label:not([slot]):not([overflow-label])');
101103
}
102104

105+
get #labelCount(): number {
106+
if (isServer) {
107+
return this._ssrLabelCount;
108+
}
109+
return this.#labels.length;
110+
}
111+
103112
get #hasCategory(): boolean {
104113
return (this._categorySlotted ?? []).length > 0;
105114
}
106115

107116
get #remaining(): number {
108-
return this.#labels.length - this.numLabels;
117+
return this.#labelCount - this.numLabels;
109118
}
110119

111120
#tabindex = RovingTabindexController.of(this, {
@@ -123,10 +132,11 @@ export class PfLabelGroup extends LitElement {
123132
constructor() {
124133
super();
125134
this.addEventListener('remove', this.#onRemove);
135+
this.addEventListener('ssr:label', this.#onSsrLabel);
126136
}
127137

128138
override render(): TemplateResult<1> {
129-
const empty = this.#labels.length <= 0;
139+
const empty = this.#labelCount <= 0;
130140
return html`
131141
<div id="outer"
132142
class="${classMap({ 'has-category': this.#hasCategory, empty })}"
@@ -191,6 +201,10 @@ export class PfLabelGroup extends LitElement {
191201
}
192202
}
193203

204+
#onSsrLabel() {
205+
this._ssrLabelCount++;
206+
}
207+
194208
#updateOverflow() {
195209
this.#labels.forEach((label, i) => {
196210
label.hidden = i >= this.numLabels && !this.open;

elements/pf-label/pf-label.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { LitElement, html, type TemplateResult } from 'lit';
1+
import { LitElement, html, isServer, type TemplateResult } from 'lit';
22
import { customElement } from 'lit/decorators/custom-element.js';
33
import { property } from 'lit/decorators/property.js';
44
import { classMap } from 'lit/directives/class-map.js';
@@ -71,6 +71,13 @@ export class PfLabel extends LitElement {
7171
/** Represents the state of the anonymous and icon slots */
7272
#slots = new SlotController(this, null, 'icon');
7373

74+
override connectedCallback(): void {
75+
super.connectedCallback();
76+
if (isServer) {
77+
this.dispatchEvent(new Event('ssr:label', { bubbles: true }));
78+
}
79+
}
80+
7481
override render(): TemplateResult<1> {
7582
const { compact, truncated } = this;
7683
const { variant, color, icon } = this;

0 commit comments

Comments
 (0)