refactor: use histoire instead of view components page

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/581/head
Ryan Wang 2022-04-22 16:05:30 +08:00
parent 36b77fc563
commit 2e56412670
16 changed files with 524 additions and 460 deletions

View File

@ -1,3 +1,5 @@
import { defineConfig } from "histoire";
export default defineConfig({});
export default defineConfig({
setupFile: "/src/histoire.setup.ts",
});

View File

@ -7,7 +7,7 @@
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview --port 5050",
"test:unit": "vitest --environment jsdom --run",
"test:unit:watch": "vitest --environment jsdom --watch",
"test:unit:watch": "vitest --environment jsdom --watch --ui",
"test:unit:coverage": "vitest run --environment jsdom --coverage",
"test:e2e": "start-server-and-test preview http://127.0.0.1:5050/ 'cypress open'",
"test:e2e:ci": "start-server-and-test preview http://127.0.0.1:5050/ 'cypress run'",
@ -28,17 +28,18 @@
"@types/node": "^17.0.25",
"@vitejs/plugin-vue": "^2.3.1",
"@vitejs/plugin-vue-jsx": "^1.3.10",
"@vitest/ui": "^0.9.4",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^10.0.0",
"@vue/test-utils": "^2.0.0-rc.20",
"@vue/test-utils": "^2.0.0-rc.21",
"@vue/tsconfig": "^0.1.3",
"autoprefixer": "^10.4.4",
"c8": "^7.11.0",
"c8": "^7.11.2",
"cypress": "^9.5.4",
"eslint": "^8.13.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-vue": "^8.6.0",
"histoire": "^0.2.4",
"histoire": "^0.2.5",
"husky": "^7.0.4",
"jsdom": "^19.0.0",
"postcss": "^8.4.12",
@ -50,7 +51,7 @@
"typescript": "~4.6.3",
"unplugin-icons": "^0.14.1",
"vite": "^2.9.5",
"vitest": "^0.9.3",
"vitest": "^0.9.4",
"vue-tsc": "^0.31.4"
}
}

View File

