Skip to content

Commit 082e0c4

Browse files
committed
Extract element by dig inside the fragment until get pure component
1 parent b9bcea6 commit 082e0c4

6 files changed

Lines changed: 80 additions & 66 deletions

File tree

src/components/ButtonGroup/ButtonGroup.vue

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ export default {
2424
import { computed, useSlots } from 'vue';
2525
import type { VNodeArrayChildren } from 'vue';
2626
import { classNames } from 'polaris/polaris-react/src/utilities/css';
27-
import { Item } from './components';
27+
import { extractElement } from '@/utilities/extract-fragment';
2828
import styles from '@/classes/ButtonGroup.json';
29+
import { Item } from './components';
2930
3031
type Spacing = 'extraTight' | 'tight' | 'loose';
3132
@@ -47,24 +48,15 @@ const props = defineProps<Props>();
4748
const slots = useSlots();
4849
4950
const itemMarkup = computed(() => {
50-
const items : VNodeArrayChildren = [];
51+
let elms : VNodeArrayChildren = [];
5152
if (slots.default) {
52-
slots.default().map(item => {
53-
const children = item.children as VNodeArrayChildren;
54-
if (typeof children === 'string' && children === 'v-if') {
55-
return;
56-
}
57-
58-
if (item.type.toString() === 'Symbol(Fragment)' || item.type.toString() === 'Symbol()') {
59-
for (const child of children) {
60-
items.push(child);
61-
}
62-
} else {
63-
items.push(item);
64-
}
53+
const groups = slots.default().map(group => {
54+
return extractElement(group);
6555
});
56+
elms = groups.flat();
6657
}
67-
return items;
58+
59+
return elms;
6860
});
6961
7062
const className = computed(() => {

src/components/FormLayout/FormLayout.vue

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ div(:class="styles.FormLayout")
2424
<script setup lang="ts">
2525
import { computed, onBeforeUpdate, onMounted, ref, useSlots } from 'vue';
2626
import type { VNodeArrayChildren } from 'vue';
27+
import { extractElement } from '@/utilities/extract-fragment';
2728
import styles from '@/classes/FormLayout.json';
2829
import { Item } from './components';
2930
@@ -34,24 +35,15 @@ const itemGroupIndexes = ref<boolean[]>([]);
3435
const slots = useSlots();
3536
3637
const slotsElms = computed(() => {
37-
const items : VNodeArrayChildren = [];
38+
let elms : VNodeArrayChildren = [];
3839
if (slots.default) {
39-
slots.default().map(item => {
40-
const children = item.children as VNodeArrayChildren;
41-
if (typeof children === 'string' && children === 'v-if') {
42-
return;
43-
}
44-
45-
if (item.type.toString() === 'Symbol(Fragment)' || item.type.toString() === 'Symbol()') {
46-
for (const child of children) {
47-
items.push(child);
48-
}
49-
} else {
50-
items.push(item);
51-
}
40+
const groups = slots.default().map(group => {
41+
return extractElement(group);
5242
});
43+
elms = groups.flat();
5344
}
54-
return items;
45+
46+
return elms;
5547
});
5648
5749
onBeforeUpdate(() => {

src/components/FormLayout/components/Group/Group.vue

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,11 @@ div(
1414
template(v-else) {{ title }}
1515
div(:class="styles.Items")
1616
template(v-if="slots.default && hasSlot(slots.default)")
17-
template(
18-
v-for="item, index in slots.default()",
17+
Item(
18+
v-for="item, index in slotsElms",
1919
:key="index",
2020
)
21-
Item(
22-
v-if="item.type.toString() === 'Symbol(Fragment)' && item.el === null && item.children",
23-
v-for="child, childIndex in item.children",
24-
:key="`${index}-${childIndex.toString()}`",
25-
)
26-
component(:is="child")
27-
Item(v-else)
28-
component(:is="item")
21+
component(:is="item")
2922
slot(v-else)
3023
div(
3124
v-if="slots['help-text'] || helpText",
@@ -38,9 +31,11 @@ div(
3831

3932
<script setup lang="ts">
4033
import { computed, useSlots } from 'vue';
34+
import type { VNodeArrayChildren } from 'vue';
4135
import { classNames } from 'polaris/polaris-react/src/utilities/css';
4236
import { Item } from '../Item';
4337
import { hasSlot } from '@/utilities/has-slot';
38+
import { extractElement } from '@/utilities/extract-fragment';
4439
import styles from '@/classes/FormLayout.json';
4540
import { UseUniqueId } from '@/use';
4641
@@ -71,4 +66,16 @@ defineExpose({ name: 'FormGroup' });
7166
const className = computed(() => {
7267
return classNames(props.condensed ? styles.condensed : styles.grouped);
7368
});
69+
70+
const slotsElms = computed(() => {
71+
let elms : VNodeArrayChildren = [];
72+
if (slots.default) {
73+
const groups = slots.default().map(group => {
74+
return extractElement(group);
75+
});
76+
elms = groups.flat();
77+
}
78+
79+
return elms;
80+
});
7481
</script>

src/components/ResourceList/ResourceList.vue

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ import type { CheckboxHandles } from '@/utilities/interface';
9090
import { classNames } from 'polaris/polaris-react/src/utilities/css';
9191
import { UseI18n } from '@/use';
9292
import { hasSlot } from '@/utilities/has-slot';
93+
import { extractElement } from '@/utilities/extract-fragment';
9394
import { tokens, toPx } from '@shopify/polaris-tokens';
9495
import { Button, EventListener, Sticky, Spinner, Select, EmptySearchResult, BulkActions, CheckableButton } from '@/components';
9596
import { SELECT_ALL_ITEMS } from '../../utilities/resource-list';
@@ -197,23 +198,14 @@ const generateItemId = (item: any, index: number) => {
197198
};
198199
199200
const items = computed<TItemType[]>(() => {
200-
const tmpItems : VNodeArrayChildren = [];
201+
let tmpItems: VNodeArrayChildren = [];
201202
if (slots.default) {
202-
slots.default().map(item => {
203-
const children = item.children as VNodeArrayChildren;
204-
if (typeof children === 'string' && children === 'v-if') {
205-
return;
206-
}
207-
208-
if (item.type.toString() === 'Symbol(Fragment)' || item.type.toString() === 'Symbol()') {
209-
for (const child of children) {
210-
tmpItems.push(child);
211-
}
212-
} else {
213-
tmpItems.push(item);
214-
}
203+
const groups = slots.default().map(group => {
204+
return extractElement(group);
215205
});
206+
tmpItems = groups.flat();
216207
}
208+
217209
return tmpItems;
218210
});
219211

src/components/Stack/Stack.vue

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,21 @@
11
<template lang="pug">
22
div(:class="className")
33
template(v-if="!noItemWrap && slots.default && hasSlot(slots.default)")
4-
template(
5-
v-for="item, index in slots.default()",
4+
StackItem(
5+
v-for="item, index in slotsElms",
66
:key="index",
77
)
8-
StackItem(
9-
v-if="item.type.toString() === 'Symbol(Fragment)' && item.el === null && item.children",
10-
v-for="child, childIndex in item.children",
11-
:key="`${index}-${childIndex.toString()}`",
12-
)
13-
component(:is="child")
14-
StackItem(v-else)
15-
component(:is="item")
8+
component(:is="item")
169
slot(v-else)
1710
</template>
1811

1912
<script setup lang="ts">
20-
import { computed, onMounted, useSlots } from 'vue';
13+
import { computed, useSlots } from 'vue';
14+
import type { VNodeArrayChildren } from 'vue';
2115
import { classNames, variationName } from 'polaris/polaris-react/src/utilities/css';
2216
import styles from '@/classes/Stack.json';
2317
import { hasSlot } from '@/utilities/has-slot';
18+
import { extractElement } from '@/utilities/extract-fragment';
2419
import { Item as StackItem } from './components';
2520
2621
type Spacing =
@@ -77,6 +72,18 @@ const className = computed(() => {
7772
props.wrap === false && styles.noWrap,
7873
);
7974
});
75+
76+
const slotsElms = computed(() => {
77+
let elms : VNodeArrayChildren = [];
78+
if (slots.default) {
79+
const groups = slots.default().map(group => {
80+
return extractElement(group);
81+
});
82+
elms = groups.flat();
83+
}
84+
85+
return elms;
86+
});
8087
</script>
8188

8289
<style lang="scss">

src/utilities/extract-fragment.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { VNodeArrayChildren } from 'vue';
2+
3+
export function isFragment(item : any) {
4+
return item.type.toString() === 'Symbol(Fragment)' || item.type.toString() === 'Symbol()';
5+
}
6+
7+
// input: Fragment element
8+
// output: array of pure children elements
9+
export function extractElement(elm: any) {
10+
if (!isFragment(elm)) {
11+
return [elm];
12+
}
13+
14+
const children = elm.children as VNodeArrayChildren;
15+
const items: VNodeArrayChildren = [];
16+
for (const child of children) {
17+
if (isFragment(child)) {
18+
items.push(...extractElement(child));
19+
} else {
20+
items.push(child);
21+
}
22+
}
23+
return items;
24+
}

0 commit comments

Comments
 (0)