Schema-driven edit components

One form rendered from the field schema your API sends, the per-field controls that go with it, and the diff / proposal / revision views for reviewing what someone changed. Composes KunUI and ships no CSS of its own.

Integration guide GitHub v0.1.1 on npm AGPL-3.0-only
install
pnpm add @nextmoe/edit-ui-nuxt @nextmoe/edit-ui-vue @nextmoe/edit-ui-core
@nextmoe/edit-ui-core

Framework-free TypeScript: the wire/schema types plus the pure diff, formatting and badge helpers. No Vue in its dependency closure.

@nextmoe/edit-ui-vue

The Vue 3 components — the schema form, the per-field controls, the diff / proposal / revision views. Ships no CSS of its own.

@nextmoe/edit-ui-nuxt

A Nuxt module that auto-imports every component under a configurable prefix (default Edit), so templates need no imports.

Everything below is live

The schema, the values and the injected functions (upload / search / resolve) are local fixtures, so this page never touches a network. The components' own built-in strings are zh-CN today; every field label you see comes from the site's config, not from the package.

Full configuration

Every control the package ships, grouped into sections, in both layouts. The last field carries a control the package does not know — it degrades to a read-only display instead of throwing.

update:patch — only the fields that actually differ from the server values, deep-compared. Edit anything above to see it appear.

{}

Minimal configuration

The same component with three fields and no groups. This is the smallest useful integration.

script
import type { EditFieldConfigMap } from '@nextmoe/edit-ui-vue'

// `fields` and `values` come from your API. `config` is the presentation
// layer only the site knows about — labels, controls, placeholders.
const config: EditFieldConfigMap = {
  title: { label: 'Title', control: 'input' },
  intro: { label: 'Intro', control: 'textarea' },
  aliases: { label: 'Aliases', control: 'string-list' }
}
template
<EditSchemaForm
  :fields="fields"
  :values="values"
  :config="config"
  @update:patch="(value) => (patch = value)"
/>

Field diffs

FieldDiff routes one field's before/after by its diff_hint.

  • diff_hint: inlineWord-level text diff (Intl.Segmenter, so CJK splits on words).
  • diff_hint: linesSame diff, whitespace preserved, long runs elided.
  • diff_hint: itemsList membership: added / removed / kept.
  • diff_hint: imageOnly the pictures that changed — never the whole gallery.

标题

+1
ひぐらしのなく頃に

简介

+3 −2
雏见泽村,昭和五十八年六月。 绵流之夜,连续怪死事件再度第四次上演。

别名

− Higurashi
+ 寒蝉鸣泣之时 礼

画廊

+1 −11 张未改动
+

Review and history

The proposal queue and the revision timeline — the read side of an edit workflow.

ReviewQueue + ProposalCard

Proposals by status, with the patched field labels resolved through the labelFor function the site supplies.

待审核 提案 #101 审核修正 ×1
标题别名

补一个别名,顺便修标题的空格

提案人:鲲

RevisionTimeline

Pick any two revisions and it emits diff(fromSeq, toSeq) — fetching that diff is the site's job.

点击任意两个版本进行对比

#9合并提案

修改字段: 标题、别名

编辑者
鲲
审核者
梨花
梨花
#8直接编辑

修改字段: 画廊

编辑者
梨花
梨花
#1创建 迁移 · 导入 小修改

从旧 wiki 迁入

编辑者
鲲

Wire it into your app

Two paths: a Nuxt module that auto-imports every component, or direct imports in any Vue 3 app. Both need one Tailwind @source line that is easy to miss.