@ -7,17 +7,18 @@ specifiers:
'@types/node': ^17.0.25
'@vitejs/plugin-vue': ^2.3.1
'@vitejs/plugin-vue-jsx': ^1.3.10
'@vitest/ui': ^0.9.4
'@vue/eslint-config-prettier': ^7.0.0
'@vue/eslint-config-typescript': ^10.0.0
'@vue/test-utils': ^2.0.0-rc.20
'@vue/test-utils': ^2.0.0-rc.21
'@vue/tsconfig': ^0.1.3
autoprefixer: ^10.4.4
c8: ^7.11.0
c8: ^7.11.2
cypress: ^9.5.4
eslint: ^8.13.0
eslint-plugin-cypress: ^2.12.1
eslint-plugin-vue: ^8.6.0
histoire: ^0.2.4
histoire: ^0.2.5
husky: ^7.0.4
jsdom: ^19.0.0
pinia: ^2.0.13
@ -30,7 +31,7 @@ specifiers:
typescript: ~4.6.3
unplugin-icons: ^0.14.1
vite: ^2.9.5
vitest: ^0.9.3
vitest: ^0.9.4
vue: ^3.2.33
vue-router: ^4.0.14
vue-tsc: ^0.31.4
@ -47,17 +48,18 @@ devDependencies:
'@types/node': 17.0.25
'@vitejs/plugin-vue': 2.3.1_vite@2.9.5+vue@3.2.33
'@vitejs/plugin-vue-jsx': 1.3.10
'@vitest/ui': 0.9.4
'@vue/eslint-config-prettier': 7.0.0_eslint@8.13.0+prettier@2.6.2
'@vue/eslint-config-typescript': 10.0.0_a62cbc2f4797496d74696b1f6538012a
'@vue/test-utils': 2.0.0-rc.20_vue@3.2.33
'@vue/test-utils': 2.0.0-rc.21_vue@3.2.33
'@vue/tsconfig': 0.1.3_@types+node@17.0.25
autoprefixer: 10.4.4_postcss@8.4.12
c8: 7.11.0
c8: 7.11.2
cypress: 9.5.4
eslint: 8.13.0
eslint-plugin-cypress: 2.12.1_eslint@8.13.0
eslint-plugin-vue: 8.6.0_eslint@8.13.0
histoire: 0.2.4_470c9fb72f69752b7738379dbac6ab3d
histoire: 0.2.5_470c9fb72f69752b7738379dbac6ab3d
husky: 7.0.4
jsdom: 19.0.0
postcss: 8.4.12
@ -69,7 +71,7 @@ devDependencies:
typescript: 4.6.3
unplugin-icons: 0.14.1_vite@2.9.5
vite: 2.9.5_sass@1.50.1
vitest: 0.9.3_40eeb18efc0a382653524b81f64824b7
vitest: 0.9.4_2f3c27121f62934692d33844851ba7e1
vue-tsc: 0.31.4_typescript@4.6.3
packages:
@ -506,8 +508,8 @@ packages:
'@hapi/hoek': 9.2.1
dev: true
/@histoire/controls/0.2.4_vue@3.2.33:
resolution: {integrity: sha512-w16oZSxNwquPxu4c00gXdgWja7et9UX4LWBOonM+Ioqi5fWmHKcdAxWEbmQgxO7pYgHP0taoiBrR/GXEbeqhlg==}
/@histoire/controls/0.2.5_vue@3.2.33:
resolution: {integrity: sha512-4+yTBlUaIiVBe6jVoDB90bfyUUaNANDqFRPpURPPibZQ715zoTo9QGxemZun1etKGG2ZYH92d0pOmnGKwa/rPQ==}
dependencies:
'@iconify/vue': 3.2.1_vue@3.2.33
'@vueuse/core': 8.2.5_vue@3.2.33
@ -584,6 +586,13 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.11
dev: true
/@jridgewell/trace-mapping/0.3.9:
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
dependencies:
'@jridgewell/resolve-uri': 3.0.5
'@jridgewell/sourcemap-codec': 1.4.11
dev: true
/@nodelib/fs.scandir/2.1.5:
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@ -643,11 +652,11 @@ packages:
/@types/chai-subset/1.3.3:
resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==}
dependencies:
'@types/chai': 4.3.0
'@types/chai': 4.3.1
dev: true
/@types/chai/4.3.0:
resolution: {integrity: sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==}
/@types/chai/4.3.1:
resolution: {integrity: sha512-/zPMqDkzSZ8t3VtxOa4KPq7uzzW978M9Tvh+j7GHKuo6k6GTLxPJ4J5gE5cjfJ26pnXst0N5Hax8Sr0T2Mi9zQ==}
dev: true
/@types/concat-stream/1.6.1:
@ -873,6 +882,12 @@ packages:
vue: 3.2.33
dev: true
/@vitest/ui/0.9.4:
resolution: {integrity: sha512-30fSFtqKW+j0EcYuLzFOOC6+nobi3p7bptmUunkF9oLV3578QY+jqjWCJOY+sTQSUnq9cvOzwHjIsvIoLiq4Jw==}
dependencies:
sirv: 2.0.2
dev: true
/@volar/code-gen/0.31.4:
resolution: {integrity: sha512-ngivMEbBNd19v+EHdLyCJoIGRaoD9J4P20ZgdCEGf2voztja59u3Tilpf9r9ENy/731nG7XncToYm4+c1t/LhA==}
dependencies:
@ -1070,8 +1085,8 @@ packages:
/@vue/shared/3.2.33:
resolution: {integrity: sha512-UBc1Pg1T3yZ97vsA2ueER0F6GbJebLHYlEi4ou1H5YL4KWvMOOWwpYo9/QpWq93wxKG6Wo13IY74Hcn/f7c7Bg==}
/@vue/test-utils/2.0.0-rc.20_vue@3.2.33:
resolution: {integrity: sha512-aSkOAzM/ZlIyYgN7yj661FTjhFZZy5i9+FUbbDNoMGYA4F1WKwDdcDCPj9B/qzt3wGFkuCP5PO6SBtdSTMEhIA==}
/@vue/test-utils/2.0.0-rc.21_vue@3.2.33:
resolution: {integrity: sha512-wIJR4e/jISBKVKfiod3DV32BlDsoD744WVCuCaGtaSKvhvTL9gI5vl2AYSy00V51YaM8dCOFi3zcpCON8G1WqA==}
peerDependencies:
vue: ^3.0.1
dependencies:
@ -1407,8 +1422,8 @@ packages:
ieee754: 1.2.1
dev: true
/c8/7.11.0:
resolution: {integrity: sha512-XqPyj1uvlHMr+Y1IeRndC2X5P7iJzJlEJwBpCdBbq2JocXOgJfr+JVfJkyNMGROke5LfKrhSFXGFXnwnRJAUJw==}
/c8/7.11.2:
resolution: {integrity: sha512-6ahJSrhS6TqSghHm+HnWt/8Y2+z0hM/FQyB1ybKhAR30+NYL9CTQ1uwHxuWw6U7BHlHv6wvhgOrH81I+lfCkxg==}
engines: {node: '>=10.12.0'}
hasBin: true
dependencies:
@ -1421,7 +1436,7 @@ packages:
istanbul-reports: 3.1.4
rimraf: 3.0.2
test-exclude: 6.0.0
v8-to-istanbul: 8.1.1
v8-to-istanbul: 9.0.0
yargs: 16.2.0
yargs-parser: 20.2.9
dev: true
@ -2848,14 +2863,14 @@ packages:
hasBin: true
dev: true
/histoire/0.2.4_470c9fb72f69752b7738379dbac6ab3d:
resolution: {integrity: sha512-ZG/BNAWME24MZNW8jh1AXLxjoT8xFYZ1t4ZXl/zK+2ue93IfBbcht/cQ4g8dQTevILawYiK1yoW7KuP2R5ZNrw==}
/histoire/0.2.5_470c9fb72f69752b7738379dbac6ab3d:
resolution: {integrity: sha512-kqSN1PZiZ+Q8Kxn2x9FS9/533Q+UPb/3+udrLPUC9hS51T7aTWm55Prd4cmKeo/0ZsB+lOgDAmoJxTNWPTjO3g==}
hasBin: true
peerDependencies:
vite: ^2.9.0
vue: ^3.2.31
dependencies:
'@histoire/controls': 0.2.4_vue@3.2.33
'@histoire/controls': 0.2.5_vue@3.2.33
'@iconify/vue': 3.2.1_vue@3.2.33
'@vitejs/plugin-vue': 2.3.1_vite@2.9.5+vue@3.2.33
'@vueuse/core': 8.2.5_vue@3.2.33
@ -4211,11 +4226,6 @@ packages:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
/source-map/0.7.3:
resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==}
engines: {node: '>= 8'}
dev: true
/sourcemap-codec/1.4.8:
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
dev: false
@ -4663,13 +4673,13 @@ packages:
resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==}
dev: true
/v8-to-istanbul/8.1.1:
resolution: {integrity: sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==}
/v8-to-istanbul/9.0.0:
resolution: {integrity: sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==}
engines: {node: '>=10.12.0'}
dependencies:
'@jridgewell/trace-mapping': 0.3.9
'@types/istanbul-lib-coverage': 2.0.4
convert-source-map: 1.8.0
source-map: 0.7.3
dev: true
/verror/1.10.0:
@ -4722,8 +4732,8 @@ packages:
fsevents: 2.3.2
dev: true
/vitest/0.9.3_40eeb18efc0a382653524b81f64824b7:
resolution: {integrity: sha512-hKjqdBI732cV5giNLERyAsaJBebstrX5mvTbZr+jUDYUHnX1O4DpAJcHtqBOutuBi7lVIGQ5IF8eWvHHqbCHBA==}
/vitest/0.9.4_2f3c27121f62934692d33844851ba7e1:
resolution: {integrity: sha512-Em+EJb3keCr3GjyqnkxHuY7zMerEgLsN+m2nqsUcCzO7C4+Y0E7O7LXSNaODh3Gc/An3dqnoaAe/uLBrAJXUdQ==}
engines: {node: '>=v14.16.0'}
hasBin: true
peerDependencies:
@ -4741,9 +4751,10 @@ packages:
jsdom:
optional: true
dependencies:
'@types/chai': 4.3.0
'@types/chai': 4.3.1
'@types/chai-subset': 1.3.3
c8: 7.11.0
'@vitest/ui': 0.9.4
c8: 7.11.2
chai: 4.3.6
jsdom: 19.0.0
local-pkg: 0.4.1

