@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
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "@vyr/design",
3
+ "version": "0.0.1",
4
+ "main": "./src/index.ts",
5
+ "dependencies": {
6
+ "vue": "3.5.22",
7
+ "@popperjs/core": "^2.11.8",
8
+ "@vyr/locale": "0.0.1",
9
+ "async-validator": "^4.2.5",
10
+ "tinycolor2": "1.6.0"
11
+ },
12
+ "files": [
13
+ "package.json",
14
+ "src/"
15
+ ]
16
+ }
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="vyr-button" :style="style" @click="e => emit('click', e)">
3
+ <slot></slot>
4
+ </div>
5
+ </template>
6
+
7
+ <script lang="ts" setup>
8
+ import { computed } from 'vue';
9
+
10
+ const props = defineProps({
11
+ width: { default: 'auto' }
12
+ })
13
+ const style = computed(() => {
14
+ let style = ''
15
+
16
+ style += props.width === 'auto' ? '' : 'width:100%;text-align:center;'
17
+
18
+ return style
19
+ })
20
+ const emit = defineEmits(['click'])
21
+ </script>
22
+
23
+ <style lang="less" scoped>
24
+ @import '../theme/global.less';
25
+
26
+ @button-background-color: rgba(35, 35, 35, 1);
27
+ @button-border-color: rgba(71, 71, 71, 1);
28
+ @button-background-color-hover: rgba(40, 40, 40, 1);
29
+ @button-border-color-hover: rgba(87, 87, 87, 1);
30
+ @button-background-color-active: rgba(47, 47, 47, 1);
31
+ @button-border-color-active: rgba(111, 111, 111, 1);
32
+
33
+ .vyr-button {
34
+ .vyr-font-family;
35
+ cursor: pointer;
36
+ color: var(--vyr-font-color);
37
+ font-size: var(--vyr-font-size);
38
+ line-height: 1em;
39
+ padding: 10px 18px;
40
+ background-color: @button-background-color;
41
+ display: inline-block;
42
+ border-radius: var(--vyr-radius-size);
43
+ border: @button-border-color 1px solid;
44
+ box-sizing: border-box;
45
+ user-select: none;
46
+ letter-spacing: 2px;
47
+ transition: all 0.2s;
48
+ margin: 0 20px 0 0;
49
+
50
+ &:hover {
51
+ background-color: @button-background-color-hover;
52
+ border: @button-border-color-hover 1px solid;
53
+ }
54
+
55
+ &:active {
56
+ background-color: @button-background-color-active;
57
+ border: @button-border-color-active 1px solid;
58
+ }
59
+ }
60
+
61
+ .vyr-button:last-child {
62
+ margin-right: 0;
63
+ }
64
+ </style>
@@ -0,0 +1,203 @@
1
+ <template>
2
+ <div class="vyr-card" :style="style">
3
+ <div class="card-header" :class="{ 'handle': arrow }" @click="changeVisible">
4
+ <div class="header-title">
5
+ <slot v-if="$slots.title" name="title"></slot>
6
+ <div v-else class="title-text">
7
+ {{ title }}
8
+ </div>
9
+ </div>
10
+ <div class="header-icon" :class="{ 'expand': state.visible }">
11
+ <slot name="icon">
12
+ <i v-if="arrow" class="vyrfont vyr-arrow-down-bold"></i>
13
+ </slot>
14
+ </div>
15
+ </div>
16
+ <div class="card-body" :class="{ scroll }" ref="refBody" :style="state.style">
17
+ <template v-if="scroll">
18
+ <vyr-scroll :margin="8" :padding="8">
19
+ <slot></slot>
20
+ </vyr-scroll>
21
+ </template>
22
+ <template v-else>
23
+ <div class="body-wrapper" ref="refWrapper">
24
+ <slot></slot>
25
+ </div>
26
+ </template>
27
+ </div>
28
+ <div class="card-tool" v-if="$slots.tool">
29
+ <slot name="tool"></slot>
30
+ </div>
31
+ </div>
32
+ </template>
33
+
34
+ <script lang="ts" setup>
35
+ import { computed, ref, useTemplateRef, watch } from 'vue'
36
+ import { Theme } from '../theme';
37
+ import VyrScroll from './Scroll.vue'
38
+
39
+ const props = defineProps({
40
+ title: { default: '' },
41
+ arrow: { default: false },
42
+ scroll: { default: false }
43
+ })
44
+
45
+ const refBody = useTemplateRef('refBody')
46
+ const refWrapper = useTemplateRef('refWrapper')
47
+ const state = ref({
48
+ visible: true,
49
+ style: '',
50
+ showing: false,
51
+ })
52
+ const showBodyEnd = () => {
53
+ state.value.showing = false
54
+ state.value.style = ''
55
+ }
56
+ const showBody = () => {
57
+ if (!refWrapper.value) return
58
+ let height = refWrapper.value.clientHeight
59
+ state.value.style = `height:${height}px;overflow:hidden;`
60
+ setTimeout(showBodyEnd, Theme.config.animationTime.value)
61
+ }
62
+ const hideBodyEnd = () => {
63
+ state.value.showing = false
64
+ state.value.style = 'display:none;'
65
+ }
66
+ const hideBody = () => {
67
+ if (!refBody.value) return
68
+ state.value.style = `height:${refBody.value.clientHeight}px;overflow:hidden;`
69
+ requestAnimationFrame(() => state.value.style = `height:0px;overflow:hidden;`)
70
+ setTimeout(hideBodyEnd, Theme.config.animationTime.value)
71
+ }
72
+ const watchVisible = () => {
73
+ state.value.showing = true
74
+ if (state.value.visible === true) {
75
+ state.value.style = 'height:0px;overflow:hidden;'
76
+ requestAnimationFrame(showBody)
77
+ } else {
78
+ hideBody()
79
+ }
80
+ }
81
+ watch(() => state.value.visible, watchVisible)
82
+
83
+ const style = computed(() => {
84
+ return props.scroll ? 'height:100%;' : ''
85
+ })
86
+
87
+ const changeVisible = () => {
88
+ if (props.arrow === false || state.value.showing === true) return
89
+ state.value.visible = !state.value.visible
90
+ }
91
+ </script>
92
+
93
+ <style lang="less" scoped>
94
+ @import '../theme/global.less';
95
+
96
+ @card-pad-size: 10px;
97
+ @header-icon-width: 25px;
98
+
99
+ .vyr-card {
100
+ .vyr-font-family;
101
+ width: 100%;
102
+ font-size: var(--vyr-font-size);
103
+ color: var(--vyr-font-color);
104
+ border: 1px solid var(--vyr-border-color);
105
+ box-sizing: border-box;
106
+ border-bottom-left-radius: 2px;
107
+ border-bottom-right-radius: 2px;
108
+ display: flex;
109
+ flex-wrap: nowrap;
110
+ flex-direction: column;
111
+
112
+ .card-header {
113
+ width: 100%;
114
+ box-sizing: border-box;
115
+ line-height: 1.5em;
116
+ padding: 0 @card-pad-size;
117
+ background-color: var(--vyr-topic-color);
118
+ position: relative;
119
+ left: 0;
120
+ top: 0;
121
+ display: flex;
122
+ flex-wrap: nowrap;
123
+ flex-direction: row;
124
+ justify-content: space-between;
125
+ align-items: center;
126
+ align-content: center;
127
+
128
+ .header-title {
129
+ width: calc(~'100% - @{header-icon-width}');
130
+ display: flex;
131
+ align-items: center;
132
+
133
+ .title-text {
134
+ .t_hide;
135
+ line-height: calc(1em + 24px);
136
+ margin-right: 4px;
137
+ }
138
+ }
139
+
140
+ .header-icon {
141
+ width: @header-icon-width;
142
+ display: flex;
143
+ flex-wrap: nowrap;
144
+ flex-direction: row;
145
+ justify-content: flex-end;
146
+ align-items: center;
147
+ align-content: center;
148
+
149
+ .vyrfont {
150
+ cursor: pointer;
151
+ font-size: var(--vyr-font-size);
152
+ display: inline-block;
153
+ transition: all var(--vyr-animation-time);
154
+ color: var(--vyr-helper-color);
155
+ }
156
+ }
157
+
158
+ .header-icon.expand {
159
+ .vyrfont {
160
+ transform: rotate(-180deg);
161
+ }
162
+ }
163
+ }
164
+
165
+ .card-body {
166
+ width: 100%;
167
+ box-sizing: border-box;
168
+ background-color: var(--vyr-topic-color);
169
+ border-top: var(--vyr-border-size) solid var(--vyr-border-color);
170
+ transition: height var(--vyr-animation-time);
171
+ flex: 1;
172
+
173
+ .body-wrapper {
174
+ min-height: @card-pad-size;
175
+ box-sizing: border-box;
176
+ padding: @card-pad-size*0.5 @card-pad-size;
177
+ }
178
+ }
179
+
180
+ .card-body.scroll {
181
+ height: 100%;
182
+ overflow: hidden;
183
+ }
184
+
185
+ .card-tool {
186
+ border-top: var(--vyr-border-size) solid var(--vyr-border-color);
187
+ padding: @card-pad-size;
188
+ box-sizing: border-box;
189
+ display: flex;
190
+
191
+ >* {
192
+ font-size: 18px;
193
+ margin-right: 16px;
194
+ cursor: pointer;
195
+ transition: all var(--vyr-animation-time);
196
+
197
+ &:hover {
198
+ color: var(--vyr-active-topic-color);
199
+ }
200
+ }
201
+ }
202
+ }
203
+ </style>
@@ -0,0 +1,171 @@
1
+ <template>
2
+ <div class="vyr-cascader" :style="`width:${curInputWidth};`">
3
+ <vyr-select ref="refSelector" popover-class="vyr-cascader-popover" :popover-card="false" :placement
4
+ :model-value="modelValue" :placeholder="placeholder" :data="data" :getter="curGetter" :arrow="arrow"
5
+ :offset="offset" :readonly="curReadonly" :clearable="curClearable" :readonly-clearable="curReadonlyClearable"
6
+ :searchable="searchable" :width="`100%`" :popover-width="popoverWidth" @show="selectShow" @close="emit('close')"
7
+ @clear="emit('update:modelValue', '')">
8
+ <template #trigger>
9
+ <slot name="trigger"></slot>
10
+ </template>
11
+ <template #default="select">
12
+ <vyr-options v-for="(items, i) in currentRenderQuaua" :key="i" :data="items" :getter="curGetter"
13
+ :forced-prompt="select.forcedPrompt" :width="select.width" :max-count :min-count="curMinCount"
14
+ :checked="checked" :left="state.left" :visible="visible" @click="clickOption"></vyr-options>
15
+ </template>
16
+ </vyr-select>
17
+ </div>
18
+ </template>
19
+
20
+ <script lang="ts" setup>
21
+ import { computed, ref, useTemplateRef, watch } from 'vue'
22
+ import { commonDefaultProps, selectCommonDefaultProps, popoverCommonDefaultProps, getterCommonDefaultProps, useInputCommonProps, inputCommonDefaultProps } from './composables/useDefaultProps'
23
+ import { usePopoverProvider, updatePopoverProvider, updateCascaderProvider } from './composables/useProvider'
24
+ import { useCommonProps } from './composables/useDefaultProps'
25
+ import { searchDefaultProps } from './composables/useSearch'
26
+ import { useGetter } from './composables/useGetter'
27
+ import { CascaderOption, CascaderOptions, SelectPopoverLayout } from './types'
28
+ import { getInputValue, getSearchOptions, getSelectOptions } from './utils'
29
+ import VyrSelect from './Select.vue'
30
+ import VyrOptions from './Options.vue'
31
+
32
+
33
+ const getPopoverLayout = (layout: SelectPopoverLayout) => {
34
+ state.value.left = layout.position[1] === 'end' ? false : true
35
+ }
36
+ const cascaderProvider = ref({ getInputValue, getPopoverLayout, getSearchOptions, searchOptions: [] as CascaderOptions })
37
+ updateCascaderProvider(cascaderProvider)
38
+ const popoverProvider = usePopoverProvider()
39
+ updatePopoverProvider(ref({ ...popoverProvider.value, useFlexLayout: true }))
40
+
41
+ const props = defineProps({
42
+ ...commonDefaultProps,
43
+ ...popoverCommonDefaultProps,
44
+ ...searchDefaultProps,
45
+ ...inputCommonDefaultProps,
46
+ ...selectCommonDefaultProps,
47
+ ...getterCommonDefaultProps,
48
+ popoverWidth: { default: 'auto' },
49
+ maxCount: { default: 5 },
50
+ minCount: { default: 1 },
51
+ data: { default() { return [] as CascaderOptions }, },
52
+ visible: { default() { return (item: CascaderOption) => { return true as boolean } } },
53
+ })
54
+ const curGetter = useGetter(props)
55
+ const refSelector = useTemplateRef('refSelector')
56
+ const emit = defineEmits(['update:modelValue', 'change', 'show', 'close'])
57
+ const state = ref({
58
+ renderOption: '' as CascaderOption['value'],
59
+ checkedOption: '' as CascaderOption['value'],
60
+ left: true
61
+ })
62
+
63
+ const { curReadonly, curClearable, curReadonlyClearable } = useCommonProps(props)
64
+ const { curInputWidth } = useInputCommonProps(props)
65
+ const checked = computed(() => {
66
+ const checked = []
67
+ const options = getSelectOptions(props.data, state.value.checkedOption, curGetter)
68
+ for (const item of options) checked.push(curGetter.value(item))
69
+ return checked
70
+ })
71
+ const traceQuaua = computed(() => {
72
+ const quaua: CascaderOptions[] = []
73
+ const options = getSelectOptions(props.data, state.value.renderOption, curGetter)
74
+
75
+ for (const item of options) {
76
+ const children = curGetter.children(item)
77
+ if (children.length === 0) continue
78
+ quaua.push(children)
79
+ }
80
+ quaua.push(props.data)
81
+
82
+ return quaua
83
+ })
84
+ const renderQuaua = computed(() => {
85
+ const quaua: Array<CascaderOption>[] = [...traceQuaua.value]
86
+
87
+ return state.value.left ? quaua.reverse() : quaua
88
+ })
89
+ const currentRenderQuaua = computed(() => cascaderProvider.value.searchOptions.length === 0 ? renderQuaua.value : [cascaderProvider.value.searchOptions])
90
+ const curMinCount = computed(() => {
91
+ let count = props.minCount
92
+
93
+ for (const item of currentRenderQuaua.value) {
94
+ count = Math.max(item.length, count)
95
+ }
96
+
97
+ return Math.min(count, props.maxCount)
98
+ })
99
+ watch(currentRenderQuaua, () => refSelector.value?.resize())
100
+
101
+ const selectShow = () => {
102
+ state.value.renderOption = props.modelValue
103
+ state.value.checkedOption = props.modelValue
104
+ emit('show')
105
+ }
106
+ const clickOption = (item: CascaderOption, e: MouseEvent) => {
107
+ e.stopPropagation()
108
+
109
+ const children = curGetter.children(item)
110
+ const select = children.length === 0 ? true : false
111
+ select ? selectItem(item, e) : expandItem(item, e)
112
+ }
113
+ const expandItem = (item: CascaderOption, e: MouseEvent) => {
114
+ const value = curGetter.value(item)
115
+ state.value.renderOption = value
116
+ state.value.checkedOption = value
117
+ }
118
+ const selectItem = (item: CascaderOption, e: MouseEvent) => {
119
+ if (props.readonly) return
120
+ refSelector.value?.close()
121
+ const value = curGetter.value(item)
122
+ if (props.modelValue === value) return
123
+ emit('update:modelValue', value)
124
+ emit('change', item, e)
125
+ }
126
+
127
+ const expose = {
128
+ show: () => refSelector.value?.show(),
129
+ close: () => refSelector.value?.close()
130
+ }
131
+ defineExpose(expose)
132
+ </script>
133
+
134
+ <style lang="less" scoped>
135
+ @import '../theme/global.less';
136
+
137
+ .vyr-cascader {
138
+ .vyr-font-family;
139
+ }
140
+
141
+ @option-pad-left: 4px;
142
+
143
+ .vyr-cascader-popover {
144
+ .vyr-options {
145
+ border-radius: 0;
146
+
147
+
148
+ :deep(.vyr-option) {
149
+ padding: 0 @option-pad-left 0 var(--vyr-input-l-r-padding);
150
+ }
151
+
152
+ :deep(.vyr-option.justify) {
153
+ padding: 0 var(--vyr-input-l-r-padding) 0 @option-pad-left;
154
+ }
155
+ }
156
+
157
+ .vyr-options:not(:first-child) {
158
+ border-left-color: transparent;
159
+ }
160
+
161
+ .vyr-options:first-child {
162
+ border-top-left-radius: var(--vyr-radius-size);
163
+ border-bottom-left-radius: var(--vyr-radius-size);
164
+ }
165
+
166
+ .vyr-options:last-child {
167
+ border-top-right-radius: var(--vyr-radius-size);
168
+ border-bottom-right-radius: var(--vyr-radius-size);
169
+ }
170
+ }
171
+ </style>
@@ -0,0 +1,124 @@
1
+ <template>
2
+ <div class="vyr-checked" :class="{ disabled: disabled }" @click="change">
3
+ <div class="checked-box">
4
+ <i class="vyrfont vyr-checked-no" :class="{ 'active': multiple || checked }"> </i>
5
+ <template v-if="multiple">
6
+ <i class="vyrfont vyr-checked-multiple"></i>
7
+ </template>
8
+ <template v-else>
9
+ <i class="vyrfont vyr-checked-all" v-if="checked"> </i>
10
+ </template>
11
+ </div>
12
+ <div class="checked-body" v-if="$slots.default">
13
+ <slot></slot>
14
+ </div>
15
+ </div>
16
+ </template>
17
+
18
+ <script lang="ts" setup>
19
+ import { computed } from 'vue'
20
+ import { checkedCommonDefaultProps } from './composables/useDefaultProps'
21
+ import { useCheckedGroupProvider, useProvider } from './composables/useProvider'
22
+
23
+ const props = defineProps({
24
+ ...checkedCommonDefaultProps,
25
+ readonly: { default: null as boolean | null },
26
+ disabled: { default: false },
27
+ multiple: { default: false },
28
+ })
29
+
30
+ const emit = defineEmits(['update:modelValue', 'change'])
31
+
32
+ const provider = useProvider()
33
+ const curReadonly = computed(() => props.readonly === null ? provider.value.readonly : props.readonly)
34
+
35
+ const checkedGroupProvider = useCheckedGroupProvider()
36
+ const checked = computed(() => checkedGroupProvider === null ? props.modelValue === props.value : checkedGroupProvider.value.checked(props.value))
37
+
38
+ const change = () => {
39
+ if (curReadonly.value === true) return
40
+
41
+ if (checkedGroupProvider === null) {
42
+ const value = !props.modelValue
43
+ emit('update:modelValue', value)
44
+ emit('change', value)
45
+ return
46
+ }
47
+
48
+ checkedGroupProvider.value.change(props.value)
49
+ }
50
+ </script>
51
+
52
+ <style lang="less" scoped>
53
+ @import '../theme/global.less';
54
+
55
+ @checked-icon-color: #676767;
56
+
57
+ .vyr-checked {
58
+ .vyr-font-family;
59
+ cursor: pointer;
60
+ max-width: 100%;
61
+ color: var(--vyr-font-color);
62
+ margin: 0 10px 0 0;
63
+ display: inline-flex;
64
+ flex-wrap: nowrap;
65
+ flex-direction: row;
66
+ vertical-align: top;
67
+
68
+ .checked-box {
69
+ display: flex;
70
+ flex-wrap: nowrap;
71
+ flex-direction: row;
72
+ justify-content: flex-start;
73
+ align-items: center;
74
+ align-content: center;
75
+ position: relative;
76
+ left: 0;
77
+ top: 0;
78
+
79
+ .vyrfont {
80
+ font-size: 22px;
81
+ color: @checked-icon-color;
82
+ transition: all var(--vyr-animation-time);
83
+ }
84
+
85
+ .vyrfont:hover,
86
+ .vyrfont.active,
87
+ .vyr-checked-all,
88
+ .vyr-checked-multiple {
89
+ color: var(--vyr-active-topic-color);
90
+ }
91
+
92
+ .vyr-checked-multiple,
93
+ .vyr-checked-all {
94
+ position: absolute;
95
+ left: 50%;
96
+ top: 50%;
97
+ transform: translate(-50%, -50%);
98
+ }
99
+ }
100
+
101
+ .checked-body {
102
+ .t_hide;
103
+ line-height: var(--vyr-input-height);
104
+ padding: 0 0 0 10px;
105
+ box-sizing: border-box;
106
+ }
107
+ }
108
+
109
+ .vyr-checked.disabled {
110
+ cursor: not-allowed;
111
+
112
+ .checked-box {
113
+
114
+ .vyrfont,
115
+ .vyrfont:hover {
116
+ color: #313131 !important;
117
+ }
118
+ }
119
+ }
120
+
121
+ .vyr-checked:last-child {
122
+ margin-right: 0;
123
+ }
124
+ </style>
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <div class="vyr-checked-group">
3
+ <slot>
4
+ <vyr-checked v-for="(item, i) in data" :key="i" :value="item.value">{{ item.label }}</vyr-checked>
5
+ </slot>
6
+ </div>
7
+ </template>
8
+
9
+ <script lang="ts" setup>
10
+ import { ref } from 'vue'
11
+ import { Options } from './types';
12
+ import { updateCheckedGroupProvider } from './composables/useProvider'
13
+ import { ArrayUtils } from '../tool';
14
+ import VyrChecked from './Checked.vue';
15
+
16
+ const props = defineProps({
17
+ modelValue: { default: [] as any[] | any },
18
+ data: { default() { return [] as Options } },
19
+ multiple: { default: true }
20
+ })
21
+
22
+ const emit = defineEmits(['update:modelValue'])
23
+
24
+ const change = (value: any) => {
25
+ let values
26
+ if (props.multiple) {
27
+ values = [...props.modelValue]
28
+ ArrayUtils.auto(values, value)
29
+ } else {
30
+ values = value
31
+ }
32
+ emit('update:modelValue', values)
33
+ }
34
+ const checked = (value: any) => {
35
+ if (props.multiple) {
36
+ return props.modelValue.includes(value)
37
+ } else {
38
+ return props.modelValue === value
39
+ }
40
+ }
41
+ updateCheckedGroupProvider(ref({ change, checked }))
42
+
43
+ </script>
44
+
45
+ <style lang="less" scoped>
46
+ @import '../theme/global.less';
47
+
48
+ .vyr-checked-group {
49
+ .vyr-font-family;
50
+ }
51
+ </style>
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div class="vyr-col" :class="[`vyr-col-${span}`, offset > 0 ? `vyr-col-offset-${offset}` : '']" :style="style">
3
+ <slot></slot>
4
+ </div>
5
+ </template>
6
+
7
+ <script lang="ts" setup>
8
+ import { computed, onBeforeUnmount, onMounted } from 'vue'
9
+ import { useRowProvider } from './composables/useProvider';
10
+
11
+ defineProps({
12
+ span: { default: 24, validator(value: number) { return value > 0 && value <= 24 } },
13
+ offset: { default: 0 },
14
+ })
15
+
16
+ const rowProvider = useRowProvider()
17
+ const style = computed(() => `padding:0 ${rowProvider.value.gutter}px;`)
18
+
19
+ onMounted(() => rowProvider.value.count++)
20
+ onBeforeUnmount(() => rowProvider.value.count--)
21
+
22
+ </script>
23
+
24
+ <style lang="less" scoped>
25
+ @import '../theme/global.less';
26
+
27
+ @col-unit: (1/24) * 100%;
28
+
29
+ .vyr-col {
30
+ .vyr-font-family;
31
+ display: inline-flex;
32
+ flex-wrap: nowrap;
33
+ flex-direction: row;
34
+ box-sizing: border-box;
35
+ vertical-align: top;
36
+ }
37
+
38
+ .vyr-col-loop (@i) when (@i > 1) {
39
+
40
+ .vyr-col-@{i} {
41
+ width: @i * @col-unit;
42
+ }
43
+
44
+ .vyr-col-offset-@{i} {
45
+ margin: 0 0 0 @i * @col-unit;
46
+ }
47
+
48
+ .vyr-col-loop(@i - 1);
49
+ }
50
+
51
+ .vyr-col-loop(24);
52
+ </style>