@particle-academy/react-fancy 4.14.1 → 4.15.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 CHANGED
@@ -163,6 +163,7 @@ npx vite build # Build demo app (verifies imports work)
163
163
  | Composer | Chat-style message input composing textarea + actions | [docs](docs/Composer.md) |
164
164
  | Chart | SVG-based Bar, Line, Area, Pie, Donut, and Sparkline charts | [docs](docs/Chart.md) |
165
165
  | Editor | Toolbar chrome wrapper for contentEditable, with a Source toggle to edit raw HTML/Markdown | [docs](docs/Editor.md) |
166
+ | CodeView | Lightweight syntax-highlighted source view (HTML highlighted; fills height) | [docs](docs/CodeView.md) |
166
167
  | Kanban | Drag-and-drop board with columns and cards | [docs](docs/Kanban.md) |
167
168
  | Canvas | Interactive node canvas with pan, zoom, and connections | [docs](docs/Canvas.md) |
168
169
  | Diagram | Entity-relationship diagram with draggable nodes and relation lines | [docs](docs/Diagram.md) |
package/dist/index.cjs CHANGED
@@ -7,6 +7,7 @@ var jsxRuntime = require('react/jsx-runtime');
7
7
  var reactDom = require('react-dom');
8
8
  var lucideReact = require('lucide-react');
9
9
  var marked = require('marked');
10
+ var fancyFileCommons = require('@particle-academy/fancy-file-commons');
10
11
 
11
12
  // src/components/Button/Button.tsx
12
13
  function cn(...inputs) {
@@ -11388,7 +11389,7 @@ function EditorToolbar({
11388
11389
  {
11389
11390
  "data-react-fancy-editor-toolbar": "",
11390
11391
  className: cn(
11391
- "flex items-center gap-0.5 border-b border-zinc-200 px-2 py-1.5 dark:border-zinc-700",
11392
+ "flex shrink-0 items-center gap-0.5 border-b border-zinc-200 px-2 py-1.5 dark:border-zinc-700",
11392
11393
  className
11393
11394
  ),
11394
11395
  children: children ?? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -11430,6 +11431,98 @@ function EditorToolbarSeparator() {
11430
11431
  );
11431
11432
  }
11432
11433
  EditorToolbarSeparator.displayName = "EditorToolbarSeparator";
11434
+ function subscribeDark(callback) {
11435
+ const mq = window.matchMedia("(prefers-color-scheme: dark)");
11436
+ mq.addEventListener("change", callback);
11437
+ const observer = new MutationObserver(callback);
11438
+ observer.observe(document.documentElement, {
11439
+ attributes: true,
11440
+ attributeFilter: ["class"]
11441
+ });
11442
+ return () => {
11443
+ mq.removeEventListener("change", callback);
11444
+ observer.disconnect();
11445
+ };
11446
+ }
11447
+ function darkSnapshot() {
11448
+ return document.documentElement.classList.contains("dark") || window.matchMedia("(prefers-color-scheme: dark)").matches;
11449
+ }
11450
+ function useIsDark() {
11451
+ return react.useSyncExternalStore(subscribeDark, darkSnapshot, () => false);
11452
+ }
11453
+ var TEXT_METRICS = "m-0 p-3 font-mono text-xs leading-relaxed";
11454
+ function CodeView({
11455
+ value,
11456
+ onChange,
11457
+ language = "plaintext",
11458
+ readOnly = false,
11459
+ placeholder,
11460
+ minHeight = 120,
11461
+ maxHeight,
11462
+ className
11463
+ }) {
11464
+ const textareaRef = react.useRef(null);
11465
+ const isDark = useIsDark();
11466
+ const colors = isDark ? fancyFileCommons.DARK_COLORS : fancyFileCommons.LIGHT_COLORS;
11467
+ const highlighted = react.useMemo(() => {
11468
+ const tokens = language === "html" ? fancyFileCommons.tokenizeHtml(value) : [];
11469
+ return fancyFileCommons.highlightCode(value, tokens, colors);
11470
+ }, [value, language, colors]);
11471
+ react.useEffect(() => {
11472
+ const el = textareaRef.current;
11473
+ if (!el) return;
11474
+ el.style.height = "auto";
11475
+ el.style.height = `${el.scrollHeight}px`;
11476
+ }, [value]);
11477
+ const editable = !readOnly && !!onChange;
11478
+ return /* @__PURE__ */ jsxRuntime.jsx(
11479
+ "div",
11480
+ {
11481
+ "data-react-fancy-code-view": "",
11482
+ className: cn("relative overflow-auto", className),
11483
+ style: { backgroundColor: colors.background, color: colors.foreground, minHeight, maxHeight },
11484
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative min-h-full", children: [
11485
+ /* @__PURE__ */ jsxRuntime.jsx(
11486
+ "pre",
11487
+ {
11488
+ "aria-hidden": "true",
11489
+ className: cn("pointer-events-none absolute inset-0 overflow-hidden border-none", TEXT_METRICS),
11490
+ style: { whiteSpace: "pre-wrap", overflowWrap: "break-word" },
11491
+ children: /* @__PURE__ */ jsxRuntime.jsx("code", { dangerouslySetInnerHTML: { __html: highlighted + "\n" } })
11492
+ }
11493
+ ),
11494
+ placeholder && value.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("pointer-events-none absolute left-0 top-0 opacity-40", TEXT_METRICS), children: placeholder }),
11495
+ /* @__PURE__ */ jsxRuntime.jsx(
11496
+ "textarea",
11497
+ {
11498
+ ref: textareaRef,
11499
+ "data-react-fancy-code-view-input": "",
11500
+ value,
11501
+ onChange: editable ? (e) => onChange(e.target.value) : void 0,
11502
+ readOnly: !editable,
11503
+ spellCheck: false,
11504
+ autoComplete: "off",
11505
+ autoCorrect: "off",
11506
+ autoCapitalize: "off",
11507
+ "aria-label": placeholder,
11508
+ className: cn(
11509
+ "relative block w-full resize-none border-none bg-transparent text-transparent outline-none",
11510
+ TEXT_METRICS
11511
+ ),
11512
+ style: {
11513
+ caretColor: colors.cursorColor,
11514
+ overflow: "hidden",
11515
+ whiteSpace: "pre-wrap",
11516
+ overflowWrap: "break-word",
11517
+ minHeight
11518
+ }
11519
+ }
11520
+ )
11521
+ ] })
11522
+ }
11523
+ );
11524
+ }
11525
+ CodeView.displayName = "CodeView";
11433
11526
 