View File

@ -2,43 +2,160 @@
<Story title="Button">
<Variant title="Type">
<template #default>
<VButton type="primary"> primary </VButton>
<VButton type="secondary"> secondary </VButton>
<VButton type="danger"> danger </VButton>
<VSpace>
<VButton type="primary"> primary </VButton>
<VButton type="secondary"> secondary </VButton>
<VButton type="danger"> danger </VButton>
<VButton type="default"> default </VButton>
</VSpace>
</template>
</Variant>
<Variant title="Size">
<template #default>
<VButton type="secondary" size="lg"> Large </VButton>
<VButton type="secondary"> default </VButton>
<VButton type="secondary" size="sm"> sm </VButton>
<VButton type="secondary" size="xs"> xs </VButton>
<VSpace>
<VButton type="secondary" size="lg"> Large </VButton>
<VButton type="secondary"> default </VButton>
<VButton type="secondary" size="sm"> sm </VButton>
<VButton type="secondary" size="xs"> xs </VButton>
</VSpace>
</template>
</Variant>
<Variant title="Circle">
<template #default>
<VButton type="secondary" size="lg" circle> lg </VButton>
<VButton type="secondary" circle> d </VButton>
<VButton type="secondary" size="sm" circle> sm </VButton>
<VButton type="secondary" size="xs" circle> xs </VButton>
<VSpace>
<VButton type="secondary" size="lg" circle> lg </VButton>
<VButton type="secondary" circle> d </VButton>
<VButton type="secondary" size="sm" circle> sm </VButton>
<VButton type="secondary" size="xs" circle> xs </VButton>
</VSpace>
</template>
</Variant>
<Variant title="Block">
<template #default>
<VButton type="primary" block> primary </VButton>
<VButton type="secondary" block> secondary </VButton>
<VButton type="danger" block> danger </VButton>
<VSpace direction="column" class="w-full">
<VButton type="primary" block> primary </VButton>
<VButton type="secondary" block> secondary </VButton>
<VButton type="danger" block> danger </VButton>
<VButton type="default" block> default </VButton>
</VSpace>
</template>
</Variant>
<Variant title="Disabled">
<template #default>
<VButton type="primary" disabled> primary </VButton>
<VButton type="secondary" disabled> secondary </VButton>
<VButton type="danger" disabled> danger </VButton>
<Variant title="Disabled" :init-state="disabledState">
<template #default="{ state }">
<VSpace>
<VButton type="primary" :disabled="state.disabled"> primary </VButton>
<VButton type="secondary" :disabled="state.disabled">
secondary
</VButton>
<VButton type="danger" :disabled="state.disabled"> danger </VButton>
<VButton type="default" :disabled="state.disabled"> default </VButton>
</VSpace>
</template>
<template #controls="{ state }">
<HstCheckbox v-model="state.disabled" title="Disabled" />
</template>
</Variant>
<Variant title="Loading" :init-state="loadingState">
<template #default="{ state }">
<VSpace>
<VButton type="primary" :loading="state.loading"> Primary </VButton>
<VButton type="secondary" :loading="state.loading">
Secondary
</VButton>
<VButton type="danger" :loading="state.loading"> Danger </VButton>
<VButton type="default" :loading="state.loading"> Default </VButton>
<VButton size="lg" type="secondary" :loading="state.loading">
Large
</VButton>
<VButton type="secondary" :loading="state.loading">Default</VButton>
<VButton size="sm" type="secondary" :loading="state.loading">
sm
</VButton>
<VButton size="xs" type="secondary" :loading="state.loading">
xs
</VButton>
</VSpace>
</template>
<template #controls="{ state }">
<HstCheckbox v-model="state.loading" title="Loading" />
</template>
</Variant>
<Variant title="Icon" :init-state="iconState">
<template #default="{ state }">
<VSpace>
<VButton
size="lg"
type="primary"
:loading="state.loading"
:disabled="state.disabled"
>
<template #icon>
<IconSettings class="w-full h-full" />
</template>
Large
</VButton>
<VButton
type="secondary"
:loading="state.loading"
:disabled="state.disabled"
>
<template #icon>
<IconSettings class="w-full h-full" />
</template>
Default
</VButton>
<VButton
size="sm"
type="danger"
:loading="state.loading"
:disabled="state.disabled"
>
<template #icon>
<IconSettings class="w-full h-full" />
</template>
sm
</VButton>
<VButton
size="xs"
type="default"
:loading="state.loading"
:disabled="state.disabled"
>
<template #icon>
<IconSettings class="w-full h-full" />
</template>
xs
</VButton>
</VSpace>
</template>
<template #controls="{ state }">
<HstCheckbox v-model="state.loading" title="Loading" />
<HstCheckbox v-model="state.disabled" title="Disabled" />
</template>
</Variant>
</Story>
</template>
<script setup>
<script lang="ts" setup>
import { VButton } from "./index";
import { VSpace } from "../space";
import { IconSettings } from "@/core/icons";
function loadingState() {
return {
loading: true,
};
}
function disabledState() {
return {
disabled: true,
};
}
function iconState() {
return {
loading: false,
disabled: false,
};
}
</script>

