@digitalwalletcorp/vue-core 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 digitalwalletcorp
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # Vue Core
2
+
3
+ Basic UI components for Vue 3.
4
+
5
+ #### ✨ Features
6
+
7
+ * **Tree-shaking**: Only import what you use. Importing a single component won't bundle the rest of the library.
8
+ * **Fully typed**: Type definitions are included, allowing your editor to auto-complete props and default values automatically.
9
+ * **Easy overrides**: Default styles use zero specificity (`:where()`), so your own CSS always wins.
10
+
11
+ #### 📦 Installation
12
+
13
+ ```bash
14
+ npm install @digitalwalletcorp/vue-core
15
+ # or
16
+ yarn add @digitalwalletcorp/vue-core
17
+ ```
18
+
19
+ > ##### ⚠️ Requirements
20
+ >
21
+ > * **Vue 3.5.29+**: Props are typed with Vue's `ClassValue`, which is exported since Vue 3.5.29.
22
+
23
+ #### 📖 Usage
24
+
25
+ There are three ways to use the components.
26
+
27
+ | | When to use | Bundled components |
28
+ | --- | ----------- | ------------------ |
29
+ | [Import individually](#1-import-components-individually) | When you want to minimize bundle size or prefer explicit imports | Only the components you import |
30
+ | [Register all components globally (Vue)](#2-register-all-components-globally-vue) | When you want to use components without importing them in each file | All components |
31
+ | [Register components globally (Nuxt)](#3-register-components-globally-nuxt) | When you want to use components globally in a Nuxt project | Only the components you use |
32
+
33
+ ##### 1. Import components individually
34
+
35
+ ```vue
36
+ <script setup lang="ts">
37
+ import { LabelButton } from '@digitalwalletcorp/vue-core';
38
+ </script>
39
+
40
+ <template>
41
+ <LabelButton class="btn" :preset="labelPresets.search" />
42
+ </template>
43
+ ```
44
+
45
+ ##### 2. Register all components globally (Vue)
46
+
47
+ ```ts
48
+ // main.ts
49
+ import { createApp } from 'vue';
50
+ import { registerComponents } from '@digitalwalletcorp/vue-core/register';
51
+ import App from './App.vue';
52
+
53
+ const app = createApp(App);
54
+ registerComponents(app);
55
+ app.mount('#app');
56
+ ```
57
+
58
+ ##### 3. Register components globally (Nuxt)
59
+
60
+ ```ts
61
+ // nuxt.config.ts
62
+ export default defineNuxtConfig({
63
+ modules: ['@digitalwalletcorp/vue-core/nuxt']
64
+ });
65
+ ```
66
+
67
+ ##### 📐 Stylesheet
68
+
69
+ The components need the bundled stylesheet.
70
+
71
+ * **Vue:** Import in your entry file.
72
+
73
+ ```ts
74
+ // main.ts
75
+ import '@digitalwalletcorp/vue-core/style.css';
76
+ ```
77
+
78
+ * **Nuxt:** Add to your config array.
79
+
80
+ ```ts
81
+ // nuxt.config.ts
82
+ export default defineNuxtConfig({
83
+ css: ['@digitalwalletcorp/vue-core/style.css']
84
+ });
85
+ ```
86
+
87
+ #### 🧰 Components
88
+
89
+ | Component | Description |
90
+ | --------- | ----------- |
91
+ | [`LabelIcon`](https://github.com/digitalwalletcorp/vue-core/blob/main/docs/components/label-icon.md) | Displays an icon and a text label side by side. |
92
+ | [`LabelButton`](https://github.com/digitalwalletcorp/vue-core/blob/main/docs/components/label-button.md) | Renders a button containing an icon and a text label. |
93
+
94
+ #### 📜 License
95
+
96
+ This project is licensed under the MIT License. See the [LICENSE](https://opensource.org/licenses/MIT) file for details.
@@ -0,0 +1 @@
1
+ "use strict";const e=require("./label-button.vue_vue_type_script_setup_true_lang-BNMpM0Tg.cjs"),t=require("./label-icon.vue_vue_type_style_index_0_lang-Df1Vmx77.cjs"),_=Object.freeze(Object.defineProperty({__proto__:null,LabelButton:e._sfc_main,LabelIcon:t._sfc_main},Symbol.toStringTag,{value:"Module"}));exports.components=_;
@@ -0,0 +1,10 @@
1
+ import { _ as o } from "./label-button.vue_vue_type_script_setup_true_lang-DsN7-lkK.js";
2
+ import { _ as e } from "./label-icon.vue_vue_type_style_index_0_lang-CD5U0MIO.js";
3
+ const r = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4
+ __proto__: null,
5
+ LabelButton: o,
6
+ LabelIcon: e
7
+ }, Symbol.toStringTag, { value: "Module" }));
8
+ export {
9
+ r as c
10
+ };
@@ -0,0 +1,2 @@
1
+ export { default as LabelButton } from './label-button';
2
+ export { default as LabelIcon } from './label-icon';
@@ -0,0 +1,7 @@
1
+ type VueCoreComponents = typeof import('../components');
2
+
3
+ declare module 'vue' {
4
+ interface GlobalComponents extends VueCoreComponents {}
5
+ }
6
+
7
+ export {};
package/lib/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./label-button.vue_vue_type_script_setup_true_lang-BNMpM0Tg.cjs"),t=require("./label-icon.vue_vue_type_style_index_0_lang-Df1Vmx77.cjs");exports.LabelButton=e._sfc_main;exports.LabelIcon=t._sfc_main;
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './components';
2
+ export type { LabelPreset } from './types/label-preset';
package/lib/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import { _ as e } from "./label-button.vue_vue_type_script_setup_true_lang-DsN7-lkK.js";
2
+ import { _ as t } from "./label-icon.vue_vue_type_style_index_0_lang-CD5U0MIO.js";
3
+ export {
4
+ e as LabelButton,
5
+ t as LabelIcon
6
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./label-button.vue_vue_type_script_setup_true_lang-BNMpM0Tg.cjs");exports.default=e._sfc_main;
@@ -0,0 +1,30 @@
1
+ import { ClassValue, StyleValue } from 'vue';
2
+ import { LabelPreset } from './types/label-preset';
3
+ interface Props {
4
+ /** アイコンとラベルの組み合わせ */
5
+ preset?: LabelPreset;
6
+ /** アイコンとラベルの間隔。未指定ならLabelIconの既定値(0.25em) */
7
+ gap?: string;
8
+ /** presetのアイコンに付けるclass。スロットで渡したアイコンには、スロット側で直接指定する */
9
+ iconClass?: ClassValue;
10
+ /** presetのアイコンに付けるstyle。スロットで渡したアイコンには、スロット側で直接指定する */
11
+ iconStyle?: StyleValue;
12
+ /** ラベルに付けるclass */
13
+ labelClass?: ClassValue;
14
+ /** ラベルに付けるstyle */
15
+ labelStyle?: StyleValue;
16
+ }
17
+ interface Slots {
18
+ icon?(): unknown;
19
+ default?(): unknown;
20
+ }
21
+ type __VLS_Slots = Slots;
22
+ declare const __VLS_base: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
23
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
24
+ declare const _default: typeof __VLS_export;
25
+ export default _default;
26
+ type __VLS_WithSlots<T, S> = T & {
27
+ new (): {
28
+ $slots: S;
29
+ };
30
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as f } from "./label-button.vue_vue_type_script_setup_true_lang-DsN7-lkK.js";
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1 @@
1
+ "use strict";const e=require("vue"),a=require("./label-icon.vue_vue_type_style_index_0_lang-Df1Vmx77.cjs"),o=e.defineComponent({__name:"label-button",props:{preset:{},gap:{},iconClass:{type:[Boolean,null,String,Object,Array]},iconStyle:{type:[Boolean,null,String,Object,Array]},labelClass:{type:[Boolean,null,String,Object,Array]},labelStyle:{type:[Boolean,null,String,Object,Array]}},setup(s){const l=s,t=e.useSlots();return(n,c)=>(e.openBlock(),e.createElementBlock("button",null,[e.createVNode(a._sfc_main,{preset:l.preset,gap:l.gap,"icon-class":l.iconClass,"icon-style":l.iconStyle,"label-class":l.labelClass,"label-style":l.labelStyle},e.createSlots({_:2},[t.icon!=null?{name:"icon",fn:e.withCtx(()=>[e.renderSlot(n.$slots,"icon")]),key:"0"}:void 0,t.default!=null?{name:"default",fn:e.withCtx(()=>[e.renderSlot(n.$slots,"default")]),key:"1"}:void 0]),1032,["preset","gap","icon-class","icon-style","label-class","label-style"])]))}});exports._sfc_main=o;
@@ -0,0 +1,44 @@
1
+ import { defineComponent as s, useSlots as r, openBlock as c, createElementBlock as i, createVNode as p, createSlots as y, withCtx as n, renderSlot as o } from "vue";
2
+ import { _ as u } from "./label-icon.vue_vue_type_style_index_0_lang-CD5U0MIO.js";
3
+ const f = /* @__PURE__ */ s({
4
+ __name: "label-button",
5
+ props: {
6
+ preset: {},
7
+ gap: {},
8
+ iconClass: { type: [Boolean, null, String, Object, Array] },
9
+ iconStyle: { type: [Boolean, null, String, Object, Array] },
10
+ labelClass: { type: [Boolean, null, String, Object, Array] },
11
+ labelStyle: { type: [Boolean, null, String, Object, Array] }
12
+ },
13
+ setup(a) {
14
+ const e = a, l = r();
15
+ return (t, b) => (c(), i("button", null, [
16
+ p(u, {
17
+ preset: e.preset,
18
+ gap: e.gap,
19
+ "icon-class": e.iconClass,
20
+ "icon-style": e.iconStyle,
21
+ "label-class": e.labelClass,
22
+ "label-style": e.labelStyle
23
+ }, y({ _: 2 }, [
24
+ l.icon != null ? {
25
+ name: "icon",
26
+ fn: n(() => [
27
+ o(t.$slots, "icon")
28
+ ]),
29
+ key: "0"
30
+ } : void 0,
31
+ l.default != null ? {
32
+ name: "default",
33
+ fn: n(() => [
34
+ o(t.$slots, "default")
35
+ ]),
36
+ key: "1"
37
+ } : void 0
38
+ ]), 1032, ["preset", "gap", "icon-class", "icon-style", "label-class", "label-style"])
39
+ ]));
40
+ }
41
+ });
42
+ export {
43
+ f as _
44
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./label-icon.vue_vue_type_style_index_0_lang-Df1Vmx77.cjs");exports.default=e._sfc_main;
@@ -0,0 +1,30 @@
1
+ import { ClassValue, StyleValue } from 'vue';
2
+ import { LabelPreset } from './types/label-preset';
3
+ interface Props {
4
+ /** アイコンとラベルの組み合わせ */
5
+ preset?: LabelPreset;
6
+ /** アイコンとラベルの間隔。未指定なら既定値(0.25em) */
7
+ gap?: string;
8
+ /** presetのアイコンに付けるclass。スロットで渡したアイコンには、スロット側で直接指定する */
9
+ iconClass?: ClassValue;
10
+ /** presetのアイコンに付けるstyle。スロットで渡したアイコンには、スロット側で直接指定する */
11
+ iconStyle?: StyleValue;
12
+ /** ラベルに付けるclass */
13
+ labelClass?: ClassValue;
14
+ /** ラベルに付けるstyle */
15
+ labelStyle?: StyleValue;
16
+ }
17
+ interface Slots {
18
+ icon?(): unknown;
19
+ default?(): unknown;
20
+ }
21
+ type __VLS_Slots = Slots;
22
+ declare const __VLS_base: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
23
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
24
+ declare const _default: typeof __VLS_export;
25
+ export default _default;
26
+ type __VLS_WithSlots<T, S> = T & {
27
+ new (): {
28
+ $slots: S;
29
+ };
30
+ };
@@ -0,0 +1,4 @@
1
+ import { _ as f } from "./label-icon.vue_vue_type_style_index_0_lang-CD5U0MIO.js";
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1,38 @@
1
+ import { defineComponent as c, useSlots as i, openBlock as l, createElementBlock as s, normalizeStyle as n, renderSlot as o, createBlock as y, resolveDynamicComponent as u, mergeProps as b, createCommentVNode as a, normalizeClass as m, createTextVNode as S, toDisplayString as g } from "vue";
2
+ const f = /* @__PURE__ */ c({
3
+ __name: "label-icon",
4
+ props: {
5
+ preset: {},
6
+ gap: {},
7
+ iconClass: { type: [Boolean, null, String, Object, Array] },
8
+ iconStyle: { type: [Boolean, null, String, Object, Array] },
9
+ labelClass: { type: [Boolean, null, String, Object, Array] },
10
+ labelStyle: { type: [Boolean, null, String, Object, Array] }
11
+ },
12
+ setup(r) {
13
+ const e = r, p = i();
14
+ return (t, d) => (l(), s("span", {
15
+ class: "dwui-label-icon",
16
+ style: n(e.gap == null ? void 0 : { gap: e.gap })
17
+ }, [
18
+ o(t.$slots, "icon", {}, () => [
19
+ e.preset != null ? (l(), y(u(e.preset.icon), b({ key: 0 }, e.preset.iconProps, {
20
+ class: e.iconClass,
21
+ style: e.iconStyle
22
+ }), null, 16, ["class", "style"])) : a("", !0)
23
+ ]),
24
+ p.default != null || e.preset != null ? (l(), s("span", {
25
+ key: 0,
26
+ class: m(e.labelClass),
27
+ style: n(e.labelStyle)
28
+ }, [
29
+ o(t.$slots, "default", {}, () => [
30
+ S(g(typeof e.preset?.label == "function" ? e.preset.label() : e.preset?.label), 1)
31
+ ])
32
+ ], 6)) : a("", !0)
33
+ ], 4));
34
+ }
35
+ });
36
+ export {
37
+ f as _
38
+ };
@@ -0,0 +1 @@
1
+ "use strict";const e=require("vue"),s=e.defineComponent({__name:"label-icon",props:{preset:{},gap:{},iconClass:{type:[Boolean,null,String,Object,Array]},iconStyle:{type:[Boolean,null,String,Object,Array]},labelClass:{type:[Boolean,null,String,Object,Array]},labelStyle:{type:[Boolean,null,String,Object,Array]}},setup(n){const l=n,o=e.useSlots();return(t,a)=>(e.openBlock(),e.createElementBlock("span",{class:"dwui-label-icon",style:e.normalizeStyle(l.gap==null?void 0:{gap:l.gap})},[e.renderSlot(t.$slots,"icon",{},()=>[l.preset!=null?(e.openBlock(),e.createBlock(e.resolveDynamicComponent(l.preset.icon),e.mergeProps({key:0},l.preset.iconProps,{class:l.iconClass,style:l.iconStyle}),null,16,["class","style"])):e.createCommentVNode("",!0)]),o.default!=null||l.preset!=null?(e.openBlock(),e.createElementBlock("span",{key:0,class:e.normalizeClass(l.labelClass),style:e.normalizeStyle(l.labelStyle)},[e.renderSlot(t.$slots,"default",{},()=>[e.createTextVNode(e.toDisplayString(typeof l.preset?.label=="function"?l.preset.label():l.preset?.label),1)])],6)):e.createCommentVNode("",!0)],4))}});exports._sfc_main=s;
package/lib/nuxt.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("@nuxt/kit"),r=require("./components-1J1mbyrx.cjs");var t=typeof document<"u"?document.currentScript:null;const u=e.defineNuxtModule({meta:{name:"@digitalwalletcorp/vue-core",configKey:"vueCore"},setup(){const n=e.createResolver(typeof document>"u"?require("url").pathToFileURL(__filename).href:t&&t.tagName.toUpperCase()==="SCRIPT"&&t.src||new URL("nuxt.cjs",document.baseURI).href);for(const o of Object.keys(r.components))e.addComponent({name:o,export:o,filePath:n.resolve("./index")})}});exports.default=u;
package/lib/nuxt.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * コンポーネントをNuxtのコンポーネント自動importへ登録するモジュール。
3
+ * グローバル登録(registerComponents)と違い、テンプレートで使ったコンポーネントだけがバンドルされ、
4
+ * 型は Nuxt が .nuxt/components.d.ts へ生成するため、利用側に型定義は要らない。
5
+ *
6
+ * 名前の一覧を得るためだけに ./components をimportしている。
7
+ * このモジュールはビルド時にNuxtが読み込むもので、アプリの実行時バンドルには入らない
8
+ */
9
+ declare const _default: import('@nuxt/schema').NuxtModule<import('@nuxt/schema').ModuleOptions, import('@nuxt/schema').ModuleOptions, false>;
10
+ export default _default;
package/lib/nuxt.js ADDED
@@ -0,0 +1,16 @@
1
+ import { defineNuxtModule as t, createResolver as r, addComponent as n } from "@nuxt/kit";
2
+ import { c as a } from "./components-eEXuNeht.js";
3
+ const c = t({
4
+ meta: {
5
+ name: "@digitalwalletcorp/vue-core",
6
+ configKey: "vueCore"
7
+ },
8
+ setup() {
9
+ const o = r(import.meta.url);
10
+ for (const e of Object.keys(a))
11
+ n({ name: e, export: e, filePath: o.resolve("./index") });
12
+ }
13
+ });
14
+ export {
15
+ c as default
16
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./components-1J1mbyrx.cjs");function r(e){for(const[o,n]of Object.entries(t.components))e.component(o,n)}exports.registerComponents=r;
@@ -0,0 +1,9 @@
1
+ import { App } from 'vue';
2
+ import * as components from './components';
3
+ type VueCoreComponents = typeof components;
4
+ declare module 'vue' {
5
+ interface GlobalComponents extends VueCoreComponents {
6
+ }
7
+ }
8
+ export declare function registerComponents(app: App): void;
9
+ export {};
@@ -0,0 +1,8 @@
1
+ import { c as t } from "./components-eEXuNeht.js";
2
+ function m(o) {
3
+ for (const [n, e] of Object.entries(t))
4
+ o.component(n, e);
5
+ }
6
+ export {
7
+ m as registerComponents
8
+ };
package/lib/style.css ADDED
@@ -0,0 +1 @@
1
+ :where(.dwui-label-icon){display:inline-flex;align-items:center;gap:.25em}
@@ -0,0 +1,12 @@
1
+ import { Component } from 'vue';
2
+ /**
3
+ * アイコンとラベルの組み合わせ
4
+ */
5
+ export interface LabelPreset {
6
+ /** アイコンのコンポーネント */
7
+ icon: Component;
8
+ /** アイコンに渡すProps */
9
+ iconProps?: Record<string, unknown>;
10
+ /** ラベル。言語切替に追従させる場合は、描画のたびに呼ばれる関数で渡す */
11
+ label: string | (() => string);
12
+ }
package/package.json ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "@digitalwalletcorp/vue-core",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Basic UI components for Vue 3",
6
+ "main": "lib/index.cjs",
7
+ "module": "lib/index.js",
8
+ "types": "lib/index.d.ts",
9
+ "sideEffects": [
10
+ "**/*.css"
11
+ ],
12
+ "exports": {
13
+ ".": {
14
+ "types": "./lib/index.d.ts",
15
+ "import": "./lib/index.js",
16
+ "require": "./lib/index.cjs"
17
+ },
18
+ "./nuxt": {
19
+ "types": "./lib/nuxt.d.ts",
20
+ "import": "./lib/nuxt.js"
21
+ },
22
+ "./register": {
23
+ "types": "./lib/register.d.ts",
24
+ "import": "./lib/register.js",
25
+ "require": "./lib/register.cjs"
26
+ },
27
+ "./global": {
28
+ "types": "./lib/global.d.ts"
29
+ },
30
+ "./style.css": "./lib/style.css",
31
+ "./*": {
32
+ "types": "./lib/*.d.ts",
33
+ "import": "./lib/*.js",
34
+ "require": "./lib/*.cjs"
35
+ }
36
+ },
37
+ "scripts": {
38
+ "build": "vite build",
39
+ "install:dev": "rm -rf lib dest && find node_modules -mindepth 1 -delete && yarn install",
40
+ "typecheck": "vue-tsc --noEmit -p tsconfig.json",
41
+ "version:patch": "npm version patch",
42
+ "version:minor": "npm version minor",
43
+ "version:major": "npm version major",
44
+ "prepack": "rm -rf lib && npm run build",
45
+ "pack": "rm -rf dest && mkdir -p dest && npm pack --pack-destination=dest",
46
+ "publish:npm": "bash ../bin/publish.sh",
47
+ "test:unit": "vitest run --coverage"
48
+ },
49
+ "keywords": [
50
+ "vue",
51
+ "vue3",
52
+ "nuxt",
53
+ "components",
54
+ "ui"
55
+ ],
56
+ "author": "satoshi kotaki",
57
+ "license": "MIT",
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "git+https://github.com/digitalwalletcorp/vue-core.git"
61
+ },
62
+ "homepage": "https://github.com/digitalwalletcorp/vue-core",
63
+ "bugs": {
64
+ "url": "https://github.com/digitalwalletcorp/vue-core/issues"
65
+ },
66
+ "files": [
67
+ "lib/**/*",
68
+ "src/**/*"
69
+ ],
70
+ "peerDependencies": {
71
+ "vue": "^3.5.29"
72
+ },
73
+ "devDependencies": {
74
+ "@nuxt/kit": "^3.17.5",
75
+ "@types/node": "24.13.6",
76
+ "@vitejs/plugin-vue": "^6.0.0",
77
+ "@vitest/coverage-v8": "3.2.4",
78
+ "@vue/test-utils": "2.4.6",
79
+ "happy-dom": "20.14.5",
80
+ "nuxt": "^3.17.5",
81
+ "typescript": "6.0.3",
82
+ "vite": "^7.0.0",
83
+ "vite-plugin-dts": "5.1.0",
84
+ "vite-tsconfig-paths": "6.1.1",
85
+ "vitest": "3.2.4",
86
+ "vue": "^3.5.29",
87
+ "vue-tsc": "3.1.5"
88
+ }
89
+ }
@@ -0,0 +1,3 @@
1
+ // 公開するコンポーネントをここに列挙する。index/register/nuxtはここから読む
2
+ export { default as LabelButton } from '@/label-button.vue';
3
+ export { default as LabelIcon } from '@/label-icon.vue';
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from '@/components';
2
+ export type { LabelPreset } from '@/types/label-preset';
@@ -0,0 +1,57 @@
1
+ <!--
2
+ アイコンとラベルを持つボタン
3
+ -->
4
+ <template>
5
+ <button>
6
+ <LabelIcon
7
+ :preset="props.preset"
8
+ :gap="props.gap"
9
+ :icon-class="props.iconClass"
10
+ :icon-style="props.iconStyle"
11
+ :label-class="props.labelClass"
12
+ :label-style="props.labelStyle"
13
+ >
14
+ <!-- 渡されたスロットだけを中継する。空のスロットを渡すとpresetの内容が表示されなくなるため -->
15
+ <template
16
+ v-if="slots.icon != null"
17
+ #icon
18
+ >
19
+ <slot name="icon" />
20
+ </template>
21
+ <template
22
+ v-if="slots.default != null"
23
+ #default
24
+ >
25
+ <slot />
26
+ </template>
27
+ </LabelIcon>
28
+ </button>
29
+ </template>
30
+
31
+ <script setup lang="ts">
32
+ import type { ClassValue, StyleValue } from 'vue';
33
+ import LabelIcon from '@/label-icon.vue';
34
+ import type { LabelPreset } from '@/types/label-preset';
35
+
36
+ interface Props {
37
+ /** アイコンとラベルの組み合わせ */
38
+ preset?: LabelPreset;
39
+ /** アイコンとラベルの間隔。未指定ならLabelIconの既定値(0.25em) */
40
+ gap?: string;
41
+ /** presetのアイコンに付けるclass。スロットで渡したアイコンには、スロット側で直接指定する */
42
+ iconClass?: ClassValue;
43
+ /** presetのアイコンに付けるstyle。スロットで渡したアイコンには、スロット側で直接指定する */
44
+ iconStyle?: StyleValue;
45
+ /** ラベルに付けるclass */
46
+ labelClass?: ClassValue;
47
+ /** ラベルに付けるstyle */
48
+ labelStyle?: StyleValue;
49
+ }
50
+ const props = defineProps<Props>();
51
+
52
+ interface Slots {
53
+ icon?(): unknown;
54
+ default?(): unknown;
55
+ }
56
+ const slots = defineSlots<Slots>();
57
+ </script>
@@ -0,0 +1,62 @@
1
+ <!--
2
+ アイコンとラベルを横に並べる
3
+ -->
4
+ <template>
5
+ <span
6
+ class="dwui-label-icon"
7
+ :style="props.gap == null ? undefined : { gap: props.gap }"
8
+ >
9
+ <slot name="icon">
10
+ <component
11
+ :is="props.preset.icon"
12
+ v-if="props.preset != null"
13
+ v-bind="props.preset.iconProps"
14
+ :class="props.iconClass"
15
+ :style="props.iconStyle"
16
+ />
17
+ </slot>
18
+ <!-- スロットに複数の要素が入っても、flexの子要素に分かれて間にgapが入らないよう1つにまとめる -->
19
+ <span
20
+ v-if="slots.default != null || props.preset != null"
21
+ :class="props.labelClass"
22
+ :style="props.labelStyle"
23
+ >
24
+ <slot>{{ typeof props.preset?.label === 'function' ? props.preset.label() : props.preset?.label }}</slot>
25
+ </span>
26
+ </span>
27
+ </template>
28
+
29
+ <script setup lang="ts">
30
+ import type { ClassValue, StyleValue } from 'vue';
31
+ import type { LabelPreset } from '@/types/label-preset';
32
+
33
+ interface Props {
34
+ /** アイコンとラベルの組み合わせ */
35
+ preset?: LabelPreset;
36
+ /** アイコンとラベルの間隔。未指定なら既定値(0.25em) */
37
+ gap?: string;
38
+ /** presetのアイコンに付けるclass。スロットで渡したアイコンには、スロット側で直接指定する */
39
+ iconClass?: ClassValue;
40
+ /** presetのアイコンに付けるstyle。スロットで渡したアイコンには、スロット側で直接指定する */
41
+ iconStyle?: StyleValue;
42
+ /** ラベルに付けるclass */
43
+ labelClass?: ClassValue;
44
+ /** ラベルに付けるstyle */
45
+ labelStyle?: StyleValue;
46
+ }
47
+ const props = defineProps<Props>();
48
+
49
+ interface Slots {
50
+ icon?(): unknown;
51
+ default?(): unknown;
52
+ }
53
+ const slots = defineSlots<Slots>();
54
+ </script>
55
+
56
+ <style>
57
+ :where(.dwui-label-icon) {
58
+ display: inline-flex;
59
+ align-items: center;
60
+ gap: 0.25em;
61
+ }
62
+ </style>
package/src/nuxt.ts ADDED
@@ -0,0 +1,23 @@
1
+ import { addComponent, createResolver, defineNuxtModule } from '@nuxt/kit';
2
+ import * as components from '@/components';
3
+
4
+ /**
5
+ * コンポーネントをNuxtのコンポーネント自動importへ登録するモジュール。
6
+ * グローバル登録(registerComponents)と違い、テンプレートで使ったコンポーネントだけがバンドルされ、
7
+ * 型は Nuxt が .nuxt/components.d.ts へ生成するため、利用側に型定義は要らない。
8
+ *
9
+ * 名前の一覧を得るためだけに ./components をimportしている。
10
+ * このモジュールはビルド時にNuxtが読み込むもので、アプリの実行時バンドルには入らない
11
+ */
12
+ export default defineNuxtModule({
13
+ meta: {
14
+ name: '@digitalwalletcorp/vue-core',
15
+ configKey: 'vueCore'
16
+ },
17
+ setup() {
18
+ const resolver = createResolver(import.meta.url);
19
+ for (const name of Object.keys(components)) {
20
+ addComponent({ name, export: name, filePath: resolver.resolve('./index') });
21
+ }
22
+ }
23
+ });
@@ -0,0 +1,14 @@
1
+ import type { App, Component } from 'vue';
2
+ import * as components from '@/components';
3
+
4
+ type VueCoreComponents = typeof components;
5
+
6
+ declare module 'vue' {
7
+ interface GlobalComponents extends VueCoreComponents {}
8
+ }
9
+
10
+ export function registerComponents(app: App) {
11
+ for (const [name, component] of Object.entries<Component>(components)) {
12
+ app.component(name, component);
13
+ }
14
+ }
@@ -0,0 +1,7 @@
1
+ type VueCoreComponents = typeof import('../components');
2
+
3
+ declare module 'vue' {
4
+ interface GlobalComponents extends VueCoreComponents {}
5
+ }
6
+
7
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { Component } from 'vue';
2
+
3
+ /**
4
+ * アイコンとラベルの組み合わせ
5
+ */
6
+ export interface LabelPreset {
7
+ /** アイコンのコンポーネント */
8
+ icon: Component;
9
+ /** アイコンに渡すProps */
10
+ iconProps?: Record<string, unknown>;
11
+ /** ラベル。言語切替に追従させる場合は、描画のたびに呼ばれる関数で渡す */
12
+ label: string | (() => string);
13
+ }