@oneflowui/ui 0.1.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 (127) hide show
  1. package/README.md +161 -0
  2. package/dist/FieldCheckbox-B1eVag_x.js +30 -0
  3. package/dist/FieldDate-BCitHPQn.js +34 -0
  4. package/dist/FieldDatetime-BGeyZJl-.js +34 -0
  5. package/dist/FieldEmail-Ds8lTvNh.js +34 -0
  6. package/dist/FieldMultiSelect-_cY4aZuE.js +145 -0
  7. package/dist/FieldNumber-DayaF31C.js +43 -0
  8. package/dist/FieldRating-Dw9rvhUe.js +32 -0
  9. package/dist/FieldSelect-DEVkjnNY.js +122 -0
  10. package/dist/FieldText-LzCqM7jk.js +34 -0
  11. package/dist/FieldUrl-zqYEJCPK.js +34 -0
  12. package/dist/components/ContextMenu/index.d.ts +2 -0
  13. package/dist/components/ContextMenu/index.vue.d.ts +27 -0
  14. package/dist/components/Dashboard/charts/BarChart.vue.d.ts +17 -0
  15. package/dist/components/Dashboard/charts/DoughnutChart.vue.d.ts +12 -0
  16. package/dist/components/Dashboard/charts/NumberCard.vue.d.ts +17 -0
  17. package/dist/components/Dashboard/charts/PieChart.vue.d.ts +21 -0
  18. package/dist/components/Dashboard/charts/TableChart.vue.d.ts +20 -0
  19. package/dist/components/Dashboard/index.d.ts +6 -0
  20. package/dist/components/Dashboard/index.vue.d.ts +23 -0
  21. package/dist/components/ai/AiMessageBubble.vue.d.ts +11 -0
  22. package/dist/components/ai/AiMessageList.vue.d.ts +19 -0
  23. package/dist/components/ai/AiSender.vue.d.ts +33 -0
  24. package/dist/components/ai/AiStreamingCursor.vue.d.ts +5 -0
  25. package/dist/components/ai/AiThinking.vue.d.ts +5 -0
  26. package/dist/components/ai/UserMessageBubble.vue.d.ts +7 -0
  27. package/dist/components/ai/index.d.ts +7 -0
  28. package/dist/components/auxiliary/ColorPanel.vue.d.ts +19 -0
  29. package/dist/components/auxiliary/FileUpload.vue.d.ts +24 -0
  30. package/dist/components/auxiliary/PersonPanel.vue.d.ts +24 -0
  31. package/dist/components/auxiliary/index.d.ts +3 -0
  32. package/dist/components/base/AddViewBtn.vue.d.ts +6 -0
  33. package/dist/components/base/ButtonGroup.vue.d.ts +30 -0
  34. package/dist/components/base/DropdownMenu.vue.d.ts +25 -0
  35. package/dist/components/base/EmptyState.vue.d.ts +26 -0
  36. package/dist/components/base/RangeSlider.vue.d.ts +29 -0
  37. package/dist/components/base/StatisticCard.vue.d.ts +22 -0
  38. package/dist/components/base/ToolbarBtn.vue.d.ts +11 -0
  39. package/dist/components/base/ViewTab.vue.d.ts +11 -0
  40. package/dist/components/base/index.d.ts +11 -0
  41. package/dist/components/breadcrumb/Breadcrumb.vue.d.ts +48 -0
  42. package/dist/components/breadcrumb/BreadcrumbItem.vue.d.ts +42 -0
  43. package/dist/components/breadcrumb/index.d.ts +3 -0
  44. package/dist/components/detail/CommentItem.vue.d.ts +6 -0
  45. package/dist/components/detail/DetailLayout.vue.d.ts +37 -0
  46. package/dist/components/detail/PropPanel.vue.d.ts +26 -0
  47. package/dist/components/detail/PropRow.vue.d.ts +44 -0
  48. package/dist/components/detail/index.d.ts +4 -0
  49. package/dist/components/editor/BlockQuote.vue.d.ts +13 -0
  50. package/dist/components/editor/CodeBlock.vue.d.ts +10 -0
  51. package/dist/components/editor/ContentBlock.vue.d.ts +27 -0
  52. package/dist/components/editor/RefLink.vue.d.ts +11 -0
  53. package/dist/components/editor/RichTextEditor.vue.d.ts +186 -0
  54. package/dist/components/editor/index.d.ts +5 -0
  55. package/dist/components/field/FieldCheckbox.vue.d.ts +14 -0
  56. package/dist/components/field/FieldDate.vue.d.ts +17 -0
  57. package/dist/components/field/FieldDatetime.vue.d.ts +17 -0
  58. package/dist/components/field/FieldEmail.vue.d.ts +17 -0
  59. package/dist/components/field/FieldMultiSelect.vue.d.ts +18 -0
  60. package/dist/components/field/FieldNumber.vue.d.ts +17 -0
  61. package/dist/components/field/FieldRating.vue.d.ts +15 -0
  62. package/dist/components/field/FieldSelect.vue.d.ts +18 -0
  63. package/dist/components/field/FieldText.vue.d.ts +17 -0
  64. package/dist/components/field/FieldUrl.vue.d.ts +17 -0
  65. package/dist/components/form/FormDesigner.vue.d.ts +17 -0
  66. package/dist/components/form/index.d.ts +1 -0
  67. package/dist/components/gallery/GalleryCard.vue.d.ts +10 -0
  68. package/dist/components/gallery/GalleryView.vue.d.ts +24 -0
  69. package/dist/components/gallery/index.d.ts +2 -0
  70. package/dist/components/kanban/KanbanBoard.vue.d.ts +26 -0
  71. package/dist/components/kanban/KanbanCard.vue.d.ts +23 -0
  72. package/dist/components/kanban/KanbanColumn.vue.d.ts +25 -0
  73. package/dist/components/kanban/QuickAddRow.vue.d.ts +13 -0
  74. package/dist/components/kanban/index.d.ts +4 -0
  75. package/dist/components/layout/AppLayout.vue.d.ts +20 -0
  76. package/dist/components/layout/Navbar.vue.d.ts +34 -0
  77. package/dist/components/layout/Sidebar.vue.d.ts +26 -0
  78. package/dist/components/layout/StatusBar.vue.d.ts +11 -0
  79. package/dist/components/layout/index.d.ts +4 -0
  80. package/dist/components/mermaid/MermaidChart.vue.d.ts +46 -0
  81. package/dist/components/mermaid/index.d.ts +1 -0
  82. package/dist/components/overlay/Dialog.vue.d.ts +69 -0
  83. package/dist/components/overlay/Modal.vue.d.ts +59 -0
  84. package/dist/components/overlay/index.d.ts +2 -0
  85. package/dist/components/split/SplitPane.vue.d.ts +41 -0
  86. package/dist/components/split/index.d.ts +1 -0
  87. package/dist/components/table/DataTable.vue.d.ts +43 -0
  88. package/dist/components/table/FieldCell.vue.d.ts +33 -0
  89. package/dist/components/table/NewRowBtn.vue.d.ts +6 -0
  90. package/dist/components/table/TableColumnManager.vue.d.ts +13 -0
  91. package/dist/components/table/TableDataRow.vue.d.ts +47 -0
  92. package/dist/components/table/TableFilterPanel.vue.d.ts +24 -0
  93. package/dist/components/table/TableHeaderRow.vue.d.ts +23 -0
  94. package/dist/components/table/index.d.ts +8 -0
  95. package/dist/components/tabs/TabPanel.vue.d.ts +38 -0
  96. package/dist/components/tabs/Tabs.vue.d.ts +60 -0
  97. package/dist/components/tabs/index.d.ts +3 -0
  98. package/dist/components/timeline/GanttRow.vue.d.ts +42 -0
  99. package/dist/components/timeline/GanttTimeline.vue.d.ts +46 -0
  100. package/dist/components/timeline/index.d.ts +2 -0
  101. package/dist/components/toast/ToastContainer.vue.d.ts +2 -0
  102. package/dist/components/toast/ToastItem.vue.d.ts +16 -0
  103. package/dist/components/toast/index.d.ts +2 -0
  104. package/dist/composables/index.d.ts +16 -0
  105. package/dist/composables/useAiChat.d.ts +45 -0
  106. package/dist/composables/useBadge.d.ts +27 -0
  107. package/dist/composables/useInlineEdit.d.ts +17 -0
  108. package/dist/composables/useMarkdown.d.ts +16 -0
  109. package/dist/composables/useStream.d.ts +15 -0
  110. package/dist/composables/useTable.d.ts +62 -0
  111. package/dist/composables/useTableFilter.d.ts +36 -0
  112. package/dist/composables/useToast.d.ts +63 -0
  113. package/dist/composables/useTypewriter.d.ts +11 -0
  114. package/dist/dev/App.vue.d.ts +2 -0
  115. package/dist/dev/main.d.ts +0 -0
  116. package/dist/index-B9LF7Kv4.js +10661 -0
  117. package/dist/index.d.ts +45 -0
  118. package/dist/oneflow-ui.js +84 -0
  119. package/dist/oneflow-ui.umd.cjs +13 -0
  120. package/dist/style.css +1 -0
  121. package/dist/tests/gantt.integration.spec.d.ts +1 -0
  122. package/dist/tests/table-detail.integration.spec.d.ts +1 -0
  123. package/dist/tests/three-layer-model.integration.spec.d.ts +1 -0
  124. package/dist/types/index.d.ts +161 -0
  125. package/dist/utils/icon.d.ts +7 -0
  126. package/dist/utils/index.d.ts +1 -0
  127. package/package.json +62 -0
