djm-ui 0.67.4 → 0.73.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 (46) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/README.md +38 -2
  3. package/dist/djm-ui.cjs +1625 -803
  4. package/dist/djm-ui.cjs.map +4 -4
  5. package/dist/djm-ui.css +1043 -41
  6. package/dist/djm-ui.esm.js +1581 -761
  7. package/dist/djm-ui.esm.js.map +4 -4
  8. package/dist/djm-ui.esm.min.js +439 -247
  9. package/dist/djm-ui.min.cjs +439 -247
  10. package/dist/djm-ui.min.css +2 -2
  11. package/dist/djm-ui.umd.js +1104 -285
  12. package/dist/djm-ui.umd.min.js +439 -247
  13. package/dist/mcp/manifest.json +12300 -0
  14. package/dist/mcp/server.js +90 -0
  15. package/package.json +12 -4
  16. package/src/components/drawer/index.js +4 -2
  17. package/src/components/icon/index.js +13 -1
  18. package/src/components/modal/index.js +4 -2
  19. package/src/components/progress/index.js +72 -3
  20. package/src/components/rich-editor/index.js +724 -61
  21. package/src/components/spin/index.js +69 -22
  22. package/src/index.js +2 -1
  23. package/src/locale/en-US.js +33 -1
  24. package/src/locale/zh-CN.js +33 -1
  25. package/src/styles/base.css +2 -3
  26. package/src/styles/components/button.css +2 -1
  27. package/src/styles/components/console.css +5 -0
  28. package/src/styles/components/content.css +517 -0
  29. package/src/styles/components/feedback.css +46 -0
  30. package/src/styles/components/form.css +5 -0
  31. package/src/styles/components/glass.css +58 -0
  32. package/src/styles/components/layout.css +326 -0
  33. package/src/styles/components/media-picker.css +3 -3
  34. package/src/styles/components/menu.css +2 -1
  35. package/src/styles/components/org-picker.css +1 -1
  36. package/src/styles/components/responsive.css +86 -0
  37. package/src/styles/components/rich-editor.css +206 -7
  38. package/src/styles/components/skin.css +54 -0
  39. package/src/styles/components/spin.css +156 -4
  40. package/src/styles/components/template.css +5 -0
  41. package/src/styles/index.css +2 -0
  42. package/src/styles/theme-dark.css +5 -0
  43. package/src/styles/tokens.css +13 -0
  44. package/src/theme/index.js +62 -0
  45. package/src/utils/sanitize-html.js +44 -6
  46. package/types/index.d.ts +17 -0
@@ -1,42 +1,89 @@
1
1
  /**
2
- * 加载中:单独使用是转圈提示;包裹内容时在内容上盖一层遮罩
3
- * 用法:<DjmSpin /> / <DjmSpin :spinning="loading" tip="加载中"><Table /></DjmSpin>
2
+ * 加载中:支持环形、点状、柱状、脉冲四种形态
3
+ * 用法:<DjmSpin /> / <DjmSpin type="dots" /> / <DjmSpin :spinning="loading" tip="加载中"><Table /></DjmSpin>
4
+ * 延迟显示:<DjmSpin :delay="300" />,避免快速请求时闪一下
4
5
  */
