@bettercms-ai/kit 2.0.0 → 2.0.1

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 (120) hide show
  1. package/dist/adapters/lossy.d.ts +12 -4
  2. package/dist/adapters/lossy.js +19 -8
  3. package/dist/adapters/lossy.js.map +1 -1
  4. package/dist/adapters/prod-types.d.ts +46 -14
  5. package/dist/adapters/prod-types.js +37 -35
  6. package/dist/adapters/prod-types.js.map +1 -1
  7. package/dist/adapters/schema.d.ts +39 -0
  8. package/dist/adapters/schema.js +281 -82
  9. package/dist/adapters/schema.js.map +1 -1
  10. package/dist/context.d.ts +39 -0
  11. package/dist/context.js +40 -1
  12. package/dist/context.js.map +1 -1
  13. package/dist/controls/form-picker-register.d.ts +7 -1
  14. package/dist/controls/form-picker-register.js +1 -5
  15. package/dist/controls/form-picker-register.js.map +1 -1
  16. package/dist/controls/icon.d.ts +1 -1
  17. package/dist/controls/icon.js +1 -1
  18. package/dist/controls/icon.js.map +1 -1
  19. package/dist/controls/link.d.ts +11 -4
  20. package/dist/controls/link.js +120 -202
  21. package/dist/controls/link.js.map +1 -1
  22. package/dist/controls/location.js +3 -8
  23. package/dist/controls/location.js.map +1 -1
  24. package/dist/controls/media.d.ts +0 -14
  25. package/dist/controls/media.js +52 -95
  26. package/dist/controls/media.js.map +1 -1
  27. package/dist/controls/reference-services.d.ts +23 -2
  28. package/dist/controls/reference.d.ts +2 -2
  29. package/dist/controls/reference.js +79 -28
  30. package/dist/controls/reference.js.map +1 -1
  31. package/dist/controls/rich-text/article-shell.d.ts +145 -0
  32. package/dist/controls/rich-text/article-shell.js +514 -0
  33. package/dist/controls/rich-text/article-shell.js.map +1 -0
  34. package/dist/controls/rich-text/author.d.ts +25 -0
  35. package/dist/controls/rich-text/author.js +107 -0
  36. package/dist/controls/rich-text/author.js.map +1 -0
  37. package/dist/controls/rich-text/blocks.d.ts +19 -2
  38. package/dist/controls/rich-text/blocks.js +275 -638
  39. package/dist/controls/rich-text/blocks.js.map +1 -1
  40. package/dist/controls/rich-text/button.d.ts +23 -0
  41. package/dist/controls/rich-text/button.js +81 -0
  42. package/dist/controls/rich-text/button.js.map +1 -0
  43. package/dist/controls/rich-text/catalog.d.ts +2 -5
  44. package/dist/controls/rich-text/catalog.js +121 -7
  45. package/dist/controls/rich-text/catalog.js.map +1 -1
  46. package/dist/controls/rich-text/checklist.d.ts +24 -0
  47. package/dist/controls/rich-text/checklist.js +115 -0
  48. package/dist/controls/rich-text/checklist.js.map +1 -0
  49. package/dist/controls/rich-text/codec.d.ts +15 -1
  50. package/dist/controls/rich-text/codec.js +11 -1
  51. package/dist/controls/rich-text/codec.js.map +1 -1
  52. package/dist/controls/rich-text/columns.d.ts +41 -0
  53. package/dist/controls/rich-text/columns.js +181 -0
  54. package/dist/controls/rich-text/columns.js.map +1 -0
  55. package/dist/controls/rich-text/control.js +1 -0
  56. package/dist/controls/rich-text/control.js.map +1 -1
  57. package/dist/controls/rich-text/dom.d.ts +84 -4
  58. package/dist/controls/rich-text/dom.js +171 -10
  59. package/dist/controls/rich-text/dom.js.map +1 -1
  60. package/dist/controls/rich-text/editor.d.ts +4 -2
  61. package/dist/controls/rich-text/editor.js +199 -26
  62. package/dist/controls/rich-text/editor.js.map +1 -1
  63. package/dist/controls/rich-text/embed.d.ts +28 -0
  64. package/dist/controls/rich-text/embed.js +210 -0
  65. package/dist/controls/rich-text/embed.js.map +1 -0
  66. package/dist/controls/rich-text/footnote.d.ts +41 -0
  67. package/dist/controls/rich-text/footnote.js +185 -0
  68. package/dist/controls/rich-text/footnote.js.map +1 -0
  69. package/dist/controls/rich-text/gallery.d.ts +28 -0
  70. package/dist/controls/rich-text/gallery.js +167 -0
  71. package/dist/controls/rich-text/gallery.js.map +1 -0
  72. package/dist/controls/rich-text/link-form.d.ts +13 -1
  73. package/dist/controls/rich-text/link-form.js +41 -7
  74. package/dist/controls/rich-text/link-form.js.map +1 -1
  75. package/dist/controls/rich-text/ops.js +6 -0
  76. package/dist/controls/rich-text/ops.js.map +1 -1
  77. package/dist/controls/rich-text/related.d.ts +49 -0
  78. package/dist/controls/rich-text/related.js +233 -0
  79. package/dist/controls/rich-text/related.js.map +1 -0
  80. package/dist/controls/rich-text/toc.d.ts +47 -0
  81. package/dist/controls/rich-text/toc.js +160 -0
  82. package/dist/controls/rich-text/toc.js.map +1 -0
  83. package/dist/controls/slot-register.d.ts +6 -1
  84. package/dist/controls/slot-register.js +1 -4
  85. package/dist/controls/slot-register.js.map +1 -1
  86. package/dist/core/core.d.ts +11 -3
  87. package/dist/core/core.js +24 -6
  88. package/dist/core/core.js.map +1 -1
  89. package/dist/core/facets.d.ts +16 -0
  90. package/dist/core/facets.js +17 -1
  91. package/dist/core/facets.js.map +1 -1
  92. package/dist/core/index.js +2 -2
  93. package/dist/index.js +16 -5
  94. package/dist/index.js.map +1 -1
  95. package/dist/ledgers/exclusions.v1.js +141 -0
  96. package/dist/ledgers/exclusions.v1.js.map +1 -0
  97. package/dist/library/coverage.d.ts +13 -1
  98. package/dist/library/coverage.js +12 -1
  99. package/dist/library/coverage.js.map +1 -1
  100. package/dist/library/kit-catalog.json +156 -153
  101. package/dist/schema/types.d.ts +17 -0
  102. package/dist/schema/types.js.map +1 -1
  103. package/dist/styles.css +1 -1
  104. package/dist/testing/coverage-extras.d.ts +8 -0
  105. package/dist/testing/coverage-extras.js +44 -0
  106. package/dist/testing/coverage-extras.js.map +1 -0
  107. package/dist/testing/exclusions.d.ts +30 -0
  108. package/dist/testing/exclusions.js +13 -0
  109. package/dist/testing/exclusions.js.map +1 -0
  110. package/dist/ui/autocomplete.d.ts +29 -1
  111. package/dist/ui/autocomplete.js +102 -47
  112. package/dist/ui/autocomplete.js.map +1 -1
  113. package/dist/ui/button.js +3 -5
  114. package/dist/ui/button.js.map +1 -1
  115. package/dist/ui/index.js +2 -2
  116. package/dist/ui/overlay.d.ts +4 -1
  117. package/dist/ui/overlay.js +2 -1
  118. package/dist/ui/overlay.js.map +1 -1
  119. package/dist/ui/toast.js +1 -1
  120. package/package.json +8 -2