View File

@ -0,0 +1,36 @@
<template>
<Story title="CheckBox" :init-state="initState">
<template #default="{ state }">
<VCheckboxGroup
v-model="state.value"
:options="checkboxData"
name="fruit"
/>
Checked: {{ state.value.join(", ") }}
</template>
</Story>
</template>
<script lang="ts" setup>
import { VCheckboxGroup } from "@/components/base/checkbox";
function initState() {
return {
value: ["apple"],
};
}
const checkboxData = [
{
value: "apple",
label: "Apple",
},
{
value: "banana",
label: "Banana",
},
{
value: "orange",
label: "Orange",
},
];
</script>

View File

@ -0,0 +1,31 @@
<template>
<Story title="Input" :init-state="initState">
<template #default="{ state }">
<div class="w-1/2">
<VInput
v-model="state.value"
:disabled="state.disabled"
:placeholder="state.placeholder"
:size="state.size"
/>
</div>
</template>
<template #controls="{ state }">
<HstText v-model="state.value" title="Value" />
<HstText v-model="state.placeholder" title="Placeholder" />
<HstCheckbox v-model="state.disabled" title="Disabled" />
</template>
</Story>
</template>
<script lang="ts" setup>
import { VInput } from "@/components/base/input/index";
function initState() {
return {
value: "Hello Halo",
disabled: false,
placeholder: "",
size: "md",
};
}
</script>

