vanilla-vue-ui 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # vanilla-vue-ui
2
+
3
+ This template should help get you started developing with Vue 3 in Vite.
4
+
5
+ ## Recommended IDE Setup
6
+
7
+ [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
8
+
9
+ ## Type Support for `.vue` Imports in TS
10
+
11
+ TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
12
+
13
+ ## Customize configuration
14
+
15
+ See [Vite Configuration Reference](https://vite.dev/config/).
16
+
17
+ ## Project Setup
18
+
19
+ ```sh
20
+ npm install
21
+ ```
22
+
23
+ ### Compile and Hot-Reload for Development
24
+
25
+ ```sh
26
+ npm run dev
27
+ ```
28
+
29
+ ### Type-Check, Compile and Minify for Production
30
+
31
+ ```sh
32
+ npm run build
33
+ ```
34
+
35
+ ### Run Unit Tests with [Vitest](https://vitest.dev/)
36
+
37
+ ```sh
38
+ npm run test:unit
39
+ ```
40
+
41
+ ### Lint with [ESLint](https://eslint.org/)
42
+
43
+ ```sh
44
+ npm run lint
45
+ ```
@@ -0,0 +1,61 @@
1
+ // Replace vue3 with vue if you are using Storybook for Vue 2
2
+ import type { Meta, StoryObj } from '@storybook/vue3';
3
+ import WRange from './WRange.vue';
4
+ import { ref, watchEffect } from 'vue';
5
+
6
+ type WRangeProps = InstanceType<typeof WRange>['$props']
7
+
8
+ const meta: Meta<typeof WRange> = {
9
+ component: WRange,
10
+ };
11
+
12
+ export default meta;
13
+ type Story = StoryObj<typeof WRange>;
14
+
15
+ /*
16
+ *👇 Render functions are a framework specific feature to allow you control on how the component renders.
17
+ * See https://storybook.js.org/docs/api/csf
18
+ * to learn how to use render functions.
19
+ */
20
+ export const Primary: Story = {
21
+ render: () => ({
22
+ components: { WRange },
23
+ template: '<w-range @customInput="(value) => console.log(`Received customInput event with value:`, value)"></w-range>',
24
+ }),
25
+ };
26
+
27
+ export const PrimaryDataBinding: Story = {
28
+ render: (args: WRangeProps) => ({
29
+ setup() {
30
+ const modelValue = ref(args.modelValue)
31
+
32
+ // `update:modelValue`イベントをリッスンして、内部状態を更新
33
+ watchEffect(() => {
34
+ modelValue.value = args.modelValue;
35
+ });
36
+
37
+ return {
38
+ ...args,
39
+ modelValue,
40
+ updateModelValue: (newValue: number) => {
41
+ modelValue.value = newValue;
42
+ },
43
+ }
44
+ },
45
+ components: { WRange },
46
+ template: `
47
+ <w-range
48
+ :max="max"
49
+ :min="min"
50
+ :step="step"
51
+ v-model="modelValue"
52
+ ></w-range>
53
+ `,
54
+ }),
55
+ args: {
56
+ max: 100,
57
+ min: 0,
58
+ step: 10,
59
+ modelValue: 0
60
+ }
61
+ };
@@ -0,0 +1,93 @@
1
+ <template>
2
+ <input
3
+ type="range"
4
+ class="w-full"
5
+ :class="[
6
+ mergedClasses.content?.base,
7
+ mergedClasses.content?.backgroundColor,
8
+ mergedClasses.content?.rounded,
9
+ mergedClasses.content?.size,
10
+ ]"
11
+ :min="min"
12
+ :max="max"
13
+ :step="step"
14
+ :value="modelValue"
15
+ @input="inputValue"
16
+ >
17
+ </template>
18
+
19
+ <script setup lang="ts">
20
+ import { defineProps, type PropType, ref } from 'vue'
21
+ import type { ClassObject } from '../../types/ClassObject';
22
+ import { deepMergeClassObject } from '../../util';
23
+
24
+ const props = defineProps({
25
+ min: {
26
+ type: Number as PropType<number>,
27
+ default() {
28
+ return 0
29
+ }
30
+ },
31
+ max: {
32
+ type: Number as PropType<number>,
33
+ default() {
34
+ return 100
35
+ }
36
+ },
37
+ step: {
38
+ type: Number as PropType<number>,
39
+ default() {
40
+ return 1
41
+ }
42
+ },
43
+ modelValue: {
44
+ type: Number as PropType<number>,
45
+ default() {
46
+ return 0
47
+ }
48
+ },
49
+ classes: {
50
+ type: Object as PropType<ClassObject>,
51
+ }
52
+ })
53
+
54
+ const defaultClasses: ClassObject = {
55
+ icon: {
56
+ color: 'text-gray-500'
57
+ },
58
+ content: {
59
+ base: 'appearance-none [-webkit-appearance: none]',
60
+ backgroundColor: 'bg-gray-400',
61
+ rounded: 'rounded-full',
62
+ size: 'h-2'
63
+ }
64
+ }
65
+
66
+ // props.classesが渡されていない場合、defaultClassesを使用する
67
+ const mergedClasses = props.classes ? deepMergeClassObject(defaultClasses, props.classes) : defaultClasses;
68
+
69
+ const modelValue = ref<string>(props.modelValue.toString())
70
+
71
+ const emit = defineEmits<{
72
+ customInput: [value: Event],
73
+ 'update:modelValue': [value: number]
74
+ }>()
75
+
76
+ function inputValue(e: Event) {
77
+ const target = e.target as HTMLInputElement | null
78
+
79
+ if (target) {
80
+ emitCustomEvent(target.value)
81
+ modelValue.value = target.value
82
+
83
+ emit('update:modelValue', Number(target.value))
84
+ }
85
+ }
86
+
87
+ function emitCustomEvent(value: string) {
88
+ const event = new CustomEvent('input', {
89
+ detail: value
90
+ })
91
+ emit('customInput', event)
92
+ }
93
+ </script>
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "vanilla-vue-ui",
3
+ "version": "0.0.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "files": [
7
+ "basic",
8
+ "template",
9
+ "custom",
10
+ "icon",
11
+ "types",
12
+ "util"
13
+ ],
14
+ "scripts": {
15
+ "dev": "vite",
16
+ "build": "npm run copy",
17
+ "preview": "vite preview",
18
+ "test:unit": "vitest",
19
+ "build-only": "vite build",
20
+ "type-check": "vue-tsc --build",
21
+ "lint": "eslint . --fix",
22
+ "format": "prettier --write src/",
23
+ "storybook": "storybook dev -p 6006",
24
+ "build-storybook": "storybook build",
25
+ "copy-template": "copyfiles -u 1 src/template/**/* .",
26
+ "copy-basic": "copyfiles -u 1 src/basic/**/* .",
27
+ "copy-custom": "copyfiles -u 1 src/custom/**/* .",
28
+ "copy-icon": "copyfiles -u 1 src/icon/**/* .",
29
+ "copy-types": "copyfiles -u 1 src/types/**/* .",
30
+ "copy-util": "copyfiles -u 1 src/util/**/* .",
31
+ "copy": "npm run copy-template && npm run copy-basic && npm run copy-custom && npm run copy-icon && npm run copy-types && npm run copy-util"
32
+ },
33
+ "dependencies": {
34
+ "vue": "^3.5.13"
35
+ },
36
+ "devDependencies": {
37
+ "@chromatic-com/storybook": "^3.2.4",
38
+ "@storybook/addon-essentials": "^8.5.5",
39
+ "@storybook/addon-interactions": "^8.5.5",
40
+ "@storybook/addon-onboarding": "^8.5.5",
41
+ "@storybook/blocks": "^8.5.5",
42
+ "@storybook/test": "^8.5.5",
43
+ "@storybook/vue3": "^8.5.5",
44
+ "@storybook/vue3-vite": "^8.5.5",
45
+ "@tsconfig/node22": "^22.0.0",
46
+ "@types/jsdom": "^21.1.7",
47
+ "@types/node": "^22.9.3",
48
+ "@vitejs/plugin-vue": "^5.2.1",
49
+ "@vitest/eslint-plugin": "1.1.10",
50
+ "@vue/eslint-config-prettier": "^10.1.0",
51
+ "@vue/eslint-config-typescript": "^14.1.3",
52
+ "@vue/test-utils": "^2.4.6",
53
+ "@vue/tsconfig": "^0.7.0",
54
+ "copyfiles": "^2.4.1",
55
+ "eslint": "^9.14.0",
56
+ "eslint-plugin-storybook": "^0.11.2",
57
+ "eslint-plugin-vue": "^9.30.0",
58
+ "jsdom": "^25.0.1",
59
+ "npm-run-all2": "^7.0.1",
60
+ "prettier": "^3.3.3",
61
+ "storybook": "^8.5.5",
62
+ "typescript": "~5.6.3",
63
+ "vite": "^6.0.1",
64
+ "vite-plugin-vue-devtools": "^7.6.5",
65
+ "vitest": "^2.1.5",
66
+ "vue-tsc": "^2.1.10"
67
+ },
68
+ "eslintConfig": {
69
+ "extends": [
70
+ "plugin:storybook/recommended"
71
+ ]
72
+ }
73
+ }
@@ -0,0 +1,21 @@
1
+ export type ClassObject = {
2
+ base?: string;
3
+ backgroundColor?: string;
4
+ spacing?: string;
5
+ size?: string;
6
+ color?: string;
7
+ shadow?: string;
8
+ rounded?: string;
9
+ border?: string;
10
+ layout?: string;
11
+ text?: ClassObject;
12
+ outline?: ClassObject;
13
+ label?: ClassObject;
14
+ errorMessage?: ClassObject;
15
+ title?: ClassObject;
16
+ content?: ClassObject;
17
+ icon?: ClassObject;
18
+ button?: ClassObject;
19
+ input?: ClassObject;
20
+ [key: string]: any; // インデックスシグネチャの追加
21
+ }
@@ -0,0 +1,13 @@
1
+ import type { ClassObject } from "../types/ClassObject";
2
+
3
+ // 深くマージする関数
4
+ export function deepMergeClassObject(target: ClassObject, source: ClassObject): ClassObject {
5
+ for (const key in source) {
6
+ if (source[key] instanceof Object && key in target) {
7
+ target[key] = deepMergeClassObject(target[key], source[key]);
8
+ } else {
9
+ target[key] = source[key];
10
+ }
11
+ }
12
+ return target;
13
+ }
package/util/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { deepMergeClassObject } from "./deepMergeClassObject";
2
+
3
+ export { deepMergeClassObject }