@petrarca/sonnet-ui 0.4.0 → 0.4.2

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.js CHANGED
@@ -3007,14 +3007,231 @@ function PaginationFooter({
3007
3007
  ] });
3008
3008
  }
3009
3009
 
3010
+ // src/PropertyList/PropertyList.tsx
3011
+ import React26 from "react";
3012
+ import { copyTextToClipboard } from "@petrarca/sonnet-core";
3013
+
3014
+ // src/PropertyList/PropertyValue.tsx
3015
+ import { useState as useState3 } from "react";
3016
+ import { JSONTree } from "react-json-tree";
3017
+ import { jsx as jsx29, jsxs as jsxs9 } from "react/jsx-runtime";
3018
+ var DEFAULT_CLAMP_CHARS = 180;
3019
+ var tokenTheme = {
3020
+ scheme: "sonnet",
3021
+ base00: "transparent",
3022
+ base01: "hsl(var(--muted))",
3023
+ base02: "hsl(var(--border))",
3024
+ base03: "hsl(var(--muted-foreground))",
3025
+ base04: "hsl(var(--muted-foreground))",
3026
+ base05: "hsl(var(--foreground))",
3027
+ base06: "hsl(var(--foreground))",
3028
+ base07: "hsl(var(--foreground))",
3029
+ base08: "hsl(var(--destructive))",
3030
+ base09: "hsl(var(--primary))",
3031
+ base0A: "hsl(var(--primary))",
3032
+ base0B: "hsl(var(--primary))",
3033
+ base0C: "hsl(var(--primary))",
3034
+ base0D: "hsl(var(--primary))",
3035
+ base0E: "hsl(var(--primary))",
3036
+ base0F: "hsl(var(--muted-foreground))"
3037
+ };
3038
+ function isObjectLike(v) {
3039
+ return typeof v === "object" && v !== null;
3040
+ }
3041
+ function JsonValue({ value }) {
3042
+ const [open, setOpen] = useState3(false);
3043
+ const summary = Array.isArray(value) ? `[${value.length} item${value.length === 1 ? "" : "s"}]` : `{${Object.keys(value).length} key${Object.keys(value).length === 1 ? "" : "s"}}`;
3044
+ if (!open) {
3045
+ return /* @__PURE__ */ jsxs9(
3046
+ "button",
3047
+ {
3048
+ type: "button",
3049
+ onClick: (e) => {
3050
+ e.stopPropagation();
3051
+ setOpen(true);
3052
+ },
3053
+ className: "text-sm font-mono text-muted-foreground hover:text-foreground",
3054
+ children: [
3055
+ summary,
3056
+ " ",
3057
+ /* @__PURE__ */ jsx29("span", { className: "text-xs", children: "\u2014 show" })
3058
+ ]
3059
+ }
3060
+ );
3061
+ }
3062
+ return /* @__PURE__ */ jsxs9("div", { className: "text-xs font-mono", children: [
3063
+ /* @__PURE__ */ jsx29(
3064
+ "button",
3065
+ {
3066
+ type: "button",
3067
+ onClick: (e) => {
3068
+ e.stopPropagation();
3069
+ setOpen(false);
3070
+ },
3071
+ className: "mb-1 text-xs text-muted-foreground hover:text-foreground",
3072
+ children: "hide"
3073
+ }
3074
+ ),
3075
+ /* @__PURE__ */ jsx29("div", { className: "max-h-64 overflow-auto rounded border border-border bg-muted/30 px-2 py-1", children: /* @__PURE__ */ jsx29(
3076
+ JSONTree,
3077
+ {
3078
+ data: value,
3079
+ theme: tokenTheme,
3080
+ invertTheme: false,
3081
+ shouldExpandNodeInitially: () => true,
3082
+ hideRoot: true
3083
+ }
3084
+ ) })
3085
+ ] });
3086
+ }
3087
+ function LongTextValue({ text }) {
3088
+ const [open, setOpen] = useState3(false);
3089
+ if (!open) {
3090
+ return /* @__PURE__ */ jsxs9("span", { className: "break-words", children: [
3091
+ /* @__PURE__ */ jsx29("span", { className: "line-clamp-3 align-bottom", children: text }),
3092
+ /* @__PURE__ */ jsx29(
3093
+ "button",
3094
+ {
3095
+ type: "button",
3096
+ onClick: (e) => {
3097
+ e.stopPropagation();
3098
+ setOpen(true);
3099
+ },
3100
+ className: "text-xs text-muted-foreground hover:text-foreground",
3101
+ children: "Show more"
3102
+ }
3103
+ )
3104
+ ] });
3105
+ }
3106
+ return /* @__PURE__ */ jsxs9("span", { className: "break-words", children: [
3107
+ /* @__PURE__ */ jsx29("span", { className: "block max-h-64 overflow-auto whitespace-pre-wrap rounded border border-border bg-muted/30 px-2 py-1", children: text }),
3108
+ /* @__PURE__ */ jsx29(
3109
+ "button",
3110
+ {
3111
+ type: "button",
3112
+ onClick: (e) => {
3113
+ e.stopPropagation();
3114
+ setOpen(false);
3115
+ },
3116
+ className: "text-xs text-muted-foreground hover:text-foreground",
3117
+ children: "Show less"
3118
+ }
3119
+ )
3120
+ ] });
3121
+ }
3122
+ function renderFromSchema(value, schema, className) {
3123
+ const cellName = schema["x-ui-cell"] ?? inferCellRenderer(schema.type, schema.format);
3124
+ if (cellName === "json") {
3125
+ const parsed = typeof value === "string" ? safeParse(value) : value;
3126
+ return isObjectLike(parsed) ? /* @__PURE__ */ jsx29(JsonValue, { value: parsed }) : null;
3127
+ }
3128
+ if (cellName && cellName !== "text") {
3129
+ const Renderer = CELL_RENDERERS[cellName];
3130
+ if (Renderer) {
3131
+ return /* @__PURE__ */ jsx29("span", { className, children: /* @__PURE__ */ jsx29(
3132
+ Renderer,
3133
+ {
3134
+ value,
3135
+ row: {},
3136
+ options: schema["x-ui-cell-options"] ?? {}
3137
+ }
3138
+ ) });
3139
+ }
3140
+ }
3141
+ return null;
3142
+ }
3143
+ function renderObjectLike(value, className) {
3144
+ if (Array.isArray(value) && value.every((v) => !isObjectLike(v))) {
3145
+ return /* @__PURE__ */ jsx29("span", { className: `break-words ${className ?? ""}`, children: value.map(String).join(", ") });
3146
+ }
3147
+ return /* @__PURE__ */ jsx29(JsonValue, { value });
3148
+ }
3149
+ function renderString(value, className, clampChars) {
3150
+ if (typeof value === "boolean") {
3151
+ return /* @__PURE__ */ jsx29("span", { className, children: value ? "true" : "false" });
3152
+ }
3153
+ const str = String(value);
3154
+ if (str.length > clampChars || str.includes("\n")) {
3155
+ return /* @__PURE__ */ jsx29("span", { className, children: /* @__PURE__ */ jsx29(LongTextValue, { text: str }) });
3156
+ }
3157
+ return /* @__PURE__ */ jsx29("span", { className: `break-words ${className ?? ""}`, children: str });
3158
+ }
3159
+ function renderFromValue(value, className, clampChars) {
3160
+ if (value == null) {
3161
+ return /* @__PURE__ */ jsx29("span", { className: `text-muted-foreground ${className ?? ""}`, children: "\u2014" });
3162
+ }
3163
+ if (isObjectLike(value)) return renderObjectLike(value, className);
3164
+ return renderString(value, className, clampChars);
3165
+ }
3166
+ function PropertyValue({
3167
+ value,
3168
+ schema,
3169
+ className,
3170
+ clampChars = DEFAULT_CLAMP_CHARS
3171
+ }) {
3172
+ const fromSchema = schema ? renderFromSchema(value, schema, className) : null;
3173
+ return fromSchema ?? renderFromValue(value, className, clampChars);
3174
+ }
3175
+ function safeParse(s) {
3176
+ try {
3177
+ return JSON.parse(s);
3178
+ } catch {
3179
+ return void 0;
3180
+ }
3181
+ }
3182
+
3183
+ // src/PropertyList/PropertyList.tsx
3184
+ import { jsx as jsx30, jsxs as jsxs10 } from "react/jsx-runtime";
3185
+ function PropertyList({
3186
+ properties,
3187
+ propertySchemas,
3188
+ layout = "inline",
3189
+ showHeader = false,
3190
+ copyable = true,
3191
+ emptyLabel = "No properties",
3192
+ className
3193
+ }) {
3194
+ const entries = Object.entries(properties ?? {});
3195
+ if (entries.length === 0) {
3196
+ return /* @__PURE__ */ jsx30("p", { className: "text-sm text-muted-foreground italic", children: emptyLabel });
3197
+ }
3198
+ const header = showHeader && /* @__PURE__ */ jsx30("p", { className: "text-[11px] text-muted-foreground mb-1.5", children: "Properties" });
3199
+ const dtClass = `text-[11px] text-muted-foreground ${copyable ? "cursor-pointer hover:text-foreground" : ""}`;
3200
+ const dtProps = (value) => copyable ? {
3201
+ onClick: () => copyTextToClipboard(stringForCopy(value)),
3202
+ title: "Click to copy value"
3203
+ } : {};
3204
+ if (layout === "stacked") {
3205
+ return /* @__PURE__ */ jsxs10("div", { className, children: [
3206
+ header,
3207
+ /* @__PURE__ */ jsx30("dl", { className: "space-y-1", children: entries.map(([key, value]) => /* @__PURE__ */ jsxs10("div", { children: [
3208
+ /* @__PURE__ */ jsx30("dt", { className: dtClass, ...dtProps(value), children: key }),
3209
+ /* @__PURE__ */ jsx30("dd", { className: "text-sm text-foreground font-medium break-words", children: /* @__PURE__ */ jsx30(PropertyValue, { value, schema: propertySchemas?.[key] }) })
3210
+ ] }, key)) })
3211
+ ] });
3212
+ }
3213
+ return /* @__PURE__ */ jsxs10("div", { className, children: [
3214
+ header,
3215
+ /* @__PURE__ */ jsx30("dl", { className: "grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 items-baseline", children: entries.map(([key, value]) => /* @__PURE__ */ jsxs10(React26.Fragment, { children: [
3216
+ /* @__PURE__ */ jsx30("dt", { className: `${dtClass} whitespace-nowrap`, ...dtProps(value), children: key }),
3217
+ /* @__PURE__ */ jsx30("dd", { className: "text-sm text-foreground min-w-0 break-words", children: /* @__PURE__ */ jsx30(PropertyValue, { value, schema: propertySchemas?.[key] }) })
3218
+ ] }, key)) })
3219
+ ] });
3220
+ }
3221
+ function stringForCopy(value) {
3222
+ if (value == null) return "";
3223
+ if (typeof value === "object") return JSON.stringify(value);
3224
+ return String(value);
3225
+ }
3226
+
3010
3227
  // src/EntitySelect/EntitySelect.tsx
