bsky-richtext-react 1.0.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.
@@ -0,0 +1,106 @@
1
+ /* src/styles.css */
2
+ .bsky-richtext {
3
+ display: inline;
4
+ word-break: break-word;
5
+ overflow-wrap: break-word;
6
+ }
7
+ .bsky-mention,
8
+ .bsky-link,
9
+ .bsky-tag {
10
+ display: inline;
11
+ }
12
+ .bsky-editor {
13
+ display: block;
14
+ width: 100%;
15
+ box-sizing: border-box;
16
+ position: relative;
17
+ }
18
+ .bsky-editor-content {
19
+ display: block;
20
+ width: 100%;
21
+ box-sizing: border-box;
22
+ }
23
+ .bsky-editor .ProseMirror,
24
+ .bsky-editor-content .ProseMirror {
25
+ display: block;
26
+ width: 100%;
27
+ box-sizing: border-box;
28
+ outline: none;
29
+ min-height: 1em;
30
+ }
31
+ .bsky-editor .ProseMirror p,
32
+ .bsky-editor-content .ProseMirror p {
33
+ margin: 0;
34
+ }
35
+ .bsky-editor .ProseMirror p.is-editor-empty:first-child::before,
36
+ .bsky-editor-content .ProseMirror p.is-editor-empty:first-child::before {
37
+ content: attr(data-placeholder);
38
+ float: left;
39
+ height: 0;
40
+ pointer-events: none;
41
+ }
42
+ .bsky-editor-mention {
43
+ display: inline;
44
+ }
45
+ .autolink {
46
+ display: inline;
47
+ }
48
+ .bsky-suggestions {
49
+ display: flex;
50
+ flex-direction: column;
51
+ box-sizing: border-box;
52
+ max-height: 320px;
53
+ overflow-y: auto;
54
+ }
55
+ .bsky-suggestion-item {
56
+ display: flex;
57
+ flex-direction: row;
58
+ align-items: center;
59
+ width: 100%;
60
+ box-sizing: border-box;
61
+ cursor: pointer;
62
+ border: none;
63
+ background: transparent;
64
+ text-align: left;
65
+ padding: 0;
66
+ margin: 0;
67
+ user-select: none;
68
+ }
69
+ .bsky-suggestion-text {
70
+ display: flex;
71
+ flex-direction: column;
72
+ flex: 1;
73
+ min-width: 0;
74
+ overflow: hidden;
75
+ }
76
+ .bsky-suggestion-name,
77
+ .bsky-suggestion-handle {
78
+ display: block;
79
+ overflow: hidden;
80
+ white-space: nowrap;
81
+ text-overflow: ellipsis;
82
+ }
83
+ .bsky-suggestion-avatar {
84
+ display: flex;
85
+ flex-shrink: 0;
86
+ align-items: center;
87
+ justify-content: center;
88
+ }
89
+ .bsky-suggestion-avatar-img {
90
+ display: block;
91
+ width: 100%;
92
+ height: 100%;
93
+ object-fit: cover;
94
+ }
95
+ .bsky-suggestion-avatar-placeholder {
96
+ display: flex;
97
+ align-items: center;
98
+ justify-content: center;
99
+ width: 100%;
100
+ height: 100%;
101
+ }
102
+ .bsky-suggestion-empty {
103
+ display: block;
104
+ box-sizing: border-box;
105
+ }
106
+ /*# sourceMappingURL=styles.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/styles.css"],"sourcesContent":["/**\n * bsky-richtext-react — Structural CSS\n *\n * Import this file in your app for essential layout styles.\n * These rules define structure and positioning only — no colors,\n * fonts, or visual decoration. Override freely with your own styles.\n *\n * Usage:\n * import 'bsky-richtext-react/styles.css'\n *\n * Class names reference (matching the default classNames objects):\n *\n * RichTextDisplay:\n * .bsky-richtext — root <span>\n * .bsky-mention — @mention anchor\n * .bsky-link — link anchor\n * .bsky-tag — #hashtag anchor\n *\n * RichTextEditor:\n * .bsky-editor — root wrapper <div>\n * .bsky-editor-content — ProseMirror editable area wrapper\n * .bsky-editor-mention — mention chip inside the editor\n * .autolink — URL decoration span inside the editor\n *\n * MentionSuggestionList (dropdown):\n * .bsky-suggestions — outer container\n * .bsky-suggestion-item — each suggestion row (<button>)\n * .bsky-suggestion-item-selected — currently highlighted row\n * .bsky-suggestion-avatar — avatar wrapper\n * .bsky-suggestion-avatar-img — <img> element\n * .bsky-suggestion-avatar-placeholder — initial-letter fallback\n * .bsky-suggestion-text — text column (name + handle)\n * .bsky-suggestion-name — display name\n * .bsky-suggestion-handle — @handle\n * .bsky-suggestion-empty — \"No results\" message\n *\n * Visual styling guide:\n * All class names above can be targeted directly in your CSS.\n * Use generateClassNames() to append your own classes without\n * removing the structural defaults.\n */\n\n/* ─── RichTextDisplay ────────────────────────────────────────────────────── */\n\n.bsky-richtext {\n /* Inline so the span respects the parent's flow and wraps naturally */\n display: inline;\n /* Allow long URLs and handles to break at word boundaries */\n word-break: break-word;\n overflow-wrap: break-word;\n}\n\n/* Facet anchors — stay inline, no block-level layout shift */\n.bsky-mention,\n.bsky-link,\n.bsky-tag {\n display: inline;\n}\n\n/* ─── RichTextEditor ─────────────────────────────────────────────────────── */\n\n.bsky-editor {\n /* Fill available width */\n display: block;\n width: 100%;\n box-sizing: border-box;\n /* Establish a positioning context for any absolutely-positioned children */\n position: relative;\n}\n\n/* The ProseMirror editable region wrapper */\n.bsky-editor-content {\n display: block;\n width: 100%;\n box-sizing: border-box;\n}\n\n/* The ProseMirror editable region itself */\n.bsky-editor .ProseMirror,\n.bsky-editor-content .ProseMirror {\n display: block;\n width: 100%;\n box-sizing: border-box;\n /* Remove browser's default focus outline — consumers provide their own */\n outline: none;\n /* At least one line tall when empty, so clicks register */\n min-height: 1em;\n}\n\n/* Paragraphs — reset margin so consumers control spacing */\n.bsky-editor .ProseMirror p,\n.bsky-editor-content .ProseMirror p {\n margin: 0;\n}\n\n/* Placeholder — floated so it doesn't push content down */\n.bsky-editor .ProseMirror p.is-editor-empty:first-child::before,\n.bsky-editor-content .ProseMirror p.is-editor-empty:first-child::before {\n content: attr(data-placeholder);\n float: left;\n height: 0;\n pointer-events: none;\n}\n\n/* Mention chips inside the editor */\n.bsky-editor-mention {\n display: inline;\n}\n\n/* URL decorations inside the editor */\n.autolink {\n display: inline;\n}\n\n/* ─── Mention Suggestion Dropdown ───────────────────────────────────────── */\n\n.bsky-suggestions {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n /* Constrain height so very long lists don't overflow the viewport */\n max-height: 320px;\n overflow-y: auto;\n}\n\n.bsky-suggestion-item {\n /* Full-width button row */\n display: flex;\n flex-direction: row;\n align-items: center;\n width: 100%;\n box-sizing: border-box;\n cursor: pointer;\n /* Reset button element defaults */\n border: none;\n background: transparent;\n text-align: left;\n padding: 0;\n margin: 0;\n /* Prevent text selection on rapid clicks */\n user-select: none;\n}\n\n.bsky-suggestion-text {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0; /* allow text to truncate */\n overflow: hidden;\n}\n\n.bsky-suggestion-name,\n.bsky-suggestion-handle {\n display: block;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n/* Avatar wrapper — fixed square, circular clip via consumer CSS */\n.bsky-suggestion-avatar {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n}\n\n.bsky-suggestion-avatar-img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.bsky-suggestion-avatar-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n.bsky-suggestion-empty {\n display: block;\n box-sizing: border-box;\n}\n"],"mappings":";AA4CA,CAAC;AAEC,WAAS;AAET,cAAY;AACZ,iBAAe;AACjB;AAGA,CAAC;AACD,CAAC;AACD,CAAC;AACC,WAAS;AACX;AAIA,CAAC;AAEC,WAAS;AACT,SAAO;AACP,cAAY;AAEZ,YAAU;AACZ;AAGA,CAAC;AACC,WAAS;AACT,SAAO;AACP,cAAY;AACd;AAGA,CAjBC,YAiBY,CAAC;AACd,CARC,oBAQoB,CADP;AAEZ,WAAS;AACT,SAAO;AACP,cAAY;AAEZ,WAAS;AAET,cAAY;AACd;AAGA,CA7BC,YA6BY,CAZC,YAYY;AAC1B,CApBC,oBAoBoB,CAbP,YAaoB;AAChC,UAAQ;AACV;AAGA,CAnCC,YAmCY,CAlBC,YAkBY,CAAC,CAAC,eAAe,YAAY;AACvD,CA1BC,oBA0BoB,CAnBP,YAmBoB,CAAC,CADP,eACuB,YAAY;AAC7D,WAAS,KAAK;AACd,SAAO;AACP,UAAQ;AACR,kBAAgB;AAClB;AAGA,CAAC;AACC,WAAS;AACX;AAGA,CAAC;AACC,WAAS;AACX;AAIA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,cAAY;AAEZ,cAAY;AACZ,cAAY;AACd;AAEA,CAAC;AAEC,WAAS;AACT,kBAAgB;AAChB,eAAa;AACb,SAAO;AACP,cAAY;AACZ,UAAQ;AAER,UAAQ;AACR,cAAY;AACZ,cAAY;AACZ,WAAS;AACT,UAAQ;AAER,eAAa;AACf;AAEA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,QAAM;AACN,aAAW;AACX,YAAU;AACZ;AAEA,CAAC;AACD,CAAC;AACC,WAAS;AACT,YAAU;AACV,eAAa;AACb,iBAAe;AACjB;AAGA,CAAC;AACC,WAAS;AACT,eAAa;AACb,eAAa;AACb,mBAAiB;AACnB;AAEA,CAAC;AACC,WAAS;AACT,SAAO;AACP,UAAQ;AACR,cAAY;AACd;AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,SAAO;AACP,UAAQ;AACV;AAEA,CAAC;AACC,WAAS;AACT,cAAY;AACd;","names":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/package.json ADDED
@@ -0,0 +1,126 @@
1
+ {
2
+ "name": "bsky-richtext-react",
3
+ "version": "1.0.0",
4
+ "description": "React components for rendering and editing Bluesky richtext content (app.bsky.richtext lexicon)",
5
+ "author": "satyam-mishra-pce",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "bluesky",
9
+ "atproto",
10
+ "at-protocol",
11
+ "richtext",
12
+ "react",
13
+ "mention",
14
+ "editor",
15
+ "tiptap",
16
+ "facets"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/satyam-mishra-pce/bsky-richtext-react.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/satyam-mishra-pce/bsky-richtext-react/issues"
24
+ },
25
+ "homepage": "https://github.com/satyam-mishra-pce/bsky-richtext-react#readme",
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "type": "module",
30
+ "main": "./dist/index.cjs",
31
+ "module": "./dist/index.js",
32
+ "types": "./dist/index.d.ts",
33
+ "exports": {
34
+ ".": {
35
+ "import": {
36
+ "types": "./dist/index.d.ts",
37
+ "default": "./dist/index.js"
38
+ },
39
+ "require": {
40
+ "types": "./dist/index.d.cts",
41
+ "default": "./dist/index.cjs"
42
+ }
43
+ },
44
+ "./styles.css": "./dist/styles.css"
45
+ },
46
+ "files": [
47
+ "dist",
48
+ "README.md",
49
+ "CHANGELOG.md"
50
+ ],
51
+ "sideEffects": [
52
+ "*.css"
53
+ ],
54
+ "scripts": {
55
+ "dev": "storybook dev -p 6006",
56
+ "build": "tsup",
57
+ "build:watch": "tsup --watch",
58
+ "build:storybook": "storybook build",
59
+ "test": "vitest",
60
+ "test:run": "vitest run",
61
+ "test:coverage": "vitest run --coverage",
62
+ "test:ui": "vitest --ui",
63
+ "lint": "eslint \"src/**/*.{ts,tsx}\"",
64
+ "lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix",
65
+ "format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
66
+ "format:check": "prettier --check \"src/**/*.{ts,tsx,css}\"",
67
+ "typecheck": "tsc --noEmit",
68
+ "clean": "rm -rf dist",
69
+ "prepublishOnly": "bun run typecheck && bun run test:run && bun run build"
70
+ },
71
+ "peerDependencies": {
72
+ "react": "^18.0.0 || ^19.0.0",
73
+ "react-dom": "^18.0.0 || ^19.0.0"
74
+ },
75
+ "peerDependenciesMeta": {
76
+ "react-dom": {
77
+ "optional": false
78
+ }
79
+ },
80
+ "dependencies": {
81
+ "@atproto/api": "^0.13.16",
82
+ "@tiptap/core": "^2.11.5",
83
+ "@tiptap/extension-document": "^2.11.5",
84
+ "@tiptap/extension-hard-break": "^2.11.5",
85
+ "@tiptap/extension-history": "^2.11.5",
86
+ "@tiptap/extension-mention": "^2.11.5",
87
+ "@tiptap/extension-paragraph": "^2.11.5",
88
+ "@tiptap/extension-placeholder": "^2.11.5",
89
+ "@tiptap/extension-text": "^2.11.5",
90
+ "@tiptap/react": "^2.11.5",
91
+ "tippy.js": "^6.3.7"
92
+ },
93
+ "devDependencies": {
94
+ "@eslint/js": "^9.18.0",
95
+ "@storybook/addon-essentials": "^8.5.3",
96
+ "@storybook/addon-interactions": "^8.5.3",
97
+ "@storybook/addon-links": "^8.5.3",
98
+ "@storybook/blocks": "^8.5.3",
99
+ "@storybook/react": "^8.5.3",
100
+ "@storybook/react-vite": "^8.5.3",
101
+ "@storybook/test": "^8.5.3",
102
+ "@testing-library/jest-dom": "^6.6.3",
103
+ "@testing-library/react": "^16.1.0",
104
+ "@testing-library/user-event": "^14.5.2",
105
+ "@types/react": "^19.0.7",
106
+ "@types/react-dom": "^19.0.3",
107
+ "@types/tippy.js": "^6.3.0",
108
+ "@vitejs/plugin-react": "^4.3.4",
109
+ "@vitest/coverage-v8": "^3.0.2",
110
+ "@vitest/ui": "^3.0.2",
111
+ "eslint": "^9.18.0",
112
+ "eslint-plugin-react": "^7.37.4",
113
+ "eslint-plugin-react-hooks": "^5.1.0",
114
+ "globals": "^15.14.0",
115
+ "jsdom": "^26.0.0",
116
+ "prettier": "^3.4.2",
117
+ "react": "^19.0.0",
118
+ "react-dom": "^19.0.0",
119
+ "storybook": "^8.5.3",
120
+ "tsup": "^8.3.5",
121
+ "typescript": "^5.7.3",
122
+ "typescript-eslint": "^8.20.0",
123
+ "vite": "^6.0.7",
124
+ "vitest": "^3.0.2"
125
+ }
126
+ }