geekplus-digital-ui 0.1.41 → 0.2.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 (85) hide show
  1. package/components/icons/filter-list-light.vue.d.ts +2 -0
  2. package/components/index.d.ts +1 -0
  3. package/components/index.js +13 -11
  4. package/components/table/index.d.ts +120 -0
  5. package/components/table/src/table-filter.vue.d.ts +2 -0
  6. package/components/table/src/table-wrapper.vue.d.ts +7 -0
  7. package/components/table/src/table.vue.d.ts +54 -0
  8. package/hooks/index.js +2 -2
  9. package/index.js +16 -15
  10. package/locale/index.js +6 -6
  11. package/locale/lang/en.d.ts +9 -0
  12. package/locale/lang/ja.d.ts +9 -0
  13. package/locale/lang/ko.d.ts +9 -0
  14. package/locale/lang/zh-cn.d.ts +9 -0
  15. package/locale/lang/zh-tw.d.ts +9 -0
  16. package/package.json +36 -34
  17. package/{components → packages/components}/copy/src/copy.js +3 -3
  18. package/{components → packages/components}/editor/src/code-collapse.js +7 -7
  19. package/packages/components/editor/src/code-collapse.vue_vue_type_style_index_0_scoped_04a8d31f_lang.css +1 -0
  20. package/packages/components/editor/src/editor.vue_vue_type_style_index_0_scoped_125d5f42_lang.css +1 -0
  21. package/{components → packages/components}/editor/src/editor2.js +8 -8
  22. package/{components → packages/components}/fold-text/src/fold-text.js +8 -8
  23. package/packages/components/fold-text/src/fold-text.vue_vue_type_style_index_0_scoped_f460d6d5_lang.css +1 -0
  24. package/{components → packages/components}/icon/src/icon.js +1 -1
  25. package/{components → packages/components}/icon-tip/src/icon-tip.js +5 -5
  26. package/packages/components/icon-tip/src/icon-tip.vue_vue_type_style_index_0_scoped_fd7f9264_lang.css +1 -0
  27. package/{components → packages/components}/icons/angle-down-light.js +1 -1
  28. package/{components → packages/components}/icons/angle-up-light.js +1 -1
  29. package/{components → packages/components}/icons/circle-exclamation-solid.js +1 -1
  30. package/{components → packages/components}/icons/circle-play-light.js +1 -1
  31. package/{components → packages/components}/icons/circle-xmark-light.js +1 -1
  32. package/{components → packages/components}/icons/copy-light.js +1 -1
  33. package/{components → packages/components}/icons/download-light.js +1 -1
  34. package/{components → packages/components}/icons/eye-light.js +1 -1
  35. package/{components → packages/components}/icons/file-light.js +1 -1
  36. package/packages/components/icons/filter-list-light.js +16 -0
  37. package/{components → packages/components}/icons/image-light.js +1 -1
  38. package/{components → packages/components}/icons/plus-light.js +1 -1
  39. package/{components → packages/components}/icons/trash-light.js +1 -1
  40. package/{components → packages/components}/inline-edit/src/inline-edit.js +5 -5
  41. package/packages/components/inline-edit/src/inline-edit.vue_vue_type_style_index_0_scoped_b066ddcd_lang.css +1 -0
  42. package/{components → packages/components}/search-form/src/search-form.js +7 -7
  43. package/packages/components/search-form/src/search-form.vue_vue_type_style_index_0_scoped_ff9cbf76_lang.css +1 -0
  44. package/{components → packages/components}/search-item/src/search-item.js +5 -5
  45. package/packages/components/search-item/src/search-item.vue_vue_type_style_index_0_scoped_a37eaef0_lang.css +1 -0
  46. package/packages/components/table/index.js +5 -0
  47. package/packages/components/table/src/table-filter.js +131 -0
  48. package/packages/components/table/src/table-filter.vue_vue_type_style_index_0_scoped_70a03e33_lang.css +1 -0
  49. package/packages/components/table/src/table-wrapper.js +53 -0
  50. package/packages/components/table/src/table.js +166 -0
  51. package/packages/components/table/src/table.vue_vue_type_style_index_0_scoped_a6c85ac1_lang.css +1 -0
  52. package/{components → packages/components}/upload/src/upload.js +16 -16
  53. package/packages/components/upload/src/upload.vue_vue_type_style_index_0_scoped_aef1e5b2_lang.css +1 -0
  54. package/packages/components/upload/src/upload.vue_vue_type_style_index_1_lang.css +1 -0
  55. package/{hooks → packages/hooks}/use-locale/index.js +1 -1
  56. package/{install.js → packages/install.js} +3 -3
  57. package/{locale → packages/locale}/lang/en.js +8 -0
  58. package/{locale → packages/locale}/lang/ja.js +8 -0
  59. package/{locale → packages/locale}/lang/ko.js +8 -0
  60. package/{locale → packages/locale}/lang/zh-cn.js +8 -0
  61. package/{locale → packages/locale}/lang/zh-tw.js +8 -0
  62. package/skills/use-geekplus-digital-ui/SKILL.md +245 -104
  63. package/components/editor/src/code-collapse.vue_vue_type_style_index_0_scoped_44e188d6_lang.css +0 -1
  64. package/components/editor/src/editor.vue_vue_type_style_index_0_scoped_9103e51e_lang.css +0 -1
  65. package/components/fold-text/src/fold-text.vue_vue_type_style_index_0_scoped_cc699234_lang.css +0 -1
  66. package/components/icon-tip/src/icon-tip.vue_vue_type_style_index_0_scoped_fe982c8e_lang.css +0 -1
  67. package/components/inline-edit/src/inline-edit.vue_vue_type_style_index_0_scoped_fc1016d4_lang.css +0 -1
  68. package/components/search-form/src/search-form.vue_vue_type_style_index_0_scoped_cea05b8f_lang.css +0 -1
  69. package/components/search-item/src/search-item.vue_vue_type_style_index_0_scoped_27c41622_lang.css +0 -1
  70. package/components/upload/src/upload.vue_vue_type_style_index_0_scoped_c4e16833_lang.css +0 -1
  71. package/components/upload/src/upload.vue_vue_type_style_index_1_lang.css +0 -1
  72. /package/{components → packages/components}/copy/index.js +0 -0
  73. /package/{components → packages/components}/copy/src/copy.vue_vue_type_style_index_0_scoped_80dabae9_lang.css +0 -0
  74. /package/{components → packages/components}/editor/index.js +0 -0
  75. /package/{components → packages/components}/editor/src/editor.css +0 -0
  76. /package/{components → packages/components}/fold-text/index.js +0 -0
  77. /package/{components → packages/components}/icon/index.js +0 -0
  78. /package/{components → packages/components}/icon/src/icon.vue_vue_type_style_index_0_scoped_29c845ca_lang.css +0 -0
  79. /package/{components → packages/components}/icon-tip/index.js +0 -0
  80. /package/{components → packages/components}/inline-edit/index.js +0 -0
  81. /package/{components → packages/components}/search-form/index.js +0 -0
  82. /package/{components → packages/components}/search-item/index.js +0 -0
  83. /package/{components → packages/components}/upload/index.js +0 -0
  84. /package/{hooks → packages/hooks}/use-activated/index.js +0 -0
  85. /package/{locale → packages/locale}/i18n.js +0 -0
