@fuzdev/fuz_ui 0.191.4 → 0.193.0
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/dist/ApiIndex.svelte +3 -3
- package/dist/ApiModule.svelte +2 -2
- package/dist/ApiModulesList.svelte +3 -3
- package/dist/ColorSchemeInput.svelte +6 -6
- package/dist/ContextmenuLinkEntry.svelte +1 -1
- package/dist/ContextmenuRoot.svelte +10 -10
- package/dist/ContextmenuRootForSafariCompatibility.svelte +19 -19
- package/dist/ContextmenuSeparator.svelte +3 -3
- package/dist/ContextmenuSubmenu.svelte +3 -3
- package/dist/CopyToClipboard.svelte +3 -3
- package/dist/DeclarationLink.svelte +1 -1
- package/dist/Dialog.svelte +16 -16
- package/dist/Docs.svelte +12 -12
- package/dist/DocsFooter.svelte +2 -2
- package/dist/DocsList.svelte +7 -7
- package/dist/DocsMenu.svelte +4 -4
- package/dist/DocsMenu.svelte.d.ts.map +1 -1
- package/dist/DocsPageLinks.svelte +4 -4
- package/dist/DocsPrimaryNav.svelte +2 -2
- package/dist/DocsSecondaryNav.svelte +4 -4
- package/dist/DocsTertiaryNav.svelte +13 -13
- package/dist/DocsTertiaryNav.svelte.d.ts +1 -1
- package/dist/GithubLink.svelte +1 -1
- package/dist/Hashlink.svelte +2 -2
- package/dist/HueInput.svelte +5 -5
- package/dist/LibraryDetail.svelte +8 -8
- package/dist/LibrarySummary.svelte +4 -4
- package/dist/MdnLink.svelte +1 -1
- package/dist/ModuleLink.svelte +1 -1
- package/dist/PasteFromClipboard.svelte +1 -1
- package/dist/PendingAnimation.svelte +2 -2
- package/dist/PendingButton.svelte +2 -2
- package/dist/ProjectLinks.svelte +4 -4
- package/dist/Teleport.svelte +2 -2
- package/dist/ThemeInput.svelte +5 -5
- package/dist/TomeContent.svelte +3 -3
- package/dist/TomeHeader.svelte +15 -14
- package/dist/TomeHeader.svelte.d.ts.map +1 -1
- package/dist/TomeLink.svelte +13 -6
- package/dist/TomeLink.svelte.d.ts +1 -1
- package/dist/TomeLink.svelte.d.ts.map +1 -1
- package/dist/TomeSection.svelte +1 -1
- package/dist/TomeSectionHeader.svelte +3 -3
- package/dist/api_search.svelte.js +2 -2
- package/dist/contextmenu_state.svelte.d.ts.map +1 -1
- package/dist/contextmenu_state.svelte.js +11 -10
- package/dist/csp.d.ts +81 -90
- package/dist/csp.d.ts.map +1 -1
- package/dist/csp.js +145 -163
- package/dist/csp_of_fuzdev.d.ts +13 -3
- package/dist/csp_of_fuzdev.d.ts.map +1 -1
- package/dist/csp_of_fuzdev.js +23 -7
- package/dist/dimensions.svelte.d.ts.map +1 -1
- package/dist/dimensions.svelte.js +2 -2
- package/dist/library.svelte.d.ts +1 -1
- package/dist/library_generate.js +1 -1
- package/dist/style_variable_helpers.svelte.d.ts.map +1 -1
- package/dist/style_variable_helpers.svelte.js +1 -1
- package/dist/theme_state.svelte.d.ts.map +1 -1
- package/dist/theme_state.svelte.js +2 -2
- package/dist/tome.d.ts +8 -3
- package/dist/tome.d.ts.map +1 -1
- package/dist/tome.js +24 -8
- package/dist/tsdoc_helpers.d.ts +9 -0
- package/dist/tsdoc_helpers.d.ts.map +1 -1
- package/dist/tsdoc_helpers.js +15 -5
- package/package.json +5 -5
- package/src/lib/api_search.svelte.ts +2 -2
- package/src/lib/contextmenu_state.svelte.ts +11 -10
- package/src/lib/csp.ts +224 -258
- package/src/lib/csp_of_fuzdev.ts +24 -8
- package/src/lib/dimensions.svelte.ts +2 -2
- package/src/lib/library_generate.ts +1 -1
- package/src/lib/style_variable_helpers.svelte.ts +1 -1
- package/src/lib/theme_state.svelte.ts +2 -2
- package/src/lib/tome.ts +25 -8
- package/src/lib/tsdoc_helpers.ts +18 -7
package/dist/ApiIndex.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import {library_context, type Library} from './library.svelte.js';
|
|
3
|
-
import {
|
|
3
|
+
import {tome_get_by_slug, type Tome} from './tome.js';
|
|
4
4
|
import TomeContent from './TomeContent.svelte';
|
|
5
5
|
import TomeLink from './TomeLink.svelte';
|
|
6
6
|
import DocsSearch from './DocsSearch.svelte';
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const {
|
|
12
12
|
library = library_context.get(),
|
|
13
|
-
tome =
|
|
13
|
+
tome = tome_get_by_slug('api'),
|
|
14
14
|
minimal = false,
|
|
15
15
|
}: {
|
|
16
16
|
/**
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
<TomeContent {tome}>
|
|
41
41
|
{#if minimal}
|
|
42
42
|
<section>
|
|
43
|
-
<p>Browse the full <TomeLink
|
|
43
|
+
<p>Browse the full <TomeLink slug="api" /> docs.</p>
|
|
44
44
|
</section>
|
|
45
45
|
{:else}
|
|
46
46
|
<section>
|
package/dist/ApiModule.svelte
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import {library_context, type Library} from './library.svelte.js';
|
|
3
|
-
import {
|
|
3
|
+
import {tome_get_by_slug, type Tome} from './tome.js';
|
|
4
4
|
import TomeContent from './TomeContent.svelte';
|
|
5
5
|
import TomeSection from './TomeSection.svelte';
|
|
6
6
|
import TomeSectionHeader from './TomeSectionHeader.svelte';
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
const {
|
|
14
14
|
module_path: module_path_param,
|
|
15
15
|
library = library_context.get(),
|
|
16
|
-
tome =
|
|
16
|
+
tome = tome_get_by_slug('api'),
|
|
17
17
|
}: {
|
|
18
18
|
/**
|
|
19
19
|
* The module path parameter from the route (e.g., "lib/Button.svelte").
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
{#if modules.length === 0}
|
|
28
28
|
<p class="color_c">No modules match your search.</p>
|
|
29
29
|
{:else}
|
|
30
|
-
<ul class="
|
|
30
|
+
<ul class="modules-list">
|
|
31
31
|
{#each modules as module (module.path)}
|
|
32
32
|
<li>
|
|
33
33
|
<ModuleLink module_path={module.path} />
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
{/if}
|
|
40
40
|
|
|
41
41
|
<style>
|
|
42
|
-
.
|
|
42
|
+
.modules-list {
|
|
43
43
|
display: flex;
|
|
44
44
|
flex-wrap: wrap;
|
|
45
45
|
gap: var(--space_xs);
|
|
46
46
|
padding: 0;
|
|
47
47
|
list-style: none;
|
|
48
48
|
}
|
|
49
|
-
.
|
|
49
|
+
.modules-list li {
|
|
50
50
|
margin: 0;
|
|
51
51
|
}
|
|
52
52
|
</style>
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
|
|
18
18
|
<!-- TODO maybe support menubar aria
|
|
19
19
|
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menubar_role -->
|
|
20
|
-
<menu {...rest} class="
|
|
20
|
+
<menu {...rest} class="color-scheme-control unstyled {rest.class}">
|
|
21
21
|
{#each color_schemes as color_scheme (color_scheme)}
|
|
22
22
|
{@const selected = color_scheme === value.color_scheme}
|
|
23
23
|
<button
|
|
24
24
|
type="button"
|
|
25
|
-
class="
|
|
25
|
+
class="color-scheme color_a"
|
|
26
26
|
role="menuitemradio"
|
|
27
27
|
title={selected
|
|
28
28
|
? `${color_scheme} color scheme is selected`
|
|
@@ -40,7 +40,7 @@ https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menubar_ro
|
|
|
40
40
|
</menu>
|
|
41
41
|
|
|
42
42
|
<style>
|
|
43
|
-
.
|
|
43
|
+
.color-scheme-control {
|
|
44
44
|
display: flex;
|
|
45
45
|
flex-direction: row;
|
|
46
46
|
justify-content: center;
|
|
@@ -51,14 +51,14 @@ https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/menubar_ro
|
|
|
51
51
|
justify-content: center;
|
|
52
52
|
padding: 0 var(--space_lg);
|
|
53
53
|
}
|
|
54
|
-
.
|
|
54
|
+
.color-scheme {
|
|
55
55
|
border-radius: 0;
|
|
56
56
|
}
|
|
57
|
-
.
|
|
57
|
+
.color-scheme:first-child {
|
|
58
58
|
border-top-left-radius: var(--border_radius, var(--border_radius_md));
|
|
59
59
|
border-bottom-left-radius: var(--border_radius, var(--border_radius_md));
|
|
60
60
|
}
|
|
61
|
-
.
|
|
61
|
+
.color-scheme:last-child {
|
|
62
62
|
border-top-right-radius: var(--border_radius, var(--border_radius_md));
|
|
63
63
|
border-bottom-right-radius: var(--border_radius, var(--border_radius_md));
|
|
64
64
|
}
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
const get_contextmenu = contextmenu_context.get();
|
|
24
24
|
const contextmenu = $derived(get_contextmenu());
|
|
25
25
|
|
|
26
|
-
let anchor_el: HTMLAnchorElement | undefined = $state();
|
|
26
|
+
let anchor_el: HTMLAnchorElement | undefined = $state.raw();
|
|
27
27
|
|
|
28
28
|
// Register with state management for keyboard navigation
|
|
29
29
|
// When activated via keyboard, programmatically click the anchor to trigger navigation
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
|
|
114
114
|
if (DEV) contextmenu_check_global_root(() => scoped); // TODO @many is this import tree-shaken?
|
|
115
115
|
|
|
116
|
-
let el: HTMLElement | undefined = $state();
|
|
116
|
+
let el: HTMLElement | undefined = $state.raw();
|
|
117
117
|
|
|
118
118
|
const {layout} = $derived(contextmenu);
|
|
119
119
|
|
|
@@ -128,11 +128,11 @@
|
|
|
128
128
|
|
|
129
129
|
// State for tap-then-longpress bypass detection.
|
|
130
130
|
// These values are `undefined` when unused, and `null` after being reset.
|
|
131
|
-
let touch_x: number | undefined | null = $state();
|
|
132
|
-
let touch_y: number | undefined | null = $state();
|
|
133
|
-
let first_tap_time: number | undefined | null = $state();
|
|
134
|
-
let longpress_bypass: boolean | undefined = $state();
|
|
135
|
-
let tap_tracking_timeout: NodeJS.Timeout | undefined | null = $state();
|
|
131
|
+
let touch_x: number | undefined | null = $state.raw();
|
|
132
|
+
let touch_y: number | undefined | null = $state.raw();
|
|
133
|
+
let first_tap_time: number | undefined | null = $state.raw();
|
|
134
|
+
let longpress_bypass: boolean | undefined = $state.raw();
|
|
135
|
+
let tap_tracking_timeout: NodeJS.Timeout | undefined | null = $state.raw();
|
|
136
136
|
|
|
137
137
|
const on_window_contextmenu = (e: MouseEvent) => {
|
|
138
138
|
// Handle the tap-then-longpress bypass gesture
|
|
@@ -273,7 +273,7 @@
|
|
|
273
273
|
|
|
274
274
|
{#if scoped}
|
|
275
275
|
<div
|
|
276
|
-
class="
|
|
276
|
+
class="contextmenu-root"
|
|
277
277
|
role="region"
|
|
278
278
|
oncontextmenu={on_window_contextmenu}
|
|
279
279
|
ontouchstartcapture={!bypass_with_tap_then_longpress ? undefined : touchstart}
|
|
@@ -287,7 +287,7 @@
|
|
|
287
287
|
|
|
288
288
|
{#if !contextmenu.has_custom_layout}
|
|
289
289
|
<div
|
|
290
|
-
class="
|
|
290
|
+
class="contextmenu-layout"
|
|
291
291
|
bind:clientWidth={layout.width}
|
|
292
292
|
bind:clientHeight={layout.height}
|
|
293
293
|
aria-hidden="true"
|
|
@@ -335,7 +335,7 @@
|
|
|
335
335
|
{/snippet}
|
|
336
336
|
|
|
337
337
|
<style>
|
|
338
|
-
.
|
|
338
|
+
.contextmenu-root {
|
|
339
339
|
display: contents;
|
|
340
340
|
}
|
|
341
341
|
.contextmenu {
|
|
@@ -356,7 +356,7 @@
|
|
|
356
356
|
border-radius: var(--contextmenu_border_radius, var(--border_radius_xs));
|
|
357
357
|
}
|
|
358
358
|
|
|
359
|
-
.
|
|
359
|
+
.contextmenu-layout {
|
|
360
360
|
z-index: -200;
|
|
361
361
|
position: fixed;
|
|
362
362
|
inset: 0;
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
|
|
128
128
|
if (DEV) contextmenu_check_global_root(() => scoped); // TODO @many is this import tree-shaken?
|
|
129
129
|
|
|
130
|
-
let el: HTMLElement | undefined = $state();
|
|
130
|
+
let el: HTMLElement | undefined = $state.raw();
|
|
131
131
|
|
|
132
132
|
const {layout} = $derived(contextmenu);
|
|
133
133
|
|
|
@@ -144,34 +144,34 @@
|
|
|
144
144
|
|
|
145
145
|
// State for tap-then-longpress bypass detection.
|
|
146
146
|
// These values are `undefined` when unused, and `null` after being reset.
|
|
147
|
-
let touch_x: number | undefined | null = $state();
|
|
148
|
-
let touch_y: number | undefined | null = $state();
|
|
149
|
-
let first_tap_time: number | undefined | null = $state();
|
|
150
|
-
let longpress_timeout: NodeJS.Timeout | undefined | null = $state();
|
|
151
|
-
let longpress_opened: boolean | undefined = $state();
|
|
152
|
-
let longpress_bypass: boolean | undefined = $state();
|
|
153
|
-
let tap_tracking_timeout: NodeJS.Timeout | undefined | null = $state();
|
|
147
|
+
let touch_x: number | undefined | null = $state.raw();
|
|
148
|
+
let touch_y: number | undefined | null = $state.raw();
|
|
149
|
+
let first_tap_time: number | undefined | null = $state.raw();
|
|
150
|
+
let longpress_timeout: NodeJS.Timeout | undefined | null = $state.raw();
|
|
151
|
+
let longpress_opened: boolean | undefined = $state.raw();
|
|
152
|
+
let longpress_bypass: boolean | undefined = $state.raw();
|
|
153
|
+
let tap_tracking_timeout: NodeJS.Timeout | undefined | null = $state.raw();
|
|
154
154
|
|
|
155
155
|
/**
|
|
156
156
|
* Blocks the next click event. Set to true when a longpress completes to prevent
|
|
157
157
|
* iOS's synthesized click from activating the first menu item.
|
|
158
158
|
*/
|
|
159
|
-
let block_next_click = $state(false);
|
|
159
|
+
let block_next_click = $state.raw(false);
|
|
160
160
|
|
|
161
161
|
/**
|
|
162
|
-
* Adds
|
|
162
|
+
* Adds contextmenu-pending class to body during longpress tracking.
|
|
163
163
|
* This applies aggressive user-select/touch-callout blocking via CSS
|
|
164
164
|
* to give iOS the earliest possible signal to not show selection UI.
|
|
165
165
|
*/
|
|
166
166
|
const add_contextmenu_pending_class = (): void => {
|
|
167
|
-
document.body.classList.add('
|
|
167
|
+
document.body.classList.add('contextmenu-pending');
|
|
168
168
|
};
|
|
169
169
|
|
|
170
170
|
/**
|
|
171
|
-
* Removes
|
|
171
|
+
* Removes contextmenu-pending class from body when tracking ends.
|
|
172
172
|
*/
|
|
173
173
|
const remove_contextmenu_pending_class = (): void => {
|
|
174
|
-
document.body.classList.remove('
|
|
174
|
+
document.body.classList.remove('contextmenu-pending');
|
|
175
175
|
};
|
|
176
176
|
|
|
177
177
|
/**
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
* Resets all state - both longpress and tap tracking.
|
|
207
207
|
*/
|
|
208
208
|
const reset_all = (): void => {
|
|
209
|
-
reset_longpress_timeout(); // Also removes
|
|
209
|
+
reset_longpress_timeout(); // Also removes contextmenu-pending class
|
|
210
210
|
reset_tap_tracking();
|
|
211
211
|
};
|
|
212
212
|
|
|
@@ -419,7 +419,7 @@
|
|
|
419
419
|
|
|
420
420
|
{#if scoped}
|
|
421
421
|
<div
|
|
422
|
-
class="
|
|
422
|
+
class="contextmenu-root"
|
|
423
423
|
role="region"
|
|
424
424
|
oncontextmenu={on_window_contextmenu}
|
|
425
425
|
{@attach touch_event_attachment}
|
|
@@ -432,7 +432,7 @@
|
|
|
432
432
|
|
|
433
433
|
{#if !contextmenu.has_custom_layout}
|
|
434
434
|
<div
|
|
435
|
-
class="
|
|
435
|
+
class="contextmenu-layout"
|
|
436
436
|
bind:clientWidth={layout.width}
|
|
437
437
|
bind:clientHeight={layout.height}
|
|
438
438
|
aria-hidden="true"
|
|
@@ -487,7 +487,7 @@
|
|
|
487
487
|
{/snippet}
|
|
488
488
|
|
|
489
489
|
<style>
|
|
490
|
-
:global(body.
|
|
490
|
+
:global(body.contextmenu-pending) {
|
|
491
491
|
/* Applied during active longpress tracking.
|
|
492
492
|
Aggressive blocking to give iOS earliest possible signal to not show selection UI.
|
|
493
493
|
Combined with preventDefault() in touchmove for defense in depth. */
|
|
@@ -496,7 +496,7 @@
|
|
|
496
496
|
-webkit-touch-callout: none !important;
|
|
497
497
|
}
|
|
498
498
|
|
|
499
|
-
.
|
|
499
|
+
.contextmenu-root {
|
|
500
500
|
display: contents;
|
|
501
501
|
}
|
|
502
502
|
.contextmenu {
|
|
@@ -525,7 +525,7 @@
|
|
|
525
525
|
}
|
|
526
526
|
|
|
527
527
|
/* TODO better way to do this? */
|
|
528
|
-
.
|
|
528
|
+
.contextmenu-layout {
|
|
529
529
|
z-index: -200;
|
|
530
530
|
position: fixed;
|
|
531
531
|
inset: 0;
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
const {...rest}: SvelteHTMLElements['li'] = $props();
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
|
-
<li role="separator" aria-orientation="vertical" {...rest} class:
|
|
7
|
+
<li role="separator" aria-orientation="vertical" {...rest} class:contextmenu-separator={true}></li>
|
|
8
8
|
|
|
9
9
|
<style>
|
|
10
|
-
.
|
|
10
|
+
.contextmenu-separator {
|
|
11
11
|
height: var(--border_width);
|
|
12
|
-
margin: var(--
|
|
12
|
+
margin: var(--space_xs) var(--space_sm);
|
|
13
13
|
background-color: var(--border_color_10);
|
|
14
14
|
list-style: none;
|
|
15
15
|
}
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
|
|
26
26
|
const {selected} = $derived(submenu);
|
|
27
27
|
|
|
28
|
-
let el: HTMLElement | undefined = $state();
|
|
28
|
+
let el: HTMLElement | undefined = $state.raw();
|
|
29
29
|
|
|
30
30
|
const parent_dimensions = contextmenu_dimensions_context.get();
|
|
31
31
|
const dimensions = contextmenu_dimensions_context.set();
|
|
32
32
|
|
|
33
|
-
let translate_x = $state(0);
|
|
34
|
-
let translate_y = $state(0);
|
|
33
|
+
let translate_x = $state.raw(0);
|
|
34
|
+
let translate_y = $state.raw(0);
|
|
35
35
|
$effect(() => {
|
|
36
36
|
if (el) update_position(el, layout, parent_dimensions);
|
|
37
37
|
});
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
} = $props();
|
|
31
31
|
|
|
32
32
|
// These are for visual feedback
|
|
33
|
-
let copied = $state(false);
|
|
34
|
-
let failed = $state(false);
|
|
33
|
+
let copied = $state.raw(false);
|
|
34
|
+
let failed = $state.raw(false);
|
|
35
35
|
let copy_timeout: NodeJS.Timeout | undefined;
|
|
36
36
|
|
|
37
37
|
const copy = async (e: MouseEvent) => {
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
type="button"
|
|
63
63
|
title="copy to clipboard"
|
|
64
64
|
{...rest}
|
|
65
|
-
class="
|
|
65
|
+
class="copy-to-clipboard {rest.class}"
|
|
66
66
|
class:icon_button={children ? false : icon_button}
|
|
67
67
|
class:copied
|
|
68
68
|
class:failed
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
<!-- eslint-disable svelte/no-navigation-without-resolve -->
|
|
35
35
|
<a
|
|
36
36
|
{...rest}
|
|
37
|
-
class="
|
|
37
|
+
class="declaration-link {class_prop}"
|
|
38
38
|
href={declaration.url_api + (hash ? ensure_start(hash, '#') : '')}
|
|
39
39
|
{@attach contextmenu_attachment(contextmenu_entries)}
|
|
40
40
|
>
|
package/dist/Dialog.svelte
CHANGED
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
const ROOT_SELECTOR = 'body'; // TODO make configurable
|
|
59
59
|
const CONTAINER_ID = 'fuz_dialog';
|
|
60
60
|
|
|
61
|
-
let container_el: HTMLElement | undefined = $state();
|
|
61
|
+
let container_el: HTMLElement | undefined = $state.raw();
|
|
62
62
|
$effect(() => {
|
|
63
63
|
update_container_el(container);
|
|
64
64
|
});
|
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
-
let dialog_el: HTMLElement | undefined = $state();
|
|
87
|
-
let content_el: HTMLElement | undefined = $state();
|
|
86
|
+
let dialog_el: HTMLElement | undefined = $state.raw();
|
|
87
|
+
let content_el: HTMLElement | undefined = $state.raw();
|
|
88
88
|
|
|
89
89
|
const close = (e?: Event) => {
|
|
90
90
|
if (e) swallow(e);
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
|
|
107
107
|
// The dialog isn't "ready" until the teleport moves it.
|
|
108
108
|
// Rendering the the dialog's children only once it's ready fixes things like `autofocus`.
|
|
109
|
-
let ready = $state(false);
|
|
109
|
+
let ready = $state.raw(false);
|
|
110
110
|
</script>
|
|
111
111
|
|
|
112
112
|
<svelte:window onkeydown={active ? on_window_keydown : undefined} />
|
|
@@ -129,16 +129,16 @@
|
|
|
129
129
|
<div
|
|
130
130
|
class="dialog"
|
|
131
131
|
class:ready
|
|
132
|
-
class:
|
|
132
|
+
class:layout-page={layout === 'page'}
|
|
133
133
|
role="dialog"
|
|
134
134
|
aria-modal="true"
|
|
135
135
|
bind:this={dialog_el}
|
|
136
136
|
tabindex="-1"
|
|
137
137
|
style:z-index={100 + index}
|
|
138
138
|
>
|
|
139
|
-
<div class="
|
|
139
|
+
<div class="dialog-layout">
|
|
140
140
|
<div
|
|
141
|
-
class="
|
|
141
|
+
class="dialog-wrapper"
|
|
142
142
|
role="none"
|
|
143
143
|
onmousedown={(e) => {
|
|
144
144
|
// Close if clicking outside `content_el` but inside the wrapper
|
|
@@ -153,8 +153,8 @@
|
|
|
153
153
|
}
|
|
154
154
|
}}
|
|
155
155
|
>
|
|
156
|
-
<div class="
|
|
157
|
-
<div class="
|
|
156
|
+
<div class="dialog-bg" aria-hidden="true"></div>
|
|
157
|
+
<div class="dialog-content" bind:this={content_el}>
|
|
158
158
|
<!-- mount the content only after teleporting to avoid issues -->
|
|
159
159
|
{#if ready}{@render children(close)}{/if}
|
|
160
160
|
</div>
|
|
@@ -180,18 +180,18 @@
|
|
|
180
180
|
overscroll-behavior: contain;
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
.
|
|
183
|
+
.dialog-wrapper {
|
|
184
184
|
position: relative; /* for the surface */
|
|
185
185
|
min-height: 100%;
|
|
186
186
|
display: flex;
|
|
187
187
|
align-items: center;
|
|
188
188
|
justify-content: center;
|
|
189
189
|
}
|
|
190
|
-
.
|
|
190
|
+
.layout-page .dialog-wrapper {
|
|
191
191
|
align-items: start;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
.
|
|
194
|
+
.dialog-bg {
|
|
195
195
|
position: absolute;
|
|
196
196
|
inset: 0;
|
|
197
197
|
z-index: 0;
|
|
@@ -199,23 +199,23 @@
|
|
|
199
199
|
transition: opacity var(--duration_3) ease;
|
|
200
200
|
background-color: var(--dialog_bg, var(--darken_60));
|
|
201
201
|
}
|
|
202
|
-
.ready .
|
|
202
|
+
.ready .dialog-bg {
|
|
203
203
|
opacity: 1;
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
.
|
|
206
|
+
.dialog-layout {
|
|
207
207
|
height: 100%;
|
|
208
208
|
/* makes the content overflow downwards instead of upwards+downwards because it's centered */
|
|
209
209
|
max-height: 100%;
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
.
|
|
212
|
+
.dialog-content {
|
|
213
213
|
width: 100%;
|
|
214
214
|
transform: scale(0.99);
|
|
215
215
|
transition: transform var(--duration_1) ease;
|
|
216
216
|
padding: 40px;
|
|
217
217
|
}
|
|
218
|
-
.ready .
|
|
218
|
+
.ready .dialog-content {
|
|
219
219
|
transform: scale(1);
|
|
220
220
|
}
|
|
221
221
|
</style>
|
package/dist/Docs.svelte
CHANGED
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
} = $props();
|
|
28
28
|
|
|
29
29
|
// TODO this API is messy, inconsistent usage of props/context
|
|
30
|
-
const
|
|
31
|
-
tomes_context.set(() =>
|
|
30
|
+
const tomes_by_slug = $derived(new Map(tomes.map((t) => [t.slug, t])));
|
|
31
|
+
tomes_context.set(() => tomes_by_slug);
|
|
32
32
|
|
|
33
33
|
// TODO @many dialog navs - this is messy to satisfy SSR with the current design that puts the secondary nav in a dialog
|
|
34
34
|
const TERTIARY_NAV_BREAKPOINT = 1000;
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
const docs_menu_width = '180px';
|
|
38
38
|
|
|
39
|
-
let show_secondary_nav_dialog = $state(false);
|
|
39
|
+
let show_secondary_nav_dialog = $state.raw(false);
|
|
40
40
|
const toggle_secondary_nav_dialog = (show?: boolean): void => {
|
|
41
41
|
show_secondary_nav_dialog = show ?? !show_secondary_nav_dialog;
|
|
42
42
|
};
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
|
|
53
53
|
<div class="docs" style:--docs_menu_width={docs_menu_width}>
|
|
54
54
|
<DocsPrimaryNav {library} {breadcrumb_children}>
|
|
55
|
-
<div class="
|
|
55
|
+
<div class="nav-dialog-toggle">
|
|
56
56
|
<button class="plain" type="button" onclick={() => toggle_secondary_nav_dialog()}>menu</button
|
|
57
57
|
>
|
|
58
58
|
</div>
|
|
59
59
|
</DocsPrimaryNav>
|
|
60
60
|
<!-- TODO @many dialog navs -->
|
|
61
61
|
{#if !innerWidth.current || innerWidth.current > SECONDARY_NAV_BREAKPOINT}
|
|
62
|
-
<div class="
|
|
62
|
+
<div class="secondary-nav-wrapper">
|
|
63
63
|
<DocsSecondaryNav {tomes} />
|
|
64
64
|
</div>
|
|
65
65
|
{/if}
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
{/key}
|
|
70
70
|
<!-- TODO @many dialog navs -->
|
|
71
71
|
{#if !innerWidth.current || innerWidth.current > TERTIARY_NAV_BREAKPOINT}
|
|
72
|
-
<DocsTertiaryNav {tomes} {
|
|
72
|
+
<DocsTertiaryNav {tomes} {tomes_by_slug} />
|
|
73
73
|
{/if}
|
|
74
74
|
<section class="box">
|
|
75
75
|
<DocsFooter {library} root_url="https://www.fuz.dev/">
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
</div>
|
|
103
103
|
<div class="px_lg pb_xl">
|
|
104
104
|
<DocsSecondaryNav {tomes} sidebar={false} />
|
|
105
|
-
<DocsTertiaryNav {tomes} {
|
|
105
|
+
<DocsTertiaryNav {tomes} {tomes_by_slug} sidebar={false} />
|
|
106
106
|
</div>
|
|
107
107
|
</div>
|
|
108
108
|
</Dialog>
|
|
@@ -133,14 +133,14 @@
|
|
|
133
133
|
overflow: hidden; /* TODO maybe heavy handed */
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
.
|
|
136
|
+
.secondary-nav-wrapper {
|
|
137
137
|
display: contents;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
.
|
|
140
|
+
.nav-dialog-toggle {
|
|
141
141
|
display: none;
|
|
142
142
|
}
|
|
143
|
-
.
|
|
143
|
+
.nav-dialog-toggle button {
|
|
144
144
|
padding-left: var(--space_xl3);
|
|
145
145
|
padding-right: var(--space_xl3);
|
|
146
146
|
border-radius: 0;
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
margin-right: 0;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
.
|
|
158
|
+
.nav-dialog-toggle {
|
|
159
159
|
display: contents;
|
|
160
160
|
}
|
|
161
161
|
}
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
margin-left: 0;
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
.
|
|
171
|
+
.secondary-nav-wrapper {
|
|
172
172
|
display: none;
|
|
173
173
|
}
|
|
174
174
|
}
|
package/dist/DocsFooter.svelte
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
{@render logo_footer?.()}
|
|
39
39
|
</div>
|
|
40
40
|
{#if root_url}
|
|
41
|
-
<div class="
|
|
41
|
+
<div class="root-url">
|
|
42
42
|
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
|
|
43
43
|
<a href={root_url}>{format_url(root_url)}</a>
|
|
44
44
|
</div>
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
.logo a:hover {
|
|
59
59
|
--border_color: var(--color_a_50);
|
|
60
60
|
}
|
|
61
|
-
.
|
|
61
|
+
.root-url {
|
|
62
62
|
/* TODO messy */
|
|
63
63
|
margin-top: var(--space_md);
|
|
64
64
|
}
|
package/dist/DocsList.svelte
CHANGED
|
@@ -14,31 +14,31 @@
|
|
|
14
14
|
} = $props();
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
|
-
<div {...rest} class="
|
|
17
|
+
<div {...rest} class="docs-list {rest.class}" class:expand-width={expand_width} class:margin>
|
|
18
18
|
{@render children()}
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
<style>
|
|
22
|
-
.
|
|
22
|
+
.docs-list {
|
|
23
23
|
width: var(--docs_menu_width);
|
|
24
24
|
min-width: var(--docs_menu_width);
|
|
25
25
|
}
|
|
26
|
-
.
|
|
26
|
+
.docs-list.expand-width {
|
|
27
27
|
width: 100%;
|
|
28
28
|
max-width: var(--distance_md);
|
|
29
29
|
}
|
|
30
|
-
.
|
|
30
|
+
.docs-list.margin {
|
|
31
31
|
margin: var(--space_xl6) 0;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/* TODO should be fixed upstream in fuz_css */
|
|
35
|
-
.
|
|
35
|
+
.docs-list :global(a.highlighted) {
|
|
36
36
|
background-color: var(--fg_10);
|
|
37
37
|
}
|
|
38
|
-
.
|
|
38
|
+
.docs-list :global(a:hover) {
|
|
39
39
|
background-color: var(--fg_10);
|
|
40
40
|
}
|
|
41
|
-
.
|
|
41
|
+
.docs-list :global(a:is(:active, .selected)) {
|
|
42
42
|
background-color: var(--fg_20);
|
|
43
43
|
}
|
|
44
44
|
</style>
|
package/dist/DocsMenu.svelte
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type {SvelteHTMLElements} from 'svelte/elements';
|
|
6
6
|
|
|
7
7
|
import DocsList from './DocsList.svelte';
|
|
8
|
-
import {
|
|
8
|
+
import {tome_to_pathname, tome_to_title, type Tome} from './tome.js';
|
|
9
9
|
import DocsMenuHeader from './DocsMenuHeader.svelte';
|
|
10
10
|
|
|
11
11
|
const {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
<!-- eslint-disable svelte/no-navigation-without-resolve -->
|
|
31
31
|
|
|
32
|
-
<DocsList {...rest} {expand_width} margin={false} class="
|
|
32
|
+
<DocsList {...rest} {expand_width} margin={false} class="docs-menu">
|
|
33
33
|
<ul class="unstyled">
|
|
34
34
|
{#each Object.entries(tomes_by_category) as [category, tomes] (category)}
|
|
35
35
|
<li class="category">
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
>{/if}
|
|
38
38
|
<ul class="unstyled">
|
|
39
39
|
{#each tomes as item (item)}
|
|
40
|
-
{@const pathname =
|
|
40
|
+
{@const pathname = tome_to_pathname(item)}
|
|
41
41
|
<li role="none" transition:slide>
|
|
42
42
|
<a class="menuitem" href={pathname} class:selected={pathname === page.url.pathname}
|
|
43
|
-
><div class="ellipsis">{item
|
|
43
|
+
><div class="ellipsis">{tome_to_title(item)}</div></a
|
|
44
44
|
>
|
|
45
45
|
</li>
|
|
46
46
|
{/each}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocsMenu.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/DocsMenu.svelte"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AAGxD,OAAO,
|
|
1
|
+
{"version":3,"file":"DocsMenu.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/DocsMenu.svelte"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,iBAAiB,CAAC;AAGxD,OAAO,EAAkC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AAGpE,KAAK,gBAAgB,GAAI,kBAAkB,CAAC,KAAK,CAAC,GAAG;IACpD,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAkDH,QAAA,MAAM,QAAQ,sDAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
const hash = $derived(page.url.hash.slice(1));
|
|
21
21
|
</script>
|
|
22
22
|
|
|
23
|
-
<DocsList {...rest} {expand_width} class="
|
|
23
|
+
<DocsList {...rest} {expand_width} class="docs-page-links">
|
|
24
24
|
<h4 class="mb_sm">on this page</h4>
|
|
25
25
|
{#if sidebar}
|
|
26
|
-
<div class="
|
|
26
|
+
<div class="sidebar-wrapper">{@render content()}</div>
|
|
27
27
|
{:else}
|
|
28
28
|
{@render content()}
|
|
29
29
|
{/if}
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
{/snippet}
|
|
55
55
|
|
|
56
56
|
<style>
|
|
57
|
-
/* this is needed because `.
|
|
58
|
-
.
|
|
57
|
+
/* this is needed because `.docs-page-links` needs to be a block to collapse the vertical margin */
|
|
58
|
+
.sidebar-wrapper {
|
|
59
59
|
display: flex;
|
|
60
60
|
flex-direction: column;
|
|
61
61
|
align-items: flex-start;
|