fit2cloud-ui-plus 0.0.1-beta.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.
Files changed (89) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +16 -0
  3. package/lib/favicon.bmp +0 -0
  4. package/lib/fit2cloud-ui-plus.es.js +3796 -0
  5. package/lib/fit2cloud-ui-plus.umd.js +1 -0
  6. package/package.json +48 -0
  7. package/src/components/filter-bar/FuFilter.vue +175 -0
  8. package/src/components/filter-bar/FuFilterBar.vue +75 -0
  9. package/src/components/filter-bar/FuFilterConditions.vue +29 -0
  10. package/src/components/filter-bar/FuSearchInput.vue +31 -0
  11. package/src/components/filter-bar/filter-components/FuFilterDate.vue +62 -0
  12. package/src/components/filter-bar/filter-components/FuFilterDateTime.vue +65 -0
  13. package/src/components/filter-bar/filter-components/FuFilterOption.vue +38 -0
  14. package/src/components/filter-bar/filter-components/FuFilterSelect.vue +143 -0
  15. package/src/components/filter-bar/index.ts +19 -0
  16. package/src/components/filter-bar/types.ts +31 -0
  17. package/src/components/read-write-switch/FuInputRwSwitch.vue +44 -0
  18. package/src/components/read-write-switch/FuReadWriteSwitch.vue +91 -0
  19. package/src/components/read-write-switch/FuSelectRwSwitch.vue +53 -0
  20. package/src/components/read-write-switch/index.ts +13 -0
  21. package/src/components/search-bar/FuComplexSearch.vue +108 -0
  22. package/src/components/search-bar/FuQuickSearch.vue +43 -0
  23. package/src/components/search-bar/FuSearchBar.vue +165 -0
  24. package/src/components/search-bar/FuSearchBarButton.vue +14 -0
  25. package/src/components/search-bar/FuSearchContions.vue +24 -0
  26. package/src/components/search-bar/index.ts +13 -0
  27. package/src/components/search-bar/store.ts +25 -0
  28. package/src/components/speed-dial/FuSpeedDial.vue +280 -0
  29. package/src/components/speed-dial/FuSpeedDialActionButton.vue +88 -0
  30. package/src/components/speed-dial/FuSpeedDialButton.vue +42 -0
  31. package/src/components/speed-dial/FuSpeedDialItem.vue +88 -0
  32. package/src/components/speed-dial/index.ts +11 -0
  33. package/src/components/split-pane/FuSplitPane.vue +228 -0
  34. package/src/components/split-pane/index.ts +8 -0
  35. package/src/components/steps/FuHorizontalNavigation.vue +18 -0
  36. package/src/components/steps/FuHorizontalSteps.vue +94 -0
  37. package/src/components/steps/FuStep.vue +13 -0
  38. package/src/components/steps/FuSteps.vue +22 -0
  39. package/src/components/steps/FuStepsFooter.ts +79 -0
  40. package/src/components/steps/FuVerticalNavigation.vue +35 -0
  41. package/src/components/steps/FuVerticalSteps.vue +79 -0
  42. package/src/components/steps/Stepper.ts +188 -0
  43. package/src/components/steps/index.ts +11 -0
  44. package/src/components/table/FuTable.vue +145 -0
  45. package/src/components/table/FuTableBody.ts +40 -0
  46. package/src/components/table/FuTablePagination.vue +42 -0
  47. package/src/components/table/index.ts +15 -0
  48. package/src/components/table/table-column-dropdown/FuTableColumnDropdown.vue +102 -0
  49. package/src/components/table/table-column-dropdown/index.ts +7 -0
  50. package/src/components/table/table-column-select/FuTableColumnSelect.vue +22 -0
  51. package/src/components/table/table-column-select/FuTableColumnSelectDialog.vue +99 -0
  52. package/src/components/table/table-column-select/FuTableColumnSelectPopover.vue +80 -0
  53. package/src/components/table/table-column-select/index.ts +8 -0
  54. package/src/components/table/table-column-select/utils.ts +59 -0
  55. package/src/components/table/table-operations/FuTableButton.vue +19 -0
  56. package/src/components/table/table-operations/FuTableMoreButton.vue +52 -0
  57. package/src/components/table/table-operations/FuTableOperations.vue +88 -0
  58. package/src/components/table/table-operations/index.ts +12 -0
  59. package/src/components/tabs/FuTabs.vue +84 -0
  60. package/src/components/tabs/index.ts +8 -0
  61. package/src/components/virtual-scroller/FuVirtualHorizontalScroll.js +96 -0
  62. package/src/components/virtual-scroller/FuVirtualScroll.js +15 -0
  63. package/src/components/virtual-scroller/FuVirtualVerticalScroll.js +95 -0
  64. package/src/components/virtual-scroller/index.js +10 -0
  65. package/src/hooks/index.ts +3 -0
  66. package/src/hooks/use-global-config/index.ts +32 -0
  67. package/src/hooks/use-locale/index.ts +47 -0
  68. package/src/index.ts +19 -0
  69. package/src/locale/index.ts +12 -0
  70. package/src/locale/lang/en.ts +58 -0
  71. package/src/locale/lang/zh-cn.ts +58 -0
  72. package/src/locale/lang/zh-tw.ts +58 -0
  73. package/src/styles/common/config.scss +5 -0
  74. package/src/styles/common/function.scss +81 -0
  75. package/src/styles/common/mixins.scss +85 -0
  76. package/src/styles/common/variables.scss +28 -0
  77. package/src/styles/components/filter-bar.scss +227 -0
  78. package/src/styles/components/read-write-switch.scss +6 -0
  79. package/src/styles/components/search-bar.scss +285 -0
  80. package/src/styles/components/speed-dial.scss +107 -0
  81. package/src/styles/components/split-pane.scss +111 -0
  82. package/src/styles/components/steps.scss +110 -0
  83. package/src/styles/components/table.scss +105 -0
  84. package/src/styles/components/tabs.scss +10 -0
  85. package/src/styles/components/virtual-scroller.scss +24 -0
  86. package/src/styles/index.scss +11 -0
  87. package/src/tools/theme.ts +23 -0
  88. package/src/tools/time.ts +30 -0
  89. package/src/tools/utils.ts +60 -0