@@ -1,7 +1,7 @@
1
1
  import { useLocale as e } from "../../../hooks/use-locale/index.js";
2
2
  import { useActivated as t } from "../../../hooks/use-activated/index.js";
3
- import "../../../hooks/index.js";
4
- import n from "../../../_virtual/_plugin-vue_export-helper.js";
3
+ import "../../../../hooks/index.js";
4
+ import n from "../../../../_virtual/_plugin-vue_export-helper.js";
5
5
  import r from "../../icons/angle-down-light.js";
6
6
  import i from "../../icons/angle-up-light.js";
7
7
  import a from "../../icon/index.js";
@@ -13,9 +13,9 @@ import ie from "../../icons/file-light.js";
13
13
  import ae from "../../icons/plus-light.js";
14
14
  import oe from "../../icons/trash-light.js";
15
15
  import se from "../../icons/image-light.js";
16
- import './upload.vue_vue_type_style_index_1_lang.css';import './upload.vue_vue_type_style_index_0_scoped_c4e16833_lang.css';/* empty css */
16
+ import './upload.vue_vue_type_style_index_1_lang.css';import './upload.vue_vue_type_style_index_0_scoped_aef1e5b2_lang.css';/* empty css */
17
17
  /* empty css */
18
- import "../../index.js";
18
+ import "../../../../components/index.js";
19
19
  import { isFunction as ce } from "lodash-es";
20
20
  import { Fragment as o, computed as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createTextVNode as f, createVNode as p, mergeModels as m, normalizeClass as le, normalizeStyle as h, onBeforeUnmount as ue, onMounted as de, openBlock as g, reactive as fe, ref as _, renderList as v, toDisplayString as y, unref as b, useModel as x, useTemplateRef as pe, watch as me, withCtx as S, withModifiers as he } from "vue";
21
21
  import { ElButton as C, ElDialog as ge, ElImage as _e, ElImageViewer as ve, ElLink as w, ElMessage as T, ElMessageBox as ye, ElProgress as E, ElUpload as be, useFormItem as xe } from "element-plus";
@@ -23,10 +23,10 @@ import { saveAs as Se } from "file-saver";
23
23
  //#region packages/components/upload/src/upload.vue
24
24
  var Ce = { class: "d-upload__preview" }, we = ["src"], Te = {
25
25
  key: 2,
26
- class: "header"
27
- }, Ee = ["onClick"], De = { class: "card-cover" }, Oe = ["innerHTML"], ke = { class: "file-row" }, Ae = {
26
+ class: "d-upload__header"
27
+ }, Ee = ["onClick"], De = { class: "d-upload__card-cover" }, Oe = ["innerHTML"], ke = { class: "d-upload__file-row" }, Ae = {
28
28
  key: 6,
29
- class: "expand-toggle"
29
+ class: "d-upload__expand-toggle"
30
30
  }, D = /* @__PURE__ */ n(/* @__PURE__ */ Object.assign({ name: "DUpload" }, {
31
31
  __name: "upload",
32
32
  props: /* @__PURE__ */ m({
@@ -283,7 +283,7 @@ var Ce = { class: "d-upload__preview" }, we = ["src"], Te = {
283
283
  ref: B,
284
284
  src: L.value,
285
285
  controls: "",
286
- class: "preview-video"
286
+ class: "d-upload__preview-video"
287
287
  }, null, 8, we)) : l("", !0)])]),
288
288
  _: 1
289
289
  }, 8, ["modelValue", "title"])) : l("", !0),
@@ -304,11 +304,11 @@ var Ce = { class: "d-upload__preview" }, we = ["src"], Te = {
304
304
  })) : l("", !0)])) : l("", !0),
