@openeditor/emoji 0.0.14

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 ADDED
@@ -0,0 +1,19 @@
1
+ # `@openeditor/emoji`
2
+
3
+ Reusable web emoji selection for OpenEditor. The package composes Frimousse's
4
+ emoji primitives with a Base UI popover and exposes a stable OpenEditor-owned
5
+ component API. It intentionally contains no document or block knowledge.
6
+
7
+ Callouts, pages, and future emoji-bearing features store plain Unicode strings
8
+ in the portable document model and use this package only for web selection.
9
+ Import `@openeditor/ui/styles.css` for the default visual treatment.
10
+
11
+ ```tsx
12
+ import { OpenEditorEmojiPicker } from "@openeditor/emoji";
13
+
14
+ <OpenEditorEmojiPicker
15
+ emoji="šŸ’”"
16
+ label="Change emoji"
17
+ onEmojiSelect={(emoji) => console.log(emoji)}
18
+ />
19
+ ```
@@ -0,0 +1,19 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { Locale } from 'frimousse';
4
+
5
+ type OpenEditorEmojiPickerProps = {
6
+ emoji: string;
7
+ onEmojiSelect: (emoji: string) => void;
8
+ label: string;
9
+ disabled?: boolean;
10
+ container?: HTMLElement | null;
11
+ className?: string;
12
+ children?: ReactNode;
13
+ locale?: Locale;
14
+ emojibaseUrl?: string;
15
+ emojiVersion?: number;
16
+ };
17
+ declare const OpenEditorEmojiPicker: ({ emoji, onEmojiSelect, label, disabled, container, className, children, locale, emojibaseUrl, emojiVersion, }: OpenEditorEmojiPickerProps) => react.JSX.Element;
18
+
19
+ export { OpenEditorEmojiPicker, type OpenEditorEmojiPickerProps };
package/dist/index.js ADDED
@@ -0,0 +1,102 @@
1
+ import { Popover } from '@base-ui/react/popover';
2
+ import { EmojiPicker } from 'frimousse';
3
+ import { useState } from 'react';
4
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
+
6
+ // src/index.tsx
7
+ var emojiListComponents = {
8
+ CategoryHeader: ({ category, ...props }) => /* @__PURE__ */ jsx("div", { className: "oe-emoji-category", ...props, children: category.label }),
9
+ Row: ({ children, ...props }) => /* @__PURE__ */ jsx("div", { className: "oe-emoji-row", ...props, children }),
10
+ Emoji: ({ emoji, ...props }) => /* @__PURE__ */ jsx(
11
+ "button",
12
+ {
13
+ ...props,
14
+ "aria-label": emoji.label,
15
+ className: "oe-emoji-option",
16
+ type: "button",
17
+ children: emoji.emoji
18
+ }
19
+ )
20
+ };
21
+ var OpenEditorEmojiPicker = ({
22
+ emoji,
23
+ onEmojiSelect,
24
+ label,
25
+ disabled = false,
26
+ container,
27
+ className,
28
+ children,
29
+ locale,
30
+ emojibaseUrl,
31
+ emojiVersion
32
+ }) => {
33
+ const [open, setOpen] = useState(false);
34
+ return /* @__PURE__ */ jsxs(Popover.Root, { open, onOpenChange: setOpen, modal: false, children: [
35
+ /* @__PURE__ */ jsx(
36
+ Popover.Trigger,
37
+ {
38
+ "aria-label": label,
39
+ className: ["oe-emoji-trigger", className].filter(Boolean).join(" "),
40
+ disabled,
41
+ type: "button",
42
+ children: children ?? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: emoji })
43
+ }
44
+ ),
45
+ /* @__PURE__ */ jsx(Popover.Portal, { container, children: /* @__PURE__ */ jsx(
46
+ Popover.Positioner,
47
+ {
48
+ align: "start",
49
+ collisionPadding: 12,
50
+ positionMethod: "fixed",
51
+ side: "bottom",
52
+ sideOffset: 8,
53
+ children: /* @__PURE__ */ jsx(Popover.Popup, { className: "oe-emoji-popover", children: /* @__PURE__ */ jsxs(
54
+ EmojiPicker.Root,
55
+ {
56
+ className: "oe-emoji-picker",
57
+ emojibaseUrl,
58
+ emojiVersion,
59
+ locale,
60
+ onEmojiSelect: (selection) => {
61
+ onEmojiSelect(selection.emoji);
62
+ setOpen(false);
63
+ },
64
+ children: [
65
+ /* @__PURE__ */ jsx(
66
+ EmojiPicker.Search,
67
+ {
68
+ "aria-label": "Search emoji",
69
+ autoFocus: true,
70
+ className: "oe-emoji-search",
71
+ placeholder: "Search emoji\u2026"
72
+ }
73
+ ),
74
+ /* @__PURE__ */ jsxs(EmojiPicker.Viewport, { className: "oe-emoji-viewport", children: [
75
+ /* @__PURE__ */ jsx(EmojiPicker.Loading, { className: "oe-emoji-state", children: "Loading emoji\u2026" }),
76
+ /* @__PURE__ */ jsx(EmojiPicker.Empty, { className: "oe-emoji-state", children: "No emoji found." }),
77
+ /* @__PURE__ */ jsx(
78
+ EmojiPicker.List,
79
+ {
80
+ className: "oe-emoji-list",
81
+ components: emojiListComponents
82
+ }
83
+ )
84
+ ] }),
85
+ /* @__PURE__ */ jsxs("footer", { className: "oe-emoji-footer", children: [
86
+ /* @__PURE__ */ jsx(EmojiPicker.ActiveEmoji, { children: ({ emoji: active }) => active ? /* @__PURE__ */ jsxs(Fragment, { children: [
87
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: active.emoji }),
88
+ /* @__PURE__ */ jsx("span", { children: active.label })
89
+ ] }) : "Choose an emoji" }),
90
+ /* @__PURE__ */ jsx(EmojiPicker.SkinToneSelector, { "aria-label": "Change skin tone" })
91
+ ] })
92
+ ]
93
+ }
94
+ ) })
95
+ }
96
+ ) })
97
+ ] });
98
+ };
99
+
100
+ export { OpenEditorEmojiPicker };
101
+ //# sourceMappingURL=index.js.map
102
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { Popover } from \"@base-ui/react/popover\";\nimport {\n EmojiPicker,\n type EmojiPickerListComponents,\n type Locale,\n} from \"frimousse\";\nimport { useState, type ReactNode } from \"react\";\n\nconst emojiListComponents: EmojiPickerListComponents = {\n CategoryHeader: ({ category, ...props }) => (\n <div className=\"oe-emoji-category\" {...props}>{category.label}</div>\n ),\n Row: ({ children, ...props }) => (\n <div className=\"oe-emoji-row\" {...props}>{children}</div>\n ),\n Emoji: ({ emoji, ...props }) => (\n <button\n {...props}\n aria-label={emoji.label}\n className=\"oe-emoji-option\"\n type=\"button\"\n >\n {emoji.emoji}\n </button>\n ),\n};\n\nexport type OpenEditorEmojiPickerProps = {\n emoji: string;\n onEmojiSelect: (emoji: string) => void;\n label: string;\n disabled?: boolean;\n container?: HTMLElement | null;\n className?: string;\n children?: ReactNode;\n locale?: Locale;\n emojibaseUrl?: string;\n emojiVersion?: number;\n};\n\nexport const OpenEditorEmojiPicker = ({\n emoji,\n onEmojiSelect,\n label,\n disabled = false,\n container,\n className,\n children,\n locale,\n emojibaseUrl,\n emojiVersion,\n}: OpenEditorEmojiPickerProps) => {\n const [open, setOpen] = useState(false);\n\n return (\n <Popover.Root open={open} onOpenChange={setOpen} modal={false}>\n <Popover.Trigger\n aria-label={label}\n className={[\"oe-emoji-trigger\", className].filter(Boolean).join(\" \")}\n disabled={disabled}\n type=\"button\"\n >\n {children ?? <span aria-hidden=\"true\">{emoji}</span>}\n </Popover.Trigger>\n <Popover.Portal container={container}>\n <Popover.Positioner\n align=\"start\"\n collisionPadding={12}\n positionMethod=\"fixed\"\n side=\"bottom\"\n sideOffset={8}\n >\n <Popover.Popup className=\"oe-emoji-popover\">\n <EmojiPicker.Root\n className=\"oe-emoji-picker\"\n emojibaseUrl={emojibaseUrl}\n emojiVersion={emojiVersion}\n locale={locale}\n onEmojiSelect={(selection) => {\n onEmojiSelect(selection.emoji);\n setOpen(false);\n }}\n >\n <EmojiPicker.Search\n aria-label=\"Search emoji\"\n autoFocus\n className=\"oe-emoji-search\"\n placeholder=\"Search emoji…\"\n />\n <EmojiPicker.Viewport className=\"oe-emoji-viewport\">\n <EmojiPicker.Loading className=\"oe-emoji-state\">Loading emoji…</EmojiPicker.Loading>\n <EmojiPicker.Empty className=\"oe-emoji-state\">No emoji found.</EmojiPicker.Empty>\n <EmojiPicker.List\n className=\"oe-emoji-list\"\n components={emojiListComponents}\n />\n </EmojiPicker.Viewport>\n <footer className=\"oe-emoji-footer\">\n <EmojiPicker.ActiveEmoji>\n {({ emoji: active }) => active ? <><span aria-hidden=\"true\">{active.emoji}</span><span>{active.label}</span></> : \"Choose an emoji\"}\n </EmojiPicker.ActiveEmoji>\n <EmojiPicker.SkinToneSelector aria-label=\"Change skin tone\" />\n </footer>\n </EmojiPicker.Root>\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n};\n"]}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@openeditor/emoji",
3
+ "version": "0.0.14",
4
+ "type": "module",
5
+ "sideEffects": false,
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/EasyLink-HQ/openeditor.git",
9
+ "directory": "packages/emoji"
10
+ },
11
+ "main": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "import": "./dist/index.js"
23
+ },
24
+ "./package.json": "./package.json"
25
+ },
26
+ "scripts": {
27
+ "build": "tsup --config tsup.config.ts",
28
+ "typecheck": "tsc -p tsconfig.json --noEmit",
29
+ "clean": "rm -rf dist"
30
+ },
31
+ "dependencies": {
32
+ "@base-ui/react": "^1.6.0",
33
+ "frimousse": "0.3.0",
34
+ "react": "19.2.7"
35
+ },
36
+ "devDependencies": {
37
+ "@types/react": "19.2.17",
38
+ "tsup": "^8.5.1",
39
+ "typescript": "6.0.3"
40
+ },
41
+ "peerDependencies": {
42
+ "react": ">=19"
43
+ }
44
+ }