View File

@ -2,18 +2,47 @@
<Story title="Menu">
<Variant title="Playground">
<template #default>
<VMenu>
<VMenuItem title="仪表盘">
<template #icon>
<Component :is="IconDashboard" />
</template>
</VMenuItem>
</VMenu>
<div class="w-1/3">
<VMenu>
<VMenuItem title="仪表盘" active>
<template #icon>
<Component :is="IconDashboard" />
</template>
</VMenuItem>
<VMenuLabel>内容</VMenuLabel>
<VMenuItem title="文章">
<template #icon>
<Component :is="IconBookRead" />
</template>
</VMenuItem>
<VMenuItem title="页面">
<template #icon>
<Component :is="IconPages" />
</template>
</VMenuItem>
<VMenuItem title="评论">
<template #icon>
<Component :is="IconMessage" />
</template>
</VMenuItem>
<VMenuItem title="附件">
<template #icon>
<Component :is="IconFolder" />
</template>
</VMenuItem>
</VMenu>
</div>
</template>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { VMenu, VMenuItem } from "./index";
import { IconDashboard } from "@/core/icons";
import { VMenu, VMenuItem, VMenuLabel } from "./index";
import {
IconDashboard,
IconBookRead,
IconPages,
IconMessage,
IconFolder,
} from "@/core/icons";
</script>

View File

@ -0,0 +1,40 @@
<template>
<Story title="Radio" :init-state="initState">
<template #default="{ state }">
<VRadioGroup v-model="state.value" :options="radioData"></VRadioGroup>
<VRadio
v-for="(option, index) in radioData"
:key="index"
v-model="state.value"
:label="option.label"
:value="option.value"
name="fruit"
></VRadio>
</template>
</Story>
</template>
<script lang="ts" setup>
import { VRadioGroup, VRadio } from "@/components/base/radio/index";
function initState() {
return {
value: "apple",
};
}
const radioData = [
{
value: "banana",
label: "Banana",
},
{
value: "apple",
label: "Apple",
},
{
value: "orange",
label: "Orange",
},
];
</script>

View File

@ -0,0 +1,49 @@
<template>
<Story :init-state="initState" title="Select">
<template #default="{ state }">
<div class="w-1/2">
<VSelect
v-model="state.value"
:disabled="state.disabled"
:placeholder="state.placeholder"
>
<VOption
v-for="(option, index) in selectData"
:key="index"
:value="option.value"
>
{{ option.label }}
</VOption>
</VSelect>
</div>
</template>
<template #controls="{ state }">
<HstText v-model="state.value" title="Value" />
<HstText v-model="state.placeholder" title="Placeholder" />
<HstCheckbox v-model="state.disabled" title="Disabled" />
</template>
</Story>
</template>
<script lang="ts" setup>
import { VOption, VSelect } from "@/components/base/select/index";
function initState() {
return {
value: undefined,
disabled: false,
placeholder: "",
size: "md",
};
}
const selectData = [
{
value: "apple",
label: "Apple",
},
{
value: "banana",
label: "Banana",
},
];
</script>

View File

@ -0,0 +1,52 @@
<template>
<Story title="Space" :init-state="initState">
<template #default="{ state }">
<VRadio
v-for="(option, index) in ['row', 'column']"
:key="index"
v-model="state.direction"
:label="option"
:value="option"
name="direction"
></VRadio>
<VRadio
v-for="(option, index) in ['start', 'center', 'end', 'stretch']"
:key="index"
v-model="state.align"
:label="option"
:value="option"
name="align"
></VRadio>
<VRadio
v-for="(option, index) in ['xs', 'sm', 'md', 'lg']"
:key="index"
v-model="state.spacing"
:label="option"
:value="option"
name="spacing"
></VRadio>
<VSpace
:direction="state.direction"
:spacing="state.spacing"
:align="state.align"
>
<div>Control</div>
<VButton type="primary">确定</VButton>
<VButton>取消</VButton>
</VSpace>
</template>
</Story>
</template>
<script lang="ts" setup>
import { VSpace } from "@/components/base/space/index";
import { VButton } from "@/components/base/button";
import { VRadio } from "@/components/base/radio";
function initState() {
return {
direction: "row",
spacing: "xs",
align: "center",
};
}
</script>