305
305
  G.value ? l("", !0) : (g(), u("div", {
306
306
  key: 3,
307
- class: "card",
307
+ class: "d-upload__card",
308
308
  style: h(Ve.value)
309
309
  }, [(g(!0), u(o, null, v(H.value, (e, t) => (g(), u("div", {
310
310
  key: e.id || `${e.name}-${t}`,
311
- class: "card-item",
311
+ class: "d-upload__card-item",
312
312
  style: h(ze.value),
313
313
  onClick: (t) => nt(e)
314
314
  }, [Y(e) ? (g(), u(o, { key: 0 }, [q(e) ? (g(), c(b(_e), {
@@ -347,7 +347,7 @@ var Ce = { class: "d-upload__preview" }, we = ["src"], Te = {
347
347
  "show-text": !1
348
348
  }, null, 8, ["percentage"]))], 12, Ee))), 128)), W.value ? (g(), u("div", {
349
349
  key: 0,
350
- class: "card-item",
350
+ class: "d-upload__card-item",
351
351
  style: h(ze.value),
352
352
  onClick: X
353
353
  }, [p(b(a), null, {
@@ -356,16 +356,16 @@ var Ce = { class: "d-upload__preview" }, we = ["src"], Te = {
356
356
  })], 4)) : l("", !0)], 4)),
357
357
  W.value && n.showTip ? (g(), u("p", {
358
358
  key: 4,
359
- class: "tip",
359
+ class: "d-upload__tip",
360
360
  innerHTML: He.value
361
361
  }, null, 8, Oe)) : l("", !0),
362
362
  G.value ? (g(), u("div", {
363
363
  key: 5,
364
364
  style: h(Ve.value),
365
- class: "list"
365
+ class: "d-upload__list"
366
366
  }, [(g(!0), u(o, null, v(H.value, (e, t) => (g(), u("div", {
367
367
  key: e.id || `${e.name}-${t}`,
368
- class: "list-item"
368
+ class: "d-upload__list-item"
369
369
  }, [d("div", ke, [p(b(w), {
370
370
  type: "primary",
371
371
  underline: "never",
@@ -375,7 +375,7 @@ var Ce = { class: "d-upload__preview" }, we = ["src"], Te = {
375
375
  _: 2
376
376
  }, 1032, ["onClick"]), We(e) ? (g(), c(b(a), {
377
377
  key: 0,
378
- class: "remove-icon",
378
+ class: "d-upload__remove-icon",
379
379
  onClick: he((t) => Z(e), ["stop"])
380
380
  }, {
381
381
  default: S(() => [p(te)]),
@@ -410,6 +410,6 @@ var Ce = { class: "d-upload__preview" }, we = ["src"], Te = {
410
410
  }))])) : l("", !0)
411
411
  ], 2));
412
412
  }
413
- }), [["__scopeId", "data-v-c4e16833"]]);
413
+ }), [["__scopeId", "data-v-aef1e5b2"]]);
414
414
  //#endregion
415
415
  export { D as default };
@@ -0,0 +1 @@
1
+ .d-upload[data-v-aef1e5b2]{line-height:normal}.d-upload .d-upload__header[data-v-aef1e5b2]{align-items:center;gap:8px;width:100%;display:flex}.d-upload .d-upload__header .el-button[data-v-aef1e5b2]{margin:0}.d-upload.is-list[data-v-aef1e5b2],.d-upload.is-list .d-upload__list[data-v-aef1e5b2]{flex-direction:column;gap:8px;display:flex}.d-upload.is-list .d-upload__list .d-upload__list-item .d-upload__file-row[data-v-aef1e5b2]{align-items:center;gap:4px;display:flex;position:relative}.d-upload.is-list .d-upload__list .d-upload__list-item .d-upload__file-row[data-v-aef1e5b2] .el-link{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.d-upload.is-list .d-upload__list .d-upload__list-item .d-upload__file-row[data-v-aef1e5b2] .el-link .el-link__inner{display:inline}.d-upload.is-list .d-upload__list .d-upload__list-item .d-upload__file-row .d-upload__remove-icon[data-v-aef1e5b2]{cursor:pointer;color:var(--el-text-color-secondary);display:none}.d-upload.is-list .d-upload__list .d-upload__list-item .d-upload__file-row:hover .d-upload__remove-icon[data-v-aef1e5b2]{display:block}.d-upload.is-card[data-v-aef1e5b2],.d-upload.is-card .d-upload__card[data-v-aef1e5b2]{flex-wrap:wrap;gap:8px;display:flex}.d-upload.is-card .d-upload__card .d-upload__card-item[data-v-aef1e5b2]{box-sizing:border-box;border:1px solid var(--el-border-color);cursor:pointer;border-radius:4px;justify-content:center;align-items:center;font-size:16px;display:flex;position:relative;overflow:hidden}.d-upload.is-card .d-upload__card .d-upload__card-item .d-upload__card-cover[data-v-aef1e5b2]{background:var(--el-overlay-color);opacity:0;justify-content:center;align-items:center;gap:12px;width:100%;height:100%;display:flex;position:absolute;top:0;left:0}.d-upload.is-card .d-upload__card .d-upload__card-item .d-upload__card-cover .d-icon[data-v-aef1e5b2]{color:var(--el-color-white)}.d-upload.is-card .d-upload__card .d-upload__card-item .d-upload__card-cover[data-v-aef1e5b2]:hover{opacity:1}.d-upload.is-card .d-upload__card .el-image[data-v-aef1e5b2]{width:100%;height:100%}.d-upload.is-card .d-upload__card .el-image .el-image__error[data-v-aef1e5b2]{font-size:16px}.d-upload .d-upload__expand-toggle[data-v-aef1e5b2]{width:100%;display:flex}.d-upload .d-upload__expand-toggle[data-v-aef1e5b2] .el-link__inner{gap:4px}.d-upload .d-upload__tip[data-v-aef1e5b2]{width:100%;color:var(--el-text-color-regular);margin:0;font-size:12px}
@@ -0,0 +1 @@
1
+ .d-upload__preview{justify-content:center;height:calc(80vh - 120px);display:flex}.d-upload__preview .d-upload__preview-video{max-width:100%;height:100%}
@@ -1,5 +1,5 @@
1
1
  import { getLocale as e, setLocale as t, t as n } from "../../locale/i18n.js";
2
- import "../../locale/index.js";
2
+ import "../../../locale/index.js";
3
3
  //#region packages/hooks/use-locale/index.js
4
4
  var r = () => ({
5
5
  t: n,
@@ -1,7 +1,7 @@
1
1
  import { initI18n as e } from "./locale/i18n.js";
2
- import "./locale/index.js";
3
- import { components_exports as t } from "./components/index.js";
4
- import { setComponentRegistry as n, setGlobalConfig as r } from "./config/index.js";
2
+ import "../locale/index.js";
3
+ import { components_exports as t } from "../components/index.js";
4
+ import { setComponentRegistry as n, setGlobalConfig as r } from "../config/index.js";
5
5
  //#region packages/install.js
6
6
  var i = (i, a = {}) => {
7
7
  let { locale: o, config: s } = a;
@@ -18,6 +18,14 @@ var e = {
18
18
  expand: "Expand",
19
19
  collapse: "Collapse"
20
20
  },
21
+ table: {
22
+ columnSetting: "Column Settings",
23
+ reset: "Reset",
24
+ fixedLeft: "Fixed Left",
25
+ fixedRight: "Fixed Right",
26
+ columns: "Columns",
27
+ scrollTip: "Horizontal scroll: Shift + scroll wheel"
28
+ },
21
29
  upload: {
22
30
  lessThan: "Less than {size}MB",
23
31
  format: "Format {format}",
@@ -18,6 +18,14 @@ var e = {
18
18
  expand: "展開",
19
19
  collapse: "折りたたむ"
20
20
  },
21
+ table: {
22
+ columnSetting: "列設定",
23
+ reset: "リセット",
24
+ fixedLeft: "左に固定",
25
+ fixedRight: "右に固定",
26
+ columns: "通常列",
27
+ scrollTip: "横スクロール:Shift + スクロール"
28
+ },
21
29
  upload: {
22
30
  lessThan: "{size}MB 未満",
23
31
  format: "形式 {format}",
@@ -18,6 +18,14 @@ var e = {
18
18
  expand: "펼치기",
19
19
  collapse: "접기"
20
20
  },
21
+ table: {
22
+ columnSetting: "열 설정",
23
+ reset: "초기화",
24
+ fixedLeft: "왼쪽 고정",
25
+ fixedRight: "오른쪽 고정",
26
+ columns: "일반 열",
27
+ scrollTip: "가로 스크롤:Shift + 스크롤"
28
+ },
21
29
  upload: {
22
30
  lessThan: "{size}MB 이하",
23
31
  format: "형식 {format}",
@@ -18,6 +18,14 @@ var e = {
18
18
  expand: "展开",
19
19
  collapse: "收起"
20
20
  },
21
+ table: {
22
+ columnSetting: "列设置",
23
+ reset: "重置",
24
+ fixedLeft: "固定左侧",
25
+ fixedRight: "固定右侧",
26
+ columns: "普通列",
27
+ scrollTip: "横向滚动快捷方式:Shift + 滚轮滚动"
28
+ },
21
29
  upload: {
22
30
  lessThan: "小于 {size}MB",
23
31
  format: "格式 {format}",
@@ -18,6 +18,14 @@ var e = {
18
18
  expand: "展開",
19
19
  collapse: "收起"
20
20
  },
21
+ table: {
22
+ columnSetting: "欄位設定",
23
+ reset: "重置",
24
+ fixedLeft: "固定左側",
25
+ fixedRight: "固定右側",
26
+ columns: "普通欄",
27
+ scrollTip: "橫向捲動快捷鍵:Shift + 滾輪"
28
+ },
21
29
  upload: {
22
30
  lessThan: "小於 {size}MB",
23
31
  format: "格式 {format}",
@@ -1,104 +1,245 @@
1
- ---
2
- name: use-geekplus-digital-ui
3
- description: Use when developing Vue 3 features involving clipboard copy, file upload/preview/download, rich text editor, text collapse/expand, icon with tooltip, or inline editing. Triggers on keywords like 复制、上传、富文本、折叠文本、行内编辑、图标提示、copy, upload, editor, fold text, inline edit, icon tip.
4
- ---
5
-
6
- # Geekplus Digital UI 组件库
7
-
8
- **核心原则:不要重复造轮子。** 当功能已被 `geekplus-digital-ui` 覆盖时,必须使用现有组件,而非自行实现。
9
-
10
- 文档站点:https://ui.geekplus.cc/static/ui/
11
-
12
- ## 安装与引入
13
-
14
- ```bash
15
- npm install geekplus-digital-ui
16
- # 或
17
- pnpm add geekplus-digital-ui
18
- # 或
19
- yarn add geekplus-digital-ui
20
- ```
21
-
22
- ```js
23
- import { createApp } from 'vue';
24
- import ElementPlus from 'element-plus';
25
- import GeekplusDigitalUI from 'geekplus-digital-ui';
26
- import 'element-plus/dist/index.css';
27
- import 'element-plus/theme-chalk/dark/css-vars.css';
28
-
29
- const app = createApp(App);
30
- app.use(ElementPlus);
31
- app.use(GeekplusDigitalUI);
32
- app.mount('#app');
33
- ```
34
-
35
- Peer dependencies: `vue@^3.5.0`、`element-plus@^2.13.0`
36
-
37
- ## 组件速查表
38
-
39
- | 组件 | 标签 | 用途 |
40
- |------|------|------|
41
- | **Copy** | `<d-copy>` | 一键复制文本到剪贴板 |
42
- | **Upload** | `<d-upload>` | 文件上传/预览/下载,支持卡片和列表模式 |
43
- | **Editor** | `<d-editor>` | 富文本编辑器(基于 wangEditor-next) |
44
- | **FoldText** | `<d-fold-text>` | 多行文本折叠/展开 |
45
- | **IconTip** | `<d-icon-tip>` | 图标 + 悬浮提示 |
46
- | **InlineEdit** | `<d-inline-edit>` | 展示态/编辑态切换 |
47
-
48
- 详细 Props/Events/Slots API 请查阅文档:https://ui.geekplus.cc/static/ui/
49
-
50
- ## 使用规则
51
-
52
- 1. **禁止自行实现以下功能**,必须使用对应组件:
53
- - 复制到剪贴板 → `<d-copy>`
54
- - 文件上传/预览/下载 → `<d-upload>`
55
- - 富文本编辑 → `<d-editor>`
56
- - 长文本折叠展开 → `<d-fold-text>`
57
- - 图标悬浮提示 → `<d-icon-tip>`
58
- - 行内编辑切换 → `<d-inline-edit>`
59
-
60
- 2. **全局配置优先**:通用参数(如 Upload 的 `domain`、`axios`、`url`)应通过全局配置注入,业务页面只关注数据绑定和交互逻辑:
61
-
62
- ```js
63
- app.use(GeekplusDigitalUI, {
64
- config: {
65
- components: {
66
- upload: { domain: 'https://example.com', axios, url: '/upload' },
67
- },
68
- },
69
- });
70
- ```
71
-
72
- 3. **国际化**:组件库内置 5 种语言(zh-cn / zh-tw / en / ja / ko),通过 `locale` 选项配置,不要在业务代码中硬编码组件内部文案。
73
-
74
- 4. **样式一致性**:组件基于 Element Plus 构建,不要覆盖组件内部样式。如需定制,使用组件暴露的 Props 和 Slots。
75
-
76
- ## 常见场景映射
77
-
78
- | 你想做的事 | 不要这样做 | 应该这样做 |
79
- |-----------|-----------|-----------|
80
- | 复制文本到剪贴板 | 自己写 `navigator.clipboard` 逻辑 | `<d-copy :text="content" />` |
81
- | 上传并预览文件 | 自己封装 el-upload | `<d-upload v-model="files" />` |
82
- | 富文本编辑器 | 自己集成 wangEditor/Quill/TinyMCE | `<d-editor v-model="html" border />` |
83
- | 长文本展开收起 | 自己写 CSS line-clamp + 按钮 | `<d-fold-text :line-clamp="3">{{ text }}</d-fold-text>` |
84
- | 字段旁加说明图标 | 自己写 el-tooltip + icon | `<d-icon-tip content="说明文字" />` |
85
- | 单元格就地编辑 | 自己写 v-if 切换显示/输入 | `<d-inline-edit>展示内容<template #editor>编辑内容</template></d-inline-edit>` |
86
-
87
- ## Hooks
88
-
89
- ```js
90
- import { useLocale, useActivated } from 'geekplus-digital-ui';
91
-
92
- const { t, getLocale, setLocale } = useLocale(); // 国际化
93
- const { activated } = useActivated(); // 组件激活状态检测
94
- ```
95
-
96
- ## 在其他项目中启用此 Skill
97
-
98
- 在目标项目的 `CLAUDE.md` 中添加:
99
-
100
- ```
101
- @node_modules/geekplus-digital-ui/skills/use-geekplus-digital-ui/SKILL.md
102
- ```
103
-
104
- 或将此文件复制到目标项目的 `.claude/skills/` 目录中。
1
+ ---
2
+ name: use-geekplus-digital-ui
3
+ description: Use when developing Vue 3 features involving clipboard copy, file upload/preview/download, rich text editor, text collapse/expand, icon with tooltip, inline editing, search form filters, or data tables with column filtering/sorting/pagination. Triggers on keywords like 复制、上传、富文本、折叠文本、行内编辑、图标提示、搜索表单、搜索筛选、表格、列筛选、分页、copy, upload, editor, fold text, inline edit, icon tip, search form, table, column filter, pagination.
4
+ ---
5
+
6
+ # Geekplus Digital UI 组件库
7
+
8
+ **核心原则:不要重复造轮子。** 当功能已被 `geekplus-digital-ui` 覆盖时,必须使用现有组件,而非自行实现。
9
+
10
+ 文档站点:https://ui.geekplus.cc/static/ui/
11
+
12
+ ## 安装与引入
13
+
14
+ ```bash
15
+ npm install geekplus-digital-ui
16
+ # 或
17
+ pnpm add geekplus-digital-ui
18
+ # 或
19
+ yarn add geekplus-digital-ui
20
+ ```
21
+
22
+ ```js
23
+ import { createApp } from 'vue';
24
+ import ElementPlus from 'element-plus';
25
+ import GeekplusDigitalUI from 'geekplus-digital-ui';
26
+ import 'element-plus/dist/index.css';
27
+ import 'element-plus/theme-chalk/dark/css-vars.css';
28
+
29
+ const app = createApp(App);
30
+ app.use(ElementPlus);
31
+ app.use(GeekplusDigitalUI);
32
+ app.mount('#app');
33
+ ```
34
+
35
+ Peer dependencies: `vue@^3.5.0`、`element-plus@^2.13.0`
36
+
37
+ ## 组件速查表
38
+
39
+ | 组件 | 标签 | 用途 |
40
+ |------|------|------|
41
+ | **Copy** | `<d-copy>` | 一键复制文本到剪贴板 |
42
+ | **Upload** | `<d-upload>` | 文件上传/预览/下载,支持卡片和列表模式 |
43
+ | **Editor** | `<d-editor>` | 富文本编辑器(基于 wangEditor-next) |
44
+ | **FoldText** | `<d-fold-text>` | 多行文本折叠/展开 |
45
+ | **IconTip** | `<d-icon-tip>` | 图标 + 悬浮提示 |
46
+ | **InlineEdit** | `<d-inline-edit>` | 展示态/编辑态切换 |
47
+ | **SearchForm** | `<d-search-form>` | 可折叠搜索筛选区域 |
48
+ | **SearchItem** | `<d-search-item>` | 搜索表单的单个搜索项,配合 SearchForm 使用 |
49
+ | **Table** | `<d-table>` | 表格列筛选/拖排/内置分页/自适应高度 |
50
+
51
+ 详细 Props/Events/Slots API 请查阅文档:https://ui.geekplus.cc/static/ui/
52
+
53
+ ## 使用规则
54
+
55
+ 1. **禁止自行实现以下功能**,必须使用对应组件:
56
+ - 复制到剪贴板 → `<d-copy>`
57
+ - 文件上传/预览/下载 → `<d-upload>`
58
+ - 富文本编辑 → `<d-editor>`
59
+ - 长文本折叠展开 → `<d-fold-text>`
60
+ - 图标悬浮提示 `<d-icon-tip>`
61
+ - 行内编辑切换 → `<d-inline-edit>`
62
+ - 搜索筛选表单 → `<d-search-form>` + `<d-search-item>`
63
+ - 表格列显示/隐藏、列拖动排序、分页、表格自适应高度 → `<d-table>`
64
+
65
+ 2. **全局配置优先**:通用参数(如 Upload 的 `domain`、`axios`、`url`)应通过全局配置注入,业务页面只关注数据绑定和交互逻辑:
66
+
67
+ ```js
68
+ app.use(GeekplusDigitalUI, {
69
+ config: {
70
+ components: {
71
+ upload: { domain: 'https://example.com', axios, url: '/upload' },
72
+ },
73
+ },
74
+ });
75
+ ```
76
+
77
+ 3. **国际化**:组件库内置 5 种语言(zh-cn / zh-tw / en / ja / ko),通过 `locale` 选项配置,不要在业务代码中硬编码组件内部文案。
78
+
79
+ 4. **样式一致性**:组件基于 Element Plus 构建,不要覆盖组件内部样式。如需定制,使用组件暴露的 Props 和 Slots。
80
+
81
+ ## 常见场景映射
82
+
83
+ | 你想做的事 | 不要这样做 | 应该这样做 |
84
+ |-----------|-----------|-----------|
85
+ | 复制文本到剪贴板 | 自己写 `navigator.clipboard` 逻辑 | `<d-copy :text="content" />` |
86
+ | 上传并预览文件 | 自己封装 el-upload | `<d-upload v-model="files" />` |
87
+ | 富文本编辑器 | 自己集成 wangEditor/Quill/TinyMCE | `<d-editor v-model="html" border />` |
88
+ | 长文本展开收起 | 自己写 CSS line-clamp + 按钮 | `<d-fold-text :line-clamp="3">{{ text }}</d-fold-text>` |
89
+ | 字段旁加说明图标 | 自己写 el-tooltip + icon | `<d-icon-tip content="说明文字" />` |
90
+ | 单元格就地编辑 | 自己写 v-if 切换显示/输入 | `<d-inline-edit>展示内容<template #editor>编辑内容</template></d-inline-edit>` |
91
+ | 列表页搜索筛选区 | 自己用 el-form + el-row/col 手写 | `<d-search-form>` + `<d-search-item>` 组合 |
92
+ | 表格列显示/隐藏 + 持久化 | 自己用 el-checkbox + localStorage | `<d-table filterable storage-key="xxx">` |
93
+ | 表格内置分页 | 每个表格单独写 el-pagination | `<d-table :total="total" v-model:current-page="page">` |
94
+ | 表格填满视口高度 | 手算高度或写死 height | `<d-table auto-height>` |
95
+
96
+ ## Copy 用法
97
+
98
+ ```vue
99
+ <!-- 纯图标,一直显示 -->
100
+ <d-copy :text="value" />
101
+
102
+ <!-- 带文字(通过 default slot) -->
103
+ <d-copy :text="value">复制链接</d-copy>
104
+
105
+ <!-- 悬停父元素时才显示(trigger-element 传 CSS 选择器) -->
106
+ <d-copy :text="value" trigger-element=".table-row" />
107
+ ```
108
+
109
+ ## Upload 用法
110
+
111
+ `domain`、`axios`、`url` 建议通过全局配置注入,业务页面只传数据:
112
+
113
+ ```vue
114
+ <d-upload v-model="fileList" :max-number="5" :format="['jpg', 'png', 'pdf']" />
115
+ ```
116
+
117
+ - 默认列表模式;`show-type="card"` 切换卡片模式
118
+ - `v-model` 绑定 `{ name, url }[]` 格式的文件数组
119
+
120
+ ## Editor 用法
121
+
122
+ ```vue
123
+ <d-editor v-model="html" border />
124
+ ```
125
+
126
+ - `border` 显示边框;`disabled` 只读模式
127
+ - 工具栏通过全局配置的 `toolbarConfig` 定制
128
+
129
+ ## FoldText 用法
130
+
131
+ ```vue
132
+ <d-fold-text :line-clamp="3">
133
+ 这里是很长很长的文本内容,超出 3 行后自动折叠并显示展开按钮...
134
+ </d-fold-text>
135
+ ```
136
+
137
+ ## IconTip 用法
138
+
139
+ ```vue
140
+ <!-- 默认 info 图标 + tooltip -->
141
+ <d-icon-tip content="这里是说明文字" />
142
+
143
+ <!-- 自定义图标 -->
144
+ <d-icon-tip content="说明" icon="warning" type="warning" />
145
+ ```
146
+
147
+ ## InlineEdit 用法
148
+
149
+ ```vue
150
+ <d-inline-edit>
151
+ {{ row.name }}
152
+ <template #editor>
153
+ <el-input v-model="row.name" @blur="save" />
154
+ </template>
155
+ </d-inline-edit>
156
+ ```
157
+
158
+ - 单击进入编辑模式,点击外部自动退出(`onClickOutside`)
159
+ - `trigger="dblclick"` 改为双击触发
160
+ - `before-close` 可返回 `false` 阻止退出(用于校验)
161
+ - 无 `v-model`,通过 `#editor` slot 直接绑定数据
162
+
163
+ ## SearchForm 用法
164
+
165
+ ```vue
166
+ <template>
167
+ <d-search-form :loading="loading" @search="handleSearch" @reset="handleReset">
168
+ <d-search-item label="关键词" :span="6" track-label="keyword" :track-value="form.keyword">
169
+ <el-input v-model="form.keyword" clearable />
170
+ </d-search-item>
171
+ <d-search-item label="状态" :span="6">
172
+ <el-select v-model="form.status" clearable>
173
+ <el-option label="启用" value="1" />
174
+ </el-select>
175
+ </d-search-item>
176
+ </d-search-form>
177
+ </template>
178
+ ```
179
+
180
+ - 超过单行时自动出现展开/收起按钮
181
+ - `track-label` + `track-value` 启用埋点,通过 `formRef.getTrackText()` 获取 `keyword=hello,status=1` 格式字符串(空值自动过滤)
182
+ - `no-label` 无标签紧凑模式;`enter-click` 回车触发查询
183
+
184
+ ## Table 用法
185
+
186
+ ```vue
187
+ <template>
188
+ <d-table
189
+ storage-key="userList"
190
+ filterable
191
+ :total="total"
192
+ v-model:current-page="page"
193
+ v-model:page-size="pageSize"
194
+ auto-height
195
+ :available-height="windowHeight"
196
+ height-container=".page-container"
197
+ @page-change="fetchData"
198
+ >
199
+ <template #toolbar>
200
+ <el-button type="danger">批量删除</el-button>
201
+ </template>
202
+ <template #default="{ tableHeight }">
203
+ <el-table :height="tableHeight" :data="list" border>
204
+ <el-table-column type="selection" width="55" />
205
+ <el-table-column prop="name" label="姓名" />
206
+ <el-table-column prop="dept" label="部门" />
207
+ <el-table-column prop="action" label="操作">
208
+ <template #default="{ row }">
209
+ <el-button @click="edit(row)">编辑</el-button>
210
+ </template>
211
+ </el-table-column>
212
+ </el-table>
213
+ </template>
214
+ </d-table>
215
+ </template>
216
+
217
+ <script setup>
218
+ import { useWindowSize } from '@vueuse/core';
219
+ const { height: windowHeight } = useWindowSize();
220
+ </script>
221
+ ```
222
+
223
+ - `filterable` 默认关闭;开启时**必须**传 `storage-key`(唯一标识列配置的 localStorage key),否则列设置不持久化
224
+ - `auto-height` 需配合 `:available-height="windowHeight"` 和 `height-container=".page-container"`(指向搜索栏+表格共同的外层容器)使用,表格自动填满剩余空间
225
+ - 操作列建议加 `prop="action"` 以便在列设置中控制其显示
226
+ - `type="selection"` / `type="index"` 系统列始终显示,不进列设置面板
227
+
228
+ ## Hooks
229
+
230
+ ```js
231
+ import { useLocale, useActivated } from 'geekplus-digital-ui';
232
+
233
+ const { t, getLocale, setLocale } = useLocale(); // 国际化
234
+ const { activated } = useActivated(); // 组件激活状态检测
235
+ ```
236
+
237
+ ## 在其他项目中启用此 Skill
238
+
239
+ 在目标项目的 `CLAUDE.md` 中添加:
240
+
241
+ ```
242
+ @node_modules/geekplus-digital-ui/skills/use-geekplus-digital-ui/SKILL.md
243
+ ```
244
+
245
+ 或将此文件复制到目标项目的 `.claude/skills/` 目录中。
@@ -1 +0,0 @@
1
- .code-collapse[data-v-44e188d6]{border:1px solid var(--el-border-color);background:var(--el-bg-color-overlay);border-radius:4px;overflow:hidden}.code-collapse summary[data-v-44e188d6]{cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--el-text-color-primary);justify-content:flex-end;align-items:center;gap:4px;padding:8px 12px;line-height:normal;list-style:none;display:flex}.code-collapse[data-v-44e188d6] pre code{border:none;border-radius:0;margin:0}
@@ -1 +0,0 @@
1
- .d-editor[data-v-9103e51e]{width:100%}.d-editor.w-e-full-screen-container[data-v-9103e51e]{z-index:1000}.d-editor .toolbar-container[data-v-9103e51e]{border-bottom:1px solid var(--el-border-color)}.d-editor .toolbar-container[data-v-9103e51e] .w-e-toolbar{border-radius:4px}.d-editor .toolbar-container[data-v-9103e51e] .w-e-drop-panel{z-index:100}.d-editor .editor-container[data-v-9103e51e]{min-height:var(--minHeight);background:var(--el-fill-color-blank);border-radius:4px}.d-editor .editor-container[data-v-9103e51e] p[id^=w-e-element-paragraph-]{margin:10px 0}.d-editor .editor-container[data-v-9103e51e] .w-e-text-placeholder{font-size:14px;font-style:normal;line-height:normal;top:11px}.d-editor .editor-container[data-v-9103e51e] .w-e-image-container{width:500px}.d-editor .editor-container[data-v-9103e51e] pre code{text-shadow:none}.d-editor.editor-disabled[data-v-9103e51e]:not(.editor-border) div[id^=w-e-textarea-]{padding:0}.d-editor.editor-disabled[data-v-9103e51e]:not(.editor-border) p[id^=w-e-element-paragraph-]:first-child{margin-top:0}.d-editor.editor-disabled[data-v-9103e51e]:not(.editor-border) p[id^=w-e-element-paragraph-]:last-child{margin-bottom:0}.editor-border[data-v-9103e51e]{border:1px solid var(--el-border-color);background:var(--el-bg-color);border-radius:4px;transition:border-color .2s cubic-bezier(.645,.045,.355,1)}.editor-border[data-v-9103e51e]:hover{border-color:var(--el-text-color-disabled)}.editor-disabled .editor-container[data-v-9103e51e] img{cursor:zoom-in}.el-form-item.is-error .editor-border[data-v-9103e51e]{border:1px solid var(--el-color-danger)}
@@ -1 +0,0 @@
1
- .d-fold-text[data-v-cc699234]{overflow-wrap:break-word;flex-direction:column;display:flex}.d-fold-text .text-content[data-v-cc699234]{white-space:pre-wrap}.d-fold-text .text-content.line-clamp[data-v-cc699234]{-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.d-fold-text .text-link[data-v-cc699234]{display:flex}.d-fold-text .text-link[data-v-cc699234] .el-link__inner{gap:4px}
@@ -1 +0,0 @@
1
- .d-icon-tip .tip-content[data-v-fe982c8e]{white-space:pre-wrap}
@@ -1 +0,0 @@
1
- .d-inline-edit .text-hover[data-v-fc1016d4]{cursor:text;border-radius:4px}.d-inline-edit .text-hover[data-v-fc1016d4]:hover{box-shadow:0 0 0 1px var(--el-border-color) inset}
@@ -1 +0,0 @@
1
- .d-search-form[data-v-cea05b8f]{align-items:flex-start;gap:12px;display:flex;overflow:hidden}.d-search-form.is-open[data-v-cea05b8f]{overflow:visible}.d-search-form .search-row[data-v-cea05b8f]{flex:1}.d-search-form .search-row[data-v-cea05b8f] .el-row{flex-wrap:wrap;gap:12px 0}.d-search-form .search-btns[data-v-cea05b8f]{flex-shrink:0;align-items:center;gap:12px;display:flex;position:relative}.d-search-form .search-btns[data-v-cea05b8f] .el-button{margin:0}.d-search-form .search-btns[data-v-cea05b8f] .el-button .d-icon{margin-left:4px}
@@ -1 +0,0 @@
1
- .d-search-item .item-label[data-v-27c41622]{text-overflow:ellipsis;white-space:nowrap;height:32px;line-height:32px;overflow:hidden}.d-search-item .item-content[data-v-27c41622] .el-select,.d-search-item .item-content[data-v-27c41622] .el-input,.d-search-item .item-content[data-v-27c41622] .el-date-editor{width:100%}
@@ -1 +0,0 @@
1
- .d-upload[data-v-c4e16833]{line-height:normal}.d-upload .header[data-v-c4e16833]{align-items:center;gap:8px;width:100%;display:flex}.d-upload .header .el-button[data-v-c4e16833]{margin:0}.d-upload.is-list[data-v-c4e16833],.d-upload.is-list .list[data-v-c4e16833]{flex-direction:column;gap:8px;display:flex}.d-upload.is-list .list .list-item .file-row[data-v-c4e16833]{align-items:center;gap:4px;display:flex;position:relative}.d-upload.is-list .list .list-item .file-row[data-v-c4e16833] .el-link{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.d-upload.is-list .list .list-item .file-row[data-v-c4e16833] .el-link .el-link__inner{display:inline}.d-upload.is-list .list .list-item .file-row .remove-icon[data-v-c4e16833]{cursor:pointer;color:var(--el-text-color-secondary);display:none}.d-upload.is-list .list .list-item .file-row:hover .remove-icon[data-v-c4e16833]{display:block}.d-upload.is-card[data-v-c4e16833],.d-upload.is-card .card[data-v-c4e16833]{flex-wrap:wrap;gap:8px;display:flex}.d-upload.is-card .card .card-item[data-v-c4e16833]{box-sizing:border-box;border:1px solid var(--el-border-color);cursor:pointer;border-radius:4px;justify-content:center;align-items:center;font-size:16px;display:flex;position:relative;overflow:hidden}.d-upload.is-card .card .card-item .card-cover[data-v-c4e16833]{background:var(--el-overlay-color);opacity:0;justify-content:center;align-items:center;gap:12px;width:100%;height:100%;display:flex;position:absolute;top:0;left:0}.d-upload.is-card .card .card-item .card-cover .d-icon[data-v-c4e16833]{color:var(--el-color-white)}.d-upload.is-card .card .card-item .card-cover[data-v-c4e16833]:hover{opacity:1}.d-upload.is-card .card .el-image[data-v-c4e16833]{width:100%;height:100%}.d-upload.is-card .card .el-image .el-image__error[data-v-c4e16833]{font-size:16px}.d-upload .expand-toggle[data-v-c4e16833]{width:100%;display:flex}.d-upload .expand-toggle[data-v-c4e16833] .el-link__inner{gap:4px}.d-upload .tip[data-v-c4e16833]{width:100%;color:var(--el-text-color-regular);margin:0;font-size:12px}
@@ -1 +0,0 @@
1
- .d-upload__preview{justify-content:center;height:calc(80vh - 120px);display:flex}.d-upload__preview .preview-video{max-width:100%;height:100%}
File without changes