11434
11527
  // src/components/Editor/editor.utils.ts
11435
11528
  var proseClasses = [
@@ -11652,24 +11745,14 @@ function EditorContent({ className, maxHeight, sourceClassName }) {
11652
11745
  );
11653
11746
  if (showSource) {
11654
11747
  return /* @__PURE__ */ jsxRuntime.jsx(
11655
- "textarea",
11748
+ CodeView,
11656
11749
  {
11657
- "data-react-fancy-editor-source": "",
11658
11750
  value: _sourceValue,
11659
- onChange: (e) => _onSourceInput(e.target.value),
11660
- spellCheck: false,
11751
+ onChange: _onSourceInput,
11752
+ language: outputFormat === "html" ? "html" : "plaintext",
11661
11753
  placeholder,
11662
- "aria-label": `${outputFormat === "markdown" ? "Markdown" : "HTML"} source`,
11663
- style: {
11664
- maxHeight: maxHeight ? `${maxHeight}px` : void 0
11665
- },
11666
- className: cn(
11667
- "block min-h-[120px] w-full resize-y px-4 py-3 font-mono text-xs leading-relaxed outline-none",
11668
- "bg-zinc-50 text-zinc-800 focus:outline-none dark:bg-zinc-900 dark:text-zinc-200",
11669
- "placeholder:text-zinc-400",
11670
- maxHeight && "overflow-y-auto",
11671
- sourceClassName
11672
- )
11754
+ maxHeight,
11755
+ className: cn("min-h-0 flex-auto", sourceClassName)
11673
11756
  }
11674
11757
  );
11675
11758
  }
@@ -11687,9 +11770,8 @@ function EditorContent({ className, maxHeight, sourceClassName }) {
11687
11770
  maxHeight: maxHeight ? `${maxHeight}px` : void 0
11688
11771
  },
11689
11772
  className: cn(
11690
- "min-h-[120px] px-4 py-3 text-sm outline-none",
11773
+ "min-h-[120px] flex-auto overflow-y-auto px-4 py-3 text-sm outline-none",
11691
11774
  "focus:outline-none",
11692
- maxHeight && "overflow-y-auto",
11693
11775
  proseClasses,
11694
11776
  extClasses,
11695
11777
  "empty:before:content-[attr(data-placeholder)] empty:before:text-zinc-400 empty:before:pointer-events-none",
@@ -11989,7 +12071,7 @@ function EditorRoot({
11989
12071
  "data-react-fancy-editor": "",
11990
12072
  "data-mode": "edit",
11991
12073
  className: cn(
11992
- "overflow-hidden rounded-xl border border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900",
12074
+ "flex flex-col overflow-hidden rounded-xl border border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900",
11993
12075
  className
11994
12076
  ),
11995
12077
  children
@@ -15995,6 +16077,7 @@ exports.Chart = Chart;
15995
16077
  exports.ChatDrawer = ChatDrawer;
15996
16078
  exports.Checkbox = Checkbox;
15997
16079
  exports.CheckboxGroup = CheckboxGroup;
16080
+ exports.CodeView = CodeView;
15998
16081
  exports.ColorPicker = ColorPicker;
15999
16082
  exports.Command = Command;
16000
16083
  exports.Composer = Composer;