@espressif/dashboard-ui-components 1.5.0 → 1.7.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.
@@ -1,9 +1,9 @@
1
1
  import { Card, CardHeader, CardTitle, CardDescription, CardContent, Label, Badge, Popover, PopoverTrigger, PopoverContent, resolveVariantStyles, VariantGradientUnderlay, PRESET_GRADIENT_BACKDROP, PRESET_GRADIENT_FRAME, VARIANT_GRADIENT_BACKDROP_BASE, SILVER_GRADIENT_BACKDROP, VARIANT_GRADIENT_HOVER_OVERLAY_CLASS, arbitraryGradientBackgroundImage, SilverShineOverlay, SilverMetallicBorderOverlay, buttonGroupVariants, useIsInView } from './chunk-ABBHGIFI.js';
2
- import { FieldLabelRow, fieldHintClassName, Button, inputLabelClassName, Input, Tooltip2, TooltipProvider, buttonVariants as buttonVariants$1, CopyButton, Link, Tooltip, TooltipTrigger, TooltipContent, HighlightItem, Slot as Slot$1, Highlight, ScrollArea, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuCheckboxItem, Sheet, SheetContent, SheetHeader, SheetTitle } from './chunk-ZEQNTNMW.js';
2
+ import { FieldLabelRow, fieldHintClassName, Button, inputLabelClassName, Input, Tooltip2, TooltipProvider, buttonVariants as buttonVariants$1, CopyButton, Link, Tooltip, TooltipTrigger, TooltipContent, HighlightItem, Slot as Slot$1, Highlight, ScrollArea, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuCheckboxItem, Sheet, SheetContent, SheetHeader, SheetTitle } from './chunk-3PO2SF7T.js';
3
3
  import { getStrictContext, buttonVariants, Separator, CollapsibleContent, Collapsible, CollapsibleTrigger, useIsMobile, useControlledState, Button as Button$1, Skeleton, Avatar, AvatarFallback } from './chunk-OKB2WTX7.js';
4
4
  import { cn, resolveColor, isPresetColor } from './chunk-VU4CZ76T.js';
5
5
  import { __commonJS, __toESM } from './chunk-TRTQSARU.js';
6
- import { ChevronDown, ChevronUp, Check, Upload, X, RefreshCw, LoaderCircle, Triangle, Info, MinusIcon, ArrowLeft, ArrowRight, Search, ClockIcon, Crown, ShieldCheck, Tag as Tag$1, ChevronRight, CircleAlert, Eye, EyeOff, Circle, FileCheck, CheckCheck, TriangleAlert, CircleX, Menu, ChevronsUpDown, ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon, CalendarIcon, CalendarRangeIcon, CheckIcon, ChevronLeft, Columns2, ChevronsRight, ChevronsLeft, XIcon, MoveLeft, CircleIcon, Bolt, Plus, Trash2, Clock, XCircle, CheckCircle2 } from 'lucide-react';
6
+ import { ChevronDown, ChevronUp, Check, Upload, X, RefreshCw, LoaderCircle, Triangle, Info, MinusIcon, ArrowLeft, ArrowRight, Search, ClockIcon, Crown, ShieldCheck, Tag as Tag$1, ChevronRight, CircleAlert, Eye, EyeOff, Circle, Braces, FileCheck, CheckCheck, TriangleAlert, CircleX, Menu, ChevronsUpDown, ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon, CalendarIcon, CalendarRangeIcon, CheckIcon, XIcon, ChevronLeft, Columns2, ChevronsRight, ChevronsLeft, MoveLeft, CircleIcon, Bolt, Plus, Trash2, Clock, XCircle, CheckCircle2 } from 'lucide-react';
7
7
  import * as React10 from 'react';
8
8
  import React10__default, { forwardRef, useMemo, isValidElement, useRef, useState, useCallback, useLayoutEffect, useEffect, useId, Fragment as Fragment$1, Children, cloneElement, createElement } from 'react';
9
9
  import { Switch as Switch$1, ToggleGroup as ToggleGroup$1, Dialog as Dialog$1, Accordion as Accordion$1 } from 'radix-ui';
@@ -24,7 +24,7 @@ import Autoplay from 'embla-carousel-autoplay';
24
24
  import useEmblaCarousel from 'embla-carousel-react';
25
25
  import { Command as Command$1 } from 'cmdk';
26
26
  import { getDefaultClassNames, DayPicker } from 'react-day-picker';
