@connextar/house 0.1.0 → 0.2.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.
- package/README.md +205 -28
- package/dist/account/index.d.ts +1 -1
- package/dist/account/index.d.ts.map +1 -1
- package/dist/account/index.js +1 -1
- package/dist/account/index.js.map +1 -1
- package/dist/auth/index.d.ts +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/changelog/changelog.d.ts +60 -0
- package/dist/changelog/changelog.d.ts.map +1 -0
- package/dist/changelog/changelog.js +61 -0
- package/dist/changelog/changelog.js.map +1 -0
- package/dist/changelog/index.d.ts +2 -0
- package/dist/changelog/index.d.ts.map +1 -0
- package/dist/changelog/index.js +2 -0
- package/dist/changelog/index.js.map +1 -0
- package/dist/editor/block-handle.d.ts +15 -0
- package/dist/editor/block-handle.d.ts.map +1 -0
- package/dist/editor/block-handle.js +106 -0
- package/dist/editor/block-handle.js.map +1 -0
- package/dist/editor/blocks.d.ts +35 -0
- package/dist/editor/blocks.d.ts.map +1 -0
- package/dist/editor/blocks.js +114 -0
- package/dist/editor/blocks.js.map +1 -0
- package/dist/editor/bubble-toolbar.d.ts +11 -0
- package/dist/editor/bubble-toolbar.d.ts.map +1 -0
- package/dist/editor/bubble-toolbar.js +87 -0
- package/dist/editor/bubble-toolbar.js.map +1 -0
- package/dist/editor/content-index.d.ts +2 -0
- package/dist/editor/content-index.d.ts.map +1 -0
- package/dist/editor/content-index.js +2 -0
- package/dist/editor/content-index.js.map +1 -0
- package/dist/editor/content.d.ts +30 -0
- package/dist/editor/content.d.ts.map +1 -0
- package/dist/editor/content.js +256 -0
- package/dist/editor/content.js.map +1 -0
- package/dist/editor/editor.d.ts +52 -0
- package/dist/editor/editor.d.ts.map +1 -0
- package/dist/editor/editor.js +160 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/emoji-index.d.ts +2 -0
- package/dist/editor/emoji-index.d.ts.map +1 -0
- package/dist/editor/emoji-index.js +2 -0
- package/dist/editor/emoji-index.js.map +1 -0
- package/dist/editor/emoji-picker.d.ts +16 -0
- package/dist/editor/emoji-picker.d.ts.map +1 -0
- package/dist/editor/emoji-picker.js +37 -0
- package/dist/editor/emoji-picker.js.map +1 -0
- package/dist/editor/emoji.d.ts +18 -0
- package/dist/editor/emoji.d.ts.map +1 -0
- package/dist/editor/emoji.js +418 -0
- package/dist/editor/emoji.js.map +1 -0
- package/dist/editor/index.d.ts +5 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +6 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/suggestion-popup.d.ts +17 -0
- package/dist/editor/suggestion-popup.d.ts.map +1 -0
- package/dist/editor/suggestion-popup.js +57 -0
- package/dist/editor/suggestion-popup.js.map +1 -0
- package/dist/editor/suggestions.d.ts +93 -0
- package/dist/editor/suggestions.d.ts.map +1 -0
- package/dist/editor/suggestions.js +179 -0
- package/dist/editor/suggestions.js.map +1 -0
- package/dist/editor/ui.d.ts +54 -0
- package/dist/editor/ui.d.ts.map +1 -0
- package/dist/editor/ui.js +58 -0
- package/dist/editor/ui.js.map +1 -0
- package/dist/errors/index.d.ts +2 -2
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +2 -2
- package/dist/errors/index.js.map +1 -1
- package/dist/house.css +267 -0
- package/dist/internal/cx.d.ts +3 -0
- package/dist/internal/cx.d.ts.map +1 -0
- package/dist/internal/cx.js +5 -0
- package/dist/internal/cx.js.map +1 -0
- package/dist/internal/next-link.d.ts +23 -0
- package/dist/internal/next-link.d.ts.map +1 -0
- package/dist/internal/next-link.js +3 -0
- package/dist/internal/next-link.js.map +1 -0
- package/dist/markdown/guide.d.ts +98 -0
- package/dist/markdown/guide.d.ts.map +1 -0
- package/dist/markdown/guide.js +328 -0
- package/dist/markdown/guide.js.map +1 -0
- package/dist/markdown/index.d.ts +4 -0
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +4 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/table-view.d.ts +28 -0
- package/dist/markdown/table-view.d.ts.map +1 -0
- package/dist/markdown/table-view.js +25 -0
- package/dist/markdown/table-view.js.map +1 -0
- package/dist/markdown/table.d.ts +35 -0
- package/dist/markdown/table.d.ts.map +1 -0
- package/dist/markdown/table.js +79 -0
- package/dist/markdown/table.js.map +1 -0
- package/dist/release/changelog.d.ts +72 -0
- package/dist/release/changelog.d.ts.map +1 -0
- package/dist/release/changelog.js +92 -0
- package/dist/release/changelog.js.map +1 -0
- package/dist/release/index.d.ts +3 -0
- package/dist/release/index.d.ts.map +1 -0
- package/dist/release/index.js +3 -0
- package/dist/release/index.js.map +1 -0
- package/dist/release/version.d.ts +33 -0
- package/dist/release/version.d.ts.map +1 -0
- package/dist/release/version.js +57 -0
- package/dist/release/version.js.map +1 -0
- package/dist/trail/index.d.ts +3 -0
- package/dist/trail/index.d.ts.map +1 -0
- package/dist/trail/index.js +3 -0
- package/dist/trail/index.js.map +1 -0
- package/dist/trail/rules.d.ts +44 -0
- package/dist/trail/rules.d.ts.map +1 -0
- package/dist/trail/rules.js +74 -0
- package/dist/trail/rules.js.map +1 -0
- package/dist/trail/trail.d.ts +49 -0
- package/dist/trail/trail.d.ts.map +1 -0
- package/dist/trail/trail.js +188 -0
- package/dist/trail/trail.js.map +1 -0
- package/docs/ReleaseProcess.md +315 -0
- package/package.json +76 -11
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type SuggestionSources } from "./suggestions.js";
|
|
2
|
+
/**
|
|
3
|
+
* Notion-style writing anywhere an app asks for prose: notes, descriptions,
|
|
4
|
+
* instructions, feedback.
|
|
5
|
+
*
|
|
6
|
+
* **Blocks, not a toolbar.** There is no standing formatting bar. Formatting
|
|
7
|
+
* appears as a bubble over a text selection (with Turn into); new blocks come
|
|
8
|
+
* from typing `/` — a filterable menu — or from the `+` beside any block; every
|
|
9
|
+
* block has a grip to drag it elsewhere or open its menu (turn into, duplicate,
|
|
10
|
+
* move up, move down, delete); `:` completes an emoji shortcode. `@` references
|
|
11
|
+
* and `#` tags work when the app passes `sources`. Markdown shortcuts still work
|
|
12
|
+
* while typing (`# `, `- `, `1. `, `[] `, `> `, `**bold**`, "```").
|
|
13
|
+
*
|
|
14
|
+
* It reads and writes **Markdown strings**, deliberately: the fields it replaces
|
|
15
|
+
* are plain-text columns, Markdown needs no sanitiser because nothing HTML-shaped
|
|
16
|
+
* is stored or rendered, and old plain-text values open unchanged (a bare
|
|
17
|
+
* newline stays a line break). That is also why the block vocabulary is exactly
|
|
18
|
+
* what Markdown can say. Read-only display is `RichTextContent`.
|
|
19
|
+
*/
|
|
20
|
+
export interface RichTextEditorProps {
|
|
21
|
+
value: string;
|
|
22
|
+
onChange: (markdown: string) => void;
|
|
23
|
+
onBlur?: () => void;
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
/**
|
|
26
|
+
* "field" sits inside a form like a big textarea (bubble and `/`, no gutter);
|
|
27
|
+
* "document" is a full-page editor (block grips, wider gutter, taller).
|
|
28
|
+
*/
|
|
29
|
+
variant?: "field" | "document";
|
|
30
|
+
disabled?: boolean;
|
|
31
|
+
autoFocus?: boolean;
|
|
32
|
+
/** Where `@` and `#` get their rows. Omit either and that trigger stays inert. */
|
|
33
|
+
sources?: SuggestionSources;
|
|
34
|
+
/**
|
|
35
|
+
* How a link in the text is followed. "click": an `@`-reference opens on a
|
|
36
|
+
* plain click, as in Notion — for a page that autosaves. "modifier" (the
|
|
37
|
+
* default): only Ctrl/⌘-click follows, so a form with unsaved fields is never
|
|
38
|
+
* left by a stray click on a mention. Any link opens with Ctrl/⌘.
|
|
39
|
+
*/
|
|
40
|
+
followLinks?: "click" | "modifier";
|
|
41
|
+
/** Which internal links count as references for `followLinks="click"`. Defaults to an `@` label. */
|
|
42
|
+
isReference?: (href: string, text: string) => boolean;
|
|
43
|
+
/** How today's date is written by the `/` menu. */
|
|
44
|
+
formatDate?: (date: Date) => string;
|
|
45
|
+
id?: string;
|
|
46
|
+
className?: string;
|
|
47
|
+
"aria-invalid"?: boolean;
|
|
48
|
+
"aria-describedby"?: string;
|
|
49
|
+
"aria-label"?: string;
|
|
50
|
+
}
|
|
51
|
+
export declare function RichTextEditor({ value, onChange, onBlur, placeholder, variant, disabled, autoFocus, sources, followLinks, isReference, formatDate, id, className, ...aria }: RichTextEditorProps): import("react").JSX.Element;
|
|
52
|
+
//# sourceMappingURL=editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/editor/editor.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAML,KAAK,iBAAiB,EAEvB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kFAAkF;IAClF,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;IACnC,oGAAoG;IACpG,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACtD,mDAAmD;IACnD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;IACpC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,WAAgC,EAChC,OAAiB,EACjB,QAAgB,EAChB,SAAiB,EACjB,OAAO,EACP,WAAwB,EACxB,WAAgC,EAChC,UAAU,EACV,EAAE,EACF,SAAS,EACT,GAAG,IAAI,EACR,EAAE,mBAAmB,+BA2KrB"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { TaskItem } from "@tiptap/extension-task-item";
|
|
4
|
+
import { TaskList } from "@tiptap/extension-task-list";
|
|
5
|
+
import { Placeholder } from "@tiptap/extensions";
|
|
6
|
+
import { EditorContent, useEditor } from "@tiptap/react";
|
|
7
|
+
import { StarterKit } from "@tiptap/starter-kit";
|
|
8
|
+
import { useRouter } from "next/navigation.js";
|
|
9
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
10
|
+
import { Markdown } from "tiptap-markdown";
|
|
11
|
+
import { cx } from "../internal/cx.js";
|
|
12
|
+
import { carryTrail } from "../trail/trail.js";
|
|
13
|
+
import { BlockHandle } from "./block-handle.js";
|
|
14
|
+
import { BubbleToolbar } from "./bubble-toolbar.js";
|
|
15
|
+
import { SuggestionPopup } from "./suggestion-popup.js";
|
|
16
|
+
import { createSuggestions, DEFAULT_SUGGESTION_OPTIONS, } from "./suggestions.js";
|
|
17
|
+
const defaultIsReference = (_href, text) => text.startsWith("@");
|
|
18
|
+
export function RichTextEditor({ value, onChange, onBlur, placeholder = "Write something…", variant = "field", disabled = false, autoFocus = false, sources, followLinks = "modifier", isReference = defaultIsReference, formatDate, id, className, ...aria }) {
|
|
19
|
+
const router = useRouter();
|
|
20
|
+
// The last Markdown this editor emitted (or accepted). Guards the external
|
|
21
|
+
// value sync below from re-parsing the document on every keystroke echo.
|
|
22
|
+
const lastMarkdown = useRef(value);
|
|
23
|
+
const [session, setSession] = useState(null);
|
|
24
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
25
|
+
// The extension is built once per editor and reads these through refs, which
|
|
26
|
+
// an every-render effect keeps pointed at the current render's values.
|
|
27
|
+
const uiRef = useRef({ onOpen: () => { }, onClose: () => { }, onKeyDown: () => false });
|
|
28
|
+
const sourcesRef = useRef(sources ?? {});
|
|
29
|
+
const optionsRef = useRef({
|
|
30
|
+
...DEFAULT_SUGGESTION_OPTIONS,
|
|
31
|
+
...(formatDate ? { formatDate } : {}),
|
|
32
|
+
});
|
|
33
|
+
const placeholderRef = useRef(placeholder);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
sourcesRef.current = sources ?? {};
|
|
36
|
+
optionsRef.current = { ...DEFAULT_SUGGESTION_OPTIONS, ...(formatDate ? { formatDate } : {}) };
|
|
37
|
+
placeholderRef.current = placeholder;
|
|
38
|
+
uiRef.current = {
|
|
39
|
+
onOpen: (next) => {
|
|
40
|
+
setSession(next);
|
|
41
|
+
setActiveIndex((current) => Math.min(current, Math.max(0, next.items.length - 1)));
|
|
42
|
+
},
|
|
43
|
+
onClose: () => {
|
|
44
|
+
setSession(null);
|
|
45
|
+
setActiveIndex(0);
|
|
46
|
+
},
|
|
47
|
+
onKeyDown: (event) => {
|
|
48
|
+
if (!session || session.items.length === 0)
|
|
49
|
+
return false;
|
|
50
|
+
if (event.key === "ArrowDown") {
|
|
51
|
+
setActiveIndex((activeIndex + 1) % session.items.length);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
if (event.key === "ArrowUp") {
|
|
55
|
+
setActiveIndex((activeIndex - 1 + session.items.length) % session.items.length);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
if (event.key === "Enter" || event.key === "Tab") {
|
|
59
|
+
const item = session.items[activeIndex];
|
|
60
|
+
if (item)
|
|
61
|
+
session.command(item);
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
if (event.key === "Escape") {
|
|
65
|
+
setSession(null);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
const extensions = useMemo(() => [
|
|
73
|
+
StarterKit.configure({
|
|
74
|
+
heading: { levels: [1, 2, 3] },
|
|
75
|
+
link: { openOnClick: false, autolink: true },
|
|
76
|
+
dropcursor: { color: "var(--house-primary, var(--primary))", width: 2 },
|
|
77
|
+
}),
|
|
78
|
+
TaskList,
|
|
79
|
+
TaskItem.configure({ nested: true }),
|
|
80
|
+
Placeholder.configure({
|
|
81
|
+
// The empty document says what the field is for; an empty block in a
|
|
82
|
+
// document that has content says how to get a block — the Notion hint.
|
|
83
|
+
placeholder: ({ editor: current, node }) => {
|
|
84
|
+
if (current.isEmpty)
|
|
85
|
+
return placeholderRef.current;
|
|
86
|
+
if (variant === "document" && node.type.name === "paragraph")
|
|
87
|
+
return "Type / for blocks";
|
|
88
|
+
return "";
|
|
89
|
+
},
|
|
90
|
+
}),
|
|
91
|
+
Markdown.configure({
|
|
92
|
+
// No HTML in, no HTML out: pasted markup is flattened to text, so the
|
|
93
|
+
// stored string can never smuggle an element past a renderer.
|
|
94
|
+
html: false,
|
|
95
|
+
// A bare newline stays a visible line break, which is what every legacy
|
|
96
|
+
// plain-text value in these columns meant by one.
|
|
97
|
+
breaks: true,
|
|
98
|
+
linkify: true,
|
|
99
|
+
transformPastedText: true,
|
|
100
|
+
}),
|
|
101
|
+
createSuggestions(uiRef, sourcesRef, optionsRef),
|
|
102
|
+
],
|
|
103
|
+
// The extension set is per mount; everything that changes is read through a ref.
|
|
104
|
+
[]);
|
|
105
|
+
const editor = useEditor({
|
|
106
|
+
extensions,
|
|
107
|
+
content: value,
|
|
108
|
+
editable: !disabled,
|
|
109
|
+
autofocus: autoFocus ? "end" : false,
|
|
110
|
+
// The editor renders client-side only; the server markup comes from the page.
|
|
111
|
+
immediatelyRender: false,
|
|
112
|
+
onUpdate: ({ editor: current }) => {
|
|
113
|
+
// tiptap-markdown registers no Storage augmentation, hence the cast.
|
|
114
|
+
const markdown = current.storage.markdown.getMarkdown();
|
|
115
|
+
lastMarkdown.current = markdown;
|
|
116
|
+
onChange(markdown);
|
|
117
|
+
},
|
|
118
|
+
onBlur: () => onBlur?.(),
|
|
119
|
+
});
|
|
120
|
+
// External resets (a form reset, switching records) re-seed the document; our
|
|
121
|
+
// own keystrokes come back identical and are skipped.
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
if (!editor || value === lastMarkdown.current)
|
|
124
|
+
return;
|
|
125
|
+
lastMarkdown.current = value;
|
|
126
|
+
editor.commands.setContent(value, { emitUpdate: false });
|
|
127
|
+
}, [editor, value]);
|
|
128
|
+
// Only on a real change, and silently: `setEditable` emits an update by
|
|
129
|
+
// default, which reported a change on every mount — a form turned dirty and
|
|
130
|
+
// an autosave fired the moment a note was opened, before anyone typed.
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (editor && editor.isEditable === disabled)
|
|
133
|
+
editor.setEditable(!disabled, false);
|
|
134
|
+
}, [editor, disabled]);
|
|
135
|
+
const select = (item) => session?.command(item);
|
|
136
|
+
/** Follow a link in the text — see `followLinks`. Internal ones carry the trail. */
|
|
137
|
+
const onClickCapture = (event) => {
|
|
138
|
+
const anchor = event.target instanceof Element ? event.target.closest("a[href]") : null;
|
|
139
|
+
if (!anchor)
|
|
140
|
+
return;
|
|
141
|
+
const href = anchor.getAttribute("href") ?? "";
|
|
142
|
+
const modifier = event.metaKey || event.ctrlKey;
|
|
143
|
+
const internal = href.startsWith("/") && !href.startsWith("//") && !href.startsWith("/\\");
|
|
144
|
+
const reference = internal && isReference(href, anchor.textContent ?? "");
|
|
145
|
+
if (!modifier && !(followLinks === "click" && reference))
|
|
146
|
+
return;
|
|
147
|
+
event.preventDefault();
|
|
148
|
+
event.stopPropagation();
|
|
149
|
+
if (internal) {
|
|
150
|
+
carryTrail();
|
|
151
|
+
router.push(href);
|
|
152
|
+
}
|
|
153
|
+
else if (/^https?:\/\//i.test(href)) {
|
|
154
|
+
window.open(href, "_blank", "noopener,noreferrer");
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
return (_jsxs("div", { id: id, ...aria, onClickCapture: onClickCapture, className: cx("house-rich-text relative text-sm", variant === "field" &&
|
|
158
|
+
"rounded-md border border-input bg-background shadow-xs focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2", variant === "document" && "house-rich-text--document", aria["aria-invalid"] && "border-destructive", disabled && "opacity-60", className), children: [_jsx(EditorContent, { editor: editor, className: "house-prose" }), editor && !disabled ? _jsx(BubbleToolbar, { editor: editor }) : null, editor && !disabled && variant === "document" ? _jsx(BlockHandle, { editor: editor }) : null, session ? (_jsx(SuggestionPopup, { items: session.items, activeIndex: activeIndex, clientRect: session.clientRect, onSelect: select, onHover: setActiveIndex })) : null] }));
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/editor/editor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emoji-index.d.ts","sourceRoot":"","sources":["../../src/editor/emoji-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emoji-index.js","sourceRoot":"","sources":["../../src/editor/emoji-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAoC,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
interface EmojiPickerProps {
|
|
3
|
+
value: string | null;
|
|
4
|
+
onChange: (emoji: string | null) => void;
|
|
5
|
+
/** The trigger — whatever shows the current icon (or "Add icon"). Must accept a ref. */
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
align?: "start" | "center" | "end";
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A page-icon picker in the Notion mould: a searchable grid of emoji grouped by
|
|
11
|
+
* kind, with Remove when one is set. Backed by the curated set, so it opens
|
|
12
|
+
* instantly and never downloads a database.
|
|
13
|
+
*/
|
|
14
|
+
export declare function EmojiPicker({ value, onChange, children, align }: EmojiPickerProps): import("react").JSX.Element;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=emoji-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emoji-picker.d.ts","sourceRoot":"","sources":["../../src/editor/emoji-picker.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAM1D,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,wFAAwF;IACxF,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;CACpC;AAID;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAe,EAAE,EAAE,gBAAgB,+BAyF3F"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Search } from "lucide-react";
|
|
4
|
+
import { useMemo, useState } from "react";
|
|
5
|
+
import { cx } from "../internal/cx.js";
|
|
6
|
+
import { EMOJI, EMOJI_GROUP_LABELS, searchEmoji } from "./emoji.js";
|
|
7
|
+
import { ghostButtonClass, PopoverContent, PopoverRoot, PopoverTrigger, TextInput } from "./ui.js";
|
|
8
|
+
const GROUP_ORDER = ["smileys", "people", "nature", "food", "activities", "travel", "objects", "symbols"];
|
|
9
|
+
/**
|
|
10
|
+
* A page-icon picker in the Notion mould: a searchable grid of emoji grouped by
|
|
11
|
+
* kind, with Remove when one is set. Backed by the curated set, so it opens
|
|
12
|
+
* instantly and never downloads a database.
|
|
13
|
+
*/
|
|
14
|
+
export function EmojiPicker({ value, onChange, children, align = "start" }) {
|
|
15
|
+
const [open, setOpen] = useState(false);
|
|
16
|
+
const [query, setQuery] = useState("");
|
|
17
|
+
const grouped = useMemo(() => {
|
|
18
|
+
const term = query.trim();
|
|
19
|
+
if (term)
|
|
20
|
+
return [{ group: null, items: searchEmoji(term, 120) }];
|
|
21
|
+
return GROUP_ORDER.map((group) => ({ group, items: EMOJI.filter((entry) => entry.group === group) }));
|
|
22
|
+
}, [query]);
|
|
23
|
+
const pick = (entry) => {
|
|
24
|
+
onChange(entry.char);
|
|
25
|
+
setOpen(false);
|
|
26
|
+
setQuery("");
|
|
27
|
+
};
|
|
28
|
+
return (_jsxs(PopoverRoot, { open: open, onOpenChange: (next) => {
|
|
29
|
+
setOpen(next);
|
|
30
|
+
if (!next)
|
|
31
|
+
setQuery("");
|
|
32
|
+
}, children: [_jsx(PopoverTrigger, { asChild: true, children: children }), _jsxs(PopoverContent, { align: align, className: "w-80 p-2", children: [_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground" }), _jsx(TextInput, { value: query, onChange: (event) => setQuery(event.target.value), placeholder: "Search emoji\u2026", "aria-label": "Search emoji", className: "pl-8", autoFocus: true })] }), _jsx("div", { className: "mt-2 max-h-64 overflow-y-auto pr-1", children: grouped.every((section) => section.items.length === 0) ? (_jsxs("p", { className: "px-1 py-6 text-center text-sm text-muted-foreground", children: ["Nothing matches \u201C", query, "\u201D."] })) : (grouped.map((section) => section.items.length === 0 ? null : (_jsxs("div", { className: "mb-2", children: [section.group ? (_jsx("p", { className: "px-1 pb-1 text-[11px] font-semibold tracking-wide text-muted-foreground uppercase", children: EMOJI_GROUP_LABELS[section.group] })) : null, _jsx("div", { className: "grid grid-cols-8 gap-0.5", children: section.items.map((entry) => (_jsx("button", { type: "button", title: entry.name.replace(/_/g, " "), "aria-label": entry.name.replace(/_/g, " "), "aria-pressed": value === entry.char, onClick: () => pick(entry), className: cx("flex size-8 items-center justify-center rounded-md text-xl leading-none hover:bg-accent", value === entry.char && "bg-accent ring-1 ring-ring"), children: entry.char }, entry.name))) })] }, section.group ?? "results")))) }), value ? (_jsx("div", { className: "mt-1 flex justify-end border-t border-border pt-2", children: _jsx("button", { type: "button", className: `${ghostButtonClass} h-8 px-3`, onClick: () => {
|
|
33
|
+
onChange(null);
|
|
34
|
+
setOpen(false);
|
|
35
|
+
}, children: "Remove icon" }) })) : null] })] }));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=emoji-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emoji-picker.js","sourceRoot":"","sources":["../../src/editor/emoji-picker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type EmojiGroup = "smileys" | "people" | "nature" | "food" | "activities" | "travel" | "objects" | "symbols";
|
|
2
|
+
export interface EmojiEntry {
|
|
3
|
+
/** The character itself. */
|
|
4
|
+
char: string;
|
|
5
|
+
/** The `:shortcode:` name, lowercase, underscores. */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Extra search words beyond the name. */
|
|
8
|
+
keywords: string[];
|
|
9
|
+
group: EmojiGroup;
|
|
10
|
+
}
|
|
11
|
+
export declare const EMOJI_GROUP_LABELS: Record<EmojiGroup, string>;
|
|
12
|
+
export declare const EMOJI: EmojiEntry[];
|
|
13
|
+
/**
|
|
14
|
+
* Case-insensitive search over names and keywords. An empty query returns the
|
|
15
|
+
* whole set in catalogue order, which is what a picker wants to open with.
|
|
16
|
+
*/
|
|
17
|
+
export declare function searchEmoji(query: string, limit?: number): EmojiEntry[];
|
|
18
|
+
//# sourceMappingURL=emoji.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emoji.d.ts","sourceRoot":"","sources":["../../src/editor/emoji.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAEpH,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CASzD,CAAC;AASF,eAAO,MAAM,KAAK,EAAE,UAAU,EA0X7B,CAAC;AAEF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,UAAU,EAAE,CAWnE"}
|