webcake-ui-kit 1.1.28 → 1.1.30
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/package.json +7 -2
- package/src/components/alert/Alert.vue +3 -2
- package/src/components/alert/alert.css +29 -3
- package/src/components/date-picker/CalendarPanel.vue +154 -0
- package/src/components/date-picker/CalendarView.vue +104 -0
- package/src/components/date-picker/DatePicker.vue +587 -0
- package/src/components/date-picker/PanelFooter.vue +45 -0
- package/src/components/date-picker/PanelHeader.vue +102 -0
- package/src/components/date-picker/TimePanel.vue +98 -0
- package/src/components/date-picker/calendar-panel.css +36 -0
- package/src/components/date-picker/calendar-view.css +134 -0
- package/src/components/date-picker/calendar.js +116 -0
- package/src/components/date-picker/date-picker.css +95 -0
- package/src/components/date-picker/dayjs.js +34 -0
- package/src/components/date-picker/panel-footer.css +42 -0
- package/src/components/date-picker/panel-header.css +71 -0
- package/src/components/date-picker/time-panel.css +63 -0
- package/src/components/dropdown/Dropdown.vue +14 -2
- package/src/components/dropdown/DropdownMenuItems.vue +7 -3
- package/src/components/dropdown/dropdown-menu-items.css +4 -11
- package/src/components/input/input.css +7 -2
- package/src/components/menu/Menu.vue +7 -2
- package/src/components/menu/menu.css +0 -1
- package/src/components/message/Message.vue +72 -0
- package/src/components/message/MessageContainer.vue +200 -0
- package/src/components/message/message-container.css +108 -0
- package/src/components/message/message.css +69 -0
- package/src/components/message/message.js +133 -0
- package/src/components/progress/Progress.vue +42 -0
- package/src/components/progress/progress.css +15 -0
- package/src/components/radio/Radio.vue +1 -1
- package/src/components/radio-group/RadioGroup.vue +2 -2
- package/src/components/select/Select.vue +5 -1
- package/src/components/select/select.css +13 -7
- package/src/components/select-option/SelectOption.vue +6 -0
- package/src/components/select-option/select_option.css +20 -0
- package/src/components/table/Table.vue +434 -92
- package/src/components/table/table.css +178 -5
- package/src/components/tooltip/Tooltip.vue +6 -3
- package/src/floating/click-outside-mixin.js +21 -1
- package/src/index.js +5 -0
- package/src/styles/color_general.css +20 -12
- package/src/styles/raw_colors.css +4 -4
- package/src/styles/shadow.css +3 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
.ui-message {
|
|
2
|
+
pointer-events: auto;
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
gap: var(--spacing-sm);
|
|
6
|
+
max-width: 480px;
|
|
7
|
+
padding: var(--spacing-sm) var(--spacing-md);
|
|
8
|
+
background: var(--card);
|
|
9
|
+
border: 1px solid var(--border-primary);
|
|
10
|
+
border-radius: var(--rounded-xl);
|
|
11
|
+
box-shadow: var(--shadow-sonner);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.ui-message__icon {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
flex-shrink: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.ui-message__wrapper {
|
|
22
|
+
flex: 1;
|
|
23
|
+
min-width: 0;
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
gap: var(--spacing-2xs);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.ui-message__content {
|
|
30
|
+
color: var(--primary-fg);
|
|
31
|
+
font-family: var(--font-family-body);
|
|
32
|
+
font-size: var(--paragraph-small-font-size);
|
|
33
|
+
font-style: normal;
|
|
34
|
+
font-weight: 500;
|
|
35
|
+
line-height: var(--paragraph-small-line-height);
|
|
36
|
+
letter-spacing: var(--paragraph-small-letter-spacing, 0);
|
|
37
|
+
word-break: break-word;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.ui-message__description {
|
|
41
|
+
color: var(--muted-fg);
|
|
42
|
+
font-size: var(--paragraph-small-font-size);
|
|
43
|
+
font-family: var(--font-family-body);
|
|
44
|
+
font-style: normal;
|
|
45
|
+
font-weight: 400;
|
|
46
|
+
line-height: var(--paragraph-small-line-height);
|
|
47
|
+
letter-spacing: var(--paragraph-small-letter-spacing);
|
|
48
|
+
word-break: break-word;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.ui-message--success .ui-message__icon {
|
|
52
|
+
color: var(--positive);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.ui-message--error .ui-message__icon {
|
|
56
|
+
color: var(--destructive);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.ui-message--warning .ui-message__icon {
|
|
60
|
+
color: var(--warning);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.ui-message--info .ui-message__icon {
|
|
64
|
+
color: var(--infor);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.ui-message--loading .ui-message__icon {
|
|
68
|
+
color: var(--primary-fg);
|
|
69
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Global message service — an Ant-Design-style singleton.
|
|
2
|
+
//
|
|
3
|
+
// Usage:
|
|
4
|
+
// import { wkMessage } from 'webcake-ui-kit'
|
|
5
|
+
// wkMessage.success('Saved')
|
|
6
|
+
// const hide = wkMessage.loading('Uploading...') // sticky; call hide() to dismiss
|
|
7
|
+
// wkMessage.config({ placement: 'bottom', maxCount: 3, duration: 5000 })
|
|
8
|
+
//
|
|
9
|
+
// A single MessageContainer is lazily mounted to document.body the first time a
|
|
10
|
+
// message is shown; consumers never render it themselves.
|
|
11
|
+
//
|
|
12
|
+
// Dual-compat note: the library ships raw SFCs consumed by both Vue 2.7 and
|
|
13
|
+
// Vue 3.4. We namespace-import `vue` (which never errors on a missing member)
|
|
14
|
+
// and branch at runtime to avoid static import errors in Vue 2.
|
|
15
|
+
// eslint-disable-next-line no-restricted-imports
|
|
16
|
+
import * as VueRuntime from 'vue'
|
|
17
|
+
import MessageContainer from './MessageContainer.vue'
|
|
18
|
+
|
|
19
|
+
const DEFAULTS = { duration: 3000, placement: 'top', offset: 24, maxCount: 0 }
|
|
20
|
+
|
|
21
|
+
let globalConfig = { ...DEFAULTS }
|
|
22
|
+
let app = null // Vue 3 application instance (needed for unmount)
|
|
23
|
+
let containerVm = null // MessageContainer instance we drive imperatively
|
|
24
|
+
let hostEl = null
|
|
25
|
+
|
|
26
|
+
function ensureContainer() {
|
|
27
|
+
if (containerVm) return containerVm
|
|
28
|
+
if (typeof document === 'undefined') return null
|
|
29
|
+
|
|
30
|
+
hostEl = document.createElement('div')
|
|
31
|
+
hostEl.setAttribute('data-wk-message-host', '')
|
|
32
|
+
document.body.appendChild(hostEl)
|
|
33
|
+
|
|
34
|
+
// Bypass strict static analysis in bundlers (e.g. Webpack 5)
|
|
35
|
+
const createAppKey = 'createApp'
|
|
36
|
+
const defaultKey = 'default'
|
|
37
|
+
|
|
38
|
+
if (typeof VueRuntime[createAppKey] === 'function') {
|
|
39
|
+
app = VueRuntime[createAppKey](MessageContainer)
|
|
40
|
+
containerVm = app.mount(hostEl)
|
|
41
|
+
} else {
|
|
42
|
+
const Vue = VueRuntime[defaultKey] || VueRuntime
|
|
43
|
+
const vm = new Vue({
|
|
44
|
+
render: h => h(MessageContainer)
|
|
45
|
+
}).$mount(hostEl)
|
|
46
|
+
containerVm = vm.$children[0]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
containerVm.configure(globalConfig)
|
|
50
|
+
return containerVm
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Accept either a config object, (content, optsObj), or (content, duration?, onClose?).
|
|
54
|
+
function toConfig(content, durationOrOpts, onClose) {
|
|
55
|
+
const cfg = content && typeof content === 'object' ? { ...content } : { content }
|
|
56
|
+
if (durationOrOpts && typeof durationOrOpts === 'object') {
|
|
57
|
+
Object.assign(cfg, durationOrOpts)
|
|
58
|
+
} else if (typeof durationOrOpts === 'function') {
|
|
59
|
+
cfg.onClose = durationOrOpts
|
|
60
|
+
} else {
|
|
61
|
+
if (durationOrOpts !== undefined) cfg.duration = durationOrOpts
|
|
62
|
+
if (onClose !== undefined) cfg.onClose = onClose
|
|
63
|
+
}
|
|
64
|
+
return cfg
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Show a message. Returns a function that dismisses it early.
|
|
68
|
+
function open(config) {
|
|
69
|
+
const vm = ensureContainer()
|
|
70
|
+
if (!vm) return function () {}
|
|
71
|
+
|
|
72
|
+
// Per-call placement/offset override (applied before add so the container
|
|
73
|
+
// is positioned correctly when the message enters).
|
|
74
|
+
if (config.placement != null || config.offset != null) {
|
|
75
|
+
vm.configure({
|
|
76
|
+
placement: config.placement,
|
|
77
|
+
offset: config.offset
|
|
78
|
+
})
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const type = config.type || 'info'
|
|
82
|
+
const duration = config.duration !== undefined ? config.duration : type === 'loading' ? 0 : globalConfig.duration
|
|
83
|
+
|
|
84
|
+
const key = vm.add({
|
|
85
|
+
key: config.key,
|
|
86
|
+
type,
|
|
87
|
+
content: config.content,
|
|
88
|
+
description: config.description,
|
|
89
|
+
action: config.action,
|
|
90
|
+
duration,
|
|
91
|
+
onClose: config.onClose
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
return function close() {
|
|
95
|
+
vm.remove(key)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function makeOpener(type) {
|
|
100
|
+
return function (content, duration, onClose) {
|
|
101
|
+
const cfg = toConfig(content, duration, onClose)
|
|
102
|
+
cfg.type = type
|
|
103
|
+
return open(cfg)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export const wkMessage = {
|
|
108
|
+
open,
|
|
109
|
+
success: makeOpener('success'),
|
|
110
|
+
error: makeOpener('error'),
|
|
111
|
+
info: makeOpener('info'),
|
|
112
|
+
warning: makeOpener('warning'),
|
|
113
|
+
loading: makeOpener('loading'),
|
|
114
|
+
// destroy(key) removes one message; destroy() with no key removes all.
|
|
115
|
+
destroy(key) {
|
|
116
|
+
if (!containerVm) return
|
|
117
|
+
if (key === undefined) {
|
|
118
|
+
containerVm.clear()
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
containerVm.remove(key)
|
|
122
|
+
},
|
|
123
|
+
destroyAll() {
|
|
124
|
+
if (containerVm) containerVm.clear()
|
|
125
|
+
},
|
|
126
|
+
// Update global defaults (placement/offset/maxCount/duration). Applies live.
|
|
127
|
+
config(options) {
|
|
128
|
+
globalConfig = { ...globalConfig, ...options }
|
|
129
|
+
if (containerVm) containerVm.configure(globalConfig)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export default wkMessage
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ui-progress" role="progressbar" :aria-valuemin="0" :aria-valuemax="max" :aria-valuenow="clampedValue">
|
|
3
|
+
<div class="ui-progress__bar" :style="{ width: percent + '%' }" />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
export default {
|
|
9
|
+
name: 'Progress',
|
|
10
|
+
|
|
11
|
+
props: {
|
|
12
|
+
// Current progress value, clamped to the [0, max] range.
|
|
13
|
+
value: {
|
|
14
|
+
type: Number,
|
|
15
|
+
default: 0
|
|
16
|
+
},
|
|
17
|
+
// Upper bound of the progress scale (value === max renders a full bar).
|
|
18
|
+
max: {
|
|
19
|
+
type: Number,
|
|
20
|
+
default: 100,
|
|
21
|
+
validator: function (v) {
|
|
22
|
+
return v > 0
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
emits: [],
|
|
28
|
+
|
|
29
|
+
computed: {
|
|
30
|
+
clampedValue() {
|
|
31
|
+
if (this.value < 0) return 0
|
|
32
|
+
if (this.value > this.max) return this.max
|
|
33
|
+
return this.value
|
|
34
|
+
},
|
|
35
|
+
percent() {
|
|
36
|
+
return (this.clampedValue / this.max) * 100
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<style src="./progress.css" scoped></style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.ui-progress {
|
|
2
|
+
position: relative;
|
|
3
|
+
width: 100%;
|
|
4
|
+
height: 6px;
|
|
5
|
+
overflow: hidden;
|
|
6
|
+
background: var(--accent-2);
|
|
7
|
+
border-radius: var(--rounded-xl);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.ui-progress__bar {
|
|
11
|
+
height: 100%;
|
|
12
|
+
background: var(--primary-fg);
|
|
13
|
+
border-radius: var(--rounded-md) 0 0 var(--rounded-md);
|
|
14
|
+
transition: width 0.2s ease;
|
|
15
|
+
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
:close-on-select="false"
|
|
9
9
|
@change="onMenuChange"
|
|
10
10
|
@close="onMenuClose"
|
|
11
|
+
:overlay-class-name="overlayClassName"
|
|
12
|
+
:overlay-style="overlayStyle"
|
|
11
13
|
>
|
|
12
14
|
<template #trigger="{ toggle, isOpen: open, attrs, triggerRef }">
|
|
13
15
|
<div
|
|
@@ -187,7 +189,9 @@ export default {
|
|
|
187
189
|
filterOption: {
|
|
188
190
|
type: Function,
|
|
189
191
|
default: null
|
|
190
|
-
}
|
|
192
|
+
},
|
|
193
|
+
overlayClassName: { type: [String, Array, Object], default: null },
|
|
194
|
+
overlayStyle: { type: [Object, Array], default: null }
|
|
191
195
|
},
|
|
192
196
|
|
|
193
197
|
emits: ['change', 'update:modelValue'],
|
|
@@ -154,28 +154,30 @@
|
|
|
154
154
|
|
|
155
155
|
/* — multiple mode — */
|
|
156
156
|
.ui-select--multiple {
|
|
157
|
-
height: 36px;
|
|
157
|
+
min-height: 36px;
|
|
158
|
+
height: auto;
|
|
158
159
|
align-items: center;
|
|
159
160
|
flex-wrap: wrap;
|
|
160
161
|
padding: var(--spacing-2xs) var(--spacing-sm) var(--spacing-2xs) var(--spacing-xs);
|
|
161
162
|
}
|
|
162
163
|
|
|
163
164
|
.ui-select--multiple.ui-select--lg {
|
|
164
|
-
height: 40px;
|
|
165
|
+
min-height: 40px;
|
|
165
166
|
height: auto;
|
|
166
|
-
padding: var(--spacing-
|
|
167
|
+
padding: var(--spacing-7) var(--spacing-md) var(--spacing-7) var(--spacing-xs);
|
|
167
168
|
align-items: center;
|
|
168
169
|
}
|
|
169
170
|
|
|
170
171
|
.ui-select--multiple.ui-select--sm {
|
|
171
|
-
height: 32px;
|
|
172
|
+
min-height: 32px;
|
|
172
173
|
height: auto;
|
|
173
|
-
padding: var(--spacing-
|
|
174
|
+
padding: var(--spacing-5) var(--spacing-xs);
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
.ui-select--multiple.ui-select--xs {
|
|
177
|
-
height: 28px;
|
|
178
|
-
|
|
178
|
+
min-height: 28px;
|
|
179
|
+
height: auto;
|
|
180
|
+
padding: var(--spacing-3) var(--spacing-6) var(--spacing-3) var(--spacing-2xs);
|
|
179
181
|
}
|
|
180
182
|
|
|
181
183
|
.ui-select--multiple .ui-select__chevron {
|
|
@@ -211,6 +213,10 @@
|
|
|
211
213
|
font-size: 14px;
|
|
212
214
|
}
|
|
213
215
|
|
|
216
|
+
.ui-select--multiple.ui-select--xs .ui-select__search::placeholder {
|
|
217
|
+
font-size: 12px;
|
|
218
|
+
}
|
|
219
|
+
|
|
214
220
|
.ui-select__search--single {
|
|
215
221
|
width: 100%;
|
|
216
222
|
flex: 1;
|
|
@@ -15,9 +15,15 @@
|
|
|
15
15
|
:aria-disabled="isDisabled ? 'true' : null"
|
|
16
16
|
@click="handleClick"
|
|
17
17
|
>
|
|
18
|
+
<span v-if="$slots.prefix" class="ui-select-option__prefix">
|
|
19
|
+
<slot name="prefix" />
|
|
20
|
+
</span>
|
|
18
21
|
<span class="ui-select-option--label">
|
|
19
22
|
<slot>{{ label || value }}</slot>
|
|
20
23
|
</span>
|
|
24
|
+
<span v-if="$slots.suffix" class="ui-select-option__suffix">
|
|
25
|
+
<slot name="suffix" />
|
|
26
|
+
</span>
|
|
21
27
|
<WkiCheck v-if="isSelected && isMultiMode" :size="16" color="var(--muted-fg)" />
|
|
22
28
|
</div>
|
|
23
29
|
</template>
|
|
@@ -78,3 +78,23 @@
|
|
|
78
78
|
text-overflow: ellipsis;
|
|
79
79
|
white-space: nowrap;
|
|
80
80
|
}
|
|
81
|
+
|
|
82
|
+
.ui-select-option__prefix {
|
|
83
|
+
display: inline-flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
flex-shrink: 0;
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
min-width: 20px;
|
|
89
|
+
height: 20px;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.ui-select-option--sm .ui-select-option__prefix {
|
|
93
|
+
min-width: 16px;
|
|
94
|
+
height: 16px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.ui-select-option__suffix {
|
|
98
|
+
font-size: var(--paragraph-mini-font-size);
|
|
99
|
+
line-height: var(--paragraph-mini-line-height);
|
|
100
|
+
}
|