@didaoktv/didaoui-uniapp 1.0.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/LICENSE +21 -0
- package/README.md +89 -0
- package/components/dd-action-sheet/dd-action-sheet.vue +207 -0
- package/components/dd-alert/dd-alert.vue +240 -0
- package/components/dd-avatar/dd-avatar.vue +168 -0
- package/components/dd-backtop/dd-backtop.vue +75 -0
- package/components/dd-badge/dd-badge.vue +150 -0
- package/components/dd-button/dd-button.vue +215 -0
- package/components/dd-capsule-button/dd-capsule-button.vue +109 -0
- package/components/dd-card/dd-card.vue +155 -0
- package/components/dd-cell/dd-cell.vue +201 -0
- package/components/dd-cell-group/dd-cell-group.vue +56 -0
- package/components/dd-champion-card/dd-champion-card.vue +258 -0
- package/components/dd-checkbox/dd-checkbox.vue +145 -0
- package/components/dd-collapse/dd-collapse.vue +63 -0
- package/components/dd-collapse-item/dd-collapse-item.vue +154 -0
- package/components/dd-count-down/dd-count-down.vue +163 -0
- package/components/dd-date-picker/dd-date-picker.vue +253 -0
- package/components/dd-dialog/dd-dialog.vue +264 -0
- package/components/dd-divider/dd-divider.vue +104 -0
- package/components/dd-drawer/dd-drawer.vue +214 -0
- package/components/dd-dropdown-item/dd-dropdown-item.vue +203 -0
- package/components/dd-dropdown-menu/dd-dropdown-menu.vue +177 -0
- package/components/dd-empty-state/dd-empty-state.vue +140 -0
- package/components/dd-feature-grid/dd-feature-grid.vue +139 -0
- package/components/dd-field/dd-field.vue +240 -0
- package/components/dd-icon/dd-icon.vue +464 -0
- package/components/dd-image/dd-image.vue +158 -0
- package/components/dd-input/dd-input.vue +172 -0
- package/components/dd-list-cell/dd-list-cell.vue +152 -0
- package/components/dd-loading/dd-loading.vue +187 -0
- package/components/dd-loadmore/dd-loadmore.vue +152 -0
- package/components/dd-mini-program-navbar/dd-mini-program-navbar.vue +245 -0
- package/components/dd-modal/dd-modal.vue +286 -0
- package/components/dd-navigation/dd-navigation.vue +134 -0
- package/components/dd-overlay/dd-overlay.vue +114 -0
- package/components/dd-picker/dd-picker.vue +203 -0
- package/components/dd-popover/dd-popover.vue +190 -0
- package/components/dd-popover-item/dd-popover-item.vue +88 -0
- package/components/dd-popup/dd-popup.vue +243 -0
- package/components/dd-progress/dd-progress.vue +255 -0
- package/components/dd-pull-refresh/dd-pull-refresh.vue +232 -0
- package/components/dd-radio/dd-radio.vue +129 -0
- package/components/dd-rate/dd-rate.vue +133 -0
- package/components/dd-room-card/dd-room-card.vue +309 -0
- package/components/dd-search-bar/dd-search-bar.vue +176 -0
- package/components/dd-segmented-tab/dd-segmented-tab.vue +187 -0
- package/components/dd-skeleton/dd-skeleton.vue +184 -0
- package/components/dd-slider/dd-slider.vue +227 -0
- package/components/dd-stat-card/dd-stat-card.vue +174 -0
- package/components/dd-step/dd-step.vue +188 -0
- package/components/dd-stepper/dd-stepper.vue +171 -0
- package/components/dd-steps/dd-steps.vue +61 -0
- package/components/dd-sticky/dd-sticky.vue +132 -0
- package/components/dd-swipe/dd-swipe.vue +146 -0
- package/components/dd-swipe-action/dd-swipe-action.vue +248 -0
- package/components/dd-swipe-item/dd-swipe-item.vue +27 -0
- package/components/dd-swipeable-tab/dd-swipeable-tab.vue +202 -0
- package/components/dd-switch/dd-switch.vue +106 -0
- package/components/dd-tabbar/dd-tabbar.vue +112 -0
- package/components/dd-tabbar-item/dd-tabbar-item.vue +122 -0
- package/components/dd-tag/dd-tag.vue +178 -0
- package/components/dd-toast/dd-toast.vue +195 -0
- package/components/dd-top-navbar/dd-top-navbar.vue +184 -0
- package/components/dd-upload/dd-upload.vue +187 -0
- package/index.ts +127 -0
- package/libs/utils.ts +106 -0
- package/package.json +58 -0
- package/scss/_functions.scss +68 -0
- package/scss/_mixins.scss +154 -0
- package/scss/_reset.scss +30 -0
- package/scss/_variables.scss +317 -0
- package/uni.scss +4 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 帝到KTV
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @didaoktv/didaoui-uniapp
|
|
2
|
+
|
|
3
|
+
> 帝到KTV UniApp 组件库 — 帝王金 · 皇家蓝 · 抖音商城风
|
|
4
|
+
|
|
5
|
+
专为 KTV 场景打造的 UniApp 组件库。
|
|
6
|
+
|
|
7
|
+
## 特性
|
|
8
|
+
|
|
9
|
+
- **帝王级配色** — 帝王金 `#F5A623` + 皇家蓝 `#2D4BA0` 双主色,暗色主题默认
|
|
10
|
+
- **玻璃拟态设计** — 多层级玻璃拟态效果,打造高端夜店沉浸感
|
|
11
|
+
- **61 个精心打磨的组件** — 覆盖表单、导航、布局、数据展示、浮层反馈、交互六大类
|
|
12
|
+
- **Vue3 + TypeScript** — 完整类型定义,Composition API
|
|
13
|
+
- **多端兼容** — H5 / 微信小程序 / 抖音小程序 / Android / iOS
|
|
14
|
+
|
|
15
|
+
## 安装
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @didaoktv/didaoui-uniapp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 快速开始
|
|
22
|
+
|
|
23
|
+
### 全局引入
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { createSSRApp } from 'vue'
|
|
27
|
+
import App from './App.vue'
|
|
28
|
+
import DdktvUI from '@didaoktv/didaoui-uniapp'
|
|
29
|
+
import '@didaoktv/didaoui-uniapp/uni.scss'
|
|
30
|
+
|
|
31
|
+
export function createApp() {
|
|
32
|
+
const app = createSSRApp(App)
|
|
33
|
+
app.use(DdktvUI)
|
|
34
|
+
return { app }
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 按需引入
|
|
39
|
+
|
|
40
|
+
```vue
|
|
41
|
+
<script setup lang="ts">
|
|
42
|
+
import { DdButton, DdInput } from '@didaoktv/didaoui-uniapp'
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<dd-button type="primary">预订包房</dd-button>
|
|
47
|
+
<dd-input v-model="value" placeholder="请输入" />
|
|
48
|
+
</template>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 组件分类
|
|
52
|
+
|
|
53
|
+
| 分类 | 数量 | 组件 |
|
|
54
|
+
| ----- | -- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
|
+
| 表单输入 | 13 | Button, Input, Field, Switch, Checkbox, Radio, Stepper, SearchBar, Slider, DatePicker, Picker, Rate, Upload |
|
|
56
|
+
| 导航 | 12 | Navigation, TopNavbar, SwipeableTab, SegmentedTab, Drawer, Tabbar, TabbarItem, Backtop, Collapse, CollapseItem, DropdownMenu, DropdownItem |
|
|
57
|
+
| 布局 | 4 | Card, RoomCard, FeatureGrid, Sticky |
|
|
58
|
+
| 数据展示 | 16 | Tag, StatCard, ChampionCard, Avatar, Badge, ListCell, Cell, CellGroup, CountDown, Divider, Image, Progress, Skeleton, EmptyState, Step, Steps |
|
|
59
|
+
| 浮层反馈 | 11 | Modal, ActionSheet, Toast, Alert, Loading, Dialog, Overlay, Popup, Popover, PopoverItem, SwipeAction |
|
|
60
|
+
| 交互 | 3 | Swipe, SwipeItem, PullRefresh |
|
|
61
|
+
| 小程序专属 | 2 | CapsuleButton, MiniProgramNavbar |
|
|
62
|
+
|
|
63
|
+
## 设计规范
|
|
64
|
+
|
|
65
|
+
### 色彩系统
|
|
66
|
+
|
|
67
|
+
- **帝王金** `#F5A623` — 主操作、强调、高光
|
|
68
|
+
- **皇家蓝** `#2D4BA0` — 辅助色、深色基底
|
|
69
|
+
- **星空黑** `#0A0A0A` — 页面底色
|
|
70
|
+
- 语义色: success `#4CAF50` / warning `#F9A825` / error `#E53935` / info `#00BCD4`
|
|
71
|
+
|
|
72
|
+
### 字体
|
|
73
|
+
|
|
74
|
+
- 主字体: 'Noto Sans SC', sans-serif
|
|
75
|
+
- 展示字体: 'Playfair Display', serif
|
|
76
|
+
- 等宽字体: 'JetBrains Mono', monospace
|
|
77
|
+
- 字号阶梯: 12 / 14 / 16 / 18 / 20 / 24 / 32 px
|
|
78
|
+
|
|
79
|
+
### 圆角
|
|
80
|
+
|
|
81
|
+
2 / 4 / 8 / 12 / 16 / 9999 px (Vant 对齐小圆角)
|
|
82
|
+
|
|
83
|
+
### 间距
|
|
84
|
+
|
|
85
|
+
4 / 8 / 12 / 16 / 24 / 32 / 48 / 64 px (8pt 基础网格)
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
[MIT](./LICENSE) © 帝到KTV
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="dd-action-sheet">
|
|
3
|
+
<view
|
|
4
|
+
class="dd-action-sheet__mask"
|
|
5
|
+
:class="{ 'dd-action-sheet__mask--show': modelValue }"
|
|
6
|
+
@click="onMaskClick"
|
|
7
|
+
></view>
|
|
8
|
+
<view class="dd-action-sheet__panel" :class="{ 'dd-action-sheet__panel--show': modelValue }">
|
|
9
|
+
<view class="dd-action-sheet__handle"></view>
|
|
10
|
+
<view v-if="title" class="dd-action-sheet__title">
|
|
11
|
+
<text class="dd-action-sheet__title-text">{{ title }}</text>
|
|
12
|
+
</view>
|
|
13
|
+
|
|
14
|
+
<view class="dd-action-sheet__grid">
|
|
15
|
+
<view
|
|
16
|
+
v-for="(item, i) in items"
|
|
17
|
+
:key="i"
|
|
18
|
+
class="dd-action-sheet__item"
|
|
19
|
+
:style="{ width: 100 / columns + '%' }"
|
|
20
|
+
@click="onSelect(item, i)"
|
|
21
|
+
>
|
|
22
|
+
<view class="dd-action-sheet__icon">
|
|
23
|
+
<dd-icon v-if="item.icon" :name="item.icon" class="dd-action-sheet__icon-text" />
|
|
24
|
+
<text v-else class="dd-action-sheet__icon-text">{{ item.name.charAt(0) }}</text>
|
|
25
|
+
</view>
|
|
26
|
+
<text class="dd-action-sheet__name">{{ item.name }}</text>
|
|
27
|
+
</view>
|
|
28
|
+
</view>
|
|
29
|
+
|
|
30
|
+
<view v-if="showCancel" class="dd-action-sheet__cancel" @click="onClose">
|
|
31
|
+
<text class="dd-action-sheet__cancel-text">{{ cancelText }}</text>
|
|
32
|
+
</view>
|
|
33
|
+
<view class="dd-action-sheet__safe-bottom"></view>
|
|
34
|
+
</view>
|
|
35
|
+
</view>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<script setup lang="ts">
|
|
39
|
+
import DdIcon from '../dd-icon/dd-icon.vue'
|
|
40
|
+
|
|
41
|
+
interface ActionItem {
|
|
42
|
+
name: string
|
|
43
|
+
icon?: string
|
|
44
|
+
color?: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface Props {
|
|
48
|
+
modelValue?: boolean
|
|
49
|
+
items?: ActionItem[]
|
|
50
|
+
columns?: number
|
|
51
|
+
title?: string
|
|
52
|
+
showCancel?: boolean
|
|
53
|
+
cancelText?: string
|
|
54
|
+
closeOnClickModal?: boolean
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
58
|
+
modelValue: false,
|
|
59
|
+
items: () => [],
|
|
60
|
+
columns: 4,
|
|
61
|
+
title: '',
|
|
62
|
+
showCancel: true,
|
|
63
|
+
cancelText: '取消',
|
|
64
|
+
closeOnClickModal: true,
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const emit = defineEmits<{
|
|
68
|
+
(e: 'update:modelValue', val: boolean): void
|
|
69
|
+
(e: 'select', item: ActionItem, index: number): void
|
|
70
|
+
(e: 'close'): void
|
|
71
|
+
}>()
|
|
72
|
+
|
|
73
|
+
function close() {
|
|
74
|
+
emit('update:modelValue', false)
|
|
75
|
+
emit('close')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function onMaskClick() {
|
|
79
|
+
if (!props.closeOnClickModal) return
|
|
80
|
+
close()
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function onSelect(item: ActionItem, index: number) {
|
|
84
|
+
emit('select', item, index)
|
|
85
|
+
close()
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function onClose() {
|
|
89
|
+
close()
|
|
90
|
+
}
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<style lang="scss" scoped>
|
|
94
|
+
@import '../../scss/variables';
|
|
95
|
+
@import '../../scss/mixins';
|
|
96
|
+
|
|
97
|
+
.dd-action-sheet {
|
|
98
|
+
&__mask {
|
|
99
|
+
position: fixed;
|
|
100
|
+
inset: 0;
|
|
101
|
+
background: $dd-color-overlay-strong;
|
|
102
|
+
opacity: 0;
|
|
103
|
+
visibility: hidden;
|
|
104
|
+
z-index: 1000;
|
|
105
|
+
@include dd-transition(opacity 0.3s, visibility 0.3s);
|
|
106
|
+
|
|
107
|
+
&--show {
|
|
108
|
+
opacity: 1;
|
|
109
|
+
visibility: visible;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ponytail: glassmorphism 背景 (dd-glass),区别于 modal 的实心 elevated 背景
|
|
114
|
+
&__panel {
|
|
115
|
+
position: fixed;
|
|
116
|
+
left: 0;
|
|
117
|
+
right: 0;
|
|
118
|
+
bottom: 0;
|
|
119
|
+
transform: translateY(100%);
|
|
120
|
+
z-index: 1001;
|
|
121
|
+
@include dd-glass;
|
|
122
|
+
border-radius: $dd-radius-2xl $dd-radius-2xl 0 0;
|
|
123
|
+
padding: $dd-space-3 $dd-space-4 $dd-space-4;
|
|
124
|
+
@include dd-transition(transform 0.3s ease-out);
|
|
125
|
+
|
|
126
|
+
&--show {
|
|
127
|
+
transform: translateY(0);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
&__handle {
|
|
132
|
+
width: 72rpx;
|
|
133
|
+
height: 8rpx;
|
|
134
|
+
border-radius: $dd-radius-full;
|
|
135
|
+
background: rgba(255, 255, 255, 0.3);
|
|
136
|
+
margin: 8rpx auto 16rpx;
|
|
137
|
+
opacity: 0.6;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
&__title {
|
|
141
|
+
text-align: center;
|
|
142
|
+
margin-bottom: $dd-space-3;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
&__title-text {
|
|
146
|
+
font-size: $dd-font-size-h4;
|
|
147
|
+
font-weight: $dd-font-weight-h4;
|
|
148
|
+
color: $dd-text-primary;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
&__grid {
|
|
152
|
+
display: flex;
|
|
153
|
+
flex-wrap: wrap;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
&__item {
|
|
157
|
+
display: flex;
|
|
158
|
+
flex-direction: column;
|
|
159
|
+
align-items: center;
|
|
160
|
+
padding: $dd-space-2 0;
|
|
161
|
+
box-sizing: border-box;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
&__icon {
|
|
165
|
+
width: 96rpx;
|
|
166
|
+
height: 96rpx;
|
|
167
|
+
border-radius: 50%;
|
|
168
|
+
background: $dd-gradient-primary;
|
|
169
|
+
@include dd-flex-center;
|
|
170
|
+
@include dd-glow(gold);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
&__icon-text {
|
|
174
|
+
font-size: 44rpx;
|
|
175
|
+
font-weight: 700;
|
|
176
|
+
color: $dd-color-white;
|
|
177
|
+
line-height: 1;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
&__name {
|
|
181
|
+
margin-top: 8rpx;
|
|
182
|
+
font-size: $dd-font-size-caption;
|
|
183
|
+
color: $dd-text-secondary;
|
|
184
|
+
max-width: 128rpx;
|
|
185
|
+
@include dd-ellipsis(1);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
&__cancel {
|
|
189
|
+
margin-top: $dd-space-3;
|
|
190
|
+
height: 96rpx;
|
|
191
|
+
border-radius: $dd-radius-xl;
|
|
192
|
+
background: $dd-surface-container-high;
|
|
193
|
+
@include dd-flex-center;
|
|
194
|
+
@include dd-hairline-top($dd-border-strong);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
&__cancel-text {
|
|
198
|
+
font-size: $dd-font-size-body;
|
|
199
|
+
color: $dd-text-primary;
|
|
200
|
+
font-weight: $dd-font-weight-body;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
&__safe-bottom {
|
|
204
|
+
@include dd-safe-area-bottom;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
</style>
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="dd-alert">
|
|
3
|
+
<view
|
|
4
|
+
class="dd-alert__mask"
|
|
5
|
+
:class="{ 'dd-alert__mask--show': modelValue }"
|
|
6
|
+
@click="onMaskClick"
|
|
7
|
+
></view>
|
|
8
|
+
<view class="dd-alert__card" :class="{ 'dd-alert__card--show': modelValue }">
|
|
9
|
+
<view class="dd-alert__icon" :class="[`dd-alert__icon--${type}`]">
|
|
10
|
+
<dd-icon :name="iconName" class="dd-alert__icon-text" />
|
|
11
|
+
</view>
|
|
12
|
+
<text v-if="title" class="dd-alert__title">{{ title }}</text>
|
|
13
|
+
<text v-if="message" class="dd-alert__message">{{ message }}</text>
|
|
14
|
+
<view class="dd-alert__actions" :class="{ 'dd-alert__actions--single': !showCancel }">
|
|
15
|
+
<view v-if="showCancel" class="dd-alert__btn dd-alert__btn--cancel" @click="onCancel">
|
|
16
|
+
<text class="dd-alert__btn-text dd-alert__btn-text--cancel">{{ cancelText }}</text>
|
|
17
|
+
</view>
|
|
18
|
+
<view class="dd-alert__btn dd-alert__btn--confirm" @click="onConfirm">
|
|
19
|
+
<text class="dd-alert__btn-text dd-alert__btn-text--confirm">{{ confirmText }}</text>
|
|
20
|
+
</view>
|
|
21
|
+
</view>
|
|
22
|
+
</view>
|
|
23
|
+
</view>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<script setup lang="ts">
|
|
27
|
+
import { computed } from 'vue'
|
|
28
|
+
import DdIcon from '../dd-icon/dd-icon.vue'
|
|
29
|
+
|
|
30
|
+
type AlertType = 'info' | 'success' | 'warning' | 'error' | 'confirm'
|
|
31
|
+
|
|
32
|
+
interface Props {
|
|
33
|
+
modelValue?: boolean
|
|
34
|
+
type?: AlertType
|
|
35
|
+
title?: string
|
|
36
|
+
message?: string
|
|
37
|
+
showCancel?: boolean
|
|
38
|
+
confirmText?: string
|
|
39
|
+
cancelText?: string
|
|
40
|
+
closeOnClickModal?: boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
44
|
+
modelValue: false,
|
|
45
|
+
type: 'info',
|
|
46
|
+
title: '',
|
|
47
|
+
message: '',
|
|
48
|
+
showCancel: true,
|
|
49
|
+
confirmText: '确定',
|
|
50
|
+
cancelText: '取消',
|
|
51
|
+
closeOnClickModal: false,
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const emit = defineEmits<{
|
|
55
|
+
(e: 'update:modelValue', val: boolean): void
|
|
56
|
+
(e: 'confirm'): void
|
|
57
|
+
(e: 'cancel'): void
|
|
58
|
+
}>()
|
|
59
|
+
|
|
60
|
+
const iconName = computed(() => {
|
|
61
|
+
const map: Record<AlertType, string> = {
|
|
62
|
+
info: 'info',
|
|
63
|
+
success: 'success',
|
|
64
|
+
warning: 'warning',
|
|
65
|
+
error: 'fail',
|
|
66
|
+
confirm: 'question',
|
|
67
|
+
}
|
|
68
|
+
return map[props.type]
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
function close() {
|
|
72
|
+
emit('update:modelValue', false)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function onConfirm() {
|
|
76
|
+
emit('confirm')
|
|
77
|
+
close()
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function onCancel() {
|
|
81
|
+
emit('cancel')
|
|
82
|
+
close()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function onMaskClick() {
|
|
86
|
+
// 默认 mask 不关闭,防止误操作
|
|
87
|
+
if (!props.closeOnClickModal) return
|
|
88
|
+
close()
|
|
89
|
+
}
|
|
90
|
+
</script>
|
|
91
|
+
|
|
92
|
+
<style lang="scss" scoped>
|
|
93
|
+
@import '../../scss/variables';
|
|
94
|
+
@import '../../scss/mixins';
|
|
95
|
+
|
|
96
|
+
.dd-alert {
|
|
97
|
+
&__mask {
|
|
98
|
+
position: fixed;
|
|
99
|
+
inset: 0;
|
|
100
|
+
background: $dd-color-overlay-strong;
|
|
101
|
+
opacity: 0;
|
|
102
|
+
visibility: hidden;
|
|
103
|
+
z-index: 1000;
|
|
104
|
+
@include dd-transition(opacity 0.25s, visibility 0.25s);
|
|
105
|
+
|
|
106
|
+
&--show {
|
|
107
|
+
opacity: 1;
|
|
108
|
+
visibility: visible;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&__card {
|
|
113
|
+
position: fixed;
|
|
114
|
+
top: 50%;
|
|
115
|
+
left: 50%;
|
|
116
|
+
transform: translate(-50%, -50%) scale(0.9);
|
|
117
|
+
opacity: 0;
|
|
118
|
+
visibility: hidden;
|
|
119
|
+
z-index: 1001;
|
|
120
|
+
width: 560rpx;
|
|
121
|
+
background: $dd-bg-elevated;
|
|
122
|
+
border: 1px solid $dd-border-default;
|
|
123
|
+
border-radius: $dd-radius-xl;
|
|
124
|
+
box-shadow: $dd-shadow-4;
|
|
125
|
+
padding: $dd-space-5 $dd-space-5 $dd-space-4;
|
|
126
|
+
display: flex;
|
|
127
|
+
flex-direction: column;
|
|
128
|
+
align-items: center;
|
|
129
|
+
@include dd-transition(transform 0.25s ease, opacity 0.25s ease, visibility 0.25s);
|
|
130
|
+
|
|
131
|
+
&--show {
|
|
132
|
+
transform: translate(-50%, -50%) scale(1);
|
|
133
|
+
opacity: 1;
|
|
134
|
+
visibility: visible;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
&__icon {
|
|
139
|
+
width: 112rpx;
|
|
140
|
+
height: 112rpx;
|
|
141
|
+
border-radius: 50%;
|
|
142
|
+
@include dd-flex-center;
|
|
143
|
+
margin-bottom: $dd-space-3;
|
|
144
|
+
|
|
145
|
+
&--info {
|
|
146
|
+
background: $dd-gradient-accent;
|
|
147
|
+
box-shadow: 0 0 40rpx rgba(45, 75, 160, 0.4);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
&--success {
|
|
151
|
+
background: $dd-gradient-success;
|
|
152
|
+
box-shadow: 0 0 40rpx rgba(76, 175, 80, 0.4);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
&--warning {
|
|
156
|
+
background: $dd-gradient-warning;
|
|
157
|
+
box-shadow: 0 0 40rpx rgba(249, 168, 37, 0.4);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
&--error {
|
|
161
|
+
background: $dd-gradient-error;
|
|
162
|
+
box-shadow: 0 0 40rpx rgba(229, 57, 53, 0.4);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
&--confirm {
|
|
166
|
+
background: $dd-gradient-primary-wide;
|
|
167
|
+
@include dd-glow(gold);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
&__icon-text {
|
|
172
|
+
color: $dd-color-white;
|
|
173
|
+
font-size: 56rpx;
|
|
174
|
+
font-weight: 700;
|
|
175
|
+
line-height: 1;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
&__title {
|
|
179
|
+
font-size: $dd-font-size-h4;
|
|
180
|
+
font-weight: $dd-font-weight-h4;
|
|
181
|
+
color: $dd-text-primary;
|
|
182
|
+
text-align: center;
|
|
183
|
+
line-height: $dd-line-height-h4;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
&__message {
|
|
187
|
+
margin-top: $dd-space-2;
|
|
188
|
+
font-size: $dd-font-size-body;
|
|
189
|
+
color: $dd-text-secondary;
|
|
190
|
+
text-align: center;
|
|
191
|
+
line-height: $dd-line-height-body;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
&__actions {
|
|
195
|
+
display: flex;
|
|
196
|
+
gap: $dd-space-3;
|
|
197
|
+
width: 100%;
|
|
198
|
+
margin-top: $dd-space-5;
|
|
199
|
+
|
|
200
|
+
&--single {
|
|
201
|
+
gap: 0;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
&__btn {
|
|
206
|
+
flex: 1;
|
|
207
|
+
border-radius: $dd-radius-full;
|
|
208
|
+
@include dd-flex-center;
|
|
209
|
+
|
|
210
|
+
&--cancel {
|
|
211
|
+
height: 88rpx;
|
|
212
|
+
background: $dd-neutral-700;
|
|
213
|
+
border: 1px solid $dd-border-strong;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
&--confirm {
|
|
217
|
+
height: 88rpx;
|
|
218
|
+
background: $dd-gradient-primary;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
&__actions--single &__btn--confirm {
|
|
223
|
+
height: 96rpx;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
&__btn-text {
|
|
227
|
+
font-size: $dd-font-size-body;
|
|
228
|
+
font-weight: $dd-font-weight-body;
|
|
229
|
+
|
|
230
|
+
&--cancel {
|
|
231
|
+
color: $dd-text-secondary;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
&--confirm {
|
|
235
|
+
color: $dd-neutral-900;
|
|
236
|
+
font-weight: 700;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
</style>
|