View File

@ -0,0 +1,49 @@
<template>
<Story title="Tag">
<Variant title="Theme">
<template #default>
<VSpace>
<VTag theme="default">Halo</VTag>
<VTag theme="primary">Halo</VTag>
<VTag theme="secondary">Halo</VTag>
<VTag theme="danger">Halo</VTag>
</VSpace>
</template>
</Variant>
<Variant title="Icon">
<template #default>
<VSpace>
<VTag theme="default" rounded>
<template #leftIcon>
<IconSettings />
</template>
Halo
</VTag>
<VTag theme="primary" rounded>
<template #leftIcon>
<IconSettings />
</template>
Halo
</VTag>
<VTag theme="secondary">
<template #leftIcon>
<IconSettings />
</template>
Halo
</VTag>
<VTag theme="danger">
<template #leftIcon>
<IconSettings />
</template>
Halo
</VTag>
</VSpace>
</template>
</Variant>
</Story>
</template>
<script lang="ts" setup>
import { VTag } from "@/components/base/tag/index";
import { VSpace } from "@/components/base/space/index";
import { IconSettings } from "@/core/icons";
</script>

View File

@ -0,0 +1,33 @@
<template>
<Story title="Textarea" :init-state="initState">
<template #default="{ state }">
<div class="w-1/2">
<VTextarea
v-model="state.value"
:disabled="state.disabled"
:placeholder="state.placeholder"
:size="state.size"
:rows="state.rows"
/>
</div>
</template>
<template #controls="{ state }">
<HstText v-model="state.value" title="Value" />
<HstText v-model="state.placeholder" title="Placeholder" />
<HstCheckbox v-model="state.disabled" title="Disabled" />
<HstNumber v-model="state.rows" title="Rows"></HstNumber>
</template>
</Story>
</template>
<script lang="ts" setup>
import { VTextarea } from "@/components/base/textarea/index";
function initState() {
return {
value: "Hello Halo",
disabled: false,
placeholder: "",
rows: 3,
};
}
</script>

5
src/histoire.setup.ts Normal file
View File

@ -0,0 +1,5 @@
import "@/styles/tailwind.css";
import { defineVue3StorySetup } from "histoire/client";
// eslint-disable-next-line @typescript-eslint/no-empty-function
export default defineVue3StorySetup(() => {});

View File

@ -2,15 +2,14 @@ import {
IconBookRead,
IconDashboard,
IconEye,
IconFolder,
IconListSettings,
IconMagic,
IconMessage,
IconPages,
IconPalette,
IconPlug,
IconSettings,
IconUserSettings,
IconFolder,
} from "@/core/icons";
import type { Component } from "vue";
@ -100,11 +99,6 @@ export const menus: MenuGroupType[] = [
path: "/settings",
icon: IconSettings,
},
{
name: "组件",
path: "/components",
icon: IconMagic,
},
],
},
];

View File

