@ynetlabo/ui-vue 0.1.4
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 +21 -0
- package/README.md +70 -0
- package/package.json +56 -0
- package/src/index.d.ts +60 -0
- package/src/index.js +11 -0
- package/src/prefecture-picker.js +107 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yuuki.U (ynetlabo) https://ynetlabo.net
|
|
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,70 @@
|
|
|
1
|
+
# @ynetlabo/ui-vue
|
|
2
|
+
|
|
3
|
+
[ui-labo](https://github.com/yuuint/ui-labo) の Vue 3 向けラッパー。
|
|
4
|
+
[`@ynetlabo/ui-core`](https://www.npmjs.com/package/@ynetlabo/ui-core) のカスタム要素を、
|
|
5
|
+
`v-model` と型付きの props で使えるようにします。
|
|
6
|
+
|
|
7
|
+
**[デモとドキュメント](https://ui.ynetlabo.net/)**
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @ynetlabo/ui-vue
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```vue
|
|
14
|
+
<script setup>
|
|
15
|
+
import { ref } from "vue";
|
|
16
|
+
import { YnPrefecturePicker } from "@ynetlabo/ui-vue";
|
|
17
|
+
import "@ynetlabo/ui-tokens/dist/tokens.css";
|
|
18
|
+
|
|
19
|
+
const pref = ref(null);
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<YnPrefecturePicker v-model="pref" name="pref" code-format="jis" />
|
|
24
|
+
</template>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`app.use()` でまとめて登録もできます。
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import YnLaboUi from "@ynetlabo/ui-vue";
|
|
31
|
+
app.use(YnLaboUi);
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 使い勝手のためにしていること
|
|
35
|
+
|
|
36
|
+
- **`isCustomElement` の設定が要りません。** レンダー関数で書いているため、
|
|
37
|
+
テンプレートコンパイラを通りません
|
|
38
|
+
- **SSR を通せます。** 要素の登録は `onMounted` の動的 import に寄せてあるので、
|
|
39
|
+
サーバでは空の要素が出るだけです。`<client-only>` で囲む必要はありません
|
|
40
|
+
- **指定しなかった prop は既定を倒しません。** 例えば `searchable` は既定が真ですが、
|
|
41
|
+
書かなければ真のままです
|
|
42
|
+
|
|
43
|
+
## props
|
|
44
|
+
|
|
45
|
+
`modelValue`(`v-model`)のほか、core と同じ指定が使えます。
|
|
46
|
+
|
|
47
|
+
`selectionLevel` / `multiple` / `codeFormat` / `grouping` / `layout` / `display` /
|
|
48
|
+
`searchable` / `placeholder` / `disabled` / `required` / `invalid` / `name` /
|
|
49
|
+
`transition` / `mode` / `footer` / `items`
|
|
50
|
+
|
|
51
|
+
意味と取りうる値は[コンポーネントのページ](https://ui.ynetlabo.net/prefecture-picker.html)にあります。
|
|
52
|
+
|
|
53
|
+
## イベント
|
|
54
|
+
|
|
55
|
+
| | |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `update:modelValue` | 選択が変わったとき。値は `codeFormat` に従う(複数選択では配列) |
|
|
58
|
+
| `change` | 下地のカスタム要素の `CustomEvent` をそのまま渡す |
|
|
59
|
+
|
|
60
|
+
## 下地の要素に触る
|
|
61
|
+
|
|
62
|
+
```vue
|
|
63
|
+
<YnPrefecturePicker ref="picker" />
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
picker.value.element // <yn-prefecture-picker>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
MIT © Yuuki.U ([ynetlabo](https://ynetlabo.net))
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ynetlabo/ui-vue",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "ui-labo の Vue 向けラッパー。core のカスタム要素を v-model と型付きの props で使えるようにする",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "ynetlabo",
|
|
9
|
+
"url": "https://ynetlabo.net"
|
|
10
|
+
},
|
|
11
|
+
"main": "./src/index.js",
|
|
12
|
+
"types": "./src/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./src/index.d.ts",
|
|
16
|
+
"default": "./src/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"src"
|
|
21
|
+
],
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@ynetlabo/ui-core": "^0.1.4"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"vue": "^3.4.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@vue/server-renderer": "^3.5.0",
|
|
31
|
+
"vue": "^3.5.0"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"test": "node --test test/*.test.mjs"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"vue",
|
|
38
|
+
"web-components",
|
|
39
|
+
"japan",
|
|
40
|
+
"prefecture",
|
|
41
|
+
"ui-labo",
|
|
42
|
+
"ynetlabo"
|
|
43
|
+
],
|
|
44
|
+
"homepage": "https://ui.ynetlabo.net/",
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/yuuint/ui-labo/issues"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com/yuuint/ui-labo.git",
|
|
54
|
+
"directory": "packages/vue"
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { DefineComponent, Plugin } from "vue";
|
|
2
|
+
|
|
3
|
+
/** codeFormat に応じた値の表現。詳細は spec `prefecture-picker` */
|
|
4
|
+
export type PrefectureValue = string | number;
|
|
5
|
+
|
|
6
|
+
export interface YnPrefecturePickerProps {
|
|
7
|
+
/** 選択中の値。multiple のときは配列 */
|
|
8
|
+
modelValue?: PrefectureValue | PrefectureValue[] | null;
|
|
9
|
+
/** 選ぶ単位 */
|
|
10
|
+
selectionLevel?: "prefecture" | "area";
|
|
11
|
+
multiple?: boolean;
|
|
12
|
+
/** value と change の表現 */
|
|
13
|
+
codeFormat?: "jis" | "jisNumber" | "ynetlabo" | "iso" | "name" | "shortName";
|
|
14
|
+
/** 区切り。カスタム定義はオブジェクトで渡す */
|
|
15
|
+
grouping?: "region9" | "region8" | "region11" | "kana" | "none" | object;
|
|
16
|
+
layout?: "list" | "map";
|
|
17
|
+
/** トリガへ表示する表記 */
|
|
18
|
+
display?: "name" | "shortName";
|
|
19
|
+
searchable?: boolean;
|
|
20
|
+
placeholder?: string;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
required?: boolean;
|
|
23
|
+
invalid?: boolean;
|
|
24
|
+
/** フォーム送信時のフィールド名 */
|
|
25
|
+
name?: string;
|
|
26
|
+
transition?: "auto" | "fade" | "slide" | "none";
|
|
27
|
+
/** dropdown は押して開く、inline は常に表示 */
|
|
28
|
+
mode?: "dropdown" | "inline";
|
|
29
|
+
/** フッタに出す部品。"auto" | "none" か count / clear / done の並び */
|
|
30
|
+
footer?: string;
|
|
31
|
+
/** 都道府県データの差し替え */
|
|
32
|
+
items?: unknown[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface YnPrefecturePickerEmits {
|
|
36
|
+
(e: "update:modelValue", value: PrefectureValue | PrefectureValue[] | null): void;
|
|
37
|
+
(e: "change", event: CustomEvent): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface YnPrefecturePickerExposed {
|
|
41
|
+
/** 下地のカスタム要素 */
|
|
42
|
+
readonly element: HTMLElement | null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export declare const YnPrefecturePicker: DefineComponent<
|
|
46
|
+
YnPrefecturePickerProps,
|
|
47
|
+
YnPrefecturePickerExposed,
|
|
48
|
+
{},
|
|
49
|
+
{},
|
|
50
|
+
{},
|
|
51
|
+
{},
|
|
52
|
+
{},
|
|
53
|
+
YnPrefecturePickerEmits
|
|
54
|
+
>;
|
|
55
|
+
|
|
56
|
+
export declare const TAG: "yn-prefecture-picker";
|
|
57
|
+
export declare const PROP_MAP: Record<keyof YnPrefecturePickerProps, string>;
|
|
58
|
+
|
|
59
|
+
declare const plugin: Plugin;
|
|
60
|
+
export default plugin;
|
package/src/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** ui-labo の Vue 向け入口。core のカスタム要素を Vue から使えるようにする */
|
|
2
|
+
import { YnPrefecturePicker } from "./prefecture-picker.js";
|
|
3
|
+
|
|
4
|
+
export { YnPrefecturePicker, TAG, PROP_MAP } from "./prefecture-picker.js";
|
|
5
|
+
|
|
6
|
+
/** app.use() でまとめて登録したいとき */
|
|
7
|
+
export default {
|
|
8
|
+
install(app) {
|
|
9
|
+
app.component("YnPrefecturePicker", YnPrefecturePicker);
|
|
10
|
+
},
|
|
11
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <YnPrefecturePicker> — core のカスタム要素を Vue から自然に使うための薄い覆い。
|
|
3
|
+
*
|
|
4
|
+
* 振る舞いは core にしかない(ADR `vue-wraps-custom-element`)。ここでやるのは 3 つだけ。
|
|
5
|
+
* 1. v-model を仲介する
|
|
6
|
+
* 2. 値をプロパティとして入れる(属性は文字列しか運べない)
|
|
7
|
+
* 3. カスタム要素の登録をクライアントに寄せ、SSR を素通りさせる
|
|
8
|
+
*/
|
|
9
|
+
import { defineComponent, h, onBeforeUnmount, onMounted, shallowRef, watchEffect } from "vue";
|
|
10
|
+
|
|
11
|
+
export const TAG = "yn-prefecture-picker";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Vue の prop 名 → カスタム要素のプロパティ名。
|
|
15
|
+
* core の `static props` と 1 対 1 で対応する(ずれたら test が落ちる)。
|
|
16
|
+
*
|
|
17
|
+
* **並び順に意味がある。value は必ず最後。**
|
|
18
|
+
* 値の解釈は codeFormat と selectionLevel に依るので、設定より先に value を
|
|
19
|
+
* 入れると別の表現として読まれ、正しい値が捨てられる。
|
|
20
|
+
*/
|
|
21
|
+
export const PROP_MAP = {
|
|
22
|
+
selectionLevel: "selectionLevel",
|
|
23
|
+
multiple: "multiple",
|
|
24
|
+
codeFormat: "codeFormat",
|
|
25
|
+
grouping: "grouping",
|
|
26
|
+
layout: "layout",
|
|
27
|
+
display: "display",
|
|
28
|
+
searchable: "searchable",
|
|
29
|
+
placeholder: "placeholder",
|
|
30
|
+
disabled: "disabled",
|
|
31
|
+
required: "required",
|
|
32
|
+
invalid: "invalid",
|
|
33
|
+
name: "name",
|
|
34
|
+
transition: "transition",
|
|
35
|
+
mode: "mode",
|
|
36
|
+
footer: "footer",
|
|
37
|
+
items: "items",
|
|
38
|
+
modelValue: "value",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// 既定値は core が持っている。ここで false を補うと searchable のように
|
|
42
|
+
// 既定が真のものを黙って倒してしまうので、指定が無ければ undefined のままにする
|
|
43
|
+
const opt = (type) => ({ type, default: undefined });
|
|
44
|
+
|
|
45
|
+
export const YnPrefecturePicker = defineComponent({
|
|
46
|
+
name: "YnPrefecturePicker",
|
|
47
|
+
|
|
48
|
+
props: {
|
|
49
|
+
modelValue: opt([String, Number, Array]),
|
|
50
|
+
selectionLevel: opt(String),
|
|
51
|
+
multiple: opt(Boolean),
|
|
52
|
+
codeFormat: opt(String),
|
|
53
|
+
grouping: opt([String, Object]),
|
|
54
|
+
layout: opt(String),
|
|
55
|
+
display: opt(String),
|
|
56
|
+
searchable: opt(Boolean),
|
|
57
|
+
placeholder: opt(String),
|
|
58
|
+
disabled: opt(Boolean),
|
|
59
|
+
required: opt(Boolean),
|
|
60
|
+
invalid: opt(Boolean),
|
|
61
|
+
name: opt(String),
|
|
62
|
+
transition: opt(String),
|
|
63
|
+
mode: opt(String),
|
|
64
|
+
footer: opt(String),
|
|
65
|
+
items: opt(Array),
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
// ここで宣言しておくと、Vue が同名の native リスナを重ねて付けない
|
|
69
|
+
emits: ["update:modelValue", "change"],
|
|
70
|
+
|
|
71
|
+
setup(props, { emit, expose }) {
|
|
72
|
+
const el = shallowRef(null);
|
|
73
|
+
|
|
74
|
+
const onChange = (e) => {
|
|
75
|
+
emit("update:modelValue", e.detail.value);
|
|
76
|
+
emit("change", e);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// 描画の後に流す。要素が出来ていないと入れる先が無い
|
|
80
|
+
watchEffect(() => {
|
|
81
|
+
const node = el.value;
|
|
82
|
+
if (!node) return;
|
|
83
|
+
for (const [from, to] of Object.entries(PROP_MAP)) {
|
|
84
|
+
const v = props[from];
|
|
85
|
+
if (v === undefined) continue; // 指定が無いものは core の既定に任せる
|
|
86
|
+
if (node[to] !== v) node[to] = v;
|
|
87
|
+
}
|
|
88
|
+
}, { flush: "post" });
|
|
89
|
+
|
|
90
|
+
onMounted(async () => {
|
|
91
|
+
el.value?.addEventListener("change", onChange);
|
|
92
|
+
// 定義前に入れたプロパティは、昇格のときに core の基底クラスが拾い直す
|
|
93
|
+
if (!customElements.get(TAG)) await import("@ynetlabo/ui-core");
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
onBeforeUnmount(() => el.value?.removeEventListener("change", onChange));
|
|
97
|
+
|
|
98
|
+
expose({
|
|
99
|
+
/** 下地のカスタム要素。フォーム検証など core 側の API を直に触りたいとき */
|
|
100
|
+
get element() { return el.value; },
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// テンプレートを通さないので、利用側に isCustomElement の設定が要らない。
|
|
104
|
+
// サーバでは空の要素になるだけで、DOM にも触れない
|
|
105
|
+
return () => h(TAG, { ref: el });
|
|
106
|
+
},
|
|
107
|
+
});
|