@farming-labs/svelte-theme 0.0.53 → 0.0.54
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/package.json +3 -3
- package/src/components/DocsContent.svelte +108 -11
- package/styles/colorful.css +15 -0
- package/styles/darksharp.css +19 -0
- package/styles/docs.css +117 -0
- package/styles/greentree.css +15 -0
- package/styles/pixel-border.css +17 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farming-labs/svelte-theme",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.54",
|
|
4
4
|
"description": "Svelte UI components for @farming-labs/docs — layout, sidebar, TOC, search, and theme toggle",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"docs",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
"dependencies": {
|
|
83
83
|
"gray-matter": "^4.0.3",
|
|
84
84
|
"sugar-high": "^0.9.5",
|
|
85
|
-
"@farming-labs/
|
|
86
|
-
"@farming-labs/
|
|
85
|
+
"@farming-labs/svelte": "0.0.54",
|
|
86
|
+
"@farming-labs/docs": "0.0.54"
|
|
87
87
|
},
|
|
88
88
|
"peerDependencies": {
|
|
89
89
|
"svelte": ">=5.0.0"
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
let copyLabel = $state("Copy page");
|
|
14
14
|
let copied = $state(false);
|
|
15
15
|
let selectedFeedback = $state(null);
|
|
16
|
+
let feedbackComment = $state("");
|
|
17
|
+
let feedbackStatus = $state("idle");
|
|
16
18
|
|
|
17
19
|
let titleSuffix = $derived(
|
|
18
20
|
config?.metadata?.titleTemplate
|
|
@@ -122,12 +124,17 @@
|
|
|
122
124
|
);
|
|
123
125
|
let showActionsAbove = $derived(pageActionsPosition === "above-title" && showPageActions);
|
|
124
126
|
let showActionsBelow = $derived(pageActionsPosition === "below-title" && showPageActions);
|
|
127
|
+
let feedbackPathKey = $derived(
|
|
128
|
+
`${data.locale ?? ""}:${data.entry ?? config?.entry ?? "docs"}:${data.slug ?? ""}`
|
|
129
|
+
);
|
|
125
130
|
let feedbackConfig = $derived.by(() => {
|
|
126
131
|
const defaults = {
|
|
127
132
|
enabled: false,
|
|
128
133
|
question: "How is this guide?",
|
|
134
|
+
placeholder: "Leave your feedback...",
|
|
129
135
|
positiveLabel: "Good",
|
|
130
136
|
negativeLabel: "Bad",
|
|
137
|
+
submitLabel: "Submit",
|
|
131
138
|
onFeedback: undefined,
|
|
132
139
|
};
|
|
133
140
|
|
|
@@ -137,12 +144,21 @@
|
|
|
137
144
|
return {
|
|
138
145
|
enabled: feedback.enabled !== false,
|
|
139
146
|
question: feedback.question ?? defaults.question,
|
|
147
|
+
placeholder: feedback.placeholder ?? defaults.placeholder,
|
|
140
148
|
positiveLabel: feedback.positiveLabel ?? defaults.positiveLabel,
|
|
141
149
|
negativeLabel: feedback.negativeLabel ?? defaults.negativeLabel,
|
|
150
|
+
submitLabel: feedback.submitLabel ?? defaults.submitLabel,
|
|
142
151
|
onFeedback: typeof feedback.onFeedback === "function" ? feedback.onFeedback : undefined,
|
|
143
152
|
};
|
|
144
153
|
});
|
|
145
154
|
|
|
155
|
+
$effect(() => {
|
|
156
|
+
feedbackPathKey;
|
|
157
|
+
selectedFeedback = null;
|
|
158
|
+
feedbackComment = "";
|
|
159
|
+
feedbackStatus = "idle";
|
|
160
|
+
});
|
|
161
|
+
|
|
146
162
|
function handleCopyPage() {
|
|
147
163
|
let text = "";
|
|
148
164
|
if (data.rawMarkdown && typeof data.rawMarkdown === "string" && data.rawMarkdown.length > 0) {
|
|
@@ -191,9 +207,7 @@
|
|
|
191
207
|
closeDropdown();
|
|
192
208
|
}
|
|
193
209
|
|
|
194
|
-
function
|
|
195
|
-
selectedFeedback = value;
|
|
196
|
-
|
|
210
|
+
function buildFeedbackPayload() {
|
|
197
211
|
const pathname =
|
|
198
212
|
typeof window !== "undefined"
|
|
199
213
|
? window.location.pathname.replace(/\/$/, "") || "/"
|
|
@@ -201,8 +215,9 @@
|
|
|
201
215
|
? `/${data.entry ?? config?.entry ?? "docs"}/${data.slug}`
|
|
202
216
|
: `/${data.entry ?? config?.entry ?? "docs"}`;
|
|
203
217
|
|
|
204
|
-
|
|
205
|
-
value,
|
|
218
|
+
return {
|
|
219
|
+
value: selectedFeedback,
|
|
220
|
+
comment: feedbackComment.trim() ? feedbackComment.trim() : undefined,
|
|
206
221
|
title: data.title,
|
|
207
222
|
description: data.description,
|
|
208
223
|
url: typeof window !== "undefined" ? window.location.href : pathname,
|
|
@@ -212,21 +227,50 @@
|
|
|
212
227
|
slug: data.slug ?? "",
|
|
213
228
|
locale: data.locale,
|
|
214
229
|
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async function emitFeedback(payload) {
|
|
233
|
+
let firstError = null;
|
|
215
234
|
|
|
216
235
|
try {
|
|
217
|
-
feedbackConfig.onFeedback?.(payload);
|
|
218
|
-
} catch {
|
|
236
|
+
await feedbackConfig.onFeedback?.(payload);
|
|
237
|
+
} catch (error) {
|
|
238
|
+
firstError ??= error;
|
|
239
|
+
}
|
|
219
240
|
|
|
220
241
|
try {
|
|
221
242
|
const docsWindow = typeof window !== "undefined" ? window : undefined;
|
|
222
243
|
if (docsWindow && typeof docsWindow.__fdOnFeedback__ === "function") {
|
|
223
|
-
docsWindow.__fdOnFeedback__(payload);
|
|
244
|
+
await docsWindow.__fdOnFeedback__(payload);
|
|
224
245
|
}
|
|
225
|
-
} catch {
|
|
246
|
+
} catch (error) {
|
|
247
|
+
firstError ??= error;
|
|
248
|
+
}
|
|
226
249
|
|
|
227
250
|
if (typeof window !== "undefined") {
|
|
228
251
|
window.dispatchEvent(new CustomEvent("fd:feedback", { detail: payload }));
|
|
229
252
|
}
|
|
253
|
+
|
|
254
|
+
if (firstError) throw firstError;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function handleFeedback(value) {
|
|
258
|
+
selectedFeedback = value;
|
|
259
|
+
if (feedbackStatus !== "idle") feedbackStatus = "idle";
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async function submitFeedback() {
|
|
263
|
+
if (!selectedFeedback || feedbackStatus === "submitting" || feedbackStatus === "submitted") {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
try {
|
|
268
|
+
feedbackStatus = "submitting";
|
|
269
|
+
await emitFeedback(buildFeedbackPayload());
|
|
270
|
+
feedbackStatus = "submitted";
|
|
271
|
+
} catch {
|
|
272
|
+
feedbackStatus = "error";
|
|
273
|
+
}
|
|
230
274
|
}
|
|
231
275
|
|
|
232
276
|
function handleClickOutside(e) {
|
|
@@ -411,9 +455,10 @@
|
|
|
411
455
|
<div class="fd-feedback-actions" role="group" aria-label={feedbackConfig.question}>
|
|
412
456
|
<button
|
|
413
457
|
type="button"
|
|
414
|
-
class="fd-page-action-btn"
|
|
458
|
+
class="fd-page-action-btn fd-feedback-choice"
|
|
415
459
|
aria-pressed={selectedFeedback === "positive"}
|
|
416
460
|
data-selected={selectedFeedback === "positive" ? "true" : undefined}
|
|
461
|
+
disabled={feedbackStatus === "submitting"}
|
|
417
462
|
onclick={() => handleFeedback("positive")}
|
|
418
463
|
>
|
|
419
464
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
@@ -429,9 +474,10 @@
|
|
|
429
474
|
</button>
|
|
430
475
|
<button
|
|
431
476
|
type="button"
|
|
432
|
-
class="fd-page-action-btn"
|
|
477
|
+
class="fd-page-action-btn fd-feedback-choice"
|
|
433
478
|
aria-pressed={selectedFeedback === "negative"}
|
|
434
479
|
data-selected={selectedFeedback === "negative" ? "true" : undefined}
|
|
480
|
+
disabled={feedbackStatus === "submitting"}
|
|
435
481
|
onclick={() => handleFeedback("negative")}
|
|
436
482
|
>
|
|
437
483
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
@@ -447,6 +493,57 @@
|
|
|
447
493
|
</button>
|
|
448
494
|
</div>
|
|
449
495
|
</div>
|
|
496
|
+
{#if selectedFeedback}
|
|
497
|
+
<div class="fd-feedback-form">
|
|
498
|
+
<textarea
|
|
499
|
+
class="fd-feedback-input"
|
|
500
|
+
aria-label="Additional feedback"
|
|
501
|
+
placeholder={feedbackConfig.placeholder}
|
|
502
|
+
bind:value={feedbackComment}
|
|
503
|
+
disabled={feedbackStatus === "submitting"}
|
|
504
|
+
oninput={() => {
|
|
505
|
+
if (feedbackStatus !== "idle") feedbackStatus = "idle";
|
|
506
|
+
}}
|
|
507
|
+
></textarea>
|
|
508
|
+
<div class="fd-feedback-submit-row">
|
|
509
|
+
<button
|
|
510
|
+
type="button"
|
|
511
|
+
class="fd-page-action-btn fd-feedback-submit"
|
|
512
|
+
disabled={feedbackStatus === "submitting" || feedbackStatus === "submitted"}
|
|
513
|
+
onclick={() => void submitFeedback()}
|
|
514
|
+
>
|
|
515
|
+
{#if feedbackStatus === "submitting"}
|
|
516
|
+
<span class="fd-feedback-spinner" aria-hidden="true"></span>
|
|
517
|
+
{:else if feedbackStatus === "submitted"}
|
|
518
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
519
|
+
<path
|
|
520
|
+
d="M20 6 9 17l-5-5"
|
|
521
|
+
stroke="currentColor"
|
|
522
|
+
stroke-width="2"
|
|
523
|
+
stroke-linecap="round"
|
|
524
|
+
stroke-linejoin="round"
|
|
525
|
+
/>
|
|
526
|
+
</svg>
|
|
527
|
+
{/if}
|
|
528
|
+
<span>
|
|
529
|
+
{feedbackStatus === "submitted"
|
|
530
|
+
? "Submitted"
|
|
531
|
+
: feedbackConfig.submitLabel}
|
|
532
|
+
</span>
|
|
533
|
+
</button>
|
|
534
|
+
{#if feedbackStatus === "submitted"}
|
|
535
|
+
<p class="fd-feedback-status" data-status="success" role="status" aria-live="polite">
|
|
536
|
+
Thanks for the feedback.
|
|
537
|
+
</p>
|
|
538
|
+
{/if}
|
|
539
|
+
</div>
|
|
540
|
+
{#if feedbackStatus === "error"}
|
|
541
|
+
<p class="fd-feedback-status" data-status="error" role="status" aria-live="polite">
|
|
542
|
+
Could not send feedback. Please try again.
|
|
543
|
+
</p>
|
|
544
|
+
{/if}
|
|
545
|
+
</div>
|
|
546
|
+
{/if}
|
|
450
547
|
</section>
|
|
451
548
|
{/if}
|
|
452
549
|
</div>
|
package/styles/colorful.css
CHANGED
|
@@ -328,3 +328,18 @@
|
|
|
328
328
|
.fd-ai-floating-trigger .ask-ai-trigger:hover {
|
|
329
329
|
box-shadow: 0 10px 40px rgba(180, 140, 20, 0.4);
|
|
330
330
|
}
|
|
331
|
+
|
|
332
|
+
/* ─── Feedback (colorful theme) ──────────────────────────────────── */
|
|
333
|
+
|
|
334
|
+
.fd-feedback-input,
|
|
335
|
+
.fd-feedback-submit {
|
|
336
|
+
border-radius: 0.5rem;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.fd-feedback-choice[data-selected="true"] {
|
|
340
|
+
background: color-mix(in srgb, var(--color-fd-primary) 12%, var(--color-fd-secondary));
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.fd-feedback-status[data-status="success"] {
|
|
344
|
+
color: var(--color-fd-primary);
|
|
345
|
+
}
|
package/styles/darksharp.css
CHANGED
|
@@ -275,3 +275,22 @@ code:not(pre code) {
|
|
|
275
275
|
background: var(--color-fd-accent) !important;
|
|
276
276
|
color: var(--color-fd-accent-foreground) !important;
|
|
277
277
|
}
|
|
278
|
+
|
|
279
|
+
/* ─── Feedback (darksharp theme) ─────────────────────────────────── */
|
|
280
|
+
|
|
281
|
+
.fd-feedback-input,
|
|
282
|
+
.fd-feedback-submit {
|
|
283
|
+
border-radius: 0.2rem !important;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.dark .fd-feedback-input {
|
|
287
|
+
background: hsl(0 0% 4%);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
.dark .fd-feedback-choice[data-selected="true"] {
|
|
291
|
+
background: hsl(0 0% 8%);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.dark .fd-feedback-status[data-status="success"] {
|
|
295
|
+
color: hsl(0 0% 90%);
|
|
296
|
+
}
|
package/styles/docs.css
CHANGED
|
@@ -726,6 +726,7 @@ samp {
|
|
|
726
726
|
|
|
727
727
|
.fd-feedback {
|
|
728
728
|
margin-top: 2rem;
|
|
729
|
+
margin-bottom: 1.25rem;
|
|
729
730
|
padding-top: 1.25rem;
|
|
730
731
|
border-top: 1px solid var(--color-fd-border);
|
|
731
732
|
}
|
|
@@ -753,6 +754,122 @@ samp {
|
|
|
753
754
|
flex-wrap: wrap;
|
|
754
755
|
}
|
|
755
756
|
|
|
757
|
+
.fd-feedback-form {
|
|
758
|
+
display: flex;
|
|
759
|
+
flex-direction: column;
|
|
760
|
+
gap: 0.75rem;
|
|
761
|
+
margin-top: 0.875rem;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
.fd-feedback-form[hidden],
|
|
765
|
+
.fd-feedback-spinner[hidden],
|
|
766
|
+
.fd-feedback-status[hidden],
|
|
767
|
+
.fd-feedback-submit svg[hidden] {
|
|
768
|
+
display: none !important;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
.fd-feedback-choice[data-selected="true"] {
|
|
772
|
+
background: var(--color-fd-accent);
|
|
773
|
+
color: var(--color-fd-accent-foreground);
|
|
774
|
+
border-color: color-mix(in srgb, var(--color-fd-primary, currentColor) 65%, transparent);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
.fd-feedback-input {
|
|
778
|
+
width: 100%;
|
|
779
|
+
min-height: 4.75rem;
|
|
780
|
+
resize: vertical;
|
|
781
|
+
padding: 0.875rem 1rem;
|
|
782
|
+
border: 1px solid
|
|
783
|
+
color-mix(in srgb, var(--color-fd-border) 78%, var(--color-fd-foreground) 22%);
|
|
784
|
+
border-radius: 0.5rem;
|
|
785
|
+
background: var(--color-fd-card, transparent);
|
|
786
|
+
color: var(--color-fd-foreground);
|
|
787
|
+
font: inherit;
|
|
788
|
+
line-height: 1.55;
|
|
789
|
+
outline: none;
|
|
790
|
+
transition:
|
|
791
|
+
border-color 150ms ease,
|
|
792
|
+
box-shadow 150ms ease,
|
|
793
|
+
background-color 150ms ease;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
.fd-feedback-input::placeholder {
|
|
797
|
+
color: var(--color-fd-muted-foreground);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.fd-feedback-input:focus {
|
|
801
|
+
border-color: var(--color-fd-ring, var(--color-fd-primary, currentColor));
|
|
802
|
+
box-shadow: 0 0 0 1px var(--color-fd-ring, var(--color-fd-primary, currentColor));
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.fd-feedback-submit-row {
|
|
806
|
+
display: flex;
|
|
807
|
+
align-items: center;
|
|
808
|
+
gap: 0.75rem;
|
|
809
|
+
flex-wrap: nowrap;
|
|
810
|
+
min-height: 2rem;
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
.fd-feedback-submit {
|
|
814
|
+
min-width: 7rem;
|
|
815
|
+
padding-inline: 0.875rem;
|
|
816
|
+
justify-content: center;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
.fd-feedback-submit:disabled {
|
|
820
|
+
cursor: not-allowed;
|
|
821
|
+
opacity: 0.65;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
.fd-feedback-spinner {
|
|
825
|
+
width: 0.875rem;
|
|
826
|
+
height: 0.875rem;
|
|
827
|
+
border-radius: 9999px;
|
|
828
|
+
border: 2px solid currentColor;
|
|
829
|
+
border-right-color: transparent;
|
|
830
|
+
animation: fd-feedback-spin 0.8s linear infinite;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
.fd-feedback-status {
|
|
834
|
+
margin: 0 !important;
|
|
835
|
+
font-size: 0.8125rem;
|
|
836
|
+
line-height: 1.35;
|
|
837
|
+
color: var(--color-fd-muted-foreground);
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
.fd-feedback-status[data-status="success"] {
|
|
841
|
+
display: inline-flex;
|
|
842
|
+
align-self: center;
|
|
843
|
+
align-items: center;
|
|
844
|
+
gap: 0.4rem;
|
|
845
|
+
min-height: 2rem;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
.fd-feedback-status[data-status="success"] {
|
|
849
|
+
color: color-mix(in srgb, var(--color-fd-primary) 85%, var(--color-fd-foreground));
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
.fd-feedback-status[data-status="error"] {
|
|
853
|
+
color: var(--color-fd-foreground);
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
@keyframes fd-feedback-spin {
|
|
857
|
+
to {
|
|
858
|
+
transform: rotate(360deg);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
@media (max-width: 640px) {
|
|
863
|
+
.fd-feedback-content {
|
|
864
|
+
flex-direction: column;
|
|
865
|
+
align-items: flex-start;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
.fd-feedback-submit-row {
|
|
869
|
+
flex-wrap: wrap;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
|
|
756
873
|
/* ─── Breadcrumb ─────────────────────────────────────────────────────── */
|
|
757
874
|
|
|
758
875
|
.fd-breadcrumb {
|
package/styles/greentree.css
CHANGED
|
@@ -892,3 +892,18 @@ details > :not(summary) {
|
|
|
892
892
|
.fd-sidebar::-webkit-scrollbar-track {
|
|
893
893
|
background: transparent;
|
|
894
894
|
}
|
|
895
|
+
|
|
896
|
+
/* ─── Feedback (greentree theme) ─────────────────────────────────── */
|
|
897
|
+
|
|
898
|
+
.fd-feedback-input,
|
|
899
|
+
.fd-feedback-submit {
|
|
900
|
+
border-radius: 0.75rem;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
.fd-feedback-choice[data-selected="true"] {
|
|
904
|
+
background: color-mix(in srgb, var(--color-fd-primary) 12%, var(--color-fd-secondary));
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
.fd-feedback-status[data-status="success"] {
|
|
908
|
+
color: var(--color-fd-primary);
|
|
909
|
+
}
|
package/styles/pixel-border.css
CHANGED
|
@@ -848,3 +848,20 @@ code:not(pre code) {
|
|
|
848
848
|
.fd-page-action-menu-item:first-child {
|
|
849
849
|
border-top: none !important;
|
|
850
850
|
}
|
|
851
|
+
|
|
852
|
+
/* ─── Feedback (pixel-border theme) ──────────────────────────────── */
|
|
853
|
+
|
|
854
|
+
.fd-feedback-input,
|
|
855
|
+
.fd-feedback-submit {
|
|
856
|
+
border-radius: 0 !important;
|
|
857
|
+
box-shadow: 3px 3px 0 0 var(--color-fd-border);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
.fd-feedback-choice[data-selected="true"] {
|
|
861
|
+
background: var(--color-fd-secondary);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.fd-feedback-status[data-status="success"] {
|
|
865
|
+
font-family: var(--fd-font-mono, var(--font-geist-mono, ui-monospace, monospace));
|
|
866
|
+
text-transform: uppercase;
|
|
867
|
+
}
|