@digitalwalletcorp/vue-core 1.2.0 → 1.3.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 +95 -8
- package/lib/accordion-fieldset.d.cts +14 -4
- package/lib/accordion-fieldset.d.ts +14 -4
- package/lib/accordion-section.d.cts +20 -10
- package/lib/accordion-section.d.ts +20 -10
- package/lib/components-2zQ2SZuY.js +26 -0
- package/lib/components-HaiHcseF.cjs +1 -0
- package/lib/components.d.cts +10 -0
- package/lib/components.d.ts +10 -0
- package/lib/copy-button.d.cts +34 -0
- package/lib/copy-button.d.ts +34 -0
- package/lib/dark-mode-selector.d.cts +32 -0
- package/lib/dark-mode-selector.d.ts +32 -0
- package/lib/data-table.d.cts +30 -0
- package/lib/data-table.d.ts +30 -0
- package/lib/help-button.d.cts +39 -0
- package/lib/help-button.d.ts +39 -0
- package/lib/help-popper.d.cts +39 -0
- package/lib/help-popper.d.ts +39 -0
- package/lib/helpers/data-table-csv.d.cts +17 -0
- package/lib/helpers/data-table-csv.d.ts +17 -0
- package/lib/helpers/show-floating-component.d.cts +82 -0
- package/lib/helpers/show-floating-component.d.ts +82 -0
- package/lib/helpers/show-modal-dialog.d.cts +73 -0
- package/lib/helpers/show-modal-dialog.d.ts +73 -0
- package/lib/helpers/show-overlay-box.d.cts +53 -0
- package/lib/helpers/show-overlay-box.d.ts +53 -0
- package/lib/helpers/show-screen-loading.d.cts +20 -0
- package/lib/helpers/show-screen-loading.d.ts +20 -0
- package/lib/helpers/show-snackbar.d.cts +47 -0
- package/lib/helpers/show-snackbar.d.ts +47 -0
- package/lib/hourglass-loading.d.cts +1 -1
- package/lib/hourglass-loading.d.ts +1 -1
- package/lib/index.cjs +1 -1
- package/lib/index.d.cts +34 -0
- package/lib/index.d.ts +34 -0
- package/lib/index.js +445 -18
- package/lib/internal/anchored-popover.d.cts +35 -0
- package/lib/internal/anchored-popover.d.ts +35 -0
- package/lib/internal/anchored-position.d.cts +50 -0
- package/lib/internal/anchored-position.d.ts +50 -0
- package/lib/internal/data-table-controls.d.cts +42 -0
- package/lib/internal/data-table-controls.d.ts +42 -0
- package/lib/internal/data-table-value.d.cts +32 -0
- package/lib/internal/data-table-value.d.ts +32 -0
- package/lib/internal/floating-component.d.cts +52 -0
- package/lib/internal/floating-component.d.ts +52 -0
- package/lib/internal/icon-popper.d.cts +32 -0
- package/lib/internal/icon-popper.d.ts +32 -0
- package/lib/internal/mount-window.d.cts +39 -0
- package/lib/internal/mount-window.d.ts +39 -0
- package/lib/internal/movable-window.d.cts +55 -0
- package/lib/internal/movable-window.d.ts +55 -0
- package/lib/internal/opened-overlay-boxes.d.cts +2 -0
- package/lib/internal/opened-overlay-boxes.d.ts +2 -0
- package/lib/internal/pagination.d.cts +22 -0
- package/lib/internal/pagination.d.ts +22 -0
- package/lib/internal/snackbar-container.d.cts +20 -0
- package/lib/internal/snackbar-container.d.ts +20 -0
- package/lib/internal/snackbar-item.d.cts +17 -0
- package/lib/internal/snackbar-item.d.ts +17 -0
- package/lib/internal/tab-group-context.d.cts +4 -2
- package/lib/internal/tab-group-context.d.ts +4 -2
- package/lib/internal/use-movable-window.d.cts +44 -0
- package/lib/internal/use-movable-window.d.ts +44 -0
- package/lib/internal/window-order.d.cts +6 -0
- package/lib/internal/window-order.d.ts +6 -0
- package/lib/intersection-lazy-component.d.cts +32 -0
- package/lib/intersection-lazy-component.d.ts +32 -0
- package/lib/label-button.d.cts +2 -2
- package/lib/label-button.d.ts +2 -2
- package/lib/label-icon.d.cts +2 -2
- package/lib/label-icon.d.ts +2 -2
- package/lib/modal-dialog.d.cts +67 -0
- package/lib/modal-dialog.d.ts +67 -0
- package/lib/nuxt.cjs +1 -1
- package/lib/nuxt.js +1 -1
- package/lib/overlay-box.d.cts +52 -0
- package/lib/overlay-box.d.ts +52 -0
- package/lib/page-section.d.cts +2 -2
- package/lib/page-section.d.ts +2 -2
- package/lib/page-title.d.cts +2 -2
- package/lib/page-title.d.ts +2 -2
- package/lib/register.cjs +1 -1
- package/lib/register.js +1 -1
- package/lib/screen-loading.d.cts +7 -0
- package/lib/screen-loading.d.ts +7 -0
- package/lib/style.css +1 -1
- package/lib/tab-content.d.cts +5 -5
- package/lib/tab-content.d.ts +5 -5
- package/lib/tab-group.d.cts +7 -10
- package/lib/tab-group.d.ts +7 -10
- package/lib/types/data-table.d.cts +185 -0
- package/lib/types/data-table.d.ts +185 -0
- package/lib/types/modal-dialog.d.cts +13 -0
- package/lib/types/modal-dialog.d.ts +13 -0
- package/lib/types/movable-window.d.cts +16 -0
- package/lib/types/movable-window.d.ts +16 -0
- package/lib/warning-popper.d.cts +39 -0
- package/lib/warning-popper.d.ts +39 -0
- package/lib/warning-popper.vue_vue_type_style_index_0_lang-CxVzqsbn.cjs +1 -0
- package/lib/warning-popper.vue_vue_type_style_index_0_lang-zt-jCsvz.js +1833 -0
- package/package.json +43 -16
- package/src/accordion-fieldset.vue +29 -19
- package/src/accordion-section.vue +41 -26
- package/src/components.ts +10 -0
- package/src/copy-button.vue +89 -0
- package/src/dark-mode-selector.vue +212 -0
- package/src/data-table.vue +643 -0
- package/src/help-button.vue +128 -0
- package/src/help-popper.vue +70 -0
- package/src/helpers/data-table-csv.ts +55 -0
- package/src/helpers/show-floating-component.ts +169 -0
- package/src/helpers/show-modal-dialog.ts +121 -0
- package/src/helpers/show-overlay-box.ts +106 -0
- package/src/helpers/show-screen-loading.ts +37 -0
- package/src/helpers/show-snackbar.ts +153 -0
- package/src/hourglass-loading.vue +1 -1
- package/src/index.ts +34 -0
- package/src/internal/anchored-popover.vue +192 -0
- package/src/internal/anchored-position.ts +135 -0
- package/src/internal/data-table-controls.vue +203 -0
- package/src/internal/data-table-value.ts +99 -0
- package/src/internal/floating-component.vue +202 -0
- package/src/internal/icon-popper.vue +185 -0
- package/src/internal/mount-window.ts +110 -0
- package/src/internal/movable-window.vue +315 -0
- package/src/internal/opened-overlay-boxes.ts +2 -0
- package/src/internal/pagination.vue +325 -0
- package/src/internal/snackbar-container.vue +258 -0
- package/src/internal/snackbar-item.ts +20 -0
- package/src/internal/tab-group-context.ts +4 -2
- package/src/internal/use-movable-window.ts +208 -0
- package/src/internal/window-order.ts +11 -0
- package/src/intersection-lazy-component.vue +84 -0
- package/src/label-button.vue +37 -3
- package/src/label-icon.vue +2 -2
- package/src/modal-dialog.vue +287 -0
- package/src/overlay-box.vue +218 -0
- package/src/page-section.vue +7 -7
- package/src/page-title.vue +5 -5
- package/src/screen-loading.vue +90 -0
- package/src/tab-content.vue +17 -16
- package/src/tab-group.vue +55 -46
- package/src/types/data-table.ts +196 -0
- package/src/types/modal-dialog.ts +16 -0
- package/src/types/movable-window.ts +18 -0
- package/src/warning-popper.vue +70 -0
- package/lib/accordion-fieldset.cjs +0 -1
- package/lib/accordion-fieldset.js +0 -4
- package/lib/accordion-fieldset.vue_vue_type_style_index_0_lang-n-IZxUiu.js +0 -66
- package/lib/accordion-fieldset.vue_vue_type_style_index_0_lang-t9NqmoZW.cjs +0 -1
- package/lib/accordion-section.cjs +0 -1
- package/lib/accordion-section.js +0 -4
- package/lib/accordion-section.vue_vue_type_style_index_0_lang-CFDdUEnn.cjs +0 -1
- package/lib/accordion-section.vue_vue_type_style_index_0_lang-Gvjjx02P.js +0 -78
- package/lib/components-CNOeuZPu.cjs +0 -1
- package/lib/components-DBK8NUBh.js +0 -24
- package/lib/hourglass-loading.cjs +0 -1
- package/lib/hourglass-loading.js +0 -4
- package/lib/hourglass-loading.vue_vue_type_style_index_0_lang-C72UVA9W.cjs +0 -1
- package/lib/hourglass-loading.vue_vue_type_style_index_0_lang-DkUGIxQ2.js +0 -22
- package/lib/label-button.cjs +0 -1
- package/lib/label-button.js +0 -4
- package/lib/label-button.vue_vue_type_script_setup_true_lang-BwVOxaJP.cjs +0 -1
- package/lib/label-button.vue_vue_type_script_setup_true_lang-DorC4pKz.js +0 -44
- package/lib/label-icon.cjs +0 -1
- package/lib/label-icon.js +0 -4
- package/lib/label-icon.vue_vue_type_style_index_0_lang-D9Cimu20.cjs +0 -1
- package/lib/label-icon.vue_vue_type_style_index_0_lang-me52HE2V.js +0 -38
- package/lib/page-section.cjs +0 -1
- package/lib/page-section.js +0 -4
- package/lib/page-section.vue_vue_type_style_index_0_lang-DEAkTLxd.cjs +0 -1
- package/lib/page-section.vue_vue_type_style_index_0_lang-DpVQe_rV.js +0 -54
- package/lib/page-title.cjs +0 -1
- package/lib/page-title.js +0 -4
- package/lib/page-title.vue_vue_type_style_index_0_lang-BqIsIks5.cjs +0 -1
- package/lib/page-title.vue_vue_type_style_index_0_lang-ChZot85K.js +0 -36
- package/lib/tab-content.cjs +0 -1
- package/lib/tab-content.js +0 -4
- package/lib/tab-content.vue_vue_type_style_index_0_lang-BeCi7Xkp.cjs +0 -1
- package/lib/tab-content.vue_vue_type_style_index_0_lang-CcQLHmIF.js +0 -44
- package/lib/tab-group.cjs +0 -1
- package/lib/tab-group.js +0 -4
- package/lib/tab-group.vue_vue_type_style_index_0_lang-C84mDEOC.js +0 -103
- package/lib/tab-group.vue_vue_type_style_index_0_lang-CMaufRJV.cjs +0 -1
- package/lib/use-shrinkable-CS2bmsJJ.js +0 -17
- package/lib/use-shrinkable-Cu9JQZll.cjs +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitalwalletcorp/vue-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Basic UI components for Vue 3",
|
|
6
6
|
"main": "lib/index.cjs",
|
|
@@ -37,22 +37,15 @@
|
|
|
37
37
|
"./global": {
|
|
38
38
|
"types": "./lib/global.d.ts"
|
|
39
39
|
},
|
|
40
|
-
"./style.css": "./lib/style.css"
|
|
41
|
-
"./*": {
|
|
42
|
-
"import": {
|
|
43
|
-
"types": "./lib/*.d.ts",
|
|
44
|
-
"default": "./lib/*.js"
|
|
45
|
-
},
|
|
46
|
-
"require": {
|
|
47
|
-
"types": "./lib/*.d.cts",
|
|
48
|
-
"default": "./lib/*.cjs"
|
|
49
|
-
}
|
|
50
|
-
}
|
|
40
|
+
"./style.css": "./lib/style.css"
|
|
51
41
|
},
|
|
52
42
|
"scripts": {
|
|
53
43
|
"build": "vite build",
|
|
44
|
+
"yarn:dedupe": "npx yarn-deduplicate --strategy highest yarn.lock",
|
|
54
45
|
"install:dev": "rm -rf lib dest && find node_modules -mindepth 1 -delete && yarn install",
|
|
55
|
-
"
|
|
46
|
+
"tsc": "vue-tsc --noEmit -p tsconfig.json",
|
|
47
|
+
"lint": "eslint . && stylelint \"src/**/*.vue\" \"src/**/*.css\"",
|
|
48
|
+
"lint:fix": "eslint --fix . && stylelint --fix \"**/*.vue\" \"**/*.css\"",
|
|
56
49
|
"version:patch": "npm version patch",
|
|
57
50
|
"version:minor": "npm version minor",
|
|
58
51
|
"version:major": "npm version major",
|
|
@@ -68,7 +61,7 @@
|
|
|
68
61
|
"components",
|
|
69
62
|
"ui"
|
|
70
63
|
],
|
|
71
|
-
"author": "
|
|
64
|
+
"author": "Digital Wallet Corporation",
|
|
72
65
|
"license": "MIT",
|
|
73
66
|
"repository": {
|
|
74
67
|
"type": "git",
|
|
@@ -83,24 +76,58 @@
|
|
|
83
76
|
"src/**/*"
|
|
84
77
|
],
|
|
85
78
|
"peerDependencies": {
|
|
86
|
-
"@digitalwalletcorp/vue-svg-icons": "^1.
|
|
79
|
+
"@digitalwalletcorp/vue-svg-icons": "^1.15.3",
|
|
80
|
+
"@nuxt/kit": "^3.17.5",
|
|
87
81
|
"vue": "^3.5.29"
|
|
88
82
|
},
|
|
83
|
+
"peerDependenciesMeta": {
|
|
84
|
+
"@nuxt/kit": {
|
|
85
|
+
"optional": true
|
|
86
|
+
}
|
|
87
|
+
},
|
|
89
88
|
"devDependencies": {
|
|
90
|
-
"@digitalwalletcorp/vue-svg-icons": "^1.
|
|
89
|
+
"@digitalwalletcorp/vue-svg-icons": "^1.15.3",
|
|
91
90
|
"@nuxt/kit": "^3.17.5",
|
|
91
|
+
"@stylistic/eslint-plugin": "5.10.0",
|
|
92
|
+
"@stylistic/stylelint-plugin": "5.3.1",
|
|
92
93
|
"@types/node": "24.13.6",
|
|
93
94
|
"@vitejs/plugin-vue": "^6.0.0",
|
|
94
95
|
"@vitest/coverage-v8": "3.2.4",
|
|
96
|
+
"@vue/compiler-core": "3.5.43",
|
|
95
97
|
"@vue/test-utils": "2.4.6",
|
|
98
|
+
"eslint": "10.11.0",
|
|
99
|
+
"eslint-plugin-vue": "10.11.1",
|
|
100
|
+
"globals": "17.13.0",
|
|
96
101
|
"happy-dom": "20.14.5",
|
|
97
102
|
"nuxt": "^3.17.5",
|
|
103
|
+
"postcss-html": "2.0.0",
|
|
104
|
+
"stylelint": "17.16.0",
|
|
105
|
+
"stylelint-config-recommended-vue": "2.0.0",
|
|
106
|
+
"stylelint-config-standard": "40.0.0",
|
|
98
107
|
"typescript": "6.0.3",
|
|
108
|
+
"typescript-eslint": "8.71.0",
|
|
99
109
|
"vite": "^7.0.0",
|
|
100
110
|
"vite-plugin-dts": "5.1.0",
|
|
101
111
|
"vite-tsconfig-paths": "6.1.1",
|
|
102
112
|
"vitest": "3.2.4",
|
|
103
113
|
"vue": "^3.5.29",
|
|
114
|
+
"vue-eslint-parser": "10.4.1",
|
|
104
115
|
"vue-tsc": "3.1.5"
|
|
116
|
+
},
|
|
117
|
+
"resolutions": {
|
|
118
|
+
"eslint": "10.11.0",
|
|
119
|
+
"eslint-plugin-vue": "10.11.1",
|
|
120
|
+
"typescript-eslint": "8.71.0",
|
|
121
|
+
"@stylistic/eslint-plugin": "5.10.0",
|
|
122
|
+
"globals": "17.13.0",
|
|
123
|
+
"vue-eslint-parser": "10.4.1",
|
|
124
|
+
"stylelint": "17.16.0",
|
|
125
|
+
"@stylistic/stylelint-plugin": "5.3.1",
|
|
126
|
+
"stylelint-config-standard": "40.0.0",
|
|
127
|
+
"stylelint-config-recommended-vue": "2.0.0",
|
|
128
|
+
"stylelint-config-recommended": "18.0.0",
|
|
129
|
+
"stylelint-config-html": "2.0.0",
|
|
130
|
+
"postcss-html": "2.0.0",
|
|
131
|
+
"postcss": "8.5.28"
|
|
105
132
|
}
|
|
106
133
|
}
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
class="dwui-accordion-fieldset"
|
|
7
7
|
:disabled="props.disabled"
|
|
8
8
|
>
|
|
9
|
-
<legend>
|
|
9
|
+
<legend class="dwui-accordion-legend">
|
|
10
10
|
<button
|
|
11
11
|
type="button"
|
|
12
12
|
class="dwui-accordion-toggle"
|
|
13
|
-
:aria-expanded="
|
|
13
|
+
:aria-expanded="expanded"
|
|
14
14
|
@click="onClickToggle"
|
|
15
15
|
>
|
|
16
|
-
<SvgTriangleButton :direction="
|
|
16
|
+
<SvgTriangleButton :direction="expanded ? 'up' : 'down'" />
|
|
17
17
|
<LabelIcon v-if="props.legend != null || slots.legend != null || slots.icon != null">
|
|
18
18
|
<!-- 渡されたスロットだけを中継する。空のラベルを渡すとアイコンの後ろに間隔が空くため -->
|
|
19
19
|
<template
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
</legend>
|
|
34
34
|
<div
|
|
35
35
|
ref="refContents"
|
|
36
|
-
:class="[ 'dwui-accordion-contents', shrinkable ?
|
|
36
|
+
:class="[ 'dwui-accordion-contents', shrinkable ? expanded ? 'dwui-expanded' : 'dwui-shrunk' : '' ]"
|
|
37
37
|
>
|
|
38
38
|
<slot />
|
|
39
39
|
</div>
|
|
@@ -41,22 +41,22 @@
|
|
|
41
41
|
</template>
|
|
42
42
|
|
|
43
43
|
<script setup lang="ts">
|
|
44
|
-
import {
|
|
44
|
+
import { computed, ref } from 'vue';
|
|
45
45
|
import { SvgTriangleButton } from '@digitalwalletcorp/vue-svg-icons';
|
|
46
46
|
import LabelIcon from '@/label-icon.vue';
|
|
47
47
|
import { useShrinkable } from '@/internal/use-shrinkable';
|
|
48
48
|
|
|
49
|
-
interface Props {
|
|
49
|
+
export interface Props {
|
|
50
50
|
/** 凡例の文字。HTMLを含める場合は#legendスロットを使う */
|
|
51
51
|
legend?: string;
|
|
52
52
|
/** trueの場合、fieldsetを無効にする */
|
|
53
53
|
disabled?: boolean;
|
|
54
|
-
/** trueの場合、開いた状態で表示する デフォルト false */
|
|
54
|
+
/** trueの場合、開いた状態で表示する デフォルト false。v-model:expanded で束縛しないときの初期値 */
|
|
55
55
|
initialExpand?: boolean;
|
|
56
56
|
}
|
|
57
57
|
const props = defineProps<Props>();
|
|
58
58
|
|
|
59
|
-
interface Slots {
|
|
59
|
+
export interface Slots {
|
|
60
60
|
/** 凡例の文字の前に表示するアイコン */
|
|
61
61
|
icon?(): unknown;
|
|
62
62
|
/** 凡例。legendより優先する */
|
|
@@ -66,18 +66,23 @@ interface Slots {
|
|
|
66
66
|
const slots = defineSlots<Slots>();
|
|
67
67
|
|
|
68
68
|
const refContents = ref<HTMLElement>();
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
// 真偽値の prop は未指定だと false に変換されるため、未指定を undefined のまま受けるよう既定値を明示する
|
|
70
|
+
/** 親が v-model:expanded で束縛したときの開閉状態。束縛しなければ undefined */
|
|
71
|
+
const model = defineModel<boolean | undefined>('expanded', { default: undefined });
|
|
72
|
+
/** 束縛しないときの開閉状態 */
|
|
73
|
+
const localExpanded = ref(!!props.initialExpand);
|
|
74
|
+
const expanded = computed({
|
|
75
|
+
get: (): boolean => model.value ?? localExpanded.value,
|
|
76
|
+
set: (value: boolean): void => {
|
|
77
|
+
localExpanded.value = value;
|
|
78
|
+
model.value = value;
|
|
79
|
+
}
|
|
71
80
|
});
|
|
72
81
|
const shrinkable = useShrinkable(refContents);
|
|
73
82
|
|
|
74
83
|
const onClickToggle = () => {
|
|
75
|
-
|
|
84
|
+
expanded.value = !expanded.value;
|
|
76
85
|
};
|
|
77
|
-
|
|
78
|
-
onMounted(() => {
|
|
79
|
-
pageContext.expanded = !!props.initialExpand;
|
|
80
|
-
});
|
|
81
86
|
</script>
|
|
82
87
|
|
|
83
88
|
<style>
|
|
@@ -85,12 +90,12 @@ onMounted(() => {
|
|
|
85
90
|
position: relative;
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
/*
|
|
93
|
+
/* 開閉ボタンは押しボタンではなく凡例と一体の操作として見せるため、既定では枠・背景を持たない */
|
|
89
94
|
:where(.dwui-accordion-toggle) {
|
|
90
95
|
display: inline-flex;
|
|
91
96
|
align-items: center;
|
|
92
|
-
gap:
|
|
93
|
-
margin-left:
|
|
97
|
+
gap: 0.33em;
|
|
98
|
+
margin-left: 0.33em;
|
|
94
99
|
padding: 0;
|
|
95
100
|
border: none;
|
|
96
101
|
background: none;
|
|
@@ -103,10 +108,15 @@ onMounted(() => {
|
|
|
103
108
|
cursor: not-allowed;
|
|
104
109
|
}
|
|
105
110
|
|
|
111
|
+
:where(.dwui-accordion-toggle:focus-visible) {
|
|
112
|
+
outline: var(--dwui-outline-width-focus-ring, 2px) solid var(--dwui-outline-color-focus-ring, Highlight);
|
|
113
|
+
outline-offset: var(--dwui-outline-offset-focus-ring, 2px);
|
|
114
|
+
}
|
|
115
|
+
|
|
106
116
|
:where(.dwui-accordion-contents) {
|
|
107
117
|
position: relative;
|
|
108
118
|
width: fit-content;
|
|
109
|
-
padding:
|
|
119
|
+
padding: 0.17em;
|
|
110
120
|
overflow: hidden;
|
|
111
121
|
opacity: 1;
|
|
112
122
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
ref="refContents"
|
|
8
8
|
class="dwui-accordion-section-contents"
|
|
9
9
|
:class="[
|
|
10
|
-
shrinkable ?
|
|
10
|
+
shrinkable ? expanded ? 'dwui-expanded' : 'dwui-shrunk' : '',
|
|
11
11
|
{ 'dwui-no-gradient': props.noGradient }
|
|
12
12
|
]"
|
|
13
13
|
>
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
type="button"
|
|
22
22
|
class="dwui-accordion-section-toggle"
|
|
23
23
|
:disabled="props.disabled"
|
|
24
|
-
:aria-expanded="
|
|
24
|
+
:aria-expanded="expanded"
|
|
25
25
|
@click.stop="onClickToggle"
|
|
26
26
|
>
|
|
27
27
|
<LabelIcon v-if="toggleIcon() != null || toggleLabel != null">
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
</LabelIcon>
|
|
44
44
|
<SvgTriangleButton
|
|
45
45
|
v-else
|
|
46
|
-
:direction="
|
|
46
|
+
:direction="expanded ? 'up' : 'down'"
|
|
47
47
|
/>
|
|
48
48
|
</button>
|
|
49
49
|
</div>
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
</template>
|
|
52
52
|
|
|
53
53
|
<script setup lang="ts">
|
|
54
|
-
import { computed,
|
|
54
|
+
import { computed, ref } from 'vue';
|
|
55
55
|
import type { Component, Slot } from 'vue';
|
|
56
56
|
import { SvgTriangleButton } from '@digitalwalletcorp/vue-svg-icons';
|
|
57
57
|
import LabelIcon from '@/label-icon.vue';
|
|
@@ -60,40 +60,49 @@ import type { LabelPreset } from '@/types/label-preset';
|
|
|
60
60
|
|
|
61
61
|
// 開閉ボタンのアイコンとラベルは別々に決める。どちらも、スロット/ラベルの指定 > プリセット の順で使う
|
|
62
62
|
// 何も指定が無い場合だけ、既定の三角を表示する
|
|
63
|
-
interface Props {
|
|
63
|
+
export interface Props {
|
|
64
64
|
/** trueの場合、開閉ボタンを無効にする */
|
|
65
65
|
disabled?: boolean;
|
|
66
|
-
/** trueの場合、開いた状態で表示する デフォルト false */
|
|
66
|
+
/** trueの場合、開いた状態で表示する デフォルト false。v-model:expanded で束縛しないときの初期値 */
|
|
67
67
|
initialExpand?: boolean;
|
|
68
68
|
/** trueの場合、縮めたときに中身の下側をぼかさない */
|
|
69
69
|
noGradient?: boolean;
|
|
70
70
|
/** 縮めているときの開閉ボタン(開く)のラベル */
|
|
71
|
-
|
|
71
|
+
expandLabel?: string;
|
|
72
72
|
/** 開いているときの開閉ボタン(閉じる)のラベル */
|
|
73
|
-
|
|
73
|
+
collapseLabel?: string;
|
|
74
74
|
/** 縮めているときの開閉ボタン(開く)のアイコンとラベル */
|
|
75
|
-
|
|
75
|
+
expandPreset?: LabelPreset;
|
|
76
76
|
/** 開いているときの開閉ボタン(閉じる)のアイコンとラベル */
|
|
77
|
-
|
|
77
|
+
collapsePreset?: LabelPreset;
|
|
78
78
|
}
|
|
79
79
|
const props = defineProps<Props>();
|
|
80
80
|
|
|
81
|
-
interface Slots {
|
|
81
|
+
export interface Slots {
|
|
82
82
|
/** 縮めているときの開閉ボタン(開く)のアイコン */
|
|
83
|
-
'
|
|
83
|
+
'expand-icon'?(): unknown;
|
|
84
84
|
/** 開いているときの開閉ボタン(閉じる)のアイコン */
|
|
85
|
-
'
|
|
85
|
+
'collapse-icon'?(): unknown;
|
|
86
86
|
default?(): unknown;
|
|
87
87
|
}
|
|
88
88
|
const slots = defineSlots<Slots>();
|
|
89
89
|
|
|
90
90
|
const refContents = ref<HTMLElement>();
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
// 真偽値の prop は未指定だと false に変換されるため、未指定を undefined のまま受けるよう既定値を明示する
|
|
92
|
+
/** 親が v-model:expanded で束縛したときの開閉状態。束縛しなければ undefined */
|
|
93
|
+
const model = defineModel<boolean | undefined>('expanded', { default: undefined });
|
|
94
|
+
/** 束縛しないときの開閉状態 */
|
|
95
|
+
const localExpanded = ref(!!props.initialExpand);
|
|
96
|
+
const expanded = computed({
|
|
97
|
+
get: (): boolean => model.value ?? localExpanded.value,
|
|
98
|
+
set: (value: boolean): void => {
|
|
99
|
+
localExpanded.value = value;
|
|
100
|
+
model.value = value;
|
|
101
|
+
}
|
|
93
102
|
});
|
|
94
103
|
const shrinkable = useShrinkable(refContents);
|
|
95
104
|
|
|
96
|
-
const togglePreset = computed((): LabelPreset | undefined =>
|
|
105
|
+
const togglePreset = computed((): LabelPreset | undefined => expanded.value ? props.collapsePreset : props.expandPreset);
|
|
97
106
|
|
|
98
107
|
/**
|
|
99
108
|
* 開閉ボタンに表示するアイコン。スロットは関数のままコンポーネントとして描画する
|
|
@@ -102,7 +111,7 @@ const togglePreset = computed((): LabelPreset | undefined => pageContext.expande
|
|
|
102
111
|
* @returns {Slot | Component | undefined}
|
|
103
112
|
*/
|
|
104
113
|
const toggleIcon = (): Slot | Component | undefined => {
|
|
105
|
-
const slot =
|
|
114
|
+
const slot = expanded.value ? slots['collapse-icon'] : slots['expand-icon'];
|
|
106
115
|
return (slot as Slot | undefined) ?? togglePreset.value?.icon;
|
|
107
116
|
};
|
|
108
117
|
|
|
@@ -112,12 +121,12 @@ const toggleIcon = (): Slot | Component | undefined => {
|
|
|
112
121
|
* @returns {Record<string, unknown> | undefined}
|
|
113
122
|
*/
|
|
114
123
|
const toggleIconProps = (): Record<string, unknown> | undefined => {
|
|
115
|
-
const slot =
|
|
124
|
+
const slot = expanded.value ? slots['collapse-icon'] : slots['expand-icon'];
|
|
116
125
|
return slot == null ? togglePreset.value?.iconProps : undefined;
|
|
117
126
|
};
|
|
118
127
|
|
|
119
128
|
const toggleLabel = computed((): string | undefined => {
|
|
120
|
-
const label =
|
|
129
|
+
const label = expanded.value ? props.collapseLabel : props.expandLabel;
|
|
121
130
|
if (label != null) {
|
|
122
131
|
return label;
|
|
123
132
|
}
|
|
@@ -126,12 +135,8 @@ const toggleLabel = computed((): string | undefined => {
|
|
|
126
135
|
});
|
|
127
136
|
|
|
128
137
|
const onClickToggle = () => {
|
|
129
|
-
|
|
138
|
+
expanded.value = !expanded.value;
|
|
130
139
|
};
|
|
131
|
-
|
|
132
|
-
onMounted(() => {
|
|
133
|
-
pageContext.expanded = !!props.initialExpand;
|
|
134
|
-
});
|
|
135
140
|
</script>
|
|
136
141
|
|
|
137
142
|
<style>
|
|
@@ -172,9 +177,14 @@ onMounted(() => {
|
|
|
172
177
|
width: 100%;
|
|
173
178
|
}
|
|
174
179
|
|
|
180
|
+
/* 開閉ボタンは押しボタンではなくアイコンとラベルの操作として見せるため、既定では枠・背景を持たない */
|
|
175
181
|
:where(.dwui-accordion-section-toggle) {
|
|
176
182
|
display: inline-flex;
|
|
177
183
|
align-items: center;
|
|
184
|
+
padding: 0;
|
|
185
|
+
border: none;
|
|
186
|
+
background: none;
|
|
187
|
+
color: inherit;
|
|
178
188
|
cursor: pointer;
|
|
179
189
|
}
|
|
180
190
|
|
|
@@ -183,12 +193,17 @@ onMounted(() => {
|
|
|
183
193
|
cursor: not-allowed;
|
|
184
194
|
}
|
|
185
195
|
|
|
196
|
+
:where(.dwui-accordion-section-toggle:focus-visible) {
|
|
197
|
+
outline: var(--dwui-outline-width-focus-ring, 2px) solid var(--dwui-outline-color-focus-ring, Highlight);
|
|
198
|
+
outline-offset: var(--dwui-outline-offset-focus-ring, 2px);
|
|
199
|
+
}
|
|
200
|
+
|
|
186
201
|
:where(.dwui-accordion-section-toggle[aria-expanded='true']) {
|
|
187
|
-
margin-top:
|
|
202
|
+
margin-top: 0.67em;
|
|
188
203
|
}
|
|
189
204
|
|
|
190
205
|
/* 縮めたときはボタンを中身のぼかしに少し重ね、中身とボタンの間を詰める */
|
|
191
206
|
:where(.dwui-accordion-section-toggle[aria-expanded='false']) {
|
|
192
|
-
margin-top: -
|
|
207
|
+
margin-top: -0.83em;
|
|
193
208
|
}
|
|
194
209
|
</style>
|
package/src/components.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
// 公開するコンポーネントをここに列挙する。index/register/nuxtはここから読む
|
|
2
2
|
export { default as AccordionFieldset } from '@/accordion-fieldset.vue';
|
|
3
3
|
export { default as AccordionSection } from '@/accordion-section.vue';
|
|
4
|
+
export { default as CopyButton } from '@/copy-button.vue';
|
|
5
|
+
export { default as DarkModeSelector } from '@/dark-mode-selector.vue';
|
|
6
|
+
export { default as DataTable } from '@/data-table.vue';
|
|
7
|
+
export { default as HelpButton } from '@/help-button.vue';
|
|
8
|
+
export { default as HelpPopper } from '@/help-popper.vue';
|
|
4
9
|
export { default as HourglassLoading } from '@/hourglass-loading.vue';
|
|
10
|
+
export { default as IntersectionLazyComponent } from '@/intersection-lazy-component.vue';
|
|
5
11
|
export { default as LabelButton } from '@/label-button.vue';
|
|
6
12
|
export { default as LabelIcon } from '@/label-icon.vue';
|
|
13
|
+
export { default as ModalDialog } from '@/modal-dialog.vue';
|
|
14
|
+
export { default as OverlayBox } from '@/overlay-box.vue';
|
|
7
15
|
export { default as PageSection } from '@/page-section.vue';
|
|
8
16
|
export { default as PageTitle } from '@/page-title.vue';
|
|
17
|
+
export { default as ScreenLoading } from '@/screen-loading.vue';
|
|
9
18
|
export { default as TabContent } from '@/tab-content.vue';
|
|
10
19
|
export { default as TabGroup } from '@/tab-group.vue';
|
|
20
|
+
export { default as WarningPopper } from '@/warning-popper.vue';
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
値をクリップボードにコピーするボタン
|
|
3
|
+
-->
|
|
4
|
+
<template>
|
|
5
|
+
<button
|
|
6
|
+
type="button"
|
|
7
|
+
class="dwui-copy-button"
|
|
8
|
+
:aria-label="slots.default ? undefined : props.label"
|
|
9
|
+
@click="onClickCopy"
|
|
10
|
+
>
|
|
11
|
+
<slot>
|
|
12
|
+
<SvgMemo />
|
|
13
|
+
</slot>
|
|
14
|
+
</button>
|
|
15
|
+
</template>
|
|
16
|
+
|
|
17
|
+
<script setup lang="ts">
|
|
18
|
+
import { SvgMemo } from '@digitalwalletcorp/vue-svg-icons';
|
|
19
|
+
|
|
20
|
+
export interface Props {
|
|
21
|
+
/** コピーする値。関数を渡すとクリック時に呼び出して値を得る */
|
|
22
|
+
value: string | number | (() => string | number);
|
|
23
|
+
/** ボタンの読み上げ名。スロットで文字を渡したときは使わない */
|
|
24
|
+
label?: string;
|
|
25
|
+
}
|
|
26
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
27
|
+
label: 'Copy'
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export interface Emits {
|
|
31
|
+
/** コピーに成功したときに、コピーした文字列を発行する */
|
|
32
|
+
(e: 'emit:copy', value: string): void;
|
|
33
|
+
/** コピーに失敗したときに、原因のエラーを発行する */
|
|
34
|
+
(e: 'emit:error', error: unknown): void;
|
|
35
|
+
}
|
|
36
|
+
const emit = defineEmits<Emits>();
|
|
37
|
+
|
|
38
|
+
export interface Slots {
|
|
39
|
+
/** ボタンの中身。未指定ならメモのアイコン */
|
|
40
|
+
default?(): unknown;
|
|
41
|
+
}
|
|
42
|
+
const slots = defineSlots<Slots>();
|
|
43
|
+
|
|
44
|
+
const onClickCopy = async () => {
|
|
45
|
+
const value = String(typeof props.value === 'function' ? props.value() : props.value);
|
|
46
|
+
try {
|
|
47
|
+
await navigator.clipboard.writeText(value);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
emit('emit:error', error);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
emit('emit:copy', value);
|
|
53
|
+
};
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<style>
|
|
57
|
+
:where(.dwui-copy-button) {
|
|
58
|
+
display: inline-flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
padding: 0.17em;
|
|
62
|
+
border: none;
|
|
63
|
+
border-radius: 4px;
|
|
64
|
+
background-color: transparent;
|
|
65
|
+
background-image: none;
|
|
66
|
+
color: inherit;
|
|
67
|
+
font: inherit;
|
|
68
|
+
line-height: 0;
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
:where(.dwui-copy-button:not(:disabled):hover) {
|
|
73
|
+
background: var(--dwui-background-copy-button-hover, light-dark(rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.12)));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
:where(.dwui-copy-button:not(:disabled):active) {
|
|
77
|
+
transform: translate(1px, 1px);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
:where(.dwui-copy-button:disabled) {
|
|
81
|
+
opacity: 0.4;
|
|
82
|
+
cursor: not-allowed;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
:where(.dwui-copy-button:focus-visible) {
|
|
86
|
+
outline: var(--dwui-outline-width-focus-ring, 2px) solid var(--dwui-outline-color-focus-ring, Highlight);
|
|
87
|
+
outline-offset: var(--dwui-outline-offset-focus-ring, 2px);
|
|
88
|
+
}
|
|
89
|
+
</style>
|