27
- import { format, endOfMonth, startOfMonth, sub, endOfDay, startOfDay, endOfYear, startOfYear, endOfWeek, startOfWeek, isValid, parse, set } from 'date-fns';
27
+ import { format, sub, endOfMonth, startOfMonth, endOfDay, startOfDay, endOfYear, startOfYear, endOfWeek, startOfWeek, isValid, parse, set } from 'date-fns';
28
28
  import { useReactTable, getPaginationRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
29
29
  import { PreviewCard as PreviewCard$1 } from '@base-ui-components/react/preview-card';
30
30
  import { startCase } from 'lodash-es';
@@ -52331,6 +52331,12 @@ var stateVisuals = {
52331
52331
  titleClass: "text-success",
52332
52332
  descriptionClass: "text-success/80"
52333
52333
  },
52334
+ warning: {
52335
+ avatarColor: "warning",
52336
+ endIconClass: "text-warning",
52337
+ titleClass: "text-warning",
52338
+ descriptionClass: "text-warning/80"
52339
+ },
52334
52340
  error: {
52335
52341
  avatarColor: "error",
52336
52342
  endIconClass: "text-error",
@@ -52352,6 +52358,7 @@ var stateVisuals = {
52352
52358
  };
52353
52359
  var stateSurfaceCssVar = {
52354
52360
  success: "--color-success",
52361
+ warning: "--color-warning",
52355
52362
  error: "--color-error",
52356
52363
  in_progress: "--color-primary",
52357
52364
  not_started: "--color-gray"
@@ -52464,6 +52471,8 @@ function StatusEndIndicator({
52464
52471
  switch (state) {
52465
52472
  case "success":
52466
52473
  return /* @__PURE__ */ jsx(CheckCircle2, { className: cls, "aria-hidden": true });
52474
+ case "warning":
52475
+ return /* @__PURE__ */ jsx(TriangleAlert, { className: cls, "aria-hidden": true });
52467
52476
  case "error":
52468
52477
  return /* @__PURE__ */ jsx(XCircle, { className: cls, "aria-hidden": true });
52469
52478
  case "in_progress":
@@ -52782,15 +52791,15 @@ var Spinner = React10.forwardRef(function Spinner2({
52782
52791
  "aria-labelledby": ariaLabelledby,
52783
52792
  ...rest
52784
52793
  }, ref) {
52785
- const resolved = color != null ? resolveColor(color, "text") : void 0;
52794
+ const resolved2 = color != null ? resolveColor(color, "text") : void 0;
52786
52795
  const ariaLabelResolved = ariaLabelledby != null ? void 0 : ariaLabel !== void 0 ? ariaLabel : "Loading";
52787
52796
  return /* @__PURE__ */ jsx(
52788
52797
  LoaderCircle,
52789
52798
  {
52790
52799
  ref,
52791
52800
  ...rest,
52792
- className: cn("animate-spin", resolved?.className, className),
52793
- style: { ...resolved?.style, ...style },
52801
+ className: cn("animate-spin", resolved2?.className, className),
52802
+ style: { ...resolved2?.style, ...style },
52794
52803
  size: size ?? "1em",
52795
52804
  "aria-label": ariaLabelResolved,
52796
52805
  "aria-labelledby": ariaLabelledby
@@ -56284,6 +56293,7 @@ function DateTimePicker(props) {
56284
56293
  }
56285
56294
  DateTimePicker.displayName = "DateTimePicker";
56286
56295
  var PRESET_IDS = [
56296
+ // Calendar periods
56287
56297
  "today",
56288
56298
  "yesterday",
56289
56299
  "this-week",
@@ -56292,10 +56302,16 @@ var PRESET_IDS = [
56292
56302
  "last-month",
56293
56303
  "this-year",
56294
56304
  "last-year",
56305
+ // Trailing ranges, shortest first. A rolling preset (ends now) precedes
56306
+ // the day-snapped preset of the same length.
56307
+ "last-1-hour",
56308
+ "last-24-hours",
56295
56309
  "last-1-day",
56310
+ "past-7-days",
56296
56311
  "last-7-days",
56297
56312
  "last-14-days",
56298
56313
  "last-15-days",
56314
+ "past-30-days",
56299
56315
  "last-30-days",
56300
56316
  "last-4-weeks",
56301
56317
  "last-90-days",
@@ -56313,10 +56329,14 @@ var PRESET_LABELS = {
56313
56329
  "last-month": "Last month",
56314
56330
  "this-year": "This year",
56315
56331
  "last-year": "Last year",
56332
+ "last-1-hour": "Last 1 hour",
56333
+ "last-24-hours": "Last 24 hours",
56316
56334
  "last-1-day": "Last 1 day",
56335
+ "past-7-days": "Past 7 days",
56317
56336
  "last-7-days": "Last 7 days",
56318
56337
  "last-14-days": "Last 14 days",
56319
56338
  "last-15-days": "Last 15 days",
56339
+ "past-30-days": "Past 30 days",
56320
56340
  "last-30-days": "Last 30 days",
56321
56341
  "last-4-weeks": "Last 4 weeks",
56322
56342
  "last-90-days": "Last 90 days",
@@ -56325,6 +56345,12 @@ var PRESET_LABELS = {
56325
56345
  "last-1-year": "Last 1 year",
56326
56346
  "last-5-years": "Last 5 years"
56327
56347
  };
56348
+ var ROLLING_PRESET_IDS = [
56349
+ "last-1-hour",
56350
+ "last-24-hours",
56351
+ "past-7-days",
56352
+ "past-30-days"
56353
+ ];
56328
56354
  function computeDateRange(id) {
56329
56355
  const now = /* @__PURE__ */ new Date();
56330
56356
  switch (id) {
@@ -56401,6 +56427,14 @@ function computeDateRange(id) {
56401
56427
  return { startDate: startOfMonth(sub(now, { years: 1 })), endDate: endOfMonth(now) };
56402
56428
  case "last-5-years":
56403
56429
  return { startDate: startOfMonth(sub(now, { years: 5 })), endDate: endOfMonth(now) };
56430
+ case "last-1-hour":
56431
+ return { startDate: sub(now, { hours: 1 }), endDate: now };
56432
+ case "last-24-hours":
56433
+ return { startDate: sub(now, { hours: 24 }), endDate: now };
56434
+ case "past-7-days":
56435
+ return { startDate: sub(now, { days: 7 }), endDate: now };
56436
+ case "past-30-days":
56437
+ return { startDate: sub(now, { days: 30 }), endDate: now };
56404
56438
  }
56405
56439
  }
56406
56440
  var DEFAULT_DATE_FORMAT = "dd MMM yyyy";
@@ -56436,6 +56470,9 @@ function DateRangePicker({
56436
56470
  selectedPresetId,
56437
56471
  selectedStartDate,
56438
56472
  selectedEndDate,
56473
+ clearable = false,
56474
+ clearLabel = "Clear",
56475
+ onClear,
56439
56476
  trigger,
56440
56477
  placeholder = "Select date range",
56441
56478
  label,
@@ -56577,7 +56614,12 @@ function DateRangePicker({
56577
56614
  if (lockEndToToday) return;
56578
56615
  setEndInputValue(draftRange.endDate ? format(draftRange.endDate, dateFormat) : "");
56579
56616
  };
56617
+ const handleClear = () => {
56618
+ onClear?.();
56619
+ handleOpenChange(false);
56620
+ };
56580
56621
  const displayValue = selectedPresetId ? resolveLabel(selectedPresetId) : "";
56622
+ const hasSelection = !!(selectedPresetId || selectedStartDate);
56581
56623
  const inputTrigger = /* @__PURE__ */ jsx(
56582
56624
  Input,
56583
56625
  {
@@ -56673,6 +56715,22 @@ function DateRangePicker({
56673
56715
  ]
56674
56716
  }
56675
56717
  )
56718
+ ] }),
56719
+ clearable && hasSelection && /* @__PURE__ */ jsxs(Fragment, { children: [
56720
+ /* @__PURE__ */ jsx("div", { className: "mx-1 my-1 h-px bg-border" }),
56721
+ /* @__PURE__ */ jsxs(
56722
+ "button",
56723
+ {
56724
+ type: "button",
56725
+ onClick: handleClear,
56726
+ onMouseEnter: () => setShowCalendar(false),
56727
+ className: "flex w-full items-center justify-between gap-6 px-3 py-1.5 text-left text-sm text-muted-foreground hover:bg-accent",
56728
+ children: [
56729
+ clearLabel,
56730
+ /* @__PURE__ */ jsx(XIcon, { className: "size-4 shrink-0" })
56731
+ ]
56732
+ }
56733
+ )
56676
56734
  ] })
56677
56735
  ] }),
56678
56736
  allowCustom && showCalendar && /* @__PURE__ */ jsx(
@@ -57451,17 +57509,21 @@ function DataTable({
57451
57509
  () => enableRowSelection ? [selectColumn, ...columns] : columns,
57452
57510
  [enableRowSelection, selectColumn, columns]
57453
57511
  );
57512
+ const pagination = useMemo(() => ({ pageIndex: 0, pageSize }), [pageSize]);
57454
57513
  const table = useReactTable({
57455
57514
  data: data2,
57456
57515
  columns: tableColumns,
57457
57516
  state: {
57458
57517
  columnVisibility,
57459
- pagination: {
57460
- pageIndex: 0,
57461
- pageSize
57462
- },
57518
+ pagination,
57463
57519
  ...rowSelection !== void 0 && { rowSelection }
57464
57520
  },
57521
+ // With `manualPagination` unset, TanStack resets pageIndex (an internal
57522
+ // setState + re-render) whenever `data` changes identity. pageIndex is pinned
57523
+ // to 0 here, so that reset is a no-op; with consumers that pass a fresh array
57524
+ // each render (`data?.items ?? []`) it can loop into "Maximum update depth
57525
+ // exceeded".
57526
+ autoResetPageIndex: false,
57465
57527
  onColumnVisibilityChange: setColumnVisibility,
57466
57528
  enableRowSelection,
57467
57529
  enableMultiRowSelection,
@@ -57851,8 +57913,8 @@ function DeviceIcon({ type, size = 18, color, fallback: Fallback, className }) {
57851
57913
  const Matched = matchDevice(type);
57852
57914
  const Icon2 = Matched ?? Fallback;
57853
57915
  if (!Icon2) return null;
57854
- const resolved = color ? resolveColor(color, "text") : void 0;
57855
- return /* @__PURE__ */ jsx("span", { className: cn("inline-flex", resolved?.className, className), style: resolved?.style, children: /* @__PURE__ */ jsx(Icon2, { size }) });
57916
+ const resolved2 = color ? resolveColor(color, "text") : void 0;
57917
+ return /* @__PURE__ */ jsx("span", { className: cn("inline-flex", resolved2?.className, className), style: resolved2?.style, children: /* @__PURE__ */ jsx(Icon2, { size }) });
57856
57918
  }
57857
57919
  var userTypeBadgeRegistry = {
57858
57920
  admin: {
@@ -57913,6 +57975,12 @@ var UserTypeBadge = React10.forwardRef(
57913
57975
  }
57914
57976
  );
57915
57977
  UserTypeBadge.displayName = "UserTypeBadge";
57978
+ function renderStatusBadgeIcon(icon, px) {
57979
+ if (!icon) return null;
57980
+ if (React10.isValidElement(icon)) return icon;
57981
+ const Icon2 = icon;
57982
+ return /* @__PURE__ */ jsx(Icon2, { size: px, "aria-hidden": true });
57983
+ }
57916
57984
  var ICON_PX = {
57917
57985
  sm: 14,
57918
57986
  default: 16,
@@ -57959,7 +58027,7 @@ var StatusBadge = React10.forwardRef(
57959
58027
  }, ref) => {
57960
58028
  const iconPx = ICON_PX[size];
57961
58029
  const showIcon = isLoading || !!Icon2;
57962
- return /* @__PURE__ */ jsx("div", { ref, className: "inline-block", ...props, children: /* @__PURE__ */ jsxs(
58030
+ return /* @__PURE__ */ jsx("div", { ref, className: "inline-flex align-middle", ...props, children: /* @__PURE__ */ jsxs(
57963
58031
  Badge,
57964
58032
  {
57965
58033
  color,
@@ -57969,7 +58037,7 @@ var StatusBadge = React10.forwardRef(
57969
58037
  className
57970
58038
  ),
57971
58039
  children: [
57972
- isLoading ? /* @__PURE__ */ jsx(Spinner, { size: iconPx, "aria-hidden": true }) : Icon2 ? /* @__PURE__ */ jsx(Icon2, { size: iconPx, "aria-hidden": true }) : null,
58040
+ isLoading ? /* @__PURE__ */ jsx(Spinner, { size: iconPx, "aria-hidden": true }) : renderStatusBadgeIcon(Icon2, iconPx),
57973
58041
  /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: label })
57974
58042
  ]
57975
58043
  }
@@ -59167,7 +59235,16 @@ function renderTitleAndDescriptionBlocks(p) {
59167
59235
  extraTitleClass: s.titleSizeClass
59168
59236
  });
59169
59237
  } else {
59170
- titleBlock = /* @__PURE__ */ jsx("div", { className: cn("min-w-0 text-left", fgClass), style: fgStyle, children: title });
59238
+ titleBlock = /* @__PURE__ */ jsx(
59239
+ Typography,
59240
+ {
59241
+ as: "div",
59242
+ variant: s.titleVariant,
59243
+ className: cn("min-w-0 text-left", s.titleSizeClass, fgClass),
59244
+ style: fgStyle,
59245
+ children: title
59246
+ }
59247
+ );
59171
59248
  }
59172
59249
  }
59173
59250
  let descriptionBlock = null;
@@ -60029,6 +60106,8 @@ function getHighlighter() {
60029
60106
  function normalizeLang(lang) {
60030
60107
  return LANG_ALIASES[lang.toLowerCase()] ?? lang;
60031
60108
  }
60109
+
60110
+ // src/core/animate-ui/primitives/animate/escape-html.ts
60032
60111
  function escapeHtml(input) {
60033
60112
  return input.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
60034
60113
  }
@@ -60156,6 +60235,33 @@ function CodeBlock({
60156
60235
  }
60157
60236
  );
60158
60237
  }
60238
+ function CodeHeader({ icon: Icon2, fileName, copyContent, copyLabel = "Copy", actions }) {
60239
+ const copyButton = copyContent !== void 0 && /* @__PURE__ */ jsx(
60240
+ CopyButton,
60241
+ {
60242
+ content: copyContent,
60243
+ size: "sm",
60244
+ variant: "ghost",
60245
+ "aria-label": copyLabel,
60246
+ title: copyLabel,
60247
+ className: cn(actions == null && "ml-auto", "w-auto h-auto p-2 -mr-2")
60248
+ }
60249
+ );
60250
+ return /* @__PURE__ */ jsxs(
60251
+ "div",
60252
+ {
60253
+ className: "shrink-0 gap-x-2 border-b border-border/75 dark:border-border/50 text-sm flex text-muted-foreground items-center px-4 w-full h-10 font-medium",
60254
+ children: [
60255
+ Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "size-4" }),
60256
+ fileName,
60257
+ actions != null ? /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center gap-1", children: [
60258
+ actions,
60259
+ copyButton
60260
+ ] }) : copyButton
60261
+ ]
60262
+ }
60263
+ );
60264
+ }
60159
60265
  function Code({
60160
60266
  className,
60161
60267
  code,
@@ -60182,23 +60288,12 @@ function Code({
60182
60288
  style: { height: height2, ...style },
60183
60289
  ...props,
60184
60290
  children: [
60185
- showHeader && /* @__PURE__ */ jsxs(
60186
- "div",
60291
+ showHeader && /* @__PURE__ */ jsx(
60292
+ CodeHeader,
60187
60293
  {
60188
- className: "shrink-0 gap-x-2 border-b border-border/75 dark:border-border/50 text-sm flex text-muted-foreground items-center px-4 w-full h-10 font-medium",
60189
- children: [
60190
- Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "size-4" }),
60191
- fileName,
60192
- showCopyButton && /* @__PURE__ */ jsx(
60193
- CopyButton,
60194
- {
60195
- content: code,
60196
- size: "sm",
60197
- variant: "ghost",
60198
- className: "ml-auto w-auto h-auto p-2 -mr-2"
60199
- }
60200
- )
60201
- ]
60294
+ icon: Icon2,
60295
+ fileName,
60296
+ copyContent: showCopyButton ? code : void 0
60202
60297
  }
60203
60298
  ),
60204
60299
  lang && /* @__PURE__ */ jsx(
@@ -61017,14 +61112,79 @@ function DynamicList({
61017
61112
  );
61018
61113
  }) });
61019
61114
  }
61115
+ function KeyValueManagerField({
61116
+ field,
61117
+ label,
61118
+ value: value2,
61119
+ meta,
61120
+ error,
61121
+ errorMessage,
61122
+ selectPlaceholder,
61123
+ onChange
61124
+ }) {
61125
+ const errorContent = error ? errorMessage : void 0;
61126
+ if (meta?.options) {
61127
+ return (
61128
+ // Remounted when cleared: a Radix Select can't show its placeholder again once it held a value.
61129
+ /* @__PURE__ */ jsxs(
61130
+ Select,
61131
+ {
61132
+ value: value2 || void 0,
61133
+ onValueChange: onChange,
61134
+ children: [
61135
+ /* @__PURE__ */ jsx(
61136
+ SelectTrigger,
61137
+ {
61138
+ label,
61139
+ size: "sm",
61140
+ error,
61141
+ errorContent,
61142
+ children: /* @__PURE__ */ jsx(SelectValue, { placeholder: selectPlaceholder })
61143
+ }
61144
+ ),
61145
+ /* @__PURE__ */ jsx(SelectContent, { children: meta.options.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option, children: option }, option)) })
61146
+ ]
61147
+ },
61148
+ value2 ? "selected" : "empty"
61149
+ )
61150
+ );
61151
+ }
61152
+ if (field === "key") {
61153
+ return /* @__PURE__ */ jsx(
61154
+ Input,
61155
+ {
61156
+ label,
61157
+ value: value2,
61158
+ charLimit: meta?.maxLength,
61159
+ error,
61160
+ size: "sm",
61161
+ errorContent,
61162
+ onChange: (e) => onChange(e.target.value)
61163
+ }
61164
+ );
61165
+ }
61166
+ return /* @__PURE__ */ jsx(
61167
+ Textarea,
61168
+ {
61169
+ label,
61170
+ value: value2,
61171
+ charLimit: meta?.maxLength,
61172
+ error,
61173
+ errorContent,
61174
+ onChange: (e) => onChange(e.target.value),
61175
+ size: "sm"
61176
+ }
61177
+ );
61178
+ }
61020
61179
 
61021
61180
  // src/components/key-value-manager/key-value-manager.utils.ts
61022
61181
  function validateField(value2, meta) {
61023
61182
  if (!value2.trim()) return false;
61024
61183
  if (meta?.maxLength != null && value2.length > meta.maxLength) return false;
61184
+ if (meta?.options && !meta.options.includes(value2)) return false;
61025
61185
  if (meta?.regex) {
61026
61186
  try {
61027
- if (!new RegExp(meta.regex).test(value2)) return false;
61187
+ if (!new RegExp(meta.regex, meta.regexFlags).test(value2)) return false;
61028
61188
  } catch {
61029
61189
  }
61030
61190
  }
@@ -61113,27 +61273,29 @@ function KeyValueManagerAddPopover({
61113
61273
  ) }),
61114
61274
  /* @__PURE__ */ jsxs(PopoverContent, { align: "end", className: "w-80 space-y-4", children: [
61115
61275
  /* @__PURE__ */ jsx(
61116
- Input,
61276
+ KeyValueManagerField,
61117
61277
  {
61278
+ field: "key",
61118
61279
  label: labels.keyLabel,
61119
61280
  value: draftKey,
61120
- charLimit: meta?.key?.maxLength,
61281
+ meta: meta?.key,
61121
61282
  error: keyError,
61122
- size: "sm",
61123
- errorContent: keyError ? labels.keyErrorMessage : void 0,
61124
- onChange: (e) => handleFieldChange("key", e.target.value)
61283
+ errorMessage: labels.keyErrorMessage,
61284
+ selectPlaceholder: labels.selectPlaceholder,
61285
+ onChange: (value2) => handleFieldChange("key", value2)
61125
61286
  }
61126
61287
  ),
61127
61288
  /* @__PURE__ */ jsx(
61128
- Textarea,
61289
+ KeyValueManagerField,
61129
61290
  {
61291
+ field: "value",
61130
61292
  label: labels.valueLabel,
61131
61293
  value: draftValue,
61132
- charLimit: meta?.value?.maxLength,
61294
+ meta: meta?.value,
61133
61295
  error: valueError,
61134
- errorContent: valueError ? labels.valueErrorMessage : void 0,
61135
- onChange: (e) => handleFieldChange("value", e.target.value),
61136
- size: "sm"
61296
+ errorMessage: labels.valueErrorMessage,
61297
+ selectPlaceholder: labels.selectPlaceholder,
61298
+ onChange: (value2) => handleFieldChange("value", value2)
61137
61299
  }
61138
61300
  ),
61139
61301
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
@@ -61296,7 +61458,8 @@ var STATIC_DEFAULT_LABELS = {
61296
61458
  valueLabel: "Value",
61297
61459
  actionLabel: "Action",
61298
61460
  emptyItems: "No items",
61299
- emptySearch: "No matches"
61461
+ emptySearch: "No matches",
61462
+ selectPlaceholder: "Select"
61300
61463
  };
61301
61464
  function resolveKeyValueManagerLabels(labels) {
61302
61465
  const merged = { ...STATIC_DEFAULT_LABELS, ...labels };
@@ -61860,9 +62023,25 @@ var MarkdownContent = React10.forwardRef(
61860
62023
  }
61861
62024
  );
61862
62025
  MarkdownContent.displayName = "MarkdownContent";
62026
+ function resolveBadge(item, index2, defaultIcon, defaultColor) {
62027
+ if (typeof item === "string") {
62028
+ return {
62029
+ key: `${item}-${index2}`,
62030
+ label: item,
62031
+ icon: index2 === 0 ? defaultIcon : void 0,
62032
+ color: defaultColor
62033
+ };
62034
+ }
62035
+ return {
62036
+ key: `${item.id ?? item.label}-${index2}`,
62037
+ label: item.label,
62038
+ icon: item.icon,
62039
+ color: item.color ?? defaultColor
62040
+ };
62041
+ }
61863
62042
  function OverflowBadgeList({
61864
62043
  items,
61865
- icon: Icon2,
62044
+ icon,
61866
62045
  badgeColor,
61867
62046
  badgeVariant = "outline",
61868
62047
  badgeSize = "default",
@@ -61874,22 +62053,25 @@ function OverflowBadgeList({
61874
62053
  if (items.length === 0) {
61875
62054
  return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: noneLabel });
61876
62055
  }
61877
- const visibleCount = Math.min(Math.max(1, maxBadgesToShow), items.length);
61878
- const visibleItems = items.slice(0, visibleCount);
61879
- const hiddenCount = items.length - visibleCount;
61880
- const tooltipContent = hiddenCount > 0 ? /* @__PURE__ */ jsx("ul", { className: "max-h-48 max-w-xs list-disc space-y-1 overflow-y-auto pl-4 text-left text-sm", children: items.map((item, index2) => /* @__PURE__ */ jsx("li", { className: "break-words", children: item }, `${item}-${index2}`)) }) : null;
62056
+ const badges = items.map(
62057
+ (item, index2) => resolveBadge(item, index2, icon, badgeColor)
62058
+ );
62059
+ const visibleCount = Math.min(Math.max(1, maxBadgesToShow), badges.length);
62060
+ const visibleBadges = badges.slice(0, visibleCount);
62061
+ const hiddenCount = badges.length - visibleCount;
62062
+ const tooltipContent = hiddenCount > 0 ? /* @__PURE__ */ jsx("ul", { className: "max-h-48 max-w-xs list-disc space-y-1 overflow-y-auto pl-4 text-left text-sm", children: badges.map((badge) => /* @__PURE__ */ jsx("li", { className: "break-words", children: badge.label }, badge.key)) }) : null;
61881
62063
  return /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 flex-wrap items-center gap-2", className), children: [
61882
- visibleItems.map((item, index2) => /* @__PURE__ */ jsx(
62064
+ visibleBadges.map((badge) => /* @__PURE__ */ jsx(
61883
62065
  StatusBadge,
61884
62066
  {
61885
- label: item,
61886
- icon: index2 === 0 ? Icon2 : void 0,
62067
+ label: badge.label,
62068
+ icon: badge.icon,
61887
62069
  variant: badgeVariant,
61888
- color: badgeColor,
62070
+ color: badge.color,
61889
62071
  size: badgeSize,
61890
62072
  className: "max-w-[12rem]"
61891
62073
  },
61892
- `${item}-${index2}`
62074
+ badge.key
61893
62075
  )),
61894
62076
  hiddenCount > 0 && tooltipContent ? /* @__PURE__ */ jsx(Tooltip2, { content: tooltipContent, side: "top", align: "start", children: /* @__PURE__ */ jsx(
61895
62077
  "span",
@@ -68108,6 +68290,506 @@ var SimpleInfoCard = React10.forwardRef(
68108
68290
  }
68109
68291
  );
68110
68292
  SimpleInfoCard.displayName = "SimpleInfoCard";
68293
+
68294
+ // src/components/code-editor/code-editor.utils.ts
68295
+ function getLineStart(value2, pos) {
68296
+ return value2.lastIndexOf("\n", pos - 1) + 1;
68297
+ }
68298
+ function getLineEnd(value2, pos) {
68299
+ const next = value2.indexOf("\n", pos);
68300
+ return next === -1 ? value2.length : next;
68301
+ }
68302
+ function getLineIndent(value2, pos) {
68303
+ const lineStart = getLineStart(value2, pos);
68304
+ return /^[ \t]*/.exec(value2.slice(lineStart, pos))[0];
68305
+ }
68306
+ function isMultiLineSelection(value2, start, end) {
68307
+ return value2.slice(start, end).includes("\n");
68308
+ }
68309
+ function getSelectedLineStarts(value2, start, end) {
68310
+ const lastPos = end > start && value2[end - 1] === "\n" ? end - 1 : end;
68311
+ const starts = [getLineStart(value2, start)];
68312
+ for (let i = value2.indexOf("\n", starts[0]); i !== -1 && i < lastPos; i = value2.indexOf("\n", i + 1)) {
68313
+ starts.push(i + 1);
68314
+ }
68315
+ return starts;
68316
+ }
68317
+ function insertTab(value2, start, end, tabSize) {
68318
+ const column = start - getLineStart(value2, start);
68319
+ const text2 = " ".repeat(tabSize - column % tabSize);
68320
+ const caret = start + text2.length;
68321
+ return { start, end, text: text2, selectionStart: caret, selectionEnd: caret };
68322
+ }
68323
+ function indentLines(value2, start, end, tabSize) {
68324
+ const lineStarts = getSelectedLineStarts(value2, start, end);
68325
+ const blockStart = lineStarts[0];
68326
+ const blockEnd = getLineEnd(value2, lineStarts[lineStarts.length - 1]);
68327
+ const indent = " ".repeat(tabSize);
68328
+ const added = lineStarts.map(
68329
+ (lineStart) => lineStart === getLineEnd(value2, lineStart) ? 0 : tabSize
68330
+ );
68331
+ const lines = value2.slice(blockStart, blockEnd).split("\n");
68332
+ const text2 = lines.map((line, i) => added[i] ? indent + line : line).join("\n");
68333
+ const mapOffset = (pos, keepAtLineStart) => {
68334
+ let shift = 0;
68335
+ lineStarts.forEach((lineStart, i) => {
68336
+ if (lineStart < pos || lineStart === pos && !keepAtLineStart) shift += added[i];
68337
+ });
68338
+ return pos + shift;
68339
+ };
68340
+ return {
68341
+ start: blockStart,
68342
+ end: blockEnd,
68343
+ text: text2,
68344
+ // A selection starting at column 0 keeps starting there, so the new indentation is selected too.
68345
+ selectionStart: mapOffset(start, true),
68346
+ selectionEnd: mapOffset(end, false)
68347
+ };
68348
+ }
68349
+ function outdentLines(value2, start, end, tabSize) {
68350
+ const lineStarts = getSelectedLineStarts(value2, start, end);
68351
+ const blockStart = lineStarts[0];
68352
+ const blockEnd = getLineEnd(value2, lineStarts[lineStarts.length - 1]);
68353
+ const lines = value2.slice(blockStart, blockEnd).split("\n");
68354
+ const removed = lines.map(
68355
+ (line) => line.startsWith(" ") ? 1 : Math.min(tabSize, /^ */.exec(line)[0].length)
68356
+ );
68357
+ const text2 = lines.map((line, i) => line.slice(removed[i])).join("\n");
68358
+ const mapOffset = (pos) => {
68359
+ let shift = 0;
68360
+ lineStarts.forEach((lineStart, i) => {
68361
+ if (lineStart <= pos) shift += Math.min(removed[i], pos - lineStart);
68362
+ });
68363
+ return pos - shift;
68364
+ };
68365
+ return {
68366
+ start: blockStart,
68367
+ end: blockEnd,
68368
+ text: text2,
68369
+ selectionStart: mapOffset(start),
68370
+ selectionEnd: mapOffset(end)
68371
+ };
68372
+ }
68373
+ function insertNewline(value2, start, end) {
68374
+ const text2 = "\n" + getLineIndent(value2, start);
68375
+ const caret = start + text2.length;
68376
+ return { start, end, text: text2, selectionStart: caret, selectionEnd: caret };
68377
+ }
68378
+ function applyTextEdit(value2, edit) {
68379
+ return value2.slice(0, edit.start) + edit.text + value2.slice(edit.end);
68380
+ }
68381
+ function formatJson(value2, tabSize) {
68382
+ return JSON.stringify(JSON.parse(value2), null, tabSize);
68383
+ }
68384
+ function getBuiltInFormatter(lang) {
68385
+ return lang.toLowerCase() === "json" ? formatJson : void 0;
68386
+ }
68387
+ function applyEdit(el, edit) {
68388
+ const current = el.value;
68389
+ const expected = applyTextEdit(current, edit);
68390
+ if (expected === current) {
68391
+ el.setSelectionRange(edit.selectionStart, edit.selectionEnd);
68392
+ return;
68393
+ }
68394
+ if (el.ownerDocument.activeElement !== el) el.focus({ preventScroll: true });
68395
+ el.setSelectionRange(edit.start, edit.end);
68396
+ let applied = false;
68397
+ try {
68398
+ applied = typeof document.execCommand === "function" && document.execCommand(edit.text ? "insertText" : "delete", false, edit.text);
68399
+ } catch {
68400
+ applied = false;
68401
+ }
68402
+ if (!applied || el.value !== expected) {
68403
+ if (el.value !== current) el.value = current;
68404
+ el.setRangeText(edit.text, edit.start, edit.end, "end");
68405
+ el.dispatchEvent(new Event("input", { bubbles: true }));
68406
+ }
68407
+ el.setSelectionRange(edit.selectionStart, edit.selectionEnd);
68408
+ }
68409
+ function useCodeEditorKeys({ tabSize, onKeyDown, onBlur }) {
68410
+ const tabReleasedRef = React10.useRef(false);
68411
+ const handleKeyDown = React10.useCallback(
68412
+ (event) => {
68413
+ onKeyDown?.(event);
68414
+ if (event.defaultPrevented) return;
68415
+ if (event.nativeEvent.isComposing || event.keyCode === 229) return;
68416
+ const el = event.currentTarget;
68417
+ if (el.readOnly || el.disabled) return;
68418
+ if (event.key === "Escape") {
68419
+ tabReleasedRef.current = true;
68420
+ return;
68421
+ }
68422
+ if (event.key === "Shift") return;
68423
+ const released = tabReleasedRef.current;
68424
+ tabReleasedRef.current = false;
68425
+ const { value: value2, selectionStart: start, selectionEnd: end } = el;
68426
+ if (event.key === "Tab") {
68427
+ if (released || event.altKey || event.ctrlKey || event.metaKey) return;
68428
+ event.preventDefault();
68429
+ if (event.shiftKey) {
68430
+ applyEdit(el, outdentLines(value2, start, end, tabSize));
68431
+ } else if (isMultiLineSelection(value2, start, end)) {
68432
+ applyEdit(el, indentLines(value2, start, end, tabSize));
68433
+ } else {
68434
+ applyEdit(el, insertTab(value2, start, end, tabSize));
68435
+ }
68436
+ return;
68437
+ }
68438
+ if (event.key === "Enter" && !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey) {
68439
+ event.preventDefault();
68440
+ applyEdit(el, insertNewline(value2, start, end));
68441
+ }
68442
+ },
68443
+ [onKeyDown, tabSize]
68444
+ );
68445
+ const handleBlur = React10.useCallback(
68446
+ (event) => {
68447
+ tabReleasedRef.current = false;
68448
+ onBlur?.(event);
68449
+ },
68450
+ [onBlur]
68451
+ );
68452
+ return { onKeyDown: handleKeyDown, onBlur: handleBlur };
68453
+ }
68454
+ var DEFAULT_CODE_EDITOR_THEMES = {
68455
+ light: "everforest-light",
68456
+ dark: "everforest-dark"
68457
+ };
68458
+ var PLAIN_LANGS = /* @__PURE__ */ new Set(["text", "plaintext", "txt", "plain"]);
68459
+ var TRAILING_LINE = "\u200B";
68460
+ var transformer = {
68461
+ // Shiki makes its `<pre>` focusable; this one sits in an `aria-hidden` layer.
68462
+ pre(node) {
68463
+ delete node.properties.tabindex;
68464
+ },
68465
+ code(node) {
68466
+ node.children.push({ type: "text", value: TRAILING_LINE });
68467
+ }
68468
+ };
68469
+ function plainHtml(value2) {
68470
+ return `<pre><code>${escapeHtml(value2)}${TRAILING_LINE}</code></pre>`;
68471
+ }
68472
+ var warned = /* @__PURE__ */ new Set();
68473
+ function warnOnce(key2, message, error) {
68474
+ if (warned.has(key2)) return;
68475
+ warned.add(key2);
68476
+ console.warn(`[dashboard-ui-components] ${message}`, ...error ? [error] : []);
68477
+ }
68478
+ var resolved = /* @__PURE__ */ new WeakMap();
68479
+ function useHighlightedHtml(value2, { lang, theme, themes, maxHighlightLength }) {
68480
+ const [highlighter, setHighlighter] = React10.useState(() => {
68481
+ const promise = getHighlighter();
68482
+ return resolved.get(promise) ?? null;
68483
+ });
68484
+ React10.useEffect(() => {
68485
+ if (highlighter) return;
68486
+ let active2 = true;
68487
+ const promise = getHighlighter();
68488
+ promise.then(
68489
+ (loaded) => {
68490
+ resolved.set(promise, loaded);
68491
+ if (active2) setHighlighter(loaded);
68492
+ },
68493
+ (error) => warnOnce("load", "Syntax highlighter failed to load; showing plain text.", error)
68494
+ );
68495
+ return () => {
68496
+ active2 = false;
68497
+ };
68498
+ }, [highlighter]);
68499
+ const deferredValue = React10.useDeferredValue(value2);
68500
+ const { light, dark } = themes;
68501
+ return React10.useMemo(() => {
68502
+ if (!highlighter || deferredValue.length > maxHighlightLength) {
68503
+ return plainHtml(deferredValue);
68504
+ }
68505
+ const normalizedLang = normalizeLang(lang);
68506
+ if (!PLAIN_LANGS.has(normalizedLang) && !highlighter.getLoadedLanguages().includes(normalizedLang)) {
68507
+ warnOnce(
68508
+ `lang:${lang}`,
68509
+ `Falling back to plain text for lang="${lang}"; not in the curated Shiki bundle.`
68510
+ );
68511
+ return plainHtml(deferredValue);
68512
+ }
68513
+ try {
68514
+ return highlighter.codeToHtml(deferredValue, {
68515
+ lang: normalizedLang,
68516
+ themes: { light, dark },
68517
+ defaultColor: theme,
68518
+ transformers: [transformer]
68519
+ });
68520
+ } catch (error) {
68521
+ warnOnce(
68522
+ `theme:${light}:${dark}:${lang}`,
68523
+ `Falling back to plain text for themes "${light}" / "${dark}" with lang="${lang}".`,
68524
+ error
68525
+ );
68526
+ return plainHtml(deferredValue);
68527
+ }
68528
+ }, [highlighter, deferredValue, lang, theme, light, dark, maxHighlightLength]);
68529
+ }
68530
+ var layerClassName = "col-start-1 row-start-1 m-0 box-border border-0 p-4 font-mono text-[16px] leading-normal tracking-normal [font-variant-ligatures:none] md:text-[13px]";
68531
+ var highlightClassName = "[&_pre]:m-0 [&_pre]:p-0 [&_pre]:!bg-transparent [&_pre]:[font:inherit] [&_pre]:[white-space:inherit] [&_pre]:[overflow-wrap:inherit] [&_code]:[font:inherit]";
68532
+ function observeValueWrites(node, onWrite) {
68533
+ const own = Object.getOwnPropertyDescriptor(node, "value");
68534
+ const base = own ?? Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, "value");
68535
+ if (!base?.get || !base.set || own && !own.configurable) return () => {
68536
+ };
68537
+ const { get, set: set2 } = base;
68538
+ Object.defineProperty(node, "value", {
68539
+ configurable: true,
68540
+ enumerable: base.enumerable,
68541
+ get() {
68542
+ return get.call(this);
68543
+ },
68544
+ set(next) {
68545
+ set2.call(this, next);
68546
+ onWrite(get.call(this));
68547
+ }
68548
+ });
68549
+ const form = node.form;
68550
+ const handleReset = () => setTimeout(() => onWrite(node.value));
68551
+ form?.addEventListener("reset", handleReset);
68552
+ return () => {
68553
+ form?.removeEventListener("reset", handleReset);
68554
+ if (own) Object.defineProperty(node, "value", own);
68555
+ else delete node.value;
68556
+ };
68557
+ }
68558
+ function hasContent(node) {
68559
+ return node != null && node !== false && node !== "";
68560
+ }
68561
+ function toCssSize(size) {
68562
+ return typeof size === "number" ? `${size}px` : size;
68563
+ }
68564
+ var CodeEditor = React10.forwardRef(
68565
+ ({
68566
+ className,
68567
+ style,
68568
+ lang = "json",
68569
+ theme = "light",
68570
+ themes = DEFAULT_CODE_EDITOR_THEMES,
68571
+ hideHeader = false,
68572
+ fileName,
68573
+ icon,
68574
+ copyButton = true,
68575
+ formatButton,
68576
+ formatter,
68577
+ onFormatError,
68578
+ formatLabel = "Format",
68579
+ copyLabel,
68580
+ headerActions,
68581
+ label,
68582
+ required,
68583
+ hintContent,
68584
+ error,
68585
+ errorContent,
68586
+ minHeight,
68587
+ maxHeight,
68588
+ wrap = false,
68589
+ tabSize = 2,
68590
+ maxHighlightLength = 1e4,
68591
+ id,
68592
+ value: value2,
68593
+ defaultValue,
68594
+ onChange,
68595
+ onKeyDown,
68596
+ onBlur,
68597
+ onScroll,
68598
+ disabled,
68599
+ readOnly,
68600
+ "aria-describedby": ariaDescribedBy,
68601
+ ...textareaProps
68602
+ }, forwardedRef) => {
68603
+ const autoId = React10.useId();
68604
+ const textareaId = id || autoId;
68605
+ const errorId = `${textareaId}-error`;
68606
+ const hasError = error || !!errorContent;
68607
+ const isControlled = value2 !== void 0;
68608
+ const [innerValue, setInnerValue] = React10.useState(
68609
+ () => defaultValue == null ? "" : String(defaultValue)
68610
+ );
68611
+ const currentValue = isControlled ? String(value2 ?? "") : innerValue;
68612
+ const html = useHighlightedHtml(currentValue, {
68613
+ lang,
68614
+ theme,
68615
+ themes,
68616
+ maxHighlightLength
68617
+ });
68618
+ const keys = useCodeEditorKeys({ tabSize, onKeyDown, onBlur });
68619
+ const textareaRef = React10.useRef(null);
68620
+ const stopObservingRef = React10.useRef(void 0);
68621
+ const setTextareaRef = React10.useCallback(
68622
+ (node) => {
68623
+ textareaRef.current = node;
68624
+ stopObservingRef.current?.();
68625
+ stopObservingRef.current = void 0;
68626
+ if (node && !isControlled) {
68627
+ stopObservingRef.current = observeValueWrites(node, setInnerValue);
68628
+ setInnerValue(node.value);
68629
+ }
68630
+ if (typeof forwardedRef === "function") forwardedRef(node);
68631
+ else if (forwardedRef) forwardedRef.current = node;
68632
+ },
68633
+ [forwardedRef, isControlled]
68634
+ );
68635
+ const handleChange = (event) => {
68636
+ if (!isControlled) setInnerValue(event.target.value);
68637
+ onChange?.(event);
68638
+ };
68639
+ const handleScroll = (event) => {
68640
+ const el = event.currentTarget;
68641
+ if (el.scrollTop !== 0) el.scrollTop = 0;
68642
+ if (el.scrollLeft !== 0) el.scrollLeft = 0;
68643
+ onScroll?.(event);
68644
+ };
68645
+ const builtInFormatter = getBuiltInFormatter(lang);
68646
+ const format6 = formatter ?? (builtInFormatter && ((v) => builtInFormatter(v, tabSize)));
68647
+ const showFormatButton = formatButton !== false && format6 !== void 0;
68648
+ const handleFormat = () => {
68649
+ const el = textareaRef.current;
68650
+ if (!el || !format6) return;
68651
+ let formatted;
68652
+ try {
68653
+ formatted = format6(el.value);
68654
+ } catch (formatError) {
68655
+ onFormatError?.(formatError);
68656
+ return;
68657
+ }
68658
+ applyEdit(el, {
68659
+ start: 0,
68660
+ end: el.value.length,
68661
+ text: formatted,
68662
+ selectionStart: 0,
68663
+ selectionEnd: 0
68664
+ });
68665
+ };
68666
+ const describedBy = [ariaDescribedBy, errorContent ? errorId : void 0].filter(Boolean).join(" ") || void 0;
68667
+ const wrapClassName = wrap ? "whitespace-pre-wrap [overflow-wrap:anywhere]" : "whitespace-pre [overflow-wrap:normal]";
68668
+ const showHeader = !hideHeader && (hasContent(fileName) || copyButton || showFormatButton || hasContent(headerActions));
68669
+ const actions = hasContent(headerActions) || showFormatButton ? /* @__PURE__ */ jsxs(Fragment, { children: [
68670
+ headerActions,
68671
+ showFormatButton && /* @__PURE__ */ jsx(
68672
+ "button",
68673
+ {
68674
+ type: "button",
68675
+ "data-slot": "code-editor-format",
68676
+ "aria-label": formatLabel,
68677
+ title: formatLabel,
68678
+ disabled: disabled || readOnly || currentValue.trim() === "",
68679
+ onClick: handleFormat,
68680
+ className: cn(buttonVariants$1({ variant: "ghost", size: "sm" }), "w-auto h-auto p-2"),
68681
+ children: /* @__PURE__ */ jsx(Braces, {})
68682
+ }
68683
+ )
68684
+ ] }) : void 0;
68685
+ const editor = /* @__PURE__ */ jsxs(
68686
+ "div",
68687
+ {
68688
+ "data-slot": "code-editor",
68689
+ "data-disabled": disabled ? "" : void 0,
68690
+ className: cn(
68691
+ "relative flex flex-col overflow-hidden rounded-lg border bg-background ring-offset-background transition-[box-shadow,border-color] duration-200 ease-in-out",
68692
+ "has-[textarea:focus-visible]:ring-2 has-[textarea:focus-visible]:ring-ring has-[textarea:focus-visible]:ring-offset-2",
68693
+ hasError && "border-destructive has-[textarea:focus-visible]:ring-destructive",
68694
+ className
68695
+ ),
68696
+ style,
68697
+ children: [
68698
+ showHeader && /* @__PURE__ */ jsx(
68699
+ CodeHeader,
68700
+ {
68701
+ icon,
68702
+ fileName,
68703
+ actions,
68704
+ copyContent: copyButton ? currentValue : void 0,
68705
+ copyLabel
68706
+ }
68707
+ ),
68708
+ /* @__PURE__ */ jsx(
68709
+ "div",
68710
+ {
68711
+ className: cn(
68712
+ "relative min-h-0 flex-1 overflow-auto bg-accent/10",
68713
+ disabled && "cursor-not-allowed opacity-50"
68714
+ ),
68715
+ style: { maxHeight: toCssSize(maxHeight) },
68716
+ children: /* @__PURE__ */ jsxs(
68717
+ "div",
68718
+ {
68719
+ className: cn("grid", wrap ? "w-full grid-cols-[minmax(0,1fr)]" : "w-max min-w-full"),
68720
+ style: { minHeight: toCssSize(minHeight), tabSize },
68721
+ children: [
68722
+ /* @__PURE__ */ jsxs("div", { "aria-hidden": true, className: cn(layerClassName, wrapClassName, "invisible"), children: [
68723
+ currentValue,
68724
+ "\u200B"
68725
+ ] }),
68726
+ /* @__PURE__ */ jsx(
68727
+ "div",
68728
+ {
68729
+ "aria-hidden": true,
68730
+ className: cn(layerClassName, wrapClassName, highlightClassName, "pointer-events-none"),
68731
+ dangerouslySetInnerHTML: { __html: html }
68732
+ }
68733
+ ),
68734
+ /* @__PURE__ */ jsx(
68735
+ "textarea",
68736
+ {
68737
+ id: textareaId,
68738
+ ref: setTextareaRef,
68739
+ value: value2,
68740
+ defaultValue,
68741
+ disabled,
68742
+ readOnly,
68743
+ required,
68744
+ wrap: wrap ? "soft" : "off",
68745
+ spellCheck: false,
68746
+ autoCapitalize: "off",
68747
+ autoComplete: "off",
68748
+ autoCorrect: "off",
68749
+ translate: "no",
68750
+ "data-gramm": "false",
68751
+ "aria-invalid": hasError || void 0,
68752
+ "aria-describedby": describedBy,
68753
+ ...textareaProps,
68754
+ onChange: handleChange,
68755
+ onKeyDown: keys.onKeyDown,
68756
+ onBlur: keys.onBlur,
68757
+ onScroll: handleScroll,
68758
+ style: { tabSize },
68759
+ className: cn(
68760
+ layerClassName,
68761
+ wrapClassName,
68762
+ "relative z-10 h-full w-full resize-none overflow-hidden bg-transparent text-transparent caret-foreground outline-none [-webkit-text-fill-color:transparent]",
68763
+ "placeholder:text-muted-foreground placeholder:[-webkit-text-fill-color:var(--color-muted-foreground)] selection:bg-primary/20",
68764
+ "disabled:cursor-not-allowed read-only:cursor-default"
68765
+ )
68766
+ }
68767
+ )
68768
+ ]
68769
+ }
68770
+ )
68771
+ }
68772
+ )
68773
+ ]
68774
+ }
68775
+ );
68776
+ if (label == null && hintContent == null && errorContent == null) return editor;
68777
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2 flex-1", children: [
68778
+ label != null ? /* @__PURE__ */ jsx(
68779
+ FieldLabelRow,
68780
+ {
68781
+ htmlFor: textareaId,
68782
+ label,
68783
+ required,
68784
+ hintContent
68785
+ }
68786
+ ) : hintContent != null && /* @__PURE__ */ jsx("span", { className: fieldHintClassName, children: hintContent }),
68787
+ editor,
68788
+ errorContent != null && /* @__PURE__ */ jsx("div", { id: errorId, className: "text-sm text-destructive", children: errorContent })
68789
+ ] });
68790
+ }
68791
+ );
68792
+ CodeEditor.displayName = "CodeEditor";
68111
68793
  var maxWidthClasses = {
68112
68794
  sm: "max-w-2xl",
68113
68795
  md: "max-w-4xl",
@@ -68288,4 +68970,4 @@ lottie-react/build/index.es.js:
68288
68970
  (*! goToAndStop must be relative to the start of the current segment *)
68289
68971
  */
68290
68972
 
68291
- export { Accordion3 as Accordion, AdvancedSearchBox, Alert, AnimatedCard, AnimatedRainmakerLogo, AreaChart, AsyncCombobox, AsyncMultiSelect, BarChart, BasicDetailsCard, CHART_CATEGORY_COLORS, CHART_SERIES_COLORS, Calendar, CalendarDayButton, Carousel2 as Carousel, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox2 as Checkbox, CircularProgress, Code, CollapsibleCard, ComposedChart, ConfirmationDialog, ContentContainer, CopiableText, DEFAULT_CHART_SERIES_COLORS, DEFAULT_PAGE_SIZE_OPTIONS, DataTable, DatePicker, DateRangePicker, DateTimePicker, DeviceIcon, Dialog2 as Dialog, DialogClose2 as DialogClose, DialogContent2 as DialogContent, DialogDescription2 as DialogDescription, DialogFooter2 as DialogFooter, DialogHeader2 as DialogHeader, DialogTitle2 as DialogTitle, DialogTrigger2 as DialogTrigger, DonutChart, DynamicList, FileInput, FileUpload, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, FullSizeError, FullscreenDialog, IconAvatar, IconTextActionCard, Illustration, InlineError, InputOTP, InputOTPSeparator, KeyValueManager, LineChart, ListDetails, LottieAnimationContainer, MarkdownContent, MonospaceContent, NavBar, OverflowBadgeList, PRESET_IDS, PRESET_LABELS, PageContainer, PageContainerSkeleton, Pagination, PopCollectionItem, PreviewCard2 as PreviewCard, PreviewCardBackdrop2 as PreviewCardBackdrop, PreviewCardPanel, PreviewCardTrigger2 as PreviewCardTrigger, ProgressBar, RadioGroup3 as RadioGroup, RequirementList, ScrollableSections, SearchBox, SectionCard, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SelectableCardList, SimpleCard, SimpleClickableCard, SimpleInfoCard, SimpleList, SimplePaginatedList, SimplifiedDate, Spinner, StatCard, StatusBadge, StatusCardList, Switch2 as Switch, TYPOGRAPHY_VARIANTS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableSkeleton, Tabs2 as Tabs, TabsContent2 as TabsContent, TabsContents2 as TabsContents, TabsList2 as TabsList, TabsTrigger2 as TabsTrigger, Tag, TagInput, Textarea, TimePicker, Toast, Toaster, TogglableItemsList, ToggleGroup2 as ToggleGroup, ToggleGroupItem2 as ToggleGroupItem, TransferList, TreemapChart, Typography, UserTypeBadge, VerificationInProgress, VerticalStepper, animatedCardAnimations, animatedCardTypeKeys, buildSeriesChartConfig, computeDateRange, getChartSeriesColor, illustrationRegistry, illustrationsById, no_data_card_default, parseSvgViewBoxAspectRatio, statusBadgeSizeVariants, toast, typographyDefaultElement, typographyVariantClasses, useFormField, userTypeBadgeRegistry, userTypeBadgeSizeVariants, userTypeBadgeUserTypes };
68973
+ export { Accordion3 as Accordion, AdvancedSearchBox, Alert, AnimatedCard, AnimatedRainmakerLogo, AreaChart, AsyncCombobox, AsyncMultiSelect, BarChart, BasicDetailsCard, CHART_CATEGORY_COLORS, CHART_SERIES_COLORS, Calendar, CalendarDayButton, Carousel2 as Carousel, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox2 as Checkbox, CircularProgress, Code, CodeEditor, CollapsibleCard, ComposedChart, ConfirmationDialog, ContentContainer, CopiableText, DEFAULT_CHART_SERIES_COLORS, DEFAULT_PAGE_SIZE_OPTIONS, DataTable, DatePicker, DateRangePicker, DateTimePicker, DeviceIcon, Dialog2 as Dialog, DialogClose2 as DialogClose, DialogContent2 as DialogContent, DialogDescription2 as DialogDescription, DialogFooter2 as DialogFooter, DialogHeader2 as DialogHeader, DialogTitle2 as DialogTitle, DialogTrigger2 as DialogTrigger, DonutChart, DynamicList, FileInput, FileUpload, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, FullSizeError, FullscreenDialog, IconAvatar, IconTextActionCard, Illustration, InlineError, InputOTP, InputOTPSeparator, KeyValueManager, LineChart, ListDetails, LottieAnimationContainer, MarkdownContent, MonospaceContent, NavBar, OverflowBadgeList, PRESET_IDS, PRESET_LABELS, PageContainer, PageContainerSkeleton, Pagination, PopCollectionItem, PreviewCard2 as PreviewCard, PreviewCardBackdrop2 as PreviewCardBackdrop, PreviewCardPanel, PreviewCardTrigger2 as PreviewCardTrigger, ProgressBar, ROLLING_PRESET_IDS, RadioGroup3 as RadioGroup, RequirementList, ScrollableSections, SearchBox, SectionCard, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SelectableCardList, SimpleCard, SimpleClickableCard, SimpleInfoCard, SimpleList, SimplePaginatedList, SimplifiedDate, Spinner, StatCard, StatusBadge, StatusCardList, Switch2 as Switch, TYPOGRAPHY_VARIANTS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableSkeleton, Tabs2 as Tabs, TabsContent2 as TabsContent, TabsContents2 as TabsContents, TabsList2 as TabsList, TabsTrigger2 as TabsTrigger, Tag, TagInput, Textarea, TimePicker, Toast, Toaster, TogglableItemsList, ToggleGroup2 as ToggleGroup, ToggleGroupItem2 as ToggleGroupItem, TransferList, TreemapChart, Typography, UserTypeBadge, VerificationInProgress, VerticalStepper, animatedCardAnimations, animatedCardTypeKeys, buildSeriesChartConfig, computeDateRange, getChartSeriesColor, illustrationRegistry, illustrationsById, no_data_card_default, parseSvgViewBoxAspectRatio, statusBadgeSizeVariants, toast, typographyDefaultElement, typographyVariantClasses, useFormField, userTypeBadgeRegistry, userTypeBadgeSizeVariants, userTypeBadgeUserTypes };