@vyr/design 0.0.1

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.
Files changed (83) hide show
  1. package/package.json +16 -0
  2. package/src/components/Button.vue +64 -0
  3. package/src/components/Card.vue +203 -0
  4. package/src/components/Cascader.vue +171 -0
  5. package/src/components/Checked.vue +124 -0
  6. package/src/components/CheckedGroup.vue +51 -0
  7. package/src/components/Col.vue +52 -0
  8. package/src/components/ColorPicker.vue +331 -0
  9. package/src/components/Confirm.vue +86 -0
  10. package/src/components/Dialog.vue +220 -0
  11. package/src/components/Divider.vue +40 -0
  12. package/src/components/Draggable.vue +50 -0
  13. package/src/components/Dropdown.vue +175 -0
  14. package/src/components/DynamicDialog.vue +113 -0
  15. package/src/components/DynamicLayouter.vue +235 -0
  16. package/src/components/Form.vue +88 -0
  17. package/src/components/Input.vue +254 -0
  18. package/src/components/InputNumber.vue +96 -0
  19. package/src/components/Label.vue +116 -0
  20. package/src/components/Loading.vue +196 -0
  21. package/src/components/Mask.vue +47 -0
  22. package/src/components/Notify.vue +130 -0
  23. package/src/components/Option.vue +159 -0
  24. package/src/components/Options.vue +202 -0
  25. package/src/components/Popover.vue +271 -0
  26. package/src/components/Provider.vue +12 -0
  27. package/src/components/RightMenu.vue +127 -0
  28. package/src/components/Row.vue +50 -0
  29. package/src/components/Scroll.vue +99 -0
  30. package/src/components/Select.vue +223 -0
  31. package/src/components/Slot.vue +23 -0
  32. package/src/components/SubTree.vue +262 -0
  33. package/src/components/Tree.vue +129 -0
  34. package/src/components/common/DraggableController.ts +113 -0
  35. package/src/components/common/ResizeListener.ts +49 -0
  36. package/src/components/composables/useDefaultProps.ts +179 -0
  37. package/src/components/composables/useDraggable.ts +65 -0
  38. package/src/components/composables/useGetter.ts +15 -0
  39. package/src/components/composables/useMarginStyle.ts +45 -0
  40. package/src/components/composables/usePopover.ts +33 -0
  41. package/src/components/composables/useProvider.ts +186 -0
  42. package/src/components/composables/useScroll.ts +46 -0
  43. package/src/components/composables/useSearch.ts +97 -0
  44. package/src/components/composables/useTimer.ts +5 -0
  45. package/src/components/index.ts +1 -0
  46. package/src/components/singleton/confirm.ts +25 -0
  47. package/src/components/singleton/dialog.ts +25 -0
  48. package/src/components/singleton/index.ts +5 -0
  49. package/src/components/singleton/loading.ts +36 -0
  50. package/src/components/singleton/notify.ts +36 -0
  51. package/src/components/types/index.ts +82 -0
  52. package/src/components/utils/Cascader.ts +52 -0
  53. package/src/components/utils/Confirm.ts +41 -0
  54. package/src/components/utils/Dialog.ts +38 -0
  55. package/src/components/utils/DynamicDialog.ts +41 -0
  56. package/src/components/utils/DynamicLayouter.ts +5 -0
  57. package/src/components/utils/FloatLayer.ts +40 -0
  58. package/src/components/utils/InputNumber.ts +3 -0
  59. package/src/components/utils/Notify.ts +25 -0
  60. package/src/components/utils/Popover.ts +58 -0
  61. package/src/components/utils/RightMenu.ts +21 -0
  62. package/src/components/utils/Scroll.ts +4 -0
  63. package/src/components/utils/Slot.ts +73 -0
  64. package/src/components/utils/index.ts +12 -0
  65. package/src/font/demo.css +539 -0
  66. package/src/font/demo_index.html +1292 -0
  67. package/src/font/iconfont.css +207 -0
  68. package/src/font/iconfont.js +1 -0
  69. package/src/font/iconfont.json +345 -0
  70. package/src/font/iconfont.ttf +0 -0
  71. package/src/font/iconfont.woff +0 -0
  72. package/src/font/iconfont.woff2 +0 -0
  73. package/src/index.ts +68 -0
  74. package/src/locale/Language.ts +10 -0
  75. package/src/locale/LanguageProvider.ts +38 -0
  76. package/src/locale/index.ts +2 -0
  77. package/src/theme/global.less +91 -0
  78. package/src/theme/index.ts +155 -0
  79. package/src/tool/ArrayUtils.ts +38 -0
  80. package/src/tool/Color.ts +7 -0
  81. package/src/tool/Draggable.ts +36 -0
  82. package/src/tool/Listener.ts +59 -0
  83. package/src/tool/index.ts +4 -0
