@adobe-commerce/elsie 1.0.1-alpha04151330 → 1.0.1-alpha04151720
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__mocks__/svg.js +2 -1
- package/package.json +1 -1
- package/src/docs/slots.mdx +21 -3
- package/src/lib/slot.tsx +19 -13
package/__mocks__/svg.js
CHANGED
package/package.json
CHANGED
package/src/docs/slots.mdx
CHANGED
|
@@ -32,23 +32,41 @@ The `<Slot />` component is used to define a slot in a container. It receives a
|
|
|
32
32
|
|
|
33
33
|
The name of the slot in _PascalCase_. `string` (required).
|
|
34
34
|
|
|
35
|
-
###
|
|
35
|
+
### slotTag
|
|
36
36
|
|
|
37
37
|
The HTML tag to use for the slot's wrapper element. This allows you to change the wrapper element from the default `div` to any valid HTML tag (e.g., 'span', 'p', 'a', etc.). When using specific tags like 'a', you can also provide their respective HTML attributes (e.g., 'href', 'target', etc.).
|
|
38
38
|
|
|
39
39
|
Example:
|
|
40
40
|
```tsx
|
|
41
41
|
// Render with a span wrapper
|
|
42
|
-
<Slot name="MySlot"
|
|
42
|
+
<Slot name="MySlot" slotTag="span">
|
|
43
43
|
Inline content
|
|
44
44
|
</Slot>
|
|
45
45
|
|
|
46
46
|
// Render with an anchor wrapper
|
|
47
|
-
<Slot name="MySlot"
|
|
47
|
+
<Slot name="MySlot" slotTag="a" href="https://example.com" target="_blank">
|
|
48
48
|
Link content
|
|
49
49
|
</Slot>
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### contentTag
|
|
53
|
+
|
|
54
|
+
The HTML tag to use for wrapping dynamically inserted content within the slot. This is separate from the slot's wrapper tag and allows you to control how dynamic content is structured. Defaults to 'div'.
|
|
55
|
+
|
|
56
|
+
Example:
|
|
57
|
+
```tsx
|
|
58
|
+
<Slot
|
|
59
|
+
name="MySlot"
|
|
60
|
+
slotTag="article" // The outer wrapper will be an article
|
|
61
|
+
contentTag="section" // Dynamic content will be wrapped in sections
|
|
62
|
+
slot={(ctx) => {
|
|
63
|
+
const elem = document.createElement('div');
|
|
64
|
+
elem.innerHTML = 'Dynamic content';
|
|
65
|
+
ctx.appendChild(elem); // This will be wrapped in a section tag
|
|
66
|
+
}}
|
|
67
|
+
/>
|
|
68
|
+
```
|
|
69
|
+
|
|
52
70
|
### slot (required)
|
|
53
71
|
|
|
54
72
|
- `ctx`: An object representing the context of the slot, including methods for manipulating the slot's content.
|
package/src/lib/slot.tsx
CHANGED
|
@@ -42,7 +42,7 @@ interface PrivateContext<T> {
|
|
|
42
42
|
_registerMethod: (
|
|
43
43
|
cb: (next: T & DefaultSlotContext<T>, state: State) => void
|
|
44
44
|
) => void;
|
|
45
|
-
_htmlElementToVNode: (element: HTMLElement) => VNode;
|
|
45
|
+
_htmlElementToVNode: (element: HTMLElement, tag: keyof HTMLElementTagNameMap) => VNode;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
interface DefaultSlotContext<T> extends PrivateContext<T> {
|
|
@@ -75,7 +75,8 @@ export function useSlot<K, V extends HTMLElement>(
|
|
|
75
75
|
context: Context<K> = {},
|
|
76
76
|
callback?: SlotProps<K>,
|
|
77
77
|
children?: ComponentChildren,
|
|
78
|
-
render?: Function
|
|
78
|
+
render?: Function,
|
|
79
|
+
contentTag: keyof HTMLElementTagNameMap = 'div'
|
|
79
80
|
): [RefObject<V>, Record<string, any>] {
|
|
80
81
|
const slotsQueue = useContext(SlotQueueContext);
|
|
81
82
|
|
|
@@ -146,15 +147,17 @@ export function useSlot<K, V extends HTMLElement>(
|
|
|
146
147
|
context._registerMethod = _registerMethod;
|
|
147
148
|
|
|
148
149
|
const _htmlElementToVNode = useCallback((elem: HTMLElement) => {
|
|
149
|
-
return (
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
return createElement(
|
|
151
|
+
contentTag,
|
|
152
|
+
{
|
|
153
|
+
'data-slot-html-element': elem.tagName.toLowerCase(),
|
|
154
|
+
ref: (refElem: HTMLElement | null): void => {
|
|
153
155
|
refElem?.appendChild(elem);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
null
|
|
156
159
|
);
|
|
157
|
-
}, []);
|
|
160
|
+
}, [contentTag]);
|
|
158
161
|
|
|
159
162
|
// @ts-ignore
|
|
160
163
|
context._htmlElementToVNode = _htmlElementToVNode;
|
|
@@ -356,7 +359,8 @@ interface SlotPropsComponent<T>
|
|
|
356
359
|
slot?: SlotProps<T>;
|
|
357
360
|
context?: Context<T>;
|
|
358
361
|
render?: (props: Record<string, any>) => VNode | VNode[];
|
|
359
|
-
|
|
362
|
+
slotTag?: keyof HTMLElementTagNameMap; // The tag for the slot wrapper itself
|
|
363
|
+
contentTag?: keyof HTMLElementTagNameMap; // The tag for dynamically inserted content
|
|
360
364
|
children?: ComponentChildren;
|
|
361
365
|
}
|
|
362
366
|
|
|
@@ -366,7 +370,8 @@ export function Slot<T>({
|
|
|
366
370
|
slot,
|
|
367
371
|
children,
|
|
368
372
|
render,
|
|
369
|
-
|
|
373
|
+
slotTag = 'div',
|
|
374
|
+
contentTag = 'div',
|
|
370
375
|
...props
|
|
371
376
|
}: Readonly<SlotPropsComponent<T>>) {
|
|
372
377
|
const slotsQueue = useContext(SlotQueueContext);
|
|
@@ -376,7 +381,8 @@ export function Slot<T>({
|
|
|
376
381
|
context,
|
|
377
382
|
slot,
|
|
378
383
|
children,
|
|
379
|
-
render
|
|
384
|
+
render,
|
|
385
|
+
contentTag
|
|
380
386
|
);
|
|
381
387
|
|
|
382
388
|
useMemo(() => {
|
|
@@ -392,7 +398,7 @@ export function Slot<T>({
|
|
|
392
398
|
}, [name, slotsQueue]);
|
|
393
399
|
|
|
394
400
|
return createElement(
|
|
395
|
-
|
|
401
|
+
slotTag,
|
|
396
402
|
{
|
|
397
403
|
...props,
|
|
398
404
|
ref: elementRef,
|