@connextar/house 0.1.1 → 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/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/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 +75 -11
|
@@ -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"}
|