package/README.md ADDED
@@ -0,0 +1,161 @@
1
+ # OneFlow UI
2
+
3
+ OneFlow 设计系统组件库,基于 Vue 3 + TypeScript 构建。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ # pnpm(推荐)
9
+ pnpm add oneflow-ui
10
+
11
+ # npm
12
+ npm install oneflow-ui
13
+
14
+ # yarn
15
+ yarn add oneflow-ui
16
+ ```
17
+
18
+ ## 开发与测试
19
+
20
+ ```bash
21
+ # 启动开发环境(固定端口 5174)
22
+ npm run dev
23
+
24
+ # 类型检查
25
+ npm run type-check
26
+
27
+ # 集成测试
28
+ npm run test
29
+ ```
30
+
31
+ ## 全局注册
32
+
33
+ ```ts
34
+ import { createApp } from 'vue'
35
+ import App from './App.vue'
36
+ import OneflowUI from 'oneflow-ui'
37
+ import 'oneflow-ui/styles'
38
+
39
+ const app = createApp(App)
40
+ app.use(OneflowUI)
41
+ app.mount('#app')
42
+ ```
43
+
44
+ ## 按需引入
45
+
46
+ ```ts
47
+ import { DetailLayout, PropPanel, DataTable } from 'oneflow-ui'
48
+ import 'oneflow-ui/styles'
49
+ ```
50
+
51
+ ## 样式引入
52
+
53
+ ```ts
54
+ // 在入口文件引入 CSS 变量和基础样式
55
+ import 'oneflow-ui/styles'
56
+ ```
57
+
58
+ ---
59
+
60
+ ## 组件示例
61
+
62
+ ### KanbanBoard
63
+
64
+ ```vue
65
+ <KanbanBoard
66
+ :columns="[
67
+ { id: 'todo', title: '待处理', color: '#64748B', tasks: [] },
68
+ { id: 'in_progress', title: '进行中', color: '#2563EB', tasks: [] },
69
+ ]"
70
+ @task-click="onTaskClick"
71
+ @add-task="onAddTask"
72
+ />
73
+
74
+ <!-- 或者使用 DataRecord 配置泳道字段 -->
75
+ <KanbanBoard
76
+ :records="records"
77
+ kanban-field-id="stage"
78
+ :lane-order="['todo', 'doing', 'done']"
79
+ :lane-titles="{ todo: '待处理', doing: '进行中', done: '已完成' }"
80
+ />
81
+ ```
82
+
83
+ ### DataTable
84
+
85
+ ```vue
86
+ <DataTable
87
+ :columns="[
88
+ { key: 'title', label: '标题', width: 'fill' },
89
+ { key: 'status', label: '状态', width: 120 },
90
+ { key: 'priority', label: '优先级', width: 100 },
91
+ ]"
92
+ :rows="tasks"
93
+ @row-click="onRowClick"
94
+ />
95
+ ```
96
+
97
+ ### GalleryView
98
+
99
+ ```vue
100
+ <GalleryView
101
+ :items="galleryItems"
102
+ @card-click="onCardClick"
103
+ />
104
+
105
+ <!-- 或者使用 DataRecord 配置封面字段 -->
106
+ <GalleryView
107
+ :records="records"
108
+ cover-field-id="coverUrl"
109
+ :card-field-ids="['assignee', 'priority']"
110
+ />
111
+ ```
112
+
113
+ ### GanttTimeline
114
+
115
+ ```vue
116
+ <GanttTimeline
117
+ :items="ganttItems"
118
+ :start-date="'2026-01-01'"
119
+ :end-date="'2026-12-31'"
120
+ @item-click="onItemClick"
121
+ />
122
+ ```
123
+
124
+ ### DetailLayout
125
+
126
+ ```vue
127
+ <DetailLayout
128
+ :task="currentTask"
129
+ v-model:description-content="detailDescription"
130
+ :description-editable="true"
131
+ :comments="comments"
132
+ :prop-items="[
133
+ { key: '状态', value: '进行中' },
134
+ { key: '优先级', value: 'P1' },
135
+ { key: '负责人', value: '张三' },
136
+ { key: '截止日期', value: '2026-06-30' },
137
+ ]"
138
+ />
139
+ ```
140
+
141
+ ### CodeBlock
142
+
143
+ ```vue
144
+ <CodeBlock
145
+ language="typescript"
146
+ :code="sourceCode"
147
+ />
148
+ ```
149
+
150
+ ---
151
+
152
+ ## 集成测试覆盖(Task 2.4)
153
+
154
+ - 三层数据模型:`TableSchema + DataRecord + ViewConfig` 联动可用
155
+ - Table + Detail:表格点击事件与详情渲染链路可用
156
+ - Dashboard 甘特图:空态/有数据态渲染与点击事件可用
157
+
158
+ 对应测试文件:
159
+ - `src/tests/three-layer-model.integration.spec.ts`
160
+ - `src/tests/table-detail.integration.spec.ts`
161
+ - `src/tests/gantt.integration.spec.ts`
@@ -0,0 +1,30 @@
1
+ import { defineComponent as s, computed as f, openBlock as p, createElementBlock as r, withModifiers as d, createElementVNode as m, toDisplayString as _ } from "vue";
2
+ import { _ as u } from "./index-B9LF7Kv4.js";
3
+ const k = { class: "of-field-checkbox__icon" }, x = /* @__PURE__ */ s({
4
+ __name: "FieldCheckbox",
5
+ props: {
6
+ value: {},
7
+ field: {}
8
+ },
9
+ emits: ["commit", "cancel", "tabNext"],
10
+ setup(n, { emit: a }) {
11
+ const i = n, t = a, o = f(() => !!i.value);
12
+ function c() {
13
+ t("commit", !o.value);
14
+ }
15
+ function l(e) {
16
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), c()), e.key === "Escape" && (e.preventDefault(), t("cancel")), e.key === "Tab" && (e.preventDefault(), t("tabNext"));
17
+ }
18
+ return (e, b) => (p(), r("div", {
19
+ class: "of-field-checkbox",
20
+ tabindex: "0",
21
+ onClick: d(c, ["stop"]),
22
+ onKeydown: l
23
+ }, [
24
+ m("span", k, _(o.value ? "☑" : "☐"), 1)
25
+ ], 32));
26
+ }
27
+ }), y = /* @__PURE__ */ u(x, [["__scopeId", "data-v-e5dffacb"]]);
28
+ export {
29
+ y as default
30
+ };
@@ -0,0 +1,34 @@
1
+ import { defineComponent as f, ref as u, onMounted as m, nextTick as s, withDirectives as d, openBlock as v, createElementBlock as y, vModelText as _ } from "vue";
2
+ import { _ as k } from "./index-B9LF7Kv4.js";
3
+ const x = /* @__PURE__ */ f({
4
+ __name: "FieldDate",
5
+ props: {
6
+ value: { type: [String, Number, Boolean, Array, null] },
7
+ field: {}
8
+ },
9
+ emits: ["commit", "cancel", "tabNext"],
10
+ setup(i, { emit: r }) {
11
+ const c = i, t = r, o = u(null), n = u(String(c.value ?? ""));
12
+ m(() => s(() => {
13
+ var e;
14
+ return (e = o.value) == null ? void 0 : e.focus();
15
+ }));
16
+ function p(e) {
17
+ e.key === "Enter" && (e.preventDefault(), t("commit", n.value || null)), e.key === "Escape" && (e.preventDefault(), t("cancel")), e.key === "Tab" && (e.preventDefault(), t("commit", n.value || null), t("tabNext"));
18
+ }
19
+ return (e, l) => d((v(), y("input", {
20
+ ref_key: "inputRef",
21
+ ref: o,
22
+ "onUpdate:modelValue": l[0] || (l[0] = (a) => n.value = a),
23
+ class: "of-field-input",
24
+ type: "date",
25
+ onKeydown: p,
26
+ onBlur: l[1] || (l[1] = (a) => t("commit", n.value || null))
27
+ }, null, 544)), [
28
+ [_, n.value]
29
+ ]);
30
+ }
31
+ }), B = /* @__PURE__ */ k(x, [["__scopeId", "data-v-3acdd712"]]);
32
+ export {
33
+ B as default
34
+ };
@@ -0,0 +1,34 @@
1
+ import { defineComponent as f, ref as i, onMounted as p, nextTick as s, withDirectives as d, openBlock as v, createElementBlock as y, vModelText as _ } from "vue";
2
+ import { _ as k } from "./index-B9LF7Kv4.js";
3
+ const x = /* @__PURE__ */ f({
4
+ __name: "FieldDatetime",
5
+ props: {
6
+ value: { type: [String, Number, Boolean, Array, null] },
7
+ field: {}
8
+ },
9
+ emits: ["commit", "cancel", "tabNext"],
10
+ setup(u, { emit: r }) {
11
+ const c = u, t = r, o = i(null), n = i(String(c.value ?? ""));
12
+ p(() => s(() => {
13
+ var e;
14
+ return (e = o.value) == null ? void 0 : e.focus();
15
+ }));
16
+ function m(e) {
17
+ e.key === "Enter" && (e.preventDefault(), t("commit", n.value || null)), e.key === "Escape" && (e.preventDefault(), t("cancel")), e.key === "Tab" && (e.preventDefault(), t("commit", n.value || null), t("tabNext"));
18
+ }
19
+ return (e, l) => d((v(), y("input", {
20
+ ref_key: "inputRef",
21
+ ref: o,
22
+ "onUpdate:modelValue": l[0] || (l[0] = (a) => n.value = a),
23
+ class: "of-field-input",
24
+ type: "datetime-local",
25
+ onKeydown: m,
26
+ onBlur: l[1] || (l[1] = (a) => t("commit", n.value || null))
27
+ }, null, 544)), [
28
+ [_, n.value]
29
+ ]);
30
+ }
31
+ }), B = /* @__PURE__ */ k(x, [["__scopeId", "data-v-bedfdcc6"]]);
32
+ export {
33
+ B as default
34
+ };
@@ -0,0 +1,34 @@
1
+ import { defineComponent as f, ref as a, onMounted as p, nextTick as s, withDirectives as d, openBlock as v, createElementBlock as y, vModelText as _ } from "vue";
2
+ import { _ as k } from "./index-B9LF7Kv4.js";
3
+ const x = /* @__PURE__ */ f({
4
+ __name: "FieldEmail",
5
+ props: {
6
+ value: { type: [String, Number, Boolean, Array, null] },
7
+ field: {}
8
+ },
9
+ emits: ["commit", "cancel", "tabNext"],
10
+ setup(u, { emit: r }) {
11
+ const c = u, t = r, o = a(null), n = a(String(c.value ?? ""));
12
+ p(() => s(() => {
13
+ var e;
14
+ return (e = o.value) == null ? void 0 : e.focus();
15
+ }));
16
+ function m(e) {
17
+ e.key === "Enter" && (e.preventDefault(), t("commit", n.value)), e.key === "Escape" && (e.preventDefault(), t("cancel")), e.key === "Tab" && (e.preventDefault(), t("commit", n.value), t("tabNext"));
18
+ }
19
+ return (e, l) => d((v(), y("input", {
20
+ ref_key: "inputRef",
21
+ ref: o,
22
+ class: "of-field-input",
23
+ type: "email",
24
+ "onUpdate:modelValue": l[0] || (l[0] = (i) => n.value = i),
25
+ onKeydown: m,
26
+ onBlur: l[1] || (l[1] = (i) => t("commit", n.value))
27
+ }, null, 544)), [
28
+ [_, n.value]
29
+ ]);
30
+ }
31
+ }), B = /* @__PURE__ */ k(x, [["__scopeId", "data-v-cdd23fdc"]]);
32
+ export {
33
+ B as default
34
+ };
@@ -0,0 +1,145 @@
1
+ import { defineComponent as $, ref as a, computed as M, onMounted as z, nextTick as F, onBeforeUnmount as O, watch as T, openBlock as l, createElementBlock as i, Fragment as A, renderList as L, normalizeStyle as w, toDisplayString as k, createBlock as I, Teleport as P, withModifiers as m, normalizeClass as U, createElementVNode as p, createCommentVNode as V } from "vue";
2
+ import { _ as K } from "./index-B9LF7Kv4.js";
3
+ const W = {
4
+ key: 0,
5
+ class: "of-field-multiselect__chips"
6
+ }, j = {
7
+ key: 1,
8
+ class: "of-field-multiselect__placeholder"
9
+ }, q = ["onMouseenter", "onClick"], G = ["checked"], H = { key: 1 }, J = { class: "of-field-multiselect__actions" }, Q = /* @__PURE__ */ $({
10
+ __name: "FieldMultiSelect",
11
+ props: {
12
+ value: { type: [String, Number, Boolean, Array, null] },
13
+ field: {}
14
+ },
15
+ emits: ["commit", "cancel", "tabNext"],
16
+ setup(S, { emit: B }) {
17
+ const d = S, _ = B, s = a(null), b = a(null), h = a({ top: "0px", left: "0px", width: "0px" }), f = a(!0), v = M(() => d.field.options ?? []), o = a([]), r = a(0), x = M(() => {
18
+ const e = new Set(o.value);
19
+ return v.value.filter((n) => e.has(n.value));
20
+ });
21
+ function g() {
22
+ o.value = Array.isArray(d.value) ? d.value.filter((e) => typeof e == "string") : [];
23
+ }
24
+ function u() {
25
+ if (!s.value) return;
26
+ const e = s.value.getBoundingClientRect();
27
+ h.value = {
28
+ top: `${e.bottom}px`,
29
+ left: `${e.left}px`,
30
+ width: `${Math.max(e.width, 220)}px`
31
+ };
32
+ }
33
+ function C(e) {
34
+ if (o.value.indexOf(e) >= 0) {
35
+ o.value = o.value.filter((t) => t !== e);
36
+ return;
37
+ }
38
+ o.value = [...o.value, e];
39
+ }
40
+ function y() {
41
+ f.value = !1, _("commit", [...o.value]);
42
+ }
43
+ function D() {
44
+ f.value && (f.value = !1, _("cancel"));
45
+ }
46
+ function N(e) {
47
+ if (e.key === "ArrowDown") {
48
+ e.preventDefault(), r.value = Math.min(r.value + 1, Math.max(v.value.length - 1, 0));
49
+ return;
50
+ }
51
+ if (e.key === "ArrowUp") {
52
+ e.preventDefault(), r.value = Math.max(r.value - 1, 0);
53
+ return;
54
+ }
55
+ if (e.key === " " || e.key === "Enter") {
56
+ e.preventDefault();
57
+ const n = v.value[r.value];
58
+ n && C(n.value);
59
+ return;
60
+ }
61
+ if (e.key === "Escape") {
62
+ e.preventDefault(), D();
63
+ return;
64
+ }
65
+ e.key === "Tab" && (e.preventDefault(), y(), _("tabNext"));
66
+ }
67
+ function E(e) {
68
+ var t, c;
69
+ const n = e.target;
70
+ n && ((t = s.value) != null && t.contains(n) || (c = b.value) != null && c.contains(n) || y());
71
+ }
72
+ return z(() => {
73
+ g(), F(() => {
74
+ var e;
75
+ u(), (e = s.value) == null || e.focus();
76
+ }), window.addEventListener("resize", u), window.addEventListener("scroll", u, !0), window.addEventListener("mousedown", E, !0);
77
+ }), O(() => {
78
+ window.removeEventListener("resize", u), window.removeEventListener("scroll", u, !0), window.removeEventListener("mousedown", E, !0);
79
+ }), T(
80
+ () => d.value,
81
+ () => {
82
+ g();
83
+ }
84
+ ), (e, n) => (l(), i("div", {
85
+ ref_key: "triggerRef",
86
+ ref: s,
87
+ class: "of-field-multiselect",
88
+ tabindex: "0",
89
+ onKeydown: N
90
+ }, [
91
+ x.value.length ? (l(), i("div", W, [
92
+ (l(!0), i(A, null, L(x.value, (t) => (l(), i("span", {
93
+ key: t.value,
94
+ class: "of-field-multiselect__badge",
95
+ style: w(t.color ? { background: t.color } : void 0)
96
+ }, k(t.label), 5))), 128))
97
+ ])) : (l(), i("span", j, "—")),
98
+ (l(), I(P, { to: "body" }, [
99
+ f.value ? (l(), i("div", {
100
+ key: 0,
101
+ ref_key: "dropdownRef",
102
+ ref: b,
103
+ class: "of-field-multiselect__dropdown",
104
+ style: w(h.value)
105
+ }, [
106
+ (l(!0), i(A, null, L(v.value, (t, c) => (l(), i("div", {
107
+ key: t.value,
108
+ class: U(["of-field-multiselect__option", { active: c === r.value, selected: o.value.includes(t.value) }]),
109
+ onMouseenter: (R) => r.value = c,
110
+ onClick: m((R) => C(t.value), ["stop"])
111
+ }, [
112
+ p("input", {
113
+ class: "of-field-multiselect__checkbox",
114
+ type: "checkbox",
115
+ tabindex: "-1",
116
+ checked: o.value.includes(t.value),
117
+ onChange: n[0] || (n[0] = m(() => {
118
+ }, ["prevent"]))
119
+ }, null, 40, G),
120
+ t.color ? (l(), i("span", {
121
+ key: 0,
122
+ class: "of-field-multiselect__badge",
123
+ style: w({ background: t.color })
124
+ }, k(t.label), 5)) : (l(), i("span", H, k(t.label), 1))
125
+ ], 42, q))), 128)),
126
+ p("div", J, [
127
+ p("button", {
128
+ class: "of-field-multiselect__btn",
129
+ type: "button",
130
+ onClick: m(D, ["stop"])
131
+ }, "取消"),
132
+ p("button", {
133
+ class: "of-field-multiselect__btn of-field-multiselect__btn--primary",
134
+ type: "button",
135
+ onClick: m(y, ["stop"])
136
+ }, "完成")
137
+ ])
138
+ ], 4)) : V("", !0)
139
+ ]))
140
+ ], 544));
141
+ }
142
+ }), Z = /* @__PURE__ */ K(Q, [["__scopeId", "data-v-8e54ce8e"]]);
143
+ export {
144
+ Z as default
145
+ };
@@ -0,0 +1,43 @@
1
+ import { defineComponent as p, ref as m, onMounted as v, nextTick as d, withDirectives as N, openBlock as b, createElementBlock as y, vModelText as k } from "vue";
2
+ import { _ } from "./index-B9LF7Kv4.js";
3
+ const x = /* @__PURE__ */ p({
4
+ __name: "FieldNumber",
5
+ props: {
6
+ value: { type: [String, Number, Boolean, Array, null] },
7
+ field: {}
8
+ },
9
+ emits: ["commit", "cancel", "tabNext"],
10
+ setup(f, { emit: c }) {
11
+ const o = f, u = c, a = m(null), t = m(o.value === null || o.value === void 0 ? "" : String(o.value));
12
+ v(() => d(() => {
13
+ var e;
14
+ return (e = a.value) == null ? void 0 : e.focus();
15
+ }));
16
+ function r() {
17
+ if (t.value === "") return null;
18
+ const e = Number(t.value);
19
+ return Number.isNaN(e) ? null : e;
20
+ }
21
+ function i(e) {
22
+ const n = t.value === "" ? 0 : Number(t.value), l = Number.isNaN(n) ? 0 : n;
23
+ t.value = String(l + e);
24
+ }
25
+ function s(e) {
26
+ e.key === "ArrowUp" && (e.preventDefault(), i(1)), e.key === "ArrowDown" && (e.preventDefault(), i(-1)), e.key === "Enter" && (e.preventDefault(), u("commit", r())), e.key === "Escape" && (e.preventDefault(), u("cancel")), e.key === "Tab" && (e.preventDefault(), u("commit", r()), u("tabNext"));
27
+ }
28
+ return (e, n) => N((b(), y("input", {
29
+ ref_key: "inputRef",
30
+ ref: a,
31
+ class: "of-field-input",
32
+ type: "number",
33
+ "onUpdate:modelValue": n[0] || (n[0] = (l) => t.value = l),
34
+ onKeydown: s,
35
+ onBlur: n[1] || (n[1] = (l) => u("commit", r()))
36
+ }, null, 544)), [
37
+ [k, t.value]
38
+ ]);
39
+ }
40
+ }), B = /* @__PURE__ */ _(x, [["__scopeId", "data-v-81dd7528"]]);
41
+ export {
42
+ B as default
43
+ };
@@ -0,0 +1,32 @@
1
+ import { defineComponent as v, ref as _, openBlock as o, createElementBlock as r, withKeys as x, Fragment as g, renderList as b, unref as c, withModifiers as k, normalizeClass as y } from "vue";
2
+ import { _ as C } from "./index-B9LF7Kv4.js";
3
+ const M = ["onMouseenter", "onClick"], $ = /* @__PURE__ */ v({
4
+ __name: "FieldRating",
5
+ props: {
6
+ value: { type: [String, Number, Boolean, Array, null] },
7
+ field: {}
8
+ },
9
+ emits: ["commit", "cancel", "tabNext"],
10
+ setup(u, { emit: m }) {
11
+ const s = u, a = m, n = _(0), d = s.field.max ?? 5, f = Number(s.value ?? 0);
12
+ function p(i) {
13
+ a("commit", i);
14
+ }
15
+ return (i, t) => (o(), r("div", {
16
+ class: "of-field-rating",
17
+ onKeydown: t[1] || (t[1] = x((e) => a("cancel"), ["escape"])),
18
+ tabindex: "0"
19
+ }, [
20
+ (o(!0), r(g, null, b(c(d), (e) => (o(), r("span", {
21
+ key: e,
22
+ class: y(["of-field-rating__star", { filled: e <= (n.value || c(f)) }]),
23
+ onMouseenter: (l) => n.value = e,
24
+ onMouseleave: t[0] || (t[0] = (l) => n.value = 0),
25
+ onClick: k((l) => p(e), ["stop"])
26
+ }, "★", 42, M))), 128))
27
+ ], 32));
28
+ }
29
+ }), F = /* @__PURE__ */ C($, [["__scopeId", "data-v-80c63bd9"]]);
30
+ export {
31
+ F as default
32
+ };
@@ -0,0 +1,122 @@
1
+ import { defineComponent as N, ref as f, computed as x, onMounted as R, nextTick as V, onBeforeUnmount as z, watch as A, openBlock as l, createElementBlock as a, normalizeStyle as b, toDisplayString as w, createBlock as I, Teleport as F, createElementVNode as T, withModifiers as C, normalizeClass as L, Fragment as O, renderList as P, createCommentVNode as U } from "vue";
2
+ import { _ as K } from "./index-B9LF7Kv4.js";
3
+ const W = {
4
+ key: 1,
5
+ class: "of-field-select__display"
6
+ }, j = ["onMouseenter", "onClick"], q = { key: 1 }, G = /* @__PURE__ */ N({
7
+ __name: "FieldSelect",
8
+ props: {
9
+ value: { type: [String, Number, Boolean, Array, null] },
10
+ field: {}
11
+ },
12
+ emits: ["commit", "cancel", "tabNext"],
13
+ setup(M, { emit: B }) {
14
+ const s = M, y = B, i = f(null), h = f(null), E = f({ top: "0px", left: "0px", width: "0px" }), p = f(!0), r = x(() => s.field.options ?? []), c = x(() => {
15
+ const e = typeof s.value == "string" ? s.value : null;
16
+ return r.value.findIndex((t) => t.value === e);
17
+ }), n = f(0);
18
+ function d() {
19
+ if (!i.value) return;
20
+ const e = i.value.getBoundingClientRect();
21
+ E.value = {
22
+ top: `${e.bottom}px`,
23
+ left: `${e.left}px`,
24
+ width: `${Math.max(e.width, 160)}px`
25
+ };
26
+ }
27
+ function m(e) {
28
+ p.value = !1, y("commit", e);
29
+ }
30
+ function k() {
31
+ p.value && (p.value = !1, y("cancel"));
32
+ }
33
+ function S(e) {
34
+ var t, o;
35
+ if (!r.value.length) {
36
+ e.key === "Escape" && (e.preventDefault(), k());
37
+ return;
38
+ }
39
+ if (e.key === "ArrowDown") {
40
+ e.preventDefault(), n.value = Math.min(n.value + 1, r.value.length - 1);
41
+ return;
42
+ }
43
+ if (e.key === "ArrowUp") {
44
+ e.preventDefault(), n.value = Math.max(n.value - 1, 0);
45
+ return;
46
+ }
47
+ if (e.key === "Enter") {
48
+ e.preventDefault(), m(((t = r.value[n.value]) == null ? void 0 : t.value) ?? null);
49
+ return;
50
+ }
51
+ if (e.key === "Escape") {
52
+ e.preventDefault(), k();
53
+ return;
54
+ }
55
+ e.key === "Tab" && (e.preventDefault(), m(((o = r.value[n.value]) == null ? void 0 : o.value) ?? null), y("tabNext"));
56
+ }
57
+ function D(e) {
58
+ var o, v;
59
+ const t = e.target;
60
+ t && ((o = i.value) != null && o.contains(t) || (v = h.value) != null && v.contains(t) || k());
61
+ }
62
+ R(() => {
63
+ n.value = c.value >= 0 ? c.value : 0, V(() => {
64
+ var e;
65
+ d(), (e = i.value) == null || e.focus();
66
+ }), window.addEventListener("resize", d), window.addEventListener("scroll", d, !0), window.addEventListener("mousedown", D, !0);
67
+ }), z(() => {
68
+ window.removeEventListener("resize", d), window.removeEventListener("scroll", d, !0), window.removeEventListener("mousedown", D, !0);
69
+ }), A(c, (e) => {
70
+ e >= 0 && (n.value = e);
71
+ });
72
+ const _ = x(() => {
73
+ const e = typeof s.value == "string" ? s.value : null;
74
+ return r.value.find((t) => t.value === e);
75
+ });
76
+ return (e, t) => {
77
+ var o, v;
78
+ return l(), a("div", {
79
+ ref_key: "triggerRef",
80
+ ref: i,
81
+ class: "of-field-select",
82
+ tabindex: "0",
83
+ onKeydown: S
84
+ }, [
85
+ (o = _.value) != null && o.color ? (l(), a("span", {
86
+ key: 0,
87
+ class: "of-field-select__badge",
88
+ style: b({ background: _.value.color })
89
+ }, w(_.value.label), 5)) : (l(), a("span", W, w(((v = _.value) == null ? void 0 : v.label) ?? "—"), 1)),
90
+ (l(), I(F, { to: "body" }, [
91
+ p.value ? (l(), a("div", {
92
+ key: 0,
93
+ ref_key: "dropdownRef",
94
+ ref: h,
95
+ class: "of-field-select__dropdown",
96
+ style: b(E.value)
97
+ }, [
98
+ T("div", {
99
+ class: L(["of-field-select__option of-field-select__option--clear", { active: n.value === -1, selected: c.value === -1 }]),
100
+ onClick: t[0] || (t[0] = C((u) => m(null), ["stop"]))
101
+ }, " — ", 2),
102
+ (l(!0), a(O, null, P(r.value, (u, g) => (l(), a("div", {
103
+ key: u.value,
104
+ class: L(["of-field-select__option", { active: g === n.value, selected: g === c.value }]),
105
+ onMouseenter: ($) => n.value = g,
106
+ onClick: C(($) => m(u.value), ["stop"])
107
+ }, [
108
+ u.color ? (l(), a("span", {
109
+ key: 0,
110
+ class: "of-field-select__badge",
111
+ style: b({ background: u.color })
112
+ }, w(u.label), 5)) : (l(), a("span", q, w(u.label), 1))
113
+ ], 42, j))), 128))
114
+ ], 4)) : U("", !0)
115
+ ]))
116
+ ], 544);
117
+ };
118
+ }
119
+ }), Q = /* @__PURE__ */ K(G, [["__scopeId", "data-v-7a426fe0"]]);
120
+ export {
121
+ Q as default
122
+ };
@@ -0,0 +1,34 @@
1
+ import { defineComponent as f, ref as a, onMounted as m, nextTick as s, withDirectives as v, openBlock as d, createElementBlock as x, vModelText as y } from "vue";
2
+ import { _ } from "./index-B9LF7Kv4.js";
3
+ const k = /* @__PURE__ */ f({
4
+ __name: "FieldText",
5
+ props: {
6
+ value: { type: [String, Number, Boolean, Array, null] },
7
+ field: {}
8
+ },
9
+ emits: ["commit", "cancel", "tabNext"],
10
+ setup(u, { emit: r }) {
11
+ const c = u, t = r, l = a(null), n = a(String(c.value ?? ""));
12
+ m(() => s(() => {
13
+ var e;
14
+ return (e = l.value) == null ? void 0 : e.focus();
15
+ }));
16
+ function p(e) {
17
+ e.key === "Enter" && (e.preventDefault(), t("commit", n.value)), e.key === "Escape" && (e.preventDefault(), t("cancel")), e.key === "Tab" && (e.preventDefault(), t("commit", n.value), t("tabNext"));
18
+ }
19
+ return (e, o) => v((d(), x("input", {
20
+ ref_key: "inputRef",
21
+ ref: l,
22
+ class: "of-field-input",
23
+ type: "text",
24
+ "onUpdate:modelValue": o[0] || (o[0] = (i) => n.value = i),
25
+ onKeydown: p,
26
+ onBlur: o[1] || (o[1] = (i) => t("commit", n.value))
27
+ }, null, 544)), [
28
+ [y, n.value]
29
+ ]);
30
+ }
31
+ }), B = /* @__PURE__ */ _(k, [["__scopeId", "data-v-14e46c45"]]);
32
+ export {
33
+ B as default
34
+ };