@marimo-team/frontend 0.24.1-dev32 → 0.24.1-dev35

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.
Files changed (24) hide show
  1. package/dist/assets/{JsonOutput-htT793Wj.js → JsonOutput-DJrr9OT1.js} +12 -12
  2. package/dist/assets/{add-connection-dialog-DGYhyXo6.js → add-connection-dialog-ebUK47A-.js} +1 -1
  3. package/dist/assets/{agent-panel--Nt4UmNj.js → agent-panel-syljN-vd.js} +1 -1
  4. package/dist/assets/{cell-editor-DgOfL9Xv.js → cell-editor-Dfh89ttH.js} +1 -1
  5. package/dist/assets/{column-preview-BaRqZ9P8.js → column-preview-wrymhKlT.js} +1 -1
  6. package/dist/assets/{command-palette-Cbie8JV9.js → command-palette-oY9BI5F9.js} +1 -1
  7. package/dist/assets/{edit-page-DKAg2YW9.js → edit-page-Do204YE6.js} +4 -4
  8. package/dist/assets/{file-explorer-panel-DwA9Lprz.js → file-explorer-panel-Bc75pRB9.js} +1 -1
  9. package/dist/assets/{form-Cj9BLARR.js → form-D9rHu7Cq.js} +1 -1
  10. package/dist/assets/index-BBAof751.css +2 -0
  11. package/dist/assets/{index-DemYxG9z.js → index-XtcQuufP.js} +2 -2
  12. package/dist/assets/{layout-YPBtS2D6.js → layout-BGbMrroI.js} +3 -3
  13. package/dist/assets/{panels-DRv39UwA.js → panels-CCNbfGX1.js} +1 -1
  14. package/dist/assets/{reveal-component-Cl6cd65E.js → reveal-component-CkUOqs6t.js} +1 -1
  15. package/dist/assets/{run-page-Phwq7OJt.js → run-page-DZ9O8xra.js} +1 -1
  16. package/dist/assets/{scratchpad-panel-CvihhlAP.js → scratchpad-panel-SKv1cqWC.js} +1 -1
  17. package/dist/assets/{session-panel-BmQ0PDHO.js → session-panel-Dn6J9S-p.js} +1 -1
  18. package/dist/assets/{skeleton-BsZq3Vmq.js → skeleton-CPbmAcKR.js} +1 -1
  19. package/dist/assets/{useNotebookActions-BI53NQV3.js → useNotebookActions-DaBCZvGq.js} +1 -1
  20. package/dist/index.html +5 -5
  21. package/package.json +1 -1
  22. package/src/components/data-table/__tests__/columns.test.tsx +166 -2
  23. package/src/components/data-table/columns.tsx +87 -10
  24. package/dist/assets/index-CxZ6uZaz.css +0 -2
@@ -7,12 +7,14 @@ const PopoverClose = PopoverPrimitive.Close;
7
7
 
8
8
  import type { Column, ColumnDef } from "@tanstack/react-table";
9
9
  import { formatDate, isValid } from "date-fns";
10
+ import { useRef } from "react";
10
11
  import { useLocale, useNumberFormatter } from "react-aria";
11
12
  import { WithLocale } from "@/core/i18n/with-locale";
12
13
  import type { DataType } from "@/core/kernel/messages";
13
14
  import type { CalculateTopKRows } from "@/plugins/impl/DataTablePlugin";
14
15
  import { cn } from "@/utils/cn";
15
16
  import { type DateFormat, exactDateTime, getDateFormat } from "@/utils/dates";
17
+ import { Events } from "@/utils/events";
16
18
  import { Logger } from "@/utils/Logger";
17
19
  import { Maps } from "@/utils/maps";
18
20
  import { maxFractionalDigits } from "@/utils/numbers";
