@digitalwalletcorp/vue-core 1.2.1 → 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 +79 -3
- 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 +40 -14
- package/src/accordion-fieldset.vue +24 -19
- package/src/accordion-section.vue +33 -28
- 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 +9 -6
- 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 +4 -4
- package/src/screen-loading.vue +90 -0
- package/src/tab-content.vue +16 -15
- package/src/tab-group.vue +34 -36
- 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-Cf4czDXz.js +0 -66
- package/lib/accordion-fieldset.vue_vue_type_style_index_0_lang-DoM5QjpJ.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-C63HJoCn.cjs +0 -1
- package/lib/components-q4Cf97bO.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_style_index_0_lang-D7ZgfZOL.cjs +0 -1
- package/lib/label-button.vue_vue_type_style_index_0_lang-DqRYddVt.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,23 +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",
|
|
54
44
|
"yarn:dedupe": "npx yarn-deduplicate --strategy highest yarn.lock",
|
|
55
45
|
"install:dev": "rm -rf lib dest && find node_modules -mindepth 1 -delete && yarn install",
|
|
56
|
-
"
|
|
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\"",
|
|
57
49
|
"version:patch": "npm version patch",
|
|
58
50
|
"version:minor": "npm version minor",
|
|
59
51
|
"version:major": "npm version major",
|
|
@@ -69,7 +61,7 @@
|
|
|
69
61
|
"components",
|
|
70
62
|
"ui"
|
|
71
63
|
],
|
|
72
|
-
"author": "
|
|
64
|
+
"author": "Digital Wallet Corporation",
|
|
73
65
|
"license": "MIT",
|
|
74
66
|
"repository": {
|
|
75
67
|
"type": "git",
|
|
@@ -85,23 +77,57 @@
|
|
|
85
77
|
],
|
|
86
78
|
"peerDependencies": {
|
|
87
79
|
"@digitalwalletcorp/vue-svg-icons": "^1.15.3",
|
|
80
|
+
"@nuxt/kit": "^3.17.5",
|
|
88
81
|
"vue": "^3.5.29"
|
|
89
82
|
},
|
|
83
|
+
"peerDependenciesMeta": {
|
|
84
|
+
"@nuxt/kit": {
|
|
85
|
+
"optional": true
|
|
86
|
+
}
|
|
87
|
+
},
|
|
90
88
|
"devDependencies": {
|
|
91
89
|
"@digitalwalletcorp/vue-svg-icons": "^1.15.3",
|
|
92
90
|
"@nuxt/kit": "^3.17.5",
|
|
91
|
+
"@stylistic/eslint-plugin": "5.10.0",
|
|
92
|
+
"@stylistic/stylelint-plugin": "5.3.1",
|
|
93
93
|
"@types/node": "24.13.6",
|
|
94
94
|
"@vitejs/plugin-vue": "^6.0.0",
|
|
95
95
|
"@vitest/coverage-v8": "3.2.4",
|
|
96
|
+
"@vue/compiler-core": "3.5.43",
|
|
96
97
|
"@vue/test-utils": "2.4.6",
|
|
98
|
+
"eslint": "10.11.0",
|
|
99
|
+
"eslint-plugin-vue": "10.11.1",
|
|
100
|
+
"globals": "17.13.0",
|
|
97
101
|
"happy-dom": "20.14.5",
|
|
98
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",
|
|
99
107
|
"typescript": "6.0.3",
|
|
108
|
+
"typescript-eslint": "8.71.0",
|
|
100
109
|
"vite": "^7.0.0",
|
|
101
110
|
"vite-plugin-dts": "5.1.0",
|
|
102
111
|
"vite-tsconfig-paths": "6.1.1",
|
|
103
112
|
"vitest": "3.2.4",
|
|
104
113
|
"vue": "^3.5.29",
|
|
114
|
+
"vue-eslint-parser": "10.4.1",
|
|
105
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"
|
|
106
132
|
}
|
|
107
133
|
}
|
|
@@ -10,10 +10,10 @@
|
|
|
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>
|
|
@@ -89,8 +94,8 @@ onMounted(() => {
|
|
|
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;
|
|
@@ -104,14 +109,14 @@ onMounted(() => {
|
|
|
104
109
|
}
|
|
105
110
|
|
|
106
111
|
:where(.dwui-accordion-toggle:focus-visible) {
|
|
107
|
-
outline: var(--dwui-width-focus-ring, 2px) solid var(--dwui-outline-color-focus-ring, Highlight);
|
|
108
|
-
outline-offset: var(--dwui-offset-focus-ring, 2px);
|
|
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);
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
:where(.dwui-accordion-contents) {
|
|
112
117
|
position: relative;
|
|
113
118
|
width: fit-content;
|
|
114
|
-
padding:
|
|
119
|
+
padding: 0.17em;
|
|
115
120
|
overflow: hidden;
|
|
116
121
|
opacity: 1;
|
|
117
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>
|
|
@@ -189,16 +194,16 @@ onMounted(() => {
|
|
|
189
194
|
}
|
|
190
195
|
|
|
191
196
|
:where(.dwui-accordion-section-toggle:focus-visible) {
|
|
192
|
-
outline: var(--dwui-width-focus-ring, 2px) solid var(--dwui-outline-color-focus-ring, Highlight);
|
|
193
|
-
outline-offset: var(--dwui-offset-focus-ring, 2px);
|
|
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);
|
|
194
199
|
}
|
|
195
200
|
|
|
196
201
|
:where(.dwui-accordion-section-toggle[aria-expanded='true']) {
|
|
197
|
-
margin-top:
|
|
202
|
+
margin-top: 0.67em;
|
|
198
203
|
}
|
|
199
204
|
|
|
200
205
|
/* 縮めたときはボタンを中身のぼかしに少し重ね、中身とボタンの間を詰める */
|
|
201
206
|
:where(.dwui-accordion-section-toggle[aria-expanded='false']) {
|
|
202
|
-
margin-top: -
|
|
207
|
+
margin-top: -0.83em;
|
|
203
208
|
}
|
|
204
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>
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
ライトモードとダークモードを切り替えるスイッチ
|
|
3
|
+
選んだモードを <html> の class(light / dark)に反映し、localStorage に保存する。
|
|
4
|
+
保存値が無ければ OS の設定に従う。OS の設定が変わったとき、およびモードを切り替えたときは同一サイトのすべてのタブ、ウィンドウが追随する。
|
|
5
|
+
SSRではライトの状態で描画されるため、一瞬ちらつきが発生することがある。
|
|
6
|
+
これを回避するには dark-mode-selector.md に記載されている回避ロジックを実装する。
|
|
7
|
+
-->
|
|
8
|
+
<template>
|
|
9
|
+
<button
|
|
10
|
+
type="button"
|
|
11
|
+
role="switch"
|
|
12
|
+
class="dwui-dark-mode-selector"
|
|
13
|
+
:aria-label="props.label"
|
|
14
|
+
:aria-checked="isDark"
|
|
15
|
+
@click="onClickToggle"
|
|
16
|
+
>
|
|
17
|
+
<span class="dwui-dark-mode-selector-track">
|
|
18
|
+
<span class="dwui-dark-mode-selector-icon-light"><slot name="icon-light"><SvgHighBrightness /></slot></span>
|
|
19
|
+
<span class="dwui-dark-mode-selector-icon-dark"><slot name="icon-dark"><SvgMoonPhases :moon-age="3.85" /></slot></span>
|
|
20
|
+
</span>
|
|
21
|
+
<span class="dwui-dark-mode-selector-handle" />
|
|
22
|
+
</button>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script setup lang="ts">
|
|
26
|
+
import { onBeforeUnmount, onMounted, ref } from 'vue';
|
|
27
|
+
import { SvgHighBrightness, SvgMoonPhases } from '@digitalwalletcorp/vue-svg-icons';
|
|
28
|
+
|
|
29
|
+
type ColorScheme = 'light' | 'dark';
|
|
30
|
+
|
|
31
|
+
export interface Props {
|
|
32
|
+
/** 選んだモードを保存する localStorage のキー */
|
|
33
|
+
storageKey?: string;
|
|
34
|
+
/** スイッチの読み上げ名 */
|
|
35
|
+
label?: string;
|
|
36
|
+
}
|
|
37
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
38
|
+
storageKey: 'dwui-color-scheme',
|
|
39
|
+
label: 'Dark mode'
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export interface Emits {
|
|
43
|
+
/** マウント時に決まったモードと、その後モードが変わるたびに、新しいモードを発行する */
|
|
44
|
+
(e: 'emit:change', value: ColorScheme): void;
|
|
45
|
+
}
|
|
46
|
+
const emit = defineEmits<Emits>();
|
|
47
|
+
|
|
48
|
+
export interface Slots {
|
|
49
|
+
'icon-light'?(): unknown;
|
|
50
|
+
'icon-dark'?(): unknown;
|
|
51
|
+
}
|
|
52
|
+
defineSlots<Slots>();
|
|
53
|
+
|
|
54
|
+
const isDark = ref<boolean>(false);
|
|
55
|
+
|
|
56
|
+
let applied: ColorScheme | null = null;
|
|
57
|
+
let mediaQuery: MediaQueryList | null = null;
|
|
58
|
+
|
|
59
|
+
const isColorScheme = (value: unknown): value is ColorScheme => value === 'light' || value === 'dark';
|
|
60
|
+
|
|
61
|
+
/** OS の設定から得られるモード */
|
|
62
|
+
const osScheme = (): ColorScheme => mediaQuery?.matches ? 'dark' : 'light';
|
|
63
|
+
|
|
64
|
+
/** 保存されているモード。無い場合や localStorage が使えない場合は null */
|
|
65
|
+
const storedScheme = (): ColorScheme | null => {
|
|
66
|
+
try {
|
|
67
|
+
const value = localStorage.getItem(props.storageKey);
|
|
68
|
+
return isColorScheme(value) ? value : null;
|
|
69
|
+
} catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/** モードを <html> の class に反映する。変わったときだけ change を発行する */
|
|
75
|
+
const applyScheme = (scheme: ColorScheme): void => {
|
|
76
|
+
const classList = document.documentElement.classList;
|
|
77
|
+
classList.remove(scheme === 'dark' ? 'light' : 'dark');
|
|
78
|
+
classList.add(scheme);
|
|
79
|
+
isDark.value = scheme === 'dark';
|
|
80
|
+
if (applied !== scheme) {
|
|
81
|
+
applied = scheme;
|
|
82
|
+
emit('emit:change', scheme);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/** モードを保存して反映する */
|
|
87
|
+
const selectScheme = (scheme: ColorScheme): void => {
|
|
88
|
+
try {
|
|
89
|
+
localStorage.setItem(props.storageKey, scheme);
|
|
90
|
+
} catch {
|
|
91
|
+
// 保存できなくても表示の切り替えは行う
|
|
92
|
+
}
|
|
93
|
+
applyScheme(scheme);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const onClickToggle = (): void => {
|
|
97
|
+
selectScheme(isDark.value ? 'light' : 'dark');
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const onChangeOsScheme = (event: MediaQueryListEvent): void => {
|
|
101
|
+
selectScheme(event.matches ? 'dark' : 'light');
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// 別のタブで切り替えたとき。保存値が消されたときは OS の設定に戻る
|
|
105
|
+
const onStorage = (event: StorageEvent): void => {
|
|
106
|
+
if (event.key !== props.storageKey) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
applyScheme(isColorScheme(event.newValue) ? event.newValue : osScheme());
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
onMounted(() => {
|
|
113
|
+
mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
114
|
+
applyScheme(storedScheme() ?? osScheme());
|
|
115
|
+
mediaQuery.addEventListener('change', onChangeOsScheme);
|
|
116
|
+
window.addEventListener('storage', onStorage);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
onBeforeUnmount(() => {
|
|
120
|
+
mediaQuery?.removeEventListener('change', onChangeOsScheme);
|
|
121
|
+
window.removeEventListener('storage', onStorage);
|
|
122
|
+
});
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<style>
|
|
126
|
+
:where(.dwui-dark-mode-selector) {
|
|
127
|
+
position: relative;
|
|
128
|
+
display: inline-block;
|
|
129
|
+
vertical-align: top;
|
|
130
|
+
width: 3.85em;
|
|
131
|
+
height: 1.65em;
|
|
132
|
+
padding: 0;
|
|
133
|
+
border: none;
|
|
134
|
+
border-radius: 0.85em;
|
|
135
|
+
background-color: transparent;
|
|
136
|
+
background-image: none;
|
|
137
|
+
color: inherit;
|
|
138
|
+
font: inherit;
|
|
139
|
+
line-height: 0;
|
|
140
|
+
cursor: pointer;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
:where(.dwui-dark-mode-selector-track) {
|
|
144
|
+
position: relative;
|
|
145
|
+
display: block;
|
|
146
|
+
height: inherit;
|
|
147
|
+
border-radius: inherit;
|
|
148
|
+
background: var(--dwui-background-dark-mode-selector, azure);
|
|
149
|
+
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.15);
|
|
150
|
+
font-size: 0.85em;
|
|
151
|
+
transition: background 0.15s ease-out;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
:where(.dwui-dark-mode-selector[aria-checked='true'] > .dwui-dark-mode-selector-track) {
|
|
155
|
+
background: var(--dwui-background-dark-mode-selector-checked, darkslategray);
|
|
156
|
+
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15), inset 0 0 3px rgba(0, 0, 0, 0.2);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
:where(.dwui-dark-mode-selector-icon-light, .dwui-dark-mode-selector-icon-dark) {
|
|
160
|
+
position: absolute;
|
|
161
|
+
top: 50%;
|
|
162
|
+
transform: translateY(-50%);
|
|
163
|
+
display: inline-flex;
|
|
164
|
+
align-items: center;
|
|
165
|
+
line-height: 1;
|
|
166
|
+
transition: opacity 0.15s ease-out;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
:where(.dwui-dark-mode-selector-icon-light) {
|
|
170
|
+
right: 0.6em;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
:where(.dwui-dark-mode-selector-icon-dark) {
|
|
174
|
+
left: 0.6em;
|
|
175
|
+
opacity: 0;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
:where(.dwui-dark-mode-selector[aria-checked='true'] .dwui-dark-mode-selector-icon-light) {
|
|
179
|
+
opacity: 0;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
:where(.dwui-dark-mode-selector[aria-checked='true'] .dwui-dark-mode-selector-icon-dark) {
|
|
183
|
+
opacity: 1;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
:where(.dwui-dark-mode-selector-handle) {
|
|
187
|
+
position: absolute;
|
|
188
|
+
top: 0.075em;
|
|
189
|
+
left: 0;
|
|
190
|
+
width: 1.5em;
|
|
191
|
+
height: 1.5em;
|
|
192
|
+
border-radius: 0.75em;
|
|
193
|
+
background: var(--dwui-background-dark-mode-selector-handle, linear-gradient(0.25turn, #888484 0%, #b4abab 50%, #888484 100%));
|
|
194
|
+
box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
|
|
195
|
+
transition: left 0.15s ease-out;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
:where(.dwui-dark-mode-selector[aria-checked='true'] > .dwui-dark-mode-selector-handle) {
|
|
199
|
+
left: calc(3.85em - 1.5em - 0.075em);
|
|
200
|
+
box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.2);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
:where(.dwui-dark-mode-selector:disabled) {
|
|
204
|
+
opacity: 0.5;
|
|
205
|
+
cursor: not-allowed;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
:where(.dwui-dark-mode-selector:focus-visible) {
|
|
209
|
+
outline: var(--dwui-outline-width-focus-ring, 2px) solid var(--dwui-outline-color-focus-ring, Highlight);
|
|
210
|
+
outline-offset: var(--dwui-outline-offset-focus-ring, 2px);
|
|
211
|
+
}
|
|
212
|
+
</style>
|