Skip to content

Commit

Permalink
feat: loader for ListBox
Browse files Browse the repository at this point in the history
  • Loading branch information
kubaszajna committed May 28, 2024
1 parent bdacf39 commit 79c3648
Showing 1 changed file with 56 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/components/organisms/UiList/UiList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,35 @@
</UiListItem>
</template>
</slot>
<template v-if="hasLoader">
<component
:is="loader"
:is-loading="isLoading"
v-bind="defaultProps.loaderAttrs"
>
<template #loader>
<!-- @slot Use this slot to replace loader. -->
<slot name="loader" />
</template>
<!-- @slot Use this slot to place content inside button. -->
<slot />
</component>
</template>
</component>
</template>

<script setup lang="ts">
import {
h,
computed,
ref,
watch,
type HTMLAttributes,
defineAsyncComponent,
useSlots,
} from 'vue';
import UiListItem, { type ListItemAttrsProps } from './_internal/UiListItem.vue';
import type { LoaderAttrsProps } from '../../molecules/UiLoader/UiLoader.vue';
import UiListItemContent from './_internal/UiListItemContent.vue';
import type {
DefineAttrsProps,
Expand All @@ -63,13 +83,36 @@ export interface ListProps {
* Use this props to pass list items.
*/
items?: ListItem[];
/**
* Use this props to set button into loading state.
*/
isLoading?: boolean;
/**
* Use this props to pass attrs for UiLoader.
*/
loaderAttrs?: LoaderAttrsProps;
}
export type ListAttrsProps<HTMLAttrs = HTMLAttributes> = DefineAttrsProps<ListProps, HTMLAttrs>;
const props = withDefaults(defineProps<ListProps>(), {
tag: 'ul',
items: () => ([]),
isLoading: false,
loaderAttrs: () => ({}),
});
const defaultProps = computed(() => ({
loaderAttrs: {
type: 'skeleton' as const,
'transition-type': 'show',
...props.loaderAttrs,
},
}));
const hasLoader = ref(props.isLoading);
watch(() => (props.isLoading), (isLoading) => {
if (isLoading && !hasLoader.value) {
hasLoader.value = true;
}
}, { once: true });
const itemsToRender = computed(() => (props.items
.map((item, index) => {
if (typeof item === 'string') {
Expand All @@ -83,6 +126,19 @@ const itemsToRender = computed(() => (props.items
name: item.name || `list-item-${index}`,
};
})));
const slots = useSlots();
const loader = computed(() => (
hasLoader.value
? defineAsyncComponent({
loader: () => import('../../molecules/UiLoader/UiLoader.vue'),
delay: 0,
loadingComponent: () => (slots.default
? h('slot', slots.default())
: null)
,
})
: null
));
</script>

<style lang="scss">
Expand Down

0 comments on commit 79c3648

Please sign in to comment.