@keyfunc/keybricks-ds 2.7.0 → 2.8.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 (40) hide show
  1. package/DEPLOY.md +3 -3
  2. package/DESIGN.md +8 -1
  3. package/INTEGRATION.md +18 -2
  4. package/_adherence.oxlintrc.json +0 -1
  5. package/_ds_bundle.js +293 -307
  6. package/{components/feedback → _vue-services}/MESSAGE_SERVICES.md +2 -2
  7. package/_vue-services/_internal/MessageBoxView.vue +150 -0
  8. package/{components/feedback → _vue-services}/_internal/service-utils.js +0 -12
  9. package/_vue-services/message.js +87 -0
  10. package/changelog.js +10 -1
  11. package/components/_cards/modal.card.html +8 -2
  12. package/components/_cards/table.card.html +10 -1
  13. package/components/_cards/toast.card.html +11 -1
  14. package/components/_cards/tree.card.html +22 -1
  15. package/components/data/Table.d.ts +5 -0
  16. package/components/data/Table.jsx +10 -5
  17. package/components/data/Table.vue +9 -3
  18. package/components/data/data.prompt.md +2 -0
  19. package/components/data/row-open.js +13 -0
  20. package/components/feedback/Modal.d.ts +58 -7
  21. package/components/feedback/Modal.jsx +46 -16
  22. package/components/feedback/Modal.vue +24 -6
  23. package/components/feedback/Toast.vue +3 -3
  24. package/components/feedback/ToastStack.vue +37 -4
  25. package/components/feedback/feedback.prompt.md +5 -1
  26. package/components/feedback/modal-behavior.js +50 -0
  27. package/components/navigation/Tree.d.ts +5 -1
  28. package/components/navigation/Tree.jsx +9 -7
  29. package/components/navigation/Tree.vue +7 -6
  30. package/components/navigation/navigation.prompt.md +2 -0
  31. package/index.html +3 -3
  32. package/package.json +6 -5
  33. package/site-nav.js +1 -1
  34. package/tokens/tokens.json +1 -1
  35. package/components/feedback/_internal/MessageBoxView.vue +0 -237
  36. package/components/feedback/_internal/MessageView.vue +0 -73
  37. package/components/feedback/message.js +0 -68
  38. /package/{components/feedback → _vue-services}/message-box.d.ts +0 -0
  39. /package/{components/feedback → _vue-services}/message-box.js +0 -0
  40. /package/{components/feedback → _vue-services}/message.d.ts +0 -0
