fix admin save state architecture
This commit is contained in:
@@ -5,22 +5,27 @@ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
||||
import { Check } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useHiddenInputSync } from "@/components/ui/use-hidden-input-sync";
|
||||
|
||||
type CheckboxProps = React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root> & {
|
||||
name?: string;
|
||||
checkedValue?: string;
|
||||
uncheckedValue?: string;
|
||||
};
|
||||
|
||||
const Checkbox = React.forwardRef<
|
||||
React.ElementRef<typeof CheckboxPrimitive.Root>,
|
||||
CheckboxProps
|
||||
>(({ className, name, checked, defaultChecked, onCheckedChange, ...props }, ref) => {
|
||||
>(({ className, name, checked, defaultChecked, onCheckedChange, checkedValue = "on", uncheckedValue = "false", ...props }, ref) => {
|
||||
const [internalChecked, setInternalChecked] = React.useState(defaultChecked === true);
|
||||
const isControlled = checked !== undefined;
|
||||
const currentChecked = isControlled ? checked === true : internalChecked;
|
||||
const hiddenValue = currentChecked ? checkedValue : uncheckedValue;
|
||||
const hiddenInputRef = useHiddenInputSync(hiddenValue);
|
||||
|
||||
return (
|
||||
<>
|
||||
{name ? <input type="hidden" name={name} value={currentChecked ? "on" : "false"} /> : null}
|
||||
{name ? <input ref={hiddenInputRef} type="hidden" name={name} value={hiddenValue} /> : null}
|
||||
<CheckboxPrimitive.Root
|
||||
ref={ref}
|
||||
checked={checked}
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as SelectPrimitive from "@radix-ui/react-select";
|
||||
import { Check, ChevronDown, ChevronUp } from "lucide-react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useHiddenInputSync } from "@/components/ui/use-hidden-input-sync";
|
||||
|
||||
type SelectProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Root> & {
|
||||
name?: string;
|
||||
@@ -23,10 +24,11 @@ function Select({
|
||||
const [internalValue, setInternalValue] = React.useState(defaultValue ?? "");
|
||||
const isControlled = value !== undefined;
|
||||
const currentValue = (isControlled ? value : internalValue) as string;
|
||||
const hiddenInputRef = useHiddenInputSync(currentValue);
|
||||
|
||||
return (
|
||||
<>
|
||||
{name ? <input type="hidden" name={name} value={currentValue} required={required} /> : null}
|
||||
{name ? <input ref={hiddenInputRef} type="hidden" name={name} value={currentValue} required={required} /> : null}
|
||||
<SelectPrimitive.Root
|
||||
value={value}
|
||||
defaultValue={defaultValue}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
|
||||
export function useHiddenInputSync(value: string) {
|
||||
const inputRef = React.useRef<HTMLInputElement | null>(null);
|
||||
const mountedRef = React.useRef(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
const input = inputRef.current;
|
||||
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mountedRef.current) {
|
||||
mountedRef.current = true;
|
||||
return;
|
||||
}
|
||||
|
||||
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
input.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
}, [value]);
|
||||
|
||||
return inputRef;
|
||||
}
|
||||
Reference in New Issue
Block a user