@particle-academy/react-fancy 4.4.7 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3077,6 +3077,44 @@ function InputWrapper({
3077
3077
  hasInsideSuffix && /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute right-3 z-10 text-zinc-400 dark:text-zinc-500", children: suffix })
3078
3078
  ] });
3079
3079
  }
3080
+ var FieldModeContext = createContext(null);
3081
+ function useFieldMode(explicit) {
3082
+ const ctx = useContext(FieldModeContext);
3083
+ return explicit ?? ctx?.mode ?? "edit";
3084
+ }
3085
+ function isEmpty(value) {
3086
+ return value === null || value === void 0 || value === "";
3087
+ }
3088
+ function DisplayValue({
3089
+ children,
3090
+ size = "md",
3091
+ leading,
3092
+ trailing,
3093
+ empty = "\u2014",
3094
+ className
3095
+ }) {
3096
+ const empties = isEmpty(children);
3097
+ return /* @__PURE__ */ jsxs(
3098
+ "div",
3099
+ {
3100
+ "data-react-fancy-display": "",
3101
+ "data-mode": "view",
3102
+ className: cn(
3103
+ "flex w-full items-center gap-2 text-zinc-900 dark:text-zinc-100",
3104
+ inputSizeClasses[size],
3105
+ // Strip the editable box look — keep only the size/padding rhythm.
3106
+ "border-0 bg-transparent px-0",
3107
+ empties && "text-zinc-400 dark:text-zinc-500",
3108
+ className
3109
+ ),
3110
+ children: [
3111
+ leading && /* @__PURE__ */ jsx("span", { className: "text-zinc-400 dark:text-zinc-500", children: leading }),
3112
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: empties ? empty : children }),
3113
+ trailing && /* @__PURE__ */ jsx("span", { className: "text-zinc-400 dark:text-zinc-500", children: trailing })
3114
+ ]
3115
+ }
3116
+ );
3117
+ }
3080
3118
  var Input = forwardRef(
3081
3119
  ({
3082
3120
  type = "text",
@@ -3095,13 +3133,15 @@ var Input = forwardRef(
3095
3133
  suffix,
3096
3134
  prefixPosition,
3097
3135
  suffixPosition,
3136
+ mode,
3098
3137
  onValueChange,
3099
3138
  onChange,
3100
3139
  ...props
3101
3140
  }, ref) => {
3102
3141
  const autoId = useId();
3103
3142
  const inputId = id ?? autoId;
3104
- const input = /* @__PURE__ */ jsx(
3143
+ const resolvedMode = useFieldMode(mode);
3144
+ const input = resolvedMode === "view" ? /* @__PURE__ */ jsx(DisplayValue, { size, leading: leading ?? prefix, trailing: trailing ?? suffix, children: type === "password" ? props.value ? "\u2022\u2022\u2022\u2022\u2022\u2022" : "" : props.value }) : /* @__PURE__ */ jsx(
3105
3145
  InputWrapper,
3106
3146
  {
3107
3147
  prefix,
@@ -3176,6 +3216,7 @@ var Textarea = forwardRef(
3176
3216
  suffix,
3177
3217
  prefixPosition: _prefixPosition,
3178
3218
  suffixPosition: _suffixPosition,
3219
+ mode,
3179
3220
  onValueChange,
3180
3221
  onChange,
3181
3222
  value,
@@ -3185,6 +3226,7 @@ var Textarea = forwardRef(
3185
3226
  const autoId = useId();
3186
3227
  const textareaId = id ?? autoId;
3187
3228
  const internalRef = useRef(null);
3229
+ const resolvedMode = useFieldMode(mode);
3188
3230
  useEffect(() => {
3189
3231
  const el = internalRef.current;
3190
3232
  if (!autoResize || !el) return;
@@ -3194,7 +3236,7 @@ var Textarea = forwardRef(
3194
3236
  const maxHeight = maxRows ? maxRows * lineHeight : Infinity;
3195
3237
  el.style.height = `${Math.min(Math.max(el.scrollHeight, minHeight), maxHeight)}px`;
3196
3238
  }, [autoResize, minRows, maxRows, value, defaultValue]);
3197
- const textarea = /* @__PURE__ */ jsx(
3239
+ const textarea = resolvedMode === "view" ? /* @__PURE__ */ jsx(DisplayValue, { size, className: "whitespace-pre-wrap", children: value ?? defaultValue }) : /* @__PURE__ */ jsx(
3198
3240
  InputWrapper,
3199
3241
  {
3200
3242
  prefix,
@@ -3466,6 +3508,7 @@ var NativeSelect = forwardRef(
3466
3508
  suffix,
3467
3509
  prefixPosition,
3468
3510
  suffixPosition,
3511
+ mode,
3469
3512
  onValueChange,
3470
3513
  onChange,
3471
3514
  value,
@@ -3474,6 +3517,27 @@ var NativeSelect = forwardRef(
3474
3517
  }, ref) => {
3475
3518
  const autoId = useId();
3476
3519
  const selectId = id ?? autoId;
3520
+ const resolvedMode = useFieldMode(mode);
3521
+ if (resolvedMode === "view") {
3522
+ const current = value ?? defaultValue;
3523
+ const opt = flattenOptions(list).map((o) => resolveOption(o)).find((o) => o.value === current);
3524
+ const display = /* @__PURE__ */ jsx(DisplayValue, { size, leading: prefix, trailing: suffix, children: opt?.label ?? current });
3525
+ if (label || error || description) {
3526
+ return /* @__PURE__ */ jsx(
3527
+ Field,
3528
+ {
3529
+ label,
3530
+ description,
3531
+ error,
3532
+ required,
3533
+ htmlFor: selectId,
3534
+ size,
3535
+ children: display
3536
+ }
3537
+ );
3538
+ }
3539
+ return display;
3540
+ }
3477
3541
  const isControlled = value !== void 0;
3478
3542
  const resolvedDefault = !isControlled && defaultValue === void 0 && placeholder ? "" : defaultValue;
3479
3543
  const select = /* @__PURE__ */ jsx(
@@ -3562,11 +3626,13 @@ var ListboxSelect = forwardRef(
3562
3626
  createLabel = "Create",
3563
3627
  selectedSuffix = "selected",
3564
3628
  indicator = "check",
3629
+ mode,
3565
3630
  value: controlledSingleValue,
3566
3631
  defaultValue: defaultSingleValue
3567
3632
  }, _ref) => {
3568
3633
  const autoId = useId();
3569
3634
  const selectId = id ?? autoId;
3635
+ const resolvedMode = useFieldMode(mode);
3570
3636
  const textInputEnabled = searchable || creatable;
3571
3637
  const [open, setOpen] = useState(false);
3572
3638
  const [search2, setSearch] = useState("");
@@ -3693,6 +3759,27 @@ var ListboxSelect = forwardRef(
3693
3759
  }
3694
3760
  }
3695
3761
  };
3762
+ if (resolvedMode === "view") {
3763
+ const labels = multiple ? currentMulti.map(
3764
+ (v) => resolvedOptions.find((o) => o.value === v)?.label ?? v
3765
+ ) : currentSingle ? [resolvedOptions.find((o) => o.value === currentSingle)?.label ?? currentSingle] : [];
3766
+ const display = /* @__PURE__ */ jsx(DisplayValue, { size, children: labels.join(", ") });
3767
+ if (label || error || description) {
3768
+ return /* @__PURE__ */ jsx(
3769
+ Field,
3770
+ {
3771
+ label,
3772
+ description,
3773
+ error,
3774
+ required,
3775
+ htmlFor: selectId,
3776
+ size,
3777
+ children: display
3778
+ }
3779
+ );
3780
+ }
3781
+ return display;
3782
+ }
3696
3783
  const trigger = /* @__PURE__ */ jsxs(
3697
3784
  "button",
3698
3785
  {
@@ -3868,11 +3955,13 @@ var Checkbox = forwardRef(
3868
3955
  checked: controlledChecked,
3869
3956
  defaultChecked = false,
3870
3957
  onCheckedChange,
3871
- indeterminate
3958
+ indeterminate,
3959
+ mode
3872
3960
  }, ref) => {
3873
3961
  const autoId = useId();
3874
3962
  const checkboxId = id ?? autoId;
3875
3963
  const internalRef = useRef(null);
3964
+ const resolvedMode = useFieldMode(mode);
3876
3965
  const [checked, setChecked] = useControllableState(
3877
3966
  controlledChecked,
3878
3967
  defaultChecked,
@@ -3891,8 +3980,21 @@ var Checkbox = forwardRef(
3891
3980
  lg: "h-5 w-5",
3892
3981
  xl: "h-6 w-6"
3893
3982
  }[size];
3983
+ const glyph = indeterminate ? "\u2014" : checked ? "\u2713" : "\u2715";
3894
3984
  return /* @__PURE__ */ jsxs("div", { "data-react-fancy-checkbox": "", className: cn("flex items-start gap-2", className), children: [
3895
- /* @__PURE__ */ jsx("div", { className: "relative flex items-center", children: /* @__PURE__ */ jsx(
3985
+ resolvedMode === "view" ? /* @__PURE__ */ jsx(
3986
+ "span",
3987
+ {
3988
+ "data-react-fancy-display": "",
3989
+ "data-mode": "view",
3990
+ className: cn(
3991
+ "flex shrink-0 items-center justify-center text-zinc-700 dark:text-zinc-200",
3992
+ sizeClasses6
3993
+ ),
3994
+ "aria-hidden": "true",
3995
+ children: glyph
3996
+ }
3997
+ ) : /* @__PURE__ */ jsx("div", { className: "relative flex items-center", children: /* @__PURE__ */ jsx(
3896
3998
  "input",
3897
3999
  {
3898
4000
  ref: (node) => {
@@ -3954,9 +4056,11 @@ function CheckboxGroup({
3954
4056
  value: controlledValue,
3955
4057
  defaultValue = [],
3956
4058
  onValueChange,
3957
- orientation = "vertical"
4059
+ orientation = "vertical",
4060
+ mode
3958
4061
  }) {
3959
4062
  const groupId = useId();
4063
+ const resolvedMode = useFieldMode(mode);
3960
4064
  const [value, setValue] = useControllableState(
3961
4065
  controlledValue,
3962
4066
  defaultValue,
@@ -3973,7 +4077,7 @@ function CheckboxGroup({
3973
4077
  lg: "h-5 w-5",
3974
4078
  xl: "h-6 w-6"
3975
4079
  }[size];
3976
- const content = /* @__PURE__ */ jsx(
4080
+ const content = resolvedMode === "view" ? /* @__PURE__ */ jsx(DisplayValue, { size, children: list.map(resolveOption).filter((o) => value.includes(o.value)).map((o) => o.label).join(", ") }) : /* @__PURE__ */ jsx(
3977
4081
  "div",
3978
4082
  {
3979
4083
  "data-react-fancy-checkbox-group": "",
@@ -4053,10 +4157,12 @@ function RadioGroup({
4053
4157
  value: controlledValue,
4054
4158
  defaultValue,
4055
4159
  onValueChange,
4056
- orientation = "vertical"
4160
+ orientation = "vertical",
4161
+ mode
4057
4162
  }) {
4058
4163
  const groupId = useId();
4059
4164
  const radioName = name ?? groupId;
4165
+ const resolvedMode = useFieldMode(mode);
4060
4166
  const [value, setValue] = useControllableState(
4061
4167
  controlledValue,
4062
4168
  defaultValue,
@@ -4069,7 +4175,7 @@ function RadioGroup({
4069
4175
  lg: "h-5 w-5",
4070
4176
  xl: "h-6 w-6"
4071
4177
  }[size];
4072
- const content = /* @__PURE__ */ jsx(
4178
+ const content = resolvedMode === "view" ? /* @__PURE__ */ jsx(DisplayValue, { size, children: list.map(resolveOption).find((o) => o.value === value)?.label }) : /* @__PURE__ */ jsx(
4073
4179
  "div",
4074
4180
  {
4075
4181
  "data-react-fancy-radio-group": "",
@@ -4177,10 +4283,12 @@ var Switch = forwardRef(
4177
4283
  checked: controlledChecked,
4178
4284
  defaultChecked = false,
4179
4285
  onCheckedChange,
4180
- color = "blue"
4286
+ color = "blue",
4287
+ mode
4181
4288
  }, ref) => {
4182
4289
  const autoId = useId();
4183
4290
  const switchId = id ?? autoId;
4291
+ const resolvedMode = useFieldMode(mode);
4184
4292
  const [checked, setChecked] = useControllableState(
4185
4293
  controlledChecked,
4186
4294
  defaultChecked,
@@ -4208,7 +4316,15 @@ var Switch = forwardRef(
4208
4316
  xl: "translate-x-6"
4209
4317
  }[size];
4210
4318
  return /* @__PURE__ */ jsxs("div", { "data-react-fancy-switch": "", className: cn("flex items-start gap-2", className), children: [
4211
- /* @__PURE__ */ jsx(
4319
+ resolvedMode === "view" ? /* @__PURE__ */ jsx(
4320
+ "span",
4321
+ {
4322
+ "data-react-fancy-display": "",
4323
+ "data-mode": "view",
4324
+ className: "text-sm font-medium text-zinc-700 dark:text-zinc-200",
4325
+ children: checked ? "On" : "Off"
4326
+ }
4327
+ ) : /* @__PURE__ */ jsx(
4212
4328
  "button",
4213
4329
  {
4214
4330
  ref,
@@ -4322,15 +4438,17 @@ var SingleSlider = forwardRef(
4322
4438
  marks,
4323
4439
  prefix,
4324
4440
  suffix,
4441
+ mode,
4325
4442
  ...rest
4326
4443
  }, ref) => {
4327
4444
  const singleProps = rest;
4445
+ const resolvedMode = useFieldMode(mode);
4328
4446
  const [value, setValue] = useControllableState(
4329
4447
  singleProps.value,
4330
4448
  singleProps.defaultValue ?? min,
4331
4449
  singleProps.onValueChange
4332
4450
  );
4333
- const slider = /* @__PURE__ */ jsxs("div", { "data-react-fancy-slider": "", className: cn("flex flex-col gap-1", className), children: [
4451
+ const slider = resolvedMode === "view" ? /* @__PURE__ */ jsx(DisplayValue, { size, className, children: `${prefix ?? ""}${value}${suffix ?? ""}` }) : /* @__PURE__ */ jsxs("div", { "data-react-fancy-slider": "", className: cn("flex flex-col gap-1", className), children: [
4334
4452
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
4335
4453
  /* @__PURE__ */ jsx(
4336
4454
  "input",
@@ -4392,9 +4510,11 @@ var RangeSlider = forwardRef(
4392
4510
  marks,
4393
4511
  prefix,
4394
4512
  suffix,
4513
+ mode,
4395
4514
  ...rest
4396
4515
  }, ref) => {
4397
4516
  const rangeProps = rest;
4517
+ const resolvedMode = useFieldMode(mode);
4398
4518
  const [value, setValue] = useControllableState(
4399
4519
  rangeProps.value,
4400
4520
  rangeProps.defaultValue ?? [min, max],
@@ -4408,7 +4528,7 @@ var RangeSlider = forwardRef(
4408
4528
  };
4409
4529
  const leftPercent = (value[0] - min) / (max - min) * 100;
4410
4530
  const rightPercent = (value[1] - min) / (max - min) * 100;
4411
- const slider = /* @__PURE__ */ jsxs("div", { "data-react-fancy-slider": "", className: cn("flex flex-col gap-1", className), children: [
4531
+ const slider = resolvedMode === "view" ? /* @__PURE__ */ jsx(DisplayValue, { size, className, children: `${prefix ?? ""}${value[0]}${suffix ?? ""}\u2013${prefix ?? ""}${value[1]}${suffix ?? ""}` }) : /* @__PURE__ */ jsxs("div", { "data-react-fancy-slider": "", className: cn("flex flex-col gap-1", className), children: [
4412
4532
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
4413
4533
  /* @__PURE__ */ jsxs("div", { className: "relative w-full", children: [
4414
4534
  /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute top-1/2 h-1.5 w-full -translate-y-1/2 rounded-full bg-zinc-200 dark:bg-zinc-700" }),
@@ -4510,10 +4630,12 @@ function MultiSwitch({
4510
4630
  value: controlledValue,
4511
4631
  defaultValue,
4512
4632
  onValueChange,
4513
- linear
4633
+ linear,
4634
+ mode
4514
4635
  }) {
4515
4636
  const resolvedOptions = list.map(resolveOption);
4516
4637
  const fallback = defaultValue ?? resolvedOptions[0]?.value;
4638
+ const resolvedMode = useFieldMode(mode);
4517
4639
  const [value, setValue] = useControllableState(controlledValue, fallback, onValueChange);
4518
4640
  const containerRef = useRef(null);
4519
4641
  const itemRefs = useRef([]);
@@ -4538,7 +4660,7 @@ function MultiSwitch({
4538
4660
  useEffect(() => {
4539
4661
  updateIndicator();
4540
4662
  }, [updateIndicator]);
4541
- const control = /* @__PURE__ */ jsxs(
4663
+ const control = resolvedMode === "view" ? /* @__PURE__ */ jsx(DisplayValue, { size, children: resolvedOptions.find((o) => o.value === value)?.label }) : /* @__PURE__ */ jsxs(
4542
4664
  "div",
4543
4665
  {
4544
4666
  ref: containerRef,
@@ -4601,6 +4723,22 @@ function MultiSwitch({
4601
4723
  return control;
4602
4724
  }
4603
4725
  MultiSwitch.displayName = "MultiSwitch";
4726
+ function formatDateValue(iso, includeTime) {
4727
+ if (!iso) return "";
4728
+ const date = new Date(iso);
4729
+ if (Number.isNaN(date.getTime())) return iso;
4730
+ return includeTime ? date.toLocaleString(void 0, {
4731
+ year: "numeric",
4732
+ month: "short",
4733
+ day: "numeric",
4734
+ hour: "2-digit",
4735
+ minute: "2-digit"
4736
+ }) : date.toLocaleDateString(void 0, {
4737
+ year: "numeric",
4738
+ month: "short",
4739
+ day: "numeric"
4740
+ });
4741
+ }
4604
4742
  var DatePicker = forwardRef(
4605
4743
  (props, ref) => {
4606
4744
  const {
@@ -4667,17 +4805,20 @@ var SingleDatePicker = forwardRef(
4667
4805
  name,
4668
4806
  min,
4669
4807
  max,
4808
+ includeTime,
4809
+ mode,
4670
4810
  inputType,
4671
4811
  inputClasses,
4672
4812
  ...rest
4673
4813
  }, ref) => {
4674
4814
  const singleProps = rest;
4815
+ const resolvedMode = useFieldMode(mode);
4675
4816
  const [value, setValue] = useControllableState(
4676
4817
  singleProps.value,
4677
4818
  singleProps.defaultValue ?? "",
4678
4819
  singleProps.onValueChange
4679
4820
  );
4680
- const input = /* @__PURE__ */ jsx(
4821
+ const input = resolvedMode === "view" ? /* @__PURE__ */ jsx(DisplayValue, { size, className, children: formatDateValue(value, includeTime) }) : /* @__PURE__ */ jsx(
4681
4822
  "input",
4682
4823
  {
4683
4824
  "data-react-fancy-date-picker": "",
@@ -4725,17 +4866,20 @@ var RangeDatePicker = forwardRef(
4725
4866
  name,
4726
4867
  min,
4727
4868
  max,
4869
+ includeTime,
4870
+ mode,
4728
4871
  inputType,
4729
4872
  inputClasses,
4730
4873
  ...rest
4731
4874
  }, ref) => {
4732
4875
  const rangeProps = rest;
4876
+ const resolvedMode = useFieldMode(mode);
4733
4877
  const [value, setValue] = useControllableState(
4734
4878
  rangeProps.value,
4735
4879
  rangeProps.defaultValue ?? ["", ""],
4736
4880
  rangeProps.onValueChange
4737
4881
  );
4738
- const input = /* @__PURE__ */ jsxs("div", { "data-react-fancy-date-picker": "", className: cn("flex items-center gap-2", className), children: [
4882
+ const input = resolvedMode === "view" ? /* @__PURE__ */ jsx(DisplayValue, { size, className, children: value[0] || value[1] ? `${formatDateValue(value[0], includeTime)} \u2013 ${formatDateValue(value[1], includeTime)}` : "" }) : /* @__PURE__ */ jsxs("div", { "data-react-fancy-date-picker": "", className: cn("flex items-center gap-2", className), children: [
4739
4883
  /* @__PURE__ */ jsx(
4740
4884
  "input",
4741
4885
  {
@@ -4785,6 +4929,13 @@ var RangeDatePicker = forwardRef(
4785
4929
  }
4786
4930
  );
4787
4931
  RangeDatePicker.displayName = "RangeDatePicker";
4932
+ function FormProvider({ mode = "edit", children }) {
4933
+ const value = useMemo(() => ({ mode }), [mode]);
4934
+ return /* @__PURE__ */ jsx(FieldModeContext.Provider, { value, children });
4935
+ }
4936
+ function Form({ mode, children, ...formProps }) {
4937
+ return /* @__PURE__ */ jsx(FormProvider, { mode, children: /* @__PURE__ */ jsx("form", { "data-react-fancy-form": "", ...formProps, children }) });
4938
+ }
4788
4939
  var CarouselContext = createContext(null);
4789
4940
  CarouselContext.displayName = "CarouselContext";
4790
4941
  function useCarousel() {
@@ -5124,13 +5275,15 @@ var ColorPicker = forwardRef(
5124
5275
  size = "md",
5125
5276
  variant = "outline",
5126
5277
  disabled = false,
5127
- className
5278
+ className,
5279
+ mode
5128
5280
  }, ref) => {
5129
5281
  const [color, setColor] = useControllableState(
5130
5282
  value,
5131
5283
  defaultValue,
5132
5284
  onChange
5133
5285
  );
5286
+ const resolvedMode = useFieldMode(mode);
5134
5287
  const inputRef = useRef(null);
5135
5288
  const datalistId = useId();
5136
5289
  const handleChange = (e) => {
@@ -5141,6 +5294,42 @@ var ColorPicker = forwardRef(
5141
5294
  inputRef.current?.click();
5142
5295
  }
5143
5296
  };
5297
+ if (resolvedMode === "view") {
5298
+ return /* @__PURE__ */ jsxs(
5299
+ "div",
5300
+ {
5301
+ ref,
5302
+ "data-react-fancy-color-picker": "",
5303
+ "data-mode": "view",
5304
+ className: cn("inline-flex items-center gap-2", className),
5305
+ children: [
5306
+ /* @__PURE__ */ jsx(
5307
+ "span",
5308
+ {
5309
+ className: cn(
5310
+ "shrink-0 rounded-full",
5311
+ SWATCH_SIZES[size],
5312
+ variant === "outline" && "ring-1 ring-zinc-300 dark:ring-zinc-600"
5313
+ ),
5314
+ style: { backgroundColor: color },
5315
+ "aria-label": `Color: ${color}`
5316
+ }
5317
+ ),
5318
+ /* @__PURE__ */ jsx(
5319
+ "span",
5320
+ {
5321
+ className: cn(
5322
+ "select-all font-mono uppercase",
5323
+ TEXT_SIZES[size],
5324
+ "text-zinc-700 dark:text-zinc-300"
5325
+ ),
5326
+ children: color.toUpperCase()
5327
+ }
5328
+ )
5329
+ ]
5330
+ }
5331
+ );
5332
+ }
5144
5333
  return /* @__PURE__ */ jsxs(
5145
5334
  "div",
5146
5335
  {
@@ -6030,6 +6219,14 @@ var Badge = forwardRef(
6030
6219
  }
6031
6220
  );
6032
6221
  Badge.displayName = "Badge";
6222
+ var glowColors = {
6223
+ on: "#a855f7",
6224
+ // violet — neutral
6225
+ xp: "#22c55e",
6226
+ // green
6227
+ achievement: "#f59e0b"
6228
+ // amber
6229
+ };
6033
6230
  var containerSizeClasses = {
6034
6231
  xs: "h-6 w-6",
6035
6232
  sm: "h-8 w-8",
@@ -6064,8 +6261,10 @@ var Avatar = forwardRef(
6064
6261
  fallback,
6065
6262
  size = "md",
6066
6263
  status,
6264
+ glow,
6067
6265
  className
6068
6266
  }, ref) => {
6267
+ const glowKey = glow === true ? "on" : glow || null;
6069
6268
  return /* @__PURE__ */ jsxs(
6070
6269
  "div",
6071
6270
  {
@@ -6078,6 +6277,15 @@ var Avatar = forwardRef(
6078
6277
  className
6079
6278
  ),
6080
6279
  children: [
6280
+ glowKey && /* @__PURE__ */ jsx(
6281
+ "span",
6282
+ {
6283
+ "aria-hidden": true,
6284
+ "data-react-fancy-avatar-glow": glowKey,
6285
+ className: "fancy-avatar-glow",
6286
+ style: { "--fancy-glow": glowColors[glowKey] }
6287
+ }
6288
+ ),
6081
6289
  src ? /* @__PURE__ */ jsx(
6082
6290
  "img",
6083
6291
  {
@@ -8868,13 +9076,15 @@ var Autocomplete = forwardRef(
8868
9076
  loading = false,
8869
9077
  emptyMessage = "No results found.",
8870
9078
  disabled = false,
8871
- className
9079
+ className,
9080
+ mode
8872
9081
  }, ref) {
8873
9082
  const [value, setValue] = useControllableState(
8874
9083
  controlledValue,
8875
9084
  defaultValue,
8876
9085
  onChange
8877
9086
  );
9087
+ const resolvedMode = useFieldMode(mode);
8878
9088
  const [query, setQuery] = useState(value);
8879
9089
  const [open, setOpen] = useState(false);
8880
9090
  const [activeIndex, setActiveIndex] = useState(-1);
@@ -8927,6 +9137,23 @@ var Autocomplete = forwardRef(
8927
9137
  if (item && !item.disabled) select(item.value);
8928
9138
  }
8929
9139
  };
9140
+ if (resolvedMode === "view") {
9141
+ const matched = options.find((o) => o.value === value);
9142
+ return /* @__PURE__ */ jsx(
9143
+ "div",
9144
+ {
9145
+ "data-react-fancy-autocomplete": "",
9146
+ "data-mode": "view",
9147
+ ref: wrapperRef,
9148
+ className: cn(
9149
+ "text-sm text-zinc-900 dark:text-zinc-100",
9150
+ !value && "text-zinc-400 dark:text-zinc-500",
9151
+ className
9152
+ ),
9153
+ children: matched?.label ?? value ?? "\u2014"
9154
+ }
9155
+ );
9156
+ }
8930
9157
  return /* @__PURE__ */ jsxs("div", { "data-react-fancy-autocomplete": "", ref: wrapperRef, className: cn("relative", className), children: [
8931
9158
  /* @__PURE__ */ jsx(
8932
9159
  "input",
@@ -9099,13 +9326,15 @@ var OtpInput = forwardRef(
9099
9326
  onChange,
9100
9327
  disabled = false,
9101
9328
  autoFocus = false,
9102
- className
9329
+ className,
9330
+ mode
9103
9331
  }, ref) {
9104
9332
  const [value, setValue] = useControllableState(
9105
9333
  controlledValue,
9106
9334
  "",
9107
9335
  onChange
9108
9336
  );
9337
+ const resolvedMode = useFieldMode(mode);
9109
9338
  const inputsRef = useRef([]);
9110
9339
  const focusInput = useCallback(
9111
9340
  (index) => {
@@ -9159,6 +9388,21 @@ var OtpInput = forwardRef(
9159
9388
  },
9160
9389
  [length, setValue, focusInput]
9161
9390
  );
9391
+ if (resolvedMode === "view") {
9392
+ return /* @__PURE__ */ jsx(
9393
+ "div",
9394
+ {
9395
+ "data-react-fancy-otp-input": "",
9396
+ "data-mode": "view",
9397
+ ref,
9398
+ className: cn(
9399
+ "font-mono text-lg tracking-[0.4em] text-zinc-900 dark:text-zinc-100",
9400
+ className
9401
+ ),
9402
+ children: value || "\u2014"
9403
+ }
9404
+ );
9405
+ }
9162
9406
  return /* @__PURE__ */ jsx("div", { "data-react-fancy-otp-input": "", ref, className: cn("flex gap-2", className), children: Array.from({ length }, (_, i) => /* @__PURE__ */ jsx(
9163
9407
  "input",
9164
9408
  {
@@ -9373,16 +9617,34 @@ var TimePicker = forwardRef(
9373
9617
  format = "12h",
9374
9618
  minuteStep = 1,
9375
9619
  disabled = false,
9376
- className
9620
+ className,
9621
+ mode
9377
9622
  }, ref) {
9378
9623
  const [value, setValue] = useControllableState(
9379
9624
  controlledValue,
9380
9625
  defaultValue,
9381
9626
  onChange
9382
9627
  );
9628
+ const resolvedMode = useFieldMode(mode);
9383
9629
  const { hours: h24, minutes } = parseTime(value);
9384
9630
  const isPM = h24 >= 12;
9385
9631
  const displayHour = format === "12h" ? h24 % 12 || 12 : h24;
9632
+ if (resolvedMode === "view") {
9633
+ const formatted = format === "12h" ? `${pad(displayHour)}:${pad(minutes)} ${isPM ? "PM" : "AM"}` : `${pad(displayHour)}:${pad(minutes)}`;
9634
+ return /* @__PURE__ */ jsx(
9635
+ "div",
9636
+ {
9637
+ "data-react-fancy-time-picker": "",
9638
+ "data-mode": "view",
9639
+ ref,
9640
+ className: cn(
9641
+ "text-sm font-medium tabular-nums text-zinc-900 dark:text-zinc-100",
9642
+ className
9643
+ ),
9644
+ children: formatted
9645
+ }
9646
+ );
9647
+ }
9386
9648
  const updateTime = useCallback(
9387
9649
  (hours, mins) => {
9388
9650
  setValue(`${pad(hours)}:${pad(mins)}`);
@@ -13702,6 +13964,6 @@ function caretRect(ta, start, end) {
13702
13964
  return { x, y };
13703
13965
  }
13704
13966
 
13705
- export { Accordion, AccordionPanel, AccordionPanelContent, AccordionPanelSection, AccordionPanelTrigger, Action, Autocomplete, Avatar, Badge, Brand, Breadcrumbs, Button, Calendar, Callout, Card, Carousel, Chart, ChatDrawer, Checkbox, CheckboxGroup, ColorPicker, Command, Composer, ContentRenderer, ContextMenu, DatePicker, Dropdown, EMOJI_CATEGORY_ORDER, EMOJI_DATA, EMOJI_ENTRIES, Editor, Emoji, EmojiSelect, FauxClient, Field, FileUpload, Heading, Icon, Input, InputTag, Kanban, MagicWand, Menu2 as Menu, MobileMenu, Modal, MoodMeter, MultiSwitch, Navbar, OtpInput, Pagination, Pillbox, Popover, Portal, Profile, Progress, PromptInput, RadioGroup, ReasonTag, SKIN_TONES, Select, Separator, Sidebar, Skeleton, Slider, StickyNote, Switch, Table, Tabs, Text, Textarea, TimeGrid, TimePicker, Timeline, Toast, Tooltip, TreeNav, applyTone, cn, configureIcons, contentEditableAdapter, controlledAdapter, find, hasSkinTones, inputAdapter, registerExtension, registerExtensions, registerIconSet, registerIcons, resolve, sanitizeHref, sanitizeHtml, search, skinTones, textareaAdapter, useAccordion, useAccordionPanel, useAccordionSection, useAnimation, useCarousel, useCommand, useContextMenu, useControllableState, useDropdown, useEditor, useEscapeKey, useFileUpload, useFloatingPosition, useFocusTrap, useId12 as useId, useKanban, useMenu, useMobileMenu, useModal, useNavbar, useNodeRegistry, useOutsideClick, usePanZoom, usePopover, useSidebar, useTabs, useToast, useTreeNav };
13967
+ export { Accordion, AccordionPanel, AccordionPanelContent, AccordionPanelSection, AccordionPanelTrigger, Action, Autocomplete, Avatar, Badge, Brand, Breadcrumbs, Button, Calendar, Callout, Card, Carousel, Chart, ChatDrawer, Checkbox, CheckboxGroup, ColorPicker, Command, Composer, ContentRenderer, ContextMenu, DatePicker, DisplayValue, Dropdown, EMOJI_CATEGORY_ORDER, EMOJI_DATA, EMOJI_ENTRIES, Editor, Emoji, EmojiSelect, FauxClient, Field, FieldModeContext, FileUpload, Form, FormProvider, Heading, Icon, Input, InputTag, Kanban, MagicWand, Menu2 as Menu, MobileMenu, Modal, MoodMeter, MultiSwitch, Navbar, OtpInput, Pagination, Pillbox, Popover, Portal, Profile, Progress, PromptInput, RadioGroup, ReasonTag, SKIN_TONES, Select, Separator, Sidebar, Skeleton, Slider, StickyNote, Switch, Table, Tabs, Text, Textarea, TimeGrid, TimePicker, Timeline, Toast, Tooltip, TreeNav, applyTone, cn, configureIcons, contentEditableAdapter, controlledAdapter, find, hasSkinTones, inputAdapter, registerExtension, registerExtensions, registerIconSet, registerIcons, resolve, sanitizeHref, sanitizeHtml, search, skinTones, textareaAdapter, useAccordion, useAccordionPanel, useAccordionSection, useAnimation, useCarousel, useCommand, useContextMenu, useControllableState, useDropdown, useEditor, useEscapeKey, useFieldMode, useFileUpload, useFloatingPosition, useFocusTrap, useId12 as useId, useKanban, useMenu, useMobileMenu, useModal, useNavbar, useNodeRegistry, useOutsideClick, usePanZoom, usePopover, useSidebar, useTabs, useToast, useTreeNav };
13706
13968
  //# sourceMappingURL=index.js.map
13707
13969
  //# sourceMappingURL=index.js.map