@meowdown/react 0.24.1 → 0.25.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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ReactElement, ReactNode, Ref } from "react";
2
- import { ExitBoundaryHandler, ImageClickHandler, ImageOptions, LinkClickHandler, MarkMode, PlaceholderOptions, TagClickHandler, TypedEditor, WikilinkClickHandler } from "@meowdown/core";
2
+ import { ExitBoundaryHandler, ImageClickHandler, ImageOptions, LinkClickHandler, LinkCopyHandler, MarkMode, PlaceholderOptions, TagClickHandler, TypedEditor, WikilinkClickHandler } from "@meowdown/core";
3
3
  import { SelectionJSON, SelectionJSON as SelectionJSON$1 } from "@prosekit/core";
4
4
  import { useEditor, useExtension, useKeymap } from "@prosekit/react";
5
5
 
@@ -124,6 +124,12 @@ interface EditorProps {
124
124
  * in source mode.
125
125
  */
126
126
  onLinkClick?: LinkClickHandler;
127
+ /**
128
+ * Called after a link is copied from the link menu, with its `href`. Useful
129
+ * for a toast. Pass a stable function (e.g. from `useCallback`). Ignored in
130
+ * source mode.
131
+ */
132
+ onLinkCopy?: LinkCopyHandler;
127
133
  /**
128
134
  * Called with the tag name (without the leading `#`) on click of a rendered
129
135
  * `#tag`. Pass a stable function (e.g. from `useCallback`). Ignored in source
@@ -209,6 +215,7 @@ declare function MeowdownEditor({
209
215
  onWikilinkSearch,
210
216
  onWikilinkClick,
211
217
  onLinkClick,
218
+ onLinkCopy,
212
219
  onTagClick,
213
220
  onExitBoundary,
214
221
  resolveImageUrl,
package/dist/index.js CHANGED
@@ -7,14 +7,15 @@ import { Compartment, EditorSelection, EditorState } from "@codemirror/state";
7
7
  import { EditorView, keymap } from "@codemirror/view";
8
8
  import { clamp } from "@ocavue/utils";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
- import { codeBlockLanguages, defaultResolveImageUrl, defineBulletAfterHeading, defineEditorExtension, defineEmbedPaste, defineExitBoundaryHandler, defineHTMLPaste, defineImage, defineImageClickHandler, defineLinkClickHandler, defineMarkMode, defineMarkdownCopy, definePlaceholder, defineReadonly, defineTagClickHandler, defineWikilinkClickHandler, defineWikilinkTrigger, docToMarkdown, getCodeTokens, getMarkBuilders, inlineTextToMarkChunks, listenForTweetHeight, markdownToDoc, matchEmbed } from "@meowdown/core";
10
+ import { codeBlockLanguages, defaultResolveImageUrl, defineBulletAfterHeading, defineEditorExtension, defineEmbedPaste, defineExitBoundaryHandler, defineHTMLPaste, defineImage, defineImageClickHandler, defineLinkClickHandler, defineLinkEditKeymap, defineLinkHoverHandler, defineMarkMode, defineMarkdownCopy, definePlaceholder, defineReadonly, defineTagClickHandler, defineWikilinkClickHandler, defineWikilinkTrigger, docToMarkdown, getCodeTokens, getMarkBuilders, getVirtualElementFromRange, inlineTextToMarkChunks, listenForTweetHeight, markdownToDoc, matchEmbed } from "@meowdown/core";
11
11
  import { canUseRegexLookbehind, createEditor, defineDocChangeHandler, union } from "@prosekit/core";
12
12
  import { Selection, TextSelection } from "@prosekit/pm/state";
13
13
  import { ProseKit, defineReactNodeView, useEditor, useEditor as useEditor$1, useEditorDerivedValue, useExtension, useExtension as useExtension$1, useKeymap } from "@prosekit/react";
14
14
  import { Combobox } from "@base-ui/react/combobox";
15
- import { CheckIcon, ChevronsUpDownIcon, CopyIcon, GripHorizontalIcon, GripVerticalIcon } from "lucide-react";
15
+ import { CheckIcon, ChevronsUpDownIcon, CopyIcon, GripHorizontalIcon, GripVerticalIcon, PencilIcon, UnlinkIcon } from "lucide-react";
16
16
  import { BlockHandleDraggable, BlockHandlePopup, BlockHandlePositioner, BlockHandleRoot } from "@prosekit/react/block-handle";
17
17
  import { DropIndicator } from "@prosekit/react/drop-indicator";
18
+ import { Popover } from "@base-ui/react/popover";
18
19
  import { AutocompleteEmpty, AutocompleteItem, AutocompletePopup, AutocompletePositioner, AutocompleteRoot } from "@prosekit/react/autocomplete";
19
20
  import { MenuItem, MenuPopup, MenuPositioner } from "@prosekit/react/menu";
20
21
  import { TableHandleColumnMenuRoot, TableHandleColumnMenuTrigger, TableHandleColumnPopup, TableHandleColumnPositioner, TableHandleDragPreview, TableHandleDropIndicator, TableHandleRoot, TableHandleRowMenuRoot, TableHandleRowMenuTrigger, TableHandleRowPopup, TableHandleRowPositioner } from "@prosekit/react/table-handle";
@@ -155,8 +156,41 @@ var code_block_view_module_default = {
155
156
  };
156
157
 
157
158
  //#endregion
158
- //#region src/components/code-block-view.tsx
159
+ //#region src/components/copy-button.tsx
159
160
  const COPIED_RESET_MS = 1500;
161
+ /**
162
+ * A copy-to-clipboard button with "copied" feedback. Shared by the code block
163
+ * toolbar and the link popover.
164
+ */
165
+ function CopyButton({ getText, label, onCopy, className, ...rest }) {
166
+ const [copied, setCopied] = useState(false);
167
+ const resetTimerRef = useRef(void 0);
168
+ const copy = async () => {
169
+ try {
170
+ await navigator.clipboard.writeText(getText());
171
+ setCopied(true);
172
+ clearTimeout(resetTimerRef.current);
173
+ resetTimerRef.current = setTimeout(() => setCopied(false), COPIED_RESET_MS);
174
+ onCopy?.();
175
+ } catch (error) {
176
+ console.warn("[meowdown] Failed to copy:", error);
177
+ }
178
+ };
179
+ return /* @__PURE__ */ jsx("button", {
180
+ type: "button",
181
+ className,
182
+ "data-copied": copied ? "" : void 0,
183
+ "aria-label": copied ? "Copied" : label,
184
+ title: copied ? "Copied" : label,
185
+ onMouseDown: (event) => event.preventDefault(),
186
+ onClick: copy,
187
+ ...rest,
188
+ children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
189
+ });
190
+ }
191
+
192
+ //#endregion
193
+ //#region src/components/code-block-view.tsx
160
194
  function CodeBlockView(props) {
161
195
  const language = props.node.attrs.language || "";
162
196
  const selected = useMemo(() => {
@@ -179,18 +213,6 @@ function CodeBlockView(props) {
179
213
  const setLanguage = (item) => {
180
214
  props.setAttrs({ language: item?.value ?? "" });
181
215
  };
182
- const [copied, setCopied] = useState(false);
183
- const resetTimerRef = useRef(void 0);
184
- const copy = async () => {
185
- try {
186
- await navigator.clipboard.writeText(props.node.textContent);
187
- setCopied(true);
188
- clearTimeout(resetTimerRef.current);
189
- resetTimerRef.current = setTimeout(() => setCopied(false), COPIED_RESET_MS);
190
- } catch (error) {
191
- console.warn("[meowdown] Failed to copy code block:", error);
192
- }
193
- };
194
216
  return /* @__PURE__ */ jsxs("div", {
195
217
  className: code_block_view_module_default.Root,
196
218
  children: [/* @__PURE__ */ jsxs("div", {
@@ -252,16 +274,11 @@ function CodeBlockView(props) {
252
274
  ]
253
275
  })
254
276
  }) })]
255
- }), /* @__PURE__ */ jsx("button", {
256
- type: "button",
277
+ }), /* @__PURE__ */ jsx(CopyButton, {
278
+ getText: () => props.node.textContent,
279
+ label: "Copy code",
257
280
  className: code_block_view_module_default.CopyButton,
258
- "data-testid": "code-block-copy",
259
- "data-copied": copied ? "" : void 0,
260
- "aria-label": copied ? "Copied" : "Copy code",
261
- title: copied ? "Copied" : "Copy code",
262
- onMouseDown: (event) => event.preventDefault(),
263
- onClick: copy,
264
- children: copied ? /* @__PURE__ */ jsx(CheckIcon, {}) : /* @__PURE__ */ jsx(CopyIcon, {})
281
+ "data-testid": "code-block-copy"
265
282
  })]
