@itsammarb/mention-editor 1.0.3 → 1.0.4

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 CHANGED
@@ -1,11 +1,11 @@
1
- # @nexcore/mention-editor
1
+ # @itsammarb/mention-editor
2
2
 
3
3
  A Discord-style `@mention` rich-text editor built on [Slate.js](https://www.slatejs.org/). Mentions are atomic (void + inline) nodes: backspacing next to one deletes it whole, and the suggestion menu tracks the real caret position via `ReactEditor.toDOMRange`.
4
4
 
5
5
  ## Install
6
6
 
7
7
  ```sh
8
- npm install @nexcore/mention-editor slate slate-react slate-history
8
+ npm install @itsammarb/mention-editor slate slate-react slate-history
9
9
  ```
10
10
 
11
11
  Peer dependencies: React 18 or 19, `slate` and `slate-react` `^0.94.0`. No Tailwind setup required on your end — see [Styling](#styling).
@@ -13,8 +13,8 @@ Peer dependencies: React 18 or 19, `slate` and `slate-react` `^0.94.0`. No Tailw
13
13
  ## Usage
14
14
 
15
15
  ```tsx
16
- import { MentionEditor } from '@nexcore/mention-editor';
17
- import '@nexcore/mention-editor/styles.css';
16
+ import { MentionEditor } from '@itsammarb/mention-editor';
17
+ import '@itsammarb/mention-editor/styles.css';
18
18
 
19
19
  const fields = [
20
20
  { id: 'a1b2c3d4-0000-0000-0000-000000000001', label: 'Landlord Name' },
@@ -63,7 +63,7 @@ Hello <@a1b2c3d4-0000-0000-0000-000000000001>, welcome.
63
63
 
64
64
  ## Exported utilities
65
65
 
66
- Everything importable from `@nexcore/mention-editor`:
66
+ Everything importable from `@itsammarb/mention-editor`:
67
67
 
68
68
  | Export | Kind | Description |
69
69
  | --- | --- | --- |
@@ -93,9 +93,41 @@ Every rendered part carries a stable class name, at normal specificity (plain si
93
93
 
94
94
  Override any of these by targeting the class directly in your own CSS, or via `className` on the root for layout/border/background changes.
95
95
 
96
- **Dark mode**: the built-in `dark:` utilities respond to the OS/browser's `prefers-color-scheme: dark`, *not* a manually-toggled `.dark` class (e.g. from `next-themes` or a similar library). If your app drives dark mode via a class rather than OS preference, the shipped dark colors won't follow it — override `.mention-editor`, `.mention-editor__mention`, etc. directly with your own class-scoped CSS in that case.
96
+ ### Theme colors
97
97
 
98
- If your own app happens to use Tailwind and you want to reuse its utility classes against this component's internal DOM (beyond what `className` on the root reaches), you can optionally point your app's Tailwind config/`@source` at `node_modules/@nexcore/mention-editor/dist` but this is purely an opt-in extra, not required for the component to work or look right.
98
+ Every color is also a CSS custom property, so you can retheme the whole component with a handful of variable declarations instead of overriding individual classes. Set them anywhere that's an ancestor of the whole page `:root`, `html`, `body`, or a global stylesheet rule **not** scoped to `.mention-editor` itself: the suggestion menu is rendered through a React portal directly into `document.body`, so it sits *outside* `.mention-editor` in the real DOM and wouldn't inherit a variable scoped there.
99
+
100
+ ```css
101
+ /* anywhere in your global CSS, loaded in any order relative to this package's styles.css */
102
+ :root {
103
+ --mention-editor-mention-color: #16a34a; /* green mention text/underline */
104
+ --mention-editor-mention-bg: #dcfce7; /* optional pill-style highlight behind a mention */
105
+ --mention-editor-border-color: #db2777;
106
+ --mention-editor-menu-highlight-bg: #fde68a; /* selected/hovered suggestion row */
107
+ }
108
+ ```
109
+
110
+ | Variable | Controls | Light default | Dark default |
111
+ | --- | --- | --- | --- |
112
+ | `--mention-editor-bg` | Editor container background | white | neutral-900 |
113
+ | `--mention-editor-text-color` | Editor body text color | gray-900 | gray-100 |
114
+ | `--mention-editor-border-color` | Container border (normal state) | gray-300 | neutral-700 |
115
+ | `--mention-editor-border-color-error` | Container border when `isError` | red-500 | red-500 (same in both) |
116
+ | `--mention-editor-placeholder-color` | Placeholder text color | gray-400 | neutral-500 |
117
+ | `--mention-editor-mention-color` | A mention's text/underline color | blue-600 | blue-400 |
118
+ | `--mention-editor-mention-bg` | Background behind a mention (e.g. a pill highlight) | transparent | transparent |
119
+ | `--mention-editor-menu-bg` | Suggestion menu background | white | neutral-800 |
120
+ | `--mention-editor-menu-border-color` | Suggestion menu border | gray-300 | neutral-700 |
121
+ | `--mention-editor-menu-text-color` | Suggestion menu row text | gray-900 | gray-100 |
122
+ | `--mention-editor-menu-highlight-bg` | Selected/hovered suggestion row background | indigo-50 | neutral-700 |
123
+
124
+ Setting a variable applies it in both light and dark mode (the fallback is what differs by scheme, not the override) — if you want genuinely different override colors per scheme, redeclare the variable yourself inside your own `@media (prefers-color-scheme: dark)` block.
125
+
126
+ These defaults aren't asserted anywhere as a real `:root` rule in this package's stylesheet — they're inline `var(--x, fallback)` fallbacks on each utility class instead. That's deliberate: a real default declaration and a consumer override would both be equal-specificity `:root` rules, so whichever stylesheet happened to load *last* would silently win regardless of intent. Reading the variable with an inline fallback means there's only ever one real assignment (yours, if you set one), so load order can't matter.
127
+
128
+ **Dark mode**: the built-in dark defaults respond to the OS/browser's `prefers-color-scheme: dark`, *not* a manually-toggled `.dark` class (e.g. from `next-themes` or a similar library). If your app drives dark mode via a class rather than OS preference, set the variables above directly (they'll then apply regardless of scheme), or scope your own overrides under your app's dark-mode class selector.
129
+
130
+ If your own app happens to use Tailwind and you want to reuse its utility classes against this component's internal DOM (beyond what `className` on the root reaches), you can optionally point your app's Tailwind config/`@source` at `node_modules/@itsammarb/mention-editor/dist` — but this is purely an opt-in extra, not required for the component to work or look right.
99
131
 
100
132
  ## Behavior notes
101
133
 
@@ -138,20 +138,23 @@ function MentionEditor(props) {
138
138
  }
139
139
  }, [target, index, filteredFields, selectField]);
140
140
  const rootClassName = [
141
- 'mention-editor relative rounded-md border bg-white dark:bg-neutral-900',
142
- isError ? 'border-red-500' : 'border-gray-300 dark:border-neutral-700',
141
+ 'mention-editor relative rounded-md border',
142
+ 'bg-(--mention-editor-bg,var(--color-white)) dark:bg-(--mention-editor-bg,var(--color-neutral-900))',
143
+ isError
144
+ ? 'border-(--mention-editor-border-color-error,var(--color-red-500))'
145
+ : 'border-(--mention-editor-border-color,var(--color-gray-300)) dark:border-(--mention-editor-border-color,var(--color-neutral-700))',
143
146
  disabled && 'opacity-60',
144
147
  className,
145
148
  ]
146
149
  .filter(Boolean)
147
150
  .join(' ');
148
151
  const editableStyle = rows ? { minHeight: `${rows * 1.5}em` } : undefined;
149
- return ((0, jsx_runtime_1.jsx)(slate_react_1.Slate, { editor: editor, value: slateValue, onChange: handleChange, children: (0, jsx_runtime_1.jsxs)("div", { className: rootClassName, children: [(0, jsx_runtime_1.jsx)(slate_react_1.Editable, { className: "mention-editor__editable min-h-11 px-3 py-2 text-base leading-6 text-gray-900 outline-none dark:text-gray-100", style: editableStyle, dir: dir, readOnly: disabled, onKeyDown: handleKeyDown, placeholder: placeholder, renderElement: (elementProps) => (0, jsx_runtime_1.jsx)(Element, { ...elementProps }), renderPlaceholder: renderPlaceholder }), target && ((0, jsx_runtime_1.jsx)(MentionMenu_1.MentionMenu, { fields: filteredFields, selectedIndex: index, onSelect: selectField, onHover: setIndex, targetRect: menuTargetRect }))] }) }, generation));
152
+ return ((0, jsx_runtime_1.jsx)(slate_react_1.Slate, { editor: editor, value: slateValue, onChange: handleChange, children: (0, jsx_runtime_1.jsxs)("div", { className: rootClassName, children: [(0, jsx_runtime_1.jsx)(slate_react_1.Editable, { className: "mention-editor__editable min-h-11 px-3 py-2 text-base leading-6 outline-none text-(--mention-editor-text-color,var(--color-gray-900)) dark:text-(--mention-editor-text-color,var(--color-gray-100))", style: editableStyle, dir: dir, readOnly: disabled, onKeyDown: handleKeyDown, placeholder: placeholder, renderElement: (elementProps) => (0, jsx_runtime_1.jsx)(Element, { ...elementProps }), renderPlaceholder: renderPlaceholder }), target && ((0, jsx_runtime_1.jsx)(MentionMenu_1.MentionMenu, { fields: filteredFields, selectedIndex: index, onSelect: selectField, onHover: setIndex, targetRect: menuTargetRect }))] }) }, generation));
150
153
  }
151
154
  // slate-react's default placeholder renders at a fixed dim-black opacity,
152
155
  // which reads poorly in dark mode. Overriding it lets the placeholder use
153
156
  // real (theme-aware) Tailwind colors at full opacity instead.
154
- const renderPlaceholder = ({ attributes, children }) => ((0, jsx_runtime_1.jsx)("span", { ...attributes, style: { ...attributes.style, opacity: 1 }, className: "text-gray-400 dark:text-neutral-500", children: children }));
157
+ const renderPlaceholder = ({ attributes, children }) => ((0, jsx_runtime_1.jsx)("span", { ...attributes, style: { ...attributes.style, opacity: 1 }, className: "text-(--mention-editor-placeholder-color,var(--color-gray-400)) dark:text-(--mention-editor-placeholder-color,var(--color-neutral-500))", children: children }));
155
158
  // --- TRIGGER DETECTION ---
156
159
  const MAX_MENTION_SEARCH_LENGTH = 50;
157
160
  /**
@@ -236,7 +239,7 @@ const Element = ({ attributes, children, element }) => {
236
239
  var _a;
237
240
  switch (element.type) {
238
241
  case 'mention':
239
- return ((0, jsx_runtime_1.jsxs)("span", { ...attributes, contentEditable: false, className: "mention-editor__mention cursor-default text-blue-600 underline decoration-1 underline-offset-2 [unicode-bidi:isolate] dark:text-blue-400", children: ["@", (_a = element.field) === null || _a === void 0 ? void 0 : _a.label, children] }));
242
+ return ((0, jsx_runtime_1.jsxs)("span", { ...attributes, contentEditable: false, className: "mention-editor__mention cursor-default underline decoration-1 underline-offset-2 [unicode-bidi:isolate] text-(--mention-editor-mention-color,var(--color-blue-600)) dark:text-(--mention-editor-mention-color,var(--color-blue-400)) bg-(--mention-editor-mention-bg,transparent)", children: ["@", (_a = element.field) === null || _a === void 0 ? void 0 : _a.label, children] }));
240
243
  default:
241
244
  return ((0, jsx_runtime_1.jsx)("p", { ...attributes, className: "mention-editor__paragraph m-0 [&+&]:mt-1", children: children }));
242
245
  }
@@ -13,12 +13,17 @@ const MentionMenu = ({ fields, selectedIndex, onSelect, onHover, targetRect, })
13
13
  // another modal: portaling to <body> means there's no transformed/positioned
14
14
  // ancestor between the menu and the viewport to throw off `fixed` coordinates.
15
15
  // The caller (MentionEditor) keeps `targetRect` fresh across scroll/resize.
16
- return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)("div", { className: "mention-editor__menu z-[9999] w-[280px] max-h-[300px] overflow-y-auto rounded-md border border-gray-300 bg-white py-1 shadow-lg dark:border-neutral-700 dark:bg-neutral-800", style: {
16
+ return (0, react_dom_1.createPortal)((0, jsx_runtime_1.jsx)("div", { className: "mention-editor__menu z-9999 w-70 max-h-75 overflow-y-auto rounded-md border py-1 shadow-lg border-(--mention-editor-menu-border-color,var(--color-gray-300)) dark:border-(--mention-editor-menu-border-color,var(--color-neutral-700)) bg-(--mention-editor-menu-bg,var(--color-white)) dark:bg-(--mention-editor-menu-bg,var(--color-neutral-800))", style: {
17
17
  position: 'fixed',
18
18
  top: targetRect.bottom + 8,
19
19
  left: targetRect.left,
20
- }, children: fields.map((field, i) => ((0, jsx_runtime_1.jsx)("div", { className: 'mention-editor__menu-item cursor-pointer px-3 py-2 text-gray-900 dark:text-gray-100' +
21
- (i === selectedIndex ? ' bg-indigo-50 dark:bg-neutral-700' : ''), onClick: (e) => {
20
+ }, children: fields.map((field, i) => ((0, jsx_runtime_1.jsx)("div", { className: 'mention-editor__menu-item cursor-pointer px-3 py-2' +
21
+ ' text-(--mention-editor-menu-text-color,var(--color-gray-900))' +
22
+ ' dark:text-(--mention-editor-menu-text-color,var(--color-gray-100))' +
23
+ (i === selectedIndex
24
+ ? ' bg-(--mention-editor-menu-highlight-bg,var(--color-indigo-50))' +
25
+ ' dark:bg-(--mention-editor-menu-highlight-bg,var(--color-neutral-700))'
26
+ : ''), onClick: (e) => {
22
27
  e.preventDefault();
23
28
  onSelect(field);
24
29
  }, onMouseDown: (e) => e.preventDefault(), onMouseEnter: () => onHover(i), children: field.label }, field.id))) }), document.body);
package/dist/styles.css CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}:root,:host{--color-red-500:oklch(63.7% .237 25.331);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-600:oklch(54.6% .245 262.881);--color-indigo-50:oklch(96.2% .018 272.314);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-900:oklch(21% .034 264.665);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-white:#fff;--spacing:.25rem;--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--radius-md:.375rem}.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.isolate{isolation:isolate}.z-\[9999\]{z-index:9999}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.block{display:block}.contents{display:contents}.inline{display:inline}.max-h-\[300px\]{max-height:300px}.min-h-11{min-height:calc(var(--spacing) * 11)}.w-\[280px\]{width:280px}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize{resize:both}.overflow-y-auto{overflow-y:auto}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-gray-300{border-color:var(--color-gray-300)}.border-red-500{border-color:var(--color-red-500)}.bg-indigo-50{background-color:var(--color-indigo-50)}.bg-white{background-color:var(--color-white)}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.text-blue-600{color:var(--color-blue-600)}.text-gray-400{color:var(--color-gray-400)}.text-gray-900{color:var(--color-gray-900)}.underline{text-decoration-line:underline}.decoration-1{text-decoration-thickness:1px}.underline-offset-2{text-underline-offset:2px}.opacity-60{opacity:.6}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.outline-none{--tw-outline-style:none;outline-style:none}.\[unicode-bidi\:isolate\]{unicode-bidi:isolate}@media (prefers-color-scheme:dark){.dark\:border-neutral-700{border-color:var(--color-neutral-700)}.dark\:bg-neutral-700{background-color:var(--color-neutral-700)}.dark\:bg-neutral-800{background-color:var(--color-neutral-800)}.dark\:bg-neutral-900{background-color:var(--color-neutral-900)}.dark\:text-blue-400{color:var(--color-blue-400)}.dark\:text-gray-100{color:var(--color-gray-100)}.dark\:text-neutral-500{color:var(--color-neutral-500)}}.\[\&\+\&\]\:mt-1+.\[\&\+\&\]\:mt-1{margin-top:var(--spacing)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}:root,:host{--color-red-500:oklch(63.7% .237 25.331);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-600:oklch(54.6% .245 262.881);--color-indigo-50:oklch(96.2% .018 272.314);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-900:oklch(21% .034 264.665);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-white:#fff;--spacing:.25rem;--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--radius-md:.375rem}.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.isolate{isolation:isolate}.z-9999{z-index:9999}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-0{margin:0}.block{display:block}.contents{display:contents}.inline{display:inline}.max-h-75{max-height:calc(var(--spacing) * 75)}.min-h-11{min-height:calc(var(--spacing) * 11)}.w-70{width:calc(var(--spacing) * 70)}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.resize{resize:both}.overflow-y-auto{overflow-y:auto}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-\(--mention-editor-border-color\,var\(--color-gray-300\)\){border-color:var(--mention-editor-border-color,var(--color-gray-300))}.border-\(--mention-editor-border-color-error\,var\(--color-red-500\)\){border-color:var(--mention-editor-border-color-error,var(--color-red-500))}.border-\(--mention-editor-menu-border-color\,var\(--color-gray-300\)\){border-color:var(--mention-editor-menu-border-color,var(--color-gray-300))}.border-red-500{border-color:var(--color-red-500)}.bg-\(--mention-editor-bg\,var\(--color-white\)\){background-color:var(--mention-editor-bg,var(--color-white))}.bg-\(--mention-editor-mention-bg\,transparent\){background-color:var(--mention-editor-mention-bg,transparent)}.bg-\(--mention-editor-menu-bg\,var\(--color-white\)\){background-color:var(--mention-editor-menu-bg,var(--color-white))}.bg-\(--mention-editor-menu-highlight-bg\,var\(--color-indigo-50\)\){background-color:var(--mention-editor-menu-highlight-bg,var(--color-indigo-50))}.px-3{padding-inline:calc(var(--spacing) * 3)}.py-1{padding-block:var(--spacing)}.py-2{padding-block:calc(var(--spacing) * 2)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.text-\(--mention-editor-mention-color\,var\(--color-blue-600\)\){color:var(--mention-editor-mention-color,var(--color-blue-600))}.text-\(--mention-editor-menu-text-color\,var\(--color-gray-900\)\){color:var(--mention-editor-menu-text-color,var(--color-gray-900))}.text-\(--mention-editor-placeholder-color\,var\(--color-gray-400\)\){color:var(--mention-editor-placeholder-color,var(--color-gray-400))}.text-\(--mention-editor-text-color\,var\(--color-gray-900\)\){color:var(--mention-editor-text-color,var(--color-gray-900))}.underline{text-decoration-line:underline}.decoration-1{text-decoration-thickness:1px}.underline-offset-2{text-underline-offset:2px}.opacity-60{opacity:.6}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.outline-none{--tw-outline-style:none;outline-style:none}.\[unicode-bidi\:isolate\]{unicode-bidi:isolate}@media (prefers-color-scheme:dark){.dark\:border-\(--mention-editor-border-color\,var\(--color-neutral-700\)\){border-color:var(--mention-editor-border-color,var(--color-neutral-700))}.dark\:border-\(--mention-editor-menu-border-color\,var\(--color-neutral-700\)\){border-color:var(--mention-editor-menu-border-color,var(--color-neutral-700))}.dark\:bg-\(--mention-editor-bg\,var\(--color-neutral-900\)\){background-color:var(--mention-editor-bg,var(--color-neutral-900))}.dark\:bg-\(--mention-editor-menu-bg\,var\(--color-neutral-800\)\){background-color:var(--mention-editor-menu-bg,var(--color-neutral-800))}.dark\:bg-\(--mention-editor-menu-highlight-bg\,var\(--color-neutral-700\)\){background-color:var(--mention-editor-menu-highlight-bg,var(--color-neutral-700))}.dark\:text-\(--mention-editor-mention-color\,var\(--color-blue-400\)\){color:var(--mention-editor-mention-color,var(--color-blue-400))}.dark\:text-\(--mention-editor-menu-text-color\,var\(--color-gray-100\)\){color:var(--mention-editor-menu-text-color,var(--color-gray-100))}.dark\:text-\(--mention-editor-placeholder-color\,var\(--color-neutral-500\)\){color:var(--mention-editor-placeholder-color,var(--color-neutral-500))}.dark\:text-\(--mention-editor-text-color\,var\(--color-gray-100\)\){color:var(--mention-editor-text-color,var(--color-gray-100))}}.\[\&\+\&\]\:mt-1+.\[\&\+\&\]\:mt-1{margin-top:var(--spacing)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
package/llms.txt CHANGED
@@ -64,6 +64,14 @@ function Example() {
64
64
 
65
65
  `.mention-editor` (root), `.mention-editor__editable`, `.mention-editor__paragraph`, `.mention-editor__mention`, `.mention-editor__menu`, `.mention-editor__menu-item`.
66
66
 
67
+ ## Theme colors (CSS custom properties)
68
+
69
+ Set these at `:root`/`html`/`body` scope in your own global CSS (not scoped to `.mention-editor` — the suggestion menu portals to `document.body`, outside it) to retheme without touching classes:
70
+
71
+ `--mention-editor-bg`, `--mention-editor-text-color`, `--mention-editor-border-color`, `--mention-editor-border-color-error`, `--mention-editor-placeholder-color`, `--mention-editor-mention-color`, `--mention-editor-mention-bg`, `--mention-editor-menu-bg`, `--mention-editor-menu-border-color`, `--mention-editor-menu-text-color`, `--mention-editor-menu-highlight-bg`.
72
+
73
+ Each has a light/dark default baked in as a `var(--x, fallback)` on the relevant utility class (no competing `:root` declaration in this package's own CSS), so setting one always wins regardless of stylesheet load order, and applies in both light and dark mode unless you scope your own override inside a `prefers-color-scheme` media query.
74
+
67
75
  ## Full docs
68
76
 
69
77
  See `README.md` in this package for the complete prop/export/styling reference and more detail on each point above.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itsammarb/mention-editor",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "A Discord-style @mention rich-text editor built on Slate.js",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",