@farming-labs/svelte-theme 0.0.5 → 0.0.7
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@farming-labs/svelte-theme",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
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/docs": "0.0.7",
|
|
86
|
+
"@farming-labs/svelte": "0.0.7"
|
|
87
87
|
},
|
|
88
88
|
"peerDependencies": {
|
|
89
89
|
"svelte": ">=5.0.0"
|
|
@@ -198,6 +198,10 @@
|
|
|
198
198
|
const layout = config?.theme?.ui?.layout;
|
|
199
199
|
return [buildColorsCSS(colorOverrides), buildTypographyCSS(typography), buildLayoutCSS(layout)].filter(Boolean).join("\n");
|
|
200
200
|
});
|
|
201
|
+
|
|
202
|
+
// Build style tag from parts so Vite/Svelte preprocessor doesn't treat it as a real <style> block (PostCSS would then fail on "overrideCSS")
|
|
203
|
+
const styleTagOpen = "<sty" + "le>";
|
|
204
|
+
const styleTagClose = "</sty" + "le>";
|
|
201
205
|
</script>
|
|
202
206
|
|
|
203
207
|
<svelte:window onkeydown={handleKeydown} />
|
|
@@ -205,7 +209,7 @@
|
|
|
205
209
|
<svelte:head>
|
|
206
210
|
{@html `<script>${themeInitScript}</script>`}
|
|
207
211
|
{#if overrideCSS}
|
|
208
|
-
{@html
|
|
212
|
+
{@html `${styleTagOpen}${overrideCSS}${styleTagClose}`}
|
|
209
213
|
{/if}
|
|
210
214
|
</svelte:head>
|
|
211
215
|
|
|
@@ -207,14 +207,41 @@
|
|
|
207
207
|
|
|
208
208
|
{#if mounted}
|
|
209
209
|
{#if isFullModal}
|
|
210
|
-
<!-- ═══ Full-Modal Mode (better-auth inspired) ═══
|
|
210
|
+
<!-- ═══ Full-Modal Mode (better-auth inspired) ═══
|
|
211
|
+
Trigger is always in a fixed-position wrapper when closed (no morphing).
|
|
212
|
+
When open: overlay + separate fixed input bar for smooth open/close. -->
|
|
211
213
|
|
|
214
|
+
<!-- When closed: fixed trigger only — stays in place, no layout jump -->
|
|
215
|
+
{#if !isOpen}
|
|
216
|
+
<div class="fd-ai-fm-trigger-fixed" style={btnStyle}>
|
|
217
|
+
{#if triggerComponent}
|
|
218
|
+
{@const Trigger = triggerComponent}
|
|
219
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
220
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
221
|
+
<div onclick={() => isOpen = true} class="fd-ai-floating-trigger fd-ai-floating-trigger--static">
|
|
222
|
+
<Trigger aiLabel={label} />
|
|
223
|
+
</div>
|
|
224
|
+
{:else}
|
|
225
|
+
<button
|
|
226
|
+
onclick={() => isOpen = true}
|
|
227
|
+
class="fd-ai-fm-trigger-btn"
|
|
228
|
+
aria-label="Ask {label}"
|
|
229
|
+
>
|
|
230
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
231
|
+
<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/>
|
|
232
|
+
<path d="M20 3v4"/><path d="M22 5h-4"/>
|
|
233
|
+
</svg>
|
|
234
|
+
<span>Ask {label}</span>
|
|
235
|
+
</button>
|
|
236
|
+
{/if}
|
|
237
|
+
</div>
|
|
238
|
+
{/if}
|
|
239
|
+
|
|
240
|
+
<!-- When open: overlay + input bar (separate elements, no morphing from trigger) -->
|
|
212
241
|
{#if isOpen}
|
|
213
|
-
<!-- Full-screen overlay -->
|
|
214
242
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
215
243
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
216
|
-
<div class="fd-ai-fm-overlay" onclick={(e) => { if (e.target === e.currentTarget) isOpen = false; }}>
|
|
217
|
-
<!-- Close button -->
|
|
244
|
+
<div class="fd-ai-fm-overlay fd-ai-fm-overlay--animate" onclick={(e) => { if (e.target === e.currentTarget) isOpen = false; }}>
|
|
218
245
|
<div class="fd-ai-fm-topbar">
|
|
219
246
|
<button onclick={() => isOpen = false} class="fd-ai-fm-close-btn" aria-label="Close">
|
|
220
247
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
@@ -223,7 +250,6 @@
|
|
|
223
250
|
</button>
|
|
224
251
|
</div>
|
|
225
252
|
|
|
226
|
-
<!-- Scrollable message list -->
|
|
227
253
|
<div bind:this={fmListEl} class="fd-ai-fm-messages">
|
|
228
254
|
<div class="fd-ai-fm-messages-inner">
|
|
229
255
|
{#each messages as msg, i}
|
|
@@ -252,38 +278,9 @@
|
|
|
252
278
|
</div>
|
|
253
279
|
</div>
|
|
254
280
|
</div>
|
|
255
|
-
{/if}
|
|
256
281
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
class="fd-ai-fm-input-bar {isOpen ? 'fd-ai-fm-input-bar--open' : 'fd-ai-fm-input-bar--closed'}"
|
|
260
|
-
style={isOpen ? undefined : btnStyle}
|
|
261
|
-
>
|
|
262
|
-
{#if !isOpen}
|
|
263
|
-
{#if triggerComponent}
|
|
264
|
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
265
|
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
266
|
-
<div
|
|
267
|
-
onclick={() => isOpen = true}
|
|
268
|
-
class="fd-ai-floating-trigger"
|
|
269
|
-
style={btnStyle}
|
|
270
|
-
>
|
|
271
|
-
<svelte:component this={triggerComponent} aiLabel={label} />
|
|
272
|
-
</div>
|
|
273
|
-
{:else}
|
|
274
|
-
<button
|
|
275
|
-
onclick={() => isOpen = true}
|
|
276
|
-
class="fd-ai-fm-trigger-btn"
|
|
277
|
-
aria-label="Ask {label}"
|
|
278
|
-
>
|
|
279
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
280
|
-
<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/>
|
|
281
|
-
<path d="M20 3v4"/><path d="M22 5h-4"/>
|
|
282
|
-
</svg>
|
|
283
|
-
<span>Ask {label}</span>
|
|
284
|
-
</button>
|
|
285
|
-
{/if}
|
|
286
|
-
{:else}
|
|
282
|
+
<!-- Input bar when open: fixed at bottom center, never morphs from trigger -->
|
|
283
|
+
<div class="fd-ai-fm-input-bar fd-ai-fm-input-bar--open">
|
|
287
284
|
<div class="fd-ai-fm-input-container">
|
|
288
285
|
<div class="fd-ai-fm-input-wrap">
|
|
289
286
|
<textarea
|
|
@@ -350,9 +347,8 @@
|
|
|
350
347
|
{/if}
|
|
351
348
|
</div>
|
|
352
349
|
</div>
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
350
|
+
</div>
|
|
351
|
+
{/if}
|
|
356
352
|
{:else}
|
|
357
353
|
<!-- ═══ Panel / Modal / Popover Mode ═══ -->
|
|
358
354
|
|
|
@@ -479,6 +475,7 @@
|
|
|
479
475
|
|
|
480
476
|
{#if !isOpen}
|
|
481
477
|
{#if triggerComponent}
|
|
478
|
+
{@const Trigger = triggerComponent}
|
|
482
479
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
483
480
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
484
481
|
<div
|
|
@@ -486,7 +483,7 @@
|
|
|
486
483
|
class="fd-ai-floating-trigger"
|
|
487
484
|
style={btnStyle}
|
|
488
485
|
>
|
|
489
|
-
<
|
|
486
|
+
<Trigger aiLabel={label} />
|
|
490
487
|
</div>
|
|
491
488
|
{:else}
|
|
492
489
|
<button
|
package/styles/docs.css
CHANGED
|
@@ -2017,6 +2017,56 @@ html.dark pre.shiki {
|
|
|
2017
2017
|
font-size: 12px;
|
|
2018
2018
|
}
|
|
2019
2019
|
|
|
2020
|
+
/* ─── Markdown prose inside AI bubbles (panel/modal/popover) ─────── */
|
|
2021
|
+
|
|
2022
|
+
.fd-ai-bubble-ai h2 {
|
|
2023
|
+
font-size: 1.125rem;
|
|
2024
|
+
font-weight: 600;
|
|
2025
|
+
margin: 12px 0 6px;
|
|
2026
|
+
line-height: 1.3;
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
.fd-ai-bubble-ai h3 {
|
|
2030
|
+
font-size: 1rem;
|
|
2031
|
+
font-weight: 600;
|
|
2032
|
+
margin: 10px 0 4px;
|
|
2033
|
+
line-height: 1.4;
|
|
2034
|
+
}
|
|
2035
|
+
|
|
2036
|
+
.fd-ai-bubble-ai h4 {
|
|
2037
|
+
font-size: 0.9375rem;
|
|
2038
|
+
font-weight: 600;
|
|
2039
|
+
margin: 8px 0 4px;
|
|
2040
|
+
line-height: 1.4;
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
.fd-ai-bubble-ai strong {
|
|
2044
|
+
font-weight: 600;
|
|
2045
|
+
color: var(--color-fd-foreground, #e4e4e7);
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
.fd-ai-bubble-ai em {
|
|
2049
|
+
font-style: italic;
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
.fd-ai-bubble-ai p {
|
|
2053
|
+
margin: 0 0 6px;
|
|
2054
|
+
}
|
|
2055
|
+
|
|
2056
|
+
.fd-ai-bubble-ai br {
|
|
2057
|
+
content: "";
|
|
2058
|
+
display: block;
|
|
2059
|
+
margin-top: 2px;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
.fd-ai-bubble-ai pre {
|
|
2063
|
+
margin: 8px 0;
|
|
2064
|
+
border-radius: 0;
|
|
2065
|
+
border: none;
|
|
2066
|
+
background: transparent;
|
|
2067
|
+
padding: 0;
|
|
2068
|
+
}
|
|
2069
|
+
|
|
2020
2070
|
/* ═══════════════════════════════════════════════════════════════════
|
|
2021
2071
|
* Code blocks in AI chat — fd-ai-code-*
|
|
2022
2072
|
* ═══════════════════════════════════════════════════════════════════ */
|
|
@@ -2212,6 +2262,20 @@ html.dark pre.shiki {
|
|
|
2212
2262
|
transform: scale(0.97);
|
|
2213
2263
|
}
|
|
2214
2264
|
|
|
2265
|
+
/* Dark mode: floating button and trigger use dark-friendly colors */
|
|
2266
|
+
.dark .fd-ai-floating-btn,
|
|
2267
|
+
.dark .fd-ai-fm-trigger-btn {
|
|
2268
|
+
background: color-mix(in srgb, var(--color-fd-secondary, rgba(255, 255, 255, 0.08)) 90%, transparent);
|
|
2269
|
+
color: var(--color-fd-foreground, #e4e4e7);
|
|
2270
|
+
border-color: var(--color-fd-border, rgba(255, 255, 255, 0.12));
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
.dark .fd-ai-floating-btn:hover,
|
|
2274
|
+
.dark .fd-ai-fm-trigger-btn:hover {
|
|
2275
|
+
background: var(--color-fd-accent);
|
|
2276
|
+
color: var(--color-fd-accent-foreground);
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2215
2279
|
.fd-ai-floating-trigger {
|
|
2216
2280
|
position: fixed;
|
|
2217
2281
|
z-index: 9997;
|
|
@@ -2240,12 +2304,23 @@ html.dark pre.shiki {
|
|
|
2240
2304
|
transition: transform 150ms, background 150ms, color 150ms;
|
|
2241
2305
|
}
|
|
2242
2306
|
|
|
2307
|
+
.dark .fd-ai-floating-trigger .ask-ai-trigger {
|
|
2308
|
+
background: color-mix(in srgb, var(--color-fd-secondary, rgba(255, 255, 255, 0.08)) 90%, transparent);
|
|
2309
|
+
color: var(--color-fd-foreground, #e4e4e7);
|
|
2310
|
+
border-color: var(--color-fd-border, rgba(255, 255, 255, 0.12));
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2243
2313
|
.fd-ai-floating-trigger .ask-ai-trigger:hover {
|
|
2244
2314
|
background: var(--color-fd-accent);
|
|
2245
2315
|
color: var(--color-fd-accent-foreground);
|
|
2246
2316
|
transform: scale(1.03);
|
|
2247
2317
|
}
|
|
2248
2318
|
|
|
2319
|
+
.dark .fd-ai-floating-trigger .ask-ai-trigger:hover {
|
|
2320
|
+
background: var(--color-fd-accent);
|
|
2321
|
+
color: var(--color-fd-accent-foreground);
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2249
2324
|
.fd-ai-floating-trigger .ask-ai-trigger:active {
|
|
2250
2325
|
transform: scale(0.97);
|
|
2251
2326
|
}
|
|
@@ -2254,6 +2329,17 @@ html.dark pre.shiki {
|
|
|
2254
2329
|
Full-Modal (better-auth inspired) — fd-ai-fm-*
|
|
2255
2330
|
═══════════════════════════════════════════════════════════════ */
|
|
2256
2331
|
|
|
2332
|
+
/* Fixed wrapper for trigger when closed — never morphs, so no "stuck" feel */
|
|
2333
|
+
.fd-ai-fm-trigger-fixed {
|
|
2334
|
+
position: fixed;
|
|
2335
|
+
z-index: 9997;
|
|
2336
|
+
animation: fd-ai-fade-in 200ms ease-out;
|
|
2337
|
+
}
|
|
2338
|
+
|
|
2339
|
+
.fd-ai-floating-trigger--static {
|
|
2340
|
+
position: static;
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2257
2343
|
.fd-ai-fm-overlay {
|
|
2258
2344
|
position: fixed;
|
|
2259
2345
|
inset: 0;
|
|
@@ -2263,10 +2349,13 @@ html.dark pre.shiki {
|
|
|
2263
2349
|
background: color-mix(in srgb, var(--color-fd-background, #000) 80%, transparent);
|
|
2264
2350
|
backdrop-filter: blur(8px);
|
|
2265
2351
|
z-index: 9998;
|
|
2266
|
-
animation: fd-ai-fade-in 200ms ease-out;
|
|
2267
2352
|
padding: 0 8px;
|
|
2268
2353
|
}
|
|
2269
2354
|
|
|
2355
|
+
.fd-ai-fm-overlay--animate {
|
|
2356
|
+
animation: fd-ai-fade-in 200ms ease-out;
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2270
2359
|
/* ─── Top bar (close button) ─────────────────────────────────── */
|
|
2271
2360
|
|
|
2272
2361
|
.fd-ai-fm-topbar {
|
|
@@ -2391,6 +2480,56 @@ html.dark pre.shiki {
|
|
|
2391
2480
|
font-size: 12px;
|
|
2392
2481
|
}
|
|
2393
2482
|
|
|
2483
|
+
/* ─── Markdown prose inside full-modal messages ──────────────────── */
|
|
2484
|
+
|
|
2485
|
+
.fd-ai-fm-msg-content h2 {
|
|
2486
|
+
font-size: 1.25rem;
|
|
2487
|
+
font-weight: 600;
|
|
2488
|
+
margin: 16px 0 8px;
|
|
2489
|
+
line-height: 1.3;
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
.fd-ai-fm-msg-content h3 {
|
|
2493
|
+
font-size: 1.0625rem;
|
|
2494
|
+
font-weight: 600;
|
|
2495
|
+
margin: 12px 0 6px;
|
|
2496
|
+
line-height: 1.4;
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
.fd-ai-fm-msg-content h4 {
|
|
2500
|
+
font-size: 1rem;
|
|
2501
|
+
font-weight: 600;
|
|
2502
|
+
margin: 10px 0 4px;
|
|
2503
|
+
line-height: 1.4;
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
.fd-ai-fm-msg-content strong {
|
|
2507
|
+
font-weight: 600;
|
|
2508
|
+
color: var(--color-fd-foreground, #e4e4e7);
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
.fd-ai-fm-msg-content em {
|
|
2512
|
+
font-style: italic;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
.fd-ai-fm-msg-content p {
|
|
2516
|
+
margin: 0 0 8px;
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
.fd-ai-fm-msg-content br {
|
|
2520
|
+
content: "";
|
|
2521
|
+
display: block;
|
|
2522
|
+
margin-top: 2px;
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
.fd-ai-fm-msg-content pre {
|
|
2526
|
+
margin: 8px 0;
|
|
2527
|
+
border-radius: 0;
|
|
2528
|
+
border: none;
|
|
2529
|
+
background: transparent;
|
|
2530
|
+
padding: 0;
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2394
2533
|
/* Full-modal now uses the shared .fd-ai-loader indicator */
|
|
2395
2534
|
|
|
2396
2535
|
/* ─── Bottom input bar ───────────────────────────────────────── */
|
|
@@ -2398,14 +2537,6 @@ html.dark pre.shiki {
|
|
|
2398
2537
|
.fd-ai-fm-input-bar {
|
|
2399
2538
|
position: fixed;
|
|
2400
2539
|
z-index: 9999;
|
|
2401
|
-
transition:
|
|
2402
|
-
width 300ms cubic-bezier(0.34, 1.56, 0.64, 1),
|
|
2403
|
-
height 300ms cubic-bezier(0.34, 1.56, 0.64, 1),
|
|
2404
|
-
transform 200ms ease-out;
|
|
2405
|
-
}
|
|
2406
|
-
|
|
2407
|
-
.fd-ai-fm-input-bar--closed {
|
|
2408
|
-
/* inherits position from inline btnPosition styles */
|
|
2409
2540
|
}
|
|
2410
2541
|
|
|
2411
2542
|
.fd-ai-fm-input-bar--open {
|
|
@@ -2413,6 +2544,7 @@ html.dark pre.shiki {
|
|
|
2413
2544
|
left: 50%;
|
|
2414
2545
|
transform: translateX(-50%);
|
|
2415
2546
|
width: min(800px, calc(100vw - 32px));
|
|
2547
|
+
animation: fd-ai-fade-in 200ms ease-out;
|
|
2416
2548
|
}
|
|
2417
2549
|
|
|
2418
2550
|
.fd-ai-fm-input-container {
|