Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: migrate ItemsListInjection mixin #1460

Merged
merged 23 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7d99409
lock
annacv Apr 2, 2024
fad45e2
Merge branch 'main' of https://github.com/empathyco/x into feature/EM…
annacv Apr 8, 2024
15da996
feat: WIP migrate resultsList component
annacv Apr 9, 2024
2617e13
Merge branch 'main' of https://github.com/empathyco/x into feature/EM…
annacv Apr 9, 2024
c8ac1f4
feat: WIP migrate resultsList component
annacv Apr 9, 2024
ea4a02c
chore: migrate promoteds-list component
lauramargar Apr 18, 2024
18fe26a
chore: migrate next-queries-list component
lauramargar Apr 18, 2024
5b0a5c5
chore: migrate banners-list component
lauramargar Apr 18, 2024
7fcd99e
chore: update migration of results-list component
lauramargar Apr 18, 2024
5af69d7
Merge branch 'main' into feature/EMP-3792-Migrate-result-list
lauramargar Apr 24, 2024
e38a6dd
feat: migrate component tests
lauramargar May 2, 2024
57b677f
chore: remove ItemsListInjection mixin
lauramargar May 2, 2024
98ec59a
Merge branch 'main' into feature/EMP-3792-Migrate-result-list
lauramargar May 3, 2024
b46a37d
chore: add components to the playground
lauramargar May 7, 2024
fc3a4c9
Merge branch 'main' into feature/EMP-3792-Migrate-result-list
lauramargar May 7, 2024
eb0a8ec
chore: fix pr comments
lauramargar May 7, 2024
d1bb8f0
chore: return `slots` itself instead of renaming it
lauramargar May 7, 2024
a4425ea
chore: remove lock
lauramargar May 7, 2024
092566a
chore: add @remarks on `onInfiniteScrollEnd` function
lauramargar May 7, 2024
7e84a53
chore: move test-elements-list to x-modules folder and rm disable-max…
lauramargar May 8, 2024
89d3a28
chore: move modules config to x-module files
lauramargar May 8, 2024
83686a7
Merge branch 'main' into feature/EMP-3792-Migrate-result-list
lauramargar May 9, 2024
653b6b3
chore: remove eslint unbound-method
lauramargar May 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion packages/_vue3-migration-test/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { XComponentsAdapter } from '@empathyco/x-types';
import { Component, configureCompat, createApp } from 'vue';
import { createStore } from 'vuex';
import { xPlugin } from '../../x-components/src/plugins/x-plugin';
import { getResultsStub } from '../../x-components/src/__stubs__/results-stubs.factory';
import { getBannersStub } from '../../x-components/src/__stubs__/banners-stubs.factory';
import { getPromotedsStub } from '../../x-components/src/__stubs__/promoteds-stubs.factory';
import { getNextQueriesStub } from '../../x-components/src/__stubs__/next-queries-stubs.factory';
import App from './App.vue';
import router from './router';

Expand Down Expand Up @@ -30,5 +34,30 @@ const store = createStore({});
createApp(App as Component)
.use(router)
.use(store)
.use(xPlugin, { adapter, store })
.use(xPlugin, {
adapter,
store,
__PRIVATE__xModules: {
search: {
storeModule: {
state: {
query: 'dress',
results: getResultsStub(10),
promoteds: getPromotedsStub(),
banners: getBannersStub(),
status: 'success'
}
}
},
nextQueries: {
storeModule: {
state: {
query: 'dress',
nextQueries: getNextQueriesStub(),
status: 'success'
}
}
}
}
})
.mount('#app');
6 changes: 6 additions & 0 deletions packages/_vue3-migration-test/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
TestSortDropdown,
TestSortList,
TestSortPickerList,
TestElementsList,
TestBaseColumnPickerDropdown
} from './';