6
+ import { onBeforeUnmount, ref, watch } from 'vue'
7
+
5
8
  export default {
6
9
  name: 'DjmSpin',
7
10
  props: {
8
11
  spinning: { type: Boolean, default: true },
9
- size: { type: String, default: 'md' }, // sm | md | lg
10
- tip: { type: String, default: '' }
12
+ // sm | md | lg
13
+ size: { type: String, default: 'md' },
14
+ // ring 环形 / dots 点状 / bars 柱状 / pulse 脉冲
15
+ type: { type: String, default: 'ring' },
16
+ tip: { type: String, default: '' },
17
+ // 延迟多少毫秒后显示,0 表示立即
18
+ delay: { type: Number, default: 0 },
19
+ // 全屏加载:遮罩铺满视口
20
+ fullscreen: { type: Boolean, default: false },
21
+ // 自定义指示器颜色,默认跟随品牌色
22
+ color: { type: String, default: '' }
23
+ },
24
+ setup (props) {
25
+ const visible = ref(false)
26
+ let timer = null
27
+
28
+ function sync () {
29
+ window.clearTimeout(timer)
30
+ timer = null
31
+ if (!props.spinning) {
32
+ visible.value = false
33
+ return
34
+ }
35
+ if (props.delay > 0) {
36
+ timer = window.setTimeout(() => { visible.value = true }, props.delay)
37
+ } else {
38
+ visible.value = true
39
+ }
40
+ }
41
+
42
+ watch(() => [props.spinning, props.delay], sync, { immediate: true })
43
+ onBeforeUnmount(() => window.clearTimeout(timer))
44
+
45
+ return { visible }
11
46
  },
12
47
  computed: {
13
- // 有默认插槽即为包裹模式
14
48
  wrapped () {
15
49
  return !!this.$slots.default
50
+ },
51
+ rootClass () {
52
+ return [
53
+ 'djm-spin',
54
+ 'djm-spin-' + this.size,
55
+ {
56
+ 'djm-spin-wrap': this.wrapped && !this.fullscreen,
57
+ 'djm-spin-inline': !this.wrapped && !this.fullscreen,
58
+ 'djm-spin-fullscreen': this.fullscreen
59
+ }
60
+ ]
16
61
  }
17
62
  },
18
63
  template: `
19
64
  <div
20
- v-if="wrapped"
21
- class="djm-spin-wrap"
22
- :class="'djm-spin-' + size"
23
- :aria-busy="String(spinning)"
65
+ v-if="fullscreen || wrapped || visible"
66
+ :class="rootClass"
67
+ :aria-busy="String(visible)"
68
+ :role="visible ? 'status' : undefined"
69
+ :aria-label="!wrapped && !fullscreen && !tip && visible ? '加载中' : undefined"
24
70
  >
25
- <slot />
26
- <div v-if="spinning" class="djm-spin-mask" role="status">
27
- <span class="djm-spinner"></span>
71
+ <slot v-if="wrapped && !fullscreen" />
72
+ <div v-if="visible" class="djm-spin-mask">
73
+ <span class="djm-spin-indicator" :class="'djm-spin-' + type" :style="color ? { color } : null">
74
+ <slot name="indicator">
75
+ <i v-if="type === 'ring'" class="djm-spinner"></i>
76
+ <template v-else-if="type === 'dots'">
77
+ <i></i><i></i><i></i>
78
+ </template>
79
+ <template v-else-if="type === 'bars'">
80
+ <i></i><i></i><i></i><i></i>
81
+ </template>
82
+ <i v-else class="djm-spin-core"></i>
83
+ </slot>
84
+ </span>
28
85
  <span v-if="tip" class="djm-spin-tip">{{ tip }}</span>
29
86
  </div>
30
87
  </div>
31
- <span
32
- v-else
33
- class="djm-spin-inline"
34
- :class="'djm-spin-' + size"
35
- role="status"
36
- :aria-label="tip ? undefined : '加载中'"
37
- >
38
- <span class="djm-spinner"></span>
39
- <span v-if="tip" class="djm-spin-tip">{{ tip }}</span>
40
- </span>
41
88
  `
42
89
  }
package/src/index.js CHANGED
@@ -228,6 +228,7 @@ export { moveRows } from './utils/row-move.js'
228
228
  export { setLocale, getLocale, t, localeState } from './locale/index.js'
229
229
  export {
230
230
  theme, setTheme, toggleTheme, initTheme,
231
+ glass, setGlass,
231
232
  primaryColor, PRESET_COLORS, setPrimaryColor, resetPrimaryColor
232
233
  } from './theme/index.js'
