@particle-academy/react-fancy 4.4.7 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +741 -186
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +97 -5
- package/dist/index.d.ts +97 -5
- package/dist/index.js +737 -187
- 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
|
@@ -3079,6 +3079,68 @@ function InputWrapper({
|
|
|
3079
3079
|
hasInsideSuffix && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute right-3 z-10 text-zinc-400 dark:text-zinc-500", children: suffix })
|
|
3080
3080
|
] });
|
|
3081
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
|
+
interactive,
|
|
3097
|
+
onActivate,
|
|
3098
|
+
className
|
|
3099
|
+
}) {
|
|
3100
|
+
const empties = isEmpty(children);
|
|
3101
|
+
const onKeyDown = interactive ? (e) => {
|
|
3102
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3103
|
+
e.preventDefault();
|
|
3104
|
+
onActivate?.();
|
|
3105
|
+
}
|
|
3106
|
+
} : void 0;
|
|
3107
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3108
|
+
"div",
|
|
3109
|
+
{
|
|
3110
|
+
"data-react-fancy-display": "",
|
|
3111
|
+
"data-mode": "view",
|
|
3112
|
+
role: interactive ? "button" : void 0,
|
|
3113
|
+
tabIndex: interactive ? 0 : void 0,
|
|
3114
|
+
title: interactive ? "Click to edit" : void 0,
|
|
3115
|
+
onClick: interactive ? onActivate : void 0,
|
|
3116
|
+
onKeyDown,
|
|
3117
|
+
className: cn(
|
|
3118
|
+
"flex w-full items-center gap-2 text-zinc-900 dark:text-zinc-100",
|
|
3119
|
+
inputSizeClasses[size],
|
|
3120
|
+
// Strip the editable box look — keep only the size/padding rhythm.
|
|
3121
|
+
"border-0 bg-transparent px-0",
|
|
3122
|
+
interactive && "-mx-2 cursor-text rounded-md px-2 outline-none transition-colors hover:bg-zinc-100 focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:bg-zinc-800",
|
|
3123
|
+
empties && "text-zinc-400 dark:text-zinc-500",
|
|
3124
|
+
className
|
|
3125
|
+
),
|
|
3126
|
+
children: [
|
|
3127
|
+
leading && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-zinc-400 dark:text-zinc-500", children: leading }),
|
|
3128
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate", children: empties ? empty : children }),
|
|
3129
|
+
trailing && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-zinc-400 dark:text-zinc-500", children: trailing })
|
|
3130
|
+
]
|
|
3131
|
+
}
|
|
3132
|
+
);
|
|
3133
|
+
}
|
|
3134
|
+
function useInlineEdit(mode, disabled) {
|
|
3135
|
+
const [editing, setEditing] = react.useState(false);
|
|
3136
|
+
const interactive = mode === "view" && !disabled;
|
|
3137
|
+
const showControl = mode !== "view" || interactive && editing;
|
|
3138
|
+
const enterEdit = react.useCallback(() => {
|
|
3139
|
+
if (interactive) setEditing(true);
|
|
3140
|
+
}, [interactive]);
|
|
3141
|
+
const exitEdit = react.useCallback(() => setEditing(false), []);
|
|
3142
|
+
return { showControl, interactive, enterEdit, exitEdit };
|
|
3143
|
+
}
|
|
3082
3144
|
var Input = react.forwardRef(
|
|
3083
3145
|
({
|
|
3084
3146
|
type = "text",
|
|
@@ -3097,13 +3159,26 @@ var Input = react.forwardRef(
|
|
|
3097
3159
|
suffix,
|
|
3098
3160
|
prefixPosition,
|
|
3099
3161
|
suffixPosition,
|
|
3162
|
+
mode,
|
|
3100
3163
|
onValueChange,
|
|
3101
3164
|
onChange,
|
|
3102
3165
|
...props
|
|
3103
3166
|
}, ref) => {
|
|
3104
3167
|
const autoId = react.useId();
|
|
3105
3168
|
const inputId = id ?? autoId;
|
|
3106
|
-
const
|
|
3169
|
+
const resolvedMode = useFieldMode(mode);
|
|
3170
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
3171
|
+
const input = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3172
|
+
DisplayValue,
|
|
3173
|
+
{
|
|
3174
|
+
size,
|
|
3175
|
+
interactive,
|
|
3176
|
+
onActivate: enterEdit,
|
|
3177
|
+
leading: leading ?? prefix,
|
|
3178
|
+
trailing: trailing ?? suffix,
|
|
3179
|
+
children: type === "password" ? props.value ? "\u2022\u2022\u2022\u2022\u2022\u2022" : "" : props.value
|
|
3180
|
+
}
|
|
3181
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3107
3182
|
InputWrapper,
|
|
3108
3183
|
{
|
|
3109
3184
|
prefix,
|
|
@@ -3135,7 +3210,12 @@ var Input = react.forwardRef(
|
|
|
3135
3210
|
onChange?.(e);
|
|
3136
3211
|
onValueChange?.(e.target.value);
|
|
3137
3212
|
},
|
|
3138
|
-
...props
|
|
3213
|
+
...props,
|
|
3214
|
+
autoFocus: interactive || props.autoFocus,
|
|
3215
|
+
onBlur: (e) => {
|
|
3216
|
+
props.onBlur?.(e);
|
|
3217
|
+
if (interactive) exitEdit();
|
|
3218
|
+
}
|
|
3139
3219
|
}
|
|
3140
3220
|
),
|
|
3141
3221
|
trailing && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute right-3 text-zinc-400 dark:text-zinc-500", children: trailing })
|
|
@@ -3178,6 +3258,7 @@ var Textarea = react.forwardRef(
|
|
|
3178
3258
|
suffix,
|
|
3179
3259
|
prefixPosition: _prefixPosition,
|
|
3180
3260
|
suffixPosition: _suffixPosition,
|
|
3261
|
+
mode,
|
|
3181
3262
|
onValueChange,
|
|
3182
3263
|
onChange,
|
|
3183
3264
|
value,
|
|
@@ -3187,6 +3268,8 @@ var Textarea = react.forwardRef(
|
|
|
3187
3268
|
const autoId = react.useId();
|
|
3188
3269
|
const textareaId = id ?? autoId;
|
|
3189
3270
|
const internalRef = react.useRef(null);
|
|
3271
|
+
const resolvedMode = useFieldMode(mode);
|
|
3272
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
3190
3273
|
react.useEffect(() => {
|
|
3191
3274
|
const el = internalRef.current;
|
|
3192
3275
|
if (!autoResize || !el) return;
|
|
@@ -3196,7 +3279,16 @@ var Textarea = react.forwardRef(
|
|
|
3196
3279
|
const maxHeight = maxRows ? maxRows * lineHeight : Infinity;
|
|
3197
3280
|
el.style.height = `${Math.min(Math.max(el.scrollHeight, minHeight), maxHeight)}px`;
|
|
3198
3281
|
}, [autoResize, minRows, maxRows, value, defaultValue]);
|
|
3199
|
-
const textarea = /* @__PURE__ */ jsxRuntime.jsx(
|
|
3282
|
+
const textarea = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3283
|
+
DisplayValue,
|
|
3284
|
+
{
|
|
3285
|
+
size,
|
|
3286
|
+
className: "whitespace-pre-wrap",
|
|
3287
|
+
interactive,
|
|
3288
|
+
onActivate: enterEdit,
|
|
3289
|
+
children: value ?? defaultValue
|
|
3290
|
+
}
|
|
3291
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3200
3292
|
InputWrapper,
|
|
3201
3293
|
{
|
|
3202
3294
|
prefix,
|
|
@@ -3235,7 +3327,12 @@ var Textarea = react.forwardRef(
|
|
|
3235
3327
|
onChange?.(e);
|
|
3236
3328
|
onValueChange?.(e.target.value);
|
|
3237
3329
|
},
|
|
3238
|
-
...props
|
|
3330
|
+
...props,
|
|
3331
|
+
autoFocus: interactive || props.autoFocus,
|
|
3332
|
+
onBlur: (e) => {
|
|
3333
|
+
props.onBlur?.(e);
|
|
3334
|
+
if (interactive) exitEdit();
|
|
3335
|
+
}
|
|
3239
3336
|
}
|
|
3240
3337
|
)
|
|
3241
3338
|
}
|
|
@@ -3468,6 +3565,7 @@ var NativeSelect = react.forwardRef(
|
|
|
3468
3565
|
suffix,
|
|
3469
3566
|
prefixPosition,
|
|
3470
3567
|
suffixPosition,
|
|
3568
|
+
mode,
|
|
3471
3569
|
onValueChange,
|
|
3472
3570
|
onChange,
|
|
3473
3571
|
value,
|
|
@@ -3476,6 +3574,38 @@ var NativeSelect = react.forwardRef(
|
|
|
3476
3574
|
}, ref) => {
|
|
3477
3575
|
const autoId = react.useId();
|
|
3478
3576
|
const selectId = id ?? autoId;
|
|
3577
|
+
const resolvedMode = useFieldMode(mode);
|
|
3578
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
3579
|
+
if (!showControl) {
|
|
3580
|
+
const current = value ?? defaultValue;
|
|
3581
|
+
const opt = flattenOptions(list).map((o) => resolveOption(o)).find((o) => o.value === current);
|
|
3582
|
+
const display = /* @__PURE__ */ jsxRuntime.jsx(
|
|
3583
|
+
DisplayValue,
|
|
3584
|
+
{
|
|
3585
|
+
size,
|
|
3586
|
+
leading: prefix,
|
|
3587
|
+
trailing: suffix,
|
|
3588
|
+
interactive,
|
|
3589
|
+
onActivate: enterEdit,
|
|
3590
|
+
children: opt?.label ?? current
|
|
3591
|
+
}
|
|
3592
|
+
);
|
|
3593
|
+
if (label || error || description) {
|
|
3594
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3595
|
+
Field,
|
|
3596
|
+
{
|
|
3597
|
+
label,
|
|
3598
|
+
description,
|
|
3599
|
+
error,
|
|
3600
|
+
required,
|
|
3601
|
+
htmlFor: selectId,
|
|
3602
|
+
size,
|
|
3603
|
+
children: display
|
|
3604
|
+
}
|
|
3605
|
+
);
|
|
3606
|
+
}
|
|
3607
|
+
return display;
|
|
3608
|
+
}
|
|
3479
3609
|
const isControlled = value !== void 0;
|
|
3480
3610
|
const resolvedDefault = !isControlled && defaultValue === void 0 && placeholder ? "" : defaultValue;
|
|
3481
3611
|
const select = /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3510,6 +3640,11 @@ var NativeSelect = react.forwardRef(
|
|
|
3510
3640
|
},
|
|
3511
3641
|
...props,
|
|
3512
3642
|
...isControlled ? { value } : { defaultValue: resolvedDefault },
|
|
3643
|
+
autoFocus: interactive || props.autoFocus,
|
|
3644
|
+
onBlur: (e) => {
|
|
3645
|
+
props.onBlur?.(e);
|
|
3646
|
+
if (interactive) exitEdit();
|
|
3647
|
+
},
|
|
3513
3648
|
children: [
|
|
3514
3649
|
placeholder && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: true, children: placeholder }),
|
|
3515
3650
|
list.map(
|
|
@@ -3564,11 +3699,14 @@ var ListboxSelect = react.forwardRef(
|
|
|
3564
3699
|
createLabel = "Create",
|
|
3565
3700
|
selectedSuffix = "selected",
|
|
3566
3701
|
indicator = "check",
|
|
3702
|
+
mode,
|
|
3567
3703
|
value: controlledSingleValue,
|
|
3568
3704
|
defaultValue: defaultSingleValue
|
|
3569
3705
|
}, _ref) => {
|
|
3570
3706
|
const autoId = react.useId();
|
|
3571
3707
|
const selectId = id ?? autoId;
|
|
3708
|
+
const resolvedMode = useFieldMode(mode);
|
|
3709
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
3572
3710
|
const textInputEnabled = searchable || creatable;
|
|
3573
3711
|
const [open, setOpen] = react.useState(false);
|
|
3574
3712
|
const [search2, setSearch] = react.useState("");
|
|
@@ -3695,6 +3833,27 @@ var ListboxSelect = react.forwardRef(
|
|
|
3695
3833
|
}
|
|
3696
3834
|
}
|
|
3697
3835
|
};
|
|
3836
|
+
if (!showControl) {
|
|
3837
|
+
const labels = multiple ? currentMulti.map(
|
|
3838
|
+
(v) => resolvedOptions.find((o) => o.value === v)?.label ?? v
|
|
3839
|
+
) : currentSingle ? [resolvedOptions.find((o) => o.value === currentSingle)?.label ?? currentSingle] : [];
|
|
3840
|
+
const display = /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, interactive, onActivate: enterEdit, children: labels.join(", ") });
|
|
3841
|
+
if (label || error || description) {
|
|
3842
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3843
|
+
Field,
|
|
3844
|
+
{
|
|
3845
|
+
label,
|
|
3846
|
+
description,
|
|
3847
|
+
error,
|
|
3848
|
+
required,
|
|
3849
|
+
htmlFor: selectId,
|
|
3850
|
+
size,
|
|
3851
|
+
children: display
|
|
3852
|
+
}
|
|
3853
|
+
);
|
|
3854
|
+
}
|
|
3855
|
+
return display;
|
|
3856
|
+
}
|
|
3698
3857
|
const trigger = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3699
3858
|
"button",
|
|
3700
3859
|
{
|
|
@@ -3702,6 +3861,7 @@ var ListboxSelect = react.forwardRef(
|
|
|
3702
3861
|
type: "button",
|
|
3703
3862
|
id: selectId,
|
|
3704
3863
|
disabled,
|
|
3864
|
+
autoFocus: interactive,
|
|
3705
3865
|
onClick: () => setOpen((o) => !o),
|
|
3706
3866
|
onKeyDown: handleKeyDown,
|
|
3707
3867
|
role: "combobox",
|
|
@@ -3823,10 +3983,21 @@ var ListboxSelect = react.forwardRef(
|
|
|
3823
3983
|
]
|
|
3824
3984
|
}
|
|
3825
3985
|
) });
|
|
3826
|
-
const content = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3986
|
+
const content = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3987
|
+
"div",
|
|
3988
|
+
{
|
|
3989
|
+
className: "relative",
|
|
3990
|
+
onBlur: (e) => {
|
|
3991
|
+
if (interactive && !open && !e.currentTarget.contains(e.relatedTarget)) {
|
|
3992
|
+
exitEdit();
|
|
3993
|
+
}
|
|
3994
|
+
},
|
|
3995
|
+
children: [
|
|
3996
|
+
trigger,
|
|
3997
|
+
dropdown
|
|
3998
|
+
]
|
|
3999
|
+
}
|
|
4000
|
+
);
|
|
3830
4001
|
if (label || error || description) {
|
|
3831
4002
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3832
4003
|
Field,
|
|
@@ -3870,11 +4041,14 @@ var Checkbox = react.forwardRef(
|
|
|
3870
4041
|
checked: controlledChecked,
|
|
3871
4042
|
defaultChecked = false,
|
|
3872
4043
|
onCheckedChange,
|
|
3873
|
-
indeterminate
|
|
4044
|
+
indeterminate,
|
|
4045
|
+
mode
|
|
3874
4046
|
}, ref) => {
|
|
3875
4047
|
const autoId = react.useId();
|
|
3876
4048
|
const checkboxId = id ?? autoId;
|
|
3877
4049
|
const internalRef = react.useRef(null);
|
|
4050
|
+
const resolvedMode = useFieldMode(mode);
|
|
4051
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
3878
4052
|
const [checked, setChecked] = useControllableState(
|
|
3879
4053
|
controlledChecked,
|
|
3880
4054
|
defaultChecked,
|
|
@@ -3893,8 +4067,32 @@ var Checkbox = react.forwardRef(
|
|
|
3893
4067
|
lg: "h-5 w-5",
|
|
3894
4068
|
xl: "h-6 w-6"
|
|
3895
4069
|
}[size];
|
|
4070
|
+
const glyph = indeterminate ? "\u2014" : checked ? "\u2713" : "\u2715";
|
|
3896
4071
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-checkbox": "", className: cn("flex items-start gap-2", className), children: [
|
|
3897
|
-
|
|
4072
|
+
!showControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4073
|
+
"span",
|
|
4074
|
+
{
|
|
4075
|
+
"data-react-fancy-display": "",
|
|
4076
|
+
"data-mode": "view",
|
|
4077
|
+
role: interactive ? "button" : void 0,
|
|
4078
|
+
tabIndex: interactive ? 0 : void 0,
|
|
4079
|
+
title: interactive ? "Click to edit" : void 0,
|
|
4080
|
+
onClick: interactive ? enterEdit : void 0,
|
|
4081
|
+
onKeyDown: interactive ? (e) => {
|
|
4082
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
4083
|
+
e.preventDefault();
|
|
4084
|
+
enterEdit();
|
|
4085
|
+
}
|
|
4086
|
+
} : void 0,
|
|
4087
|
+
className: cn(
|
|
4088
|
+
"flex shrink-0 items-center justify-center text-zinc-700 dark:text-zinc-200",
|
|
4089
|
+
sizeClasses6,
|
|
4090
|
+
interactive && "cursor-pointer rounded outline-none transition-colors hover:text-zinc-900 focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:text-white"
|
|
4091
|
+
),
|
|
4092
|
+
"aria-hidden": interactive ? void 0 : "true",
|
|
4093
|
+
children: glyph
|
|
4094
|
+
}
|
|
4095
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3898
4096
|
"input",
|
|
3899
4097
|
{
|
|
3900
4098
|
ref: (node) => {
|
|
@@ -3911,6 +4109,10 @@ var Checkbox = react.forwardRef(
|
|
|
3911
4109
|
disabled,
|
|
3912
4110
|
required,
|
|
3913
4111
|
checked,
|
|
4112
|
+
autoFocus: interactive,
|
|
4113
|
+
onBlur: () => {
|
|
4114
|
+
if (interactive) exitEdit();
|
|
4115
|
+
},
|
|
3914
4116
|
onChange: (e) => setChecked(e.target.checked),
|
|
3915
4117
|
className: cn(
|
|
3916
4118
|
sizeClasses6,
|
|
@@ -3956,9 +4158,12 @@ function CheckboxGroup({
|
|
|
3956
4158
|
value: controlledValue,
|
|
3957
4159
|
defaultValue = [],
|
|
3958
4160
|
onValueChange,
|
|
3959
|
-
orientation = "vertical"
|
|
4161
|
+
orientation = "vertical",
|
|
4162
|
+
mode
|
|
3960
4163
|
}) {
|
|
3961
4164
|
const groupId = react.useId();
|
|
4165
|
+
const resolvedMode = useFieldMode(mode);
|
|
4166
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
3962
4167
|
const [value, setValue] = useControllableState(
|
|
3963
4168
|
controlledValue,
|
|
3964
4169
|
defaultValue,
|
|
@@ -3975,10 +4180,13 @@ function CheckboxGroup({
|
|
|
3975
4180
|
lg: "h-5 w-5",
|
|
3976
4181
|
xl: "h-6 w-6"
|
|
3977
4182
|
}[size];
|
|
3978
|
-
const content = /* @__PURE__ */ jsxRuntime.jsx(
|
|
4183
|
+
const content = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, interactive, onActivate: enterEdit, children: list.map(resolveOption).filter((o) => value.includes(o.value)).map((o) => o.label).join(", ") }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3979
4184
|
"div",
|
|
3980
4185
|
{
|
|
3981
4186
|
"data-react-fancy-checkbox-group": "",
|
|
4187
|
+
onBlur: (e) => {
|
|
4188
|
+
if (interactive && !e.currentTarget.contains(e.relatedTarget)) exitEdit();
|
|
4189
|
+
},
|
|
3982
4190
|
className: cn(
|
|
3983
4191
|
"flex gap-3",
|
|
3984
4192
|
orientation === "vertical" ? "flex-col" : "flex-row flex-wrap",
|
|
@@ -3998,6 +4206,7 @@ function CheckboxGroup({
|
|
|
3998
4206
|
value: String(resolved.value),
|
|
3999
4207
|
checked: isChecked,
|
|
4000
4208
|
disabled: disabled || resolved.disabled,
|
|
4209
|
+
autoFocus: interactive && index === 0,
|
|
4001
4210
|
onChange: () => handleToggle(resolved.value),
|
|
4002
4211
|
className: cn(
|
|
4003
4212
|
sizeClasses6,
|
|
@@ -4055,10 +4264,13 @@ function RadioGroup({
|
|
|
4055
4264
|
value: controlledValue,
|
|
4056
4265
|
defaultValue,
|
|
4057
4266
|
onValueChange,
|
|
4058
|
-
orientation = "vertical"
|
|
4267
|
+
orientation = "vertical",
|
|
4268
|
+
mode
|
|
4059
4269
|
}) {
|
|
4060
4270
|
const groupId = react.useId();
|
|
4061
4271
|
const radioName = name ?? groupId;
|
|
4272
|
+
const resolvedMode = useFieldMode(mode);
|
|
4273
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
4062
4274
|
const [value, setValue] = useControllableState(
|
|
4063
4275
|
controlledValue,
|
|
4064
4276
|
defaultValue,
|
|
@@ -4071,11 +4283,15 @@ function RadioGroup({
|
|
|
4071
4283
|
lg: "h-5 w-5",
|
|
4072
4284
|
xl: "h-6 w-6"
|
|
4073
4285
|
}[size];
|
|
4074
|
-
const
|
|
4286
|
+
const selectedIndex = list.map(resolveOption).findIndex((o) => o.value === value);
|
|
4287
|
+
const content = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, interactive, onActivate: enterEdit, children: list.map(resolveOption).find((o) => o.value === value)?.label }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4075
4288
|
"div",
|
|
4076
4289
|
{
|
|
4077
4290
|
"data-react-fancy-radio-group": "",
|
|
4078
4291
|
role: "radiogroup",
|
|
4292
|
+
onBlur: (e) => {
|
|
4293
|
+
if (interactive && !e.currentTarget.contains(e.relatedTarget)) exitEdit();
|
|
4294
|
+
},
|
|
4079
4295
|
className: cn(
|
|
4080
4296
|
"flex gap-3",
|
|
4081
4297
|
orientation === "vertical" ? "flex-col" : "flex-row flex-wrap",
|
|
@@ -4085,6 +4301,7 @@ function RadioGroup({
|
|
|
4085
4301
|
const resolved = resolveOption(option);
|
|
4086
4302
|
const optionId = `${groupId}-${index}`;
|
|
4087
4303
|
const isSelected = value === resolved.value;
|
|
4304
|
+
const shouldAutoFocus = interactive && (selectedIndex === -1 ? index === 0 : isSelected);
|
|
4088
4305
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
4089
4306
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4090
4307
|
"input",
|
|
@@ -4095,6 +4312,7 @@ function RadioGroup({
|
|
|
4095
4312
|
value: String(resolved.value),
|
|
4096
4313
|
checked: isSelected,
|
|
4097
4314
|
disabled: disabled || resolved.disabled,
|
|
4315
|
+
autoFocus: shouldAutoFocus,
|
|
4098
4316
|
onChange: () => setValue(resolved.value),
|
|
4099
4317
|
className: cn(
|
|
4100
4318
|
sizeClasses6,
|
|
@@ -4179,10 +4397,13 @@ var Switch = react.forwardRef(
|
|
|
4179
4397
|
checked: controlledChecked,
|
|
4180
4398
|
defaultChecked = false,
|
|
4181
4399
|
onCheckedChange,
|
|
4182
|
-
color = "blue"
|
|
4400
|
+
color = "blue",
|
|
4401
|
+
mode
|
|
4183
4402
|
}, ref) => {
|
|
4184
4403
|
const autoId = react.useId();
|
|
4185
4404
|
const switchId = id ?? autoId;
|
|
4405
|
+
const resolvedMode = useFieldMode(mode);
|
|
4406
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
4186
4407
|
const [checked, setChecked] = useControllableState(
|
|
4187
4408
|
controlledChecked,
|
|
4188
4409
|
defaultChecked,
|
|
@@ -4210,7 +4431,28 @@ var Switch = react.forwardRef(
|
|
|
4210
4431
|
xl: "translate-x-6"
|
|
4211
4432
|
}[size];
|
|
4212
4433
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-switch": "", className: cn("flex items-start gap-2", className), children: [
|
|
4213
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4434
|
+
!showControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4435
|
+
"span",
|
|
4436
|
+
{
|
|
4437
|
+
"data-react-fancy-display": "",
|
|
4438
|
+
"data-mode": "view",
|
|
4439
|
+
role: interactive ? "button" : void 0,
|
|
4440
|
+
tabIndex: interactive ? 0 : void 0,
|
|
4441
|
+
title: interactive ? "Click to edit" : void 0,
|
|
4442
|
+
onClick: interactive ? enterEdit : void 0,
|
|
4443
|
+
onKeyDown: interactive ? (e) => {
|
|
4444
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
4445
|
+
e.preventDefault();
|
|
4446
|
+
enterEdit();
|
|
4447
|
+
}
|
|
4448
|
+
} : void 0,
|
|
4449
|
+
className: cn(
|
|
4450
|
+
"text-sm font-medium text-zinc-700 dark:text-zinc-200",
|
|
4451
|
+
interactive && "cursor-pointer rounded-md outline-none transition-colors hover:text-zinc-900 focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:text-white"
|
|
4452
|
+
),
|
|
4453
|
+
children: checked ? "On" : "Off"
|
|
4454
|
+
}
|
|
4455
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4214
4456
|
"button",
|
|
4215
4457
|
{
|
|
4216
4458
|
ref,
|
|
@@ -4219,6 +4461,10 @@ var Switch = react.forwardRef(
|
|
|
4219
4461
|
role: "switch",
|
|
4220
4462
|
"aria-checked": checked,
|
|
4221
4463
|
disabled,
|
|
4464
|
+
autoFocus: interactive,
|
|
4465
|
+
onBlur: () => {
|
|
4466
|
+
if (interactive) exitEdit();
|
|
4467
|
+
},
|
|
4222
4468
|
onClick: () => setChecked(!checked),
|
|
4223
4469
|
className: cn(
|
|
4224
4470
|
"relative inline-flex shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500/40 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
@@ -4324,15 +4570,27 @@ var SingleSlider = react.forwardRef(
|
|
|
4324
4570
|
marks,
|
|
4325
4571
|
prefix,
|
|
4326
4572
|
suffix,
|
|
4573
|
+
mode,
|
|
4327
4574
|
...rest
|
|
4328
4575
|
}, ref) => {
|
|
4329
4576
|
const singleProps = rest;
|
|
4577
|
+
const resolvedMode = useFieldMode(mode);
|
|
4578
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
4330
4579
|
const [value, setValue] = useControllableState(
|
|
4331
4580
|
singleProps.value,
|
|
4332
4581
|
singleProps.defaultValue ?? min,
|
|
4333
4582
|
singleProps.onValueChange
|
|
4334
4583
|
);
|
|
4335
|
-
const slider = /* @__PURE__ */ jsxRuntime.
|
|
4584
|
+
const slider = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4585
|
+
DisplayValue,
|
|
4586
|
+
{
|
|
4587
|
+
size,
|
|
4588
|
+
className,
|
|
4589
|
+
interactive,
|
|
4590
|
+
onActivate: enterEdit,
|
|
4591
|
+
children: `${prefix ?? ""}${value}${suffix ?? ""}`
|
|
4592
|
+
}
|
|
4593
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-react-fancy-slider": "", className: cn("flex flex-col gap-1", className), children: [
|
|
4336
4594
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
4337
4595
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4338
4596
|
"input",
|
|
@@ -4346,6 +4604,10 @@ var SingleSlider = react.forwardRef(
|
|
|
4346
4604
|
step,
|
|
4347
4605
|
value,
|
|
4348
4606
|
disabled,
|
|
4607
|
+
autoFocus: interactive,
|
|
4608
|
+
onBlur: () => {
|
|
4609
|
+
if (interactive) exitEdit();
|
|
4610
|
+
},
|
|
4349
4611
|
onChange: (e) => setValue(Number(e.target.value)),
|
|
4350
4612
|
className: cn(
|
|
4351
4613
|
"w-full cursor-pointer accent-blue-600 disabled:cursor-not-allowed disabled:opacity-50",
|
|
@@ -4394,9 +4656,12 @@ var RangeSlider = react.forwardRef(
|
|
|
4394
4656
|
marks,
|
|
4395
4657
|
prefix,
|
|
4396
4658
|
suffix,
|
|
4659
|
+
mode,
|
|
4397
4660
|
...rest
|
|
4398
4661
|
}, ref) => {
|
|
4399
4662
|
const rangeProps = rest;
|
|
4663
|
+
const resolvedMode = useFieldMode(mode);
|
|
4664
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
4400
4665
|
const [value, setValue] = useControllableState(
|
|
4401
4666
|
rangeProps.value,
|
|
4402
4667
|
rangeProps.defaultValue ?? [min, max],
|
|
@@ -4410,61 +4675,81 @@ var RangeSlider = react.forwardRef(
|
|
|
4410
4675
|
};
|
|
4411
4676
|
const leftPercent = (value[0] - min) / (max - min) * 100;
|
|
4412
4677
|
const rightPercent = (value[1] - min) / (max - min) * 100;
|
|
4413
|
-
const slider = /* @__PURE__ */ jsxRuntime.
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4678
|
+
const slider = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4679
|
+
DisplayValue,
|
|
4680
|
+
{
|
|
4681
|
+
size,
|
|
4682
|
+
className,
|
|
4683
|
+
interactive,
|
|
4684
|
+
onActivate: enterEdit,
|
|
4685
|
+
children: `${prefix ?? ""}${value[0]}${suffix ?? ""}\u2013${prefix ?? ""}${value[1]}${suffix ?? ""}`
|
|
4686
|
+
}
|
|
4687
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4688
|
+
"div",
|
|
4689
|
+
{
|
|
4690
|
+
"data-react-fancy-slider": "",
|
|
4691
|
+
className: cn("flex flex-col gap-1", className),
|
|
4692
|
+
onBlur: (e) => {
|
|
4693
|
+
if (interactive && !e.currentTarget.contains(e.relatedTarget)) exitEdit();
|
|
4694
|
+
},
|
|
4695
|
+
children: [
|
|
4696
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
4697
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full", children: [
|
|
4698
|
+
/* @__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" }),
|
|
4699
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4700
|
+
"div",
|
|
4701
|
+
{
|
|
4702
|
+
className: "pointer-events-none absolute top-1/2 h-1.5 -translate-y-1/2 rounded-full bg-blue-500",
|
|
4703
|
+
style: { left: `${leftPercent}%`, width: `${rightPercent - leftPercent}%` }
|
|
4704
|
+
}
|
|
4705
|
+
),
|
|
4706
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4707
|
+
"input",
|
|
4708
|
+
{
|
|
4709
|
+
ref,
|
|
4710
|
+
type: "range",
|
|
4711
|
+
min,
|
|
4712
|
+
max,
|
|
4713
|
+
step,
|
|
4714
|
+
value: value[0],
|
|
4715
|
+
disabled,
|
|
4716
|
+
autoFocus: interactive,
|
|
4717
|
+
onChange: (e) => handleMin(Number(e.target.value)),
|
|
4718
|
+
className: cn(
|
|
4719
|
+
"pointer-events-none absolute w-full cursor-pointer appearance-none bg-transparent [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-blue-600 [&::-webkit-slider-thumb]:shadow",
|
|
4720
|
+
dirtyRingClasses(dirty)
|
|
4721
|
+
)
|
|
4722
|
+
}
|
|
4723
|
+
),
|
|
4724
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4725
|
+
"input",
|
|
4726
|
+
{
|
|
4727
|
+
type: "range",
|
|
4728
|
+
min,
|
|
4729
|
+
max,
|
|
4730
|
+
step,
|
|
4731
|
+
value: value[1],
|
|
4732
|
+
disabled,
|
|
4733
|
+
onChange: (e) => handleMax(Number(e.target.value)),
|
|
4734
|
+
className: "pointer-events-none absolute w-full cursor-pointer appearance-none bg-transparent [&::-webkit-slider-thumb]:pointer-events-auto [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-blue-600 [&::-webkit-slider-thumb]:shadow"
|
|
4735
|
+
}
|
|
4736
|
+
),
|
|
4737
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-6" })
|
|
4738
|
+
] }),
|
|
4739
|
+
showValue && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-[6ch] shrink-0 whitespace-nowrap text-right text-sm font-medium text-zinc-700 dark:text-zinc-300", children: [
|
|
4740
|
+
prefix,
|
|
4741
|
+
value[0],
|
|
4742
|
+
suffix,
|
|
4743
|
+
"\u2013",
|
|
4744
|
+
prefix,
|
|
4745
|
+
value[1],
|
|
4746
|
+
suffix
|
|
4747
|
+
] })
|
|
4748
|
+
] }),
|
|
4749
|
+
marks && marks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(SliderMarks, { marks, min, max })
|
|
4750
|
+
]
|
|
4751
|
+
}
|
|
4752
|
+
);
|
|
4468
4753
|
if (label || error || description) {
|
|
4469
4754
|
return /* @__PURE__ */ jsxRuntime.jsx(Field, { label, description, error, required, htmlFor: id, size, children: slider });
|
|
4470
4755
|
}
|
|
@@ -4512,10 +4797,13 @@ function MultiSwitch({
|
|
|
4512
4797
|
value: controlledValue,
|
|
4513
4798
|
defaultValue,
|
|
4514
4799
|
onValueChange,
|
|
4515
|
-
linear
|
|
4800
|
+
linear,
|
|
4801
|
+
mode
|
|
4516
4802
|
}) {
|
|
4517
4803
|
const resolvedOptions = list.map(resolveOption);
|
|
4518
4804
|
const fallback = defaultValue ?? resolvedOptions[0]?.value;
|
|
4805
|
+
const resolvedMode = useFieldMode(mode);
|
|
4806
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
4519
4807
|
const [value, setValue] = useControllableState(controlledValue, fallback, onValueChange);
|
|
4520
4808
|
const containerRef = react.useRef(null);
|
|
4521
4809
|
const itemRefs = react.useRef([]);
|
|
@@ -4540,13 +4828,16 @@ function MultiSwitch({
|
|
|
4540
4828
|
react.useEffect(() => {
|
|
4541
4829
|
updateIndicator();
|
|
4542
4830
|
}, [updateIndicator]);
|
|
4543
|
-
const control = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4831
|
+
const control = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(DisplayValue, { size, interactive, onActivate: enterEdit, children: resolvedOptions.find((o) => o.value === value)?.label }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4544
4832
|
"div",
|
|
4545
4833
|
{
|
|
4546
4834
|
ref: containerRef,
|
|
4547
4835
|
"data-react-fancy-multi-switch": "",
|
|
4548
4836
|
role: "radiogroup",
|
|
4549
4837
|
id,
|
|
4838
|
+
onBlur: (e) => {
|
|
4839
|
+
if (interactive && !e.currentTarget.contains(e.relatedTarget)) exitEdit();
|
|
4840
|
+
},
|
|
4550
4841
|
className: cn(
|
|
4551
4842
|
"relative inline-flex rounded-lg border border-zinc-300 bg-zinc-100 dark:border-zinc-700 dark:bg-zinc-800",
|
|
4552
4843
|
dirty && "ring-2 ring-amber-400/50",
|
|
@@ -4574,6 +4865,7 @@ function MultiSwitch({
|
|
|
4574
4865
|
role: "radio",
|
|
4575
4866
|
"aria-checked": isSelected,
|
|
4576
4867
|
disabled: disabled || option.disabled,
|
|
4868
|
+
autoFocus: interactive && (selectedIndex === -1 ? index === 0 : isSelected),
|
|
4577
4869
|
onClick: () => {
|
|
4578
4870
|
if (linear) {
|
|
4579
4871
|
const nextIndex = (selectedIndex + 1) % resolvedOptions.length;
|
|
@@ -4603,6 +4895,22 @@ function MultiSwitch({
|
|
|
4603
4895
|
return control;
|
|
4604
4896
|
}
|
|
4605
4897
|
MultiSwitch.displayName = "MultiSwitch";
|
|
4898
|
+
function formatDateValue(iso, includeTime) {
|
|
4899
|
+
if (!iso) return "";
|
|
4900
|
+
const date = new Date(iso);
|
|
4901
|
+
if (Number.isNaN(date.getTime())) return iso;
|
|
4902
|
+
return includeTime ? date.toLocaleString(void 0, {
|
|
4903
|
+
year: "numeric",
|
|
4904
|
+
month: "short",
|
|
4905
|
+
day: "numeric",
|
|
4906
|
+
hour: "2-digit",
|
|
4907
|
+
minute: "2-digit"
|
|
4908
|
+
}) : date.toLocaleDateString(void 0, {
|
|
4909
|
+
year: "numeric",
|
|
4910
|
+
month: "short",
|
|
4911
|
+
day: "numeric"
|
|
4912
|
+
});
|
|
4913
|
+
}
|
|
4606
4914
|
var DatePicker = react.forwardRef(
|
|
4607
4915
|
(props, ref) => {
|
|
4608
4916
|
const {
|
|
@@ -4669,17 +4977,30 @@ var SingleDatePicker = react.forwardRef(
|
|
|
4669
4977
|
name,
|
|
4670
4978
|
min,
|
|
4671
4979
|
max,
|
|
4980
|
+
includeTime,
|
|
4981
|
+
mode,
|
|
4672
4982
|
inputType,
|
|
4673
4983
|
inputClasses,
|
|
4674
4984
|
...rest
|
|
4675
4985
|
}, ref) => {
|
|
4676
4986
|
const singleProps = rest;
|
|
4987
|
+
const resolvedMode = useFieldMode(mode);
|
|
4988
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
4677
4989
|
const [value, setValue] = useControllableState(
|
|
4678
4990
|
singleProps.value,
|
|
4679
4991
|
singleProps.defaultValue ?? "",
|
|
4680
4992
|
singleProps.onValueChange
|
|
4681
4993
|
);
|
|
4682
|
-
const input = /* @__PURE__ */ jsxRuntime.jsx(
|
|
4994
|
+
const input = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
4995
|
+
DisplayValue,
|
|
4996
|
+
{
|
|
4997
|
+
size,
|
|
4998
|
+
className,
|
|
4999
|
+
interactive,
|
|
5000
|
+
onActivate: enterEdit,
|
|
5001
|
+
children: formatDateValue(value, includeTime)
|
|
5002
|
+
}
|
|
5003
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
4683
5004
|
"input",
|
|
4684
5005
|
{
|
|
4685
5006
|
"data-react-fancy-date-picker": "",
|
|
@@ -4693,7 +5014,11 @@ var SingleDatePicker = react.forwardRef(
|
|
|
4693
5014
|
disabled,
|
|
4694
5015
|
required,
|
|
4695
5016
|
onChange: (e) => setValue(e.target.value),
|
|
4696
|
-
className: cn(inputClasses, className)
|
|
5017
|
+
className: cn(inputClasses, className),
|
|
5018
|
+
autoFocus: interactive,
|
|
5019
|
+
onBlur: () => {
|
|
5020
|
+
if (interactive) exitEdit();
|
|
5021
|
+
}
|
|
4697
5022
|
}
|
|
4698
5023
|
);
|
|
4699
5024
|
if (label || error || description) {
|
|
@@ -4727,48 +5052,72 @@ var RangeDatePicker = react.forwardRef(
|
|
|
4727
5052
|
name,
|
|
4728
5053
|
min,
|
|
4729
5054
|
max,
|
|
5055
|
+
includeTime,
|
|
5056
|
+
mode,
|
|
4730
5057
|
inputType,
|
|
4731
5058
|
inputClasses,
|
|
4732
5059
|
...rest
|
|
4733
5060
|
}, ref) => {
|
|
4734
5061
|
const rangeProps = rest;
|
|
5062
|
+
const resolvedMode = useFieldMode(mode);
|
|
5063
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
4735
5064
|
const [value, setValue] = useControllableState(
|
|
4736
5065
|
rangeProps.value,
|
|
4737
5066
|
rangeProps.defaultValue ?? ["", ""],
|
|
4738
5067
|
rangeProps.onValueChange
|
|
4739
5068
|
);
|
|
4740
|
-
const input = /* @__PURE__ */ jsxRuntime.
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
5069
|
+
const input = !showControl ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5070
|
+
DisplayValue,
|
|
5071
|
+
{
|
|
5072
|
+
size,
|
|
5073
|
+
className,
|
|
5074
|
+
interactive,
|
|
5075
|
+
onActivate: enterEdit,
|
|
5076
|
+
children: value[0] || value[1] ? `${formatDateValue(value[0], includeTime)} \u2013 ${formatDateValue(value[1], includeTime)}` : ""
|
|
5077
|
+
}
|
|
5078
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5079
|
+
"div",
|
|
5080
|
+
{
|
|
5081
|
+
"data-react-fancy-date-picker": "",
|
|
5082
|
+
className: cn("flex items-center gap-2", className),
|
|
5083
|
+
onBlur: (e) => {
|
|
5084
|
+
if (interactive && !e.currentTarget.contains(e.relatedTarget)) exitEdit();
|
|
5085
|
+
},
|
|
5086
|
+
children: [
|
|
5087
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5088
|
+
"input",
|
|
5089
|
+
{
|
|
5090
|
+
ref,
|
|
5091
|
+
id,
|
|
5092
|
+
type: inputType,
|
|
5093
|
+
name: name ? `${name}_start` : void 0,
|
|
5094
|
+
min,
|
|
5095
|
+
max: value[1] || max,
|
|
5096
|
+
value: value[0],
|
|
5097
|
+
disabled,
|
|
5098
|
+
required,
|
|
5099
|
+
onChange: (e) => setValue([e.target.value, value[1]]),
|
|
5100
|
+
className: inputClasses,
|
|
5101
|
+
autoFocus: interactive
|
|
5102
|
+
}
|
|
5103
|
+
),
|
|
5104
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-zinc-500 dark:text-zinc-400", children: "to" }),
|
|
5105
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5106
|
+
"input",
|
|
5107
|
+
{
|
|
5108
|
+
type: inputType,
|
|
5109
|
+
name: name ? `${name}_end` : void 0,
|
|
5110
|
+
min: value[0] || min,
|
|
5111
|
+
max,
|
|
5112
|
+
value: value[1],
|
|
5113
|
+
disabled,
|
|
5114
|
+
onChange: (e) => setValue([value[0], e.target.value]),
|
|
5115
|
+
className: inputClasses
|
|
5116
|
+
}
|
|
5117
|
+
)
|
|
5118
|
+
]
|
|
5119
|
+
}
|
|
5120
|
+
);
|
|
4772
5121
|
if (label || error || description) {
|
|
4773
5122
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4774
5123
|
Field,
|
|
@@ -4787,6 +5136,13 @@ var RangeDatePicker = react.forwardRef(
|
|
|
4787
5136
|
}
|
|
4788
5137
|
);
|
|
4789
5138
|
RangeDatePicker.displayName = "RangeDatePicker";
|
|
5139
|
+
function FormProvider({ mode = "edit", children }) {
|
|
5140
|
+
const value = react.useMemo(() => ({ mode }), [mode]);
|
|
5141
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FieldModeContext.Provider, { value, children });
|
|
5142
|
+
}
|
|
5143
|
+
function Form({ mode, children, ...formProps }) {
|
|
5144
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FormProvider, { mode, children: /* @__PURE__ */ jsxRuntime.jsx("form", { "data-react-fancy-form": "", ...formProps, children }) });
|
|
5145
|
+
}
|
|
4790
5146
|
var CarouselContext = react.createContext(null);
|
|
4791
5147
|
CarouselContext.displayName = "CarouselContext";
|
|
4792
5148
|
function useCarousel() {
|
|
@@ -5126,13 +5482,16 @@ var ColorPicker = react.forwardRef(
|
|
|
5126
5482
|
size = "md",
|
|
5127
5483
|
variant = "outline",
|
|
5128
5484
|
disabled = false,
|
|
5129
|
-
className
|
|
5485
|
+
className,
|
|
5486
|
+
mode
|
|
5130
5487
|
}, ref) => {
|
|
5131
5488
|
const [color, setColor] = useControllableState(
|
|
5132
5489
|
value,
|
|
5133
5490
|
defaultValue,
|
|
5134
5491
|
onChange
|
|
5135
5492
|
);
|
|
5493
|
+
const resolvedMode = useFieldMode(mode);
|
|
5494
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
5136
5495
|
const inputRef = react.useRef(null);
|
|
5137
5496
|
const datalistId = react.useId();
|
|
5138
5497
|
const handleChange = (e) => {
|
|
@@ -5143,18 +5502,72 @@ var ColorPicker = react.forwardRef(
|
|
|
5143
5502
|
inputRef.current?.click();
|
|
5144
5503
|
}
|
|
5145
5504
|
};
|
|
5505
|
+
if (!showControl) {
|
|
5506
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5507
|
+
"div",
|
|
5508
|
+
{
|
|
5509
|
+
ref,
|
|
5510
|
+
"data-react-fancy-color-picker": "",
|
|
5511
|
+
"data-mode": "view",
|
|
5512
|
+
role: interactive ? "button" : void 0,
|
|
5513
|
+
tabIndex: interactive ? 0 : void 0,
|
|
5514
|
+
title: interactive ? "Click to edit" : void 0,
|
|
5515
|
+
onClick: interactive ? enterEdit : void 0,
|
|
5516
|
+
onKeyDown: interactive ? (e) => {
|
|
5517
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
5518
|
+
e.preventDefault();
|
|
5519
|
+
enterEdit();
|
|
5520
|
+
}
|
|
5521
|
+
} : void 0,
|
|
5522
|
+
className: cn(
|
|
5523
|
+
"inline-flex items-center gap-2",
|
|
5524
|
+
interactive && "cursor-pointer rounded-md outline-none transition-opacity hover:opacity-80 focus-visible:ring-2 focus-visible:ring-blue-500/40",
|
|
5525
|
+
className
|
|
5526
|
+
),
|
|
5527
|
+
children: [
|
|
5528
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5529
|
+
"span",
|
|
5530
|
+
{
|
|
5531
|
+
className: cn(
|
|
5532
|
+
"shrink-0 rounded-full",
|
|
5533
|
+
SWATCH_SIZES[size],
|
|
5534
|
+
variant === "outline" && "ring-1 ring-zinc-300 dark:ring-zinc-600"
|
|
5535
|
+
),
|
|
5536
|
+
style: { backgroundColor: color },
|
|
5537
|
+
"aria-label": `Color: ${color}`
|
|
5538
|
+
}
|
|
5539
|
+
),
|
|
5540
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5541
|
+
"span",
|
|
5542
|
+
{
|
|
5543
|
+
className: cn(
|
|
5544
|
+
"select-all font-mono uppercase",
|
|
5545
|
+
TEXT_SIZES[size],
|
|
5546
|
+
"text-zinc-700 dark:text-zinc-300"
|
|
5547
|
+
),
|
|
5548
|
+
children: color.toUpperCase()
|
|
5549
|
+
}
|
|
5550
|
+
)
|
|
5551
|
+
]
|
|
5552
|
+
}
|
|
5553
|
+
);
|
|
5554
|
+
}
|
|
5146
5555
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5147
5556
|
"div",
|
|
5148
5557
|
{
|
|
5149
5558
|
ref,
|
|
5150
5559
|
"data-react-fancy-color-picker": "",
|
|
5151
5560
|
className: cn("inline-flex items-center gap-2", className),
|
|
5561
|
+
onBlur: (e) => {
|
|
5562
|
+
if (interactive && !e.currentTarget.contains(e.relatedTarget)) exitEdit();
|
|
5563
|
+
},
|
|
5152
5564
|
children: [
|
|
5153
5565
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5154
5566
|
"button",
|
|
5155
5567
|
{
|
|
5156
5568
|
type: "button",
|
|
5157
5569
|
disabled,
|
|
5570
|
+
autoFocus: interactive,
|
|
5158
5571
|
onClick: handleSwatchClick,
|
|
5159
5572
|
className: cn(
|
|
5160
5573
|
"relative shrink-0 rounded-full transition-shadow",
|
|
@@ -6032,6 +6445,14 @@ var Badge = react.forwardRef(
|
|
|
6032
6445
|
}
|
|
6033
6446
|
);
|
|
6034
6447
|
Badge.displayName = "Badge";
|
|
6448
|
+
var glowColors = {
|
|
6449
|
+
on: "#a855f7",
|
|
6450
|
+
// violet — neutral
|
|
6451
|
+
xp: "#22c55e",
|
|
6452
|
+
// green
|
|
6453
|
+
achievement: "#f59e0b"
|
|
6454
|
+
// amber
|
|
6455
|
+
};
|
|
6035
6456
|
var containerSizeClasses = {
|
|
6036
6457
|
xs: "h-6 w-6",
|
|
6037
6458
|
sm: "h-8 w-8",
|
|
@@ -6066,8 +6487,10 @@ var Avatar = react.forwardRef(
|
|
|
6066
6487
|
fallback,
|
|
6067
6488
|
size = "md",
|
|
6068
6489
|
status,
|
|
6490
|
+
glow,
|
|
6069
6491
|
className
|
|
6070
6492
|
}, ref) => {
|
|
6493
|
+
const glowKey = glow === true ? "on" : glow || null;
|
|
6071
6494
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6072
6495
|
"div",
|
|
6073
6496
|
{
|
|
@@ -6080,6 +6503,15 @@ var Avatar = react.forwardRef(
|
|
|
6080
6503
|
className
|
|
6081
6504
|
),
|
|
6082
6505
|
children: [
|
|
6506
|
+
glowKey && /* @__PURE__ */ jsxRuntime.jsx(
|
|
6507
|
+
"span",
|
|
6508
|
+
{
|
|
6509
|
+
"aria-hidden": true,
|
|
6510
|
+
"data-react-fancy-avatar-glow": glowKey,
|
|
6511
|
+
className: "fancy-avatar-glow",
|
|
6512
|
+
style: { "--fancy-glow": glowColors[glowKey] }
|
|
6513
|
+
}
|
|
6514
|
+
),
|
|
6083
6515
|
src ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
6084
6516
|
"img",
|
|
6085
6517
|
{
|
|
@@ -8870,13 +9302,16 @@ var Autocomplete = react.forwardRef(
|
|
|
8870
9302
|
loading = false,
|
|
8871
9303
|
emptyMessage = "No results found.",
|
|
8872
9304
|
disabled = false,
|
|
8873
|
-
className
|
|
9305
|
+
className,
|
|
9306
|
+
mode
|
|
8874
9307
|
}, ref) {
|
|
8875
9308
|
const [value, setValue] = useControllableState(
|
|
8876
9309
|
controlledValue,
|
|
8877
9310
|
defaultValue,
|
|
8878
9311
|
onChange
|
|
8879
9312
|
);
|
|
9313
|
+
const resolvedMode = useFieldMode(mode);
|
|
9314
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
8880
9315
|
const [query, setQuery] = react.useState(value);
|
|
8881
9316
|
const [open, setOpen] = react.useState(false);
|
|
8882
9317
|
const [activeIndex, setActiveIndex] = react.useState(-1);
|
|
@@ -8929,63 +9364,105 @@ var Autocomplete = react.forwardRef(
|
|
|
8929
9364
|
if (item && !item.disabled) select(item.value);
|
|
8930
9365
|
}
|
|
8931
9366
|
};
|
|
8932
|
-
|
|
8933
|
-
|
|
8934
|
-
|
|
8935
|
-
{
|
|
8936
|
-
ref: (node) => {
|
|
8937
|
-
anchorRef.current = node;
|
|
8938
|
-
if (typeof ref === "function") ref(node);
|
|
8939
|
-
else if (ref) ref.current = node;
|
|
8940
|
-
},
|
|
8941
|
-
type: "text",
|
|
8942
|
-
value: query,
|
|
8943
|
-
onChange: (e) => {
|
|
8944
|
-
setQuery(e.target.value);
|
|
8945
|
-
setOpen(true);
|
|
8946
|
-
setActiveIndex(-1);
|
|
8947
|
-
},
|
|
8948
|
-
onFocus: () => setOpen(true),
|
|
8949
|
-
onKeyDown: handleKeyDown,
|
|
8950
|
-
placeholder,
|
|
8951
|
-
disabled,
|
|
8952
|
-
role: "combobox",
|
|
8953
|
-
"aria-expanded": open,
|
|
8954
|
-
"aria-autocomplete": "list",
|
|
8955
|
-
className: "w-full rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm text-zinc-900 placeholder:text-zinc-400 outline-none transition-[border-color,box-shadow] duration-150 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/40 dark:border-zinc-700 dark:bg-[#1e1e24] dark:text-zinc-100 dark:placeholder:text-zinc-500 dark:focus:border-blue-400 dark:focus:ring-blue-400/20"
|
|
8956
|
-
}
|
|
8957
|
-
),
|
|
8958
|
-
open && /* @__PURE__ */ jsxRuntime.jsx(Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9367
|
+
if (!showControl) {
|
|
9368
|
+
const matched = options.find((o) => o.value === value);
|
|
9369
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8959
9370
|
"div",
|
|
8960
9371
|
{
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
8964
|
-
|
|
8965
|
-
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
),
|
|
8982
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(HighlightMatch, { text: option.label, query })
|
|
8983
|
-
},
|
|
8984
|
-
option.value
|
|
8985
|
-
))
|
|
9372
|
+
"data-react-fancy-autocomplete": "",
|
|
9373
|
+
"data-mode": "view",
|
|
9374
|
+
ref: wrapperRef,
|
|
9375
|
+
role: interactive ? "button" : void 0,
|
|
9376
|
+
tabIndex: interactive ? 0 : void 0,
|
|
9377
|
+
title: interactive ? "Click to edit" : void 0,
|
|
9378
|
+
onClick: interactive ? enterEdit : void 0,
|
|
9379
|
+
onKeyDown: interactive ? (e) => {
|
|
9380
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
9381
|
+
e.preventDefault();
|
|
9382
|
+
enterEdit();
|
|
9383
|
+
}
|
|
9384
|
+
} : void 0,
|
|
9385
|
+
className: cn(
|
|
9386
|
+
"text-sm text-zinc-900 dark:text-zinc-100",
|
|
9387
|
+
!value && "text-zinc-400 dark:text-zinc-500",
|
|
9388
|
+
interactive && "cursor-pointer rounded-md outline-none transition-colors hover:bg-zinc-100 focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:bg-zinc-800",
|
|
9389
|
+
className
|
|
9390
|
+
),
|
|
9391
|
+
children: matched?.label ?? value ?? "\u2014"
|
|
8986
9392
|
}
|
|
8987
|
-
)
|
|
8988
|
-
|
|
9393
|
+
);
|
|
9394
|
+
}
|
|
9395
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9396
|
+
"div",
|
|
9397
|
+
{
|
|
9398
|
+
"data-react-fancy-autocomplete": "",
|
|
9399
|
+
ref: wrapperRef,
|
|
9400
|
+
className: cn("relative", className),
|
|
9401
|
+
onBlur: (e) => {
|
|
9402
|
+
if (interactive && !open && !e.currentTarget.contains(e.relatedTarget)) {
|
|
9403
|
+
exitEdit();
|
|
9404
|
+
}
|
|
9405
|
+
},
|
|
9406
|
+
children: [
|
|
9407
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9408
|
+
"input",
|
|
9409
|
+
{
|
|
9410
|
+
ref: (node) => {
|
|
9411
|
+
anchorRef.current = node;
|
|
9412
|
+
if (typeof ref === "function") ref(node);
|
|
9413
|
+
else if (ref) ref.current = node;
|
|
9414
|
+
},
|
|
9415
|
+
type: "text",
|
|
9416
|
+
value: query,
|
|
9417
|
+
onChange: (e) => {
|
|
9418
|
+
setQuery(e.target.value);
|
|
9419
|
+
setOpen(true);
|
|
9420
|
+
setActiveIndex(-1);
|
|
9421
|
+
},
|
|
9422
|
+
onFocus: () => setOpen(true),
|
|
9423
|
+
onKeyDown: handleKeyDown,
|
|
9424
|
+
placeholder,
|
|
9425
|
+
disabled,
|
|
9426
|
+
autoFocus: interactive,
|
|
9427
|
+
role: "combobox",
|
|
9428
|
+
"aria-expanded": open,
|
|
9429
|
+
"aria-autocomplete": "list",
|
|
9430
|
+
className: "w-full rounded-lg border border-zinc-200 bg-white px-3 py-2 text-sm text-zinc-900 placeholder:text-zinc-400 outline-none transition-[border-color,box-shadow] duration-150 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/40 dark:border-zinc-700 dark:bg-[#1e1e24] dark:text-zinc-100 dark:placeholder:text-zinc-500 dark:focus:border-blue-400 dark:focus:ring-blue-400/20"
|
|
9431
|
+
}
|
|
9432
|
+
),
|
|
9433
|
+
open && /* @__PURE__ */ jsxRuntime.jsx(Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
9434
|
+
"div",
|
|
9435
|
+
{
|
|
9436
|
+
ref: listRef,
|
|
9437
|
+
role: "listbox",
|
|
9438
|
+
className: "fixed z-50 max-h-60 min-w-[8rem] overflow-y-auto rounded-xl border border-zinc-200 bg-white p-1 shadow-lg dark:border-zinc-700 dark:bg-zinc-900 dark:shadow-zinc-950/50 fancy-scale-in",
|
|
9439
|
+
style: {
|
|
9440
|
+
left: position.x,
|
|
9441
|
+
top: position.y,
|
|
9442
|
+
width: anchorRef.current?.offsetWidth
|
|
9443
|
+
},
|
|
9444
|
+
children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2 text-sm text-zinc-400", children: "Loading..." }) : filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2 text-sm text-zinc-400", children: emptyMessage }) : filtered.map((option, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
9445
|
+
"button",
|
|
9446
|
+
{
|
|
9447
|
+
type: "button",
|
|
9448
|
+
role: "option",
|
|
9449
|
+
"aria-selected": i === activeIndex,
|
|
9450
|
+
disabled: option.disabled,
|
|
9451
|
+
onClick: () => select(option.value),
|
|
9452
|
+
className: cn(
|
|
9453
|
+
"flex w-full items-center rounded-lg px-3 py-2 text-left text-sm text-zinc-700 transition-colors dark:text-zinc-200",
|
|
9454
|
+
i === activeIndex ? "bg-zinc-100 dark:bg-zinc-800" : "hover:bg-zinc-50 dark:hover:bg-zinc-800/50",
|
|
9455
|
+
option.disabled && "cursor-not-allowed opacity-50"
|
|
9456
|
+
),
|
|
9457
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(HighlightMatch, { text: option.label, query })
|
|
9458
|
+
},
|
|
9459
|
+
option.value
|
|
9460
|
+
))
|
|
9461
|
+
}
|
|
9462
|
+
) })
|
|
9463
|
+
]
|
|
9464
|
+
}
|
|
9465
|
+
);
|
|
8989
9466
|
}
|
|
8990
9467
|
);
|
|
8991
9468
|
function HighlightMatch({ text, query }) {
|
|
@@ -9101,13 +9578,16 @@ var OtpInput = react.forwardRef(
|
|
|
9101
9578
|
onChange,
|
|
9102
9579
|
disabled = false,
|
|
9103
9580
|
autoFocus = false,
|
|
9104
|
-
className
|
|
9581
|
+
className,
|
|
9582
|
+
mode
|
|
9105
9583
|
}, ref) {
|
|
9106
9584
|
const [value, setValue] = useControllableState(
|
|
9107
9585
|
controlledValue,
|
|
9108
9586
|
"",
|
|
9109
9587
|
onChange
|
|
9110
9588
|
);
|
|
9589
|
+
const resolvedMode = useFieldMode(mode);
|
|
9590
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
9111
9591
|
const inputsRef = react.useRef([]);
|
|
9112
9592
|
const focusInput = react.useCallback(
|
|
9113
9593
|
(index) => {
|
|
@@ -9161,27 +9641,64 @@ var OtpInput = react.forwardRef(
|
|
|
9161
9641
|
},
|
|
9162
9642
|
[length, setValue, focusInput]
|
|
9163
9643
|
);
|
|
9164
|
-
|
|
9165
|
-
|
|
9644
|
+
if (!showControl) {
|
|
9645
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9646
|
+
"div",
|
|
9647
|
+
{
|
|
9648
|
+
"data-react-fancy-otp-input": "",
|
|
9649
|
+
"data-mode": "view",
|
|
9650
|
+
ref,
|
|
9651
|
+
role: interactive ? "button" : void 0,
|
|
9652
|
+
tabIndex: interactive ? 0 : void 0,
|
|
9653
|
+
title: interactive ? "Click to edit" : void 0,
|
|
9654
|
+
onClick: interactive ? enterEdit : void 0,
|
|
9655
|
+
onKeyDown: interactive ? (e) => {
|
|
9656
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
9657
|
+
e.preventDefault();
|
|
9658
|
+
enterEdit();
|
|
9659
|
+
}
|
|
9660
|
+
} : void 0,
|
|
9661
|
+
className: cn(
|
|
9662
|
+
"font-mono text-lg tracking-[0.4em] text-zinc-900 dark:text-zinc-100",
|
|
9663
|
+
interactive && "cursor-pointer rounded-md outline-none transition-opacity hover:opacity-80 focus-visible:ring-2 focus-visible:ring-blue-500/40",
|
|
9664
|
+
className
|
|
9665
|
+
),
|
|
9666
|
+
children: value || "\u2014"
|
|
9667
|
+
}
|
|
9668
|
+
);
|
|
9669
|
+
}
|
|
9670
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9671
|
+
"div",
|
|
9166
9672
|
{
|
|
9167
|
-
|
|
9168
|
-
|
|
9673
|
+
"data-react-fancy-otp-input": "",
|
|
9674
|
+
ref,
|
|
9675
|
+
className: cn("flex gap-2", className),
|
|
9676
|
+
onBlur: (e) => {
|
|
9677
|
+
if (interactive && !e.currentTarget.contains(e.relatedTarget)) exitEdit();
|
|
9169
9678
|
},
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9679
|
+
children: Array.from({ length }, (_, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
9680
|
+
"input",
|
|
9681
|
+
{
|
|
9682
|
+
ref: (el) => {
|
|
9683
|
+
inputsRef.current[i] = el;
|
|
9684
|
+
},
|
|
9685
|
+
type: "text",
|
|
9686
|
+
inputMode: "numeric",
|
|
9687
|
+
maxLength: 1,
|
|
9688
|
+
value: value[i] ?? "",
|
|
9689
|
+
onChange: (e) => handleChange(i, e.target.value),
|
|
9690
|
+
onKeyDown: (e) => handleKeyDown(i, e),
|
|
9691
|
+
onPaste: handlePaste,
|
|
9692
|
+
onFocus: (e) => e.target.select(),
|
|
9693
|
+
disabled,
|
|
9694
|
+
autoFocus: (autoFocus || interactive) && i === 0,
|
|
9695
|
+
className: "h-12 w-10 rounded-lg border border-zinc-200 bg-white text-center text-lg font-medium text-zinc-900 outline-none transition-[border-color,box-shadow] duration-150 focus:border-blue-500 focus:ring-2 focus:ring-blue-500/40 dark:border-zinc-700 dark:bg-[#1e1e24] dark:text-zinc-100 dark:focus:border-blue-400 dark:focus:ring-blue-400/20",
|
|
9696
|
+
"aria-label": `Digit ${i + 1}`
|
|
9697
|
+
},
|
|
9698
|
+
i
|
|
9699
|
+
))
|
|
9700
|
+
}
|
|
9701
|
+
);
|
|
9185
9702
|
}
|
|
9186
9703
|
);
|
|
9187
9704
|
OtpInput.displayName = "OtpInput";
|
|
@@ -9375,16 +9892,46 @@ var TimePicker = react.forwardRef(
|
|
|
9375
9892
|
format = "12h",
|
|
9376
9893
|
minuteStep = 1,
|
|
9377
9894
|
disabled = false,
|
|
9378
|
-
className
|
|
9895
|
+
className,
|
|
9896
|
+
mode
|
|
9379
9897
|
}, ref) {
|
|
9380
9898
|
const [value, setValue] = useControllableState(
|
|
9381
9899
|
controlledValue,
|
|
9382
9900
|
defaultValue,
|
|
9383
9901
|
onChange
|
|
9384
9902
|
);
|
|
9903
|
+
const resolvedMode = useFieldMode(mode);
|
|
9904
|
+
const { showControl, interactive, enterEdit, exitEdit } = useInlineEdit(resolvedMode, disabled);
|
|
9385
9905
|
const { hours: h24, minutes } = parseTime(value);
|
|
9386
9906
|
const isPM = h24 >= 12;
|
|
9387
9907
|
const displayHour = format === "12h" ? h24 % 12 || 12 : h24;
|
|
9908
|
+
if (!showControl) {
|
|
9909
|
+
const formatted = format === "12h" ? `${pad(displayHour)}:${pad(minutes)} ${isPM ? "PM" : "AM"}` : `${pad(displayHour)}:${pad(minutes)}`;
|
|
9910
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9911
|
+
"div",
|
|
9912
|
+
{
|
|
9913
|
+
"data-react-fancy-time-picker": "",
|
|
9914
|
+
"data-mode": "view",
|
|
9915
|
+
ref,
|
|
9916
|
+
role: interactive ? "button" : void 0,
|
|
9917
|
+
tabIndex: interactive ? 0 : void 0,
|
|
9918
|
+
title: interactive ? "Click to edit" : void 0,
|
|
9919
|
+
onClick: interactive ? enterEdit : void 0,
|
|
9920
|
+
onKeyDown: interactive ? (e) => {
|
|
9921
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
9922
|
+
e.preventDefault();
|
|
9923
|
+
enterEdit();
|
|
9924
|
+
}
|
|
9925
|
+
} : void 0,
|
|
9926
|
+
className: cn(
|
|
9927
|
+
"text-sm font-medium tabular-nums text-zinc-900 dark:text-zinc-100",
|
|
9928
|
+
interactive && "cursor-pointer rounded-md outline-none transition-colors hover:bg-zinc-100 focus-visible:ring-2 focus-visible:ring-blue-500/40 dark:hover:bg-zinc-800",
|
|
9929
|
+
className
|
|
9930
|
+
),
|
|
9931
|
+
children: formatted
|
|
9932
|
+
}
|
|
9933
|
+
);
|
|
9934
|
+
}
|
|
9388
9935
|
const updateTime = react.useCallback(
|
|
9389
9936
|
(hours, mins) => {
|
|
9390
9937
|
setValue(`${pad(hours)}:${pad(mins)}`);
|
|
@@ -9415,6 +9962,9 @@ var TimePicker = react.forwardRef(
|
|
|
9415
9962
|
{
|
|
9416
9963
|
"data-react-fancy-time-picker": "",
|
|
9417
9964
|
ref,
|
|
9965
|
+
onBlur: (e) => {
|
|
9966
|
+
if (interactive && !e.currentTarget.contains(e.relatedTarget)) exitEdit();
|
|
9967
|
+
},
|
|
9418
9968
|
className: cn(
|
|
9419
9969
|
"inline-flex items-center gap-1 rounded-lg border border-zinc-200 bg-white p-2 dark:border-zinc-700 dark:bg-zinc-900",
|
|
9420
9970
|
disabled && "opacity-50",
|
|
@@ -9422,7 +9972,7 @@ var TimePicker = react.forwardRef(
|
|
|
9422
9972
|
),
|
|
9423
9973
|
children: [
|
|
9424
9974
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
|
|
9425
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => changeHour(1), disabled, className: spinBtnClass, "aria-label": "Increase hour", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { size: 14 }) }),
|
|
9975
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", autoFocus: interactive, onClick: () => changeHour(1), disabled, className: spinBtnClass, "aria-label": "Increase hour", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUp, { size: 14 }) }),
|
|
9426
9976
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: displayClass, children: pad(displayHour) }),
|
|
9427
9977
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: () => changeHour(-1), disabled, className: spinBtnClass, "aria-label": "Decrease hour", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { size: 14 }) })
|
|
9428
9978
|
] }),
|
|
@@ -13730,6 +14280,7 @@ exports.Composer = Composer;
|
|
|
13730
14280
|
exports.ContentRenderer = ContentRenderer;
|
|
13731
14281
|
exports.ContextMenu = ContextMenu;
|
|
13732
14282
|
exports.DatePicker = DatePicker;
|
|
14283
|
+
exports.DisplayValue = DisplayValue;
|
|
13733
14284
|
exports.Dropdown = Dropdown;
|
|
13734
14285
|
exports.EMOJI_CATEGORY_ORDER = EMOJI_CATEGORY_ORDER;
|
|
13735
14286
|
exports.EMOJI_DATA = EMOJI_DATA;
|
|
@@ -13739,7 +14290,10 @@ exports.Emoji = Emoji;
|
|
|
13739
14290
|
exports.EmojiSelect = EmojiSelect;
|
|
13740
14291
|
exports.FauxClient = FauxClient;
|
|
13741
14292
|
exports.Field = Field;
|
|
14293
|
+
exports.FieldModeContext = FieldModeContext;
|
|
13742
14294
|
exports.FileUpload = FileUpload;
|
|
14295
|
+
exports.Form = Form;
|
|
14296
|
+
exports.FormProvider = FormProvider;
|
|
13743
14297
|
exports.Heading = Heading;
|
|
13744
14298
|
exports.Icon = Icon;
|
|
13745
14299
|
exports.Input = Input;
|
|
@@ -13809,6 +14363,7 @@ exports.useControllableState = useControllableState;
|
|
|
13809
14363
|
exports.useDropdown = useDropdown;
|
|
13810
14364
|
exports.useEditor = useEditor;
|
|
13811
14365
|
exports.useEscapeKey = useEscapeKey;
|
|
14366
|
+
exports.useFieldMode = useFieldMode;
|
|
13812
14367
|
exports.useFileUpload = useFileUpload;
|
|
13813
14368
|
exports.useFloatingPosition = useFloatingPosition;
|
|
13814
14369
|
exports.useFocusTrap = useFocusTrap;
|