@shwfed/config 2.7.1 → 2.7.2
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/dist/mcp.mjs +1125 -1014
- package/dist/module.json +1 -1
- package/dist/preview/assets/badge-CJpxWUkB.js +1 -0
- package/dist/preview/assets/config-B-uvT_pb.js +1 -0
- package/dist/preview/assets/config-BRiILJ2a.js +1 -0
- package/dist/preview/assets/config-CbMKku2N.js +1 -0
- package/dist/preview/assets/config-D8tXo17l.js +1 -0
- package/dist/preview/assets/config-D9pA2oC8.js +1 -0
- package/dist/preview/assets/config-DtCRvYa9.js +1 -0
- package/dist/preview/assets/config-OQtpit00.js +1 -0
- package/dist/preview/assets/config-QHRydAV_.js +1 -0
- package/dist/preview/assets/config-dtgP-3mj.js +1 -0
- package/dist/preview/assets/definition.vue_vue_type_script_setup_true_lang-Dp8O3US_.js +1 -0
- package/dist/preview/assets/{index-BGFrUxgg.js → index-BBJQYeyQ.js} +170 -170
- package/dist/preview/assets/{index-Bw16PZhL.js → index-BWNTkzpm.js} +1 -1
- package/dist/preview/assets/index-ChitoGhE.js +1 -0
- package/dist/preview/assets/index-DFKLSxdT.css +1 -0
- package/dist/preview/assets/{item-aVe51Gy6.js → item-BpzTGOEt.js} +1 -1
- package/dist/preview/assets/{runtime-3rNI0KDH.js → runtime-B5S6icpw.js} +1 -1
- package/dist/preview/assets/{runtime-CYGmRjmI.js → runtime-BDyVuoP3.js} +1 -1
- package/dist/preview/assets/{runtime-CfVt6IWe.js → runtime-BjB2wvFX.js} +1 -1
- package/dist/preview/assets/{runtime-CXQuhSAX.js → runtime-Busbr90M.js} +1 -1
- package/dist/preview/assets/runtime-By0VH4uC.js +1 -0
- package/dist/preview/assets/{runtime-DYj-R8SZ.js → runtime-C29fORZL.js} +1 -1
- package/dist/preview/assets/runtime-DMsEFiBw.js +1 -0
- package/dist/preview/assets/runtime-DfP3qvGT.js +1 -0
- package/dist/preview/assets/runtime-DiTvLHpE.js +1 -0
- package/dist/preview/index.html +2 -2
- package/dist/runtime/components/config/blocks/2026-05-17/com.shwfed.block.chart.xy/schema.d.ts +1 -1
- package/dist/runtime/components/config/blocks/2026-05-17/com.shwfed.block.chart.xy/schema.js +1 -1
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/badge.d.vue.ts +7 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/badge.vue +91 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/badge.vue.d.ts +7 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/config.d.vue.ts +96 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/config.vue +522 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/config.vue.d.ts +96 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/runtime.d.vue.ts +96 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/runtime.vue +72 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/runtime.vue.d.ts +96 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/schema.d.ts +121 -0
- package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/schema.js +100 -0
- package/dist/runtime/components/form/config.vue +10 -18
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
- package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
- package/package.json +1 -1
- package/dist/preview/assets/config-B5FFtD0s.js +0 -1
- package/dist/preview/assets/config-BpWP2vu_.js +0 -1
- package/dist/preview/assets/config-C2OqUTNd.js +0 -1
- package/dist/preview/assets/config-D7cjMBeK.js +0 -1
- package/dist/preview/assets/config-DhORWTZC.js +0 -1
- package/dist/preview/assets/config-DuuYvFG_.js +0 -1
- package/dist/preview/assets/config-dpwN2-UY.js +0 -1
- package/dist/preview/assets/config-eP0EblYK.js +0 -1
- package/dist/preview/assets/config-hs_pZ5MM.js +0 -1
- package/dist/preview/assets/definition.vue_vue_type_script_setup_true_lang-B8-Uydoy.js +0 -1
- package/dist/preview/assets/index-BoGW90Pq.css +0 -1
- package/dist/preview/assets/index-CG261V86.js +0 -1
- package/dist/preview/assets/runtime-BOn8EwHL.js +0 -1
- package/dist/preview/assets/runtime-Bwr-rb58.js +0 -1
- package/dist/preview/assets/runtime-Ca79Fs6I.js +0 -1
- package/dist/preview/assets/runtime-Dd1GqYeP.js +0 -1
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, inject, onBeforeUnmount, ref, watch } from "vue";
|
|
3
|
+
import { Schema } from "effect";
|
|
4
|
+
import { Icon } from "@iconify/vue";
|
|
5
|
+
import BlockLayoutEditor from "../../../../block-layout-editor/index.vue";
|
|
6
|
+
import LayoutsSidebar from "../../../../block-layout-editor/sidebar.vue";
|
|
7
|
+
import LayoutMetaStrip from "../../../../block-layout-editor/meta-strip.vue";
|
|
8
|
+
import { Button } from "../../../../ui/button";
|
|
9
|
+
import { ExpressionEditor } from "../../../../ui/expression-editor";
|
|
10
|
+
import { Field, FieldLabel } from "../../../../ui/field";
|
|
11
|
+
import { InputGroup, InputGroupInput, InputGroupNumberField } from "../../../../ui/input-group";
|
|
12
|
+
import { Locale as LocaleField } from "../../../../ui/locale";
|
|
13
|
+
import { Markdown } from "../../../../ui/markdown";
|
|
14
|
+
import { ScrollArea } from "../../../../ui/scroll-area";
|
|
15
|
+
import {
|
|
16
|
+
Select,
|
|
17
|
+
SelectContent,
|
|
18
|
+
SelectItem,
|
|
19
|
+
SelectTrigger,
|
|
20
|
+
SelectValue
|
|
21
|
+
} from "../../../../ui/select";
|
|
22
|
+
import { Separator } from "../../../../ui/separator";
|
|
23
|
+
import { Switch } from "../../../../ui/switch";
|
|
24
|
+
import { BREADCRUMB_EXTENSION_KEY } from "../../../breadcrumb-extension";
|
|
25
|
+
import { findBlock } from "../../../utils/resolve";
|
|
26
|
+
import { useSlotEditor } from "../../../use-editor";
|
|
27
|
+
import {
|
|
28
|
+
BADGE_VARIANTS,
|
|
29
|
+
badgeSchema,
|
|
30
|
+
getStructFieldDescription,
|
|
31
|
+
getStructFieldTitle,
|
|
32
|
+
schema
|
|
33
|
+
} from "./schema";
|
|
34
|
+
defineOptions({ name: "ShwfedBlockCardConfig" });
|
|
35
|
+
const block = defineModel({ type: null, ...{ required: true } });
|
|
36
|
+
const props = defineProps({
|
|
37
|
+
configure: { type: Function, required: false }
|
|
38
|
+
});
|
|
39
|
+
const configure = computed(() => props.configure ?? (() => {
|
|
40
|
+
}));
|
|
41
|
+
const blockSchema = schema(() => {
|
|
42
|
+
}, Schema.Any);
|
|
43
|
+
const badgeSchemaObj = badgeSchema(() => {
|
|
44
|
+
});
|
|
45
|
+
const fieldTitle = (f) => getStructFieldTitle(blockSchema, f) ?? f;
|
|
46
|
+
const fieldDescription = (f) => getStructFieldDescription(blockSchema, f);
|
|
47
|
+
const badgeTitle = (f) => getStructFieldTitle(badgeSchemaObj, f) ?? f;
|
|
48
|
+
const badgeDescription = (f) => getStructFieldDescription(badgeSchemaObj, f);
|
|
49
|
+
const BADGE_VARIANT_LABELS = {
|
|
50
|
+
default: "\u9ED8\u8BA4",
|
|
51
|
+
secondary: "\u6B21\u8981",
|
|
52
|
+
destructive: "\u8B66\u793A",
|
|
53
|
+
outline: "\u63CF\u8FB9"
|
|
54
|
+
};
|
|
55
|
+
const slotAccessor = computed({
|
|
56
|
+
get: () => block.value.slot,
|
|
57
|
+
set: (next) => {
|
|
58
|
+
block.value = { ...block.value, slot: next };
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
const editor = useSlotEditor(slotAccessor, { configure: configure.value });
|
|
62
|
+
const viewMode = ref("content");
|
|
63
|
+
function selectContent() {
|
|
64
|
+
viewMode.value = "content";
|
|
65
|
+
drilledBlockId.value = null;
|
|
66
|
+
}
|
|
67
|
+
function selectBadge() {
|
|
68
|
+
viewMode.value = "badge";
|
|
69
|
+
drilledBlockId.value = null;
|
|
70
|
+
}
|
|
71
|
+
function selectGeneral() {
|
|
72
|
+
viewMode.value = "general";
|
|
73
|
+
drilledBlockId.value = null;
|
|
74
|
+
}
|
|
75
|
+
function setDisplayName(v) {
|
|
76
|
+
const s = String(v ?? "");
|
|
77
|
+
block.value = { ...block.value, displayName: s.length > 0 ? s : void 0 };
|
|
78
|
+
}
|
|
79
|
+
function setStyle(v) {
|
|
80
|
+
block.value = { ...block.value, style: v.trim().length > 0 ? v : void 0 };
|
|
81
|
+
}
|
|
82
|
+
function setUrl(v) {
|
|
83
|
+
block.value = { ...block.value, url: v.trim().length > 0 ? v : void 0 };
|
|
84
|
+
}
|
|
85
|
+
const badge = computed(() => block.value.badge ?? {});
|
|
86
|
+
function isLocaleBlank(v) {
|
|
87
|
+
return !v || v.every((item) => item.message.trim().length === 0);
|
|
88
|
+
}
|
|
89
|
+
function patchBadge(patch) {
|
|
90
|
+
const next = { ...badge.value, ...patch };
|
|
91
|
+
const cleaned = {};
|
|
92
|
+
for (const [k, v] of Object.entries(next)) {
|
|
93
|
+
if (v !== void 0) cleaned[k] = v;
|
|
94
|
+
}
|
|
95
|
+
block.value = {
|
|
96
|
+
...block.value,
|
|
97
|
+
badge: Object.keys(cleaned).length > 0 ? cleaned : void 0
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function setBadgeRequest(v) {
|
|
101
|
+
patchBadge({ request: v.trim().length > 0 ? v : void 0 });
|
|
102
|
+
}
|
|
103
|
+
function setBadgeContent(v) {
|
|
104
|
+
patchBadge({ content: isLocaleBlank(v) ? void 0 : v });
|
|
105
|
+
}
|
|
106
|
+
function setBadgeInterval(v) {
|
|
107
|
+
patchBadge({ interval: typeof v === "number" && v > 0 ? Math.round(v) : void 0 });
|
|
108
|
+
}
|
|
109
|
+
function setBadgeDot(v) {
|
|
110
|
+
patchBadge({ dot: v ? true : void 0 });
|
|
111
|
+
}
|
|
112
|
+
function setBadgeVariant(v) {
|
|
113
|
+
const s = typeof v === "string" ? v : "default";
|
|
114
|
+
patchBadge({ variant: s === "default" ? void 0 : s });
|
|
115
|
+
}
|
|
116
|
+
function selectLayout(index) {
|
|
117
|
+
editor.activeLayoutIndex.value = index;
|
|
118
|
+
viewMode.value = "content";
|
|
119
|
+
drilledBlockId.value = null;
|
|
120
|
+
}
|
|
121
|
+
function addLayout() {
|
|
122
|
+
const cur = editor.layouts.value;
|
|
123
|
+
editor.layouts.value = [
|
|
124
|
+
...cur,
|
|
125
|
+
{ name: "\u65B0\u5E03\u5C40", layout: { columns: 1, placements: {} } }
|
|
126
|
+
];
|
|
127
|
+
editor.activeLayoutIndex.value = cur.length;
|
|
128
|
+
viewMode.value = "content";
|
|
129
|
+
}
|
|
130
|
+
function addBlock(entry, options) {
|
|
131
|
+
editor.addBlock(entry, options);
|
|
132
|
+
}
|
|
133
|
+
const drilledBlockId = ref(null);
|
|
134
|
+
const drilledBlock = computed(() => {
|
|
135
|
+
const id = drilledBlockId.value;
|
|
136
|
+
if (!id) return null;
|
|
137
|
+
return editor.blocks.value.find((b) => b.id === id) ?? null;
|
|
138
|
+
});
|
|
139
|
+
const drilledEntry = computed(() => {
|
|
140
|
+
const b = drilledBlock.value;
|
|
141
|
+
return b ? findBlock(b.type, b.compatibilityDate) ?? null : null;
|
|
142
|
+
});
|
|
143
|
+
function onDrillDown(id) {
|
|
144
|
+
drilledBlockId.value = id;
|
|
145
|
+
}
|
|
146
|
+
function popDrill() {
|
|
147
|
+
drilledBlockId.value = null;
|
|
148
|
+
}
|
|
149
|
+
watch(
|
|
150
|
+
() => editor.blocks.value.map((b) => b.id),
|
|
151
|
+
(ids) => {
|
|
152
|
+
const id = drilledBlockId.value;
|
|
153
|
+
if (id && !ids.includes(id)) drilledBlockId.value = null;
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
function updateDrilledBlock(next) {
|
|
157
|
+
const id = drilledBlockId.value;
|
|
158
|
+
if (!id) return;
|
|
159
|
+
editor.updateBlock(id, next);
|
|
160
|
+
}
|
|
161
|
+
const breadcrumbExt = inject(BREADCRUMB_EXTENSION_KEY, null);
|
|
162
|
+
if (breadcrumbExt) {
|
|
163
|
+
const blockCrumb = breadcrumbExt.add();
|
|
164
|
+
watch(
|
|
165
|
+
drilledBlock,
|
|
166
|
+
(drilled) => {
|
|
167
|
+
if (drilled) {
|
|
168
|
+
blockCrumb.label.value = editor.getBlockLabel(drilled);
|
|
169
|
+
blockCrumb.back.value = popDrill;
|
|
170
|
+
} else {
|
|
171
|
+
blockCrumb.label.value = null;
|
|
172
|
+
blockCrumb.back.value = null;
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{ immediate: true }
|
|
176
|
+
);
|
|
177
|
+
onBeforeUnmount(() => {
|
|
178
|
+
blockCrumb.dispose();
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
</script>
|
|
182
|
+
|
|
183
|
+
<template>
|
|
184
|
+
<div class="flex min-w-0 gap-2 min-h-128">
|
|
185
|
+
<!-- Left rail: setting rows (top) + the slot's layouts (bottom). Hidden
|
|
186
|
+
while drilled into a child block so the drilled view owns the width. -->
|
|
187
|
+
<div
|
|
188
|
+
v-if="!drilledBlockId"
|
|
189
|
+
class="flex w-56 shrink-0 flex-col"
|
|
190
|
+
>
|
|
191
|
+
<div
|
|
192
|
+
class="row pl-2"
|
|
193
|
+
:class="viewMode === 'content' ? 'bg-[color-mix(in_srgb,var(--primary)_10%,white)] text-(--primary)' : 'text-zinc-700 hover:bg-zinc-50'"
|
|
194
|
+
@click="selectContent()"
|
|
195
|
+
>
|
|
196
|
+
<Icon
|
|
197
|
+
icon="fluent:apps-list-20-regular"
|
|
198
|
+
class="size-4 shrink-0"
|
|
199
|
+
/>
|
|
200
|
+
<span class="flex-1 truncate">内容</span>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<div
|
|
204
|
+
class="row pl-2"
|
|
205
|
+
:class="viewMode === 'badge' ? 'bg-[color-mix(in_srgb,var(--primary)_10%,white)] text-(--primary)' : 'text-zinc-700 hover:bg-zinc-50'"
|
|
206
|
+
@click="selectBadge()"
|
|
207
|
+
>
|
|
208
|
+
<Icon
|
|
209
|
+
icon="fluent:badge-20-regular"
|
|
210
|
+
class="size-4 shrink-0"
|
|
211
|
+
/>
|
|
212
|
+
<span class="flex-1 truncate">徽章</span>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<div
|
|
216
|
+
class="row pl-2"
|
|
217
|
+
:class="viewMode === 'general' ? 'bg-[color-mix(in_srgb,var(--primary)_10%,white)] text-(--primary)' : 'text-zinc-700 hover:bg-zinc-50'"
|
|
218
|
+
@click="selectGeneral()"
|
|
219
|
+
>
|
|
220
|
+
<Icon
|
|
221
|
+
icon="fluent:settings-20-regular"
|
|
222
|
+
class="size-4 shrink-0"
|
|
223
|
+
/>
|
|
224
|
+
<span class="flex-1 truncate">通用配置</span>
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
<Separator class="my-2" />
|
|
228
|
+
|
|
229
|
+
<!-- Layouts of the slot -->
|
|
230
|
+
<div class="flex flex-1 min-h-0 flex-col">
|
|
231
|
+
<ScrollArea class="flex-1">
|
|
232
|
+
<LayoutsSidebar
|
|
233
|
+
:model-value="editor.layouts.value"
|
|
234
|
+
:active-index="editor.activeLayoutIndex.value"
|
|
235
|
+
@update:model-value="(v) => {
|
|
236
|
+
editor.layouts.value = v;
|
|
237
|
+
}"
|
|
238
|
+
@update:active-index="selectLayout"
|
|
239
|
+
/>
|
|
240
|
+
</ScrollArea>
|
|
241
|
+
<Button
|
|
242
|
+
variant="ghost"
|
|
243
|
+
size="sm"
|
|
244
|
+
class="w-full justify-start"
|
|
245
|
+
@click="addLayout()"
|
|
246
|
+
>
|
|
247
|
+
<Icon
|
|
248
|
+
icon="fluent:add-20-regular"
|
|
249
|
+
class="size-4"
|
|
250
|
+
/>
|
|
251
|
+
<span>新增布局</span>
|
|
252
|
+
</Button>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
|
|
256
|
+
<!-- Right pane -->
|
|
257
|
+
<div class="flex min-w-0 flex-1 flex-col gap-3">
|
|
258
|
+
<!-- Drilled into a child block -->
|
|
259
|
+
<template v-if="drilledBlockId">
|
|
260
|
+
<div
|
|
261
|
+
v-if="!drilledBlock"
|
|
262
|
+
class="flex min-h-96 items-center justify-center p-8 text-sm text-zinc-400"
|
|
263
|
+
>
|
|
264
|
+
块已不存在
|
|
265
|
+
</div>
|
|
266
|
+
<div v-else-if="drilledEntry">
|
|
267
|
+
<component
|
|
268
|
+
:is="drilledEntry.config"
|
|
269
|
+
:model-value="drilledBlock"
|
|
270
|
+
:configure="configure"
|
|
271
|
+
@update:model-value="(next) => updateDrilledBlock(next)"
|
|
272
|
+
/>
|
|
273
|
+
</div>
|
|
274
|
+
<div
|
|
275
|
+
v-else
|
|
276
|
+
class="p-6 text-sm text-red-500"
|
|
277
|
+
>
|
|
278
|
+
未注册的块类型:{{ drilledBlock.type }}@{{ drilledBlock.compatibilityDate }}
|
|
279
|
+
</div>
|
|
280
|
+
</template>
|
|
281
|
+
|
|
282
|
+
<!-- General block-level settings. -->
|
|
283
|
+
<template v-else-if="viewMode === 'general'">
|
|
284
|
+
<Field orientation="vertical">
|
|
285
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
286
|
+
<template
|
|
287
|
+
v-if="fieldDescription('displayName')"
|
|
288
|
+
#tooltip
|
|
289
|
+
>
|
|
290
|
+
<Markdown
|
|
291
|
+
:source="fieldDescription('displayName')"
|
|
292
|
+
block
|
|
293
|
+
class="prose prose-sm prose-zinc"
|
|
294
|
+
/>
|
|
295
|
+
</template>
|
|
296
|
+
{{ fieldTitle("displayName") }}
|
|
297
|
+
</FieldLabel>
|
|
298
|
+
<InputGroup>
|
|
299
|
+
<InputGroupInput
|
|
300
|
+
:model-value="block.displayName ?? ''"
|
|
301
|
+
placeholder="例:概览卡片"
|
|
302
|
+
@update:model-value="setDisplayName"
|
|
303
|
+
/>
|
|
304
|
+
</InputGroup>
|
|
305
|
+
</Field>
|
|
306
|
+
|
|
307
|
+
<Field orientation="vertical">
|
|
308
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
309
|
+
<template
|
|
310
|
+
v-if="fieldDescription('style')"
|
|
311
|
+
#tooltip
|
|
312
|
+
>
|
|
313
|
+
<Markdown
|
|
314
|
+
:source="fieldDescription('style')"
|
|
315
|
+
block
|
|
316
|
+
class="prose prose-sm prose-zinc"
|
|
317
|
+
/>
|
|
318
|
+
</template>
|
|
319
|
+
{{ fieldTitle("style") }}
|
|
320
|
+
</FieldLabel>
|
|
321
|
+
<ExpressionEditor
|
|
322
|
+
:model-value="block.style ?? ''"
|
|
323
|
+
placeholder="返回 CSS 字符串或样式对象的表达式,如 'padding: 2rem'"
|
|
324
|
+
multiline
|
|
325
|
+
class="min-h-16"
|
|
326
|
+
@update:model-value="(v) => setStyle(v)"
|
|
327
|
+
/>
|
|
328
|
+
</Field>
|
|
329
|
+
|
|
330
|
+
<Field orientation="vertical">
|
|
331
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
332
|
+
<template
|
|
333
|
+
v-if="fieldDescription('url')"
|
|
334
|
+
#tooltip
|
|
335
|
+
>
|
|
336
|
+
<Markdown
|
|
337
|
+
:source="fieldDescription('url')"
|
|
338
|
+
block
|
|
339
|
+
class="prose prose-sm prose-zinc"
|
|
340
|
+
/>
|
|
341
|
+
</template>
|
|
342
|
+
{{ fieldTitle("url") }}
|
|
343
|
+
</FieldLabel>
|
|
344
|
+
<ExpressionEditor
|
|
345
|
+
:model-value="block.url ?? ''"
|
|
346
|
+
placeholder="可选;返回链接的表达式,如 '/detail/' + string(row.id)"
|
|
347
|
+
result-type="string"
|
|
348
|
+
@update:model-value="(v) => setUrl(v)"
|
|
349
|
+
/>
|
|
350
|
+
</Field>
|
|
351
|
+
</template>
|
|
352
|
+
|
|
353
|
+
<!-- Badge settings. -->
|
|
354
|
+
<template v-else-if="viewMode === 'badge'">
|
|
355
|
+
<Field orientation="vertical">
|
|
356
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
357
|
+
<template
|
|
358
|
+
v-if="badgeDescription('content')"
|
|
359
|
+
#tooltip
|
|
360
|
+
>
|
|
361
|
+
<Markdown
|
|
362
|
+
:source="badgeDescription('content')"
|
|
363
|
+
block
|
|
364
|
+
class="prose prose-sm prose-zinc"
|
|
365
|
+
/>
|
|
366
|
+
</template>
|
|
367
|
+
{{ badgeTitle("content") }}
|
|
368
|
+
</FieldLabel>
|
|
369
|
+
<LocaleField
|
|
370
|
+
markdown
|
|
371
|
+
translate-hint="card badge content"
|
|
372
|
+
:model-value="badge.content"
|
|
373
|
+
@update:model-value="setBadgeContent"
|
|
374
|
+
/>
|
|
375
|
+
</Field>
|
|
376
|
+
|
|
377
|
+
<Field orientation="vertical">
|
|
378
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
379
|
+
<template
|
|
380
|
+
v-if="badgeDescription('request')"
|
|
381
|
+
#tooltip
|
|
382
|
+
>
|
|
383
|
+
<Markdown
|
|
384
|
+
:source="badgeDescription('request')"
|
|
385
|
+
block
|
|
386
|
+
class="prose prose-sm prose-zinc"
|
|
387
|
+
/>
|
|
388
|
+
</template>
|
|
389
|
+
{{ badgeTitle("request") }}
|
|
390
|
+
</FieldLabel>
|
|
391
|
+
<ExpressionEditor
|
|
392
|
+
:model-value="badge.request ?? ''"
|
|
393
|
+
placeholder="可选;如 http.get('/api/notifications')"
|
|
394
|
+
result-type="HttpRequest"
|
|
395
|
+
multiline
|
|
396
|
+
class="min-h-20"
|
|
397
|
+
@update:model-value="(v) => setBadgeRequest(v)"
|
|
398
|
+
/>
|
|
399
|
+
</Field>
|
|
400
|
+
|
|
401
|
+
<div class="grid grid-cols-2 gap-3">
|
|
402
|
+
<Field orientation="vertical">
|
|
403
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
404
|
+
<template
|
|
405
|
+
v-if="badgeDescription('interval')"
|
|
406
|
+
#tooltip
|
|
407
|
+
>
|
|
408
|
+
<Markdown
|
|
409
|
+
:source="badgeDescription('interval')"
|
|
410
|
+
block
|
|
411
|
+
class="prose prose-sm prose-zinc"
|
|
412
|
+
/>
|
|
413
|
+
</template>
|
|
414
|
+
{{ badgeTitle("interval") }}
|
|
415
|
+
</FieldLabel>
|
|
416
|
+
<InputGroup>
|
|
417
|
+
<InputGroupNumberField
|
|
418
|
+
:model-value="badge.interval"
|
|
419
|
+
:min="1"
|
|
420
|
+
@update:model-value="(v) => setBadgeInterval(v)"
|
|
421
|
+
/>
|
|
422
|
+
</InputGroup>
|
|
423
|
+
</Field>
|
|
424
|
+
|
|
425
|
+
<Field orientation="vertical">
|
|
426
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
427
|
+
<template
|
|
428
|
+
v-if="badgeDescription('variant')"
|
|
429
|
+
#tooltip
|
|
430
|
+
>
|
|
431
|
+
<Markdown
|
|
432
|
+
:source="badgeDescription('variant')"
|
|
433
|
+
block
|
|
434
|
+
class="prose prose-sm prose-zinc"
|
|
435
|
+
/>
|
|
436
|
+
</template>
|
|
437
|
+
{{ badgeTitle("variant") }}
|
|
438
|
+
</FieldLabel>
|
|
439
|
+
<Select
|
|
440
|
+
:model-value="badge.variant ?? 'default'"
|
|
441
|
+
@update:model-value="setBadgeVariant"
|
|
442
|
+
>
|
|
443
|
+
<SelectTrigger class="w-full">
|
|
444
|
+
<SelectValue />
|
|
445
|
+
</SelectTrigger>
|
|
446
|
+
<SelectContent>
|
|
447
|
+
<SelectItem
|
|
448
|
+
v-for="opt in BADGE_VARIANTS"
|
|
449
|
+
:key="opt"
|
|
450
|
+
:value="opt"
|
|
451
|
+
>
|
|
452
|
+
{{ BADGE_VARIANT_LABELS[opt] }}
|
|
453
|
+
</SelectItem>
|
|
454
|
+
</SelectContent>
|
|
455
|
+
</Select>
|
|
456
|
+
</Field>
|
|
457
|
+
</div>
|
|
458
|
+
|
|
459
|
+
<Field orientation="horizontal">
|
|
460
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
461
|
+
<template
|
|
462
|
+
v-if="badgeDescription('dot')"
|
|
463
|
+
#tooltip
|
|
464
|
+
>
|
|
465
|
+
<Markdown
|
|
466
|
+
:source="badgeDescription('dot')"
|
|
467
|
+
block
|
|
468
|
+
class="prose prose-sm prose-zinc"
|
|
469
|
+
/>
|
|
470
|
+
</template>
|
|
471
|
+
{{ badgeTitle("dot") }}
|
|
472
|
+
</FieldLabel>
|
|
473
|
+
<Switch
|
|
474
|
+
:model-value="badge.dot ?? false"
|
|
475
|
+
@update:model-value="setBadgeDot"
|
|
476
|
+
/>
|
|
477
|
+
</Field>
|
|
478
|
+
</template>
|
|
479
|
+
|
|
480
|
+
<!-- Content: slot layout editor. -->
|
|
481
|
+
<template v-else>
|
|
482
|
+
<LayoutMetaStrip
|
|
483
|
+
:model-value="editor.layouts.value"
|
|
484
|
+
:index="editor.activeLayoutIndex.value"
|
|
485
|
+
@update:model-value="(v) => {
|
|
486
|
+
editor.layouts.value = v;
|
|
487
|
+
}"
|
|
488
|
+
/>
|
|
489
|
+
<div class="flex-1">
|
|
490
|
+
<BlockLayoutEditor
|
|
491
|
+
:model-value="editor.layouts.value"
|
|
492
|
+
:active-index="editor.activeLayoutIndex.value"
|
|
493
|
+
:selected-item-ids="editor.selectedBlockIds.value"
|
|
494
|
+
:items="editor.blocks.value"
|
|
495
|
+
:find-entry="editor.findBlockMeta"
|
|
496
|
+
:get-item-label="editor.getBlockLabel"
|
|
497
|
+
:picker-entries="editor.pickerEntries.value"
|
|
498
|
+
:can-delete="true"
|
|
499
|
+
item-noun="块"
|
|
500
|
+
@update:model-value="(v) => {
|
|
501
|
+
editor.layouts.value = v;
|
|
502
|
+
}"
|
|
503
|
+
@update:active-index="(v) => {
|
|
504
|
+
editor.activeLayoutIndex.value = v;
|
|
505
|
+
}"
|
|
506
|
+
@update:selected-item-ids="(v) => {
|
|
507
|
+
editor.selectedBlockIds.value = v;
|
|
508
|
+
}"
|
|
509
|
+
@add-new="addBlock"
|
|
510
|
+
@drill-down="onDrillDown"
|
|
511
|
+
@delete-item="(id) => editor.removeBlock(id)"
|
|
512
|
+
@delete-items="(ids) => editor.removeBlocks(ids)"
|
|
513
|
+
/>
|
|
514
|
+
</div>
|
|
515
|
+
</template>
|
|
516
|
+
</div>
|
|
517
|
+
</div>
|
|
518
|
+
</template>
|
|
519
|
+
|
|
520
|
+
<style scoped>
|
|
521
|
+
.row{align-items:center;border-radius:.25rem;cursor:pointer;display:flex;font-size:.875rem;gap:.375rem;padding-block:.375rem;padding-left:.5rem;padding-right:.5rem;position:relative;transition:background-color .1s ease;-webkit-user-select:none;-moz-user-select:none;user-select:none}
|
|
522
|
+
</style>
|
package/dist/runtime/components/config/blocks/2026-06-02/com.shwfed.block.card/config.vue.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { Environment } from '../../../../../vendor/cel-js/lib/index.js';
|
|
2
|
+
import { type Value } from './schema.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
configure?: (env: Environment) => void;
|
|
5
|
+
};
|
|
6
|
+
type __VLS_ModelProps = {
|
|
7
|
+
modelValue: Value;
|
|
8
|
+
};
|
|
9
|
+
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
"update:modelValue": (value: {
|
|
12
|
+
readonly type: "com.shwfed.block.card";
|
|
13
|
+
readonly style?: string | undefined;
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly slot: {
|
|
16
|
+
readonly blocks: readonly any[];
|
|
17
|
+
readonly layouts: readonly {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly layout: {
|
|
20
|
+
readonly style?: string | undefined;
|
|
21
|
+
readonly columns: number;
|
|
22
|
+
readonly gap?: number | undefined;
|
|
23
|
+
readonly rows?: number | undefined;
|
|
24
|
+
readonly placements: {
|
|
25
|
+
readonly [x: string]: {
|
|
26
|
+
readonly area: readonly [readonly [number, number], readonly [number, number]];
|
|
27
|
+
readonly v?: "stretch" | "center" | "end" | "start" | undefined;
|
|
28
|
+
readonly h?: "stretch" | "center" | "end" | "start" | undefined;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
readonly media?: string | undefined;
|
|
33
|
+
}[];
|
|
34
|
+
};
|
|
35
|
+
readonly displayName?: string | undefined;
|
|
36
|
+
readonly url?: string | undefined;
|
|
37
|
+
readonly compatibilityDate: "2026-06-02";
|
|
38
|
+
readonly badge?: {
|
|
39
|
+
readonly content?: readonly [{
|
|
40
|
+
readonly locale: "zh";
|
|
41
|
+
readonly message: string;
|
|
42
|
+
}, ...{
|
|
43
|
+
readonly locale: "en" | "ja" | "ko";
|
|
44
|
+
readonly message: string;
|
|
45
|
+
}[]] | undefined;
|
|
46
|
+
readonly dot?: boolean | undefined;
|
|
47
|
+
readonly variant?: "default" | "destructive" | "outline" | "secondary" | undefined;
|
|
48
|
+
readonly request?: string | undefined;
|
|
49
|
+
readonly interval?: number | undefined;
|
|
50
|
+
} | undefined;
|
|
51
|
+
}) => any;
|
|
52
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
53
|
+
"onUpdate:modelValue"?: ((value: {
|
|
54
|
+
readonly type: "com.shwfed.block.card";
|
|
55
|
+
readonly style?: string | undefined;
|
|
56
|
+
readonly id: string;
|
|
57
|
+
readonly slot: {
|
|
58
|
+
readonly blocks: readonly any[];
|
|
59
|
+
readonly layouts: readonly {
|
|
60
|
+
readonly name: string;
|
|
61
|
+
readonly layout: {
|
|
62
|
+
readonly style?: string | undefined;
|
|
63
|
+
readonly columns: number;
|
|
64
|
+
readonly gap?: number | undefined;
|
|
65
|
+
readonly rows?: number | undefined;
|
|
66
|
+
readonly placements: {
|
|
67
|
+
readonly [x: string]: {
|
|
68
|
+
readonly area: readonly [readonly [number, number], readonly [number, number]];
|
|
69
|
+
readonly v?: "stretch" | "center" | "end" | "start" | undefined;
|
|
70
|
+
readonly h?: "stretch" | "center" | "end" | "start" | undefined;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
readonly media?: string | undefined;
|
|
75
|
+
}[];
|
|
76
|
+
};
|
|
77
|
+
readonly displayName?: string | undefined;
|
|
78
|
+
readonly url?: string | undefined;
|
|
79
|
+
readonly compatibilityDate: "2026-06-02";
|
|
80
|
+
readonly badge?: {
|
|
81
|
+
readonly content?: readonly [{
|
|
82
|
+
readonly locale: "zh";
|
|
83
|
+
readonly message: string;
|
|
84
|
+
}, ...{
|
|
85
|
+
readonly locale: "en" | "ja" | "ko";
|
|
86
|
+
readonly message: string;
|
|
87
|
+
}[]] | undefined;
|
|
88
|
+
readonly dot?: boolean | undefined;
|
|
89
|
+
readonly variant?: "default" | "destructive" | "outline" | "secondary" | undefined;
|
|
90
|
+
readonly request?: string | undefined;
|
|
91
|
+
readonly interval?: number | undefined;
|
|
92
|
+
} | undefined;
|
|
93
|
+
}) => any) | undefined;
|
|
94
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
95
|
+
declare const _default: typeof __VLS_export;
|
|
96
|
+
export default _default;
|