@happyvertical/smrt-svelte 0.38.13 → 0.38.15
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/components/workspace/__tests__/AdminShell.test.js +90 -0
- package/dist/components/workspace/__tests__/TenantNav.test.js +93 -0
- package/dist/components/workspace/admin-shell/AdminShell.svelte +43 -7
- package/dist/components/workspace/admin-shell/AdminShell.svelte.d.ts.map +1 -1
- package/dist/components/workspace/admin-shell/TenantNav.svelte +94 -8
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts +7 -1
- package/dist/components/workspace/admin-shell/TenantNav.svelte.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createRawSnippet, flushSync, mount, tick, unmount } from 'svelte';
|
|
2
2
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
3
3
|
import AdminShell from '../admin-shell/AdminShell.svelte';
|
|
4
|
+
import { createShellState } from '../admin-shell/state.svelte.js';
|
|
4
5
|
function textSnippet(text) {
|
|
5
6
|
return createRawSnippet(() => ({
|
|
6
7
|
render: () => `<span>${text}</span>`,
|
|
@@ -52,4 +53,93 @@ describe('AdminShell', () => {
|
|
|
52
53
|
unmount(component);
|
|
53
54
|
}
|
|
54
55
|
});
|
|
56
|
+
it('keeps the focus rail visible when the right panel is expanded', () => {
|
|
57
|
+
const state = createShellState({
|
|
58
|
+
config: {
|
|
59
|
+
right: {
|
|
60
|
+
initial: 'expanded',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
const component = mount(AdminShell, {
|
|
65
|
+
target: container,
|
|
66
|
+
props: {
|
|
67
|
+
state,
|
|
68
|
+
children: textSnippet('main work'),
|
|
69
|
+
focusRail: textSnippet('focus rail'),
|
|
70
|
+
focusPanel: textSnippet('focus panel'),
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
try {
|
|
74
|
+
const right = container.querySelector('.smrt-admin-shell__edge--right');
|
|
75
|
+
const rail = right?.querySelector('.smrt-admin-shell__rail');
|
|
76
|
+
const panel = right?.querySelector('.smrt-admin-shell__panel--right');
|
|
77
|
+
expect(right?.getAttribute('data-state')).toBe('expanded');
|
|
78
|
+
expect(rail?.textContent).toContain('focus rail');
|
|
79
|
+
expect(panel?.textContent).toContain('focus panel');
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
unmount(component);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
it('publishes collapsed side sizes for stable top and bottom chrome', () => {
|
|
86
|
+
const state = createShellState({
|
|
87
|
+
config: {
|
|
88
|
+
left: {
|
|
89
|
+
collapsedSize: '5rem',
|
|
90
|
+
expandedSize: '20rem',
|
|
91
|
+
initial: 'expanded',
|
|
92
|
+
},
|
|
93
|
+
right: {
|
|
94
|
+
collapsedSize: '6rem',
|
|
95
|
+
expandedSize: '24rem',
|
|
96
|
+
initial: 'expanded',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
const component = mount(AdminShell, {
|
|
101
|
+
target: container,
|
|
102
|
+
props: {
|
|
103
|
+
state,
|
|
104
|
+
children: textSnippet('main work'),
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
try {
|
|
108
|
+
const shell = container.querySelector('.smrt-admin-shell');
|
|
109
|
+
const style = shell?.getAttribute('style');
|
|
110
|
+
expect(style).toContain('--smrt-admin-shell-left-track: 20rem');
|
|
111
|
+
expect(style).toContain('--smrt-admin-shell-right-track: 24rem');
|
|
112
|
+
expect(style).toContain('--smrt-admin-shell-left-collapsed: 5rem');
|
|
113
|
+
expect(style).toContain('--smrt-admin-shell-right-collapsed: 6rem');
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
unmount(component);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
it('does not reserve chrome corner space for hidden side edges', () => {
|
|
120
|
+
const state = createShellState({
|
|
121
|
+
config: {
|
|
122
|
+
left: false,
|
|
123
|
+
right: false,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
const component = mount(AdminShell, {
|
|
127
|
+
target: container,
|
|
128
|
+
props: {
|
|
129
|
+
state,
|
|
130
|
+
children: textSnippet('main work'),
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
try {
|
|
134
|
+
const shell = container.querySelector('.smrt-admin-shell');
|
|
135
|
+
const style = shell?.getAttribute('style');
|
|
136
|
+
expect(style).toContain('--smrt-admin-shell-left-track: 0rem');
|
|
137
|
+
expect(style).toContain('--smrt-admin-shell-right-track: 0rem');
|
|
138
|
+
expect(style).toContain('--smrt-admin-shell-left-collapsed: 0rem');
|
|
139
|
+
expect(style).toContain('--smrt-admin-shell-right-collapsed: 0rem');
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
unmount(component);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
55
145
|
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { mount, unmount } from 'svelte';
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
3
|
+
import TenantNav from '../admin-shell/TenantNav.svelte';
|
|
4
|
+
import TestIcon from './test-icon.svelte';
|
|
5
|
+
let container;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
container = document.createElement('div');
|
|
8
|
+
document.body.appendChild(container);
|
|
9
|
+
});
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
container.remove();
|
|
12
|
+
});
|
|
13
|
+
describe('TenantNav', () => {
|
|
14
|
+
it('renders custom icon components for nav items', () => {
|
|
15
|
+
const component = mount(TenantNav, {
|
|
16
|
+
target: container,
|
|
17
|
+
props: {
|
|
18
|
+
currentHref: '/admin/tasks',
|
|
19
|
+
iconComponent: TestIcon,
|
|
20
|
+
items: [
|
|
21
|
+
{ href: '/admin/tasks', icon: 'tasks', label: 'Tasks' },
|
|
22
|
+
{
|
|
23
|
+
href: '/admin/opportunities',
|
|
24
|
+
icon: 'briefcase',
|
|
25
|
+
label: 'Opportunities',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
try {
|
|
31
|
+
expect(container.querySelectorAll('[data-testid="custom-icon"]')).toHaveLength(2);
|
|
32
|
+
expect(container.querySelector('a[aria-current="page"]')?.textContent).toContain('Tasks');
|
|
33
|
+
}
|
|
34
|
+
finally {
|
|
35
|
+
unmount(component);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
it('uses top-level icon links when collapsed', () => {
|
|
39
|
+
const component = mount(TenantNav, {
|
|
40
|
+
target: container,
|
|
41
|
+
props: {
|
|
42
|
+
collapsed: true,
|
|
43
|
+
currentHref: '/admin/experience',
|
|
44
|
+
iconComponent: TestIcon,
|
|
45
|
+
items: [
|
|
46
|
+
{
|
|
47
|
+
href: '/admin/resume',
|
|
48
|
+
icon: 'file-text',
|
|
49
|
+
label: 'Career',
|
|
50
|
+
children: [
|
|
51
|
+
{
|
|
52
|
+
href: '/admin/experience',
|
|
53
|
+
icon: 'briefcase',
|
|
54
|
+
label: 'Experience',
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
try {
|
|
62
|
+
expect(container.querySelector('.smrt-tenant-nav--collapsed')).not.toBeNull();
|
|
63
|
+
expect(container.querySelectorAll('[data-testid="custom-icon"]')).toHaveLength(1);
|
|
64
|
+
expect(container.querySelector('a[href="/admin/experience"]')).toBeNull();
|
|
65
|
+
const parentLink = container.querySelector('a[href="/admin/resume"]');
|
|
66
|
+
expect(parentLink).not.toHaveAttribute('aria-current');
|
|
67
|
+
expect(parentLink).toHaveClass('smrt-tenant-nav__link--visible-active');
|
|
68
|
+
expect(container.querySelector('a[href="/admin/resume"]')).toHaveAttribute('title', 'Career');
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
unmount(component);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
it('renders a visible fallback glyph for iconless collapsed items', () => {
|
|
75
|
+
const component = mount(TenantNav, {
|
|
76
|
+
target: container,
|
|
77
|
+
props: {
|
|
78
|
+
collapsed: true,
|
|
79
|
+
currentHref: '/admin/memory',
|
|
80
|
+
items: [{ href: '/admin/memory', label: 'Memory' }],
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
try {
|
|
84
|
+
const link = container.querySelector('a[href="/admin/memory"]');
|
|
85
|
+
const fallback = link?.querySelector('.smrt-tenant-nav__icon--fallback');
|
|
86
|
+
expect(fallback?.textContent?.trim()).toBe('M');
|
|
87
|
+
expect(link).toHaveAttribute('aria-current', 'page');
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
unmount(component);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
@@ -15,12 +15,19 @@ function expandedSize(shell: ModuleShellState, edge: ModulePanelEdge): string {
|
|
|
15
15
|
return shell.config.panels[edge].expandedSize;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
function collapsedSize(shell: ModuleShellState, edge: ModulePanelEdge): string {
|
|
19
|
+
if (shell.panels[edge] === 'hidden') return '0rem';
|
|
20
|
+
return shell.config.panels[edge].collapsedSize;
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
function buildLayoutStyle(shell: ModuleShellState): string {
|
|
19
24
|
return [
|
|
20
25
|
`--smrt-admin-shell-left-track: ${trackFor(shell, 'left')}`,
|
|
21
26
|
`--smrt-admin-shell-right-track: ${trackFor(shell, 'right')}`,
|
|
22
27
|
`--smrt-admin-shell-top-track: ${trackFor(shell, 'top')}`,
|
|
23
28
|
`--smrt-admin-shell-bottom-track: ${trackFor(shell, 'bottom')}`,
|
|
29
|
+
`--smrt-admin-shell-left-collapsed: ${collapsedSize(shell, 'left')}`,
|
|
30
|
+
`--smrt-admin-shell-right-collapsed: ${collapsedSize(shell, 'right')}`,
|
|
24
31
|
`--smrt-admin-shell-left-expanded: ${expandedSize(shell, 'left')}`,
|
|
25
32
|
`--smrt-admin-shell-right-expanded: ${expandedSize(shell, 'right')}`,
|
|
26
33
|
`--smrt-admin-shell-top-expanded: ${expandedSize(shell, 'top')}`,
|
|
@@ -334,14 +341,17 @@ function buildLayoutStyle(shell: ModuleShellState): string {
|
|
|
334
341
|
aria-label={labelFor('right')}
|
|
335
342
|
>
|
|
336
343
|
<div class="smrt-admin-shell__rail">
|
|
337
|
-
{#if
|
|
338
|
-
{@render focusContent(activeFocusTool)}
|
|
339
|
-
{:else if focusRail}
|
|
344
|
+
{#if focusRail}
|
|
340
345
|
{@render focusRail()}
|
|
341
346
|
{:else}
|
|
342
347
|
{@render edgeToggle('right')}
|
|
343
348
|
{/if}
|
|
344
349
|
</div>
|
|
350
|
+
{#if edgeExpanded('right')}
|
|
351
|
+
<div class="smrt-admin-shell__panel smrt-admin-shell__panel--right">
|
|
352
|
+
{@render focusContent(activeFocusTool)}
|
|
353
|
+
</div>
|
|
354
|
+
{/if}
|
|
345
355
|
</aside>
|
|
346
356
|
{/if}
|
|
347
357
|
|
|
@@ -465,8 +475,8 @@ function buildLayoutStyle(shell: ModuleShellState): string {
|
|
|
465
475
|
grid-row: 1;
|
|
466
476
|
display: grid;
|
|
467
477
|
grid-template-columns:
|
|
468
|
-
var(--smrt-admin-shell-left-
|
|
469
|
-
var(--smrt-admin-shell-right-
|
|
478
|
+
var(--smrt-admin-shell-left-collapsed) minmax(0, 1fr)
|
|
479
|
+
var(--smrt-admin-shell-right-collapsed);
|
|
470
480
|
border-block-end: 1px solid var(--smrt-color-outline-variant);
|
|
471
481
|
z-index: 30;
|
|
472
482
|
}
|
|
@@ -485,13 +495,20 @@ function buildLayoutStyle(shell: ModuleShellState): string {
|
|
|
485
495
|
z-index: 20;
|
|
486
496
|
}
|
|
487
497
|
|
|
498
|
+
.smrt-admin-shell__edge--right[data-state='expanded'] {
|
|
499
|
+
display: grid;
|
|
500
|
+
grid-template-columns:
|
|
501
|
+
minmax(0, 1fr)
|
|
502
|
+
min(var(--smrt-admin-shell-right-collapsed), 100%);
|
|
503
|
+
}
|
|
504
|
+
|
|
488
505
|
.smrt-admin-shell__edge--bottom {
|
|
489
506
|
grid-column: 1 / -1;
|
|
490
507
|
grid-row: 3;
|
|
491
508
|
display: grid;
|
|
492
509
|
grid-template-columns:
|
|
493
|
-
var(--smrt-admin-shell-left-
|
|
494
|
-
var(--smrt-admin-shell-right-
|
|
510
|
+
var(--smrt-admin-shell-left-collapsed) minmax(0, 1fr)
|
|
511
|
+
var(--smrt-admin-shell-right-collapsed);
|
|
495
512
|
border-block-start: 1px solid var(--smrt-color-outline-variant);
|
|
496
513
|
z-index: 30;
|
|
497
514
|
}
|
|
@@ -544,6 +561,25 @@ function buildLayoutStyle(shell: ModuleShellState): string {
|
|
|
544
561
|
padding: var(--smrt-spacing-3);
|
|
545
562
|
}
|
|
546
563
|
|
|
564
|
+
.smrt-admin-shell__edge--right[data-state='expanded']
|
|
565
|
+
.smrt-admin-shell__rail {
|
|
566
|
+
grid-column: 2;
|
|
567
|
+
border-inline-start: 1px solid var(--smrt-color-outline-variant);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
.smrt-admin-shell__panel {
|
|
571
|
+
min-width: 0;
|
|
572
|
+
min-height: 0;
|
|
573
|
+
block-size: 100%;
|
|
574
|
+
overflow: auto;
|
|
575
|
+
padding: var(--smrt-spacing-3);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
.smrt-admin-shell__panel--right {
|
|
579
|
+
grid-column: 1;
|
|
580
|
+
grid-row: 1;
|
|
581
|
+
}
|
|
582
|
+
|
|
547
583
|
.smrt-admin-shell__edge-toggle-kbd {
|
|
548
584
|
padding: 0 var(--smrt-spacing-1);
|
|
549
585
|
border-radius: var(--smrt-radius-small);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AdminShell.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/admin-shell/AdminShell.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AdminShell.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/admin-shell/AdminShell.svelte.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAStC,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EACR,eAAe,EAGhB,MAAM,YAAY,CAAC;AAGpB,UAAU,KAAM,SAAQ,eAAe;IACrC,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;CACnB;AA0UH,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -1,42 +1,80 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { useI18n } from '@happyvertical/smrt-ui/i18n';
|
|
3
|
+
import type { Component } from 'svelte';
|
|
3
4
|
import { M } from '../../../i18n/strings.workspace.js';
|
|
4
5
|
import type { ShellNavItem } from './types.js';
|
|
5
6
|
|
|
6
7
|
interface Props {
|
|
7
8
|
items: ShellNavItem[];
|
|
8
9
|
currentHref?: string;
|
|
10
|
+
iconComponent?: Component<{ name: string; size?: number }>;
|
|
11
|
+
collapsed?: boolean;
|
|
9
12
|
onNavigate?: () => void;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
|
-
let {
|
|
15
|
+
let {
|
|
16
|
+
items,
|
|
17
|
+
currentHref = '',
|
|
18
|
+
iconComponent: IconComponent,
|
|
19
|
+
collapsed = false,
|
|
20
|
+
onNavigate,
|
|
21
|
+
}: Props = $props();
|
|
13
22
|
const { t } = useI18n();
|
|
14
23
|
|
|
15
24
|
function isActive(item: ShellNavItem): boolean {
|
|
16
25
|
return item.href === currentHref || currentHref.startsWith(`${item.href}/`);
|
|
17
26
|
}
|
|
27
|
+
|
|
28
|
+
function isVisibleActive(item: ShellNavItem): boolean {
|
|
29
|
+
if (isActive(item)) return true;
|
|
30
|
+
return collapsed && !!item.children?.some((child) => isActive(child));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function fallbackIcon(label: string): string {
|
|
34
|
+
return label.trim().charAt(0).toLocaleUpperCase() || '?';
|
|
35
|
+
}
|
|
18
36
|
</script>
|
|
19
37
|
|
|
20
38
|
<nav
|
|
21
39
|
class="smrt-tenant-nav"
|
|
40
|
+
class:smrt-tenant-nav--collapsed={collapsed}
|
|
22
41
|
aria-label={t(M['ui.tenant_nav.tenant_navigation'])}
|
|
23
42
|
>
|
|
24
43
|
{#each items as item (item.href)}
|
|
25
44
|
<div class="smrt-tenant-nav__section">
|
|
26
45
|
<a
|
|
27
46
|
href={item.href}
|
|
47
|
+
class:smrt-tenant-nav__link--visible-active={isVisibleActive(item)}
|
|
28
48
|
aria-current={isActive(item) ? 'page' : undefined}
|
|
49
|
+
title={collapsed ? item.label : item.description}
|
|
29
50
|
onclick={onNavigate}
|
|
30
51
|
>
|
|
31
52
|
{#if item.icon}
|
|
32
|
-
<span aria-hidden="true">
|
|
53
|
+
<span class="smrt-tenant-nav__icon" aria-hidden="true">
|
|
54
|
+
{#if IconComponent}
|
|
55
|
+
<IconComponent name={item.icon} size={18} />
|
|
56
|
+
{:else}
|
|
57
|
+
{item.icon}
|
|
58
|
+
{/if}
|
|
59
|
+
</span>
|
|
60
|
+
{:else if collapsed}
|
|
61
|
+
<span
|
|
62
|
+
class="smrt-tenant-nav__icon smrt-tenant-nav__icon--fallback"
|
|
63
|
+
aria-hidden="true"
|
|
64
|
+
>
|
|
65
|
+
{fallbackIcon(item.label)}
|
|
66
|
+
</span>
|
|
33
67
|
{/if}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
68
|
+
{#if collapsed}
|
|
69
|
+
<span class="smrt-tenant-nav__sr-only">{item.label}</span>
|
|
70
|
+
{:else}
|
|
71
|
+
<strong>{item.label}</strong>
|
|
72
|
+
{#if item.badge !== null && item.badge !== undefined}
|
|
73
|
+
<small>{item.badge}</small>
|
|
74
|
+
{/if}
|
|
37
75
|
{/if}
|
|
38
76
|
</a>
|
|
39
|
-
{#if item.children?.length}
|
|
77
|
+
{#if item.children?.length && !collapsed}
|
|
40
78
|
<div class="smrt-tenant-nav__children">
|
|
41
79
|
{#each item.children as child (child.href)}
|
|
42
80
|
<a
|
|
@@ -45,7 +83,13 @@ function isActive(item: ShellNavItem): boolean {
|
|
|
45
83
|
onclick={onNavigate}
|
|
46
84
|
>
|
|
47
85
|
{#if child.icon}
|
|
48
|
-
<span aria-hidden="true">
|
|
86
|
+
<span class="smrt-tenant-nav__icon" aria-hidden="true">
|
|
87
|
+
{#if IconComponent}
|
|
88
|
+
<IconComponent name={child.icon} size={16} />
|
|
89
|
+
{:else}
|
|
90
|
+
{child.icon}
|
|
91
|
+
{/if}
|
|
92
|
+
</span>
|
|
49
93
|
{/if}
|
|
50
94
|
<span>{child.label}</span>
|
|
51
95
|
{#if child.badge !== null && child.badge !== undefined}
|
|
@@ -79,9 +123,39 @@ function isActive(item: ShellNavItem): boolean {
|
|
|
79
123
|
text-decoration: none;
|
|
80
124
|
}
|
|
81
125
|
|
|
126
|
+
.smrt-tenant-nav--collapsed,
|
|
127
|
+
.smrt-tenant-nav--collapsed .smrt-tenant-nav__section {
|
|
128
|
+
justify-items: center;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.smrt-tenant-nav--collapsed a {
|
|
132
|
+
grid-template-columns: minmax(0, 1fr);
|
|
133
|
+
place-items: center;
|
|
134
|
+
inline-size: 2.25rem;
|
|
135
|
+
block-size: 2.25rem;
|
|
136
|
+
padding: 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
82
139
|
.smrt-tenant-nav a:hover,
|
|
83
|
-
.smrt-tenant-nav a[aria-current='page']
|
|
140
|
+
.smrt-tenant-nav a[aria-current='page'],
|
|
141
|
+
.smrt-tenant-nav a.smrt-tenant-nav__link--visible-active {
|
|
142
|
+
background: var(--smrt-color-surface-container-high);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.smrt-tenant-nav__icon {
|
|
146
|
+
display: inline-grid;
|
|
147
|
+
place-items: center;
|
|
148
|
+
inline-size: 1.25rem;
|
|
149
|
+
block-size: 1.25rem;
|
|
150
|
+
min-inline-size: 1.25rem;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.smrt-tenant-nav__icon--fallback {
|
|
154
|
+
border-radius: var(--smrt-radius-full);
|
|
84
155
|
background: var(--smrt-color-surface-container-high);
|
|
156
|
+
color: var(--smrt-color-on-surface-variant);
|
|
157
|
+
font-size: var(--smrt-typography-label-small-size);
|
|
158
|
+
font-weight: var(--smrt-typography-weight-semibold);
|
|
85
159
|
}
|
|
86
160
|
|
|
87
161
|
.smrt-tenant-nav strong,
|
|
@@ -98,4 +172,16 @@ function isActive(item: ShellNavItem): boolean {
|
|
|
98
172
|
.smrt-tenant-nav__children {
|
|
99
173
|
padding-inline-start: var(--smrt-spacing-4);
|
|
100
174
|
}
|
|
175
|
+
|
|
176
|
+
.smrt-tenant-nav__sr-only {
|
|
177
|
+
position: absolute;
|
|
178
|
+
inline-size: 1px;
|
|
179
|
+
block-size: 1px;
|
|
180
|
+
padding: 0;
|
|
181
|
+
margin: -1px;
|
|
182
|
+
overflow: hidden;
|
|
183
|
+
clip: rect(0, 0, 0, 0);
|
|
184
|
+
white-space: nowrap;
|
|
185
|
+
border: 0;
|
|
186
|
+
}
|
|
101
187
|
</style>
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
import type { Component } from 'svelte';
|
|
1
2
|
import type { ShellNavItem } from './types.js';
|
|
2
3
|
interface Props {
|
|
3
4
|
items: ShellNavItem[];
|
|
4
5
|
currentHref?: string;
|
|
6
|
+
iconComponent?: Component<{
|
|
7
|
+
name: string;
|
|
8
|
+
size?: number;
|
|
9
|
+
}>;
|
|
10
|
+
collapsed?: boolean;
|
|
5
11
|
onNavigate?: () => void;
|
|
6
12
|
}
|
|
7
|
-
declare const TenantNav:
|
|
13
|
+
declare const TenantNav: Component<Props, {}, "">;
|
|
8
14
|
type TenantNav = ReturnType<typeof TenantNav>;
|
|
9
15
|
export default TenantNav;
|
|
10
16
|
//# sourceMappingURL=TenantNav.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TenantNav.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/admin-shell/TenantNav.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TenantNav.svelte.d.ts","sourceRoot":"","sources":["../../../../src/components/workspace/admin-shell/TenantNav.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,UAAU,KAAK;IACb,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,SAAS,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAsFD,QAAA,MAAM,SAAS,0BAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyvertical/smrt-svelte",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.15",
|
|
4
4
|
"description": "Svelte 5 components for SMRT user management - auth, users, tenants, roles, permissions, groups",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"smrtRawPrimitives": "strict",
|
|
@@ -92,10 +92,10 @@
|
|
|
92
92
|
"@tanstack/db": "^0.6.14",
|
|
93
93
|
"@tanstack/svelte-db": "^0.1.91",
|
|
94
94
|
"esm-env": "^1.2.2",
|
|
95
|
-
"@happyvertical/smrt-languages": "0.38.
|
|
96
|
-
"@happyvertical/smrt-types": "0.38.
|
|
97
|
-
"@happyvertical/smrt-ui": "0.38.
|
|
98
|
-
"@happyvertical/smrt-web": "0.38.
|
|
95
|
+
"@happyvertical/smrt-languages": "0.38.15",
|
|
96
|
+
"@happyvertical/smrt-types": "0.38.15",
|
|
97
|
+
"@happyvertical/smrt-ui": "0.38.15",
|
|
98
|
+
"@happyvertical/smrt-web": "0.38.15"
|
|
99
99
|
},
|
|
100
100
|
"peerDependencies": {
|
|
101
101
|
"@huggingface/transformers": ">=3.8.1",
|