Expand Down Expand Up @@ -56,6 +57,11 @@ const routes = [
path: '/sort-picker-list',
name: 'SortPickerList',
component: TestSortPickerList
},
{
path: '/elements-list',
name: 'ElementsList',
component: TestElementsList
}
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default as TestSortDropdown } from './test-sort-dropdown.vue';
export { default as TestSortList } from './test-sort-list.vue';
export { default as TestSortPickerList } from './test-sort-picker-list.vue';
export { default as TestElementsList } from './test-elements-list.vue';
lauramargar marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<template>
<LocationProvider location="results">
<ResultsList>
<PromotedsList>
<BannersList>
<NextQueriesList>
<BaseGrid>
<template #result="{ item: result }">
{{ result.id }}
</template>

<template #banner="{ item: banner }">
{{ banner.id }}
</template>

<template #promoted="{ item: promoted }">
{{ promoted.title }}
</template>
<template #next-queries-group="{ item: { nextQueries } }">
<li v-for="nextQuery in nextQueries" :key="nextQuery.query" class="next-query">
{{ nextQuery.query }}
</li>
</template>
</BaseGrid>
</NextQueriesList>
</BannersList>
</PromotedsList>
</ResultsList>
</LocationProvider>
</template>

<script setup lang="ts">
// eslint-disable-next-line max-len
lauramargar marked this conversation as resolved.
Show resolved Hide resolved
import PromotedsList from '../../../../../x-components/src/x-modules/search/components/promoteds-list.vue';
// eslint-disable-next-line max-len
import ResultsList from '../../../../../x-components/src/x-modules/search/components/results-list.vue';
// eslint-disable-next-line max-len
import BannersList from '../../../../../x-components/src/x-modules/search/components/banners-list.vue';
import BaseGrid from '../../../../../x-components/src/components/base-grid.vue';
import LocationProvider from '../../../../../x-components/src/components/location-provider.vue';
// eslint-disable-next-line max-len
import NextQueriesList from '../../../../../x-components/src/x-modules/next-queries/components/next-queries-list.vue';
</script>
42 changes: 31 additions & 11 deletions packages/x-components/src/components/base-grid.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
the item using that slot composition to render.
@binding {item} item - Item to render
-->
<slot v-if="$scopedSlots[slotName]" :name="slotName" :item="item" />
<slot v-if="slots[slotName]" :name="slotName" :item="item" />
<!--
@slot (required) Default item rendering. This slot will be used by default for rendering
the item without an specific slot implementation.
Expand All @@ -41,10 +41,10 @@
ref,
watch
} from 'vue';
import { useResizeObserver } from '@vueuse/core';
import { MaybeComputedElementRef, useResizeObserver } from '@vueuse/core';
import { toKebabCase } from '../utils/string';
import { ListItem, VueCSSClasses } from '../utils/types';
import { AnimationProp } from '../types/index';
import { AnimationProp } from '../types/animation-prop';
import { useXBus } from '../composables/use-x-bus';
import { LIST_ITEMS_KEY } from './decorators/injection.consts';