266
283
  }), /* @__PURE__ */ jsx("pre", {
267
284
  ref: props.contentRef,
@@ -376,6 +393,269 @@ function EditorExtensions({ markMode, onDocChange, onWikilinkClick, onLinkClick,
376
393
  return null;
377
394
  }
378
395
 
396
+ //#endregion
397
+ //#region src/hooks/use-delayed-flag.ts
398
+ /** Delay before the flag opens, in ms. */
399
+ const OPEN_DELAY = 400;
400
+ /** Grace before the flag closes, in ms. The window lets a pointer travel from
401
+ * the hovered link onto the popover it anchors. */
402
+ const CLOSE_DELAY = 300;
403
+ /**
404
+ * Mirrors `value` into a boolean that flips true `openDelay`ms after `value`
405
+ * becomes true and false `closeDelay`ms after it becomes false, cancelling any
406
+ * pending flip on each change.
407
+ */
408
+ function useDelayedFlag(value, openDelay = OPEN_DELAY, closeDelay = CLOSE_DELAY) {
409
+ const [flag, setFlag] = useState(false);
410
+ const timerRef = useRef(void 0);
411
+ useEffect(() => {
412
+ clearTimeout(timerRef.current);
413
+ timerRef.current = setTimeout(() => setFlag(value), value ? openDelay : closeDelay);
414
+ return () => clearTimeout(timerRef.current);
415
+ }, [
416
+ value,
417
+ openDelay,
418
+ closeDelay
419
+ ]);
420
+ return flag;
421
+ }
422
+
423
+ //#endregion
424
+ //#region src/components/link-menu.module.css
425
+ var link_menu_module_default = {
426
+ "Button": "meow_Button_IjcqKG",
427
+ "Form": "meow_Form_IjcqKG",
428
+ "Input": "meow_Input_IjcqKG",
429
+ "Popup": "meow_Popup_IjcqKG",
430
+ "Positioner": "meow_Positioner_IjcqKG",
431
+ "Row": "meow_Row_IjcqKG",
432
+ "SrOnly": "meow_SrOnly_IjcqKG",
433
+ "Url": "meow_Url_IjcqKG"
434
+ };
435
+
436
+ //#endregion
437
+ //#region src/components/link-menu.tsx
438
+ /** Select the link unit so the text-backed commands target it, and keep the
439
+ * editor focused so its virtual selection stays visible behind the popover. */
440
+ function selectLinkUnit(editor, link) {
441
+ editor.commands.selectText(link.unit.from, link.unit.to);
442
+ editor.focus();
443
+ }
444
+ /** A Base UI popover anchored at `anchor`. Base UI dismisses it on an outside
445
+ * press or Escape, both routed through `onClose`. */
446
+ function LinkPopover({ anchor, onClose, onPopupHover, children }) {
447
+ return /* @__PURE__ */ jsx(Popover.Root, {
448
+ open: true,
449
+ onOpenChange: (open) => {
450
+ if (!open) onClose();
451
+ },
452
+ children: /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(Popover.Positioner, {
453
+ anchor,
454
+ side: "bottom",
455
+ sideOffset: 8,
456
+ className: link_menu_module_default.Positioner,
457
+ children: /* @__PURE__ */ jsx(Popover.Popup, {
458
+ className: link_menu_module_default.Popup,
459
+ "data-testid": "link-popover",
460
+ initialFocus: false,
461
+ finalFocus: false,
462
+ onMouseEnter: () => onPopupHover?.(true),
463
+ onMouseLeave: () => onPopupHover?.(false),
464
+ children
465
+ })
466
+ }) })
467
+ });
468
+ }
469
+ /** The hover preview: the url plus copy, edit, and remove actions. */
470
+ function LinkInfoContent({ href, onLinkClick, onLinkCopy, onEdit, onRemove }) {
471
+ return /* @__PURE__ */ jsxs("div", {
472
+ className: link_menu_module_default.Row,
473
+ "data-testid": "link-popover-read",
474
+ children: [
475
+ /* @__PURE__ */ jsx("a", {
476
+ className: link_menu_module_default.Url,
477
+ href,
478
+ title: href,
479
+ target: "_blank",
480
+ rel: "noopener noreferrer",
481
+ onClick: (event) => {
482
+ if (!onLinkClick) return;
483
+ event.preventDefault();
484
+ onLinkClick({
485
+ href,
486
+ event: event.nativeEvent
487
+ });
488
+ },
489
+ children: href
490
+ }),
491
+ /* @__PURE__ */ jsx(CopyButton, {
492
+ getText: () => href,
493
+ label: "Copy link",
494
+ className: link_menu_module_default.Button,
495
+ onCopy: () => onLinkCopy?.({ href })
496
+ }),
497
+ /* @__PURE__ */ jsx("button", {
498
+ type: "button",
499
+ className: link_menu_module_default.Button,
500
+ title: "Edit link",
501
+ "aria-label": "Edit link",
502
+ onClick: onEdit,
503
+ children: /* @__PURE__ */ jsx(PencilIcon, {})
504
+ }),
505
+ /* @__PURE__ */ jsx("button", {
506
+ type: "button",
507
+ className: link_menu_module_default.Button,
508
+ title: "Remove link",
509
+ "aria-label": "Remove link",
510
+ onClick: onRemove,
511
+ children: /* @__PURE__ */ jsx(UnlinkIcon, {})
512
+ })
513
+ ]
514
+ });
515
+ }
516
+ /** The url and title form, opened by `Mod-k` or the preview's edit button. */
517
+ function LinkEditContent({ link, onSubmit }) {
518
+ const hrefInputRef = useRef(null);
519
+ const titleInputRef = useRef(null);
520
+ const href = link ? link.href : "";
521
+ const title = link ? link.title : "";
522
+ useEffect(() => {
523
+ hrefInputRef.current?.focus();
524
+ }, []);
525
+ return /* @__PURE__ */ jsxs("form", {
526
+ className: link_menu_module_default.Form,
527
+ "data-testid": "link-popover-edit",
528
+ onSubmit: (event) => {
529
+ event.preventDefault();
530
+ onSubmit(hrefInputRef.current?.value || "", titleInputRef.current?.value || "");
531
+ },
532
+ children: [
533
+ /* @__PURE__ */ jsx("input", {
534
+ ref: hrefInputRef,
535
+ className: link_menu_module_default.Input,
536
+ defaultValue: href,
537
+ placeholder: "Paste link...",
538
+ "data-testid": "link-popover-input"
539
+ }),
540
+ /* @__PURE__ */ jsx("input", {
541
+ ref: titleInputRef,
542
+ className: link_menu_module_default.Input,
543
+ defaultValue: title,
544
+ placeholder: "Title (optional)"
545
+ }),
546
+ /* @__PURE__ */ jsx("button", {
547
+ type: "submit",
548
+ className: link_menu_module_default.SrOnly,
549
+ "data-testid": "link-popover-submit",
550
+ children: "Save"
551
+ })
552
+ ]
553
+ });
554
+ }
555
+ /**
556
+ * Owns both link triggers and shows one popover at a time:
557
+ *
558
+ * - hovering a link opens a read-only preview that follows the pointer;
559
+ * - `Mod-k` (or the preview's edit button) opens an edit form that stays until
560
+ * it is submitted, dismissed with Escape, or pressed outside.
561
+ */
562
+ function LinkMenu({ onLinkClick, onLinkCopy }) {
563
+ const editor = useEditor$1();
564
+ const [hover, setHover] = useState();
565
+ const [onLink, setOnLink] = useState(false);
566
+ const [overPopup, setOverPopup] = useState(false);
567
+ const [edit, setEdit] = useState();
568
+ const hoverOpen = useDelayedFlag(onLink || overPopup);
569
+ useExtension$1(useMemo(() => {
570
+ return defineLinkHoverHandler((hit) => {
571
+ setOnLink(!!hit);
572
+ if (hit) setHover(hit.payload);
573
+ });
574
+ }, []));
575
+ useExtension$1(useMemo(() => {
576
+ return defineLinkEditKeymap((options) => {
577
+ setEdit(options);
578
+ });
579
+ }, []));
580
+ const closeHover = useCallback(() => {
581
+ setOnLink(false);
582
+ setOverPopup(false);
583
+ setHover(void 0);
584
+ }, []);
585
+ const closeEdit = useCallback(() => {
586
+ setEdit(void 0);
587
+ closeHover();
588
+ editor.focus();
589
+ }, [editor, closeHover]);
590
+ let rangeFrom;
591
+ let rangeTo;
592
+ if (edit) {
593
+ rangeFrom = edit.from;
594
+ rangeTo = edit.to;
595
+ } else if (hover) {
596
+ rangeFrom = hover.unit.from;
597
+ rangeTo = hover.unit.to;
598
+ }
599
+ const anchor = useMemo(() => {
600
+ if (rangeFrom == null || rangeTo == null) return;
601
+ return getVirtualElementFromRange(editor.view, {
602
+ from: rangeFrom,
603
+ to: rangeTo
604
+ });
605
+ }, [
606
+ rangeFrom,
607
+ rangeTo,
608
+ editor
609
+ ]);
610
+ if (edit) return /* @__PURE__ */ jsx(LinkPopover, {
611
+ anchor,
612
+ onClose: closeEdit,
613
+ children: /* @__PURE__ */ jsx(LinkEditContent, {
614
+ link: edit.link,
615
+ onSubmit: (href, title) => {
616
+ if (edit.link) if (href.trim()) editor.commands.updateLink({
617
+ href,
618
+ title
619
+ });
620
+ else editor.commands.removeLink();
621
+ else if (href.trim()) editor.commands.insertLink({
622
+ href,
623
+ title
624
+ });
625
+ closeEdit();
626
+ }
627
+ })
628
+ });
629
+ if (hoverOpen && hover) {
630
+ const link = hover;
631
+ return /* @__PURE__ */ jsx(LinkPopover, {
632
+ anchor,
633
+ onClose: closeHover,
634
+ onPopupHover: setOverPopup,
635
+ children: /* @__PURE__ */ jsx(LinkInfoContent, {
636
+ href: link.href,
637
+ onLinkClick,
638
+ onLinkCopy,
639
+ onEdit: () => {
640
+ selectLinkUnit(editor, link);
641
+ setEdit({
642
+ from: link.unit.from,
643
+ to: link.unit.to,
644
+ link
645
+ });
646
+ closeHover();
647
+ },
648
+ onRemove: () => {
649
+ selectLinkUnit(editor, link);
650
+ editor.commands.removeLink();
651
+ closeHover();
652
+ }
653
+ })
654
+ });
655
+ }
656
+ return null;
657
+ }
658
+
379
659
  //#endregion
380
660
  //#region src/components/autocomplete-menu.module.css
381
661
  var autocomplete_menu_module_default = {
@@ -780,7 +1060,7 @@ function resolveSelection(doc, selection) {
780
1060
  return TextSelection.between(doc.resolve(anchor), doc.resolve(head));
781
1061
  }
782
1062
  }
783
- function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTagSearch, onWikilinkSearch, onWikilinkClick, onLinkClick, onTagClick, onExitBoundary, resolveImageUrl, onImagePaste, onImageSaveError, onImageClick, embedPaste, bulletAfterHeading, frontmatter = false, blockHandle = true, placeholder, readOnly, spellCheck, editorClassName, ref, children }) {
1063
+ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTagSearch, onWikilinkSearch, onWikilinkClick, onLinkClick, onLinkCopy, onTagClick, onExitBoundary, resolveImageUrl, onImagePaste, onImageSaveError, onImageClick, embedPaste, bulletAfterHeading, frontmatter = false, blockHandle = true, placeholder, readOnly, spellCheck, editorClassName, ref, children }) {
784
1064
  const [editor] = useState(() => {
785
1065
  const editor = createEditor({ extension: union(defineEditorExtension(), defineCodeBlockView()) });
786
1066
  if (initialMarkdown) editor.setContent(markdownToDoc(initialMarkdown, {
@@ -878,6 +1158,10 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTa
878
1158
  !readOnly && /* @__PURE__ */ jsx(TableHandle, {}),
879
1159
  blockHandle && !readOnly && /* @__PURE__ */ jsx(DropIndicator$1, {}),
880
1160
  /* @__PURE__ */ jsx(SlashMenu, {}),
1161
+ !readOnly && /* @__PURE__ */ jsx(LinkMenu, {
1162
+ onLinkClick,
1163
+ onLinkCopy
1164
+ }),
881
1165
  onTagSearch && /* @__PURE__ */ jsx(TagMenu, { onTagSearch }),
882
1166
  onWikilinkSearch && /* @__PURE__ */ jsx(WikilinkMenu, { onWikilinkSearch }),
883
1167
  children
@@ -887,7 +1171,7 @@ function ProseKitEditor({ markMode = "focus", initialMarkdown, onDocChange, onTa
887
1171
 
888
1172
  //#endregion
889
1173
  //#region src/components/editor.tsx
890
- function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onTagSearch, onWikilinkSearch, onWikilinkClick, onLinkClick, onTagClick, onExitBoundary, resolveImageUrl, onImagePaste, onImageSaveError, onImageClick, embedPaste = true, bulletAfterHeading = false, frontmatter = false, blockHandle = true, placeholder, readOnly, spellCheck, editorClassName, wrapperClassName, handleRef, children }) {
1174
+ function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onTagSearch, onWikilinkSearch, onWikilinkClick, onLinkClick, onLinkCopy, onTagClick, onExitBoundary, resolveImageUrl, onImagePaste, onImageSaveError, onImageClick, embedPaste = true, bulletAfterHeading = false, frontmatter = false, blockHandle = true, placeholder, readOnly, spellCheck, editorClassName, wrapperClassName, handleRef, children }) {
891
1175
  const childRef = useRef(null);
892
1176
  useImperativeHandle(handleRef, () => {
893
1177
  function getMarkdown() {
@@ -953,6 +1237,7 @@ function MeowdownEditor({ mode = "focus", initialMarkdown, onDocChange, onTagSea
953
1237
  onWikilinkSearch,
954
1238
  onWikilinkClick,
955
1239
  onLinkClick,
1240
+ onLinkCopy,
956
1241
  onTagClick,
957
1242
  onExitBoundary,
958
1243
  resolveImageUrl,
package/dist/style.css CHANGED
@@ -255,6 +255,95 @@
255
255
  background: var(--meowdown-accent);
256
256
  transition: all .15s;
257
257
  }
258
+ .meow_Positioner_IjcqKG {
259
+ z-index: 50;
260
+ width: min(20rem, 100vw - 1rem);
261
+ display: block;
262
+ }
263
+
264
+ .meow_Popup_IjcqKG {
265
+ box-sizing: border-box;
266
+ border: 1px solid var(--meowdown-border);
267
+ background: var(--meowdown-link-popover-bg, light-dark(#fff, #18181b));
268
+ border-radius: .75rem;
269
+ flex-direction: column;
270
+ width: 100%;
271
+ padding: .25rem;
272
+ font-size: .875rem;
273
+ display: flex;
274
+ box-shadow: 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a;
275
+ }
276
+
277
+ .meow_Row_IjcqKG {
278
+ align-items: center;
279
+ gap: .125rem;
280
+ display: flex;
281
+ }
282
+
283
+ .meow_Url_IjcqKG {
284
+ white-space: nowrap;
285
+ text-overflow: ellipsis;
286
+ min-width: 0;
287
+ color: var(--meowdown-accent);
288
+ cursor: pointer;
289
+ flex: 1;
290
+ padding: .25rem .5rem;
291
+ overflow: hidden;
292
+ }
293
+
294
+ .meow_Button_IjcqKG {
295
+ color: var(--meowdown-text);
296
+ cursor: pointer;
297
+ border-radius: .5rem;
298
+ flex: none;
299
+ justify-content: center;
300
+ align-items: center;
301
+ padding: .375rem;
302
+ display: inline-flex;
303
+
304
+ &:hover {
305
+ background: var(--meowdown-link-popover-hover-bg, light-dark(#f4f4f5, #27272a));
306
+ }
307
+
308
+ & svg {
309
+ width: 1rem;
310
+ height: 1rem;
311
+ }
312
+ }
313
+
314
+ .meow_Form_IjcqKG {
315
+ flex-direction: column;
316
+ gap: .25rem;
317
+ padding: .25rem;
318
+ display: flex;
319
+ }
320
+
321
+ .meow_SrOnly_IjcqKG {
322
+ clip: rect(0, 0, 0, 0);
323
+ border: 0;
324
+ width: 1px;
325
+ height: 1px;
326
+ margin: -1px;
327
+ padding: 0;
328
+ position: absolute;
329
+ overflow: hidden;
330
+ }
331
+
332
+ .meow_Input_IjcqKG {
333
+ box-sizing: border-box;
334
+ width: 100%;
335
+ font: inherit;
336
+ color: var(--meowdown-text);
337
+ border: 1px solid var(--meowdown-border);
338
+ background: none;
339
+ border-radius: .5rem;
340
+ padding: .375rem .5rem;
341
+
342
+ &:focus {
343
+ outline: 2px solid var(--meowdown-accent);
344
+ outline-offset: -1px;
345
+ }
346
+ }
258
347
  .meow_Positioner_Dqll0G {
259
348
  z-index: 50;
260
349
  width: min(24rem, 100vw - 1rem);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meowdown/react",
3
3
  "type": "module",
4
- "version": "0.24.1",
4
+ "version": "0.25.0",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -30,7 +30,7 @@
30
30
  "@prosekit/react": "^0.8.0-beta.11",
31
31
  "clsx": "^2.1.1",
32
32
  "lucide-react": "^1.21.0",
33
- "@meowdown/core": "0.24.1"
33
+ "@meowdown/core": "0.25.0"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "react": "^19.0.0",