Skip to content

Commit 80b0a7a

Browse files
committed
fix(core): initialize slotcontroller map after update
1 parent 61ead0f commit 80b0a7a

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

.changeset/fresh-things-burn.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@patternfly/pfe-core": patch
3+
---
4+
5+
`SlotController`: correctly report slot content after updating
6+

core/pfe-core/controllers/slot-controller.ts

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ export function isObjectSpread(config: SlotControllerArgs): config is [SlotsConf
3838
return config.length === 1 && typeof config[0] === 'object' && config[0] !== null;
3939
}
4040

41+
function isContent(node: Node) {
42+
switch (node.nodeType) {
43+
case Node.TEXT_NODE:
44+
return !!node.textContent?.trim();
45+
case Node.COMMENT_NODE:
46+
return false;
47+
default:
48+
return true;
49+
}
50+
}
51+
4152
/**
4253
* If it's a named slot, return its children,
4354
* for the default slot, look for direct children not assigned to a slot
@@ -112,7 +123,27 @@ export class SlotController implements SlotControllerPublicAPI {
112123

113124
#deprecations: Record<string, string> = {};
114125

115-
#mo = new MutationObserver(this.#initSlotMap.bind(this));
126+
#initSlotMap = async () => {
127+
const { host } = this;
128+
await host.updateComplete;
129+
const nodes = this.#nodes;
130+
// Loop over the properties provided by the schema
131+
for (const slotName of this.#slotNames
132+
.concat(Object.values(this.#deprecations))) {
133+
const slotId = slotName || SlotController.default;
134+
const name = slotName ?? '';
135+
const elements = this.#getChildrenForSlot(slotId);
136+
const slot = this.#getSlotElement(slotId);
137+
const hasContent =
138+
slotId === SlotController.default ? !![...host.childNodes].some(isContent)
139+
: !!slot?.assignedNodes?.().some(isContent);
140+
nodes.set(slotId, { elements, name, hasContent, slot });
141+
}
142+
host.requestUpdate();
143+
this.#slotMapInitialized = true;
144+
};
145+
146+
#mo = new MutationObserver(this.#initSlotMap);
116147

117148
constructor(public host: ReactiveElement, ...args: SlotControllerArgs) {
118149
this.#initialize(...args);
@@ -153,22 +184,6 @@ export class SlotController implements SlotControllerPublicAPI {
153184
this.#mo.disconnect();
154185
}
155186

156-
#initSlotMap() {
157-
// Loop over the properties provided by the schema
158-
for (const slotName of this.#slotNames
159-
.concat(Object.values(this.#deprecations))) {
160-
const slotId = slotName || SlotController.default;
161-
const name = slotName ?? '';
162-
const elements = this.#getChildrenForSlot(slotId);
163-
const slot = this.#getSlotElement(slotId);
164-
const hasContent =
165-
!!elements.length || !!slot?.assignedNodes?.()?.filter(x => x.textContent?.trim()).length;
166-
this.#nodes.set(slotId, { elements, name, hasContent, slot });
167-
}
168-
this.host.requestUpdate();
169-
this.#slotMapInitialized = true;
170-
}
171-
172187
#getSlotElement(slotId: string | symbol) {
173188
const selector =
174189
slotId === SlotController.default ? 'slot:not([name])' : `slot[name="${slotId as string}"]`;

0 commit comments

Comments
 (0)