233
234
  export { setPermissions, addPermissions, clearPermissions, hasPermission, vPermission } from './utils/permission.js'
@@ -345,7 +346,7 @@ const components = [
345
346
  DjmPageTabs
346
347
  ]
347
348
 
348
- export const version = '0.67.4'
349
+ export const version = '0.73.0'
349
350
 
350
351
  export function install (app, options = {}) {
351
352
  if (options.locale) setLocale(options.locale)
@@ -128,7 +128,6 @@ export default {
128
128
  'richEditor.italic': 'Italic',
129
129
  'richEditor.underline': 'Underline',
130
130
  'richEditor.strike': 'Strikethrough',
131
- 'richEditor.heading': 'Heading 2',
132
131
  'richEditor.paragraph': 'Paragraph',
133
132
  'richEditor.bulletList': 'Bullet list',
134
133
  'richEditor.numberList': 'Numbered list',
@@ -139,6 +138,39 @@ export default {
139
138
  'richEditor.redo': 'Redo',
140
139
  'richEditor.source': 'Source',
141
140
  'richEditor.visual': 'Visual',
141
+ 'richEditor.toolbar': 'Formatting toolbar',
142
+ 'richEditor.block': 'Paragraph style',
143
+ 'richEditor.heading1': 'Heading 1',
144
+ 'richEditor.heading2': 'Heading 2',
145
+ 'richEditor.heading3': 'Heading 3',
146
+ 'richEditor.quote': 'Quote',
147
+ 'richEditor.codeBlock': 'Code block',
148
+ 'richEditor.fontSize': 'Font size',
149
+ 'richEditor.defaultSize': 'Default',
150
+ 'richEditor.inlineCode': 'Inline code',
151
+ 'richEditor.textColor': 'Text color',
152
+ 'richEditor.bgColor': 'Background color',
153
+ 'richEditor.alignLeft': 'Align left',
154
+ 'richEditor.alignCenter': 'Align center',
155
+ 'richEditor.alignRight': 'Align right',
156
+ 'richEditor.alignJustify': 'Justify',
157
+ 'richEditor.outdent': 'Decrease indent',
158
+ 'richEditor.indent': 'Increase indent',
159
+ 'richEditor.unlink': 'Remove link',
160
+ 'richEditor.image': 'Insert image',
161
+ 'richEditor.singleImage': 'Insert single image',
162
+ 'richEditor.multiImage': 'Insert multiple images',
163
+ 'richEditor.mediaLibrary': 'Choose from media library',
164
+ 'richEditor.hr': 'Divider',
165
+ 'richEditor.fullscreen': 'Fullscreen',
166
+ 'richEditor.exitFullscreen': 'Exit fullscreen',
167
+ 'richEditor.wordCount': '{count} characters',
168
+ 'richEditor.uploading': 'Uploading {count} image(s)…',
169
+ 'richEditor.uploadFailed': 'Image upload failed',
170
+ 'richEditor.imageTypeError': 'Only image files are allowed',
171
+ 'richEditor.imageSizeError': 'Image must be smaller than {size}MB',
172
+ 'richEditor.imageUrlInvalid': 'Invalid image URL, insertion rejected',
173
+ 'richEditor.linkInvalid': 'Only http(s), mailto, tel or relative URLs are allowed',
142
174
 
143
175
  'approval.start': 'Started',
144
176
  'approval.cc': 'CC',
@@ -128,7 +128,6 @@ export default {
128
128
  'richEditor.italic': '斜体',
129
129
  'richEditor.underline': '下划线',
130
130
  'richEditor.strike': '删除线',
131
- 'richEditor.heading': '二级标题',
132
131
  'richEditor.paragraph': '正文',
133
132
  'richEditor.bulletList': '无序列表',
134
133
  'richEditor.numberList': '有序列表',
@@ -139,6 +138,39 @@ export default {
139
138
  'richEditor.redo': '重做',
140
139
  'richEditor.source': '源码',
141
140
  'richEditor.visual': '可视化',
141
+ 'richEditor.toolbar': '编辑工具栏',
142
+ 'richEditor.block': '段落格式',
143
+ 'richEditor.heading1': '标题 1',
144
+ 'richEditor.heading2': '标题 2',
145
+ 'richEditor.heading3': '标题 3',
146
+ 'richEditor.quote': '引用',
147
+ 'richEditor.codeBlock': '代码块',
148
+ 'richEditor.fontSize': '字号',
149
+ 'richEditor.defaultSize': '默认',
150
+ 'richEditor.inlineCode': '行内代码',
151
+ 'richEditor.textColor': '文字颜色',
152
+ 'richEditor.bgColor': '背景色',
153
+ 'richEditor.alignLeft': '左对齐',
154
+ 'richEditor.alignCenter': '居中',
155
+ 'richEditor.alignRight': '右对齐',
156
+ 'richEditor.alignJustify': '两端对齐',
157
+ 'richEditor.outdent': '减少缩进',
158
+ 'richEditor.indent': '增加缩进',
159
+ 'richEditor.unlink': '取消链接',
160
+ 'richEditor.image': '插入图片',
161
+ 'richEditor.singleImage': '插入单图',
162
+ 'richEditor.multiImage': '插入多图',
163
+ 'richEditor.mediaLibrary': '从素材库选择',
164
+ 'richEditor.hr': '分割线',
165
+ 'richEditor.fullscreen': '全屏',
166
+ 'richEditor.exitFullscreen': '退出全屏',
167
+ 'richEditor.wordCount': '共 {count} 字',
168
+ 'richEditor.uploading': '正在上传 {count} 张图片…',
169
+ 'richEditor.uploadFailed': '图片上传失败',
170
+ 'richEditor.imageTypeError': '只能上传图片文件',
171
+ 'richEditor.imageSizeError': '图片不能超过 {size}MB',
172
+ 'richEditor.imageUrlInvalid': '图片地址不合法,已拒绝插入',
173
+ 'richEditor.linkInvalid': '链接只支持 http(s)、mailto、tel 或站内相对地址',
142
174
 
143
175
  'approval.start': '发起',
144
176
  'approval.cc': '抄送',
@@ -13,8 +13,7 @@ body {
13
13
  body {
14
14
  background: var(--djm-bg);
15
15
  color: var(--djm-text);
16
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
17
- "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
16
+ font-family: var(--djm-font-sans);
18
17
  font-size: 13px;
19
18
  line-height: 1.5;
20
19
  -webkit-font-smoothing: antialiased;
@@ -95,7 +94,7 @@ a {
95
94
  }
96
95
 
97
96
  .djm-mono {
98
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
97
+ font-family: var(--djm-font-mono);
99
98
  font-size: 11.5px;
100
99
  font-variant-numeric: tabular-nums;
101
100
  }
@@ -141,7 +141,8 @@
141
141
  background: none;
142
142
  padding: 0;
143
143
  font-size: 12px;
144
- color: var(--djm-brand-600);
144
+ /* 品牌深色档:浅色底与暗色底都能过 4.5:1 */
145
+ color: var(--djm-brand-700);
145
146
  white-space: nowrap;
146
147
  }
147
148
 
@@ -204,6 +204,11 @@
204
204
  font-weight: 600;
205
205
  }
206
206
 
207
+ .djm-dict-item.djm-is-active .djm-dict-key {
208
+ /* 选中底色是浅蓝,灰字对比不够,跟着标题一起换成品牌深色 */
209
+ color: var(--djm-brand-700);
210
+ }
211
+
207
212
  .djm-dict-item.djm-is-active .djm-dict-count {
208
213
  border: 1px solid var(--djm-brand-200);
209
214
  background: var(--djm-surface);