@marianmeres/stuic 2.66.0 → 3.0.1
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/README.md +292 -4
- package/dist/README.md +41 -18
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.js +1 -0
- package/dist/actions/popover/README.md +19 -0
- package/dist/actions/popover/index.css +6 -9
- package/dist/actions/popover/popover.svelte.js +2 -2
- package/dist/actions/tooltip/README.md +18 -0
- package/dist/actions/tooltip/index.css +5 -8
- package/dist/actions/tooltip/tooltip.svelte.js +1 -1
- package/dist/actions/typeahead.svelte.d.ts +53 -0
- package/dist/actions/typeahead.svelte.js +328 -0
- package/dist/base.css +17 -0
- package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte +10 -10
- package/dist/components/AlertConfirmPrompt/AlertConfirmPrompt.svelte.d.ts +4 -3
- package/dist/components/AlertConfirmPrompt/Current.svelte +15 -18
- package/dist/components/AlertConfirmPrompt/Current.svelte.d.ts +4 -3
- package/dist/components/AlertConfirmPrompt/acp-icons.js +5 -4
- package/dist/components/AlertConfirmPrompt/index.css +66 -0
- package/dist/components/AssetsPreview/AssetsPreview.svelte +91 -73
- package/dist/components/AssetsPreview/index.css +61 -0
- package/dist/components/Avatar/Avatar.svelte +31 -18
- package/dist/components/Avatar/README.md +166 -0
- package/dist/components/Avatar/index.css +130 -0
- package/dist/components/Backdrop/Backdrop.svelte +7 -2
- package/dist/components/Backdrop/README.md +71 -6
- package/dist/components/Backdrop/index.css +31 -0
- package/dist/components/Button/Button.svelte +116 -124
- package/dist/components/Button/Button.svelte.d.ts +35 -24
- package/dist/components/Button/README.md +87 -21
- package/dist/components/Button/index.css +475 -9
- package/dist/components/Button/index.d.ts +1 -1
- package/dist/components/Button/index.js +1 -1
- package/dist/components/ButtonGroupRadio/ButtonGroupRadio.svelte +7 -39
- package/dist/components/ButtonGroupRadio/ButtonGroupRadio.svelte.d.ts +0 -1
- package/dist/components/ButtonGroupRadio/README.md +82 -4
- package/dist/components/ButtonGroupRadio/index.css +158 -14
- package/dist/components/Collapsible/Collapsible.svelte +7 -7
- package/dist/components/Collapsible/Collapsible.svelte.d.ts +2 -2
- package/dist/components/Collapsible/README.md +34 -2
- package/dist/components/Collapsible/index.css +40 -0
- package/dist/components/CommandMenu/CommandMenu.svelte +18 -26
- package/dist/components/CommandMenu/CommandMenu.svelte.d.ts +0 -1
- package/dist/components/CommandMenu/README.md +39 -0
- package/dist/components/CommandMenu/index.css +47 -2
- package/dist/components/DismissibleMessage/DismissibleMessage.svelte +53 -51
- package/dist/components/DismissibleMessage/DismissibleMessage.svelte.d.ts +6 -6
- package/dist/components/DismissibleMessage/README.md +93 -11
- package/dist/components/DismissibleMessage/index.css +128 -8
- package/dist/components/DismissibleMessage/index.d.ts +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.svelte +14 -51
- package/dist/components/DropdownMenu/DropdownMenu.svelte.d.ts +6 -7
- package/dist/components/DropdownMenu/README.md +132 -0
- package/dist/components/DropdownMenu/index.css +258 -52
- package/dist/components/Input/FieldAssets.svelte +8 -5
- package/dist/components/Input/FieldCheckbox.svelte +7 -44
- package/dist/components/Input/FieldFile.svelte +1 -6
- package/dist/components/Input/FieldInput.svelte +9 -1
- package/dist/components/Input/FieldInput.svelte.d.ts +2 -0
- package/dist/components/Input/FieldOptions.svelte +42 -39
- package/dist/components/Input/FieldRadios.svelte +7 -16
- package/dist/components/Input/FieldSelect.svelte +1 -1
- package/dist/components/Input/FieldSwitch.svelte +1 -5
- package/dist/components/Input/FieldTextarea.svelte +1 -1
- package/dist/components/Input/README.md +194 -0
- package/dist/components/Input/_internal/FieldRadioInternal.svelte +2 -40
- package/dist/components/Input/_internal/InputWrap.svelte +8 -48
- package/dist/components/Input/index.css +524 -116
- package/dist/components/KbdShortcut/KbdShortcut.svelte +4 -12
- package/dist/components/KbdShortcut/README.md +34 -0
- package/dist/components/KbdShortcut/index.css +55 -0
- package/dist/components/ListItemButton/ListItemButton.svelte +37 -74
- package/dist/components/ListItemButton/ListItemButton.svelte.d.ts +1 -10
- package/dist/components/ListItemButton/README.md +100 -45
- package/dist/components/ListItemButton/index.css +173 -52
- package/dist/components/ListItemButton/index.d.ts +1 -1
- package/dist/components/ListItemButton/index.js +1 -1
- package/dist/components/Modal/Modal.svelte +1 -8
- package/dist/components/Modal/README.md +29 -0
- package/dist/components/Modal/index.css +38 -0
- package/dist/components/ModalDialog/ModalDialog.svelte +2 -21
- package/dist/components/ModalDialog/README.md +35 -0
- package/dist/components/ModalDialog/index.css +59 -0
- package/dist/components/Nav/Nav.svelte +732 -0
- package/dist/components/Nav/Nav.svelte.d.ts +110 -0
- package/dist/components/Nav/README.md +334 -0
- package/dist/components/Nav/index.css +318 -0
- package/dist/components/Nav/index.d.ts +1 -0
- package/dist/components/Nav/index.js +1 -0
- package/dist/components/Notifications/Notifications.svelte +44 -129
- package/dist/components/Notifications/Notifications.svelte.d.ts +9 -18
- package/dist/components/Notifications/README.md +186 -70
- package/dist/components/Notifications/index.css +212 -15
- package/dist/components/Notifications/notifications-stack.svelte.d.ts +4 -0
- package/dist/components/Notifications/notifications-stack.svelte.js +8 -0
- package/dist/components/Progress/Progress.svelte +4 -2
- package/dist/components/Progress/Progress.svelte.d.ts +1 -0
- package/dist/components/Progress/README.md +97 -11
- package/dist/components/Progress/_internal/Bar.svelte +4 -15
- package/dist/components/Progress/_internal/Bar.svelte.d.ts +1 -1
- package/dist/components/Progress/_internal/Circle.svelte +30 -2
- package/dist/components/Progress/_internal/Circle.svelte.d.ts +1 -0
- package/dist/components/Progress/index.css +50 -4
- package/dist/components/Skeleton/README.md +152 -0
- package/dist/components/Skeleton/Skeleton.svelte +9 -9
- package/dist/components/Skeleton/Skeleton.svelte.d.ts +0 -1
- package/dist/components/Skeleton/index.css +72 -45
- package/dist/components/Spinner/README.md +149 -37
- package/dist/components/Spinner/Spinner.svelte +14 -38
- package/dist/components/Spinner/Spinner.svelte.d.ts +2 -1
- package/dist/components/Spinner/SpinnerCircle.svelte +6 -34
- package/dist/components/Spinner/SpinnerCircle.svelte.d.ts +1 -0
- package/dist/components/Spinner/SpinnerCircleOscillate.svelte +10 -5
- package/dist/components/Spinner/SpinnerUnicode.svelte +3 -1
- package/dist/components/Spinner/SpinnerUnicode.svelte.d.ts +1 -0
- package/dist/components/Spinner/index.css +104 -0
- package/dist/components/Switch/README.md +45 -14
- package/dist/components/Switch/Switch.svelte +23 -48
- package/dist/components/Switch/Switch.svelte.d.ts +4 -2
- package/dist/components/Switch/index.css +121 -4
- package/dist/components/Switch/index.d.ts +1 -2
- package/dist/components/Switch/index.js +1 -2
- package/dist/components/TabbedMenu/README.md +37 -21
- package/dist/components/TabbedMenu/TabbedMenu.svelte +5 -46
- package/dist/components/TabbedMenu/TabbedMenu.svelte.d.ts +0 -1
- package/dist/components/TabbedMenu/index.css +84 -17
- package/dist/components/ThemePreview/README.md +289 -0
- package/dist/components/ThemePreview/ThemePreview.svelte +394 -0
- package/dist/components/ThemePreview/ThemePreview.svelte.d.ts +35 -0
- package/dist/components/ThemePreview/index.css +509 -0
- package/dist/components/ThemePreview/index.d.ts +1 -0
- package/dist/components/ThemePreview/index.js +1 -0
- package/dist/components/TwCheck/README.md +32 -13
- package/dist/components/TwCheck/TwCheck.svelte +11 -9
- package/dist/components/TwCheck/TwCheck.svelte.d.ts +0 -1
- package/dist/components/TwCheck/index.css +17 -2
- package/dist/components/TypeaheadInput/TypeaheadInput.svelte +20 -188
- package/dist/components/TypeaheadInput/TypeaheadInput.svelte.d.ts +4 -2
- package/dist/components/X/X.svelte +12 -5
- package/dist/components/X/X.svelte.d.ts +1 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/index.css +46 -26
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/themes/blue-orange.css +217 -0
- package/dist/themes/blue-orange.d.ts +6 -0
- package/dist/themes/blue-orange.js +175 -0
- package/dist/themes/cyan-red.css +217 -0
- package/dist/themes/cyan-red.d.ts +6 -0
- package/dist/themes/cyan-red.js +175 -0
- package/dist/themes/cyan-slate.css +217 -0
- package/dist/themes/cyan-slate.d.ts +6 -0
- package/dist/themes/cyan-slate.js +175 -0
- package/dist/themes/emerald-pink.css +217 -0
- package/dist/themes/emerald-pink.d.ts +6 -0
- package/dist/themes/emerald-pink.js +175 -0
- package/dist/themes/fuchsia-emerald.css +217 -0
- package/dist/themes/fuchsia-emerald.d.ts +6 -0
- package/dist/themes/fuchsia-emerald.js +175 -0
- package/dist/themes/gray.css +217 -0
- package/dist/themes/gray.d.ts +6 -0
- package/dist/themes/gray.js +175 -0
- package/dist/themes/indigo-amber.css +217 -0
- package/dist/themes/indigo-amber.d.ts +6 -0
- package/dist/themes/indigo-amber.js +175 -0
- package/dist/themes/neutral.css +217 -0
- package/dist/themes/neutral.d.ts +6 -0
- package/dist/themes/neutral.js +175 -0
- package/dist/themes/pink-emerald.css +217 -0
- package/dist/themes/pink-emerald.d.ts +6 -0
- package/dist/themes/pink-emerald.js +175 -0
- package/dist/themes/purple-yellow.css +217 -0
- package/dist/themes/purple-yellow.d.ts +6 -0
- package/dist/themes/purple-yellow.js +175 -0
- package/dist/themes/rainbow.css +217 -0
- package/dist/themes/rainbow.d.ts +6 -0
- package/dist/themes/rainbow.js +180 -0
- package/dist/themes/red-blue.css +217 -0
- package/dist/themes/red-blue.d.ts +6 -0
- package/dist/themes/red-blue.js +175 -0
- package/dist/themes/red-cyan.css +217 -0
- package/dist/themes/red-cyan.d.ts +6 -0
- package/dist/themes/red-cyan.js +175 -0
- package/dist/themes/rose-teal.css +217 -0
- package/dist/themes/rose-teal.d.ts +6 -0
- package/dist/themes/rose-teal.js +175 -0
- package/dist/themes/sky-amber.css +217 -0
- package/dist/themes/sky-amber.d.ts +6 -0
- package/dist/themes/sky-amber.js +175 -0
- package/dist/themes/slate-cyan.css +217 -0
- package/dist/themes/slate-cyan.d.ts +6 -0
- package/dist/themes/slate-cyan.js +175 -0
- package/dist/themes/tailwind-color-pairs.md +31 -0
- package/dist/themes/teal-rose.css +217 -0
- package/dist/themes/teal-rose.d.ts +6 -0
- package/dist/themes/teal-rose.js +175 -0
- package/dist/themes/violet-lime.css +217 -0
- package/dist/themes/violet-lime.d.ts +6 -0
- package/dist/themes/violet-lime.js +175 -0
- package/dist/utils/design-tokens.d.ts +43 -0
- package/dist/utils/design-tokens.js +127 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/storage-abstraction.js +1 -1
- package/package.json +14 -11
- package/dist/components/Switch/SwitchButton.svelte +0 -135
- package/dist/components/Switch/SwitchButton.svelte.d.ts +0 -21
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
2
|
+
import type { THC } from "../Thc/Thc.svelte";
|
|
3
|
+
import type { MaybeLocalized } from "../../utils/tr.js";
|
|
4
|
+
/**
|
|
5
|
+
* Navigation item within a group.
|
|
6
|
+
*/
|
|
7
|
+
export interface NavItem {
|
|
8
|
+
/** Unique identifier for the item */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Display label (supports localization) */
|
|
11
|
+
label: MaybeLocalized;
|
|
12
|
+
/** Navigation URL (use href OR onClick, not both) */
|
|
13
|
+
href?: string;
|
|
14
|
+
/** Click handler (alternative to href) */
|
|
15
|
+
onClick?: () => void;
|
|
16
|
+
/** Icon content (THC for flexibility: string, html, component) */
|
|
17
|
+
icon?: THC;
|
|
18
|
+
/** Nested children - parent items with children become expand/collapse toggles */
|
|
19
|
+
children?: NavItem[];
|
|
20
|
+
/** Whether this item is disabled */
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
/** Additional CSS classes */
|
|
23
|
+
class?: string;
|
|
24
|
+
/** Arbitrary data to pass through */
|
|
25
|
+
data?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A navigation group containing a title and items.
|
|
29
|
+
* If items is empty, the group acts as a regular nav item (clickable without chevron).
|
|
30
|
+
*/
|
|
31
|
+
export interface NavGroup {
|
|
32
|
+
/** Group title (supports localization) */
|
|
33
|
+
title: MaybeLocalized;
|
|
34
|
+
/** Navigation items in this group (empty = group acts as nav item) */
|
|
35
|
+
items?: NavItem[];
|
|
36
|
+
/** Group icon (optional) */
|
|
37
|
+
icon?: THC;
|
|
38
|
+
/** Whether the group starts collapsed */
|
|
39
|
+
defaultCollapsed?: boolean;
|
|
40
|
+
/** Navigation URL for groups without items */
|
|
41
|
+
href?: string;
|
|
42
|
+
/** Click handler for groups without items */
|
|
43
|
+
onClick?: () => void;
|
|
44
|
+
/** Unique identifier (used for activeId matching when group has no items) */
|
|
45
|
+
id?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface Props extends Omit<HTMLAttributes<HTMLElement>, "children" | "title"> {
|
|
48
|
+
/** The navigation groups to render */
|
|
49
|
+
groups: NavGroup[];
|
|
50
|
+
/** Optional section title rendered above the groups (uppercase, non-interactive) */
|
|
51
|
+
title?: MaybeLocalized;
|
|
52
|
+
/** Current locale for MaybeLocalized resolution */
|
|
53
|
+
locale?: string;
|
|
54
|
+
/** Whether the sidebar is in collapsed mode (icon-only) */
|
|
55
|
+
isCollapsed?: boolean;
|
|
56
|
+
/** Whether the sidebar is expanding (transitioning from collapsed to expanded) */
|
|
57
|
+
isExpanding?: boolean;
|
|
58
|
+
/** Active item ID for highlighting */
|
|
59
|
+
activeId?: string;
|
|
60
|
+
/** Callback when checking if an item is active (alternative to activeId) */
|
|
61
|
+
isActive?: (item: NavItem) => boolean;
|
|
62
|
+
/** Callback when checking if a group (without items) is active */
|
|
63
|
+
isGroupActive?: (group: NavGroup) => boolean;
|
|
64
|
+
/** Callback when an item is selected */
|
|
65
|
+
onSelect?: (item: NavItem) => void;
|
|
66
|
+
/** Callback when a group (without items) is selected */
|
|
67
|
+
onGroupSelect?: (group: NavGroup) => void;
|
|
68
|
+
/** Callback when group expand/collapse state changes */
|
|
69
|
+
onGroupToggle?: (groupIndex: number, isExpanded: boolean) => void;
|
|
70
|
+
/** Touch-friendly sizing mode */
|
|
71
|
+
touchFriendly?: boolean | "auto";
|
|
72
|
+
/** Classes for the wrapper element */
|
|
73
|
+
class?: string;
|
|
74
|
+
/** Classes for the section title */
|
|
75
|
+
classTitle?: string;
|
|
76
|
+
/** Classes for the group title/header */
|
|
77
|
+
classGroupTitle?: string;
|
|
78
|
+
/** Classes for individual items */
|
|
79
|
+
classItem?: string;
|
|
80
|
+
/** Classes for active items */
|
|
81
|
+
classItemActive?: string;
|
|
82
|
+
/** Classes for collapsed mode items */
|
|
83
|
+
classItemCollapsed?: string;
|
|
84
|
+
/** Classes for disabled items */
|
|
85
|
+
classItemDisabled?: string;
|
|
86
|
+
/** Classes for icons */
|
|
87
|
+
classIcon?: string;
|
|
88
|
+
/** Classes for labels */
|
|
89
|
+
classLabel?: string;
|
|
90
|
+
/** Classes for children container */
|
|
91
|
+
classChildren?: string;
|
|
92
|
+
/** Classes for chevron icon */
|
|
93
|
+
classChevron?: string;
|
|
94
|
+
/** Skip all default styling */
|
|
95
|
+
unstyled?: boolean;
|
|
96
|
+
/** Element reference */
|
|
97
|
+
el?: HTMLElement;
|
|
98
|
+
/** Enable localStorage persistence for expand/collapse state (default: true) */
|
|
99
|
+
persistState?: boolean;
|
|
100
|
+
/** Storage key prefix for localStorage (default: 'stuic-nav') */
|
|
101
|
+
storageKeyPrefix?: string;
|
|
102
|
+
}
|
|
103
|
+
export declare const NAV_BASE_CLASSES = "stuic-nav";
|
|
104
|
+
export declare const NAV_SECTION_TITLE_CLASSES = "stuic-nav-section-title";
|
|
105
|
+
export declare const NAV_GROUP_TITLE_CLASSES = "stuic-nav-group-title";
|
|
106
|
+
export declare const NAV_ITEM_CLASSES = "stuic-nav-item";
|
|
107
|
+
export declare const NAV_CHILDREN_CLASSES = "stuic-nav-children";
|
|
108
|
+
declare const Nav: import("svelte").Component<Props, {}, "el">;
|
|
109
|
+
type Nav = ReturnType<typeof Nav>;
|
|
110
|
+
export default Nav;
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
# Nav
|
|
2
|
+
|
|
3
|
+
A navigation component for sidebars with support for groups, nested items, expand/collapse behavior, collapsed icon-only mode, and localStorage persistence.
|
|
4
|
+
|
|
5
|
+
## Props
|
|
6
|
+
|
|
7
|
+
| Prop | Type | Default | Description |
|
|
8
|
+
|------|------|---------|-------------|
|
|
9
|
+
| `groups` | `NavGroup[]` | - | Navigation groups to render |
|
|
10
|
+
| `title` | `MaybeLocalized` | - | Section title above groups (uppercase, non-interactive) |
|
|
11
|
+
| `locale` | `string` | - | Current locale for localized labels |
|
|
12
|
+
| `isCollapsed` | `boolean` | `false` | Collapsed mode (icon-only) |
|
|
13
|
+
| `isExpanding` | `boolean` | `false` | Transitioning from collapsed to expanded |
|
|
14
|
+
| `activeId` | `string` | - | Active item ID for highlighting |
|
|
15
|
+
| `isActive` | `(item: NavItem) => boolean` | - | Custom active check callback |
|
|
16
|
+
| `isGroupActive` | `(group: NavGroup) => boolean` | - | Custom group active check callback |
|
|
17
|
+
| `onSelect` | `(item: NavItem) => void` | - | Item selection callback |
|
|
18
|
+
| `onGroupSelect` | `(group: NavGroup) => void` | - | Group selection callback (groups without items) |
|
|
19
|
+
| `onGroupToggle` | `(groupIndex: number, isExpanded: boolean) => void` | - | Group expand/collapse callback |
|
|
20
|
+
| `touchFriendly` | `boolean \| "auto"` | `false` | Touch-friendly sizing mode |
|
|
21
|
+
| `persistState` | `boolean` | `true` | Enable localStorage persistence for expand/collapse state |
|
|
22
|
+
| `storageKeyPrefix` | `string` | `"stuic-nav"` | Storage key prefix for localStorage |
|
|
23
|
+
| `class` | `string` | - | Classes for wrapper element |
|
|
24
|
+
| `classTitle` | `string` | - | Classes for section title |
|
|
25
|
+
| `classGroupTitle` | `string` | - | Classes for group title/header |
|
|
26
|
+
| `classItem` | `string` | - | Classes for individual items |
|
|
27
|
+
| `classItemActive` | `string` | - | Classes for active items |
|
|
28
|
+
| `classItemCollapsed` | `string` | - | Classes for collapsed mode items |
|
|
29
|
+
| `classItemDisabled` | `string` | - | Classes for disabled items |
|
|
30
|
+
| `classIcon` | `string` | - | Classes for icons |
|
|
31
|
+
| `classLabel` | `string` | - | Classes for labels |
|
|
32
|
+
| `classChildren` | `string` | - | Classes for children container |
|
|
33
|
+
| `classChevron` | `string` | - | Classes for chevron icon |
|
|
34
|
+
| `unstyled` | `boolean` | `false` | Skip all default styling |
|
|
35
|
+
| `el` | `HTMLElement` | - | Element reference (bindable) |
|
|
36
|
+
|
|
37
|
+
## Interfaces
|
|
38
|
+
|
|
39
|
+
### NavGroup
|
|
40
|
+
|
|
41
|
+
A navigation group containing a title and items. Groups without items act as clickable nav items.
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
interface NavGroup {
|
|
45
|
+
/** Group title (supports localization) */
|
|
46
|
+
title: MaybeLocalized;
|
|
47
|
+
/** Navigation items in this group (empty = group acts as nav item) */
|
|
48
|
+
items?: NavItem[];
|
|
49
|
+
/** Group icon (optional) */
|
|
50
|
+
icon?: THC;
|
|
51
|
+
/** Whether the group starts collapsed */
|
|
52
|
+
defaultCollapsed?: boolean;
|
|
53
|
+
/** Navigation URL for groups without items */
|
|
54
|
+
href?: string;
|
|
55
|
+
/** Click handler for groups without items */
|
|
56
|
+
onClick?: () => void;
|
|
57
|
+
/** Unique identifier (used for activeId matching and localStorage persistence) */
|
|
58
|
+
id?: string;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### NavItem
|
|
63
|
+
|
|
64
|
+
A navigation item within a group. Items with children become expandable toggles.
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
interface NavItem {
|
|
68
|
+
/** Unique identifier for the item */
|
|
69
|
+
id: string;
|
|
70
|
+
/** Display label (supports localization) */
|
|
71
|
+
label: MaybeLocalized;
|
|
72
|
+
/** Navigation URL (use href OR onClick, not both) */
|
|
73
|
+
href?: string;
|
|
74
|
+
/** Click handler (alternative to href) */
|
|
75
|
+
onClick?: () => void;
|
|
76
|
+
/** Icon content (THC for flexibility: string, html, component) */
|
|
77
|
+
icon?: THC;
|
|
78
|
+
/** Nested children - parent items with children become expand/collapse toggles */
|
|
79
|
+
children?: NavItem[];
|
|
80
|
+
/** Whether this item is disabled */
|
|
81
|
+
disabled?: boolean;
|
|
82
|
+
/** Additional CSS classes */
|
|
83
|
+
class?: string;
|
|
84
|
+
/** Arbitrary data to pass through */
|
|
85
|
+
data?: Record<string, unknown>;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
### Basic Navigation
|
|
92
|
+
|
|
93
|
+
```svelte
|
|
94
|
+
<script lang="ts">
|
|
95
|
+
import { Nav } from 'stuic';
|
|
96
|
+
|
|
97
|
+
const groups = [
|
|
98
|
+
{
|
|
99
|
+
id: 'main',
|
|
100
|
+
title: 'Main',
|
|
101
|
+
items: [
|
|
102
|
+
{ id: 'dashboard', label: 'Dashboard', href: '/dashboard' },
|
|
103
|
+
{ id: 'analytics', label: 'Analytics', href: '/analytics' },
|
|
104
|
+
{ id: 'reports', label: 'Reports', href: '/reports' },
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: 'settings',
|
|
109
|
+
title: 'Settings',
|
|
110
|
+
items: [
|
|
111
|
+
{ id: 'profile', label: 'Profile', href: '/settings/profile' },
|
|
112
|
+
{ id: 'account', label: 'Account', href: '/settings/account' },
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
];
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<Nav {groups} activeId="dashboard" />
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### With Icons
|
|
122
|
+
|
|
123
|
+
```svelte
|
|
124
|
+
<script lang="ts">
|
|
125
|
+
import { Nav } from 'stuic';
|
|
126
|
+
import { iconLucideHome } from '@marianmeres/icons-fns/lucide/iconLucideHome.js';
|
|
127
|
+
import { iconLucideSettings } from '@marianmeres/icons-fns/lucide/iconLucideSettings.js';
|
|
128
|
+
|
|
129
|
+
const groups = [
|
|
130
|
+
{
|
|
131
|
+
id: 'main',
|
|
132
|
+
title: 'Navigation',
|
|
133
|
+
items: [
|
|
134
|
+
{ id: 'home', label: 'Home', href: '/', icon: iconLucideHome({ size: 18 }) },
|
|
135
|
+
{ id: 'settings', label: 'Settings', href: '/settings', icon: iconLucideSettings({ size: 18 }) },
|
|
136
|
+
],
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
</script>
|
|
140
|
+
|
|
141
|
+
<Nav {groups} />
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Nested Items
|
|
145
|
+
|
|
146
|
+
Items with children become expandable sections.
|
|
147
|
+
|
|
148
|
+
```svelte
|
|
149
|
+
<script lang="ts">
|
|
150
|
+
import { Nav } from 'stuic';
|
|
151
|
+
|
|
152
|
+
const groups = [
|
|
153
|
+
{
|
|
154
|
+
id: 'docs',
|
|
155
|
+
title: 'Documentation',
|
|
156
|
+
items: [
|
|
157
|
+
{
|
|
158
|
+
id: 'getting-started',
|
|
159
|
+
label: 'Getting Started',
|
|
160
|
+
children: [
|
|
161
|
+
{ id: 'installation', label: 'Installation', href: '/docs/installation' },
|
|
162
|
+
{ id: 'quick-start', label: 'Quick Start', href: '/docs/quick-start' },
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: 'components',
|
|
167
|
+
label: 'Components',
|
|
168
|
+
children: [
|
|
169
|
+
{ id: 'button', label: 'Button', href: '/docs/button' },
|
|
170
|
+
{ id: 'input', label: 'Input', href: '/docs/input' },
|
|
171
|
+
{ id: 'nav', label: 'Nav', href: '/docs/nav' },
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
];
|
|
177
|
+
</script>
|
|
178
|
+
|
|
179
|
+
<Nav {groups} />
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Groups Without Items
|
|
183
|
+
|
|
184
|
+
Groups without items act as regular nav items (no chevron, directly clickable).
|
|
185
|
+
|
|
186
|
+
```svelte
|
|
187
|
+
<script lang="ts">
|
|
188
|
+
import { Nav } from 'stuic';
|
|
189
|
+
import { iconLucideHome } from '@marianmeres/icons-fns/lucide/iconLucideHome.js';
|
|
190
|
+
|
|
191
|
+
const groups = [
|
|
192
|
+
{
|
|
193
|
+
id: 'home',
|
|
194
|
+
title: 'Home',
|
|
195
|
+
href: '/',
|
|
196
|
+
icon: iconLucideHome({ size: 18 }),
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
id: 'main',
|
|
200
|
+
title: 'Main',
|
|
201
|
+
items: [
|
|
202
|
+
{ id: 'dashboard', label: 'Dashboard', href: '/dashboard' },
|
|
203
|
+
{ id: 'settings', label: 'Settings', href: '/settings' },
|
|
204
|
+
],
|
|
205
|
+
},
|
|
206
|
+
];
|
|
207
|
+
</script>
|
|
208
|
+
|
|
209
|
+
<Nav {groups} activeId="home" />
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Collapsed Mode
|
|
213
|
+
|
|
214
|
+
In collapsed mode, only icons are shown with tooltips on hover.
|
|
215
|
+
|
|
216
|
+
```svelte
|
|
217
|
+
<script lang="ts">
|
|
218
|
+
import { Nav } from 'stuic';
|
|
219
|
+
|
|
220
|
+
let isCollapsed = $state(false);
|
|
221
|
+
</script>
|
|
222
|
+
|
|
223
|
+
<button onclick={() => isCollapsed = !isCollapsed}>
|
|
224
|
+
Toggle Sidebar
|
|
225
|
+
</button>
|
|
226
|
+
|
|
227
|
+
<Nav {groups} {isCollapsed} />
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### localStorage Persistence
|
|
231
|
+
|
|
232
|
+
Expand/collapse state is persisted to localStorage by default. Groups and items must have an `id` for their state to be persisted.
|
|
233
|
+
|
|
234
|
+
```svelte
|
|
235
|
+
<!-- Persistence enabled (default) -->
|
|
236
|
+
<Nav {groups} />
|
|
237
|
+
|
|
238
|
+
<!-- Disable persistence -->
|
|
239
|
+
<Nav {groups} persistState={false} />
|
|
240
|
+
|
|
241
|
+
<!-- Custom storage key prefix (for multiple Nav instances) -->
|
|
242
|
+
<Nav {groups} storageKeyPrefix="my-app-sidebar" />
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Storage keys follow the pattern:
|
|
246
|
+
- Groups: `{prefix}-group-{groupId}`
|
|
247
|
+
- Items: `{prefix}-item-{itemId}`
|
|
248
|
+
|
|
249
|
+
### Custom Active Check
|
|
250
|
+
|
|
251
|
+
```svelte
|
|
252
|
+
<script lang="ts">
|
|
253
|
+
import { Nav } from 'stuic';
|
|
254
|
+
import { page } from '$app/stores';
|
|
255
|
+
|
|
256
|
+
const groups = [/* ... */];
|
|
257
|
+
</script>
|
|
258
|
+
|
|
259
|
+
<Nav
|
|
260
|
+
{groups}
|
|
261
|
+
isActive={(item) => $page.url.pathname === item.href}
|
|
262
|
+
isGroupActive={(group) => $page.url.pathname === group.href}
|
|
263
|
+
/>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Touch-Friendly Mode
|
|
267
|
+
|
|
268
|
+
```svelte
|
|
269
|
+
<!-- Always touch-friendly -->
|
|
270
|
+
<Nav {groups} touchFriendly />
|
|
271
|
+
|
|
272
|
+
<!-- Auto-detect based on device -->
|
|
273
|
+
<Nav {groups} touchFriendly="auto" />
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### With Selection Callbacks
|
|
277
|
+
|
|
278
|
+
```svelte
|
|
279
|
+
<script lang="ts">
|
|
280
|
+
import { Nav } from 'stuic';
|
|
281
|
+
import { goto } from '$app/navigation';
|
|
282
|
+
|
|
283
|
+
function handleSelect(item) {
|
|
284
|
+
console.log('Selected:', item.id);
|
|
285
|
+
if (item.href) goto(item.href);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
function handleGroupToggle(index, isExpanded) {
|
|
289
|
+
console.log(`Group ${index} is now ${isExpanded ? 'expanded' : 'collapsed'}`);
|
|
290
|
+
}
|
|
291
|
+
</script>
|
|
292
|
+
|
|
293
|
+
<Nav
|
|
294
|
+
{groups}
|
|
295
|
+
onSelect={handleSelect}
|
|
296
|
+
onGroupToggle={handleGroupToggle}
|
|
297
|
+
/>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Features
|
|
301
|
+
|
|
302
|
+
- **Hierarchical Navigation**: Groups with items, nested items with children
|
|
303
|
+
- **Expand/Collapse**: Groups and nested items can be expanded/collapsed
|
|
304
|
+
- **localStorage Persistence**: Expand/collapse state persists across page reloads
|
|
305
|
+
- **Collapsed Mode**: Icon-only sidebar with tooltips
|
|
306
|
+
- **Active State**: Highlight current item via `activeId` or custom callback
|
|
307
|
+
- **Localization**: Labels support `MaybeLocalized` type
|
|
308
|
+
- **Touch-Friendly**: Auto-detect or manually enable larger touch targets
|
|
309
|
+
- **ARIA Compliant**: Proper roles and aria-expanded attributes
|
|
310
|
+
- **Reduced Motion**: Respects user's reduced motion preference
|
|
311
|
+
- **SSR Safe**: localStorage persistence handles SSR gracefully
|
|
312
|
+
|
|
313
|
+
## CSS Classes
|
|
314
|
+
|
|
315
|
+
The component applies these base classes (when `unstyled` is false):
|
|
316
|
+
|
|
317
|
+
| Class | Element |
|
|
318
|
+
|-------|---------|
|
|
319
|
+
| `stuic-nav` | Root `<nav>` element |
|
|
320
|
+
| `stuic-nav-section-title` | Section title |
|
|
321
|
+
| `stuic-nav-group-title` | Group header/toggle |
|
|
322
|
+
| `stuic-nav-item` | Individual nav items |
|
|
323
|
+
| `stuic-nav-children` | Nested items container |
|
|
324
|
+
|
|
325
|
+
### Data Attributes
|
|
326
|
+
|
|
327
|
+
| Attribute | Applied When |
|
|
328
|
+
|-----------|--------------|
|
|
329
|
+
| `data-collapsed` | Sidebar is in collapsed mode |
|
|
330
|
+
| `data-expanding` | Transitioning from collapsed to expanded |
|
|
331
|
+
| `data-active` | Item/group is currently active |
|
|
332
|
+
| `data-touch-friendly` | Touch-friendly mode is active |
|
|
333
|
+
| `data-has-children` | Item has nested children |
|
|
334
|
+
| `data-disabled` | Item is disabled |
|