vueless
Version:
Vue Styleless UI Component Library, powered by Tailwind CSS.
232 lines (217 loc) • 5.91 kB
text/typescript
import {
getArgs,
getArgTypes,
getSlotNames,
getSlotsFragment,
getDocsDescription,
} from "../../utils/storybook";
import UDataList from "../../ui.data-list/UDataList.vue";
import UIcon from "../../ui.image-icon/UIcon.vue";
import UButton from "../../ui.button/UButton.vue";
import URow from "../../ui.container-row/URow.vue";
import ULink from "../../ui.button-link/ULink.vue";
import UAvatar from "../../ui.image-avatar/UAvatar.vue";
import UHeader from "../../ui.text-header/UHeader.vue";
import ULoader from "../../ui.loader/ULoader.vue";
import tooltip from "../../v.tooltip/vTooltip";
import type { Meta, StoryFn } from "@storybook/vue3-vite";
import type { Props, DataListItem } from "../types";
interface UDataListArgs extends Props {
slotTemplate?: string;
enum: "size";
}
export default {
id: "7020",
title: "Data / Data List",
component: UDataList,
args: {
list: [
{ label: "Expenses", value: 1 },
{ label: "Revenue Streams", value: 2 },
{ label: "Departments", value: 3 },
],
},
argTypes: {
...getArgTypes(UDataList.__name),
},
parameters: {
docs: {
...getDocsDescription(UDataList.__name),
},
},
} as Meta;
const DefaultTemplate: StoryFn<UDataListArgs> = (args: UDataListArgs) => ({
components: { UDataList, UIcon, URow, UButton, UAvatar, ULoader, UHeader, ULink },
directives: { tooltip },
setup: () => ({
args,
slots: getSlotNames(UDataList.__name),
removeItem: (targetItem: DataListItem) =>
alert(`Removed item: ${JSON.stringify(targetItem, null, 2)}`),
editItem: (targetItem: DataListItem) =>
alert(`Edit item: ${JSON.stringify(targetItem, null, 2)}`),
}),
template: `
<UDataList v-bind="args">
${args.slotTemplate || getSlotsFragment("")}
</UDataList>
`,
});
const EnumTemplate: StoryFn<UDataListArgs> = (args: UDataListArgs, { argTypes }) => ({
components: { URow, UDataList },
setup: () => ({ args, argTypes, getArgs }),
template: `
<UDataList
v-for="option in argTypes?.[args.enum]?.options"
v-bind="getArgs(args, option)"
:key="option"
class="mb-4"
/>
`,
});
export const Default = DefaultTemplate.bind({});
Default.args = {};
export const EmptyState = DefaultTemplate.bind({});
EmptyState.args = { list: [] };
export const Nesting = DefaultTemplate.bind({});
Nesting.args = {
list: [
{
label: "Expenses",
value: 1,
children: [
{ label: "Office Supplies", value: 1.1 },
{ label: "Travel & Lodging", value: 1.2 },
{ label: "Utilities", value: 1.3 },
],
},
{
label: "Revenue Streams",
value: 2,
children: [
{ label: "Product Sales", value: 2.1 },
{ label: "Subscription Services", value: 2.2 },
{ label: "Consulting", value: 2.3 },
],
},
{
label: "Departments",
value: 3,
children: [
{ label: "Engineering", value: 3.1 },
{ label: "Marketing", value: 3.2 },
{ label: "Finance", value: 3.3 },
],
},
],
};
export const Sizes = EnumTemplate.bind({});
Sizes.args = { enum: "size" };
export const LabelSlot = DefaultTemplate.bind({});
LabelSlot.args = {
slotTemplate: `
<template
<ULink :label="item.label" />
</template>
`,
};
export const EmptySlot = DefaultTemplate.bind({});
EmptySlot.args = {
list: [],
config: {
wrapper: "flex flex-col items-center justify-center py-10 gap-4",
i18n: {
emptyTitle: "Fetching data...",
emptyDescription: "Please wait until data is received.",
},
},
slotTemplate: `
<template
<ULoader loading size="lg" />
<UHeader :label="emptyTitle" size="xs" />
<p>{{ emptyDescription }}</p>
</template>
`,
};
EmptySlot.parameters = {
docs: {
description: {
story:
"You can customize the `empty` slot's props (`emptyTitle` and `emptyDescription`) using the `i18n` config key.",
},
},
};
export const DragSlot = DefaultTemplate.bind({});
DragSlot.args = {
list: [
{
label: "John Doe (Engineering)",
value: 1,
avatar: "https://cdn-icons-png.flaticon.com/128/1999/1999625.png",
},
{
label: "Michael Johnson (Finance)",
value: 2,
avatar: "https://cdn-icons-png.flaticon.com/128/4140/4140057.png",
},
{
label: "Emma Smith (Marketing)",
value: 3,
avatar: "https://cdn-icons-png.flaticon.com/128/4140/4140047.png",
},
],
slotTemplate: `
<template
<UAvatar :src="item.avatar" rounded="full" />
</template>
`,
};
export const ActionsSlot = DefaultTemplate.bind({});
ActionsSlot.args = {
list: [
{ label: "Expenses", value: 1 },
{
label: "Revenue Streams",
value: 2,
actions: false,
children: [
{ label: "Product Sales", value: 2.1 },
{ label: "Subscription Services", value: 2.2 },
{ label: "Consulting", value: 2.3, actions: false },
],
},
{ label: "Departments", value: 3, crossed: true },
],
slotTemplate: `
<template
<UButton label="Export" variant="soft" size="xs" />
<UIcon
name="delete"
size="sm"
color="error"
interactive
v-tooltip="'Delete'"
@click="removeItem(item)"
/>
<UIcon
name="edit_note"
size="sm"
color="grayscale"
interactive
v-tooltip="'Edit'"
@click="editItem(item)"
/>
</template>
`,
};
ActionsSlot.parameters = {
docs: {
description: {
story: `
You can use meta keys on list items such as \`crossed\` (for line-through style),
\`actions\` (to toggle actions visibility), and \`children\` (for nested items).
See the the docs below for more info.
`,
},
},
};