tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
27
pulls
pipelines
adjusting some issues in popover
cozylittle.house
1 week ago
52258dbc
40e42a84
+177
-164
7 changed files
expand all
collapse all
unified
split
app
[leaflet_id]
actions
HelpButton.tsx
lish
[did]
[publication]
dashboard
settings
PublicationSettings.tsx
createPub
UpdatePubForm.tsx
components
Icons
PopoverArrow.tsx
Popover
index.tsx
ThemeManager
PubThemeSetter.tsx
ThemeProvider.tsx
+4
-2
app/[leaflet_id]/actions/HelpButton.tsx
···
19
19
side={isMobile ? "top" : "right"}
20
20
align={isMobile ? "center" : "start"}
21
21
asChild
22
22
-
className="max-w-xs w-full"
22
22
+
className="max-w-xs w-full p-0!"
23
23
trigger={<ActionButton icon={<HelpSmall />} label="About" />}
24
24
>
25
25
-
<div className="flex flex-col text-sm gap-2 text-secondary">
25
25
+
<div
26
26
+
className={`flex flex-col text-sm gap-2 p-3 text-secondary max-h-[70vh] overflow-y-auto p-2" : ""}`}
27
27
+
>
26
28
{/* about links */}
27
29
<HelpLink text="📖 Leaflet Manual" url="https://about.leaflet.pub" />
28
30
<HelpLink text="💡 Make with Leaflet" url="https://make.leaflet.pub" />
+8
-7
app/lish/[did]/[publication]/dashboard/settings/PublicationSettings.tsx
···
27
27
onOpenChange={() => setState("menu")}
28
28
side={isMobile ? "top" : "right"}
29
29
align={isMobile ? "center" : "start"}
30
30
-
className={`max-w-xs w-[1000px] ${state === "theme" && "bg-white!"}`}
30
30
+
className={`flex flex-col max-w-xs w-[1000px] ${state === "theme" && "bg-white!"} pb-0!`}
31
31
arrowFill={theme.colors["border-light"]}
32
32
trigger={
33
33
<ActionButton
···
64
64
setLoading={setLoading}
65
65
/>
66
66
)}
67
67
+
<div className="spacer h-2 w-full" aria-hidden />
67
68
</Popover>
68
69
);
69
70
}
···
93
94
props.setState("general");
94
95
}}
95
96
>
96
96
-
General Settings
97
97
+
Publication Settings
97
98
<ArrowRightTiny />
98
99
</button>
99
100
<button
100
101
className={menuItemClassName}
101
102
type="button"
102
102
-
onClick={() => props.setState("theme")}
103
103
+
onClick={() => props.setState("post-options")}
103
104
>
104
104
-
Theme and Layout
105
105
+
Post Settings
105
106
<ArrowRightTiny />
106
107
</button>
107
108
<button
108
109
className={menuItemClassName}
109
110
type="button"
110
110
-
onClick={() => props.setState("post-options")}
111
111
+
onClick={() => props.setState("theme")}
111
112
>
112
112
-
Post Options
113
113
+
Theme and Layout
113
114
<ArrowRightTiny />
114
115
</button>
115
116
</div>
···
124
125
children: React.ReactNode;
125
126
}) => {
126
127
return (
127
127
-
<div className="flex justify-between font-bold text-secondary bg-border-light -mx-3 -mt-2 px-3 py-2 mb-1">
128
128
+
<div className="flex justify-between font-bold text-secondary bg-border-light -mx-3 -mt-2 px-3 py-2 mb-1 flex-shrink-0">
128
129
{props.children}
129
130
{props.state !== "menu" && (
130
131
<div className="flex gap-2">
+2
-1
app/lish/createPub/UpdatePubForm.tsx
···
74
74
75
75
return (
76
76
<form
77
77
+
className="min-h-0 flex-1 flex flex-col pb-2"
77
78
onSubmit={async (e) => {
78
79
if (!pubData) return;
79
80
e.preventDefault();
···
104
105
>
105
106
General Settings
106
107
</PubSettingsHeader>
107
107
-
<div className="flex flex-col gap-3 w-[1000px] max-w-full pb-2">
108
108
+
<div className="flex flex-col gap-3 w-[1000px] max-w-full pb-2 overflow-y-auto min-h-0">
108
109
<div className="flex items-center justify-between gap-2 mt-2 ">
109
110
<p className="pl-0.5 pb-0.5 text-tertiary italic text-sm font-bold">
110
111
Logo <span className="font-normal">(optional)</span>
+1
-1
components/Icons/PopoverArrow.tsx
···
11
11
height="8"
12
12
viewBox="0 0 16 8"
13
13
fill="none"
14
14
-
className="-mt-px"
14
14
+
className=""
15
15
xmlns="http://www.w3.org/2000/svg"
16
16
>
17
17
<path
-1
components/Popover/index.tsx
···
47
47
max-w-(--radix-popover-content-available-width)
48
48
max-h-(--radix-popover-content-available-height)
49
49
border border-border rounded-md shadow-md
50
50
-
overflow-y-scroll
51
50
${props.className}
52
51
`}
53
52
side={props.side}
+159
-151
components/ThemeManager/PubThemeSetter.tsx
···
65
65
let toaster = useToaster();
66
66
67
67
return (
68
68
-
<BaseThemeProvider local {...localPubTheme} hasBackgroundImage={!!image}>
69
69
-
<form
70
70
-
onSubmit={async (e) => {
71
71
-
e.preventDefault();
72
72
-
if (!pub) return;
73
73
-
props.setLoading(true);
74
74
-
let result = await updatePublicationTheme({
75
75
-
uri: pub.uri,
76
76
-
theme: {
77
77
-
pageBackground: ColorToRGBA(localPubTheme.bgPage),
78
78
-
showPageBackground: showPageBackground,
79
79
-
backgroundColor: image
80
80
-
? ColorToRGBA(localPubTheme.bgLeaflet)
81
81
-
: ColorToRGB(localPubTheme.bgLeaflet),
82
82
-
backgroundRepeat: image?.repeat,
83
83
-
backgroundImage: image ? image.file : null,
84
84
-
pageWidth: pageWidth,
85
85
-
primary: ColorToRGB(localPubTheme.primary),
86
86
-
accentBackground: ColorToRGB(localPubTheme.accent1),
87
87
-
accentText: ColorToRGB(localPubTheme.accent2),
88
88
-
},
89
89
-
});
68
68
+
<BaseThemeProvider
69
69
+
local
70
70
+
{...localPubTheme}
71
71
+
hasBackgroundImage={!!image}
72
72
+
className="min-h-0!"
73
73
+
>
74
74
+
<div className="min-h-0 flex-1 flex flex-col pb-0.5">
75
75
+
<form
76
76
+
className="flex-shrink-0"
77
77
+
onSubmit={async (e) => {
78
78
+
e.preventDefault();
79
79
+
if (!pub) return;
80
80
+
props.setLoading(true);
81
81
+
let result = await updatePublicationTheme({
82
82
+
uri: pub.uri,
83
83
+
theme: {
84
84
+
pageBackground: ColorToRGBA(localPubTheme.bgPage),
85
85
+
showPageBackground: showPageBackground,
86
86
+
backgroundColor: image
87
87
+
? ColorToRGBA(localPubTheme.bgLeaflet)
88
88
+
: ColorToRGB(localPubTheme.bgLeaflet),
89
89
+
backgroundRepeat: image?.repeat,
90
90
+
backgroundImage: image ? image.file : null,
91
91
+
pageWidth: pageWidth,
92
92
+
primary: ColorToRGB(localPubTheme.primary),
93
93
+
accentBackground: ColorToRGB(localPubTheme.accent1),
94
94
+
accentText: ColorToRGB(localPubTheme.accent2),
95
95
+
},
96
96
+
});
90
97
91
91
-
if (!result.success) {
92
92
-
props.setLoading(false);
93
93
-
if (result.error && isOAuthSessionError(result.error)) {
94
94
-
toaster({
95
95
-
content: <OAuthErrorMessage error={result.error} />,
96
96
-
type: "error",
97
97
-
});
98
98
-
} else {
99
99
-
toaster({
100
100
-
content: "Failed to update theme",
101
101
-
type: "error",
102
102
-
});
98
98
+
if (!result.success) {
99
99
+
props.setLoading(false);
100
100
+
if (result.error && isOAuthSessionError(result.error)) {
101
101
+
toaster({
102
102
+
content: <OAuthErrorMessage error={result.error} />,
103
103
+
type: "error",
104
104
+
});
105
105
+
} else {
106
106
+
toaster({
107
107
+
content: "Failed to update theme",
108
108
+
type: "error",
109
109
+
});
110
110
+
}
111
111
+
return;
103
112
}
104
104
-
return;
105
105
-
}
106
113
107
107
-
mutate((pub) => {
108
108
-
if (result.publication && pub?.publication)
109
109
-
return {
110
110
-
...pub,
111
111
-
publication: { ...pub.publication, ...result.publication },
112
112
-
};
113
113
-
return pub;
114
114
-
}, false);
115
115
-
props.setLoading(false);
116
116
-
}}
117
117
-
>
118
118
-
<PubSettingsHeader
119
119
-
loading={props.loading}
120
120
-
setLoadingAction={props.setLoading}
121
121
-
backToMenuAction={props.backToMenu}
122
122
-
state={"theme"}
114
114
+
mutate((pub) => {
115
115
+
if (result.publication && pub?.publication)
116
116
+
return {
117
117
+
...pub,
118
118
+
publication: { ...pub.publication, ...result.publication },
119
119
+
};
120
120
+
return pub;
121
121
+
}, false);
122
122
+
props.setLoading(false);
123
123
+
}}
123
124
>
124
124
-
Theme and Layout
125
125
-
</PubSettingsHeader>
126
126
-
</form>
125
125
+
<PubSettingsHeader
126
126
+
loading={props.loading}
127
127
+
setLoadingAction={props.setLoading}
128
128
+
backToMenuAction={props.backToMenu}
129
129
+
state={"theme"}
130
130
+
>
131
131
+
Theme and Layout
132
132
+
</PubSettingsHeader>
133
133
+
</form>
127
134
128
128
-
<div className="themeSetterContent flex flex-col w-full overflow-y-scroll -mb-2 mt-2 ">
129
129
-
<PubPageWidthSetter
130
130
-
pageWidth={pageWidth}
131
131
-
setPageWidth={setPageWidth}
132
132
-
thisPicker="page-width"
133
133
-
openPicker={openPicker}
134
134
-
setOpenPicker={setOpenPicker}
135
135
-
/>
136
136
-
<div className="themeBGLeaflet flex flex-col">
135
135
+
<div className="themeSetterContent flex flex-col w-full overflow-y-scroll min-h-0 -mb-2 pt-2 ">
136
136
+
<PubPageWidthSetter
137
137
+
pageWidth={pageWidth}
138
138
+
setPageWidth={setPageWidth}
139
139
+
thisPicker="page-width"
140
140
+
openPicker={openPicker}
141
141
+
setOpenPicker={setOpenPicker}
142
142
+
/>
143
143
+
<div className="themeBGLeaflet flex flex-col">
144
144
+
<div
145
145
+
className={`themeBgPicker flex flex-col gap-0 -mb-[6px] z-10 w-full `}
146
146
+
>
147
147
+
<div className="bgPickerBody w-full flex flex-col gap-2 p-2 mt-1 border border-[#CCCCCC] rounded-md text-[#595959] bg-white">
148
148
+
<BackgroundPicker
149
149
+
bgImage={image}
150
150
+
setBgImage={setImage}
151
151
+
backgroundColor={localPubTheme.bgLeaflet}
152
152
+
pageBackground={localPubTheme.bgPage}
153
153
+
setPageBackground={(color) => {
154
154
+
setTheme((t) => ({ ...t, bgPage: color }));
155
155
+
}}
156
156
+
setBackgroundColor={(color) => {
157
157
+
setTheme((t) => ({ ...t, bgLeaflet: color }));
158
158
+
}}
159
159
+
openPicker={openPicker}
160
160
+
setOpenPicker={setOpenPicker}
161
161
+
hasPageBackground={!!showPageBackground}
162
162
+
setHasPageBackground={setShowPageBackground}
163
163
+
/>
164
164
+
</div>
165
165
+
166
166
+
<SectionArrow
167
167
+
fill="white"
168
168
+
stroke="#CCCCCC"
169
169
+
className="ml-2 -mt-[1px]"
170
170
+
/>
171
171
+
</div>
172
172
+
</div>
173
173
+
137
174
<div
138
138
-
className={`themeBgPicker flex flex-col gap-0 -mb-[6px] z-10 w-full `}
175
175
+
style={{
176
176
+
backgroundImage: pubBGImage ? `url(${pubBGImage})` : undefined,
177
177
+
backgroundRepeat: leafletBGRepeat ? "repeat" : "no-repeat",
178
178
+
backgroundPosition: "center",
179
179
+
backgroundSize: !leafletBGRepeat
180
180
+
? "cover"
181
181
+
: `calc(${leafletBGRepeat}px / 2 )`,
182
182
+
}}
183
183
+
className={` relative bg-bg-leaflet px-3 py-4 flex flex-col rounded-md border border-border `}
139
184
>
140
140
-
<div className="bgPickerBody w-full flex flex-col gap-2 p-2 mt-1 border border-[#CCCCCC] rounded-md text-[#595959] bg-white">
141
141
-
<BackgroundPicker
142
142
-
bgImage={image}
143
143
-
setBgImage={setImage}
144
144
-
backgroundColor={localPubTheme.bgLeaflet}
185
185
+
<div className={`flex flex-col gap-3 z-10`}>
186
186
+
<PagePickers
145
187
pageBackground={localPubTheme.bgPage}
188
188
+
primary={localPubTheme.primary}
146
189
setPageBackground={(color) => {
147
190
setTheme((t) => ({ ...t, bgPage: color }));
148
191
}}
149
149
-
setBackgroundColor={(color) => {
150
150
-
setTheme((t) => ({ ...t, bgLeaflet: color }));
192
192
+
setPrimary={(color) => {
193
193
+
setTheme((t) => ({ ...t, primary: color }));
151
194
}}
152
195
openPicker={openPicker}
153
153
-
setOpenPicker={setOpenPicker}
154
154
-
hasPageBackground={!!showPageBackground}
155
155
-
setHasPageBackground={setShowPageBackground}
196
196
+
setOpenPicker={(pickers) => setOpenPicker(pickers)}
197
197
+
hasPageBackground={showPageBackground}
198
198
+
/>
199
199
+
<PubAccentPickers
200
200
+
accent1={localPubTheme.accent1}
201
201
+
setAccent1={(color) => {
202
202
+
setTheme((t) => ({ ...t, accent1: color }));
203
203
+
}}
204
204
+
accent2={localPubTheme.accent2}
205
205
+
setAccent2={(color) => {
206
206
+
setTheme((t) => ({ ...t, accent2: color }));
207
207
+
}}
208
208
+
openPicker={openPicker}
209
209
+
setOpenPicker={(pickers) => setOpenPicker(pickers)}
156
210
/>
157
211
</div>
158
158
-
159
159
-
<SectionArrow
160
160
-
fill="white"
161
161
-
stroke="#CCCCCC"
162
162
-
className="ml-2 -mt-[1px]"
163
163
-
/>
164
212
</div>
165
165
-
</div>
166
166
-
167
167
-
<div
168
168
-
style={{
169
169
-
backgroundImage: pubBGImage ? `url(${pubBGImage})` : undefined,
170
170
-
backgroundRepeat: leafletBGRepeat ? "repeat" : "no-repeat",
171
171
-
backgroundPosition: "center",
172
172
-
backgroundSize: !leafletBGRepeat
173
173
-
? "cover"
174
174
-
: `calc(${leafletBGRepeat}px / 2 )`,
175
175
-
}}
176
176
-
className={` relative bg-bg-leaflet px-3 py-4 flex flex-col rounded-md border border-border `}
177
177
-
>
178
178
-
<div className={`flex flex-col gap-3 z-10`}>
179
179
-
<PagePickers
180
180
-
pageBackground={localPubTheme.bgPage}
181
181
-
primary={localPubTheme.primary}
182
182
-
setPageBackground={(color) => {
183
183
-
setTheme((t) => ({ ...t, bgPage: color }));
184
184
-
}}
185
185
-
setPrimary={(color) => {
186
186
-
setTheme((t) => ({ ...t, primary: color }));
187
187
-
}}
188
188
-
openPicker={openPicker}
189
189
-
setOpenPicker={(pickers) => setOpenPicker(pickers)}
190
190
-
hasPageBackground={showPageBackground}
191
191
-
/>
192
192
-
<PubAccentPickers
193
193
-
accent1={localPubTheme.accent1}
194
194
-
setAccent1={(color) => {
195
195
-
setTheme((t) => ({ ...t, accent1: color }));
196
196
-
}}
197
197
-
accent2={localPubTheme.accent2}
198
198
-
setAccent2={(color) => {
199
199
-
setTheme((t) => ({ ...t, accent2: color }));
200
200
-
}}
201
201
-
openPicker={openPicker}
202
202
-
setOpenPicker={(pickers) => setOpenPicker(pickers)}
203
203
-
/>
213
213
+
<div className="flex flex-col mt-4 ">
214
214
+
<div className="flex gap-2 items-center text-sm text-[#8C8C8C]">
215
215
+
<div className="text-sm">Preview</div>
216
216
+
<Separator classname="h-4!" />{" "}
217
217
+
<button
218
218
+
className={`${sample === "pub" ? "font-bold text-[#595959]" : ""}`}
219
219
+
onClick={() => setSample("pub")}
220
220
+
>
221
221
+
Pub
222
222
+
</button>
223
223
+
<button
224
224
+
className={`${sample === "post" ? "font-bold text-[#595959]" : ""}`}
225
225
+
onClick={() => setSample("post")}
226
226
+
>
227
227
+
Post
228
228
+
</button>
229
229
+
</div>
230
230
+
{sample === "pub" ? (
231
231
+
<SamplePub
232
232
+
pubBGImage={pubBGImage}
233
233
+
pubBGRepeat={leafletBGRepeat}
234
234
+
showPageBackground={showPageBackground}
235
235
+
/>
236
236
+
) : (
237
237
+
<SamplePost
238
238
+
pubBGImage={pubBGImage}
239
239
+
pubBGRepeat={leafletBGRepeat}
240
240
+
showPageBackground={showPageBackground}
241
241
+
/>
242
242
+
)}
204
243
</div>
205
205
-
</div>
206
206
-
<div className="flex flex-col mt-4 ">
207
207
-
<div className="flex gap-2 items-center text-sm text-[#8C8C8C]">
208
208
-
<div className="text-sm">Preview</div>
209
209
-
<Separator classname="h-4!" />{" "}
210
210
-
<button
211
211
-
className={`${sample === "pub" ? "font-bold text-[#595959]" : ""}`}
212
212
-
onClick={() => setSample("pub")}
213
213
-
>
214
214
-
Pub
215
215
-
</button>
216
216
-
<button
217
217
-
className={`${sample === "post" ? "font-bold text-[#595959]" : ""}`}
218
218
-
onClick={() => setSample("post")}
219
219
-
>
220
220
-
Post
221
221
-
</button>
222
222
-
</div>
223
223
-
{sample === "pub" ? (
224
224
-
<SamplePub
225
225
-
pubBGImage={pubBGImage}
226
226
-
pubBGRepeat={leafletBGRepeat}
227
227
-
showPageBackground={showPageBackground}
228
228
-
/>
229
229
-
) : (
230
230
-
<SamplePost
231
231
-
pubBGImage={pubBGImage}
232
232
-
pubBGRepeat={leafletBGRepeat}
233
233
-
showPageBackground={showPageBackground}
234
234
-
/>
235
235
-
)}
236
244
</div>
237
245
</div>
238
246
</BaseThemeProvider>
+3
-1
components/ThemeManager/ThemeProvider.tsx
···
122
122
showPageBackground,
123
123
pageWidth,
124
124
hasBackgroundImage,
125
125
+
className,
125
126
children,
126
127
}: {
127
128
local?: boolean;
···
136
137
highlight2: AriaColor;
137
138
highlight3: AriaColor;
138
139
pageWidth?: number;
140
140
+
className?: string;
139
141
children: React.ReactNode;
140
142
}) => {
141
143
// When showPageBackground is false and there's no background image,
···
239
241
]);
240
242
return (
241
243
<div
242
242
-
className="leafletWrapper w-full text-primary h-full min-h-fit flex flex-col bg-center items-stretch "
244
244
+
className={`leafletWrapper w-full text-primary h-full min-h-fit flex flex-col bg-center items-stretch ${className || ""}`}
243
245
style={
244
246
{
245
247
"--bg-leaflet": colorToString(bgLeaflet, "rgb"),