feat(lite/stories): first stories for components (#6616)
This commit is contained in:
committed by
GitHub
parent
53e0f17c55
commit
e5c890e29b
@@ -38,6 +38,11 @@ code * {
|
||||
color: var(--color-extra-blue-d20);
|
||||
}
|
||||
|
||||
.link:active {
|
||||
.link:active,
|
||||
.link.router-link-active {
|
||||
color: var(--color-extra-blue-d40);
|
||||
}
|
||||
|
||||
.link.router-link-active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
class="preset-tab"
|
||||
@click="open"
|
||||
>
|
||||
<UiIcon :icon="faSliders" />
|
||||
Presets
|
||||
</UiTab>
|
||||
</template>
|
||||
@@ -105,6 +106,7 @@ import UiButton from "@/components/ui/UiButton.vue";
|
||||
import UiCard from "@/components/ui/UiCard.vue";
|
||||
import UiCardTitle from "@/components/ui/UiCardTitle.vue";
|
||||
import UiCounter from "@/components/ui/UiCounter.vue";
|
||||
import UiIcon from "@/components/ui/icon/UiIcon.vue";
|
||||
import UiTab from "@/components/ui/UiTab.vue";
|
||||
import UiTabBar from "@/components/ui/UiTabBar.vue";
|
||||
import {
|
||||
@@ -116,6 +118,7 @@ import {
|
||||
ModelParam,
|
||||
type Param,
|
||||
} from "@/libs/story/story-param";
|
||||
import { faSliders } from "@fortawesome/free-solid-svg-icons";
|
||||
import "highlight.js/styles/github-dark.css";
|
||||
import { uniqueId, upperFirst } from "lodash-es";
|
||||
import { computed, reactive, ref, watch, watchEffect } from "vue";
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<StoryParamsTable>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Prop</th>
|
||||
<th>Setting</th>
|
||||
<th><!--Widget--></th>
|
||||
<th>Help</th>
|
||||
</tr>
|
||||
|
||||
15
@xen-orchestra/lite/src/stories/form-input.story.md
Normal file
15
@xen-orchestra/lite/src/stories/form-input.story.md
Normal file
@@ -0,0 +1,15 @@
|
||||
When using a `string` as `before` or `after` prop, you will probably have to set `before-width` and `after-width` accordingly.
|
||||
|
||||
```vue-template
|
||||
<FormInput
|
||||
v-model="myValue"
|
||||
color="error"
|
||||
:before="before"
|
||||
:after="after"
|
||||
:before-width="beforeWidth"
|
||||
:after-width="afterWidth"
|
||||
right
|
||||
disabled
|
||||
:wrapper-attrs="wrapperAttrs"
|
||||
/>
|
||||
```
|
||||
40
@xen-orchestra/lite/src/stories/form-input.story.vue
Normal file
40
@xen-orchestra/lite/src/stories/form-input.story.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
:params="[
|
||||
colorProp(),
|
||||
iconProp('before').type('IconDefinition | string'),
|
||||
iconProp('after').type('IconDefinition | string'),
|
||||
model().type('string').required(),
|
||||
prop('right').bool().widget(),
|
||||
prop('disabled').bool().widget(),
|
||||
prop('wrapper-attrs')
|
||||
.obj('HTMLAttributes')
|
||||
.widget()
|
||||
.preset({ foo: 'bar' }),
|
||||
prop('before-width').str().widget(),
|
||||
prop('after-width').str().widget(),
|
||||
]"
|
||||
:presets="presets"
|
||||
v-slot="{ properties }"
|
||||
>
|
||||
<FormInput v-bind="properties" />
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { faDollarSign } from "@fortawesome/free-solid-svg-icons";
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import FormInput from "@/components/form/FormInput.vue";
|
||||
import { colorProp, iconProp, model, prop } from "@/libs/story/story-param";
|
||||
|
||||
const presets = {
|
||||
$100: {
|
||||
props: {
|
||||
modelValue: "100",
|
||||
before: faDollarSign,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
62
@xen-orchestra/lite/src/stories/linear-chart.story.md
Normal file
62
@xen-orchestra/lite/src/stories/linear-chart.story.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# LinearChart
|
||||
|
||||
### Type
|
||||
|
||||
```typescript
|
||||
type LinearChartData = {
|
||||
label: string;
|
||||
data: {
|
||||
timestamp: number;
|
||||
value: number;
|
||||
}[];
|
||||
}[];
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```vue-template
|
||||
<LinearChart
|
||||
title="Chart title"
|
||||
subtitle="Chart subtitle"
|
||||
:data="data"
|
||||
/>
|
||||
```
|
||||
|
||||
```vue-script
|
||||
const data: LinearChartData = [
|
||||
{
|
||||
"label": "First series",
|
||||
"data": [
|
||||
{
|
||||
"timestamp": 1640995200000,
|
||||
"value": 4986790
|
||||
},
|
||||
{
|
||||
"timestamp": 1641081600000,
|
||||
"value": 354312074
|
||||
},
|
||||
{
|
||||
"timestamp": 1641168000000,
|
||||
"value": 379858800
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Second series",
|
||||
"data": [
|
||||
{
|
||||
"timestamp": 1640995200000,
|
||||
"value": 102528411
|
||||
},
|
||||
{
|
||||
"timestamp": 1641081600000,
|
||||
"value": 10682534
|
||||
},
|
||||
{
|
||||
"timestamp": 1641168000000,
|
||||
"value": 10421188
|
||||
},
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
138
@xen-orchestra/lite/src/stories/linear-chart.story.vue
Normal file
138
@xen-orchestra/lite/src/stories/linear-chart.story.vue
Normal file
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
:params="[
|
||||
prop('title').preset('Chart title').widget(),
|
||||
prop('subtitle').preset('Here is a subtitle').widget(),
|
||||
prop('data')
|
||||
.preset(data)
|
||||
.required()
|
||||
.obj('LinearChartData')
|
||||
.help('See doc for typing')
|
||||
.widget(),
|
||||
prop('value-formatter').type('(value: number) => string'),
|
||||
prop('max-value').type('number').widget().default(200),
|
||||
]"
|
||||
:presets="presets"
|
||||
v-slot="{ properties }"
|
||||
>
|
||||
<LinearChart v-bind="properties" />
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import humanFormat from "human-format";
|
||||
import type { LinearChartData } from "@/types/chart";
|
||||
import LinearChart from "@/components/charts/LinearChart.vue";
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import { prop } from "@/libs/story/story-param";
|
||||
|
||||
const byteFormatter = (value: number) => humanFormat.bytes(value);
|
||||
|
||||
let time = 0;
|
||||
const firstDay = () => (time = 1640995200000);
|
||||
const nextDay = () => (time += 86400000);
|
||||
|
||||
const data: LinearChartData = [
|
||||
{
|
||||
label: "Foo",
|
||||
data: [
|
||||
{ timestamp: firstDay(), value: 50 },
|
||||
{ timestamp: nextDay(), value: 20 },
|
||||
{ timestamp: nextDay(), value: 90 },
|
||||
{ timestamp: nextDay(), value: 30 },
|
||||
{ timestamp: nextDay(), value: 70 },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Bar",
|
||||
data: [
|
||||
{ timestamp: firstDay(), value: 10 },
|
||||
{ timestamp: nextDay(), value: 80 },
|
||||
{ timestamp: nextDay(), value: 30 },
|
||||
{ timestamp: nextDay(), value: 40 },
|
||||
{ timestamp: nextDay(), value: 20 },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const presets = {
|
||||
"Network bandwidth": {
|
||||
props: {
|
||||
title: "Network bandwidth",
|
||||
subtitle: "Last week",
|
||||
"value-formatter": byteFormatter,
|
||||
"max-value": 500000000,
|
||||
data: [
|
||||
{
|
||||
label: "Download",
|
||||
data: [
|
||||
{
|
||||
timestamp: firstDay(),
|
||||
value: 4986790,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 354312074,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 379858800,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 319522087,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 344568079,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 46295651,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 344130914,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Upload",
|
||||
data: [
|
||||
{
|
||||
timestamp: firstDay(),
|
||||
value: 102528411,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 10682534,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 10421188,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 102156882,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 102028168,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 102733601,
|
||||
},
|
||||
{
|
||||
timestamp: nextDay(),
|
||||
value: 102523226,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
@@ -0,0 +1,3 @@
|
||||
```vue-template
|
||||
<PowerStateIcon :state="powerState" />
|
||||
```
|
||||
22
@xen-orchestra/lite/src/stories/power-state-icon.story.vue
Normal file
22
@xen-orchestra/lite/src/stories/power-state-icon.story.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
:params="[
|
||||
prop('state')
|
||||
.enum('Running', 'Suspended', 'Halted', 'Paused')
|
||||
.required()
|
||||
.preset('Running')
|
||||
.widget(),
|
||||
]"
|
||||
v-slot="{ properties }"
|
||||
>
|
||||
<PowerStateIcon style="font-size: 10rem" v-bind="properties" />
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import PowerStateIcon from "@/components/PowerStateIcon.vue";
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import { prop } from "@/libs/story/story-param";
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
6
@xen-orchestra/lite/src/stories/progress-circle.story.md
Normal file
6
@xen-orchestra/lite/src/stories/progress-circle.story.md
Normal file
@@ -0,0 +1,6 @@
|
||||
```vue-template
|
||||
<ProgressCircle
|
||||
:value="value"
|
||||
:max-value="maxValue"
|
||||
/>
|
||||
```
|
||||
39
@xen-orchestra/lite/src/stories/progress-circle.story.vue
Normal file
39
@xen-orchestra/lite/src/stories/progress-circle.story.vue
Normal file
@@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
:params="[
|
||||
prop('value').num().preset(25).required().widget(),
|
||||
prop('max-value').num().default(100).widget(),
|
||||
]"
|
||||
:presets="presets"
|
||||
v-slot="{ properties }"
|
||||
>
|
||||
<ProgressCircle v-bind="properties" />
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ProgressCircle from "@/components/ProgressCircle.vue";
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import { prop } from "@/libs/story/story-param";
|
||||
|
||||
const presets = {
|
||||
"Half of 500": {
|
||||
props: {
|
||||
"max-value": 500,
|
||||
value: 250,
|
||||
},
|
||||
},
|
||||
"75% of 300": {
|
||||
props: {
|
||||
"max-value": 300,
|
||||
value: 225,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped>
|
||||
.progress-circle {
|
||||
max-width: 30rem;
|
||||
}
|
||||
</style>
|
||||
25
@xen-orchestra/lite/src/stories/router-tab.story.vue
Normal file
25
@xen-orchestra/lite/src/stories/router-tab.story.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
v-slot="{ properties, settings }"
|
||||
:params="[
|
||||
prop('to').required().type('RouteLocationRaw').preset({ name: 'home' }),
|
||||
prop('disabled').bool().widget(),
|
||||
slot(),
|
||||
setting('label').widget(text()).preset('Foobar'),
|
||||
]"
|
||||
>
|
||||
<UiTabBar>
|
||||
<RouterTab v-bind="properties">{{ settings.label }}</RouterTab>
|
||||
</UiTabBar>
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import RouterTab from "@/components/RouterTab.vue";
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import UiTabBar from "@/components/ui/UiTabBar.vue";
|
||||
import { prop, setting, slot } from "@/libs/story/story-param.js";
|
||||
import { text } from "@/libs/story/story-widget.js";
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
14
@xen-orchestra/lite/src/stories/ui-badge.story.vue
Normal file
14
@xen-orchestra/lite/src/stories/ui-badge.story.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
:params="[iconProp(), setting('label').preset('65%').widget(), slot()]"
|
||||
v-slot="{ properties, settings }"
|
||||
>
|
||||
<UiBadge v-bind="properties">{{ settings.label }}</UiBadge>
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import UiBadge from "@/components/ui/UiBadge.vue";
|
||||
import { iconProp, setting, slot } from "@/libs/story/story-param";
|
||||
</script>
|
||||
29
@xen-orchestra/lite/src/stories/ui-button-group.story.vue
Normal file
29
@xen-orchestra/lite/src/stories/ui-button-group.story.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
:params="[
|
||||
prop('busy').type('boolean').widget(),
|
||||
prop('disabled').type('boolean').widget(),
|
||||
colorProp(),
|
||||
prop('outlined').type('boolean').widget(),
|
||||
prop('transparent').type('boolean').widget(),
|
||||
prop('merge').type('boolean').widget(),
|
||||
slot().help('Meant to receive UiButton components'),
|
||||
]"
|
||||
v-slot="{ properties }"
|
||||
>
|
||||
<UiButtonGroup v-bind="properties">
|
||||
<UiButton>Button 1</UiButton>
|
||||
<UiButton>Button 2</UiButton>
|
||||
<UiButton>Button 3</UiButton>
|
||||
</UiButtonGroup>
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import UiButton from "@/components/ui/UiButton.vue";
|
||||
import UiButtonGroup from "@/components/ui/UiButtonGroup.vue";
|
||||
import { colorProp, prop, slot } from "@/libs/story/story-param";
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
5
@xen-orchestra/lite/src/stories/ui-button.story.md
Normal file
5
@xen-orchestra/lite/src/stories/ui-button.story.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Here is some doc for UiButton component
|
||||
|
||||
```vue-template
|
||||
<UiButton @click="doSomething">Click me</UiButton>
|
||||
```
|
||||
47
@xen-orchestra/lite/src/stories/ui-button.story.vue
Normal file
47
@xen-orchestra/lite/src/stories/ui-button.story.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
v-slot="{ properties, settings }"
|
||||
:params="[
|
||||
prop('type').enum('submit', 'button', 'reset').default('button'),
|
||||
prop('busy').bool().widget(),
|
||||
prop('disabled').bool().widget(),
|
||||
iconProp(),
|
||||
colorProp(),
|
||||
prop('outlined').bool().widget(),
|
||||
prop('transparent').bool().widget(),
|
||||
prop('active').bool().widget(),
|
||||
setting('label').preset('Click me').widget(),
|
||||
]"
|
||||
:presets="{
|
||||
'Save Button': {
|
||||
props: {
|
||||
color: 'success',
|
||||
icon: faFloppyDisk,
|
||||
},
|
||||
settings: {
|
||||
label: 'Save',
|
||||
},
|
||||
},
|
||||
'Delete Button': {
|
||||
props: {
|
||||
icon: faTrash,
|
||||
color: 'error',
|
||||
},
|
||||
settings: {
|
||||
label: 'Delete',
|
||||
},
|
||||
},
|
||||
}"
|
||||
>
|
||||
<UiButton v-bind="properties">{{ settings.label }}</UiButton>
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import UiButton from "@/components/ui/UiButton.vue";
|
||||
import { colorProp, iconProp, prop, setting } from "@/libs/story/story-param";
|
||||
import { faFloppyDisk, faTrash } from "@fortawesome/free-solid-svg-icons";
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
22
@xen-orchestra/lite/src/stories/ui-filter.story.vue
Normal file
22
@xen-orchestra/lite/src/stories/ui-filter.story.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
v-slot="{ properties, settings }"
|
||||
:params="[
|
||||
event('edit'),
|
||||
event('remove'),
|
||||
slot(),
|
||||
setting('label').widget(text()).preset('Some filter'),
|
||||
]"
|
||||
>
|
||||
<UiFilter v-bind="properties">{{ settings.label }}</UiFilter>
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import UiFilter from "@/components/ui/UiFilter.vue";
|
||||
import { event, setting, slot } from "@/libs/story/story-param";
|
||||
import { text } from "@/libs/story/story-widget";
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
19
@xen-orchestra/lite/src/stories/ui-modal.story.md
Normal file
19
@xen-orchestra/lite/src/stories/ui-modal.story.md
Normal file
@@ -0,0 +1,19 @@
|
||||
```vue-template
|
||||
<button @click="open">Delete all items</button>
|
||||
|
||||
<UiModal v-if="isOpen" @close="close" :icon="faRemove">
|
||||
<template #title>You are about to delete 12 items</template>
|
||||
<template #subtitle>They'll be gone forever</template>
|
||||
<template #buttons>
|
||||
<UiButton @click="delete" color="error">Yes, delete</UiButton>
|
||||
<UiButton @click="close">Cancel</UiButton>
|
||||
</template>
|
||||
</UiModal>
|
||||
```
|
||||
|
||||
```vue-script
|
||||
import { faRemove } from "@fortawesome/free-solid-svg-icons";
|
||||
import { useModal } from "@composable/modal.composable";
|
||||
|
||||
const { open, close, isOpen } = useModal().
|
||||
```
|
||||
45
@xen-orchestra/lite/src/stories/ui-modal.story.vue
Normal file
45
@xen-orchestra/lite/src/stories/ui-modal.story.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
:params="[
|
||||
colorProp(),
|
||||
iconProp(),
|
||||
event('close').preset(close),
|
||||
slot('default'),
|
||||
slot('title'),
|
||||
slot('subtitle'),
|
||||
slot('icon'),
|
||||
slot('buttons').help('Meant to receive UiButton components'),
|
||||
setting('title').preset('Modal Title').widget(),
|
||||
setting('subtitle').preset('Modal Subtitle').widget(),
|
||||
]"
|
||||
v-slot="{ properties, settings }"
|
||||
>
|
||||
<UiButton type="button" @click="open">Open Modal</UiButton>
|
||||
|
||||
<UiModal v-bind="properties" v-if="isOpen">
|
||||
<template #title>{{ settings.title }}</template>
|
||||
<template #subtitle>{{ settings.subtitle }}</template>
|
||||
<template #buttons>
|
||||
<UiButton @click="close">Discard</UiButton>
|
||||
</template>
|
||||
</UiModal>
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import UiButton from "@/components/ui/UiButton.vue";
|
||||
import UiModal from "@/components/ui/UiModal.vue";
|
||||
import useModal from "@/composables/modal.composable";
|
||||
import {
|
||||
colorProp,
|
||||
event,
|
||||
iconProp,
|
||||
setting,
|
||||
slot,
|
||||
} from "@/libs/story/story-param";
|
||||
|
||||
const { open, close, isOpen } = useModal();
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
24
@xen-orchestra/lite/src/stories/ui-tab-bar.story.vue
Normal file
24
@xen-orchestra/lite/src/stories/ui-tab-bar.story.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
v-slot="{ properties }"
|
||||
:params="[
|
||||
prop('disabled').bool().widget(),
|
||||
slot().help('Contains <RouterTab> or <UiTab>'),
|
||||
]"
|
||||
>
|
||||
<UiTabBar v-bind="properties">
|
||||
<UiTab>Foo</UiTab>
|
||||
<UiTab>Bar</UiTab>
|
||||
<UiTab>Baz</UiTab>
|
||||
</UiTabBar>
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import UiTab from "@/components/ui/UiTab.vue";
|
||||
import UiTabBar from "@/components/ui/UiTabBar.vue";
|
||||
import { prop, slot } from "@/libs/story/story-param.js";
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
26
@xen-orchestra/lite/src/stories/ui-tab.story.vue
Normal file
26
@xen-orchestra/lite/src/stories/ui-tab.story.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<ComponentStory
|
||||
v-slot="{ properties, settings }"
|
||||
:params="[
|
||||
prop('disabled').bool().widget(),
|
||||
prop('active').bool().widget(),
|
||||
prop('tag').str().default('span'),
|
||||
slot(),
|
||||
setting('label').widget(text()).preset('Foobar'),
|
||||
]"
|
||||
>
|
||||
<UiTabBar>
|
||||
<UiTab v-bind="properties">{{ settings.label }}</UiTab>
|
||||
</UiTabBar>
|
||||
</ComponentStory>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import ComponentStory from "@/components/component-story/ComponentStory.vue";
|
||||
import UiTab from "@/components/ui/UiTab.vue";
|
||||
import UiTabBar from "@/components/ui/UiTabBar.vue";
|
||||
import { prop, setting, slot } from "@/libs/story/story-param.js";
|
||||
import { text } from "@/libs/story/story-widget.js";
|
||||
</script>
|
||||
|
||||
<style lang="postcss" scoped></style>
|
||||
Reference in New Issue
Block a user