3011
- import * as React25 from "react";
3228
+ import * as React27 from "react";
3012
3229
  import { Check as Check4, ChevronsUpDown, Loader2 } from "lucide-react";
3013
3230
  import { cn as cn27 } from "@petrarca/sonnet-core";
3014
3231
  import {
3015
3232
  useEntityOptions
3016
3233
  } from "@petrarca/sonnet-core/hooks";
3017
- import { Fragment as Fragment2, jsx as jsx29, jsxs as jsxs9 } from "react/jsx-runtime";
3234
+ import { Fragment as Fragment2, jsx as jsx31, jsxs as jsxs11 } from "react/jsx-runtime";
3018
3235
  function emptyStateMessage({
3019
3236
  mode,
3020
3237
  search,
@@ -3032,8 +3249,8 @@ function emptyStateMessage({
3032
3249
  return emptyMessage;
3033
3250
  }
3034
3251
  function useHasSearched(submit) {
3035
- const [hasSearched, setHasSearched] = React25.useState(false);
3036
- const wrappedSubmit = React25.useCallback(() => {
3252
+ const [hasSearched, setHasSearched] = React27.useState(false);
3253
+ const wrappedSubmit = React27.useCallback(() => {
3037
3254
  setHasSearched(true);
3038
3255
  submit();
3039
3256
  }, [submit]);
@@ -3056,19 +3273,19 @@ function EntitySelectLabel({
3056
3273
  description
3057
3274
  }) {
3058
3275
  const hasLabel = label !== void 0 && label !== false;
3059
- return /* @__PURE__ */ jsxs9(Fragment2, { children: [
3060
- hasLabel && /* @__PURE__ */ jsxs9(
3276
+ return /* @__PURE__ */ jsxs11(Fragment2, { children: [
3277
+ hasLabel && /* @__PURE__ */ jsxs11(
3061
3278
  "label",
3062
3279
  {
3063
3280
  htmlFor: id,
3064
3281
  className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
3065
3282
  children: [
3066
3283
  label,
3067
- required && /* @__PURE__ */ jsx29("span", { className: "ml-1 text-destructive", children: "*" })
3284
+ required && /* @__PURE__ */ jsx31("span", { className: "ml-1 text-destructive", children: "*" })
3068
3285
  ]
3069
3286
  }
3070
3287
  ),
3071
- description && /* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: description })
3288
+ description && /* @__PURE__ */ jsx31("p", { className: "text-sm text-muted-foreground", children: description })
3072
3289
  ] });
3073
3290
  }
3074
3291
  function EntitySelectDropdown({
@@ -3085,8 +3302,8 @@ function EntitySelectDropdown({
3085
3302
  value,
3086
3303
  handleSelect
3087
3304
  }) {
3088
- return /* @__PURE__ */ jsxs9(Command, { shouldFilter: false, children: [
3089
- /* @__PURE__ */ jsx29(
3305
+ return /* @__PURE__ */ jsxs11(Command, { shouldFilter: false, children: [
3306
+ /* @__PURE__ */ jsx31(
3090
3307
  CommandInput,
3091
3308
  {
3092
3309
  placeholder: searchPlaceholder,
@@ -3100,8 +3317,8 @@ function EntitySelectDropdown({
3100
3317
  } : void 0
3101
3318
  }
3102
3319
  ),
3103
- /* @__PURE__ */ jsxs9(CommandList, { children: [
3104
- /* @__PURE__ */ jsx29(CommandEmpty, { children: emptyStateMessage({
3320
+ /* @__PURE__ */ jsxs11(CommandList, { children: [
3321
+ /* @__PURE__ */ jsx31(CommandEmpty, { children: emptyStateMessage({
3105
3322
  mode,
3106
3323
  search,
3107
3324
  minChars,
@@ -3109,13 +3326,13 @@ function EntitySelectDropdown({
3109
3326
  hasSearched,
3110
3327
  emptyMessage
3111
3328
  }) }),
3112
- /* @__PURE__ */ jsx29(CommandGroup, { children: options.map((option) => /* @__PURE__ */ jsxs9(
3329
+ /* @__PURE__ */ jsx31(CommandGroup, { children: options.map((option) => /* @__PURE__ */ jsxs11(
3113
3330
  CommandItem,
3114
3331
  {
3115
3332
  value: option.value,
3116
3333
  onSelect: handleSelect,
3117
3334
  children: [
3118
- /* @__PURE__ */ jsx29(
3335
+ /* @__PURE__ */ jsx31(
3119
3336
  Check4,
3120
3337
  {
3121
3338
  className: cn27(
@@ -3155,8 +3372,8 @@ function EntitySelect(props) {
3155
3372
  emptyMessage,
3156
3373
  disabled
3157
3374
  } = resolveEntitySelectDefaults(props);
3158
- const [open, setOpen] = React25.useState(false);
3159
- const [selectedLabel, setSelectedLabel] = React25.useState(null);
3375
+ const [open, setOpen] = React27.useState(false);
3376
+ const [selectedLabel, setSelectedLabel] = React27.useState(null);
3160
3377
  const {
3161
3378
  options,
3162
3379
  isLoading,
@@ -3165,7 +3382,7 @@ function EntitySelect(props) {
3165
3382
  submit: rawSubmit
3166
3383
  } = useEntityOptions({ fetcher, queryKey, mode, minChars });
3167
3384
  const [hasSearched, submit] = useHasSearched(rawSubmit);
3168
- React25.useEffect(() => {
3385
+ React27.useEffect(() => {
3169
3386
  if (!value) {
3170
3387
  setSelectedLabel(null);
3171
3388
  return;
@@ -3175,7 +3392,7 @@ function EntitySelect(props) {
3175
3392
  setSelectedLabel(found.label);
3176
3393
  }
3177
3394
  }, [value, options]);
3178
- const handleSelect = React25.useCallback(
3395
+ const handleSelect = React27.useCallback(
3179
3396
  (selectedValue) => {
3180
3397
  const opt = options.find((o) => o.value === selectedValue);
3181
3398
  if (opt) setSelectedLabel(opt.label);
@@ -3188,7 +3405,7 @@ function EntitySelect(props) {
3188
3405
  },
3189
3406
  [options, value, onChange, onChangeOption, setSearch]
3190
3407
  );
3191
- const handleOpenChange = React25.useCallback(
3408
+ const handleOpenChange = React27.useCallback(
3192
3409
  (newOpen) => {
3193
3410
  setOpen(newOpen);
3194
3411
  if (!newOpen) {
@@ -3198,8 +3415,8 @@ function EntitySelect(props) {
3198
3415
  },
3199
3416
  [onBlur, setSearch]
3200
3417
  );
3201
- return /* @__PURE__ */ jsxs9("div", { className: cn27("space-y-2", className), children: [
3202
- /* @__PURE__ */ jsx29(
3418
+ return /* @__PURE__ */ jsxs11("div", { className: cn27("space-y-2", className), children: [
3419
+ /* @__PURE__ */ jsx31(
3203
3420
  EntitySelectLabel,
3204
3421
  {
3205
3422
  id,
@@ -3208,8 +3425,8 @@ function EntitySelect(props) {
3208
3425
  description
3209
3426
  }
3210
3427
  ),
3211
- /* @__PURE__ */ jsxs9(Popover, { open, onOpenChange: handleOpenChange, children: [
3212
- /* @__PURE__ */ jsx29(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs9(
3428
+ /* @__PURE__ */ jsxs11(Popover, { open, onOpenChange: handleOpenChange, children: [
3429
+ /* @__PURE__ */ jsx31(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(
3213
3430
  Button,
3214
3431
  {
3215
3432
  id,
@@ -3223,20 +3440,20 @@ function EntitySelect(props) {
3223
3440
  ),
3224
3441
  disabled,
3225
3442
  children: [
3226
- /* @__PURE__ */ jsx29("span", { className: "truncate", children: selectedLabel ?? placeholder }),
3227
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1", children: [
3228
- isLoading && /* @__PURE__ */ jsx29(Loader2, { className: "h-4 w-4 animate-spin opacity-50" }),
3229
- /* @__PURE__ */ jsx29(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
3443
+ /* @__PURE__ */ jsx31("span", { className: "truncate", children: selectedLabel ?? placeholder }),
3444
+ /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1", children: [
3445
+ isLoading && /* @__PURE__ */ jsx31(Loader2, { className: "h-4 w-4 animate-spin opacity-50" }),
3446
+ /* @__PURE__ */ jsx31(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
3230
3447
  ] })
3231
3448
  ]
3232
3449
  }
3233
3450
  ) }),
3234
- /* @__PURE__ */ jsx29(
3451
+ /* @__PURE__ */ jsx31(
3235
3452
  PopoverContent,
3236
3453
  {
3237
3454
  className: "w-[--radix-popover-trigger-width] p-0",
3238
3455
  align: "start",
3239
- children: /* @__PURE__ */ jsx29(
3456
+ children: /* @__PURE__ */ jsx31(
3240
3457
  EntitySelectDropdown,
3241
3458
  {
3242
3459
  searchPlaceholder,
@@ -3256,7 +3473,7 @@ function EntitySelect(props) {
3256
3473
  }
3257
3474
  )
3258
3475
  ] }),
3259
- error && /* @__PURE__ */ jsx29("p", { className: "text-sm font-medium text-destructive", children: error })
3476
+ error && /* @__PURE__ */ jsx31("p", { className: "text-sm font-medium text-destructive", children: error })
3260
3477
  ] });
3261
3478
  }
3262
3479
 
@@ -3279,11 +3496,11 @@ import {
3279
3496
  useImperativeHandle,
3280
3497
  useMemo as useMemo3,
3281
3498
  useRef as useRef5,
3282
- useState as useState4
3499
+ useState as useState5
3283
3500
  } from "react";
3284
3501
  import { ChevronRight as ChevronRight3 } from "lucide-react";
3285
3502
  import { cn as cn28 } from "@petrarca/sonnet-core";
3286
- import { jsx as jsx30, jsxs as jsxs10 } from "react/jsx-runtime";
3503
+ import { jsx as jsx32, jsxs as jsxs12 } from "react/jsx-runtime";
3287
3504
  function flatten(nodes, expandedIds, depth = 0, parentId = null, result = []) {
3288
3505
  for (const node of nodes) {
3289
3506
  result.push({ node, depth, parentId });
@@ -3300,12 +3517,12 @@ function ToggleIcon({
3300
3517
  isExpanded
3301
3518
  }) {
3302
3519
  if (!hasChildren) {
3303
- return /* @__PURE__ */ jsx30("span", { className: "block w-1.5 h-1.5 rounded-full bg-border mx-auto" });
3520
+ return /* @__PURE__ */ jsx32("span", { className: "block w-1.5 h-1.5 rounded-full bg-border mx-auto" });
3304
3521
  }
3305
3522
  if (isLoading) {
3306
- return /* @__PURE__ */ jsx30("span", { className: "block w-3 h-3 rounded-full border-2 border-muted-foreground/40 border-t-foreground animate-spin" });
3523
+ return /* @__PURE__ */ jsx32("span", { className: "block w-3 h-3 rounded-full border-2 border-muted-foreground/40 border-t-foreground animate-spin" });
3307
3524
  }
3308
- return /* @__PURE__ */ jsx30(
3525
+ return /* @__PURE__ */ jsx32(
3309
3526
  ChevronRight3,
3310
3527
  {
3311
3528
  className: cn28(
@@ -3354,7 +3571,7 @@ function NodeRow({
3354
3571
  },
3355
3572
  [node.id, onSelectionChange]
3356
3573
  );
3357
- return /* @__PURE__ */ jsxs10(
3574
+ return /* @__PURE__ */ jsxs12(
3358
3575
  "li",
3359
3576
  {
3360
3577
  id: `${treeId}-node-${node.id}`,
@@ -3373,13 +3590,13 @@ function NodeRow({
3373
3590
  style: { paddingLeft: depth * indentPx + 8 },
3374
3591
  onClick: handleClick,
3375
3592
  children: [
3376
- /* @__PURE__ */ jsx30(
3593
+ /* @__PURE__ */ jsx32(
3377
3594
  "span",
3378
3595
  {
3379
3596
  className: "shrink-0 flex items-center justify-center w-4 h-4",
3380
3597
  onClick: handleToggle,
3381
3598
  "aria-hidden": true,
3382
- children: /* @__PURE__ */ jsx30(
3599
+ children: /* @__PURE__ */ jsx32(
3383
3600
  ToggleIcon,
3384
3601
  {
3385
3602
  hasChildren: node.hasChildren,
@@ -3389,7 +3606,7 @@ function NodeRow({
3389
3606
  )
3390
3607
  }
3391
3608
  ),
3392
- onSelectionChange && isSelectable && /* @__PURE__ */ jsx30(
3609
+ onSelectionChange && isSelectable && /* @__PURE__ */ jsx32(
3393
3610
  "input",
3394
3611
  {
3395
3612
  type: "checkbox",
@@ -3401,8 +3618,8 @@ function NodeRow({
3401
3618
  tabIndex: -1
3402
3619
  }
3403
3620
  ),
3404
- /* @__PURE__ */ jsx30("span", { className: "flex-1 min-w-0", children: renderNode(node, depth) }),
3405
- node.isError && /* @__PURE__ */ jsx30("span", { className: "shrink-0 text-xs text-destructive", "aria-live": "polite", children: "Failed to load" })
3621
+ /* @__PURE__ */ jsx32("span", { className: "flex-1 min-w-0", children: renderNode(node, depth) }),
3622
+ node.isError && /* @__PURE__ */ jsx32("span", { className: "shrink-0 text-xs text-destructive", "aria-live": "polite", children: "Failed to load" })
3406
3623
  ]
3407
3624
  }
3408
3625
  );
@@ -3422,9 +3639,9 @@ function TreeViewInner({
3422
3639
  className
3423
3640
  }, ref) {
3424
3641
  const treeId = useId2();
3425
- const [focusedId, setFocusedId] = useState4(null);
3642
+ const [focusedId, setFocusedId] = useState5(null);
3426
3643
  const listRef = useRef5(null);
3427
- const [constrainedParent, setConstrainedParent] = useState4(UNCONSTRAINED);
3644
+ const [constrainedParent, setConstrainedParent] = useState5(UNCONSTRAINED);
3428
3645
  const selectionSize = selectedIds?.size ?? 0;
3429
3646
  useEffect5(() => {
3430
3647
  if (selectionSize === 0) setConstrainedParent(UNCONSTRAINED);
@@ -3578,7 +3795,7 @@ function TreeViewInner({
3578
3795
  ]
3579
3796
  );
3580
3797
  if (nodes.length === 0) {
3581
- return /* @__PURE__ */ jsx30(
3798
+ return /* @__PURE__ */ jsx32(
3582
3799
  "div",
3583
3800
  {
3584
3801
  className: cn28(
@@ -3589,7 +3806,7 @@ function TreeViewInner({
3589
3806
  }
3590
3807
  );
3591
3808
  }
3592
- return /* @__PURE__ */ jsx30(
3809
+ return /* @__PURE__ */ jsx32(
3593
3810
  "ul",
3594
3811
  {
3595
3812
  ref: listRef,
@@ -3597,7 +3814,7 @@ function TreeViewInner({
3597
3814
  "aria-label": "Tree",
3598
3815
  className: cn28("outline-none", className),
3599
3816
  onKeyDown: handleKeyDown,
3600
- children: flatNodes.map((flat) => /* @__PURE__ */ jsx30(
3817
+ children: flatNodes.map((flat) => /* @__PURE__ */ jsx32(
3601
3818
  NodeRow,
3602
3819
  {
3603
3820
  flat,
@@ -3622,23 +3839,23 @@ function TreeViewInner({
3622
3839
  var TreeView = forwardRef19(TreeViewInner);
3623
3840
 
3624
3841
  // src/EntityTree/EntityTree.tsx
3625
- import { jsx as jsx31, jsxs as jsxs11 } from "react/jsx-runtime";
3842
+ import { jsx as jsx33, jsxs as jsxs13 } from "react/jsx-runtime";
3626
3843
  function buildCellRow(resolved, activeNodeIdRef, onNodeEdit, localRenderers) {
3627
3844
  return function renderCells(node) {
3628
3845
  const isActive = node.id === activeNodeIdRef.current;
3629
- return /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-4 min-w-0 w-full group/row", children: [
3846
+ return /* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-4 min-w-0 w-full group/row", children: [
3630
3847
  resolved.map((col) => {
3631
3848
  const Renderer = resolveCellRenderer2(
3632
3849
  col.cellRenderer,
3633
3850
  localRenderers
3634
3851
  );
3635
3852
  const value = node.data[col.key];
3636
- return /* @__PURE__ */ jsx31(
3853
+ return /* @__PURE__ */ jsx33(
3637
3854
  "span",
3638
3855
  {
3639
3856
  className: "shrink-0",
3640
3857
  style: col.width !== void 0 ? { width: col.width } : void 0,
3641
- children: /* @__PURE__ */ jsx31(
3858
+ children: /* @__PURE__ */ jsx33(
3642
3859
  Renderer,
3643
3860
  {
3644
3861
  value,
@@ -3650,7 +3867,7 @@ function buildCellRow(resolved, activeNodeIdRef, onNodeEdit, localRenderers) {
3650
3867
  col.key
3651
3868
  );
3652
3869
  }),
3653
- onNodeEdit && /* @__PURE__ */ jsx31("span", { className: "ml-auto shrink-0", children: /* @__PURE__ */ jsx31(
3870
+ onNodeEdit && /* @__PURE__ */ jsx33("span", { className: "ml-auto shrink-0", children: /* @__PURE__ */ jsx33(
3654
3871
  "button",
3655
3872
  {
3656
3873
  type: "button",
@@ -3663,7 +3880,7 @@ function buildCellRow(resolved, activeNodeIdRef, onNodeEdit, localRenderers) {
3663
3880
  "p-1 rounded hover:bg-background text-muted-foreground hover:text-foreground transition-colors",
3664
3881
  isActive ? "opacity-100" : "opacity-0 group-hover/row:opacity-100"
3665
3882
  ),
3666
- children: /* @__PURE__ */ jsx31(Pencil, { className: "h-3.5 w-3.5" })
3883
+ children: /* @__PURE__ */ jsx33(Pencil, { className: "h-3.5 w-3.5" })
3667
3884
  }
3668
3885
  ) })
3669
3886
  ] });
@@ -3686,7 +3903,7 @@ function renderTreeStatus({
3686
3903
  className
3687
3904
  }) {
3688
3905
  if (isLoading && nodes.length === 0) {
3689
- return /* @__PURE__ */ jsx31(
3906
+ return /* @__PURE__ */ jsx33(
3690
3907
  "div",
3691
3908
  {
3692
3909
  className: cn29(
@@ -3698,7 +3915,7 @@ function renderTreeStatus({
3698
3915
  );
3699
3916
  }
3700
3917
  if (isError) {
3701
- return /* @__PURE__ */ jsx31(
3918
+ return /* @__PURE__ */ jsx33(
3702
3919
  "div",
3703
3920
  {
3704
3921
  className: cn29("py-8 text-center text-sm text-destructive", className),
@@ -3707,7 +3924,7 @@ function renderTreeStatus({
3707
3924
  );
3708
3925
  }
3709
3926
  if (!isLoading && nodes.length === 0) {
3710
- return /* @__PURE__ */ jsxs11(
3927
+ return /* @__PURE__ */ jsxs13(
3711
3928
  "div",
3712
3929
  {
3713
3930
  className: cn29(
@@ -3802,7 +4019,7 @@ function EntityTreeInner(props, ref) {
3802
4019
  className
3803
4020
  });
3804
4021
  if (statusView) return statusView;
3805
- return /* @__PURE__ */ jsx31("div", { className: cn29("rounded-lg border", className), children: /* @__PURE__ */ jsx31(
4022
+ return /* @__PURE__ */ jsx33("div", { className: cn29("rounded-lg border", className), children: /* @__PURE__ */ jsx33(
3806
4023
  TreeView,
3807
4024
  {
3808
4025
  ref: treeRef,
@@ -3824,14 +4041,14 @@ function EntityTreeInner(props, ref) {
3824
4041
  var EntityTree = forwardRef20(EntityTreeInner);
3825
4042
 
3826
4043
  // src/SearchInput/SearchInput.tsx
3827
- import React30, { useMemo as useMemo6, useRef as useRef9, useState as useState7, useEffect as useEffect9 } from "react";
4044
+ import React32, { useMemo as useMemo6, useRef as useRef9, useState as useState8, useEffect as useEffect9 } from "react";
3828
4045
  import { Search as Search2, X as X3, ChevronDown } from "lucide-react";
3829
4046
  import { cn as cn31 } from "@petrarca/sonnet-core";
3830
4047
  import { getFieldTitle as getFieldTitle2 } from "@petrarca/sonnet-core/schema";
3831
4048
  import { isEmptyFilterExpr } from "@petrarca/sonnet-core/search";
3832
4049
 
3833
4050
  // src/SearchInput/useSearchInput.ts
3834
- import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo5, useRef as useRef7, useState as useState5 } from "react";
4051
+ import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo5, useRef as useRef7, useState as useState6 } from "react";
3835
4052
  import { collectTerms } from "@petrarca/sonnet-core/search";
3836
4053
 
3837
4054
  // src/SearchInput/schemaAdapter.ts
@@ -3915,11 +4132,11 @@ function useSearchInput({
3915
4132
  const terms = collectTerms(value);
3916
4133
  return terms.length === 1 && terms[0].key === "search" ? terms[0].value : "";
3917
4134
  })() : "";
3918
- const [inputValue, setInputValue] = useState5(initialInput);
3919
- const [pendingFacet, setPendingFacet] = useState5(
4135
+ const [inputValue, setInputValue] = useState6(initialInput);
4136
+ const [pendingFacet, setPendingFacet] = useState6(
3920
4137
  null
3921
4138
  );
3922
- const [draftTerms, setDraftTerms] = useState5(
4139
+ const [draftTerms, setDraftTerms] = useState6(
3923
4140
  () => isFaceted ? collectTerms(value) : []
3924
4141
  );
3925
4142
  const valueTerms = useMemo5(
@@ -4134,7 +4351,7 @@ function useSearchInput({
4134
4351
 
4135
4352
  // src/SearchInput/widgets/TextSearchWidget.tsx
4136
4353
  import { useRef as useRef8, useEffect as useEffect7 } from "react";
4137
- import { jsx as jsx32 } from "react/jsx-runtime";
4354
+ import { jsx as jsx34 } from "react/jsx-runtime";
4138
4355
  function TextSearchWidget({
4139
4356
  value,
4140
4357
  onChange,
@@ -4147,7 +4364,7 @@ function TextSearchWidget({
4147
4364
  useEffect7(() => {
4148
4365
  if (autoFocus) inputRef.current?.focus();
4149
4366
  }, [autoFocus]);
4150
- return /* @__PURE__ */ jsx32(
4367
+ return /* @__PURE__ */ jsx34(
4151
4368
  Input,
4152
4369
  {
4153
4370
  ref: inputRef,
@@ -4173,9 +4390,9 @@ function TextSearchWidget({
4173
4390
  }
4174
4391
 
4175
4392
  // src/SearchInput/widgets/EnumSearchWidget.tsx
4176
- import { useEffect as useEffect8, useState as useState6 } from "react";
4393
+ import { useEffect as useEffect8, useState as useState7 } from "react";
4177
4394
  import { cn as cn30 } from "@petrarca/sonnet-core";
4178
- import { jsx as jsx33, jsxs as jsxs12 } from "react/jsx-runtime";
4395
+ import { jsx as jsx35, jsxs as jsxs14 } from "react/jsx-runtime";
4179
4396
  function EnumSearchWidget({
4180
4397
  property,
4181
4398
  options: widgetOptions,
@@ -4184,9 +4401,9 @@ function EnumSearchWidget({
4184
4401
  placeholder,
4185
4402
  autoFocus
4186
4403
  }) {
4187
- const [open, setOpen] = useState6(false);
4188
- const [search, setSearch] = useState6("");
4189
- const [highlightedIndex, setHighlightedIndex] = useState6(0);
4404
+ const [open, setOpen] = useState7(false);
4405
+ const [search, setSearch] = useState7("");
4406
+ const [highlightedIndex, setHighlightedIndex] = useState7(0);
4190
4407
  const enumValues = property.enum ?? [];
4191
4408
  const enumNames = widgetOptions.enumNames ?? {};
4192
4409
  const items = enumValues.map((val) => ({
@@ -4239,8 +4456,8 @@ function EnumSearchWidget({
4239
4456
  return;
4240
4457
  }
4241
4458
  }
4242
- return /* @__PURE__ */ jsxs12(Popover, { open, onOpenChange: handleOpenChange, children: [
4243
- /* @__PURE__ */ jsx33(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx33(
4459
+ return /* @__PURE__ */ jsxs14(Popover, { open, onOpenChange: handleOpenChange, children: [
4460
+ /* @__PURE__ */ jsx35(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx35(
4244
4461
  "button",
4245
4462
  {
4246
4463
  type: "button",
@@ -4249,14 +4466,14 @@ function EnumSearchWidget({
4249
4466
  children: placeholder ?? "Select..."
4250
4467
  }
4251
4468
  ) }),
4252
- /* @__PURE__ */ jsxs12(
4469
+ /* @__PURE__ */ jsxs14(
4253
4470
  PopoverContent,
4254
4471
  {
4255
4472
  className: "w-48 p-1",
4256
4473
  align: "start",
4257
4474
  onOpenAutoFocus: (e) => e.preventDefault(),
4258
4475
  children: [
4259
- /* @__PURE__ */ jsx33(
4476
+ /* @__PURE__ */ jsx35(
4260
4477
  "input",
4261
4478
  {
4262
4479
  autoFocus: true,
@@ -4267,9 +4484,9 @@ function EnumSearchWidget({
4267
4484
  className: "w-full px-2 py-1.5 text-sm bg-transparent outline-none border-b border-border mb-1 placeholder:text-muted-foreground"
4268
4485
  }
4269
4486
  ),
4270
- /* @__PURE__ */ jsxs12("div", { children: [
4271
- filtered.length === 0 && /* @__PURE__ */ jsx33("p", { className: "px-2 py-1.5 text-sm text-muted-foreground", children: "No matches" }),
4272
- filtered.map((item, i) => /* @__PURE__ */ jsx33(
4487
+ /* @__PURE__ */ jsxs14("div", { children: [
4488
+ filtered.length === 0 && /* @__PURE__ */ jsx35("p", { className: "px-2 py-1.5 text-sm text-muted-foreground", children: "No matches" }),
4489
+ filtered.map((item, i) => /* @__PURE__ */ jsx35(
4273
4490
  "button",
4274
4491
  {
4275
4492
  type: "button",
@@ -4312,7 +4529,7 @@ var DEFAULT_SEARCH_WIDGETS = {
4312
4529
  };
4313
4530
 
4314
4531
  // src/SearchInput/SearchInput.tsx
4315
- import { Fragment as Fragment3, jsx as jsx34, jsxs as jsxs13 } from "react/jsx-runtime";
4532
+ import { Fragment as Fragment3, jsx as jsx36, jsxs as jsxs15 } from "react/jsx-runtime";
4316
4533
  function resolveSearchDefaults(props) {
4317
4534
  return {
4318
4535
  mode: props.mode ?? "explicit",
@@ -4332,8 +4549,8 @@ function FacetPicker({
4332
4549
  acceptFacet,
4333
4550
  inputRef
4334
4551
  }) {
4335
- return /* @__PURE__ */ jsxs13(Popover, { open: pickerVisible, onOpenChange: setPickerOpen, modal: false, children: [
4336
- /* @__PURE__ */ jsx34(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx34(
4552
+ return /* @__PURE__ */ jsxs15(Popover, { open: pickerVisible, onOpenChange: setPickerOpen, modal: false, children: [
4553
+ /* @__PURE__ */ jsx36(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx36(
4337
4554
  "button",
4338
4555
  {
4339
4556
  type: "button",
@@ -4344,17 +4561,17 @@ function FacetPicker({
4344
4561
  setPickerOpen((o) => !o);
4345
4562
  inputRef.current?.focus();
4346
4563
  },
4347
- children: /* @__PURE__ */ jsx34(ChevronDown, { className: "h-3 w-3" })
4564
+ children: /* @__PURE__ */ jsx36(ChevronDown, { className: "h-3 w-3" })
4348
4565
  }
4349
4566
  ) }),
4350
- /* @__PURE__ */ jsx34(
4567
+ /* @__PURE__ */ jsx36(
4351
4568
  PopoverContent,
4352
4569
  {
4353
4570
  className: cn31("w-44 p-1", !hasFacetsToShow && "hidden"),
4354
4571
  align: "start",
4355
4572
  onOpenAutoFocus: (e) => e.preventDefault(),
4356
4573
  onFocusOutside: (e) => e.preventDefault(),
4357
- children: filteredFacets.map((facet, i) => /* @__PURE__ */ jsx34(
4574
+ children: filteredFacets.map((facet, i) => /* @__PURE__ */ jsx36(
4358
4575
  "button",
4359
4576
  {
4360
4577
  type: "button",
@@ -4392,7 +4609,7 @@ function ValueEntry({
4392
4609
  onInputFocus
4393
4610
  }) {
4394
4611
  if (pendingFacet && PendingWidget) {
4395
- return /* @__PURE__ */ jsx34(
4612
+ return /* @__PURE__ */ jsx36(
4396
4613
  PendingWidget,
4397
4614
  {
4398
4615
  property: pendingFacet.property,
@@ -4414,7 +4631,7 @@ function ValueEntry({
4414
4631
  }
4415
4632
  );
4416
4633
  }
4417
- return /* @__PURE__ */ jsx34(
4634
+ return /* @__PURE__ */ jsx36(
4418
4635
  Input,
4419
4636
  {
4420
4637
  ref: inputRef,
@@ -4483,10 +4700,10 @@ function ActiveChips({
4483
4700
  schema,
4484
4701
  onRemove
4485
4702
  }) {
4486
- return /* @__PURE__ */ jsx34(Fragment3, { children: terms.map((term, i) => {
4703
+ return /* @__PURE__ */ jsx36(Fragment3, { children: terms.map((term, i) => {
4487
4704
  const property = schema?.properties?.[term.key];
4488
4705
  const label = property ? getFieldTitle2(term.key, property) : term.key;
4489
- return /* @__PURE__ */ jsx34(
4706
+ return /* @__PURE__ */ jsx36(
4490
4707
  FilterChip,
4491
4708
  {
4492
4709
  label: `${label}: ${term.value}`,
@@ -4510,8 +4727,8 @@ function SearchActions({
4510
4727
  onClear,
4511
4728
  onCommit
4512
4729
  }) {
4513
- return /* @__PURE__ */ jsxs13(Fragment3, { children: [
4514
- !isEmpty && /* @__PURE__ */ jsx34(
4730
+ return /* @__PURE__ */ jsxs15(Fragment3, { children: [
4731
+ !isEmpty && /* @__PURE__ */ jsx36(
4515
4732
  "button",
4516
4733
  {
4517
4734
  type: "button",
@@ -4521,10 +4738,10 @@ function SearchActions({
4521
4738
  },
4522
4739
  className: "text-muted-foreground hover:text-foreground transition-colors shrink-0",
4523
4740
  "aria-label": "Clear search",
4524
- children: /* @__PURE__ */ jsx34(X3, { className: "h-4 w-4" })
4741
+ children: /* @__PURE__ */ jsx36(X3, { className: "h-4 w-4" })
4525
4742
  }
4526
4743
  ),
4527
- showSearchButton && mode === "explicit" && /* @__PURE__ */ jsx34(
4744
+ showSearchButton && mode === "explicit" && /* @__PURE__ */ jsx36(
4528
4745
  Button,
4529
4746
  {
4530
4747
  type: "button",
@@ -4556,9 +4773,9 @@ function SearchInput(props) {
4556
4773
  const { mode, debounceMs, minChars, showSearchButton, disabled } = resolveSearchDefaults(props);
4557
4774
  const inputRef = useRef9(null);
4558
4775
  const containerRef = useRef9(null);
4559
- const [pickerOpen, setPickerOpen] = useState7(false);
4560
- const [highlightedIndex, setHighlightedIndex] = useState7(-1);
4561
- const [pickerNavigated, setPickerNavigated] = useState7(false);
4776
+ const [pickerOpen, setPickerOpen] = useState8(false);
4777
+ const [highlightedIndex, setHighlightedIndex] = useState8(-1);
4778
+ const [pickerNavigated, setPickerNavigated] = useState8(false);
4562
4779
  useEffect9(() => {
4563
4780
  if (!pickerOpen) return;
4564
4781
  function handleMouseDown(e) {
@@ -4609,7 +4826,7 @@ function SearchInput(props) {
4609
4826
  const showFacetControls = isFaceted && !pendingFacet;
4610
4827
  const pickerVisible = showFacetControls && pickerOpen;
4611
4828
  const hasFacetsToShow = pickerVisible && filteredFacets.length > 0;
4612
- const acceptFacet = React30.useCallback(
4829
+ const acceptFacet = React32.useCallback(
4613
4830
  (facet) => {
4614
4831
  selectFacet(facet);
4615
4832
  setPickerOpen(false);
@@ -4633,7 +4850,7 @@ function SearchInput(props) {
4633
4850
  acceptFacet,
4634
4851
  handleKeyDown
4635
4852
  };
4636
- return /* @__PURE__ */ jsxs13(
4853
+ return /* @__PURE__ */ jsxs15(
4637
4854
  "div",
4638
4855
  {
4639
4856
  ref: containerRef,
@@ -4650,8 +4867,8 @@ function SearchInput(props) {
4650
4867
  }
4651
4868
  },
4652
4869
  children: [
4653
- /* @__PURE__ */ jsx34(Search2, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
4654
- isFaceted && /* @__PURE__ */ jsx34(
4870
+ /* @__PURE__ */ jsx36(Search2, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
4871
+ isFaceted && /* @__PURE__ */ jsx36(
4655
4872
  ActiveChips,
4656
4873
  {
4657
4874
  terms: activeTerms,
@@ -4659,12 +4876,12 @@ function SearchInput(props) {
4659
4876
  onRemove: handleRemoveTerm
4660
4877
  }
4661
4878
  ),
4662
- pendingFacet && /* @__PURE__ */ jsxs13("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground", children: [
4879
+ pendingFacet && /* @__PURE__ */ jsxs15("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground", children: [
4663
4880
  pendingFacet.label,
4664
4881
  ":"
4665
4882
  ] }),
4666
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-1 flex-1 min-w-[120px]", children: [
4667
- showFacetControls && /* @__PURE__ */ jsx34(
4883
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1 flex-1 min-w-[120px]", children: [
4884
+ showFacetControls && /* @__PURE__ */ jsx36(
4668
4885
  FacetPicker,
4669
4886
  {
4670
4887
  pickerVisible,
@@ -4677,7 +4894,7 @@ function SearchInput(props) {
4677
4894
  inputRef
4678
4895
  }
4679
4896
  ),
4680
- /* @__PURE__ */ jsx34(
4897
+ /* @__PURE__ */ jsx36(
4681
4898
  ValueEntry,
4682
4899
  {
4683
4900
  pendingFacet,
@@ -4701,7 +4918,7 @@ function SearchInput(props) {
4701
4918
  }
4702
4919
  )
4703
4920
  ] }),
4704
- /* @__PURE__ */ jsx34(
4921
+ /* @__PURE__ */ jsx36(
4705
4922
  SearchActions,
4706
4923
  {
4707
4924
  isEmpty,
@@ -4716,14 +4933,14 @@ function SearchInput(props) {
4716
4933
  );
4717
4934
  }
4718
4935
  function FilterChip({ label, onRemove }) {
4719
- return /* @__PURE__ */ jsxs13(
4936
+ return /* @__PURE__ */ jsxs15(
4720
4937
  Badge,
4721
4938
  {
4722
4939
  variant: "secondary",
4723
4940
  className: "inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full",
4724
4941
  children: [
4725
4942
  label,
4726
- /* @__PURE__ */ jsx34(
4943
+ /* @__PURE__ */ jsx36(
4727
4944
  "button",
4728
4945
  {
4729
4946
  type: "button",
@@ -4733,7 +4950,7 @@ function FilterChip({ label, onRemove }) {
4733
4950
  },
4734
4951
  className: "ml-0.5 hover:text-destructive transition-colors",
4735
4952
  "aria-label": `Remove filter ${label}`,
4736
- children: /* @__PURE__ */ jsx34(X3, { className: "h-3 w-3" })
4953
+ children: /* @__PURE__ */ jsx36(X3, { className: "h-3 w-3" })
4737
4954
  }
4738
4955
  )
4739
4956
  ]
@@ -4743,9 +4960,9 @@ function FilterChip({ label, onRemove }) {
4743
4960
 
4744
4961
  // src/Clipboard/ClipboardButton.tsx
4745
4962
  import { Copy } from "lucide-react";
4746
- import { jsx as jsx35 } from "react/jsx-runtime";
4963
+ import { jsx as jsx37 } from "react/jsx-runtime";
4747
4964
  function ClipboardButton({ hasItems, onClick }) {
4748
- return /* @__PURE__ */ jsx35(
4965
+ return /* @__PURE__ */ jsx37(
4749
4966
  Button,
4750
4967
  {
4751
4968
  variant: "ghost",
@@ -4756,7 +4973,7 @@ function ClipboardButton({ hasItems, onClick }) {
4756
4973
  opacity: hasItems ? 1 : 0.4,
4757
4974
  cursor: hasItems ? "pointer" : "not-allowed"
4758
4975
  },
4759
- children: /* @__PURE__ */ jsx35(Copy, { size: 16 })
4976
+ children: /* @__PURE__ */ jsx37(Copy, { size: 16 })
4760
4977
  }
4761
4978
  );
4762
4979
  }
@@ -4764,13 +4981,13 @@ var ClipboardButton_default = ClipboardButton;
4764
4981
 
4765
4982
  // src/Clipboard/ClipboardItem.tsx
4766
4983
  import { X as X4, Plus } from "lucide-react";
4767
- import { jsx as jsx36, jsxs as jsxs14 } from "react/jsx-runtime";
4984
+ import { jsx as jsx38, jsxs as jsxs16 } from "react/jsx-runtime";
4768
4985
  function ClipboardItemComponent({ item, onAddItem, onRemove }) {
4769
4986
  const handleAddClick = (e) => {
4770
4987
  const keepInClipboard = e.shiftKey;
4771
4988
  onAddItem(item, keepInClipboard);
4772
4989
  };
4773
- return /* @__PURE__ */ jsx36(
4990
+ return /* @__PURE__ */ jsx38(
4774
4991
  "div",
4775
4992
  {
4776
4993
  className: "p-3 rounded mb-2",
@@ -4778,17 +4995,17 @@ function ClipboardItemComponent({ item, onAddItem, onRemove }) {
4778
4995
  borderLeft: `4px solid ${item.color}`,
4779
4996
  backgroundColor: "#f8f9fa"
4780
4997
  },
4781
- children: /* @__PURE__ */ jsxs14(SimpleGroup, { justify: "space-between", wrap: "nowrap", align: "flex-start", children: [
4782
- /* @__PURE__ */ jsxs14("div", { className: "flex-1 min-w-0 overflow-hidden", children: [
4783
- /* @__PURE__ */ jsx36("p", { className: "text-sm font-semibold truncate", children: item.label }),
4784
- /* @__PURE__ */ jsx36("p", { className: "text-xs text-muted-foreground truncate", children: item.displayName }),
4785
- /* @__PURE__ */ jsxs14("p", { className: "text-xs text-muted-foreground font-mono", children: [
4998
+ children: /* @__PURE__ */ jsxs16(SimpleGroup, { justify: "space-between", wrap: "nowrap", align: "flex-start", children: [
4999
+ /* @__PURE__ */ jsxs16("div", { className: "flex-1 min-w-0 overflow-hidden", children: [
5000
+ /* @__PURE__ */ jsx38("p", { className: "text-sm font-semibold truncate", children: item.label }),
5001
+ /* @__PURE__ */ jsx38("p", { className: "text-xs text-muted-foreground truncate", children: item.displayName }),
5002
+ /* @__PURE__ */ jsxs16("p", { className: "text-xs text-muted-foreground font-mono", children: [
4786
5003
  "#",
4787
5004
  item.entityId
4788
5005
  ] })
4789
5006
  ] }),
4790
- /* @__PURE__ */ jsxs14(SimpleGroup, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
4791
- /* @__PURE__ */ jsxs14(
5007
+ /* @__PURE__ */ jsxs16(SimpleGroup, { gap: 4, wrap: "nowrap", style: { flexShrink: 0 }, children: [
5008
+ /* @__PURE__ */ jsxs16(
4792
5009
  Button,
4793
5010
  {
4794
5011
  size: "sm",
@@ -4796,19 +5013,19 @@ function ClipboardItemComponent({ item, onAddItem, onRemove }) {
4796
5013
  onClick: handleAddClick,
4797
5014
  title: "Click to add and remove from clipboard, Shift+Click to keep in clipboard",
4798
5015
  children: [
4799
- /* @__PURE__ */ jsx36(Plus, { size: 16 }),
5016
+ /* @__PURE__ */ jsx38(Plus, { size: 16 }),
4800
5017
  "Add"
4801
5018
  ]
4802
5019
  }
4803
5020
  ),
4804
- /* @__PURE__ */ jsx36(
5021
+ /* @__PURE__ */ jsx38(
4805
5022
  Button,
4806
5023
  {
4807
5024
  size: "sm",
4808
5025
  variant: "ghost",
4809
5026
  onClick: () => onRemove(item.id),
4810
5027
  title: "Remove from clipboard",
4811
- children: /* @__PURE__ */ jsx36(X4, { size: 16 })
5028
+ children: /* @__PURE__ */ jsx38(X4, { size: 16 })
4812
5029
  }
4813
5030
  )
4814
5031
  ] })
@@ -4906,16 +5123,16 @@ var useClipboard = create()(
4906
5123
  var clipboardStore_default = useClipboard;
4907
5124
 
4908
5125
  // src/Clipboard/ClipboardMenu.tsx
4909
- import { jsx as jsx37, jsxs as jsxs15 } from "react/jsx-runtime";
5126
+ import { jsx as jsx39, jsxs as jsxs17 } from "react/jsx-runtime";
4910
5127
  function ClipboardMenu({ onAddItem }) {
4911
5128
  const { items, removeItem, clear } = clipboardStore_default();
4912
5129
  if (items.length === 0) {
4913
- return /* @__PURE__ */ jsxs15("div", { style: { padding: "16px", textAlign: "center", width: "300px" }, children: [
4914
- /* @__PURE__ */ jsx37("p", { className: "text-sm text-muted-foreground", children: "No items in clipboard" }),
4915
- /* @__PURE__ */ jsx37("p", { className: "text-xs text-muted-foreground mt-1", children: 'Right-click a node and select "Copy"' })
5130
+ return /* @__PURE__ */ jsxs17("div", { style: { padding: "16px", textAlign: "center", width: "300px" }, children: [
5131
+ /* @__PURE__ */ jsx39("p", { className: "text-sm text-muted-foreground", children: "No items in clipboard" }),
5132
+ /* @__PURE__ */ jsx39("p", { className: "text-xs text-muted-foreground mt-1", children: 'Right-click a node and select "Copy"' })
4916
5133
  ] });
4917
5134
  }
4918
- return /* @__PURE__ */ jsxs15(
5135
+ return /* @__PURE__ */ jsxs17(
4919
5136
  "div",
4920
5137
  {
4921
5138
  style: {
@@ -4926,7 +5143,7 @@ function ClipboardMenu({ onAddItem }) {
4926
5143
  maxHeight: "500px"
4927
5144
  },
4928
5145
  children: [
4929
- /* @__PURE__ */ jsx37(ScrollArea, { className: "flex-1 p-3 min-h-0", children: /* @__PURE__ */ jsx37(SimpleStack, { gap: 0, children: items.map((item) => /* @__PURE__ */ jsx37(
5146
+ /* @__PURE__ */ jsx39(ScrollArea, { className: "flex-1 p-3 min-h-0", children: /* @__PURE__ */ jsx39(SimpleStack, { gap: 0, children: items.map((item) => /* @__PURE__ */ jsx39(
4930
5147
  ClipboardItem_default,
4931
5148
  {
4932
5149
  item,
@@ -4935,8 +5152,8 @@ function ClipboardMenu({ onAddItem }) {
4935
5152
  },
4936
5153
  item.id
4937
5154
  )) }) }),
4938
- /* @__PURE__ */ jsx37(Separator2, {}),
4939
- /* @__PURE__ */ jsx37("div", { style: { padding: "8px 12px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs15(
5155
+ /* @__PURE__ */ jsx39(Separator2, {}),
5156
+ /* @__PURE__ */ jsx39("div", { style: { padding: "8px 12px", flexShrink: 0 }, children: /* @__PURE__ */ jsxs17(
4940
5157
  Button,
4941
5158
  {
4942
5159
  className: "w-full",
@@ -4944,7 +5161,7 @@ function ClipboardMenu({ onAddItem }) {
4944
5161
  size: "sm",
4945
5162
  onClick: clear,
4946
5163
  children: [
4947
- /* @__PURE__ */ jsx37(Trash2, { size: 16 }),
5164
+ /* @__PURE__ */ jsx39(Trash2, { size: 16 }),
4948
5165
  "Clear All (",
4949
5166
  items.length,
4950
5167
  ")"
@@ -5027,6 +5244,8 @@ export {
5027
5244
  Popover,
5028
5245
  PopoverContent,
5029
5246
  PopoverTrigger,
5247
+ PropertyList,
5248
+ PropertyValue,
5030
5249
  ResizeHandle,
5031
5250
  ScrollArea,
5032
5251
  ScrollBar,