@crispy-seed/data-table 0.5.0 → 0.6.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
@@ -256,6 +256,16 @@ interface DataTableColumn<TRow> {
256
256
  * 옵션의 문자열 그 자체입니다). 생략하면 `value`(또는 `row[key]`)를 그대로 씁니다.
257
257
  */
258
258
  editValue?: (row: TRow) => string | number | boolean;
259
+ /**
260
+ * `type: "entity"` 열에서만 쓰입니다 (your-moon/crisp#601 이식). 행에 마우스를
261
+ * 올리거나 키보드 포커스를 받으면 셀 오른쪽 끝에 "미리보기 열기" 아이콘이
262
+ * 나타납니다 -- crisp가 측정한 것과 동일한 20px 고스트 버튼(`radius.sm`,
263
+ * 평상시 muted, hover에서 진해짐). 생략하면 아이콘이 렌더링되지 않습니다
264
+ * (기본값). `type`이 다르면 무시됩니다.
265
+ */
266
+ onOpenPreview?: (row: TRow) => void;
267
+ /** `onOpenPreview` 아이콘의 aria-label입니다. @default "Open preview" */
268
+ openPreviewLabel?: string;
259
269
  }
260
270
  interface DataTableProps<TRow extends {
261
271
  id: string;
@@ -505,5 +515,215 @@ declare namespace DataTableViewsControl {
505
515
  var displayName: string;
506
516
  }
507
517
 
508
- export { DataTable, DataTableViewsControl };
509
- export type { DataTableColumn, DataTableColumnKind, DataTableProps, DataTableView, DataTableViewState, DataTableViewsControlProps, ToolbarFilter, ToolbarFilterOp, ToolbarSort, ToolbarSortDirection };
518
+ type ResizablePanelSide = "left" | "right";
519
+
520
+ type ResizablePanelHandleVariant = "panel" | "column";
521
+ type ResizablePanelProps = Omit<react.ComponentPropsWithoutRef<"div">, "children" | "onResize"> & {
522
+ /** Which edge of its container the panel is anchored to. @default "left" */
523
+ side?: ResizablePanelSide;
524
+ /** Controlled width, in px. */
525
+ width?: number;
526
+ /** Initial width, in px, when uncontrolled. @default 280 */
527
+ defaultSize?: number;
528
+ /** Fires with the next width on every drag move, and once more with the
529
+ * final, CSS-clamped width once a drag ends. */
530
+ onWidthChange?: (width: number) => void;
531
+ /** `min-width` in px. @default 200 */
532
+ min?: number;
533
+ /**
534
+ * `max-width` -- a px number, or a raw CSS expression for callers that
535
+ * need a real clamp, e.g. `max="min(60%, 100% - 350px)"`. Constraints are
536
+ * never re-applied in JS: the handler writes the unclamped drag width, and
537
+ * the browser's own `min-width`/`max-width` resolve the rendered size.
538
+ */
539
+ max?: number | string;
540
+ /**
541
+ * Layout model: "docked" (default) reserves flow width and sits in-line
542
+ * with a hairline border; "floating" takes the panel out of flow
543
+ * (`position: fixed`, an 8px gutter, r10, the measured floating shadow).
544
+ */
545
+ floating?: boolean;
546
+ /** Resize-handle geometry -- "panel" (default) or "column" (table edges). */
547
+ handleVariant?: ResizablePanelHandleVariant;
548
+ /**
549
+ * Renders the drag handle. `false` gives a fixed-width, non-interactive
550
+ * panel (e.g. `RecordPanel`'s own `resizable={false}` default) -- not part
551
+ * of crisp's own API, added here so a consumer built ON this primitive
552
+ * (like `RecordPanel`) can opt out of dragging entirely without crisp's
553
+ * duplicate resize-handle implementation. @default true
554
+ */
555
+ resizable?: boolean;
556
+ /**
557
+ * Persist width as a percentage of the container under this key (a `%`,
558
+ * not px, so the panel keeps its proportion on resize). Only applies when
559
+ * `width` is uncontrolled.
560
+ */
561
+ storageKey?: string;
562
+ className?: string;
563
+ children?: react.ReactNode;
564
+ };
565
+ /**
566
+ * An adjustable-panel primitive: a spacer that reserves layout width plus a
567
+ * panel that overlays it, so the panel can move between docked (in-flow) and
568
+ * floating (`position: fixed`, an overlay) without a reflow glitch. Drag the
569
+ * edge handle to resize; constraints are CSS `min-width`/`max-width`, never
570
+ * re-clamped in JS. Ported from your-moon/crisp's `ResizablePanel`
571
+ * (`components/resizablepanel/`); state/drag behavior lives in
572
+ * `useResizablePanel` (`@seed-design/react-resizable-panel`), this component
573
+ * owns the DOM + recipe classes on top of it.
574
+ */
575
+ declare const ResizablePanel: react.ForwardRefExoticComponent<Omit<Omit<react.DetailedHTMLProps<react.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "children" | "onResize"> & {
576
+ /** Which edge of its container the panel is anchored to. @default "left" */
577
+ side?: ResizablePanelSide;
578
+ /** Controlled width, in px. */
579
+ width?: number;
580
+ /** Initial width, in px, when uncontrolled. @default 280 */
581
+ defaultSize?: number;
582
+ /** Fires with the next width on every drag move, and once more with the
583
+ * final, CSS-clamped width once a drag ends. */
584
+ onWidthChange?: (width: number) => void;
585
+ /** `min-width` in px. @default 200 */
586
+ min?: number;
587
+ /**
588
+ * `max-width` -- a px number, or a raw CSS expression for callers that
589
+ * need a real clamp, e.g. `max="min(60%, 100% - 350px)"`. Constraints are
590
+ * never re-applied in JS: the handler writes the unclamped drag width, and
591
+ * the browser's own `min-width`/`max-width` resolve the rendered size.
592
+ */
593
+ max?: number | string;
594
+ /**
595
+ * Layout model: "docked" (default) reserves flow width and sits in-line
596
+ * with a hairline border; "floating" takes the panel out of flow
597
+ * (`position: fixed`, an 8px gutter, r10, the measured floating shadow).
598
+ */
599
+ floating?: boolean;
600
+ /** Resize-handle geometry -- "panel" (default) or "column" (table edges). */
601
+ handleVariant?: ResizablePanelHandleVariant;
602
+ /**
603
+ * Renders the drag handle. `false` gives a fixed-width, non-interactive
604
+ * panel (e.g. `RecordPanel`'s own `resizable={false}` default) -- not part
605
+ * of crisp's own API, added here so a consumer built ON this primitive
606
+ * (like `RecordPanel`) can opt out of dragging entirely without crisp's
607
+ * duplicate resize-handle implementation. @default true
608
+ */
609
+ resizable?: boolean;
610
+ /**
611
+ * Persist width as a percentage of the container under this key (a `%`,
612
+ * not px, so the panel keeps its proportion on resize). Only applies when
613
+ * `width` is uncontrolled.
614
+ */
615
+ storageKey?: string;
616
+ className?: string;
617
+ children?: react.ReactNode;
618
+ } & react.RefAttributes<HTMLDivElement>>;
619
+
620
+ /** One Highlights card -- label, value and an optional icon, laid out the way
621
+ * Attio's own peek panel lays its own out (your-moon/crisp#448, measured
622
+ * live): a 2-column grid, no card chrome, a muted label row with a
623
+ * trailing icon, a filled-colour value below it. */
624
+ type RecordPanelHighlight = {
625
+ key: string;
626
+ label: string;
627
+ value: react.ReactNode;
628
+ icon?: react.ComponentType<{
629
+ size?: number;
630
+ }>;
631
+ };
632
+ /** One collapsed section below Activity (your-moon/crisp#413) -- Attio's own
633
+ * peek shows Emails/Notes/Tasks this way, each a label + a count, expanding
634
+ * into the consumer's own content when clicked. Omitting `content` renders
635
+ * the row but not as a button, matching the live DOM measured on an empty
636
+ * section: no chevron, no click handler, nothing to expand into yet. */
637
+ type RecordPanelSection = {
638
+ key: string;
639
+ label: string;
640
+ count: number;
641
+ content?: react.ReactNode;
642
+ };
643
+ /** The record this panel previews. Only `name` is read directly here --
644
+ * everything else the panel shows comes from `highlights`/`activity`/
645
+ * `sections`, the consumer's own data. Unlike crisp's own `RecordPanel`
646
+ * (which reads `Row` from `product/recordpage/column`), this port has no
647
+ * such type to depend on -- crispy-seed has no RecordPage -- so this stays
648
+ * a minimal, consumer-extendable shape. */
649
+ type RecordPanelRecord = {
650
+ name?: string;
651
+ [key: string]: unknown;
652
+ };
653
+ type RecordPanelProps = Omit<react.ComponentPropsWithoutRef<"div">, "children" | "title" | "onResize"> & {
654
+ /** Whether the panel is mounted/visible. */
655
+ open: boolean;
656
+ onClose: () => void;
657
+ /** Label for the close control. */
658
+ closeLabel?: string;
659
+ /**
660
+ * A toolbar row above the panel's own identity header (your-moon/crisp#601,
661
+ * measured live on app.attio.com's peek): Close, then Previous/Next on the
662
+ * left, an "Open record" icon on the right. Close always renders
663
+ * (`onClose` is required); Previous/Next/Open record each render only when
664
+ * given a handler.
665
+ */
666
+ onOpenRecord?: () => void;
667
+ openRecordLabel?: string;
668
+ onPrevious?: () => void;
669
+ previousRecordLabel?: string;
670
+ onNext?: () => void;
671
+ nextRecordLabel?: string;
672
+ /** "2 of 37 in All Companies" (your-moon/crisp#413) -- a single
673
+ * pre-formatted string; omit for no counter at all. */
674
+ counterLabel?: react.ReactNode;
675
+ /**
676
+ * Lets a person drag the panel wider or narrower from its own left edge --
677
+ * this port reuses `ResizablePanel`'s own handle (`side="right"`, whose
678
+ * handle sits at the panel's inline-start/left edge, the same physical
679
+ * position crisp's own hand-rolled resize strip measured). Uncontrolled by
680
+ * default; pass `width`/`onWidthChange` together to own it instead.
681
+ * @default false
682
+ */
683
+ resizable?: boolean;
684
+ width?: number;
685
+ defaultWidth?: number;
686
+ onWidthChange?: (width: number) => void;
687
+ minWidth?: number;
688
+ maxWidth?: number;
689
+ /** The panel's heading, and so its accessible name. Defaults to `record.name`. */
690
+ title?: react.ReactNode;
691
+ /** Avatar image URL beside the title. Omit for an initials tile built from
692
+ * `record.name`'s first character. */
693
+ avatar?: string;
694
+ /** The record to show; renders nothing when `open` is false or `record`
695
+ * is null. */
696
+ record: RecordPanelRecord | null;
697
+ /** Heading above the highlight cards (default "Highlights"). Omit the
698
+ * whole section by omitting `highlights`. */
699
+ highlightsLabel?: react.ReactNode;
700
+ highlights?: RecordPanelHighlight[];
701
+ /** Heading above the activity feed (default "Activity"). */
702
+ activityLabel?: react.ReactNode;
703
+ viewAllActivityLabel?: react.ReactNode;
704
+ onViewAllActivity?: () => void;
705
+ activity?: react.ReactNode;
706
+ /** Collapsed sections below Activity (your-moon/crisp#413). Omit for no
707
+ * sections at all. */
708
+ sections?: RecordPanelSection[];
709
+ /** Rendered below the panel's content, e.g. an Edit button. */
710
+ footer?: react.ReactNode;
711
+ className?: string;
712
+ };
713
+ /**
714
+ * Right-side record peek panel -- Attio's own peek shows a Highlights card
715
+ * area and an Activity feed (measured live). Ported from your-moon/crisp's
716
+ * `RecordPanel` (`product/recordpanel/`), built ON `ResizablePanel`
717
+ * (`side="right" floating`) rather than crisp's own duplicate absolute-
718
+ * positioning/slide-in/resize-handle implementation -- the outer shell (the
719
+ * `@starting-style` slide-in, the floating elevation, the drag handle
720
+ * itself) all come from that primitive; this component only renders the
721
+ * CONTENT inside it.
722
+ */
723
+ declare function RecordPanel({ open, record, onClose, className, closeLabel, onOpenRecord, openRecordLabel, onPrevious, previousRecordLabel, onNext, nextRecordLabel, title, avatar, highlightsLabel, highlights, counterLabel, resizable, width, defaultWidth, onWidthChange, minWidth, maxWidth, activityLabel, viewAllActivityLabel, onViewAllActivity, activity, sections, footer, ...rest }: RecordPanelProps): react_jsx_runtime.JSX.Element | null;
724
+ declare namespace RecordPanel {
725
+ var displayName: string;
726
+ }
727
+
728
+ export { DataTable, DataTableViewsControl, RecordPanel, ResizablePanel };
729
+ export type { DataTableColumn, DataTableColumnKind, DataTableProps, DataTableView, DataTableViewState, DataTableViewsControlProps, RecordPanelHighlight, RecordPanelProps, RecordPanelRecord, RecordPanelSection, ResizablePanelHandleVariant, ResizablePanelProps, ResizablePanelSide, ToolbarFilter, ToolbarFilterOp, ToolbarSort, ToolbarSortDirection };