Expand Down Expand Up @@ -103,7 +103,11 @@
type: Array as PropType<ListItem[]>
}
},
setup(props) {
setup(props, { slots }) {
type ElementRef = {
$el: HTMLElement;
};

const xBus = useXBus();
/**
* It injects {@link ListItem} provided by an ancestor.
Expand All @@ -112,7 +116,7 @@
*/
const injectedListItems = inject<Ref<ListItem[]>>(LIST_ITEMS_KEY as string);

const gridEl = ref<HTMLElement | null>(null);
const gridEl = ref<ElementRef | HTMLElement | null>(null);

let renderedColumnsNumber = ref(0);
/**
Expand Down Expand Up @@ -193,16 +197,28 @@
})
);

/**
* Checks if a given value is an `ElementRef` object.
*
* @param value - The value to check.
* @returns `true` if the value is an `ElementRef` object, `false` otherwise.
*
* @internal
*/
const isElementRef = (value: any): value is ElementRef => {
return value && value.$el instanceof HTMLElement;
};

/**
* Updates the number of columns rendered inside the grid.
*
* @internal
*/
const updateRenderedColumnsNumber = (): void => {
if (gridEl.value !== null && gridEl.value instanceof HTMLElement) {
const { gridTemplateColumns } = getComputedStyle(gridEl.value);
renderedColumnsNumber.value = gridTemplateColumns.split(' ').length;
}
const { gridTemplateColumns } = getComputedStyle(
isElementRef(gridEl.value) ? gridEl.value.$el : (gridEl.value as Element)
);
renderedColumnsNumber.value = gridTemplateColumns.split(' ').length;
};

/**
Expand All @@ -211,14 +227,18 @@
* @internal
*/
// eslint-disable-next-line @typescript-eslint/unbound-method
lauramargar marked this conversation as resolved.
Show resolved Hide resolved
const resizeObserver = useResizeObserver(gridEl, updateRenderedColumnsNumber);
const resizeObserver = useResizeObserver(
gridEl as MaybeComputedElementRef,
updateRenderedColumnsNumber
);
onBeforeUnmount(() => resizeObserver.stop());

return {
gridItems,
cssClasses,
style,
gridEl
gridEl,
slots
};
}
});
Expand Down
1 change: 0 additions & 1 deletion packages/x-components/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,5 @@ export * from './decorators/debounce.decorators';
export * from './decorators/injection.consts';
export * from './decorators/injection.decorators';
export * from './decorators/store.decorators';
export * from './items-list-injection.mixin';
export * from './x-component.mixin';
export * from './x-component.utils';

This file was deleted.

99 changes: 59 additions & 40 deletions packages/x-components/src/components/items-list.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,56 +23,75 @@
</template>

<script lang="ts">
import Vue from 'vue';
import { Component, Mixins, Prop } from 'vue-property-decorator';
import { computed, defineComponent, PropType } from 'vue';
import { ListItem } from '../utils/types';
import { toKebabCase } from '../utils/string';
import { dynamicPropsMixin } from './dynamic-props.mixin';
import { animationProp } from '../utils/options-api';

/**
* It renders a list of {@link ListItem} providing a slot for each `slotName` which depends on
* the `modelName`of the item.
*
* @public
*/
@Component
export default class ItemsList extends Mixins(dynamicPropsMixin(['itemClass'])) {
/**
* Animation component that will be used to animate the list.
*
* @public
*/
@Prop({ default: 'ul' })
protected animation!: Vue | string;
export default defineComponent({
name: 'ItemsList',
props: {
/**
* Animation component that will be used to animate the list.
*
* @public
*/
animation: {
type: animationProp,
default: 'ul'
},

/**
* List of items.
*
* @public
*/
@Prop({ required: true })
protected items!: ListItem[];
/**
* List of items.
*
* @public
*/
items: {
type: Array as PropType<ListItem[]>,
required: true
},

/**
* The list of the items with additional properties.
*
* @returns A list of items with `dataTest`, `class` and the `slotName` for each item.
*
* @internal
*/
protected get computedItems(): {
dataTest: string;
class: Array<string | undefined>;
}[] {
return this.items.map(item => {
const modelName = toKebabCase(item.modelName);
return {
...item,
dataTest: `${modelName}s-list-item`,
class: [`x-${modelName}s-list-item`, this.itemClass],
slotName: modelName
};
});
/**
* Item's classes.
*
* @public
*/
itemClass: {
type: String
}
},
setup(props) {
/**
* The list of the items with additional properties.
*
* @returns A list of items with `dataTest`, `class` and the `slotName` for each item.
*
* @internal
*/
const computedItems = computed(
(): {
dataTest: string;
class: Array<string | undefined>;
}[] => {
return props.items.map(item => {
const modelName = toKebabCase(item.modelName);
return {
...item,
dataTest: `${modelName}s-list-item`,
class: [`x-${modelName}s-list-item`, props.itemClass],
slotName: modelName
};
});
}
);

return { computedItems };
}
}
});
</script>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { defineComponent, PropType, provide, toRef } from 'vue';
import { FeatureLocation } from '../types';
import { useNoElementRender } from '../composables/index';
import { useNoElementRender } from '../composables/use-no-element-render';

/**
* Location Provider component.
Expand Down
Loading
Loading