"use client";
import {
ColorPicker as SpectrumColorPicker,
parseColor,
Color,
ColorThumb,
ColorSlider,
Input,
ColorField,
SliderTrack,
ColorSwatch,
} from "react-aria-components";
import { Checkbox } from "components/Checkbox";
import { useMemo, useState } from "react";
import { ReplicacheMutators, useEntity, useReplicache } from "src/replicache";
import { useColorAttribute } from "components/ThemeManager/useColorAttribute";
import { Separator } from "components/Layout";
import { onMouseDown } from "src/utils/iosInputMouseDown";
import { pickers, setColorAttribute } from "../ThemeSetter";
import { ImageInput, ImageSettings } from "./ImagePicker";
import { ColorPicker, thumbStyle } from "./ColorPicker";
import { BlockImageSmall } from "components/Icons/BlockImageSmall";
import { Replicache } from "replicache";
import { CanvasBackgroundPattern } from "components/Canvas";
import { Toggle } from "components/Toggle";
import { DeleteSmall } from "components/Icons/DeleteSmall";
export const PageThemePickers = (props: {
entityID: string;
openPicker: pickers;
setOpenPicker: (thisPicker: pickers) => void;
}) => {
let { rep } = useReplicache();
let set = useMemo(() => {
return setColorAttribute(rep, props.entityID);
}, [rep, props.entityID]);
let pageType = useEntity(props.entityID, "page/type")?.data.value || "doc";
let primaryValue = useColorAttribute(props.entityID, "theme/primary");
return (
{pageType === "canvas" && (
<>
{" "}
>
)}
);
};
// Page background picker for subpages - shows Page/Containers color with optional background image
export const SubpageBackgroundPicker = (props: {
entityID: string;
openPicker: pickers;
setOpenPicker: (p: pickers) => void;
}) => {
let { rep, rootEntity } = useReplicache();
let set = useMemo(() => {
return setColorAttribute(rep, props.entityID);
}, [rep, props.entityID]);
let pageValue = useColorAttribute(props.entityID, "theme/card-background");
let pageBGImage = useEntity(props.entityID, "theme/card-background-image");
let rootPageBorderHidden = useEntity(rootEntity, "theme/card-border-hidden");
let entityPageBorderHidden = useEntity(
props.entityID,
"theme/card-border-hidden",
);
let pageBorderHidden =
(entityPageBorderHidden || rootPageBorderHidden)?.data.value || false;
let hasPageBackground = !pageBorderHidden;
// Label is "Page" when page background is visible, "Containers" when hidden
let label = hasPageBackground ? "Page" : "Containers";
// If root page border is hidden, only show color picker (no image support)
if (!hasPageBackground) {
return (
props.setOpenPicker("null")}
alpha
/>
);
}
return (
<>
{pageBGImage && (
)}
props.setOpenPicker("null")}
alpha
/>
{!pageBGImage && (
)}
>
);
};
const SubpageBackgroundImagePicker = (props: {
entityID: string;
openPicker: pickers;
setOpenPicker: (p: pickers) => void;
setValue: (c: Color) => void;
}) => {
let { rep } = useReplicache();
let bgImage = useEntity(props.entityID, "theme/card-background-image");
let bgRepeat = useEntity(
props.entityID,
"theme/card-background-image-repeat",
);
let bgColor = useColorAttribute(props.entityID, "theme/card-background");
let bgAlpha =
useEntity(props.entityID, "theme/card-background-image-opacity")?.data
.value || 1;
let alphaColor = useMemo(() => {
return parseColor(`rgba(0,0,0,${bgAlpha})`);
}, [bgAlpha]);
let open = props.openPicker === "page-background-image";
return (
<>
{open && (
{
let alpha = c.getChannelValue("alpha");
rep?.mutate.assertFact({
entity: props.entityID,
attribute: "theme/card-background-image-opacity",
data: { type: "number", value: alpha },
});
}}
>
)}
>
);
};
// Unified background picker for leaflets - matches structure of BackgroundPicker for publications
export const LeafletBackgroundPicker = (props: {
entityID: string;
openPicker: pickers;
setOpenPicker: (p: pickers) => void;
}) => {
let { rep } = useReplicache();
let set = useMemo(() => {
return setColorAttribute(rep, props.entityID);
}, [rep, props.entityID]);
let leafletBgValue = useColorAttribute(
props.entityID,
"theme/page-background",
);
let pageValue = useColorAttribute(props.entityID, "theme/card-background");
let leafletBGImage = useEntity(props.entityID, "theme/background-image");
let leafletBGRepeat = useEntity(
props.entityID,
"theme/background-image-repeat",
);
let pageBorderHidden = useEntity(props.entityID, "theme/card-border-hidden");
let hasPageBackground = !pageBorderHidden?.data.value;
// When page background is hidden and no background image, only show the Background picker
let showPagePicker = hasPageBackground || !!leafletBGImage;
return (
<>
{/* Background color/image picker */}
{leafletBGImage ? (
) : (
props.setOpenPicker("null")}
/>
)}
{/* Page/Containers color picker - only shown when page background is visible OR there's a bg image */}
{showPagePicker && (
props.setOpenPicker("null")}
alpha
/>
)}
{/* Page Background toggle */}
>
);
};
const LeafletBackgroundImagePicker = (props: {
entityID: string;
openPicker: pickers;
setOpenPicker: (p: pickers) => void;
}) => {
let { rep } = useReplicache();
let bgImage = useEntity(props.entityID, "theme/background-image");
let bgRepeat = useEntity(props.entityID, "theme/background-image-repeat");
let bgColor = useColorAttribute(props.entityID, "theme/page-background");
let open = props.openPicker === "leaflet";
return (
<>
{open && (
{}} />
)}
>
);
};
export const PageBackgroundColorPicker = (props: {
disabled?: boolean;
label: string;
openPicker: pickers;
thisPicker: pickers;
setOpenPicker: (thisPicker: pickers) => void;
setValue: (c: Color) => void;
value: Color;
alpha?: boolean;
helpText?: string;
}) => {
return (
props.setOpenPicker("null")}
alpha={props.alpha}
/>
);
};
export const PageBackgroundImagePicker = (props: {
disabled?: boolean;
entityID: string;
openPicker: pickers;
thisPicker: pickers;
setOpenPicker: (thisPicker: pickers) => void;
closePicker: () => void;
setValue: (c: Color) => void;
home?: boolean;
}) => {
let bgImage = useEntity(props.entityID, "theme/card-background-image");
let bgRepeat = useEntity(
props.entityID,
"theme/card-background-image-repeat",
);
let bgColor = useColorAttribute(props.entityID, "theme/card-background");
let bgAlpha =
useEntity(props.entityID, "theme/card-background-image-opacity")?.data
.value || 1;
let alphaColor = useMemo(() => {
return parseColor(`rgba(0,0,0,${bgAlpha})`);
}, [bgAlpha]);
let open = props.openPicker == props.thisPicker;
let { rep } = useReplicache();
return (
<>
{open && (
{
let alpha = c.getChannelValue("alpha");
rep?.mutate.assertFact({
entity: props.entityID,
attribute: "theme/card-background-image-opacity",
data: { type: "number", value: alpha },
});
}}
>
)}
>
);
};
const CanvasBGPatternPicker = (props: {
entityID: string;
rep: Replicache | null;
}) => {
let selectedPattern = useEntity(props.entityID, "canvas/background-pattern")
?.data.value;
return (
);
};
export const TextPickers = (props: {
openPicker: pickers;
setOpenPicker: (thisPicker: pickers) => void;
value: Color;
setValue: (c: Color) => void;
}) => {
return (
props.setOpenPicker("null")}
/>
);
};
export const PageBorderHider = (props: {
entityID: string;
setOpenPicker: (p: pickers) => void;
openPicker: pickers;
}) => {
let { rep, rootEntity } = useReplicache();
let rootPageBorderHidden = useEntity(rootEntity, "theme/card-border-hidden");
let entityPageBorderHidden = useEntity(
props.entityID,
"theme/card-border-hidden",
);
let pageBorderHidden =
(entityPageBorderHidden || rootPageBorderHidden)?.data.value || false;
function handleToggle() {
rep?.mutate.assertFact({
entity: props.entityID,
attribute: "theme/card-border-hidden",
data: { type: "boolean", value: !pageBorderHidden },
});
(pageBorderHidden && props.openPicker === "page") ||
(props.openPicker === "page-background-image" &&
props.setOpenPicker("null"));
}
return (
<>
{
handleToggle();
}}
disabledColor1="#8C8C8C"
disabledColor2="#DBDBDB"
>
Page Background
{pageBorderHidden ? "none" : ""}
>
);
};