@particle-academy/react-fancy 4.4.6 → 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.cjs +303 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +96 -5
- package/dist/index.d.ts +96 -5
- package/dist/index.js +299 -22
- package/dist/index.js.map +1 -1
- package/dist/styles.css +27 -0
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2569,7 +2569,22 @@ var Button = react.forwardRef(
|
|
|
2569
2569
|
trailingElements
|
|
2570
2570
|
] });
|
|
2571
2571
|
const safeHref = sanitizeHref(href);
|
|
2572
|
-
const buttonEl = safeHref && !disabled ?
|
|
2572
|
+
const buttonEl = safeHref && !disabled ? (
|
|
2573
|
+
// Anchor mode forwards the same rest props as the <button> branch so
|
|
2574
|
+
// onClick / target / rel / ref / ARIA / data-* reach the <a> (issue #7).
|
|
2575
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2576
|
+
"a",
|
|
2577
|
+
{
|
|
2578
|
+
ref,
|
|
2579
|
+
href: safeHref,
|
|
2580
|
+
className: classes,
|
|
2581
|
+
"data-react-fancy-button": "",
|
|
2582
|
+
"data-react-fancy-action": "",
|
|
2583
|
+
...props,
|
|
2584
|
+
children: content
|
|
2585
|
+
}
|
|
2586
|
+
)
|
|
2587
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2573
2588
|
"button",
|
|
2574
2589
|
{
|
|
2575
2590
|
ref,
|
|
@@ -3064,6 +3079,44 @@ function InputWrapper({
|
|
|
3064
3079
|
hasInsideSuffix && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute right-3 z-10 text-zinc-400 dark:text-zinc-500", children: suffix })
|
|
3065
3080
|
] });
|
|
3066
3081
|
}
|
|
3082
|
+
var FieldModeContext = react.createContext(null);
|
|
3083
|
+
function useFieldMode(explicit) {
|
|
3084
|
+
const ctx = react.useContext(FieldModeContext);
|
|
3085
|
+
return explicit ?? ctx?.mode ?? "edit";
|
|
3086
|
+
}
|
|
3087
|
+
function isEmpty(value) {
|
|
3088
|
+
return value === null || value === void 0 || value === "";
|
|
3089
|
+
}
|
|
3090
|
+
function DisplayValue({
|
|
3091
|
+
children,
|
|
3092
|
+
size = "md",
|
|
3093
|
+
leading,
|
|
3094
|
+
trailing,
|
|
3095
|
+
empty = "\u2014",
|
|
3096
|
+
className
|
|
3097
|
+
}) {
|
|
3098
|
+
const empties = isEmpty(children);
|
|
3099
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3100
|
+
"div",
|
|
3101
|
+
{
|
|
3102
|
+
"data-react-fancy-display": "",
|
|
3103
|
+
"data-mode": "view",
|
|
3104
|
+
className: cn(
|
|
3105
|
+
"flex w-full items-center gap-2 text-zinc-900 dark:text-zinc-100",
|
|
3106
|
+
inputSizeClasses[size],
|
|
3107
|
+
// Strip the editable box look — keep only the size/padding rhythm.
|
|
3108
|
+
"border-0 bg-transparent px-0",
|
|
3109
|
+
empties && "text-zinc-400 dark:text-zinc-500",
|
|
3110
|
+
className
|
|
3111
|
+
),
|
|
3112
|
+
children: [
|
|
3113
|
+
leading && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-zinc-400 dark:text-zinc-500", children: leading }),
|
|
3114
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: empties ? empty : children }),
|
|
3115
|
+
trailing && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-zinc-400 dark:text-zinc-500", children: trailing })
|
|
3116
|
+
]
|
|
3117
|
+
}
|
|
3118
|
+
);
|
|
3119
|
+
}
|
|
3067
3120
|
var Input = react.forwardRef(
|
|
3068
3121
|
({
|
|
3069
3122
|
type = "text",
|
|
@@ -3082,13 +3135,15 @@ var Input = react.forwardRef(
|
|
|
3082
3135
|
suffix,
|
|
3083
3136
|
prefixPosition,
|
|
3084
3137
|
suffixPosition,
|
|
3138
|
+
mode,
|
|
3085
3139
|
onValueChange,
|
|
3086
3140
|
onChange,
|
|
3087
3141
|
...props
|
|
3088
3142
|
}, ref) => {
|
|
3089
3143
|
const autoId = react.useId();
|
|
3090
3144
|
const inputId = id ?? autoId;
|
|
3091
|
-
const
|
|
3145
|
+
const resolvedMode = useFieldMode(mode);
|
|
3146
|
+
const input = resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, leading: leading ?? prefix, trailing: trailing ?? suffix, children: type === "password" ? props.value ? "\u2022\u2022\u2022\u2022\u2022\u2022" : "" : props.value }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3092
3147
|
InputWrapper,
|
|
3093
3148
|
{
|
|
3094
3149
|
prefix,
|
|
@@ -3163,6 +3218,7 @@ var Textarea = react.forwardRef(
|
|
|
3163
3218
|
suffix,
|
|
3164
3219
|
prefixPosition: _prefixPosition,
|
|
3165
3220
|
suffixPosition: _suffixPosition,
|
|
3221
|
+
mode,
|
|
3166
3222
|
onValueChange,
|
|
3167
3223
|
onChange,
|
|
3168
3224
|
value,
|
|
@@ -3172,6 +3228,7 @@ var Textarea = react.forwardRef(
|
|
|
3172
3228
|
const autoId = react.useId();
|
|
3173
3229
|
const textareaId = id ?? autoId;
|
|
3174
3230
|
const internalRef = react.useRef(null);
|
|
3231
|
+
const resolvedMode = useFieldMode(mode);
|
|
3175
3232
|
react.useEffect(() => {
|
|
3176
3233
|
const el = internalRef.current;
|
|
3177
3234
|
if (!autoResize || !el) return;
|
|
@@ -3181,7 +3238,7 @@ var Textarea = react.forwardRef(
|
|
|
3181
3238
|
const maxHeight = maxRows ? maxRows * lineHeight : Infinity;
|
|
3182
3239
|
el.style.height = `${Math.min(Math.max(el.scrollHeight, minHeight), maxHeight)}px`;
|
|
3183
3240
|
}, [autoResize, minRows, maxRows, value, defaultValue]);
|
|
3184
|
-
const textarea = /* @__PURE__ */ jsxRuntime.jsx(
|
|
3241
|
+
const textarea = resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, className: "whitespace-pre-wrap", children: value ?? defaultValue }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3185
3242
|
InputWrapper,
|
|
3186
3243
|
{
|
|
3187
3244
|
prefix,
|
|
@@ -3453,6 +3510,7 @@ var NativeSelect = react.forwardRef(
|
|
|
3453
3510
|
suffix,
|
|
3454
3511
|
prefixPosition,
|
|
3455
3512
|
suffixPosition,
|
|
3513
|
+
mode,
|
|
3456
3514
|
onValueChange,
|
|
3457
3515
|
onChange,
|
|
3458
3516
|
value,
|
|
@@ -3461,6 +3519,27 @@ var NativeSelect = react.forwardRef(
|
|
|
3461
3519
|
}, ref) => {
|
|
3462
3520
|
const autoId = react.useId();
|
|
3463
3521
|
const selectId = id ?? autoId;
|
|
3522
|
+
const resolvedMode = useFieldMode(mode);
|
|
3523
|
+
if (resolvedMode === "view") {
|
|
3524
|
+
const current = value ?? defaultValue;
|
|
3525
|
+
const opt = flattenOptions(list).map((o) => resolveOption(o)).find((o) => o.value === current);
|
|
3526
|
+
const display = /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, leading: prefix, trailing: suffix, children: opt?.label ?? current });
|
|
3527
|
+
if (label || error || description) {
|
|
3528
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3529
|
+
Field,
|
|
3530
|
+
{
|
|
3531
|
+
label,
|
|
3532
|
+
description,
|
|
3533
|
+
error,
|
|
3534
|
+
required,
|
|
3535
|
+
htmlFor: selectId,
|
|
3536
|
+
size,
|
|
3537
|
+
children: display
|
|
3538
|
+
}
|
|
3539
|
+
);
|
|
3540
|
+
}
|
|
3541
|
+
return display;
|
|
3542
|
+
}
|
|
3464
3543
|
const isControlled = value !== void 0;
|
|
3465
3544
|
const resolvedDefault = !isControlled && defaultValue === void 0 && placeholder ? "" : defaultValue;
|
|
3466
3545
|
const select = /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3549,11 +3628,13 @@ var ListboxSelect = react.forwardRef(
|
|
|
3549
3628
|
createLabel = "Create",
|
|
3550
3629
|
selectedSuffix = "selected",
|
|
3551
3630
|
indicator = "check",
|
|
3631
|
+
mode,
|
|
3552
3632
|
value: controlledSingleValue,
|
|
3553
3633
|
defaultValue: defaultSingleValue
|
|
3554
3634
|
}, _ref) => {
|
|
3555
3635
|
const autoId = react.useId();
|
|
3556
3636
|
const selectId = id ?? autoId;
|
|
3637
|
+
const resolvedMode = useFieldMode(mode);
|
|
3557
3638
|
const textInputEnabled = searchable || creatable;
|
|
3558
3639
|
const [open, setOpen] = react.useState(false);
|
|
3559
3640
|
const [search2, setSearch] = react.useState("");
|
|
@@ -3680,6 +3761,27 @@ var ListboxSelect = react.forwardRef(
|
|
|
3680
3761
|
}
|
|
3681
3762
|
}
|
|
3682
3763
|
};
|
|
3764
|
+
if (resolvedMode === "view") {
|
|
3765
|
+
const labels = multiple ? currentMulti.map(
|
|
3766
|
+
(v) => resolvedOptions.find((o) => o.value === v)?.label ?? v
|
|
3767
|
+
) : currentSingle ? [resolvedOptions.find((o) => o.value === currentSingle)?.label ?? currentSingle] : [];
|
|
3768
|
+
const display = /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, children: labels.join(", ") });
|
|
3769
|
+
if (label || error || description) {
|
|
3770
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3771
|
+
Field,
|
|
3772
|
+
{
|
|
3773
|
+
label,
|
|
3774
|
+
description,
|
|
3775
|
+
error,
|
|
3776
|
+
required,
|
|
3777
|
+
htmlFor: selectId,
|
|
3778
|
+
size,
|
|
3779
|
+
children: display
|
|
3780
|
+
}
|
|
3781
|
+
);
|
|
3782
|
+
}
|
|
3783
|
+
return display;
|
|
3784
|
+
}
|
|
3683
3785
|
const trigger = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3684
3786
|
"button",
|
|
3685
3787
|
{
|
|
@@ -3855,11 +3957,13 @@ var Checkbox = react.forwardRef(
|
|
|
3855
3957
|
checked: controlledChecked,
|
|
3856
3958
|
defaultChecked = false,
|
|
3857
3959
|
onCheckedChange,
|
|
3858
|
-
indeterminate
|
|
3960
|
+
indeterminate,
|
|
3961
|
+
mode
|
|
3859
3962
|
}, ref) => {
|
|
3860
3963
|
const autoId = react.useId();
|
|
3861
3964
|
const checkboxId = id ?? autoId;
|
|
3862
3965
|
const internalRef = react.useRef(null);
|
|
3966
|
+
const resolvedMode = useFieldMode(mode);
|
|
3863
3967
|
const [checked, setChecked] = useControllableState(
|
|
3864
3968
|
controlledChecked,
|
|
3865
3969
|
defaultChecked,
|
|
@@ -3878,8 +3982,21 @@ var Checkbox = react.forwardRef(
|
|
|
3878
3982
|
lg: "h-5 w-5",
|
|
3879
3983
|
xl: "h-6 w-6"
|
|
3880
3984
|
}[size];
|
|
3985
|
+
const glyph = indeterminate ? "\u2014" : checked ? "\u2713" : "\u2715";
|
|
3881
3986
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-checkbox": "", className: cn("flex items-start gap-2", className), children: [
|
|
3882
|
-
|
|
3987
|
+
resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3988
|
+
"span",
|
|
3989
|
+
{
|
|
3990
|
+
"data-react-fancy-display": "",
|
|
3991
|
+
"data-mode": "view",
|
|
3992
|
+
className: cn(
|
|
3993
|
+
"flex shrink-0 items-center justify-center text-zinc-700 dark:text-zinc-200",
|
|
3994
|
+
sizeClasses6
|
|
3995
|
+
),
|
|
3996
|
+
"aria-hidden": "true",
|
|
3997
|
+
children: glyph
|
|
3998
|
+
}
|
|
3999
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3883
4000
|
"input",
|
|
3884
4001
|
{
|
|
3885
4002
|
ref: (node) => {
|
|
@@ -3941,9 +4058,11 @@ function CheckboxGroup({
|
|
|
3941
4058
|
value: controlledValue,
|
|
3942
4059
|
defaultValue = [],
|
|
3943
4060
|
onValueChange,
|
|
3944
|
-
orientation = "vertical"
|
|
4061
|
+
orientation = "vertical",
|
|
4062
|
+
mode
|
|
3945
4063
|
}) {
|
|
3946
4064
|
const groupId = react.useId();
|
|
4065
|
+
const resolvedMode = useFieldMode(mode);
|
|
3947
4066
|
const [value, setValue] = useControllableState(
|
|
3948
4067
|
controlledValue,
|
|
3949
4068
|
defaultValue,
|
|
@@ -3960,7 +4079,7 @@ function CheckboxGroup({
|
|
|
3960
4079
|
lg: "h-5 w-5",
|
|
3961
4080
|
xl: "h-6 w-6"
|
|
3962
4081
|
}[size];
|
|
3963
|
-
const content = /* @__PURE__ */ jsxRuntime.jsx(
|
|
4082
|
+
const content = resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, children: list.map(resolveOption).filter((o) => value.includes(o.value)).map((o) => o.label).join(", ") }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3964
4083
|
"div",
|
|
3965
4084
|
{
|
|
3966
4085
|
"data-react-fancy-checkbox-group": "",
|
|
@@ -4040,10 +4159,12 @@ function RadioGroup({
|
|
|
4040
4159
|
value: controlledValue,
|
|
4041
4160
|
defaultValue,
|
|
4042
4161
|
onValueChange,
|
|
4043
|
-
orientation = "vertical"
|
|
4162
|
+
orientation = "vertical",
|
|
4163
|
+
mode
|
|
4044
4164
|
}) {
|
|
4045
4165
|
const groupId = react.useId();
|
|
4046
4166
|
const radioName = name ?? groupId;
|
|
4167
|
+
const resolvedMode = useFieldMode(mode);
|
|
4047
4168
|
const [value, setValue] = useControllableState(
|
|
4048
4169
|
controlledValue,
|
|
4049
4170
|
defaultValue,
|
|
@@ -4056,7 +4177,7 @@ function RadioGroup({
|
|
|
4056
4177
|
lg: "h-5 w-5",
|
|
4057
4178
|
xl: "h-6 w-6"
|
|
4058
4179
|
}[size];
|
|
4059
|
-
const content = /* @__PURE__ */ jsxRuntime.jsx(
|
|
4180
|
+
const content = resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, children: list.map(resolveOption).find((o) => o.value === value)?.label }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4060
4181
|
"div",
|
|
4061
4182
|
{
|
|
4062
4183
|
"data-react-fancy-radio-group": "",
|
|
@@ -4164,10 +4285,12 @@ var Switch = react.forwardRef(
|
|
|
4164
4285
|
checked: controlledChecked,
|
|
4165
4286
|
defaultChecked = false,
|
|
4166
4287
|
onCheckedChange,
|
|
4167
|
-
color = "blue"
|
|
4288
|
+
color = "blue",
|
|
4289
|
+
mode
|
|
4168
4290
|
}, ref) => {
|
|
4169
4291
|
const autoId = react.useId();
|
|
4170
4292
|
const switchId = id ?? autoId;
|
|
4293
|
+
const resolvedMode = useFieldMode(mode);
|
|
4171
4294
|
const [checked, setChecked] = useControllableState(
|
|
4172
4295
|
controlledChecked,
|
|
4173
4296
|
defaultChecked,
|
|
@@ -4195,7 +4318,15 @@ var Switch = react.forwardRef(
|
|
|
4195
4318
|
xl: "translate-x-6"
|
|
4196
4319
|
}[size];
|
|
4197
4320
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-switch": "", className: cn("flex items-start gap-2", className), children: [
|
|
4198
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4321
|
+
resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4322
|
+
"span",
|
|
4323
|
+
{
|
|
4324
|
+
"data-react-fancy-display": "",
|
|
4325
|
+
"data-mode": "view",
|
|
4326
|
+
className: "text-sm font-medium text-zinc-700 dark:text-zinc-200",
|
|
4327
|
+
children: checked ? "On" : "Off"
|
|
4328
|
+
}
|
|
4329
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4199
4330
|
"button",
|
|
4200
4331
|
{
|
|
4201
4332
|
ref,
|
|
@@ -4309,15 +4440,17 @@ var SingleSlider = react.forwardRef(
|
|
|
4309
4440
|
marks,
|
|
4310
4441
|
prefix,
|
|
4311
4442
|
suffix,
|
|
4443
|
+
mode,
|
|
4312
4444
|
...rest
|
|
4313
4445
|
}, ref) => {
|
|
4314
4446
|
const singleProps = rest;
|
|
4447
|
+
const resolvedMode = useFieldMode(mode);
|
|
4315
4448
|
const [value, setValue] = useControllableState(
|
|
4316
4449
|
singleProps.value,
|
|
4317
4450
|
singleProps.defaultValue ?? min,
|
|
4318
4451
|
singleProps.onValueChange
|
|
4319
4452
|
);
|
|
4320
|
-
const slider = /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-slider": "", className: cn("flex flex-col gap-1", className), children: [
|
|
4453
|
+
const slider = resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, className, children: `${prefix ?? ""}${value}${suffix ?? ""}` }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-slider": "", className: cn("flex flex-col gap-1", className), children: [
|
|
4321
4454
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
4322
4455
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4323
4456
|
"input",
|
|
@@ -4379,9 +4512,11 @@ var RangeSlider = react.forwardRef(
|
|
|
4379
4512
|
marks,
|
|
4380
4513
|
prefix,
|
|
4381
4514
|
suffix,
|
|
4515
|
+
mode,
|
|
4382
4516
|
...rest
|
|
4383
4517
|
}, ref) => {
|
|
4384
4518
|
const rangeProps = rest;
|
|
4519
|
+
const resolvedMode = useFieldMode(mode);
|
|
4385
4520
|
const [value, setValue] = useControllableState(
|
|
4386
4521
|
rangeProps.value,
|
|
4387
4522
|
rangeProps.defaultValue ?? [min, max],
|
|
@@ -4395,7 +4530,7 @@ var RangeSlider = react.forwardRef(
|
|
|
4395
4530
|
};
|
|
4396
4531
|
const leftPercent = (value[0] - min) / (max - min) * 100;
|
|
4397
4532
|
const rightPercent = (value[1] - min) / (max - min) * 100;
|
|
4398
|
-
const slider = /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-slider": "", className: cn("flex flex-col gap-1", className), children: [
|
|
4533
|
+
const slider = resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, className, children: `${prefix ?? ""}${value[0]}${suffix ?? ""}\u2013${prefix ?? ""}${value[1]}${suffix ?? ""}` }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-slider": "", className: cn("flex flex-col gap-1", className), children: [
|
|
4399
4534
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
4400
4535
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
4401
4536
|
/* @__PURE__ */ jsxRuntime.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" }),
|
|
@@ -4497,10 +4632,12 @@ function MultiSwitch({
|
|
|
4497
4632
|
value: controlledValue,
|
|
4498
4633
|
defaultValue,
|
|
4499
4634
|
onValueChange,
|
|
4500
|
-
linear
|
|
4635
|
+
linear,
|
|
4636
|
+
mode
|
|
4501
4637
|
}) {
|
|
4502
4638
|
const resolvedOptions = list.map(resolveOption);
|
|
4503
4639
|
const fallback = defaultValue ?? resolvedOptions[0]?.value;
|
|
4640
|
+
const resolvedMode = useFieldMode(mode);
|
|
4504
4641
|
const [value, setValue] = useControllableState(controlledValue, fallback, onValueChange);
|
|
4505
4642
|
const containerRef = react.useRef(null);
|
|
4506
4643
|
const itemRefs = react.useRef([]);
|
|
@@ -4525,7 +4662,7 @@ function MultiSwitch({
|
|
|
4525
4662
|
react.useEffect(() => {
|
|
4526
4663
|
updateIndicator();
|
|
4527
4664
|
}, [updateIndicator]);
|
|
4528
|
-
const control = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4665
|
+
const control = resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, children: resolvedOptions.find((o) => o.value === value)?.label }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4529
4666
|
"div",
|
|
4530
4667
|
{
|
|
4531
4668
|
ref: containerRef,
|
|
@@ -4588,6 +4725,22 @@ function MultiSwitch({
|
|
|
4588
4725
|
return control;
|
|
4589
4726
|
}
|
|
4590
4727
|
MultiSwitch.displayName = "MultiSwitch";
|
|
4728
|
+
function formatDateValue(iso, includeTime) {
|
|
4729
|
+
if (!iso) return "";
|
|
4730
|
+
const date = new Date(iso);
|
|
4731
|
+
if (Number.isNaN(date.getTime())) return iso;
|
|
4732
|
+
return includeTime ? date.toLocaleString(void 0, {
|
|
4733
|
+
year: "numeric",
|
|
4734
|
+
month: "short",
|
|
4735
|
+
day: "numeric",
|
|
4736
|
+
hour: "2-digit",
|
|
4737
|
+
minute: "2-digit"
|
|
4738
|
+
}) : date.toLocaleDateString(void 0, {
|
|
4739
|
+
year: "numeric",
|
|
4740
|
+
month: "short",
|
|
4741
|
+
day: "numeric"
|
|
4742
|
+
});
|
|
4743
|
+
}
|
|
4591
4744
|
var DatePicker = react.forwardRef(
|
|
4592
4745
|
(props, ref) => {
|
|
4593
4746
|
const {
|
|
@@ -4654,17 +4807,20 @@ var SingleDatePicker = react.forwardRef(
|
|
|
4654
4807
|
name,
|
|
4655
4808
|
min,
|
|
4656
4809
|
max,
|
|
4810
|
+
includeTime,
|
|
4811
|
+
mode,
|
|
4657
4812
|
inputType,
|
|
4658
4813
|
inputClasses,
|
|
4659
4814
|
...rest
|
|
4660
4815
|
}, ref) => {
|
|
4661
4816
|
const singleProps = rest;
|
|
4817
|
+
const resolvedMode = useFieldMode(mode);
|
|
4662
4818
|
const [value, setValue] = useControllableState(
|
|
4663
4819
|
singleProps.value,
|
|
4664
4820
|
singleProps.defaultValue ?? "",
|
|
4665
4821
|
singleProps.onValueChange
|
|
4666
4822
|
);
|
|
4667
|
-
const input = /* @__PURE__ */ jsxRuntime.jsx(
|
|
4823
|
+
const input = resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, className, children: formatDateValue(value, includeTime) }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4668
4824
|
"input",
|
|
4669
4825
|
{
|
|
4670
4826
|
"data-react-fancy-date-picker": "",
|
|
@@ -4712,17 +4868,20 @@ var RangeDatePicker = react.forwardRef(
|
|
|
4712
4868
|
name,
|
|
4713
4869
|
min,
|
|
4714
4870
|
max,
|
|
4871
|
+
includeTime,
|
|
4872
|
+
mode,
|
|
4715
4873
|
inputType,
|
|
4716
4874
|
inputClasses,
|
|
4717
4875
|
...rest
|
|
4718
4876
|
}, ref) => {
|
|
4719
4877
|
const rangeProps = rest;
|
|
4878
|
+
const resolvedMode = useFieldMode(mode);
|
|
4720
4879
|
const [value, setValue] = useControllableState(
|
|
4721
4880
|
rangeProps.value,
|
|
4722
4881
|
rangeProps.defaultValue ?? ["", ""],
|
|
4723
4882
|
rangeProps.onValueChange
|
|
4724
4883
|
);
|
|
4725
|
-
const input = /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-date-picker": "", className: cn("flex items-center gap-2", className), children: [
|
|
4884
|
+
const input = resolvedMode === "view" ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, className, children: value[0] || value[1] ? `${formatDateValue(value[0], includeTime)} \u2013 ${formatDateValue(value[1], includeTime)}` : "" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-date-picker": "", className: cn("flex items-center gap-2", className), children: [
|
|
4726
4885
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4727
4886
|
"input",
|
|
4728
4887
|
{
|
|
@@ -4772,6 +4931,13 @@ var RangeDatePicker = react.forwardRef(
|
|
|
4772
4931
|
}
|
|
4773
4932
|
);
|
|
4774
4933
|
RangeDatePicker.displayName = "RangeDatePicker";
|
|
4934
|
+
function FormProvider({ mode = "edit", children }) {
|
|
4935
|
+
const value = react.useMemo(() => ({ mode }), [mode]);
|
|
4936
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FieldModeContext.Provider, { value, children });
|
|
4937
|
+
}
|
|
4938
|
+
function Form({ mode, children, ...formProps }) {
|
|
4939
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FormProvider, { mode, children: /* @__PURE__ */ jsxRuntime.jsx("form", { "data-react-fancy-form": "", ...formProps, children }) });
|
|
4940
|
+
}
|
|
4775
4941
|
var CarouselContext = react.createContext(null);
|
|
4776
4942
|
CarouselContext.displayName = "CarouselContext";
|
|
4777
4943
|
function useCarousel() {
|
|
@@ -5111,13 +5277,15 @@ var ColorPicker = react.forwardRef(
|
|
|
5111
5277
|
size = "md",
|
|
5112
5278
|
variant = "outline",
|
|
5113
5279
|
disabled = false,
|
|
5114
|
-
className
|
|
5280
|
+
className,
|
|
5281
|
+
mode
|
|
5115
5282
|
}, ref) => {
|
|
5116
5283
|
const [color, setColor] = useControllableState(
|
|
5117
5284
|
value,
|
|
5118
5285
|
defaultValue,
|
|
5119
5286
|
onChange
|
|
5120
5287
|
);
|
|
5288
|
+
const resolvedMode = useFieldMode(mode);
|
|
5121
5289
|
const inputRef = react.useRef(null);
|
|
5122
5290
|
const datalistId = react.useId();
|
|
5123
5291
|
const handleChange = (e) => {
|
|
@@ -5128,6 +5296,42 @@ var ColorPicker = react.forwardRef(
|
|
|
5128
5296
|
inputRef.current?.click();
|
|
5129
5297
|
}
|
|
5130
5298
|
};
|
|
5299
|
+
if (resolvedMode === "view") {
|
|
5300
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5301
|
+
"div",
|
|
5302
|
+
{
|
|
5303
|
+
ref,
|
|
5304
|
+
"data-react-fancy-color-picker": "",
|
|
5305
|
+
"data-mode": "view",
|
|
5306
|
+
className: cn("inline-flex items-center gap-2", className),
|
|
5307
|
+
children: [
|
|
5308
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5309
|
+
"span",
|
|
5310
|
+
{
|
|
5311
|
+
className: cn(
|
|
5312
|
+
"shrink-0 rounded-full",
|
|
5313
|
+
SWATCH_SIZES[size],
|
|
5314
|
+
variant === "outline" && "ring-1 ring-zinc-300 dark:ring-zinc-600"
|
|
5315
|
+
),
|
|
5316
|
+
style: { backgroundColor: color },
|
|
5317
|
+
"aria-label": `Color: ${color}`
|
|
5318
|
+
}
|
|
5319
|
+
),
|
|
5320
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5321
|
+
"span",
|
|
5322
|
+
{
|
|
5323
|
+
className: cn(
|
|
5324
|
+
"select-all font-mono uppercase",
|
|
5325
|
+
TEXT_SIZES[size],
|
|
5326
|
+
"text-zinc-700 dark:text-zinc-300"
|
|
5327
|
+
),
|
|
5328
|
+
children: color.toUpperCase()
|
|
5329
|
+
}
|
|
5330
|
+
)
|
|
5331
|
+
]
|
|
5332
|
+
}
|
|
5333
|
+
);
|
|
5334
|
+
}
|
|
5131
5335
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5132
5336
|
"div",
|
|
5133
5337
|
{
|
|
@@ -6017,6 +6221,14 @@ var Badge = react.forwardRef(
|
|
|
6017
6221
|
}
|
|
6018
6222
|
);
|
|
6019
6223
|
Badge.displayName = "Badge";
|
|
6224
|
+
var glowColors = {
|
|
6225
|
+
on: "#a855f7",
|
|
6226
|
+
// violet — neutral
|
|
6227
|
+
xp: "#22c55e",
|
|
6228
|
+
// green
|
|
6229
|
+
achievement: "#f59e0b"
|
|
6230
|
+
// amber
|
|
6231
|
+
};
|
|
6020
6232
|
var containerSizeClasses = {
|
|
6021
6233
|
xs: "h-6 w-6",
|
|
6022
6234
|
sm: "h-8 w-8",
|
|
@@ -6051,8 +6263,10 @@ var Avatar = react.forwardRef(
|
|
|
6051
6263
|
fallback,
|
|
6052
6264
|
size = "md",
|
|
6053
6265
|
status,
|
|
6266
|
+
glow,
|
|
6054
6267
|
className
|
|
6055
6268
|
}, ref) => {
|
|
6269
|
+
const glowKey = glow === true ? "on" : glow || null;
|
|
6056
6270
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6057
6271
|
"div",
|
|
6058
6272
|
{
|
|
@@ -6065,6 +6279,15 @@ var Avatar = react.forwardRef(
|
|
|
6065
6279
|
className
|
|
6066
6280
|
),
|
|
6067
6281
|
children: [
|
|
6282
|
+
glowKey && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6283
|
+
"span",
|
|
6284
|
+
{
|
|
6285
|
+
"aria-hidden": true,
|
|
6286
|
+
"data-react-fancy-avatar-glow": glowKey,
|
|
6287
|
+
className: "fancy-avatar-glow",
|
|
6288
|
+
style: { "--fancy-glow": glowColors[glowKey] }
|
|
6289
|
+
}
|
|
6290
|
+
),
|
|
6068
6291
|
src ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6069
6292
|
"img",
|
|
6070
6293
|
{
|
|
@@ -8855,13 +9078,15 @@ var Autocomplete = react.forwardRef(
|
|
|
8855
9078
|
loading = false,
|
|
8856
9079
|
emptyMessage = "No results found.",
|
|
8857
9080
|
disabled = false,
|
|
8858
|
-
className
|
|
9081
|
+
className,
|
|
9082
|
+
mode
|
|
8859
9083
|
}, ref) {
|
|
8860
9084
|
const [value, setValue] = useControllableState(
|
|
8861
9085
|
controlledValue,
|
|
8862
9086
|
defaultValue,
|
|
8863
9087
|
onChange
|
|
8864
9088
|
);
|
|
9089
|
+
const resolvedMode = useFieldMode(mode);
|
|
8865
9090
|
const [query, setQuery] = react.useState(value);
|
|
8866
9091
|
const [open, setOpen] = react.useState(false);
|
|
8867
9092
|
const [activeIndex, setActiveIndex] = react.useState(-1);
|
|
@@ -8914,6 +9139,23 @@ var Autocomplete = react.forwardRef(
|
|
|
8914
9139
|
if (item && !item.disabled) select(item.value);
|
|
8915
9140
|
}
|
|
8916
9141
|
};
|
|
9142
|
+
if (resolvedMode === "view") {
|
|
9143
|
+
const matched = options.find((o) => o.value === value);
|
|
9144
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9145
|
+
"div",
|
|
9146
|
+
{
|
|
9147
|
+
"data-react-fancy-autocomplete": "",
|
|
9148
|
+
"data-mode": "view",
|
|
9149
|
+
ref: wrapperRef,
|
|
9150
|
+
className: cn(
|
|
9151
|
+
"text-sm text-zinc-900 dark:text-zinc-100",
|
|
9152
|
+
!value && "text-zinc-400 dark:text-zinc-500",
|
|
9153
|
+
className
|
|
9154
|
+
),
|
|
9155
|
+
children: matched?.label ?? value ?? "\u2014"
|
|
9156
|
+
}
|
|
9157
|
+
);
|
|
9158
|
+
}
|
|
8917
9159
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-autocomplete": "", ref: wrapperRef, className: cn("relative", className), children: [
|
|
8918
9160
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8919
9161
|
"input",
|
|
@@ -9086,13 +9328,15 @@ var OtpInput = react.forwardRef(
|
|
|
9086
9328
|
onChange,
|
|
9087
9329
|
disabled = false,
|
|
9088
9330
|
autoFocus = false,
|
|
9089
|
-
className
|
|
9331
|
+
className,
|
|
9332
|
+
mode
|
|
9090
9333
|
}, ref) {
|
|
9091
9334
|
const [value, setValue] = useControllableState(
|
|
9092
9335
|
controlledValue,
|
|
9093
9336
|
"",
|
|
9094
9337
|
onChange
|
|
9095
9338
|
);
|
|
9339
|
+
const resolvedMode = useFieldMode(mode);
|
|
9096
9340
|
const inputsRef = react.useRef([]);
|
|
9097
9341
|
const focusInput = react.useCallback(
|
|
9098
9342
|
(index) => {
|
|
@@ -9146,6 +9390,21 @@ var OtpInput = react.forwardRef(
|
|
|
9146
9390
|
},
|
|
9147
9391
|
[length, setValue, focusInput]
|
|
9148
9392
|
);
|
|
9393
|
+
if (resolvedMode === "view") {
|
|
9394
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9395
|
+
"div",
|
|
9396
|
+
{
|
|
9397
|
+
"data-react-fancy-otp-input": "",
|
|
9398
|
+
"data-mode": "view",
|
|
9399
|
+
ref,
|
|
9400
|
+
className: cn(
|
|
9401
|
+
"font-mono text-lg tracking-[0.4em] text-zinc-900 dark:text-zinc-100",
|
|
9402
|
+
className
|
|
9403
|
+
),
|
|
9404
|
+
children: value || "\u2014"
|
|
9405
|
+
}
|
|
9406
|
+
);
|
|
9407
|
+
}
|
|
9149
9408
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-react-fancy-otp-input": "", ref, className: cn("flex gap-2", className), children: Array.from({ length }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
9150
9409
|
"input",
|
|
9151
9410
|
{
|
|
@@ -9360,16 +9619,34 @@ var TimePicker = react.forwardRef(
|
|
|
9360
9619
|
format = "12h",
|
|
9361
9620
|
minuteStep = 1,
|
|
9362
9621
|
disabled = false,
|
|
9363
|
-
className
|
|
9622
|
+
className,
|
|
9623
|
+
mode
|
|
9364
9624
|
}, ref) {
|
|
9365
9625
|
const [value, setValue] = useControllableState(
|
|
9366
9626
|
controlledValue,
|
|
9367
9627
|
defaultValue,
|
|
9368
9628
|
onChange
|
|
9369
9629
|
);
|
|
9630
|
+
const resolvedMode = useFieldMode(mode);
|
|
9370
9631
|
const { hours: h24, minutes } = parseTime(value);
|
|
9371
9632
|
const isPM = h24 >= 12;
|
|
9372
9633
|
const displayHour = format === "12h" ? h24 % 12 || 12 : h24;
|
|
9634
|
+
if (resolvedMode === "view") {
|
|
9635
|
+
const formatted = format === "12h" ? `${pad(displayHour)}:${pad(minutes)} ${isPM ? "PM" : "AM"}` : `${pad(displayHour)}:${pad(minutes)}`;
|
|
9636
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9637
|
+
"div",
|
|
9638
|
+
{
|
|
9639
|
+
"data-react-fancy-time-picker": "",
|
|
9640
|
+
"data-mode": "view",
|
|
9641
|
+
ref,
|
|
9642
|
+
className: cn(
|
|
9643
|
+
"text-sm font-medium tabular-nums text-zinc-900 dark:text-zinc-100",
|
|
9644
|
+
className
|
|
9645
|
+
),
|
|
9646
|
+
children: formatted
|
|
9647
|
+
}
|
|
9648
|
+
);
|
|
9649
|
+
}
|
|
9373
9650
|
const updateTime = react.useCallback(
|
|
9374
9651
|
(hours, mins) => {
|
|
9375
9652
|
setValue(`${pad(hours)}:${pad(mins)}`);
|
|
@@ -13715,6 +13992,7 @@ exports.Composer = Composer;
|
|
|
13715
13992
|
exports.ContentRenderer = ContentRenderer;
|
|
13716
13993
|
exports.ContextMenu = ContextMenu;
|
|
13717
13994
|
exports.DatePicker = DatePicker;
|
|
13995
|
+
exports.DisplayValue = DisplayValue;
|
|
13718
13996
|
exports.Dropdown = Dropdown;
|
|
13719
13997
|
exports.EMOJI_CATEGORY_ORDER = EMOJI_CATEGORY_ORDER;
|
|
13720
13998
|
exports.EMOJI_DATA = EMOJI_DATA;
|
|
@@ -13724,7 +14002,10 @@ exports.Emoji = Emoji;
|
|
|
13724
14002
|
exports.EmojiSelect = EmojiSelect;
|
|
13725
14003
|
exports.FauxClient = FauxClient;
|
|
13726
14004
|
exports.Field = Field;
|
|
14005
|
+
exports.FieldModeContext = FieldModeContext;
|
|
13727
14006
|
exports.FileUpload = FileUpload;
|
|
14007
|
+
exports.Form = Form;
|
|
14008
|
+
exports.FormProvider = FormProvider;
|
|
13728
14009
|
exports.Heading = Heading;
|
|
13729
14010
|
exports.Icon = Icon;
|
|
13730
14011
|
exports.Input = Input;
|
|
@@ -13794,6 +14075,7 @@ exports.useControllableState = useControllableState;
|
|
|
13794
14075
|
exports.useDropdown = useDropdown;
|
|
13795
14076
|
exports.useEditor = useEditor;
|
|
13796
14077
|
exports.useEscapeKey = useEscapeKey;
|
|
14078
|
+
exports.useFieldMode = useFieldMode;
|
|
13797
14079
|
exports.useFileUpload = useFileUpload;
|
|
13798
14080
|
exports.useFloatingPosition = useFloatingPosition;
|
|
13799
14081
|
exports.useFocusTrap = useFocusTrap;
|