a tool for shared writing and social publishing
1"use client";
2
3import {
4 ColorPicker as SpectrumColorPicker,
5 parseColor,
6 Color,
7 ColorArea,
8 ColorThumb,
9 ColorSlider,
10 Input,
11 ColorField,
12 SliderTrack,
13 ColorSwatch,
14} from "react-aria-components";
15import { pickers, setColorAttribute } from "../ThemeSetter";
16import { thumbStyle } from "./ColorPicker";
17import { ImageInput, ImageSettings } from "./ImagePicker";
18import { useEntity, useReplicache } from "src/replicache";
19import { useColorAttribute } from "components/ThemeManager/useColorAttribute";
20import { Separator } from "components/Layout";
21import { onMouseDown } from "src/utils/iosInputMouseDown";
22import { BlockImageSmall } from "components/Icons/BlockImageSmall";
23import { DeleteSmall } from "components/Icons/DeleteSmall";
24
25export const LeafletBGPicker = (props: {
26 entityID: string;
27 openPicker: pickers;
28 thisPicker: pickers;
29 setOpenPicker: (thisPicker: pickers) => void;
30 closePicker: () => void;
31 setValue: (c: Color) => void;
32}) => {
33 let bgImage = useEntity(props.entityID, "theme/background-image");
34 let bgRepeat = useEntity(props.entityID, "theme/background-image-repeat");
35 let bgColor = useColorAttribute(props.entityID, "theme/page-background");
36 let open = props.openPicker == props.thisPicker;
37 let { rep } = useReplicache();
38
39 return (
40 <>
41 <div className="bgPickerLabel flex justify-between place-items-center ">
42 <div className="bgPickerColorLabel flex gap-2 items-center">
43 <button
44 onClick={() => {
45 if (props.openPicker === props.thisPicker) {
46 props.setOpenPicker("null");
47 } else {
48 props.setOpenPicker(props.thisPicker);
49 }
50 }}
51 className="flex gap-2 items-center"
52 >
53 <ColorSwatch
54 color={bgColor}
55 className={`w-6 h-6 rounded-full border-2 border-white shadow-[0_0_0_1px_#8C8C8C]`}
56 style={{
57 backgroundImage: bgImage?.data.src
58 ? `url(${bgImage.data.src})`
59 : undefined,
60 backgroundSize: "cover",
61 }}
62 />
63 <strong className={` "text-[#595959]`}>{"Background"}</strong>
64 </button>
65
66 <div className="flex">
67 {bgImage ? (
68 <div className={`"text-[#969696]`}>Image</div>
69 ) : (
70 <>
71 <ColorField className="w-fit gap-1" value={bgColor}>
72 <Input
73 onMouseDown={onMouseDown}
74 onFocus={(e) => {
75 e.currentTarget.setSelectionRange(
76 1,
77 e.currentTarget.value.length,
78 );
79 }}
80 onPaste={(e) => {
81 console.log(e);
82 }}
83 onKeyDown={(e) => {
84 if (e.key === "Enter") {
85 e.currentTarget.blur();
86 } else return;
87 }}
88 onBlur={(e) => {
89 props.setValue(parseColor(e.currentTarget.value));
90 }}
91 className={`w-[72px] bg-transparent outline-nonetext-[#595959]`}
92 />
93 </ColorField>
94 </>
95 )}
96 </div>
97 </div>
98 <div className="flex gap-1 justify-end grow text-[#969696]">
99 {bgImage && (
100 <button
101 onClick={() => {
102 if (bgImage) rep?.mutate.retractFact({ factID: bgImage.id });
103 if (bgRepeat) rep?.mutate.retractFact({ factID: bgRepeat.id });
104 }}
105 >
106 <DeleteSmall />
107 </button>
108 )}
109 <label>
110 <BlockImageSmall />
111 <div className="hidden">
112 <ImageInput
113 {...props}
114 onChange={() => {
115 props.setOpenPicker(props.thisPicker);
116 }}
117 />
118 </div>
119 </label>
120 </div>
121 </div>
122 {open && (
123 <div className="bgImageAndColorPicker w-full flex flex-col gap-2 ">
124 <SpectrumColorPicker
125 value={bgColor}
126 onChange={setColorAttribute(
127 rep,
128 props.entityID,
129 )("theme/page-background")}
130 >
131 {bgImage ? (
132 <ImageSettings
133 entityID={props.entityID}
134 setValue={props.setValue}
135 />
136 ) : (
137 <>
138 <ColorArea
139 className="w-full h-[128px] rounded-md"
140 colorSpace="hsb"
141 xChannel="saturation"
142 yChannel="brightness"
143 >
144 <ColorThumb className={thumbStyle} />
145 </ColorArea>
146 <ColorSlider
147 colorSpace="hsb"
148 className="w-full "
149 channel="hue"
150 >
151 <SliderTrack className="h-2 w-full rounded-md">
152 <ColorThumb className={`${thumbStyle} mt-[4px]`} />
153 </SliderTrack>
154 </ColorSlider>
155 </>
156 )}
157 </SpectrumColorPicker>
158 </div>
159 )}
160 </>
161 );
162};