@@ -0,0 +1,107 @@
1
+ import { useRichTextRefs } from "../../context.js";
2
+ import { ArticleEmpty, ArticlePopoverBlock } from "./article-shell.js";
3
+ import * as React from "react";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { IconUserCircle } from "@tabler/icons-react";
6
+ //#region src/controls/rich-text/author.tsx
7
+ /**
8
+ * RICH TEXT · Author bio (kit-richtext-ui-spec.md §7): V2's article block, stored as the PT block object
9
+ * `{ _type: "authorBio", author: { _ref } }`. Name, avatar and bio are derived from the referenced entry, never stored.
10
+ *
11
+ * form V2 article.ts:196-202: one required reference, "Author"; its collection comes from the field's config
12
+ * (V2 hard-codes col_authors). One setting → the shell's popover (D54); a fresh insert opens it.
13
+ * preview V2 article-blocks.tsx:599-612: avatar, name and bio as the reader sees them; "Choose an author" when none
14
+ * data KitServices.resolveRichTextRefs through useRichTextRefs. V2 read a local store synchronously; the kit asks
15
+ * the host, so a resolving card keeps the card's shape (no "Choose an author" flash) and a failure is named.
16
+ */
17
+ var AUTHOR_LABEL = "Author bio";
18
+ var authorDefault = () => ({ author: "" });
19
+ /** The popover form; `to` is the authors collection from the field's config. */
20
+ var authorSchema = (to) => ({
21
+ name: "authorBio",
22
+ title: AUTHOR_LABEL,
23
+ kind: "object",
24
+ icon: "user",
25
+ fields: [{
26
+ name: "author",
27
+ title: "Author",
28
+ type: "reference",
29
+ reference: {
30
+ to,
31
+ noun: "author"
32
+ },
33
+ validation: { required: true }
34
+ }]
35
+ });
36
+ function AuthorPreview({ m, onPick, ro }) {
37
+ const { items, loading, error } = useRichTextRefs(m.author ? {
38
+ kind: "authorBio",
39
+ ids: [m.author]
40
+ } : null);
41
+ const a = items.find((x) => x.id === m.author);
42
+ if (!m.author || !loading && !error && !a) return /* @__PURE__ */ jsx(ArticleEmpty, {
43
+ icon: /* @__PURE__ */ jsx(IconUserCircle, { stroke: 1.5 }),
44
+ title: AUTHOR_LABEL,
45
+ action: "Choose an author",
46
+ onAction: onPick,
47
+ ro
48
+ });
49
+ return /* @__PURE__ */ jsxs("aside", {
50
+ className: "flex items-start gap-3.5 rounded-kit-lg border border-kit-line bg-kit-surface px-4 py-3.5",
51
+ "aria-label": a ? `About ${a.title}` : AUTHOR_LABEL,
52
+ "aria-busy": loading || void 0,
53
+ "data-field": "author",
54
+ children: [a?.avatar ? /* @__PURE__ */ jsx("img", {
55
+ src: a.avatar,
56
+ alt: "",
57
+ draggable: false,
58
+ className: "size-12 shrink-0 rounded-full border border-kit-line object-cover"
59
+ }) : /* @__PURE__ */ jsx("span", {
60
+ className: "flex size-12 shrink-0 items-center justify-center rounded-full bg-kit-muted text-kit-fg-3",
61
+ children: /* @__PURE__ */ jsx(IconUserCircle, {
62
+ className: "size-6",
63
+ stroke: 1.5
64
+ })
65
+ }), /* @__PURE__ */ jsx("div", {
66
+ className: "min-w-0 flex-1",
67
+ children: a ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
68
+ className: "text-kit-sm font-semibold text-kit-fg",
69
+ children: a.title
70
+ }), a.bio ? /* @__PURE__ */ jsx("p", {
71
+ className: "mt-0.5 text-kit-sm leading-relaxed text-kit-fg-2",
72
+ children: a.bio
73
+ }) : null] }) : error ? /* @__PURE__ */ jsxs("p", {
74
+ role: "status",
75
+ className: "text-kit-sm text-kit-warning-fg",
76
+ children: ["The author couldn't load: ", error]
77
+ }) : /* @__PURE__ */ jsx("p", {
78
+ className: "text-kit-sm text-kit-fg-3",
79
+ children: "Loading the author…"
80
+ })
81
+ })]
82
+ });
83
+ }
84
+ function AuthorBlock({ m, set, el, ctx, autoFocus, collection }) {
85
+ const schema = React.useMemo(() => authorSchema([collection]), [collection]);
86
+ return /* @__PURE__ */ jsx(ArticlePopoverBlock, {
87
+ label: AUTHOR_LABEL,
88
+ kind: "author",
89
+ schema,
90
+ m,
91
+ set,
92
+ el,
93
+ ctx,
94
+ autoFocus,
95
+ toForm: (x) => ({ author: x.author || void 0 }),
96
+ fromForm: (v) => ({ author: typeof v.author === "string" ? v.author : "" }),
97
+ children: (open, ro) => /* @__PURE__ */ jsx(AuthorPreview, {
98
+ m,
99
+ onPick: () => open("author"),
100
+ ro
101
+ })
102
+ });
103
+ }
104
+ //#endregion
105
+ export { AUTHOR_LABEL, AuthorBlock, AuthorPreview, authorDefault, authorSchema };
106
+
107
+ //# sourceMappingURL=author.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"author.js","names":[],"sources":["../../../src/controls/rich-text/author.tsx"],"sourcesContent":["/**\n * RICH TEXT · Author bio (kit-richtext-ui-spec.md §7): V2's article block, stored as the PT block object\n * `{ _type: \"authorBio\", author: { _ref } }`. Name, avatar and bio are derived from the referenced entry, never stored.\n *\n * form V2 article.ts:196-202: one required reference, \"Author\"; its collection comes from the field's config\n * (V2 hard-codes col_authors). One setting → the shell's popover (D54); a fresh insert opens it.\n * preview V2 article-blocks.tsx:599-612: avatar, name and bio as the reader sees them; \"Choose an author\" when none\n * data KitServices.resolveRichTextRefs through useRichTextRefs. V2 read a local store synchronously; the kit asks\n * the host, so a resolving card keeps the card's shape (no \"Choose an author\" flash) and a failure is named.\n */\nimport * as React from \"react\";\nimport { IconUserCircle } from \"@tabler/icons-react\";\nimport { useRichTextRefs } from \"../../context\";\nimport type { TypeSchema } from \"../../schema/types\";\nimport { ArticleEmpty, ArticlePopoverBlock } from \"./article-shell\";\nimport type { IslandCtx } from \"./blocks\";\nimport type { IslandEl } from \"./dom\";\n\n/** The editor's model: the referenced entry's id (\"\" = none picked). The PT form wraps it as `{ _ref }`. */\nexport interface AuthorModel {\n author: string;\n}\nexport const AUTHOR_LABEL = \"Author bio\";\nexport const authorDefault = (): AuthorModel => ({ author: \"\" });\n\n/** The popover form; `to` is the authors collection from the field's config. */\nexport const authorSchema = (to: string[]): TypeSchema => ({\n name: \"authorBio\",\n title: AUTHOR_LABEL,\n kind: \"object\",\n icon: \"user\",\n // V2 ART:196-202 names the picker's record an author: \"Select an author\", \"Create new author\"\n fields: [{ name: \"author\", title: \"Author\", type: \"reference\", reference: { to, noun: \"author\" }, validation: { required: true } }],\n});\n\nexport function AuthorPreview({ m, onPick, ro }: { m: AuthorModel; onPick: () => void; ro: boolean }) {\n const { items, loading, error } = useRichTextRefs(m.author ? { kind: \"authorBio\", ids: [m.author] } : null);\n const a = items.find((x) => x.id === m.author);\n if (!m.author || (!loading && !error && !a))\n return <ArticleEmpty icon={<IconUserCircle stroke={1.5} />} title={AUTHOR_LABEL} action=\"Choose an author\" onAction={onPick} ro={ro} />;\n return (\n <aside\n className=\"flex items-start gap-3.5 rounded-kit-lg border border-kit-line bg-kit-surface px-4 py-3.5\"\n aria-label={a ? `About ${a.title}` : AUTHOR_LABEL}\n aria-busy={loading || undefined}\n data-field=\"author\"\n >\n {a?.avatar ? (\n <img src={a.avatar} alt=\"\" draggable={false} className=\"size-12 shrink-0 rounded-full border border-kit-line object-cover\" />\n ) : (\n <span className=\"flex size-12 shrink-0 items-center justify-center rounded-full bg-kit-muted text-kit-fg-3\">\n <IconUserCircle className=\"size-6\" stroke={1.5} />\n </span>\n )}\n <div className=\"min-w-0 flex-1\">\n {a ? (\n <>\n <p className=\"text-kit-sm font-semibold text-kit-fg\">{a.title}</p>\n {a.bio ? <p className=\"mt-0.5 text-kit-sm leading-relaxed text-kit-fg-2\">{a.bio}</p> : null}\n </>\n ) : error ? (\n <p role=\"status\" className=\"text-kit-sm text-kit-warning-fg\">\n The author couldn't load: {error}\n </p>\n ) : (\n <p className=\"text-kit-sm text-kit-fg-3\">Loading the author…</p>\n )}\n </div>\n </aside>\n );\n}\n\nexport function AuthorBlock({\n m, set, el, ctx, autoFocus, collection,\n}: {\n m: AuthorModel;\n set: (fn: (m: AuthorModel) => AuthorModel, label?: string) => void;\n el: IslandEl;\n ctx: IslandCtx;\n autoFocus: boolean;\n /** the authors collection the reference picks from (the field's config) */\n collection: string;\n}) {\n const schema = React.useMemo(() => authorSchema([collection]), [collection]);\n return (\n <ArticlePopoverBlock<AuthorModel>\n label={AUTHOR_LABEL}\n kind=\"author\"\n schema={schema}\n m={m}\n set={set}\n el={el}\n ctx={ctx}\n autoFocus={autoFocus}\n toForm={(x) => ({ author: x.author || undefined })}\n fromForm={(v) => ({ author: typeof v.author === \"string\" ? v.author : \"\" })}\n >\n {(open, ro) => <AuthorPreview m={m} onPick={() => open(\"author\")} ro={ro} />}\n </ArticlePopoverBlock>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAsBA,IAAa,eAAe;AAC5B,IAAa,uBAAoC,EAAE,QAAQ,GAAG;;AAG9D,IAAa,gBAAgB,QAA8B;CACzD,MAAM;CACN,OAAO;CACP,MAAM;CACN,MAAM;CAEN,QAAQ,CAAC;EAAE,MAAM;EAAU,OAAO;EAAU,MAAM;EAAa,WAAW;GAAE;GAAI,MAAM;EAAS;EAAG,YAAY,EAAE,UAAU,KAAK;CAAE,CAAC;AACpI;AAEA,SAAgB,cAAc,EAAE,GAAG,QAAQ,MAA2D;CACpG,MAAM,EAAE,OAAO,SAAS,UAAU,gBAAgB,EAAE,SAAS;EAAE,MAAM;EAAa,KAAK,CAAC,EAAE,MAAM;CAAE,IAAI,IAAI;CAC1G,MAAM,IAAI,MAAM,MAAM,MAAM,EAAE,OAAO,EAAE,MAAM;CAC7C,IAAI,CAAC,EAAE,UAAW,CAAC,WAAW,CAAC,SAAS,CAAC,GACvC,OAAO,oBAAC,cAAD;EAAc,MAAM,oBAAC,gBAAD,EAAgB,QAAQ,IAAM,CAAA;EAAG,OAAO;EAAc,QAAO;EAAmB,UAAU;EAAY;CAAK,CAAA;CACxI,OACE,qBAAC,SAAD;EACE,WAAU;EACV,cAAY,IAAI,SAAS,EAAE,UAAU;EACrC,aAAW,WAAW,KAAA;EACtB,cAAW;EAJb,UAAA,CAMG,GAAG,SACF,oBAAC,OAAD;GAAK,KAAK,EAAE;GAAQ,KAAI;GAAG,WAAW;GAAO,WAAU;EAAqE,CAAA,IAE5H,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAAC,gBAAD;IAAgB,WAAU;IAAS,QAAQ;GAAM,CAAA;EAC7C,CAAA,GAER,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA,IACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,KAAD;IAAG,WAAU;IAAyC,UAAA,EAAE;GAAS,CAAA,GAChE,EAAE,MAAM,oBAAC,KAAD;IAAG,WAAU;IAAoD,UAAA,EAAE;GAAO,CAAA,IAAI,IACvF,EAAA,CAAA,IACA,QACF,qBAAC,KAAD;IAAG,MAAK;IAAS,WAAU;IAA3B,UAAA,CAA6D,8BAChC,KAC1B;GAEH,CAAA,IAAA,oBAAC,KAAD;IAAG,WAAU;IAA4B,UAAA;GAAsB,CAAA;EAE9D,CAAA,CACA;;AAEX;AAEA,SAAgB,YAAY,EAC1B,GAAG,KAAK,IAAI,KAAK,WAAW,cAS3B;CACD,MAAM,SAAS,MAAM,cAAc,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC;CAC3E,OACE,oBAAC,qBAAD;EACE,OAAO;EACP,MAAK;EACG;EACL;EACE;EACD;EACC;EACM;EACX,SAAS,OAAO,EAAE,QAAQ,EAAE,UAAU,KAAA,EAAU;EAChD,WAAW,OAAO,EAAE,QAAQ,OAAO,EAAE,WAAW,WAAW,EAAE,SAAS,GAAG;EAEvE,WAAA,MAAM,OAAO,oBAAC,eAAD;GAAkB;GAAG,cAAc,KAAK,QAAQ;GAAO;EAAK,CAAA;CACxD,CAAA;AAEzB"}
@@ -13,11 +13,13 @@
13
13
  * block (article-blocks.tsx ArticleBlock + PullQuotePreview): drawn as the reader sees it, edited in the floating