@ -1,7 +1,6 @@
import type { RouteRecordRaw } from "vue-router";
import HomeView from "../views/HomeView.vue";
import AboutView from "../views/AboutView.vue";
import ViewComponents from "../views/ViewComponents.vue";
export const routes: Array<RouteRecordRaw> = [
{
@ -76,11 +75,6 @@ export const routes: Array<RouteRecordRaw> = [
name: "Settings",
component: AboutView,
},
{
path: "/components",
name: "Components",
component: ViewComponents,
},
];
export default routes;

View File

@ -1,379 +0,0 @@
<template>
<FilledLayout>
<div class="container p-3">
<section class="box border-2 rounded p-2 mb-3">
<h1 class="text-xl font-bold mb-2">Button</h1>
<h2 class="mb-1">Type:</h2>
<div class="mb-3">
<VSpace>
<VButton type="primary">Primary</VButton>
<VButton type="secondary">Secondary</VButton>
<VButton type="danger">Danger</VButton>
<VButton type="default">Default</VButton>
</VSpace>
</div>
<h2 class="mb-1">Size:</h2>
<div class="mb-3">
<VSpace>
<VButton size="lg" type="secondary">Large</VButton>
<VButton type="secondary"> Default</VButton>
<VButton size="sm" type="secondary"> sm</VButton>
<VButton size="xs" type="secondary"> xs</VButton>
</VSpace>
</div>
<h2 class="mb-1">Circle:</h2>
<div class="mb-3">
<VSpace>
<VButton circle size="lg" type="secondary"> lg</VButton>
<VButton circle type="secondary"> d</VButton>
<VButton circle size="sm" type="secondary"> sm</VButton>
<VButton circle size="xs" type="secondary"> xs</VButton>
</VSpace>
</div>
<h2 class="mb-1">Block:</h2>
<div class="mb-3">
<VSpace direction="column" class="w-full">
<VButton block type="primary"> Primary</VButton>
<VButton block type="secondary"> Secondary</VButton>
<VButton block type="danger"> Danger</VButton>
</VSpace>
</div>
<h2 class="mb-1">Disabled:</h2>
<div>
<VSpace>
<VButton disabled type="primary"> Primary</VButton>
<VButton disabled type="secondary"> Secondary</VButton>
<VButton disabled type="danger"> Danger</VButton>
</VSpace>
</div>
<h2 class="mb-1">Loading:</h2>
<div class="mb-3">
<VSpace>
<VButton type="default" @click="buttonLoading = !buttonLoading">
{{ buttonLoading ? "停止" : "启动" }}
</VButton>
<VButton type="primary" :loading="buttonLoading"> Primary </VButton>
<VButton type="secondary" :loading="buttonLoading">
Secondary
</VButton>
<VButton type="danger" :loading="buttonLoading"> Danger </VButton>
<VButton type="default" :loading="buttonLoading"> Default </VButton>
<VButton size="lg" type="secondary" :loading="buttonLoading"
>Large</VButton
>
<VButton type="secondary" :loading="buttonLoading">
Default</VButton
>
<VButton size="sm" type="secondary" :loading="buttonLoading">
sm</VButton
>
<VButton size="xs" type="secondary" :loading="buttonLoading">
xs</VButton
>
</VSpace>
</div>
<h2 class="mb-1">Icon:</h2>
<div class="mb-3">
<VSpace>
<VButton size="lg" type="secondary">
<template #icon>
<IconSettings class="w-full h-full" />
</template>
Large
</VButton>
<VButton type="secondary">
<template #icon>
<IconSettings class="w-full h-full" />
</template>
Default
</VButton>
<VButton size="sm" type="secondary">
<template #icon>
<IconSettings class="w-full h-full" />
</template>
sm
</VButton>
<VButton size="xs" type="secondary">
<template #icon>
<IconSettings class="w-full h-full" />
</template>
xs
</VButton>
</VSpace>
</div>
</section>
<section class="box border-2 rounded p-2 mb-3">
<h1 class="text-xl font-bold mb-2">Input</h1>
<h2 class="mb-1">Size:</h2>
<div class="mb-3">
<VInput
v-model="inputValue"
class="mb-2"
placeholder="请输入邮箱"
size="lg"
/>
<VInput
v-model="inputValue"
class="mb-2"
placeholder="请输入邮箱"
size="md"
/>
<VInput
v-model="inputValue"
class="mb-2"
placeholder="请输入邮箱"
size="sm"
/>
<VInput v-model="inputValue" placeholder="请输入邮箱" size="xs" />
</div>
<!-- <h2 class="mb-1">With Icon:</h2>-->
<!-- <div class="mb-3">-->
<!-- <VInput v-model="inputValue" class="mb-2" size="md">-->
<!-- <template #prefix>-->
<!-- <IconDashboard />-->
<!-- </template>-->
<!-- <template #suffix>-->
<!-- <IconDashboard />-->
<!-- </template>-->
<!-- </VInput>-->
<!-- </div>-->
<h2 class="mb-1">Disabled:</h2>
<div class="mb-3">
<VInput v-model="inputValue" disabled />
</div>
</section>
<section class="box border-2 rounded p-2 mb-3">
<h1 class="text-xl font-bold mb-2">Textarea</h1>
<div class="mb-3">
<VTextarea
v-model="inputValue"
placeholder="Please input your description"
/>
</div>
<h2 class="mb-1">Disabled:</h2>
<div class="mb-3">
<VTextarea v-model="inputValue" :rows="4" disabled />
</div>
</section>
<section class="box border-2 rounded p-2 mb-3">
<h1 class="text-xl font-bold mb-2">Select</h1>
<h2 class="mb-1">Size:</h2>
<div class="mb-3">
<VSelect v-model="selectValue">
<VOption
v-for="(option, index) in selectData"
:key="index"
:value="option.value"
>
{{ option.label }}
</VOption>
</VSelect>
</div>
<h2 class="mb-1">Disabled:</h2>
<div class="mb-3">
<VSelect v-model="selectValue" disabled>
<VOption
v-for="(option, index) in selectData"
:key="index"
:value="option.value"
>
{{ option.label }}
</VOption>
</VSelect>
</div>
</section>
<section class="box border-2 rounded p-2 mb-3">
<h1 class="text-xl font-bold mb-2">Radio</h1>
<h2 class="mb-1">Radio:</h2>
<div class="mb-3">
<VRadio
v-for="(option, index) in radioData"
:key="index"
v-model="radioValue"
:label="option.label"
:value="option.value"
name="fruit"
></VRadio>
</div>
<h2 class="mb-1">Radio Group:</h2>
<div class="mb-3">
<VRadioGroup v-model="radioValue" :options="radioData"></VRadioGroup>
</div>
</section>
<section class="box border-2 rounded p-2 mb-3">
<h1 class="text-xl font-bold mb-2">CheckBox</h1>
<h2 class="mb-1">CheckBox:</h2>
<div class="mb-3">
<VCheckbox v-model:checked="checkboxValue" label="Apple" />
</div>
<h2 class="mb-1">CheckBox Group:</h2>
<div class="mb-3">
<VCheckboxGroup
v-model="checkboxGroupValue"
:options="checkboxData"
name="fruit"
/>
<span class="mr-1 text-gray-500">
Checked: {{ checkboxGroupValue }}
</span>
</div>
</section>
<section class="box border-2 rounded p-2 mb-3">
<h1 class="text-xl font-bold mb-2">Space</h1>
<div class="mb-3">
<VRadio
v-for="(option, index) in ['row', 'column']"
:key="index"
v-model="spaceState.direction"
:label="option"
:value="option"
name="direction"
></VRadio>
<VRadio
v-for="(option, index) in ['start', 'center', 'end', 'stretch']"
:key="index"
v-model="spaceState.align"
:label="option"
:value="option"
name="align"
></VRadio>
<VRadio
v-for="(option, index) in ['xs', 'sm', 'md', 'lg']"
:key="index"
v-model="spaceState.spacing"
:label="option"
:value="option"
name="spacing"
></VRadio>
<VSpace
:direction="spaceState.direction"
:spacing="spaceState.spacing"
:align="spaceState.align"
>
<div>Control</div>
<VButton type="primary">确定</VButton>
<VButton>取消</VButton>
</VSpace>
</div>
</section>
<section class="box border-2 rounded p-2 mb-3">
<h1 class="text-xl font-bold mb-2">Tag</h1>
<h2 class="mb-1">Themes:</h2>
<div class="mb-3">
<VSpace>
<VTag theme="default">Halo</VTag>
<VTag theme="primary">Halo</VTag>
<VTag theme="secondary">Halo</VTag>
<VTag theme="danger">Halo</VTag>
</VSpace>
</div>
<h2 class="mb-1">With Icon:</h2>
<div class="mb-3">
<VSpace>
<VTag theme="default" rounded>
<template #leftIcon>
<IconSettings />
</template>
Halo
</VTag>
<VTag theme="primary" rounded>
<template #leftIcon>
<IconSettings />
</template>
Halo
</VTag>
<VTag theme="secondary">
<template #leftIcon>
<IconSettings />
</template>
Halo
</VTag>
<VTag theme="danger">
<template #leftIcon>
<IconSettings />
</template>
Halo
</VTag>
</VSpace>
</div>
</section>
</div>
</FilledLayout>
</template>
<script lang="ts" setup>
import { IconSettings } from "@/core/icons";
import { FilledLayout } from "../layouts";
import { VButton } from "@/components/base/button";
import { VInput } from "@/components/base/input";
import { VOption, VSelect } from "@/components/base/select";
import { VTextarea } from "@/components/base/textarea";
import { VRadio, VRadioGroup } from "@/components/base/radio";
import { VCheckbox, VCheckboxGroup } from "@/components/base/checkbox";
import { VSpace } from "@/components/base/space";
import { VTag } from "@/components/base/tag";
import { reactive, ref } from "vue";
import type {
Align,
Direction,
Spacing,
} from "@/components/base/space/interface";
const buttonLoading = ref(true);
const inputValue = ref();
const selectValue = ref();
const radioValue = ref("apple");
const checkboxValue = ref(false);
const checkboxGroupValue = ref(["apple"]);
const spaceState = reactive<{
direction: Direction;
spacing: Spacing;
align: Align;
}>({
direction: "row",
spacing: "xs",
align: "center",
});
const selectData = [
{
value: "1",
label: "1",
},
{
value: "2",
label: "2",
},
];
const radioData = [
{
value: "banana",
label: "Banana",
},
{
value: "apple",
label: "Apple",
},
{
value: "orange",
label: "Orange",
},
];
const checkboxData = [
{
value: "apple",
label: "Apple",
},
{
value: "banana",
label: "Banana",
},
{
value: "orange",
label: "Orange",
},
];
</script>