@@ -0,0 +1,165 @@
1
+ <template>
2
+ <div class="fu-search-bar">
3
+ <div class="fu-search-bar__content">
4
+ <!-- :size="configSize" -->
5
+ <fu-complex-search ref="complex" :components="components" @change="change" v-if="showComplex" @close="closePopover">
6
+ <slot name="complex" />
7
+ </fu-complex-search>
8
+ <!-- :size="configSize" -->
9
+ <fu-search-conditions :conditions="conditions" @change="change" v-if="showComplex"/>
10
+ <!-- :size="configSize" -->
11
+ <fu-quick-search :use-icon="!showComplex" :placeholder="placeholder" v-model="quick"
12
+ @change="quickChange" v-if="useQuickSearch"/>
13
+ </div>
14
+ <div class="fu-search-bar__buttons">
15
+ <slot name="buttons">
16
+ <!-- :size="configSize" -->
17
+ <fu-search-bar-button icon="Close" @click="clean" :tooltip="t('fu.search_bar.clean')"
18
+ v-if="showClean" />
19
+ <!-- :size="configSize" -->
20
+ <fu-search-bar-button icon="Refresh" @click="refresh"
21
+ :tooltip="t('fu.search_bar.refresh')" v-if="showRefresh" />
22
+ <slot />
23
+ </slot>
24
+ </div>
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import { ref, computed, useSlots } from "vue";
30
+ import FuQuickSearch from "./FuQuickSearch.vue";
31
+ import FuComplexSearch from "./FuComplexSearch.vue";
32
+ import FuSearchBarButton from "@/components/search-bar/FuSearchBarButton.vue";
33
+ import FuSearchConditions from "@/components/search-bar/FuSearchContions.vue";
34
+ import ComplexCondition from "@/components/search-bar/store";
35
+ import { useLocale } from "@/hooks"
36
+ defineOptions({ name: "FuSearchBar" });
37
+ const { t } = useLocale()
38
+
39
+ const slots = useSlots()
40
+
41
+ const props = defineProps({
42
+ quickKey: {
43
+ type: String,
44
+ default: "quick"
45
+ },
46
+ quickPlaceholder: String,
47
+ useCleanButton: { // 是否使用清除按钮
48
+ type: Boolean,
49
+ default: true
50
+ },
51
+ useRefreshButton: { // 是否使用刷新按钮
52
+ type: Boolean,
53
+ default: false
54
+ },
55
+ useQuickSearch: { // 是否使用快速搜索
56
+ type: Boolean,
57
+ default: true
58
+ },
59
+ components: Array,
60
+ })
61
+
62
+ const emit = defineEmits(["close", "exec"])
63
+
64
+
65
+ const quick = ref("")
66
+ const conditions = ref([])
67
+
68
+ // refs
69
+
70
+ const complex = ref();
71
+
72
+ // target覆盖source相同的field
73
+ function merge(source: any, target: any) {
74
+ let conditions = source.concat(target)
75
+ let conditionMap = new Map()
76
+
77
+ for (let condition of conditions) {
78
+ conditionMap.set(condition.field, condition)
79
+ }
80
+ let result: any = [];
81
+ conditionMap.forEach(c => {
82
+ result.push(c)
83
+ })
84
+
85
+ return result
86
+ }
87
+
88
+
89
+
90
+
91
+ function closePopover() {
92
+ emit("close")
93
+ }
94
+ function setConditions(conditions: any) {
95
+ conditions.value = complex.value.createConditions(conditions)
96
+
97
+ if (props.useQuickSearch && conditions[props.quickKey] !== undefined) {
98
+ quick.value = conditions[props.quickKey].value
99
+ quickChange(quick.value)
100
+ } else {
101
+ refresh()
102
+ }
103
+ }
104
+ function quickChange(value: string, e?: any) {
105
+ if (value) {
106
+ const field = props.quickKey
107
+ const valueLabel = value
108
+ // *****此处有问题,待解决
109
+ conditions.value = merge(conditions.value, [new ComplexCondition({ field, value, valueLabel })])
110
+ exec(e)
111
+ quick.value = "";
112
+ }
113
+ }
114
+ function change(conditions: any) {
115
+ conditions.value = merge(conditions.value, conditions)
116
+ exec()
117
+ }
118
+ function clean() {
119
+ quick.value = ""
120
+ conditions.value = []
121
+ emit("exec", conditions.value)
122
+ }
123
+ function refresh() {
124
+ complex.value.close()
125
+ exec()
126
+ }
127
+ function exec() {
128
+ // 只有快速搜索
129
+ if (!showComplex) {
130
+ emit("exec", quick.value )
131
+ return
132
+ }
133
+ emit("exec", condition.value )
134
+ }
135
+
136
+ const placeholder = computed(() => {
137
+ return props.quickPlaceholder ? props.quickPlaceholder : t('fu.search_bar.search')
138
+ });
139
+ const showComplex = computed(() => {
140
+ if (slots?.complex) return true
141
+ return props.components?.length > 0;
142
+ });
143
+
144
+ const showClean = computed(() => {
145
+ return props.useCleanButton && showComplex && (conditions.value.length > 0 || quick.value)
146
+ });
147
+
148
+ const showRefresh = computed(() => {
149
+ return props.useRefreshButton && showComplex
150
+ });
151
+
152
+ const condition = computed(() => {
153
+ const condition = {}
154
+ if (conditions.value.length > 0) {
155
+ conditions.value.forEach(c => {
156
+ const { field, operator, value } = c
157
+ condition[c.field] = { field, operator, value }
158
+ })
159
+ }
160
+
161
+ return condition
162
+ });
163
+
164
+
165
+ </script>
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <el-tooltip :content="tooltip" :disabled="!tooltip">
3
+ <!-- :size="configSize" -->
4
+ <el-button class="fu-search-bar-button" circle v-bind="$attrs" />
5
+ <!-- <slot></slot> -->
6
+ <!-- *****element问题 加上插槽 空的情况下渲染多出一个span标签问题 待考虑 -->
7
+ </el-tooltip>
8
+ </template>
9
+ <script setup lang="ts">
10
+ defineOptions({ name: "FuSearchBarButton" });
11
+ defineProps({
12
+ tooltip: String
13
+ });
14
+ </script>
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <!-- , 'fu-search-conditions--' + configSize -->
3
+ <div :class="['fu-search-conditions']">
4
+ <div class="fu-search-conditions__item" v-for="(condition, index) in conditions" :key="index">
5
+ <div v-if="condition.label">{{ condition.label }}</div>
6
+ <div v-if="condition.operatorLabel">{{ condition.operatorLabel }}</div>
7
+ <div class="condition-value">{{ condition.valueLabel }}</div>
8
+ <i class="el-icon-close condition-remove" @click="remove(index)" />
9
+ </div>
10
+ </div>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ const props = defineProps({
15
+ conditions: Array
16
+ })
17
+ const emit = defineEmits(["change"])
18
+
19
+ function remove(index: number) {
20
+ props.conditions.splice(index, 1)
21
+ emit("change", props.conditions)
22
+ }
23
+
24
+ </script>
@@ -0,0 +1,13 @@
1
+ import FuSearchBar from "./FuSearchBar.vue"
2
+ import FuQuickSearch from "./FuQuickSearch.vue"
3
+ import FuSearchBarButton from "./FuSearchBarButton.vue"
4
+ // import FuComplexComponents from "./complex-components"
5
+
6
+ import type { App } from 'vue'
7
+ FuSearchBar.install = (app: App): void => {
8
+ app.component(FuSearchBar.name, FuSearchBar)
9
+ app.component(FuSearchBarButton.name, FuSearchBarButton)
10
+ app.component(FuQuickSearch.name, FuQuickSearch)
11
+ // app.use(FuComplexComponents.install)
12
+ };
13
+ export default FuSearchBar;
@@ -0,0 +1,25 @@
1
+ export interface Options {
2
+ field: string
3
+ label: string
4
+ operator?: string
5
+ operatorLabel: string
6
+ value: string
7
+ valueLabel: string
8
+ }
9
+
10
+ export default class ComplexCondition {
11
+ field: string
12
+ label: string
13
+ operator?: string
14
+ operatorLabel: string
15
+ value: string
16
+ valueLabel: string
17
+ constructor(options: Options) {
18
+ this.field = options.field
19
+ this.label = options.label
20
+ this.operator = options.operator
21
+ this.operatorLabel = options.operatorLabel
22
+ this.value = options.value
23
+ this.valueLabel = options.valueLabel || options.value
24
+ }
25
+ }
@@ -0,0 +1,280 @@
1
+ <template>
2
+ <!-- v-outside-click="outsideClickClose" -->
3
+ <div class="fu-speed-dial" :style="style">
4
+ <div class="fu-speed-dial__content">
5
+ <slot name="fab">
6
+ <fu-speed-dial-button v-bind="buttonProps" @click="click" @mousedown="mousedown" />
7
+ </slot>
8
+ <div :style="contentPosition">
9
+ <slot>
10
+ <fu-speed-dial-item v-for="(item, index) in items" :index="index" :key="index" v-bind="item"
11
+ @click="itemClick" />
12
+ </slot>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ </template>
17
+
18
+
19
+ <script setup lang="ts">
20
+ import { reactive, ref, watch, getCurrentInstance, onMounted, computed, provide, useSlots } from "vue";
21
+ import type { CSSProperties } from 'vue'
22
+ // import OutsideClick from "element-ui/src/utils/clickoutside"
23
+ // directives: { OutsideClick },
24
+ import FuSpeedDialButton from "@/components/speed-dial/FuSpeedDialButton.vue"
25
+ import FuSpeedDialItem from "@/components/speed-dial/FuSpeedDialItem.vue"
26
+ defineOptions({ name: "FuSpeedDial" });
27
+ const props = defineProps({
28
+ id: String,
29
+ value: Boolean,
30
+ type: {
31
+ type: String,
32
+ default: "primary"
33
+ },
34
+ items: Array,
35
+ size: {
36
+ type: String,
37
+ default: "default",
38
+ validator: (value: string) => ["big", "default", "medium", "small"].includes(value)
39
+ },
40
+ direction: {
41
+ type: String,
42
+ default: "top",
43
+ validator: (value: string) => ["top", "bottom", "left", "right"].includes(value)
44
+ },
45
+ icon: {
46
+ type: String,
47
+ default: "el-icon-plus"
48
+ },
49
+ activeIcon: {
50
+ type: String,
51
+ default: "el-icon-close"
52
+ },
53
+ movable: {
54
+ type: Boolean,
55
+ default: false
56
+ },
57
+ position: {
58
+ type: String,
59
+ validator: (value: string) => ["absolute", "fixed"].includes(value)
60
+ },
61
+ left: String,
62
+ top: String,
63
+ right: String,
64
+ bottom: String,
65
+ zIndex: {
66
+ type: [String, Number],
67
+ default: 99
68
+ },
69
+ itemClickClose: {
70
+ type: Boolean,
71
+ default: true
72
+ },
73
+ outsideClose: {
74
+ type: Boolean,
75
+ default: true
76
+ },
77
+ manual: {
78
+ type: Boolean,
79
+ default: false
80
+ },
81
+ localKey: String,
82
+ sizeOptions: {
83
+ type: Object,
84
+ default: () => {
85
+ return {
86
+ big: {
87
+ fab: { size: 56, fontSize: "18px" },
88
+ item: { size: 40, spacing: 0, titleFontSize: "14px", buttonFontSize: "18px" }
89
+ },
90
+ default: {
91
+ fab: { size: 40, fontSize: "16px" },
92
+ item: { size: 32, spacing: 0, titleFontSize: "14px", buttonFontSize: "16px" }
93
+ },
94
+ medium: {
95
+ fab: { size: 36, fontSize: "14px" },
96
+ item: { size: 28, spacing: 0, titleFontSize: "12px", buttonFontSize: "14px" }
97
+ },
98
+ small: {
99
+ fab: { size: 32, fontSize: "12px" },
100
+ item: { size: 24, spacing: 0, titleFontSize: "12px", buttonFontSize: "12px" }
101
+ },
102
+ }
103
+ }
104
+ },
105
+ })
106
+
107
+ const emit = defineEmits(["close", "outside-click", "click"])
108
+
109
+ const slots = useSlots()
110
+ const instance = getCurrentInstance()
111
+
112
+ const { zIndex, position, left, top, right, bottom } = props
113
+
114
+ const active = ref(false)
115
+ const moving = ref(false)
116
+ const style = reactive({ zIndex, position, left, top, right, bottom }) as any
117
+ const updateStyle = function () {
118
+ style.value = { zIndex, position, left, top, right, bottom }
119
+ }
120
+
121
+ provide("FuSpeedDial", instance)
122
+
123
+ watch(() => props.value, (v) => {
124
+ active.value = v
125
+ })
126
+ watch(() => props.position, updateStyle)
127
+ watch(() => props.zIndex, updateStyle)
128
+ watch(() => props.left, updateStyle)
129
+ watch(() => props.right, updateStyle)
130
+ watch(() => props.top, updateStyle)
131
+ watch(() => props.bottom, updateStyle)
132
+
133
+ const saveKey = computed(() => {
134
+ return "Fu-SD-" + props.localKey
135
+ })
136
+ const hashChildren = computed(() => {
137
+ if (props.items && props.items.length > 0) {
138
+ return true
139
+ }
140
+ return slots && slots.default
141
+ })
142
+ const config = computed(() => {
143
+ return props.sizeOptions[props.size] || props.sizeOptions["default"]
144
+ })
145
+ const buttonProps = computed(() => {
146
+ let type = props.type
147
+ let rotate = true
148
+ let activeValue = active.value
149
+ let size = config.value.fab.size + "px"
150
+ let fontSize = config.value.fab.fontSize
151
+ let icon = props.activeIcon === props.icon ? props.icon : active.value ? props.activeIcon : props.icon
152
+ return { type, rotate, active: activeValue, size, fontSize, icon }
153
+ })
154
+ const spacing = computed(() => {
155
+ let spacing = config.value.item.spacing || 0
156
+ spacing += (config.value.fab.size - config.value.item.size) / 2
157
+ return spacing
158
+ })
159
+
160
+ const contentPosition = computed(() => {
161
+ let position = config.value.fab.size + spacing.value
162
+ if (["top", "left"].includes(props.direction)) {
163
+ position = -config.value.fab.size - spacing.value
164
+ }
165
+
166
+ let style: CSSProperties = { position: "absolute", zIndex: props.zIndex }
167
+ if (["top", "bottom"].includes(props.direction)) {
168
+ style.top = position + "px"
169
+ } else {
170
+ style.top = 0
171
+ style.left = position + "px"
172
+ }
173
+ return style
174
+ })
175
+
176
+ function toggle(active?: any) {
177
+ if (!moving.value && hashChildren.value) {
178
+ active.value = active === undefined ? !active.value : active
179
+ }
180
+ }
181
+
182
+ // function outsideClickClose() {
183
+ // if (props.outsideClose && !props.manual) {
184
+ // toggle(false)
185
+ // }
186
+ // emit("outside-click", [props.id, active.value])
187
+ // }
188
+ function click(e: Event) {
189
+ if (!props.manual) {
190
+ toggle()
191
+ }
192
+ emit("click", [props.id, active.value], e)
193
+ }
194
+ function mousedown() {
195
+ if (moving.value) {
196
+ document.addEventListener('mousemove', mousemove)
197
+ document.addEventListener('mouseup', mouseup)
198
+ }
199
+ }
200
+ function mousemove(e: MouseEvent) {
201
+ moving.value = true
202
+ if (props.position === "fixed") {
203
+ const el = instance.vnode.el as HTMLElement
204
+ const rect = el.getBoundingClientRect()
205
+ let left = e.clientX - rect.width / 2
206
+ let top = e.clientY - rect.height / 2
207
+ style.value.left = left + 'px'
208
+ style.value.top = top + 'px'
209
+ delete style.value.right
210
+ delete style.value.bottom
211
+ }
212
+
213
+ if (props.position === "absolute") {
214
+ const { offsetLeft, offsetTop, clientWidth, clientHeight, offsetParent } = this.$el
215
+ const maxWidth = offsetParent.clientWidth - clientWidth
216
+ const maxHeight = offsetParent.clientHeight - clientHeight
217
+
218
+ let left = offsetLeft + e.movementX
219
+ let top = offsetTop + e.movementY
220
+ if (left > 0 && left < maxWidth) {
221
+ style.value.left = left + 'px'
222
+ delete style.value.right
223
+ }
224
+ if (top > 0 && top < maxHeight) {
225
+ style.value.top = top + 'px'
226
+ delete style.value.bottom
227
+ }
228
+ }
229
+ }
230
+ function mouseup() {
231
+ writePosition()
232
+ document.removeEventListener('mousemove', mousemove)
233
+ document.removeEventListener('mouseup', mouseup)
234
+ setTimeout(() => moving.value = false)
235
+ }
236
+ function writePosition() {
237
+ if (props.localKey) {
238
+ localStorage.setItem(saveKey.value, JSON.stringify(style.value))
239
+ }
240
+ }
241
+ function readPosition() {
242
+ // *******????
243
+ // if (this.savePosition) {
244
+ let position = localStorage.getItem(saveKey.value)
245
+ try {
246
+ localStorage.getItem(saveKey.value)
247
+ if (position) {
248
+ style.value = JSON.parse(position)
249
+ }
250
+ } catch (e) {
251
+ console.warn(saveKey.value + " error", e)
252
+ }
253
+ // }
254
+ }
255
+ function itemClick(arg: any, e: any) {
256
+ console.log(arg)
257
+ const { index } = arg
258
+ if (index !== undefined) {
259
+ const item = props.items[index];
260
+ if (item.click && typeof item.click === "function") return item.click(arg, e)
261
+ }
262
+ }
263
+
264
+ function close() {
265
+ if (props.itemClickClose && !props.manual) {
266
+ toggle(false)
267
+ }
268
+ emit("close", [props.id, active.value])
269
+ }
270
+
271
+ onMounted(() => {
272
+ readPosition()
273
+ })
274
+
275
+
276
+ defineExpose({
277
+ close
278
+ })
279
+
280
+ </script>
@@ -0,0 +1,88 @@
1
+ <template>
2
+ <div class="fu-speed-dial-action-button">
3
+ <div v-if="title" class="fu-speed-dial-action-button__title" :style="titleSize">
4
+ <slot name="title">
5
+ <div class="fu-speed-dial-action-button__text" :class="titleClass" :style="titleStyle" @click="click">{{
6
+ title }}
7
+ </div>
8
+ </slot>
9
+ </div>
10
+ <slot>
11
+ <fu-speed-dial-button :class="buttonClass" v-bind="buttonProps" :icon="icon" @click="click"/>
12
+ </slot>
13
+ </div>
14
+ </template>
15
+
16
+ <script setup lang="ts">
17
+ import { inject, computed } from 'vue'
18
+ import type { CSSProperties } from 'vue'
19
+ import FuSpeedDialButton from "@/components/speed-dial/FuSpeedDialButton.vue";
20
+
21
+ const props = defineProps({
22
+ index: Number,
23
+ icon: {
24
+ type: String,
25
+ default: "el-icon-plus"
26
+ },
27
+ titleClass: String,
28
+ titleBgColor: String,
29
+ titleColor: String,
30
+ buttonClass: String,
31
+ bgColor: String,
32
+ color: String,
33
+ title: [String, Number]
34
+ })
35
+
36
+ const emit = defineEmits(["click"])
37
+ const FuSpeedDial = inject('FuSpeedDial')
38
+
39
+ const config =computed(()=>{
40
+ return FuSpeedDial.config;
41
+ })
42
+
43
+ const direction =computed(()=>{
44
+ return FuSpeedDial.direction;
45
+ })
46
+ const clickClose =computed(()=>{
47
+ return FuSpeedDial.clickClose;
48
+ })
49
+
50
+ const titleSize =computed(()=>{
51
+ let size = config.value.fab.size + "px";
52
+ let style: CSSProperties = {position: "absolute", height: size};
53
+ if (["top", "bottom"].includes(direction.value)) {
54
+ style['text-align'] = "right"
55
+ style['right'] = size
56
+ } else {
57
+ style['text-align'] = "center"
58
+ style['min-width'] = size
59
+ if (props.index % 2 === 0) {
60
+ style.top = size
61
+ } else {
62
+ style.top = "-" + size
63
+ }
64
+ }
65
+ return style;
66
+ })
67
+
68
+ const titleStyle =computed(()=>{
69
+ let backgroundColor = props.titleBgColor;
70
+ let color = props.titleColor
71
+ let fontSize = config.value.item.titleFontSize
72
+ return {backgroundColor, color, fontSize}
73
+ })
74
+
75
+ const buttonProps =computed(()=>{
76
+ let backgroundColor = props.bgColor;
77
+ let color = props.color
78
+ let fontSize = config.value.item.buttonFontSize
79
+ let size = config.value.item.size + "px";
80
+ return {backgroundColor, color, fontSize, size}
81
+ })
82
+
83
+ function click(e: Event) {
84
+ const {index, title} = props
85
+ emit("click", {index, title}, e);
86
+ FuSpeedDial.close();
87
+ }
88
+ </script>
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <div :class="[
3
+ 'fu-speed-dial-button',
4
+ 'fu-speed-dial-button--' + type,
5
+ {
6
+ 'fu-speed-dial-button--rotate': rotate,
7
+ 'is-disabled': disabled,
8
+ 'is-active': active,
9
+ }, ]"
10
+ :style="{
11
+ width: size,
12
+ height: size,
13
+ backgroundColor: backgroundColor,
14
+ color: color,
15
+ fontSize: fontSize }">
16
+ <slot>
17
+ <i :class="icon" />
18
+ </slot>
19
+ </div>
20
+ </template>
21
+
22
+ <script setup lang="ts">
23
+ import { validateType } from "@/tools/theme"
24
+ const props = defineProps({
25
+ type: {
26
+ type: String,
27
+ default: "default",
28
+ validator: validateType
29
+ },
30
+ rotate: Boolean,
31
+ disabled: Boolean,
32
+ active: Boolean,
33
+ icon: String,
34
+ size: {
35
+ type: String,
36
+ default: "32px"
37
+ },
38
+ backgroundColor: String,
39
+ color: String,
40
+ fontSize: String
41
+ })
42
+ </script>