14
14
  * properties panel (4 settings → panel, CPO D54) through the kit SchemaForm. Key takeaways are V2's article block too,
15
15
  * written in the text itself (article-blocks.tsx TakeawaysEditor, surface "inline"): a title line and a line per point.
16
- * The embed is V2's article block too (ArticleBlock surface "popover" + EmbedPreview): a placeholder card of the link's
17
- * provider, edited in a popover beside it (Link, Title; V2's Shape has no stored key, see dom.ts).
16
+ * The embed island draws embed.tsx's block (V2's article Embed: Link, Title, Shape), keeping the keys it lacks absent.
18
17
  */
19
18
  import * as React from "react";
20
19
  import { type IslandEl, type IslandKind, type IslandModels } from "./dom";
20
+ import { type OutlineStore } from "./toc";
21
+ import type { RichTextRead } from "./codec";
22
+ import type { RichTextFeature } from "./codec";
21
23
  export interface IslandCtx {
22
24
  readOnly?: boolean;
23
25
  dense?: boolean;
@@ -42,6 +44,21 @@ export interface IslandCtx {
42
44
  redo?: () => boolean;
43
45
  /** Drag the block to a new position (the gutter grip's drag), for a grip drawn on the block itself */
44
46
  drag?: (el: IslandEl, e: React.PointerEvent) => void;
47
+ /** what the field's stored shape keeps (the host codec's features): a setting it cannot store is not drawn */
48
+ allows?: (f: RichTextFeature) => boolean;
49
+ /** the body's live outline (its top-level H2/H3), which a table of contents lists */
50
+ outline?: OutlineStore;
51
+ /** where an author bio and related posts point (the field's config, from the host codec) */
52
+ references?: RichTextRead["references"];
53
+ }
54
+ /** `label` names the step in the editor's one undo history ("Edit alt text"). */
55
+ export type Setter<K extends IslandKind> = (patch: Partial<IslandModels[K]> | ((m: IslandModels[K]) => IslandModels[K]), label?: string, record?: boolean) => void;
56
+ export interface BlockProps<K extends IslandKind> {
57
+ m: IslandModels[K];
58
+ set: Setter<K>;
59
+ el: IslandEl;
60
+ ctx: IslandCtx;
61
+ autoFocus: boolean;
45
62
  }
46
63
  export declare function Island({ el, ctx }: {
47
64
  el: IslandEl;