@@ -382,9 +384,10 @@ const PopoutColumn = ({
382
384
  rawStringValue,
383
385
  edges,
384
386
  contentClassName,
385
- buttonText,
387
+ scrollable = false,
386
388
  wrapped,
387
389
  children,
390
+ buttonText,
388
391
  }: {
389
392
  cellStyles?: string;
390
393
  selectCell?: () => void;
@@ -393,10 +396,12 @@ const PopoutColumn = ({
393
396
  // still use `rawStringValue`. Middle is sliced from `rawStringValue`.
394
397
  edges?: { leading: string; trailing: string };
395
398
  contentClassName?: string;
396
- buttonText?: string;
399
+ scrollable?: boolean;
397
400
  wrapped?: boolean;
401
+ buttonText?: string;
398
402
  children: React.ReactNode;
399
403
  }) => {
404
+ const triggerRef = useRef<HTMLButtonElement>(null);
400
405
  const hasEdgeWhitespace =
401
406
  edges !== undefined &&
402
407
  (edges.leading.length > 0 || edges.trailing.length > 0);
@@ -412,6 +417,7 @@ const PopoutColumn = ({
412
417
  <EmotionCacheProvider container={null}>
413
418
  <Popover>
414
419
  <PopoverTrigger
420
+ ref={triggerRef}
415
421
  className={cn(cellStyles, "max-w-fit outline-hidden")}
416
422
  onClick={selectCell}
417
423
  onMouseDown={(e) => {
@@ -432,29 +438,77 @@ const PopoutColumn = ({
432
438
  </span>
433
439
  </PopoverTrigger>
434
440
  <PopoverContent
435
- className={contentClassName}
441
+ className={cn(
442
+ contentClassName,
443
+ scrollable && "flex flex-col overflow-hidden",
444
+ )}
436
445
  align="start"
437
446
  alignOffset={10}
447
+ onInteractOutside={(event) => {
448
+ // Radix sees the shadow host as the target. Resolve the original
449
+ // target so pointer-down does not dismiss before click toggles.
450
+ const target = Events.composedTarget(event.detail.originalEvent);
451
+ if (triggerRef.current?.contains(target)) {
452
+ event.preventDefault();
453
+ }
454
+ }}
438
455
  >
439
- <div className="absolute top-2 right-2">
456
+ <div
457
+ className={cn(
458
+ "flex -mt-3 -mr-2",
459
+ scrollable ? "shrink-0 justify-end" : "float-right",
460
+ )}
461
+ >
440
462
  <CopyClipboardIcon
441
463
  value={rawStringValue}
442
- className="w-2.5 h-2.5"
464
+ className="size-3 hover:text-link"
465
+ buttonClassName="flex size-5 items-center justify-center"
443
466
  tooltip={false}
444
467
  />
445
- <PopoverClose>
446
- <Button variant="link" size="xs">
468
+ <PopoverClose asChild={true}>
469
+ <Button
470
+ variant="link"
471
+ size="xs"
472
+ className={cn("size-5 p-0", !buttonText && "ml-1.5 mr-1")}
473
+ aria-label="Close"
474
+ >
447
475
  {buttonText ?? "Close"}
448
476
  </Button>
449
477
  </PopoverClose>
450
478
  </div>
451
- {children}
479
+ {scrollable ? (
480
+ <div className="min-h-0 overflow-auto">{children}</div>
481
+ ) : (
482
+ children
483
+ )}
452
484
  </PopoverContent>
453
485
  </Popover>
454
486
  </EmotionCacheProvider>
455
487
  );
456
488
  };
457
489
 
490
+ /**
491
+ * Parse a string that holds a JSON object or array document.
492
+ * Returns `undefined` for everything else, including JSON scalars,
493
+ * so ordinary text keeps its plain rendering.
494
+ */
495
+ function parseJsonDocument(text: string): unknown {
496
+ const trimmedText = text.trim();
497
+
498
+ const first = trimmedText[0];
499
+ const last = trimmedText[trimmedText.length - 1];
500
+ const isBracketPair =
501
+ (first === "{" && last === "}") || (first === "[" && last === "]");
502
+ if (!isBracketPair) {
503
+ return undefined;
504
+ }
505
+ try {
506
+ return JSON.parse(trimmedText) as unknown;
507
+ } catch {
508
+ return undefined;
509
+ }
510
+ }
511
+
458
512
  function isPrimitiveOrNullish(value: unknown): boolean {
459
513
  if (value == null) {
460
514
  return true;
@@ -639,6 +693,28 @@ export function renderCellValue<TData, TValue>({
639
693
  splitLeadingTrailingWhitespace(stringValue);
640
694
  const hasEdgeWhitespace = leading.length > 0 || trailing.length > 0;
641
695
 
696
+ // A str cell that holds a JSON document opens the same JSON viewer as
697
+ // native list/struct cells.
698
+ const jsonDocument = parseJsonDocument(middle);
699
+ if (jsonDocument !== undefined) {
700
+ return (
701
+ <PopoutColumn
702
+ cellStyles={cellStyles}
703
+ selectCell={selectCell}
704
+ rawStringValue={stringValue}
705
+ edges={{ leading, trailing }}
706
+ wrapped={isWrapped}
707
+ >
708
+ <JsonOutput
709
+ data={jsonDocument}
710
+ format="tree"
711
+ valueTypes="json"
712
+ className="max-h-64"
713
+ />
714
+ </PopoutColumn>
715
+ );
716
+ }
717
+
642
718
  // Parse only the inner content for URL detection so URLDetector doesn't
643
719
  // split on the whitespace padding.
644
720
  const parts = parseContent(hasEdgeWhitespace ? middle : stringValue);
@@ -662,9 +738,10 @@ export function renderCellValue<TData, TValue>({
662
738
  selectCell={selectCell}
663
739
  rawStringValue={stringValue}
664
740
  edges={{ leading, trailing }}
665
- contentClassName="max-h-64 overflow-auto whitespace-pre-wrap wrap-break-word text-sm w-96"
666
- buttonText="X"
741
+ contentClassName="max-h-64 whitespace-pre-wrap wrap-break-word text-sm w-96"
742
+ scrollable={true}
667
743
  wrapped={isWrapped}
744
+ buttonText="X"
668
745
  >
669
746
  <MarkdownUrlDetector
670
747
  content={stringValue}