@classic-homes/theme-svelte 1.33.0 → 1.34.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.
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import type { Snippet } from 'svelte';
|
|
14
14
|
import type { NavItem } from '../../../types/layout.js';
|
|
15
15
|
import { cn } from '../../../utils.js';
|
|
16
|
+
import { truncateTitle } from '../../../utils/truncate-title.js';
|
|
16
17
|
import { sidebarStore } from '../../../stores/sidebar.svelte.js';
|
|
17
18
|
import Icon, { type IconName } from '../../Icon.svelte';
|
|
18
19
|
import SidebarNavItem from './SidebarNavItem.svelte';
|
|
@@ -195,13 +196,13 @@
|
|
|
195
196
|
highlight: { before: string; match: string; after: string } | null
|
|
196
197
|
)}
|
|
197
198
|
{#if highlight}
|
|
198
|
-
<span class="flex-1 min-w-0 truncate">
|
|
199
|
+
<span class="flex-1 min-w-0 truncate" use:truncateTitle={name}>
|
|
199
200
|
{highlight.before}<mark class="bg-yellow-200 dark:bg-yellow-900 text-inherit rounded px-0.5"
|
|
200
201
|
>{highlight.match}</mark
|
|
201
202
|
>{highlight.after}
|
|
202
203
|
</span>
|
|
203
204
|
{:else}
|
|
204
|
-
<span class="flex-1 min-w-0 truncate">{name}</span>
|
|
205
|
+
<span class="flex-1 min-w-0 truncate" use:truncateTitle={name}>{name}</span>
|
|
205
206
|
{/if}
|
|
206
207
|
{/snippet}
|
|
207
208
|
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { Snippet } from 'svelte';
|
|
10
10
|
import type { NavSection, NavItem } from '../../../types/layout.js';
|
|
11
11
|
import { cn } from '../../../utils.js';
|
|
12
|
+
import { truncateTitle } from '../../../utils/truncate-title.js';
|
|
12
13
|
import { sidebarStore } from '../../../stores/sidebar.svelte.js';
|
|
13
14
|
import SidebarNavItem from './SidebarNavItem.svelte';
|
|
14
15
|
|
|
@@ -93,7 +94,7 @@
|
|
|
93
94
|
aria-expanded={isExpanded}
|
|
94
95
|
aria-controls={`sidebar-section-${section.id}`}
|
|
95
96
|
>
|
|
96
|
-
<span class="truncate">{section.title}</span>
|
|
97
|
+
<span class="truncate" use:truncateTitle={section.title}>{section.title}</span>
|
|
97
98
|
<svg
|
|
98
99
|
class={cn(
|
|
99
100
|
'h-4 w-4 shrink-0',
|
|
@@ -119,6 +120,7 @@
|
|
|
119
120
|
'mb-2 px-4 text-xs font-semibold uppercase tracking-wider overflow-hidden truncate',
|
|
120
121
|
isLight ? 'text-muted-foreground' : 'text-sidebar-foreground/60'
|
|
121
122
|
)}
|
|
123
|
+
use:truncateTitle={section.title}
|
|
122
124
|
>
|
|
123
125
|
{section.title}
|
|
124
126
|
</h2>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full-text tooltip for `truncate`d labels.
|
|
3
|
+
*/
|
|
4
|
+
import type { Action } from 'svelte/action';
|
|
5
|
+
/**
|
|
6
|
+
* Sets the element's native `title` to `text` while its content is cut off
|
|
7
|
+
* by an ellipsis, and removes it when the text fits. Measured on hover rather
|
|
8
|
+
* than observed, so it costs nothing until someone points at it and stays
|
|
9
|
+
* right as the container resizes. (The accessible name is the text itself,
|
|
10
|
+
* so screen readers already get the full label.)
|
|
11
|
+
*/
|
|
12
|
+
export declare const truncateTitle: Action<HTMLElement, string>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full-text tooltip for `truncate`d labels.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Sets the element's native `title` to `text` while its content is cut off
|
|
6
|
+
* by an ellipsis, and removes it when the text fits. Measured on hover rather
|
|
7
|
+
* than observed, so it costs nothing until someone points at it and stays
|
|
8
|
+
* right as the container resizes. (The accessible name is the text itself,
|
|
9
|
+
* so screen readers already get the full label.)
|
|
10
|
+
*/
|
|
11
|
+
export const truncateTitle = (node, text) => {
|
|
12
|
+
let current = text;
|
|
13
|
+
function sync() {
|
|
14
|
+
if (node.scrollWidth > node.clientWidth)
|
|
15
|
+
node.title = current;
|
|
16
|
+
else
|
|
17
|
+
node.removeAttribute('title');
|
|
18
|
+
}
|
|
19
|
+
node.addEventListener('pointerenter', sync);
|
|
20
|
+
return {
|
|
21
|
+
update(next) {
|
|
22
|
+
current = next;
|
|
23
|
+
if (node.hasAttribute('title'))
|
|
24
|
+
sync();
|
|
25
|
+
},
|
|
26
|
+
destroy() {
|
|
27
|
+
node.removeEventListener('pointerenter', sync);
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
};
|