@conciv/ui-kit-tap 0.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.
- package/LICENSE +21 -0
- package/README.md +12 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +146 -0
- package/dist/index.js.map +1 -0
- package/dist/mention-field.d.ts +29 -0
- package/dist/mention-field.d.ts.map +1 -0
- package/package.json +79 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 aidx contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# @conciv/ui-kit-tap
|
|
2
|
+
|
|
3
|
+
TipTap-based rich-text primitives for conciv (SolidJS, shadow-DOM-safe): a mention composer
|
|
4
|
+
built on `@tiptap/core` and the shared `@conciv/ui-kit-system` tokens. Each primitive is
|
|
5
|
+
viewable in Storybook.
|
|
6
|
+
|
|
7
|
+
Part of [conciv](https://github.com/conciv-dev/conciv). It ships as a dependency of the
|
|
8
|
+
umbrella package — install that:
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install -D @conciv/it
|
|
12
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAC,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { className as e, createComponent as t, delegateEvents as n, effect as r, insert as i, memo as a, setAttribute as o, setStyleProperty as s, template as c, use as l } from "solid-js/web";
|
|
2
|
+
import { For as u, Show as d, createSignal as f, onCleanup as p, onMount as m } from "solid-js";
|
|
3
|
+
import { Editor as h } from "@tiptap/core";
|
|
4
|
+
import { Document as g } from "@tiptap/extension-document";
|
|
5
|
+
import { Paragraph as _ } from "@tiptap/extension-paragraph";
|
|
6
|
+
import { Text as v } from "@tiptap/extension-text";
|
|
7
|
+
import { HardBreak as y } from "@tiptap/extension-hard-break";
|
|
8
|
+
import { Mention as b } from "@tiptap/extension-mention";
|
|
9
|
+
import { Avatar as x } from "@conciv/ui-kit-system";
|
|
10
|
+
//#region src/mention-field.tsx
|
|
11
|
+
var S = /*#__PURE__*/ c("<div><div class=\"min-h-7 max-h-32 overflow-auto bg-pw-sunken text-[0.8125rem] text-pw-text rounded-pw-md [border:1px_solid_var(--pw-line)] px-2 py-1.5 [outline:none] focus-within:[border-color:var(--pw-accent-line)] [&_.tiptap]:[outline:none] [&_[data-mention]]:text-pw-accent-hi [&_[data-mention]]:bg-pw-accent-08 [&_[data-mention]]:rounded-pw-sm [&_[data-mention]]:px-0.5\">"), C = /*#__PURE__*/ c("<span class=\"pointer-events-none absolute left-2 top-1.5 text-[0.8125rem] text-pw-text-3 select-none\">"), w = /*#__PURE__*/ c("<ul role=listbox aria-label=\"Mention a participant\"class=\"fixed z-[2147483647] min-w-44 max-h-56 overflow-auto rounded-pw-md bg-pw-panel text-pw-text border border-pw-line shadow-pw-lg p-1\">"), T = /*#__PURE__*/ c("<li role=option class=\"flex items-center gap-2 px-2 py-1.5 rounded-pw-sm text-[0.8125rem] cursor-pointer aria-selected:bg-pw-fill\">"), E = (e) => {
|
|
12
|
+
let t = [], n = (e) => {
|
|
13
|
+
if (!e) return;
|
|
14
|
+
let n = t.at(-1);
|
|
15
|
+
n && n.type === "text" ? n.text += e : t.push({
|
|
16
|
+
type: "text",
|
|
17
|
+
text: e
|
|
18
|
+
});
|
|
19
|
+
}, r = (e) => (e ?? []).forEach((e) => {
|
|
20
|
+
e.type === "text" ? n(e.text ?? "") : e.type === "mention" ? t.push({
|
|
21
|
+
type: "mention",
|
|
22
|
+
id: String(e.attrs?.id ?? ""),
|
|
23
|
+
label: String(e.attrs?.label ?? e.attrs?.id ?? "")
|
|
24
|
+
}) : e.type === "hardBreak" && n("\n");
|
|
25
|
+
}), i = e.content ?? [];
|
|
26
|
+
return i.forEach((e, t) => {
|
|
27
|
+
r(e.content), t < i.length - 1 && n("\n");
|
|
28
|
+
}), t;
|
|
29
|
+
};
|
|
30
|
+
function D(n) {
|
|
31
|
+
let c, D, [O, k] = f(!0), [A, j] = f(null), [M, N] = f(0), P = () => {
|
|
32
|
+
!D || D.isEmpty || (n.onSubmit(E(D.getJSON())), D.commands.clearContent(), k(!0), n.onEmptyChange?.(!0));
|
|
33
|
+
};
|
|
34
|
+
return m(() => {
|
|
35
|
+
c && (D = new h({
|
|
36
|
+
element: c,
|
|
37
|
+
editorProps: {
|
|
38
|
+
attributes: {
|
|
39
|
+
role: "textbox",
|
|
40
|
+
"aria-label": n.ariaLabel ?? "Message",
|
|
41
|
+
"aria-multiline": "true"
|
|
42
|
+
},
|
|
43
|
+
handleKeyDown: (e, t) => t.key === "Enter" && !t.shiftKey && !A() ? (t.preventDefault(), P(), !0) : !1
|
|
44
|
+
},
|
|
45
|
+
onUpdate: ({ editor: e }) => {
|
|
46
|
+
k(e.isEmpty), n.onEmptyChange?.(e.isEmpty);
|
|
47
|
+
},
|
|
48
|
+
extensions: [
|
|
49
|
+
g,
|
|
50
|
+
_,
|
|
51
|
+
v,
|
|
52
|
+
y,
|
|
53
|
+
b.configure({
|
|
54
|
+
HTMLAttributes: { "data-mention": "" },
|
|
55
|
+
suggestion: {
|
|
56
|
+
char: "@",
|
|
57
|
+
items: ({ query: e }) => n.items(e),
|
|
58
|
+
render: () => ({
|
|
59
|
+
onStart: (e) => {
|
|
60
|
+
j({
|
|
61
|
+
items: e.items,
|
|
62
|
+
command: e.command,
|
|
63
|
+
rect: e.clientRect?.() ?? null
|
|
64
|
+
}), N(0);
|
|
65
|
+
},
|
|
66
|
+
onUpdate: (e) => j({
|
|
67
|
+
items: e.items,
|
|
68
|
+
command: e.command,
|
|
69
|
+
rect: e.clientRect?.() ?? null
|
|
70
|
+
}),
|
|
71
|
+
onExit: () => j(null),
|
|
72
|
+
onKeyDown: ({ event: e }) => {
|
|
73
|
+
let t = A();
|
|
74
|
+
if (!t || t.items.length === 0) return !1;
|
|
75
|
+
if (e.key === "ArrowDown") return N((M() + 1) % t.items.length), !0;
|
|
76
|
+
if (e.key === "ArrowUp") return N((M() - 1 + t.items.length) % t.items.length), !0;
|
|
77
|
+
if (e.key === "Enter" || e.key === "Tab") {
|
|
78
|
+
let e = t.items[M()];
|
|
79
|
+
return e && t.command(e), !0;
|
|
80
|
+
}
|
|
81
|
+
return e.key === "Escape" ? (j(null), !0) : !1;
|
|
82
|
+
}
|
|
83
|
+
})
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
]
|
|
87
|
+
}), n.onReady?.({
|
|
88
|
+
focus: () => D?.commands.focus(),
|
|
89
|
+
clear: () => D?.commands.clearContent(),
|
|
90
|
+
submit: P,
|
|
91
|
+
element: D.view.dom
|
|
92
|
+
}));
|
|
93
|
+
}), p(() => D?.destroy()), (() => {
|
|
94
|
+
var f = S(), p = f.firstChild;
|
|
95
|
+
return l((e) => c = e, p), i(f, t(d, {
|
|
96
|
+
get when() {
|
|
97
|
+
return a(() => !!O())() && n.placeholder;
|
|
98
|
+
},
|
|
99
|
+
children: (e) => (() => {
|
|
100
|
+
var t = C();
|
|
101
|
+
return i(t, e), t;
|
|
102
|
+
})()
|
|
103
|
+
}), null), i(f, t(d, {
|
|
104
|
+
get when() {
|
|
105
|
+
return A();
|
|
106
|
+
},
|
|
107
|
+
children: (e) => t(d, {
|
|
108
|
+
get when() {
|
|
109
|
+
return a(() => e().items.length > 0)() && e().rect;
|
|
110
|
+
},
|
|
111
|
+
children: (n) => (() => {
|
|
112
|
+
var a = w();
|
|
113
|
+
return i(a, t(u, {
|
|
114
|
+
get each() {
|
|
115
|
+
return e().items;
|
|
116
|
+
},
|
|
117
|
+
children: (n, a) => (() => {
|
|
118
|
+
var s = T();
|
|
119
|
+
return s.$$pointerdown = (t) => {
|
|
120
|
+
t.preventDefault(), e().command(n);
|
|
121
|
+
}, i(s, t(x.Root, {
|
|
122
|
+
class: "size-5",
|
|
123
|
+
get children() {
|
|
124
|
+
return t(x.Fallback, { get children() {
|
|
125
|
+
return n.label.trim().charAt(0).toUpperCase() || "?";
|
|
126
|
+
} });
|
|
127
|
+
}
|
|
128
|
+
}), null), i(s, () => n.label, null), r(() => o(s, "aria-selected", a() === M())), s;
|
|
129
|
+
})()
|
|
130
|
+
})), r((e) => {
|
|
131
|
+
var t = `${n().left}px`, r = `${n().bottom + 4}px`;
|
|
132
|
+
return t !== e.e && s(a, "left", e.e = t), r !== e.t && s(a, "top", e.t = r), e;
|
|
133
|
+
}, {
|
|
134
|
+
e: void 0,
|
|
135
|
+
t: void 0
|
|
136
|
+
}), a;
|
|
137
|
+
})()
|
|
138
|
+
})
|
|
139
|
+
}), null), r(() => e(f, `relative w-full ${n.class ?? ""}`)), f;
|
|
140
|
+
})();
|
|
141
|
+
}
|
|
142
|
+
n(["pointerdown"]);
|
|
143
|
+
//#endregion
|
|
144
|
+
export { D as MentionField };
|
|
145
|
+
|
|
146
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["For","Show","createSignal","onCleanup","onMount","JSX","Editor","Document","Paragraph","Text","HardBreak","Mention","Avatar","MentionItem","id","label","MentionSegment","type","text","MentionFieldApi","focus","clear","submit","element","HTMLElement","SuggestionState","items","command","item","rect","DOMRect","JsonNode","attrs","Record","content","EDITOR","PLACEHOLDER","LISTBOX","OPTION","serialize","doc","out","pushText","last","at","push","inline","nodes","forEach","node","String","blocks","block","index","length","MentionField","props","query","onSubmit","segments","onReady","api","onEmptyChange","empty","placeholder","ariaLabel","class","Element","host","HTMLDivElement","editor","setEmpty","suggestion","setSuggestion","setIndex","isEmpty","getJSON","commands","clearContent","editorProps","attributes","role","handleKeyDown","_view","event","key","shiftKey","preventDefault","onUpdate","instance","extensions","configure","HTMLAttributes","char","render","onStart","start","clientRect","update","onExit","onKeyDown","state","view","dom","destroy","_el$","_tmpl$","_el$2","firstChild","_$use","_$insert","_$createComponent","when","_$memo","children","_el$3","_tmpl$2","_el$4","_tmpl$3","each","position","_el$5","_tmpl$4","$$pointerdown","Root","Fallback","trim","charAt","toUpperCase","_$effect","_$setAttribute","_p$","_v$","left","_v$2","bottom","e","_$setStyleProperty","t","undefined","_$className","_$delegateEvents"],"sources":["../src/mention-field.tsx"],"sourcesContent":["import {For, Show, createSignal, onCleanup, onMount, type JSX} from 'solid-js'\nimport {Editor} from '@tiptap/core'\nimport {Document} from '@tiptap/extension-document'\nimport {Paragraph} from '@tiptap/extension-paragraph'\nimport {Text} from '@tiptap/extension-text'\nimport {HardBreak} from '@tiptap/extension-hard-break'\nimport {Mention} from '@tiptap/extension-mention'\nimport {Avatar} from '@conciv/ui-kit-system'\n\nexport type MentionItem = {id: string; label: string}\nexport type MentionSegment = {type: 'text'; text: string} | {type: 'mention'; id: string; label: string}\nexport type MentionFieldApi = {focus: () => void; clear: () => void; submit: () => void; element: HTMLElement}\n\ntype SuggestionState = {items: MentionItem[]; command: (item: MentionItem) => void; rect: DOMRect | null}\ntype JsonNode = {type?: string; text?: string; attrs?: Record<string, unknown>; content?: JsonNode[]}\n\nconst EDITOR =\n 'min-h-7 max-h-32 overflow-auto bg-pw-sunken text-[0.8125rem] text-pw-text rounded-pw-md [border:1px_solid_var(--pw-line)] px-2 py-1.5 [outline:none] focus-within:[border-color:var(--pw-accent-line)] [&_.tiptap]:[outline:none] [&_[data-mention]]:text-pw-accent-hi [&_[data-mention]]:bg-pw-accent-08 [&_[data-mention]]:rounded-pw-sm [&_[data-mention]]:px-0.5'\nconst PLACEHOLDER = 'pointer-events-none absolute left-2 top-1.5 text-[0.8125rem] text-pw-text-3 select-none'\nconst LISTBOX =\n 'fixed z-[2147483647] min-w-44 max-h-56 overflow-auto rounded-pw-md bg-pw-panel text-pw-text border border-pw-line shadow-pw-lg p-1'\nconst OPTION =\n 'flex items-center gap-2 px-2 py-1.5 rounded-pw-sm text-[0.8125rem] cursor-pointer aria-selected:bg-pw-fill'\n\nconst serialize = (doc: JsonNode): MentionSegment[] => {\n const out: MentionSegment[] = []\n const pushText = (text: string): void => {\n if (!text) return\n const last = out.at(-1)\n if (last && last.type === 'text') last.text += text\n else out.push({type: 'text', text})\n }\n const inline = (nodes: JsonNode[] | undefined): void =>\n (nodes ?? []).forEach((node) => {\n if (node.type === 'text') pushText(node.text ?? '')\n else if (node.type === 'mention')\n out.push({\n type: 'mention',\n id: String(node.attrs?.id ?? ''),\n label: String(node.attrs?.label ?? node.attrs?.id ?? ''),\n })\n else if (node.type === 'hardBreak') pushText('\\n')\n })\n const blocks = doc.content ?? []\n blocks.forEach((block, index) => {\n inline(block.content)\n if (index < blocks.length - 1) pushText('\\n')\n })\n return out\n}\n\n// A TipTap (ProseMirror) composer with @mentions. ProseMirror ships real shadow-DOM selection support,\n// so this works inside the comment overlay's shadow root where Slate/Lexical/textarea-caret tricks fail.\n// The editor element is created once and never re-rendered by Solid (a re-render breaks the suggestion\n// plugin); the participant listbox is a sibling the suggestion render hook drives via signals, so focus\n// never leaves the editor.\nexport function MentionField(props: {\n items: (query: string) => MentionItem[]\n onSubmit: (segments: MentionSegment[]) => void\n onReady?: (api: MentionFieldApi) => void\n onEmptyChange?: (empty: boolean) => void\n placeholder?: string\n ariaLabel?: string\n class?: string\n}): JSX.Element {\n let host: HTMLDivElement | undefined\n let editor: Editor | undefined\n const [empty, setEmpty] = createSignal(true)\n const [suggestion, setSuggestion] = createSignal<SuggestionState | null>(null)\n const [index, setIndex] = createSignal(0)\n\n const submit = (): void => {\n if (!editor || editor.isEmpty) return\n props.onSubmit(serialize(editor.getJSON() as JsonNode))\n editor.commands.clearContent()\n setEmpty(true)\n props.onEmptyChange?.(true)\n }\n\n onMount(() => {\n if (!host) return\n editor = new Editor({\n element: host,\n editorProps: {\n attributes: {role: 'textbox', 'aria-label': props.ariaLabel ?? 'Message', 'aria-multiline': 'true'},\n handleKeyDown: (_view, event) => {\n if (event.key === 'Enter' && !event.shiftKey && !suggestion()) {\n event.preventDefault()\n submit()\n return true\n }\n return false\n },\n },\n onUpdate: ({editor: instance}) => {\n setEmpty(instance.isEmpty)\n props.onEmptyChange?.(instance.isEmpty)\n },\n extensions: [\n Document,\n Paragraph,\n Text,\n HardBreak,\n Mention.configure({\n HTMLAttributes: {'data-mention': ''},\n suggestion: {\n char: '@',\n items: ({query}) => props.items(query),\n render: () => ({\n onStart: (start) => {\n setSuggestion({items: start.items, command: start.command, rect: start.clientRect?.() ?? null})\n setIndex(0)\n },\n onUpdate: (update) =>\n setSuggestion({items: update.items, command: update.command, rect: update.clientRect?.() ?? null}),\n onExit: () => setSuggestion(null),\n onKeyDown: ({event}) => {\n const state = suggestion()\n if (!state || state.items.length === 0) return false\n if (event.key === 'ArrowDown') {\n setIndex((index() + 1) % state.items.length)\n return true\n }\n if (event.key === 'ArrowUp') {\n setIndex((index() - 1 + state.items.length) % state.items.length)\n return true\n }\n if (event.key === 'Enter' || event.key === 'Tab') {\n const item = state.items[index()]\n if (item) state.command(item)\n return true\n }\n if (event.key === 'Escape') {\n setSuggestion(null)\n return true\n }\n return false\n },\n }),\n },\n }),\n ],\n })\n props.onReady?.({\n focus: () => editor?.commands.focus(),\n clear: () => editor?.commands.clearContent(),\n submit,\n element: editor.view.dom,\n })\n })\n onCleanup(() => editor?.destroy())\n\n return (\n <div class={`relative w-full ${props.class ?? ''}`}>\n <div ref={(element) => (host = element)} class={EDITOR} />\n <Show when={empty() && props.placeholder}>{(text) => <span class={PLACEHOLDER}>{text()}</span>}</Show>\n <Show when={suggestion()}>\n {(state) => (\n <Show when={state().items.length > 0 && state().rect}>\n {(rect) => (\n <ul\n role=\"listbox\"\n aria-label=\"Mention a participant\"\n class={LISTBOX}\n style={{left: `${rect().left}px`, top: `${rect().bottom + 4}px`}}\n >\n <For each={state().items}>\n {(item, position) => (\n <li\n role=\"option\"\n aria-selected={position() === index()}\n class={OPTION}\n onPointerDown={(event) => {\n event.preventDefault()\n state().command(item)\n }}\n >\n <Avatar.Root class=\"size-5\">\n <Avatar.Fallback>{item.label.trim().charAt(0).toUpperCase() || '?'}</Avatar.Fallback>\n </Avatar.Root>\n {item.label}\n </li>\n )}\n </For>\n </ul>\n )}\n </Show>\n )}\n </Show>\n </div>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type JSX } from 'solid-js';
|
|
2
|
+
export type MentionItem = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
};
|
|
6
|
+
export type MentionSegment = {
|
|
7
|
+
type: 'text';
|
|
8
|
+
text: string;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'mention';
|
|
11
|
+
id: string;
|
|
12
|
+
label: string;
|
|
13
|
+
};
|
|
14
|
+
export type MentionFieldApi = {
|
|
15
|
+
focus: () => void;
|
|
16
|
+
clear: () => void;
|
|
17
|
+
submit: () => void;
|
|
18
|
+
element: HTMLElement;
|
|
19
|
+
};
|
|
20
|
+
export declare function MentionField(props: {
|
|
21
|
+
items: (query: string) => MentionItem[];
|
|
22
|
+
onSubmit: (segments: MentionSegment[]) => void;
|
|
23
|
+
onReady?: (api: MentionFieldApi) => void;
|
|
24
|
+
onEmptyChange?: (empty: boolean) => void;
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
ariaLabel?: string;
|
|
27
|
+
class?: string;
|
|
28
|
+
}): JSX.Element;
|
|
29
|
+
//# sourceMappingURL=mention-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-field.d.ts","sourceRoot":"","sources":["../src/mention-field.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA8C,KAAK,GAAG,EAAC,MAAM,UAAU,CAAA;AAS9E,MAAM,MAAM,WAAW,GAAG;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAA;AACrD,MAAM,MAAM,cAAc,GAAG;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,GAAG;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAA;AACxG,MAAM,MAAM,eAAe,GAAG;IAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAC,CAAA;AA6C9G,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,WAAW,EAAE,CAAA;IACvC,QAAQ,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,IAAI,CAAA;IAC9C,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,IAAI,CAAA;IACxC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,GAAG,GAAG,CAAC,OAAO,CA+Hd"}
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@conciv/ui-kit-tap",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "TipTap-based rich-text primitives for conciv (SolidJS, shadow-DOM-safe): a mention composer built on @tiptap/core and the shared ui-kit-system tokens. Each primitive is viewable in Storybook.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"conciv",
|
|
7
|
+
"prosemirror",
|
|
8
|
+
"rich-text",
|
|
9
|
+
"solid-js",
|
|
10
|
+
"tiptap",
|
|
11
|
+
"ui-kit"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/conciv-dev/conciv/tree/main/packages/ui-kit-tap#readme",
|
|
14
|
+
"bugs": "https://github.com/conciv-dev/conciv/issues",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/conciv-dev/conciv.git",
|
|
19
|
+
"directory": "packages/ui-kit-tap"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"import": "./dist/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@tiptap/core": "^3.27.1",
|
|
36
|
+
"@tiptap/extension-document": "^3.27.1",
|
|
37
|
+
"@tiptap/extension-hard-break": "^3.27.1",
|
|
38
|
+
"@tiptap/extension-mention": "^3.27.1",
|
|
39
|
+
"@tiptap/extension-paragraph": "^3.27.1",
|
|
40
|
+
"@tiptap/extension-text": "^3.27.1",
|
|
41
|
+
"@tiptap/pm": "^3.27.1",
|
|
42
|
+
"@conciv/ui-kit-system": "0.0.1"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@chromatic-com/storybook": "^5.2.1",
|
|
46
|
+
"@storybook/addon-a11y": "^10.4.4",
|
|
47
|
+
"@storybook/addon-docs": "^10.4.4",
|
|
48
|
+
"@storybook/addon-vitest": "^10.4.4",
|
|
49
|
+
"@types/node": "^22.19.21",
|
|
50
|
+
"@unocss/postcss": "^66.7.2",
|
|
51
|
+
"@unocss/reset": "^66.7.2",
|
|
52
|
+
"@vitest/browser-playwright": "4.1.8",
|
|
53
|
+
"@vitest/coverage-v8": "4.1.8",
|
|
54
|
+
"playwright": "^1.60.0",
|
|
55
|
+
"postcss": "^8.5.6",
|
|
56
|
+
"solid-js": "^1.9.13",
|
|
57
|
+
"storybook": "^10.4.4",
|
|
58
|
+
"storybook-solidjs-vite": "^10.3.0",
|
|
59
|
+
"typescript": "^6.0.3",
|
|
60
|
+
"unocss": "^66.7.2",
|
|
61
|
+
"vite": "^8.0.16",
|
|
62
|
+
"vite-plugin-solid": "^2.11.12",
|
|
63
|
+
"vitest": "^4.1.8",
|
|
64
|
+
"@conciv/uno-preset": "0.0.1"
|
|
65
|
+
},
|
|
66
|
+
"peerDependencies": {
|
|
67
|
+
"solid-js": "^1.9.13"
|
|
68
|
+
},
|
|
69
|
+
"scripts": {
|
|
70
|
+
"build": "vite build && tsc -p tsconfig.build.json",
|
|
71
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
72
|
+
"lint": "oxlint",
|
|
73
|
+
"test": "vitest run --passWithNoTests",
|
|
74
|
+
"storybook": "storybook dev -p 6009",
|
|
75
|
+
"build-storybook": "storybook build",
|
|
76
|
+
"publint": "publint",
|
|
77
|
+
"attw": "attw --pack . --profile esm-only"
|
|
78
|
+
}
|
|
79
|
+
}
|