@@ -0,0 +1,331 @@
1
+ <template>
2
+ <vyr-popover popover-class="color-picker-popover" trigger="click" :disabled="curReadonly">
3
+ <template #trigger>
4
+ <div class="vyr-color-picker" :class="[width]" v-bind="$attrs">
5
+ <div class="vyr-picker-border">
6
+ <div class="color-value" :style="state.color ? `background:${state.color};` : ``"></div>
7
+ </div>
8
+ </div>
9
+ </template>
10
+ <div class="color-picker">
11
+ <div class="picker-wrapper" :style="`width:${state.width}px;`">
12
+ <div class="picker-panel" :class="{ 'active': state.panel.started }"
13
+ :style="`height:${state.height}px;background:hsl(${state.hue.value},100%,50%);`"
14
+ @mousedown.prevent="changePanel">
15
+ <div class="picker-panel-white"></div>
16
+ <div class="picker-panel-black"></div>
17
+ <div class="picker-cursor" :style="`top:${state.panel.top}px;left:${state.panel.left}px;`"
18
+ @mousedown="startPanel"></div>
19
+ </div>
20
+ <div class="picker-bar" :class="{ 'active': state.hue.started }" @mousedown.prevent="changeHue">
21
+ <div class="picker-hue" :style="`left:${state.hue.left}px;`" @mousedown="startHue">
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </vyr-popover>
27
+ </template>
28
+
29
+ <script lang="ts" setup>
30
+ import { computed, onBeforeUnmount, ref, watch } from 'vue'
31
+ import { useProvider } from './composables/useProvider';
32
+ import { Color } from '../tool';
33
+ import VyrPopover from './Popover.vue'
34
+
35
+ defineOptions({
36
+ inheritAttrs: false
37
+ })
38
+
39
+ const props = defineProps({
40
+ modelValue: { default: '' },
41
+ readonly: { default: null as boolean | null },
42
+ width: { default: 'auto' },
43
+ opacity: { default: false },
44
+ })
45
+ const provider = useProvider()
46
+ const curReadonly = computed(() => props.readonly === null ? provider.value.readonly : props.readonly)
47
+ const emit = defineEmits(['update:modelValue'])
48
+ const state = ref({
49
+ color: '',
50
+ event: new MouseEvent(''),
51
+ width: 280,
52
+ height: 180,
53
+ panel: {
54
+ top: 0,
55
+ left: 0,
56
+ saturation: 0,
57
+ value: 0,
58
+ started: false,
59
+ xStart: 0,
60
+ xEnd: 0,
61
+ yStart: 0,
62
+ yEnd: 0,
63
+ },
64
+ hue: {
65
+ left: 0,
66
+ value: 0,
67
+ started: false,
68
+ start: 0,
69
+ end: 0,
70
+ },
71
+ opacity: 1,
72
+ next: false,
73
+ })
74
+
75
+ const watchModelValue = () => {
76
+ if (!props.modelValue || props.modelValue === state.value.color) return
77
+ state.value.color = props.modelValue
78
+
79
+ const hsv = new Color(props.modelValue).toHsv()
80
+ state.value.hue.left = Math.round((hsv.h / 360) * state.value.width)
81
+ state.value.hue.value = hsv.h
82
+
83
+ state.value.panel.saturation = hsv.s
84
+ state.value.panel.left = Math.round((hsv.s) * state.value.width)
85
+
86
+ state.value.panel.value = hsv.v
87
+ state.value.panel.top = Math.round((1 - hsv.v) * state.value.height)
88
+ }
89
+ watch(() => props.modelValue, watchModelValue, { immediate: true })
90
+
91
+ const update = () => {
92
+ const hex = new Color({ h: state.value.hue.value, s: state.value.panel.saturation, v: state.value.panel.value }).toHexString()
93
+ state.value.color = hex
94
+ emit('update:modelValue', hex)
95
+ }
96
+
97
+ const changePanel = (e: MouseEvent) => {
98
+ if (curReadonly.value === true) return
99
+ startPanel(e)
100
+ movePanel(e)
101
+ }
102
+ const startPanel = (e: MouseEvent) => {
103
+ if (curReadonly.value === true) return
104
+
105
+ state.value.hue.started = false
106
+ state.value.panel.started = true
107
+ const target = (e.target as HTMLElement).parentElement
108
+ const rect = target?.getBoundingClientRect() as DOMRect
109
+ state.value.panel.xStart = rect.left
110
+ state.value.panel.xEnd = rect.right
111
+ state.value.panel.yStart = rect.top
112
+ state.value.panel.yEnd = rect.bottom
113
+ }
114
+ const movePanel = (e: MouseEvent) => {
115
+ let curX = Math.min(e.clientX, state.value.panel.xEnd)
116
+ curX = Math.max(state.value.panel.xStart, curX)
117
+ state.value.panel.left = curX - state.value.panel.xStart
118
+
119
+ let curY = Math.min(e.clientY, state.value.panel.yEnd)
120
+ curY = Math.max(state.value.panel.yStart, curY)
121
+ state.value.panel.top = curY - state.value.panel.yStart
122
+
123
+ setSaturation()
124
+ }
125
+ const setSaturation = () => {
126
+ state.value.panel.saturation = state.value.panel.left / state.value.width
127
+ state.value.panel.value = 1 - state.value.panel.top / state.value.height
128
+
129
+ update()
130
+ }
131
+
132
+ const changeHue = (e: MouseEvent) => {
133
+ if (curReadonly.value === true) return
134
+ startHue(e)
135
+ moveHue(e)
136
+ }
137
+ const startHue = (e: MouseEvent) => {
138
+ if (curReadonly.value === true) return
139
+ state.value.panel.started = false
140
+ state.value.hue.started = true
141
+ const target = (e.target as HTMLElement).parentElement
142
+ const rect = target?.getBoundingClientRect() as DOMRect
143
+ state.value.hue.start = rect.left
144
+ state.value.hue.end = rect.right
145
+ }
146
+ const moveHue = (e: MouseEvent) => {
147
+ let cur = Math.min(e.clientX, state.value.hue.end)
148
+ cur = Math.max(state.value.hue.start, cur)
149
+ state.value.hue.left = cur - state.value.hue.start
150
+ setHue()
151
+ }
152
+ const setHue = () => {
153
+ state.value.hue.value = Math.round((state.value.hue.left / state.value.width) * 360)
154
+ update()
155
+ }
156
+
157
+ const stop = (e: MouseEvent) => {
158
+ state.value.panel.started = false
159
+ state.value.hue.started = false
160
+ }
161
+ const move = (e: MouseEvent) => {
162
+ state.value.event = e
163
+ if (state.value.next === true) return
164
+ state.value.next = true
165
+ requestAnimationFrame(() => {
166
+ if (state.value.hue.started === true) moveHue(state.value.event)
167
+ if (state.value.panel.started === true) movePanel(state.value.event)
168
+ state.value.next = false
169
+ })
170
+ }
171
+
172
+ window.addEventListener('mousemove', move)
173
+ window.addEventListener('mouseup', stop)
174
+ window.addEventListener('mouseleave', stop)
175
+ const cancel = () => {
176
+ window.removeEventListener('mousemove', move)
177
+ window.removeEventListener('mouseup', stop)
178
+ window.removeEventListener('mouseleave', stop)
179
+ }
180
+ onBeforeUnmount(cancel)
181
+ </script>
182
+
183
+ <style lang="less" scoped>
184
+ @import '../theme/global.less';
185
+
186
+ @icon-color: #7a7a7a;
187
+ @border-color: #444444;
188
+ @picker-size: 22px;
189
+ @bar-height: 14px;
190
+
191
+ .vyr-color-picker {
192
+ .vyr-font-family;
193
+ background-color: transparent;
194
+ display: inline-flex;
195
+ flex-wrap: nowrap;
196
+ flex-direction: row;
197
+ justify-content: flex-start;
198
+ align-items: center;
199
+ align-content: center;
200
+
201
+ .vyr-picker-border {
202
+ width: @picker-size;
203
+ height: @picker-size;
204
+ border: var(--vyr-border-size) solid var(--vyr-border-color);
205
+ box-sizing: border-box;
206
+ padding: 3px;
207
+ }
208
+
209
+ .color-value {
210
+ cursor: pointer;
211
+ width: 100%;
212
+ height: 100%;
213
+ background-color: transparent;
214
+ border: var(--vyr-border-size) solid var(--vyr-border-color);
215
+ box-sizing: border-box;
216
+ }
217
+ }
218
+
219
+ .color-picker-popover {
220
+ .color-picker {
221
+
222
+ .picker-wrapper {
223
+ display: flex;
224
+ flex-wrap: wrap;
225
+ flex-direction: row;
226
+
227
+ .picker-panel {
228
+ width: 100%;
229
+ position: relative;
230
+ left: 0;
231
+ top: 0;
232
+ overflow-x: hidden;
233
+ overflow-y: hidden;
234
+
235
+ .picker-panel-white {
236
+ position: absolute;
237
+ left: 0;
238
+ top: 0;
239
+ width: 100%;
240
+ height: 100%;
241
+ background: linear-gradient(90deg, #fff, hsla(0, 0%, 100%, 0));
242
+ }
243
+
244
+ .picker-panel-black {
245
+ position: absolute;
246
+ left: 0;
247
+ top: 0;
248
+ width: 100%;
249
+ height: 100%;
250
+ background: linear-gradient(0deg, #000, transparent);
251
+ }
252
+
253
+ .picker-cursor {
254
+ cursor: pointer;
255
+ position: absolute;
256
+ left: 50%;
257
+ top: 50%;
258
+ transform: translate(-50%, -50%);
259
+ width: 4px;
260
+ height: 4px;
261
+ border-radius: 50%;
262
+ border: var(--vyr-border-size) solid var(--vyr-white-color);
263
+ box-shadow: 0 0 5px var(--vyr-black-color);
264
+ background-color: rgba(0, 0, 0, 0.6);
265
+ }
266
+ }
267
+
268
+ .picker-panel.active {
269
+ cursor: pointer;
270
+ }
271
+
272
+ .picker-bar {
273
+ width: 100%;
274
+ height: @bar-height;
275
+ margin: 10px 0 0;
276
+ position: relative;
277
+ left: 0;
278
+ top: 0;
279
+ background: linear-gradient(to right, red, #ff0, lime, cyan, blue, #f0f, red);
280
+
281
+ .picker-hue {
282
+ cursor: pointer;
283
+ position: absolute;
284
+ left: 0;
285
+ top: 50%;
286
+ transform: translate(-50%, -50%);
287
+ width: 4px;
288
+ height: 100%;
289
+ border-radius: 1px;
290
+ box-sizing: border-box;
291
+ box-shadow: 0 0 5px #9d9d9d;
292
+ background-color: var(--vyr-white-color);
293
+ border: var(--vyr-border-size) solid #f0f0f0;
294
+ }
295
+ }
296
+
297
+ .picker-bar.active {
298
+ cursor: pointer;
299
+ }
300
+ }
301
+
302
+ .opacity-wrapper {
303
+ width: 100%;
304
+ height: @bar-height;
305
+ margin: 10px 0 0;
306
+ box-sizing: border-box;
307
+ display: flex;
308
+ flex-wrap: nowrap;
309
+ flex-direction: row;
310
+
311
+ .opacity-inspector {
312
+ width: 100%;
313
+ height: 100%;
314
+ }
315
+ }
316
+ }
317
+ }
318
+
319
+ .vyr-color-picker.all {
320
+ width: 100%;
321
+
322
+ .vyr-picker-border {
323
+ width: 100%;
324
+ height: var(--vyr-input-height);
325
+ }
326
+ }
327
+
328
+ .vyr-color-picker:last-child {
329
+ margin-right: 0;
330
+ }
331
+ </style>
@@ -0,0 +1,86 @@
1
+ <template>
2
+ <vyr-dialog v-model="state.visible" :mask="true" :draggable="false" width="450px" maxHeight="240px" @close="close">
3
+ <template #title>
4
+ <template v-if="state.type === 'warning'">
5
+ <i class="vyrfont vyr-warning tips-type"></i>
6
+ </template>{{ state.title }}
7
+ </template>
8
+ <div class="message" v-if="state.message">
9
+ {{ state.message }}
10
+ </div>
11
+ <div class="content" v-if="state.mode === 'input'">
12
+ <vyr-input v-model="privateState.checked" :clearable="true"></vyr-input>
13
+ </div>
14
+ <template v-if="state.options.length">
15
+ <div class="content" v-if="!state.mode">
16
+ <vyr-checked-group v-model="privateState.checked" :data="state.options" :multiple="false">
17
+ </vyr-checked-group>
18
+ </div>
19
+ <div class="content" v-if="state.mode === 'list'">
20
+ <div class="li" v-for="(item, i) in state.options" :key="i">
21
+ {{ item.label }}
22
+ </div>
23
+ </div>
24
+ <div class="content" v-if="state.mode === 'select'">
25
+ <vyr-select v-model="privateState.checked" :data="state.options" :searchable="true"
26
+ :placeholder="state.placeholder"></vyr-select>
27
+ </div>
28
+ </template>
29
+ <template #footer>
30
+ <vyr-button @click="success">{{ language.get('confirm.button.submit') }}</vyr-button>
31
+ <vyr-button @click="cencel">{{ language.get('confirm.button.cancel') }}</vyr-button>
32
+ </template>
33
+ </vyr-dialog>
34
+ </template>
35
+
36
+ <script setup lang="ts">
37
+ import { ref } from 'vue';
38
+ import { useConfirmState } from './utils';
39
+ import { language } from '../locale'
40
+ import VyrDialog from './Dialog.vue';
41
+ import VyrButton from './Button.vue';
42
+ import VyrInput from './Input.vue'
43
+ import VyrCheckedGroup from './CheckedGroup.vue';
44
+ import VyrSelect from './Select.vue'
45
+
46
+ defineOptions({
47
+ inheritAttrs: false
48
+ })
49
+
50
+ const state = useConfirmState()
51
+ const privateState = ref({
52
+ checked: state.value.value ?? '',
53
+ flag: false,
54
+ })
55
+
56
+ const success = () => {
57
+ privateState.value.flag = true
58
+ state.value.visible = false
59
+ }
60
+ const cencel = () => {
61
+ privateState.value.flag = false
62
+ state.value.visible = false
63
+ }
64
+ const close = () => {
65
+ state.value.value = privateState.value.checked ?? ''
66
+ state.value.close(privateState.value.flag)
67
+ }
68
+ </script>
69
+
70
+ <style lang="less" scoped>
71
+
72
+ .tips-type {
73
+ margin: 0 5px 0 0;
74
+ color: var(--vyr-warning-color);
75
+ }
76
+
77
+ .content {
78
+ margin: 10px 0 0;
79
+
80
+ .li {
81
+ display: inline-block;
82
+ min-height: 30px;
83
+ margin: 0 10px 0 0;
84
+ }
85
+ }
86
+ </style>
@@ -0,0 +1,220 @@
1
+ <template>
2
+ <vyr-mask :mask-id="state.id" :layer="layer" :visible="modelValue" :mask="mask" @close="emit('close')"
3
+ #default="{ layer }">
4
+ <div ref="refDialog" class="vyr-dialog" :style="`${style};${layer}`" @contextmenu.prevent.stop @mousedown="change">
5
+ <div class="dialog-header" :style="`height:${header}px;`" @mousedown="start">
6
+ <div class="header-title">
7
+ <slot name="title">{{ title }}</slot>
8
+ </div>
9
+ <i class="vyrfont vyr-close header-close" v-if="closeable" @click="close" @mousedown.stop>
10
+ </i>
11
+ </div>
12
+ <div class="dialog-body" :style="`height:calc(100% - ${$slots.footer ? header + footer : header}px);`">
13
+ <slot name="scroll">
14
+ <vyr-scroll :margin="margin" :padding="padding" @resize="computeMaxHeight">
15
+ <slot></slot>
16
+ </vyr-scroll>
17
+ </slot>
18
+ </div>
19
+ <div class="dialog-footer" :style="`height:${footer}px;`" v-if="$slots.footer">
20
+ <slot name="footer"></slot>
21
+ </div>
22
+ <slot name="dialog"></slot>
23
+ </div>
24
+ </vyr-mask>
25
+ </template>
26
+
27
+ <script lang="ts" setup>
28
+ import { computed, watch, ref, nextTick, useTemplateRef } from 'vue'
29
+ import { computedFloatLayer, dialogPrivateWarp, generateFloatLayer, getDialogHeight, getDialogWrapHeight, isActiveLayer, seActiveLayer } from './utils'
30
+ import { updateFlotaLayerProvider, FlotaLayerProvider } from './composables/useProvider'
31
+ import { dialogCommonDefaultProps } from './composables/useDefaultProps'
32
+ import { Listener } from '../tool'
33
+ import VyrMask from './Mask.vue'
34
+ import VyrScroll from './Scroll.vue'
35
+
36
+ defineOptions({
37
+ inheritAttrs: false
38
+ })
39
+
40
+ const props = defineProps({
41
+ modelValue: { default: false },
42
+ title: { default: '' },
43
+ draggable: { default: true },
44
+ closeable: { default: true },
45
+ position: { default() { return { left: '50%', top: '50%' } } },
46
+ ...dialogCommonDefaultProps,
47
+ })
48
+ const emit = defineEmits(['update:modelValue', 'active', 'close'])
49
+ const refDialog = useTemplateRef('refDialog')
50
+
51
+ const initPosition = () => {
52
+ state.value.position = `left:${props.position.left};top:${props.position.top};`
53
+ }
54
+ const state = ref({
55
+ id: generateFloatLayer(),
56
+ activeDialog: false,
57
+ offset: { x: 0, y: 0 },
58
+ height: props.height,
59
+ position: '',
60
+ moving: false,
61
+ })
62
+
63
+ const active = computed(() => isActiveLayer(state.value.id))
64
+ const layer = computed(() => computedFloatLayer(state.value.id, active.value))
65
+ const style = computed(() => {
66
+ const style = `
67
+ width:${props.width};
68
+ height:${state.value.height};
69
+ max-height:${props.maxHeight};
70
+ ${state.value.position};
71
+ `
72
+
73
+ return style
74
+ })
75
+
76
+ const flotaLayerProvider: FlotaLayerProvider = { listener: new Listener(), layer }
77
+ updateFlotaLayerProvider(flotaLayerProvider)
78
+
79
+ const close = () => {
80
+ emit('update:modelValue', false)
81
+ }
82
+ const change = () => {
83
+ seActiveLayer(state.value.id)
84
+ emit('active')
85
+ }
86
+ const start = (e: MouseEvent) => {
87
+ if (props.draggable === false) return
88
+ if (!refDialog.value) return
89
+ const rect = refDialog.value.getBoundingClientRect()
90
+ state.value.offset.x = e.clientX - rect.left - rect.width / 2
91
+ state.value.offset.y = e.clientY - rect.top - rect.height / 2
92
+ state.value.activeDialog = true
93
+ }
94
+ const move = (e: MouseEvent) => {
95
+ if (state.value.activeDialog === false || state.value.moving === true) return
96
+ state.value.moving = true
97
+
98
+ requestAnimationFrame(() => {
99
+ const x = e.clientX - state.value.offset.x
100
+ const y = e.clientY - state.value.offset.y
101
+ state.value.position = `left:${x}px;top:${y}px;`
102
+ state.value.moving = false
103
+ flotaLayerProvider.listener.trigger('move', {})
104
+ })
105
+ }
106
+ const stop = () => {
107
+ state.value.activeDialog = false
108
+ }
109
+ const watchshortcutkey = (e: KeyboardEvent) => {
110
+ if (e.code === 'Escape') close()
111
+ }
112
+
113
+ const watchModelValue = () => {
114
+ if (props.modelValue === true) {
115
+ dialogPrivateWarp.addEventListener('mousemove', move)
116
+ dialogPrivateWarp.addEventListener('mouseup', stop, false)
117
+ dialogPrivateWarp.addEventListener('mouseleave', stop)
118
+ window.addEventListener('keydown', watchshortcutkey)
119
+ if (state.value.position === '') nextTick(initPosition)
120
+ change()
121
+ } else {
122
+ dialogPrivateWarp.removeEventListener('mousemove', move)
123
+ dialogPrivateWarp.removeEventListener('mouseup', stop)
124
+ dialogPrivateWarp.removeEventListener('mouseleave', stop)
125
+ window.removeEventListener('keydown', watchshortcutkey)
126
+ }
127
+ }
128
+ watch(() => props.modelValue, watchModelValue, { immediate: true })
129
+
130
+ const wrapperHeight = computed(() => getDialogWrapHeight(props.maxHeight))
131
+ const computeMaxHeight = () => {
132
+ if (!refDialog.value) return
133
+ const dialogHeight = getDialogHeight(refDialog.value)
134
+ state.value.height = dialogHeight >= wrapperHeight.value ? wrapperHeight.value + 'px' : props.height
135
+ }
136
+
137
+ </script>
138
+
139
+ <style lang="less" scoped>
140
+ @import '../theme/global.less';
141
+
142
+ @close-width: 30px;
143
+
144
+ .vyr-dialog {
145
+ .vyr-font-family;
146
+ color: var(--vyr-font-color);
147
+ font-size: var(--vyr-font-size);
148
+ position: fixed;
149
+ left: 0;
150
+ top: 0;
151
+ transform: translate(-50%, -50%);
152
+ border-radius: var(--vyr-radius-size);
153
+ max-width: 100%;
154
+ max-height: 100%;
155
+ color: var(--vyr-white-color);
156
+ background-color: var(--vyr-topic-color);
157
+ box-sizing: border-box;
158
+ border: 1px solid var(--vyr-border-color);
159
+
160
+ .dialog-header {
161
+ width: 100%;
162
+ display: flex;
163
+ flex-wrap: nowrap;
164
+ flex-direction: row;
165
+ justify-content: space-between;
166
+ align-items: center;
167
+ align-content: center;
168
+ padding: 0 20px;
169
+ box-sizing: border-box;
170
+ background-color: var(--vyr-dialog-header-background-color);
171
+ border-bottom: var(--vyr-border-size) solid var(--vyr-border-color);
172
+
173
+ .header-title {
174
+ font-size: var(--vyr-title-size);
175
+ width: calc(~'100% - @{close-width}');
176
+ letter-spacing: 1px;
177
+ user-select: none;
178
+ }
179
+
180
+ .header-close {
181
+ cursor: pointer;
182
+ width: @close-width;
183
+ transition: all var(--vyr-animation-time);
184
+ display: flex;
185
+ flex-wrap: nowrap;
186
+ flex-direction: row;
187
+ justify-content: flex-end;
188
+ align-items: center;
189
+ align-content: center;
190
+
191
+ &:hover {
192
+ opacity: 0.7;
193
+ color: var(--vyr-active-topic-color);
194
+ }
195
+ }
196
+ }
197
+
198
+ .dialog-body {
199
+ width: 100%;
200
+ border: var(--vyr-border-size) solid transparent;
201
+ box-sizing: border-box;
202
+ }
203
+
204
+ .dialog-footer {
205
+ width: 100%;
206
+ display: flex;
207
+ flex-wrap: nowrap;
208
+ flex-direction: row;
209
+ justify-content: flex-end;
210
+ align-items: center;
211
+ align-content: center;
212
+ border-top: var(--vyr-border-size) solid var(--vyr-border-color);
213
+ box-sizing: border-box;
214
+
215
+ :deep(.vyr-button) {
216
+ margin: 0 10px;
217
+ }
218
+ }
219
+ }
220
+ </style>
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <div class="divider">
3
+ <div class="line">
4
+ <div class="text">{{ text }}</div>
5
+ </div>
6
+ </div>
7
+ </template>
8
+
9
+ <script lang="ts" setup>
10
+ defineProps<{ text: string }>()
11
+ </script>
12
+
13
+ <style lang="less" scoped>
14
+ .divider {
15
+ width: 100%;
16
+ height: calc(1em + 16px);
17
+ display: flex;
18
+ justify-content: center;
19
+ align-items: center;
20
+
21
+ .line {
22
+ width: 100%;
23
+ height: 1px;
24
+ position: relative;
25
+ top: 0;
26
+ left: 0;
27
+ border-bottom: 1px solid var(--vyr-border-color);
28
+ }
29
+
30
+ .text {
31
+ color: #c3c3c3;
32
+ background-color: var(--vyr-topic-color);
33
+ padding: 0 0 0 20px;
34
+ position: absolute;
35
+ top: 50%;
36
+ right: 0;
37
+ transform: translate(0, -50%);
38
+ }
39
+ }
40
+ </style>