@@ -1,73 +0,0 @@
1
- <script setup>
2
- import { computed, h, isVNode, onBeforeUnmount, onMounted, ref, watch } from 'vue'
3
- import Toast from '../Toast.vue'
4
- import Icon from '../../icons/Icon.vue'
5
- import { contentNode } from './service-utils.js'
6
-
7
- const props = defineProps({ options: { type: Object, required: true } })
8
- const emit = defineEmits(['close', 'height'])
9
- const root = ref(null)
10
- const tone = computed(() => props.options.type === 'error' ? 'danger' : props.options.type)
11
- const Content = () => contentNode(props.options.message, props.options.dangerouslyUseHTMLString)
12
- const CustomIcon = () => typeof props.options.icon === 'string'
13
- ? h(Icon, { name: props.options.icon, size: 16 })
14
- : isVNode(props.options.icon) ? props.options.icon : h(props.options.icon)
15
- let timer
16
- let observer
17
- let paused = false
18
- function stop() { clearTimeout(timer) }
19
- function start() {
20
- stop()
21
- if (!paused && props.options.duration > 0) timer = setTimeout(() => emit('close'), props.options.duration)
22
- }
23
- function onEscape(event) {
24
- if (event.key === 'Escape') emit('close')
25
- }
26
- watch(() => [props.options.restart, props.options.duration], start)
27
- onMounted(() => {
28
- start()
29
- const measure = () => emit('height', root.value.getBoundingClientRect().height)
30
- measure()
31
- if (typeof ResizeObserver !== 'undefined') {
32
- observer = new ResizeObserver(measure)
33
- observer.observe(root.value)
34
- }
35
- document.addEventListener('keydown', onEscape)
36
- })
37
- onBeforeUnmount(() => {
38
- stop()
39
- observer?.disconnect()
40
- document.removeEventListener('keydown', onEscape)
41
- })
42
- </script>
43
-
44
- <template>
45
- <div
46
- :id="options.id"
47
- ref="root"
48
- :class="['kb-message', options.customClass, { 'kb-message--center': options.center, 'kb-message--plain': options.plain }]"
49
- :role="options.type === 'error' || options.type === 'warning' ? 'alert' : 'status'"
50
- :style="{ position: 'fixed', top: `${options.top}px`, left: '50%', transform: 'translateX(-50%)', zIndex: options.zIndex ?? 'var(--z-toast)', maxWidth: '92vw' }"
51
- @mouseenter="paused = true; stop()"
52
- @mouseleave="paused = false; start()"
53
- @focusin="paused = true; stop()"
54
- @focusout="paused = false; start()"
55
- >
56
- <Toast
57
- :tone="tone"
58
- :dismissible="options.showClose"
59
- :close-label="options.closeLabel"
60
- :style="{ minWidth: 'min(280px, 92vw)', maxWidth: '100%', boxSizing: 'border-box', ...(options.plain ? { boxShadow: 'none' } : {}) }"
61
- @close="emit('close')"
62
- >
63
- <template v-if="options.icon" #icon><CustomIcon /></template>
64
- <Content />
65
- <span v-if="options.repeatNum > 1" class="kb-message__count"> × {{ options.repeatNum }}</span>
66
- </Toast>
67
- </div>
68
- </template>
69
-
70
- <style scoped>
71
- .kb-message--center { text-align: center; }
72
- .kb-message__count { color: var(--text-secondary); font-variant-numeric: tabular-nums; }
73
- </style>
@@ -1,68 +0,0 @@
1
- import { getCurrentInstance, isVNode, reactive } from 'vue'
2
- import MessageView from './_internal/MessageView.vue'
3
- import { mountService, resolveTarget } from './_internal/service-utils.js'
4
-
5
- const instances = []
6
- let seed = 0
7
- const normalize = value => typeof value === 'string' || typeof value === 'function' || isVNode(value)
8
- ? { message: value } : { ...value }
9
-
10
- /** Vue 消息服务;样式由 Toast 提供,业务错误脱敏仍由应用处理。 */
11
- export function Message(value = {}, appContext) {
12
- if (typeof document === 'undefined') return { close() {} }
13
- const options = { type: 'info', duration: 3000, offset: 16, ...Message.defaults, ...normalize(value) }
14
- const target = resolveTarget(options)
15
- if (options.grouping) {
16
- const existing = instances.find(item => item.target === target && item.options.message === options.message)
17
- if (existing) {
18
- existing.options.repeatNum++
19
- existing.options.type = options.type
20
- existing.options.restart++
21
- return existing.handle
22
- }
23
- }
24
- const state = reactive({ ...options, id: `kb-message-${++seed}`, repeatNum: 1, restart: 0, height: 0, top: options.offset })
25
- let dispose
26
- let closed = false
27
- const handle = { close() {
28
- if (closed) return
29
- closed = true
30
- instances.splice(instances.indexOf(entry), 1)
31
- dispose?.()
32
- reflow()
33
- options.onClose?.(handle)
34
- } }
35
- const entry = { options: state, handle, target }
36
- function reflow() {
37
- const tops = new Map()
38
- for (const item of instances) {
39
- const target = item.target
40
- item.options.top = Math.max(Number(item.options.offset) || 0, tops.get(target) || 0)
41
- tops.set(target, item.options.top + item.options.height + 16)
42
- }
43
- }
44
- instances.push(entry)
45
- try {
46
- dispose = mountService(MessageView, {
47
- options: state, onClose: handle.close,
48
- onHeight: height => { state.height = height; reflow() },
49
- }, options, appContext || getCurrentInstance()?.appContext)
50
- } catch (error) {
51
- instances.splice(instances.indexOf(entry), 1)
52
- reflow()
53
- throw error
54
- }
55
- reflow()
56
- return handle
57
- }
58
-
59
- for (const type of ['success', 'info', 'warning', 'error']) {
60
- Message[type] = (value, appContext) => Message({ ...normalize(value), type }, appContext)
61
- }
62
- Message.closeAll = type => {
63
- for (const entry of [...instances]) {
64
- if (!type || entry.options.type === type) entry.handle.close()
65
- }
66
- }
67
- export default Message
68
- Message.defaults = {}