ui-svelte 0.2.4 → 0.2.6
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/assets/country-flags.d.ts +1 -0
- package/dist/assets/country-flags.js +1612 -0
- package/dist/charts/ArcChart.svelte +291 -48
- package/dist/charts/ArcChart.svelte.d.ts +32 -1
- package/dist/charts/Candlestick.svelte +663 -115
- package/dist/charts/Candlestick.svelte.d.ts +40 -0
- package/dist/charts/css/arc-chart.css +76 -6
- package/dist/charts/css/candlestick.css +234 -11
- package/dist/control/Button.svelte +3 -1
- package/dist/control/Button.svelte.d.ts +1 -0
- package/dist/control/IconButton.svelte +3 -1
- package/dist/control/IconButton.svelte.d.ts +1 -0
- package/dist/control/ToggleGroup.svelte +82 -0
- package/dist/control/ToggleGroup.svelte.d.ts +20 -0
- package/dist/control/css/toggle-group.css +85 -0
- package/dist/css/base.css +23 -43
- package/dist/css/utilities.css +45 -0
- package/dist/display/AvatarGroup.svelte +59 -0
- package/dist/display/AvatarGroup.svelte.d.ts +17 -0
- package/dist/display/Code.svelte +14 -7
- package/dist/display/Code.svelte.d.ts +1 -0
- package/dist/display/Section.svelte +1 -1
- package/dist/display/css/avatar-group.css +46 -0
- package/dist/display/css/avatar.css +1 -10
- package/dist/display/css/badge.css +14 -11
- package/dist/form/ComboBox.svelte.d.ts +1 -1
- package/dist/form/PhoneField.svelte +8 -4
- package/dist/form/Select.svelte.d.ts +1 -1
- package/dist/index.css +43 -21
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/navigation/BottomNav.svelte +43 -16
- package/dist/navigation/NavMenu.svelte +25 -4
- package/dist/navigation/SideNav.svelte +20 -2
- package/dist/navigation/SideNav.svelte.d.ts +2 -0
- package/dist/navigation/css/bottom-nav.css +139 -15
- package/dist/navigation/css/nav-menu.css +192 -7
- package/dist/navigation/css/side-nav.css +80 -0
- package/dist/navigation/css/tabs.css +4 -4
- package/dist/utils/popover.js +6 -6
- package/package.json +2 -2
- /package/dist/{form/js → assets}/countries.d.ts +0 -0
- /package/dist/{form/js → assets}/countries.js +0 -0
- /package/dist/{form/js → assets}/phone-examples.d.ts +0 -0
- /package/dist/{form/js → assets}/phone-examples.js +0 -0
package/dist/index.css
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
@import './control/css/btn.css';
|
|
9
9
|
@import './control/css/media.css';
|
|
10
10
|
@import './control/css/video.css';
|
|
11
|
+
@import './control/css/toggle-group.css';
|
|
11
12
|
|
|
12
13
|
@import './charts/css/arc-chart.css';
|
|
13
14
|
@import './charts/css/area-chart.css';
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
@import './display/css/accordion.css';
|
|
20
21
|
@import './display/css/alert.css';
|
|
21
22
|
@import './display/css/avatar.css';
|
|
23
|
+
@import './display/css/avatar-group.css';
|
|
22
24
|
@import './display/css/badge.css';
|
|
23
25
|
@import './display/css/carousel.css';
|
|
24
26
|
@import './display/css/card.css';
|
|
@@ -69,48 +71,68 @@
|
|
|
69
71
|
@import './overlay/css/tooltip.css';
|
|
70
72
|
|
|
71
73
|
@theme {
|
|
72
|
-
--color-primary: var(--primary, oklch(54.6% 0.245 262.881));
|
|
73
|
-
|
|
74
|
+
--color-primary: var(--primary, oklch(54.6% 0.245 262.881));
|
|
75
|
+
/* blue-600 */
|
|
76
|
+
--color-on-primary: var(--on-primary, oklch(93.2% 0.032 255.585));
|
|
77
|
+
/* blue-100 */
|
|
74
78
|
|
|
75
|
-
--color-secondary: var(--secondary, oklch(0.592 0.249 0.584));
|
|
76
|
-
|
|
79
|
+
--color-secondary: var(--secondary, oklch(0.592 0.249 0.584));
|
|
80
|
+
/* pink-600 */
|
|
81
|
+
--color-on-secondary: var(--on-secondary, oklch(0.948 0.028 342.258));
|
|
82
|
+
/* pink-100 */
|
|
77
83
|
|
|
78
|
-
--color-muted: var(--muted, oklch(87.2% 0.01 258.338));
|
|
79
|
-
|
|
84
|
+
--color-muted: var(--muted, oklch(87.2% 0.01 258.338));
|
|
85
|
+
/* gray-300 */
|
|
86
|
+
--color-on-muted: var(--on-muted, oklch(27.8% 0.033 256.848));
|
|
87
|
+
/* gray-700 */
|
|
80
88
|
|
|
81
89
|
/* dark */
|
|
82
90
|
/*--color-muted: var(--muted, oklch(37.3% 0.034 259.733)); /* gray-700 */
|
|
83
91
|
/*--color-on-muted: var(--on-muted, oklch(87.2% 0.01 258.338)); /* gray-300 */
|
|
84
92
|
|
|
85
|
-
--color-background: var(--background, oklch(98.5% 0.002 247.839));
|
|
86
|
-
|
|
93
|
+
--color-background: var(--background, oklch(98.5% 0.002 247.839));
|
|
94
|
+
/* gray-50 */
|
|
95
|
+
--color-on-background: var(--on-background, oklch(21% 0.034 264.665));
|
|
96
|
+
/* gray-900 */
|
|
87
97
|
|
|
88
98
|
/* dark */
|
|
89
99
|
/*--color-background: var(--background, oklch(13% 0.028 261.692)); /* gray-950 */
|
|
90
100
|
/*--color-on-background: var(--on-background, oklch(96.7% 0.003 264.542)); /* gray-100 */
|
|
91
101
|
|
|
92
|
-
--color-surface: var(--surface, oklch(96.7% 0.003 264.542));
|
|
93
|
-
|
|
102
|
+
--color-surface: var(--surface, oklch(96.7% 0.003 264.542));
|
|
103
|
+
/* gray-100 */
|
|
104
|
+
--color-on-surface: var(--on-surface, oklch(27.9% 0.041 260.031));
|
|
105
|
+
/* gray-800 */
|
|
94
106
|
|
|
95
107
|
/* dark */
|
|
96
108
|
/*--color-surface: var(--surface, oklch(21% 0.034 264.665)); /* gray-900 */
|
|
97
109
|
/*--color-on-surface: var(--on-surface, oklch(92.8% 0.006 264.531)); /* gray-200 */
|
|
98
110
|
|
|
99
|
-
--color-overlay: var(--overlay, oklch(0 0 0 / 60%));
|
|
100
|
-
|
|
111
|
+
--color-overlay: var(--overlay, oklch(0 0 0 / 60%));
|
|
112
|
+
/* black/60 */
|
|
113
|
+
--color-on-overlay: var(--on-overlay, oklch(1 0 0));
|
|
114
|
+
/* white */
|
|
101
115
|
|
|
102
|
-
--color-success: var(--success, oklch(62.7% 0.194 149.214));
|
|
103
|
-
|
|
116
|
+
--color-success: var(--success, oklch(62.7% 0.194 149.214));
|
|
117
|
+
/* green-600 */
|
|
118
|
+
--color-on-success: var(--on-success, oklch(96.2% 0.044 156.743));
|
|
119
|
+
/* green-100 */
|
|
104
120
|
|
|
105
|
-
--color-info: var(--info, oklch(58.8% 0.158 241.966));
|
|
106
|
-
|
|
121
|
+
--color-info: var(--info, oklch(58.8% 0.158 241.966));
|
|
122
|
+
/* sky-600 */
|
|
123
|
+
--color-on-info: var(--on-info, oklch(95.1% 0.026 236.824));
|
|
124
|
+
/* sky-100 */
|
|
107
125
|
|
|
108
|
-
--color-warning: var(--warning, oklch(68.1% 0.162 75.834));
|
|
109
|
-
|
|
126
|
+
--color-warning: var(--warning, oklch(68.1% 0.162 75.834));
|
|
127
|
+
/* yellow-600 */
|
|
128
|
+
--color-on-warning: var(--on-warning, oklch(97.3% 0.071 103.193));
|
|
129
|
+
/* yellow-100 */
|
|
110
130
|
|
|
111
|
-
--color-danger: var(--danger, oklch(57.7% 0.245 27.325));
|
|
112
|
-
|
|
131
|
+
--color-danger: var(--danger, oklch(57.7% 0.245 27.325));
|
|
132
|
+
/* red-600 */
|
|
133
|
+
--color-on-danger: var(--on-danger, oklch(93.6% 0.032 17.717));
|
|
134
|
+
/* red-100 */
|
|
113
135
|
|
|
114
136
|
--radius-ui: 0.75rem;
|
|
115
137
|
--scrollbar-size: 6px;
|
|
116
|
-
}
|
|
138
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,10 +9,12 @@ import Button from './control/Button.svelte';
|
|
|
9
9
|
import IconButton from './control/IconButton.svelte';
|
|
10
10
|
import Record from './control/Record.svelte';
|
|
11
11
|
import ToggleTheme from './control/ToggleTheme.svelte';
|
|
12
|
+
import ToggleGroup from './control/ToggleGroup.svelte';
|
|
12
13
|
import Video from './control/Video.svelte';
|
|
13
14
|
import Accordion from './display/Accordion.svelte';
|
|
14
15
|
import Alert from './display/Alert.svelte';
|
|
15
16
|
import Avatar from './display/Avatar.svelte';
|
|
17
|
+
import AvatarGroup from './display/AvatarGroup.svelte';
|
|
16
18
|
import Badge from './display/Badge.svelte';
|
|
17
19
|
import Carousel from './display/Carousel.svelte';
|
|
18
20
|
import Card from './display/Card.svelte';
|
|
@@ -74,5 +76,5 @@ import { useAuth } from './hooks/use-auth.svelte.js';
|
|
|
74
76
|
import { theme } from './stores/theme.svelte.js';
|
|
75
77
|
import { useSearch } from './hooks/use-search.svelte.js';
|
|
76
78
|
import { useChat } from './hooks/use-chat.svelte.js';
|
|
77
|
-
export { AreaChart, ArcChart, BarChart, Candlestick, LineChart, PieChart, Alert, AlertDialog, AppBar, Accordion, Avatar, Audio, Badge, Button, BottomNav, Carousel, Card, ChatBox, Checkbox, Chip, Code, Collapsible, Command, ComboBox, CsvField, DateField, Drawer, Dropzone, Divider, Dropdown, Empty, Footer, FooterNav, FooterGroup, formatCurrency, formatDate, formatNumber, getWeekdays, i18n, Icon, IconButton, ImageCropper, Item, initLanguage, Modal, Marquee, NavMenu, PasswordField, PhoneField, PinField, plural, PopoverStack, Provider, RadioGroup, Record, Scaffold, Section, Select, setLanguage, Sidebar, SideNav, Slider, t, Table, Tabs, TextField, Textarea, theme, Toast, toast, Toggle, ToggleTheme, Tooltip, useAuth, useChat, useClipboard, useFetch, useForm, useLocalStorage, useScroll, useSearch, useTable, useWebSocket, Video };
|
|
79
|
+
export { AreaChart, ArcChart, BarChart, Candlestick, LineChart, PieChart, Alert, AlertDialog, AppBar, Accordion, Avatar, AvatarGroup, Audio, Badge, Button, BottomNav, Carousel, Card, ChatBox, Checkbox, Chip, Code, Collapsible, Command, ComboBox, CsvField, DateField, Drawer, Dropzone, Divider, Dropdown, Empty, Footer, FooterNav, FooterGroup, formatCurrency, formatDate, formatNumber, getWeekdays, i18n, Icon, IconButton, ImageCropper, Item, initLanguage, Modal, Marquee, NavMenu, PasswordField, PhoneField, PinField, plural, PopoverStack, Provider, RadioGroup, Record, Scaffold, Section, Select, setLanguage, Sidebar, SideNav, Slider, t, Table, Tabs, TextField, Textarea, theme, Toast, toast, Toggle, ToggleGroup, ToggleTheme, Tooltip, useAuth, useChat, useClipboard, useFetch, useForm, useLocalStorage, useScroll, useSearch, useTable, useWebSocket, Video };
|
|
78
80
|
export type { IconData, SideNavItem, SideNavSubItem };
|
package/dist/index.js
CHANGED
|
@@ -9,10 +9,12 @@ import Button from './control/Button.svelte';
|
|
|
9
9
|
import IconButton from './control/IconButton.svelte';
|
|
10
10
|
import Record from './control/Record.svelte';
|
|
11
11
|
import ToggleTheme from './control/ToggleTheme.svelte';
|
|
12
|
+
import ToggleGroup from './control/ToggleGroup.svelte';
|
|
12
13
|
import Video from './control/Video.svelte';
|
|
13
14
|
import Accordion from './display/Accordion.svelte';
|
|
14
15
|
import Alert from './display/Alert.svelte';
|
|
15
16
|
import Avatar from './display/Avatar.svelte';
|
|
17
|
+
import AvatarGroup from './display/AvatarGroup.svelte';
|
|
16
18
|
import Badge from './display/Badge.svelte';
|
|
17
19
|
import Carousel from './display/Carousel.svelte';
|
|
18
20
|
import Card from './display/Card.svelte';
|
|
@@ -74,4 +76,4 @@ import { useAuth } from './hooks/use-auth.svelte.js';
|
|
|
74
76
|
import { theme } from './stores/theme.svelte.js';
|
|
75
77
|
import { useSearch } from './hooks/use-search.svelte.js';
|
|
76
78
|
import { useChat } from './hooks/use-chat.svelte.js';
|
|
77
|
-
export { AreaChart, ArcChart, BarChart, Candlestick, LineChart, PieChart, Alert, AlertDialog, AppBar, Accordion, Avatar, Audio, Badge, Button, BottomNav, Carousel, Card, ChatBox, Checkbox, Chip, Code, Collapsible, Command, ComboBox, CsvField, DateField, Drawer, Dropzone, Divider, Dropdown, Empty, Footer, FooterNav, FooterGroup, formatCurrency, formatDate, formatNumber, getWeekdays, i18n, Icon, IconButton, ImageCropper, Item, initLanguage, Modal, Marquee, NavMenu, PasswordField, PhoneField, PinField, plural, PopoverStack, Provider, RadioGroup, Record, Scaffold, Section, Select, setLanguage, Sidebar, SideNav, Slider, t, Table, Tabs, TextField, Textarea, theme, Toast, toast, Toggle, ToggleTheme, Tooltip, useAuth, useChat, useClipboard, useFetch, useForm, useLocalStorage, useScroll, useSearch, useTable, useWebSocket, Video };
|
|
79
|
+
export { AreaChart, ArcChart, BarChart, Candlestick, LineChart, PieChart, Alert, AlertDialog, AppBar, Accordion, Avatar, AvatarGroup, Audio, Badge, Button, BottomNav, Carousel, Card, ChatBox, Checkbox, Chip, Code, Collapsible, Command, ComboBox, CsvField, DateField, Drawer, Dropzone, Divider, Dropdown, Empty, Footer, FooterNav, FooterGroup, formatCurrency, formatDate, formatNumber, getWeekdays, i18n, Icon, IconButton, ImageCropper, Item, initLanguage, Modal, Marquee, NavMenu, PasswordField, PhoneField, PinField, plural, PopoverStack, Provider, RadioGroup, Record, Scaffold, Section, Select, setLanguage, Sidebar, SideNav, Slider, t, Table, Tabs, TextField, Textarea, theme, Toast, toast, Toggle, ToggleGroup, ToggleTheme, Tooltip, useAuth, useChat, useClipboard, useFetch, useForm, useLocalStorage, useScroll, useSearch, useTable, useWebSocket, Video };
|
|
@@ -9,13 +9,17 @@
|
|
|
9
9
|
icon: IconData;
|
|
10
10
|
href?: string;
|
|
11
11
|
onclick?: (item: BottomNavItem) => void;
|
|
12
|
+
badge?: string | number;
|
|
13
|
+
isFab?: boolean;
|
|
14
|
+
isActive?: boolean;
|
|
12
15
|
};
|
|
13
16
|
|
|
14
17
|
type Props = {
|
|
15
18
|
items: BottomNavItem[];
|
|
16
|
-
variant?: 'primary' | 'secondary' | '
|
|
19
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'line';
|
|
17
20
|
size?: 'sm' | 'md' | 'lg';
|
|
18
|
-
|
|
21
|
+
isSolid?: boolean;
|
|
22
|
+
isBlock?: boolean;
|
|
19
23
|
class?: string;
|
|
20
24
|
};
|
|
21
25
|
|
|
@@ -24,13 +28,15 @@
|
|
|
24
28
|
class: className,
|
|
25
29
|
variant = 'primary',
|
|
26
30
|
size = 'md',
|
|
27
|
-
|
|
31
|
+
isSolid = false,
|
|
32
|
+
isBlock = false
|
|
28
33
|
}: Props = $props();
|
|
29
34
|
|
|
30
35
|
const variantClasses = {
|
|
31
|
-
primary: '
|
|
32
|
-
secondary: '
|
|
33
|
-
|
|
36
|
+
primary: 'is-primary',
|
|
37
|
+
secondary: 'is-secondary',
|
|
38
|
+
ghost: 'is-ghost',
|
|
39
|
+
line: 'is-line'
|
|
34
40
|
};
|
|
35
41
|
|
|
36
42
|
const sizeClasses = {
|
|
@@ -39,9 +45,15 @@
|
|
|
39
45
|
lg: 'is-lg'
|
|
40
46
|
};
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
// Determine if any item has a label
|
|
49
|
+
const hasLabels = $derived(items.some((item) => item.label));
|
|
50
|
+
|
|
51
|
+
function isItemActive(item: BottomNavItem): boolean {
|
|
52
|
+
// If item has explicit isActive, use that
|
|
53
|
+
if (item.isActive !== undefined) return item.isActive;
|
|
54
|
+
// Otherwise check against current URL
|
|
55
|
+
if (!item.href) return false;
|
|
56
|
+
return page.url.pathname === item.href || page.url.pathname.startsWith(item.href + '/');
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
function handleItemClick(item: BottomNavItem) {
|
|
@@ -56,22 +68,37 @@
|
|
|
56
68
|
'bottomnav',
|
|
57
69
|
variantClasses[variant],
|
|
58
70
|
sizeClasses[size],
|
|
59
|
-
|
|
71
|
+
isSolid && 'is-solid',
|
|
72
|
+
!hasLabels && 'is-icon-only',
|
|
73
|
+
!isBlock && 'is-fixed',
|
|
60
74
|
className
|
|
61
75
|
)}
|
|
62
76
|
>
|
|
63
77
|
{#each items as item}
|
|
78
|
+
{@const active = isItemActive(item)}
|
|
79
|
+
{@const itemClass = cn('bottomnav-item', active && 'is-active', item.isFab && 'is-fab')}
|
|
80
|
+
|
|
64
81
|
{#if item.href}
|
|
65
|
-
<a href={item.href} class={
|
|
66
|
-
<
|
|
67
|
-
|
|
82
|
+
<a href={item.href} class={itemClass}>
|
|
83
|
+
<span class="bottomnav-icon-wrapper">
|
|
84
|
+
<Icon icon={item.icon} class="bottomnav-icon" />
|
|
85
|
+
{#if item.badge !== undefined}
|
|
86
|
+
<span class="bottomnav-badge">{item.badge}</span>
|
|
87
|
+
{/if}
|
|
88
|
+
</span>
|
|
89
|
+
{#if item.label}
|
|
68
90
|
<span class="bottomnav-label">{item.label}</span>
|
|
69
91
|
{/if}
|
|
70
92
|
</a>
|
|
71
93
|
{:else}
|
|
72
|
-
<button type="button" class=
|
|
73
|
-
<
|
|
74
|
-
|
|
94
|
+
<button type="button" class={itemClass} onclick={() => handleItemClick(item)}>
|
|
95
|
+
<span class="bottomnav-icon-wrapper">
|
|
96
|
+
<Icon icon={item.icon} class="bottomnav-icon" />
|
|
97
|
+
{#if item.badge !== undefined}
|
|
98
|
+
<span class="bottomnav-badge">{item.badge}</span>
|
|
99
|
+
{/if}
|
|
100
|
+
</span>
|
|
101
|
+
{#if item.label}
|
|
75
102
|
<span class="bottomnav-label">{item.label}</span>
|
|
76
103
|
{/if}
|
|
77
104
|
</button>
|
|
@@ -26,10 +26,18 @@
|
|
|
26
26
|
type Props = {
|
|
27
27
|
items: MenuItem[];
|
|
28
28
|
size?: 'sm' | 'md' | 'lg';
|
|
29
|
+
isSolid?: boolean;
|
|
30
|
+
variant?: 'primary' | 'secondary' | 'muted' | 'success' | 'info' | 'warning' | 'danger';
|
|
29
31
|
class?: string;
|
|
30
32
|
};
|
|
31
33
|
|
|
32
|
-
const {
|
|
34
|
+
const {
|
|
35
|
+
items = [],
|
|
36
|
+
class: className,
|
|
37
|
+
size = 'md',
|
|
38
|
+
isSolid = false,
|
|
39
|
+
variant = 'muted'
|
|
40
|
+
}: Props = $props();
|
|
33
41
|
|
|
34
42
|
let openSubmenuIndex = $state<number | null>(null);
|
|
35
43
|
let triggerElements = $state<Record<number, HTMLElement>>({});
|
|
@@ -48,6 +56,18 @@
|
|
|
48
56
|
lg: 'is-lg'
|
|
49
57
|
};
|
|
50
58
|
|
|
59
|
+
const solidClass = $derived(isSolid ? 'is-filled' : 'is-default');
|
|
60
|
+
|
|
61
|
+
const variantClasses = {
|
|
62
|
+
primary: 'is-primary',
|
|
63
|
+
secondary: 'is-secondary',
|
|
64
|
+
muted: 'is-muted',
|
|
65
|
+
success: 'is-success',
|
|
66
|
+
info: 'is-info',
|
|
67
|
+
warning: 'is-warning',
|
|
68
|
+
danger: 'is-danger'
|
|
69
|
+
};
|
|
70
|
+
|
|
51
71
|
const style = $derived(
|
|
52
72
|
`top: ${position.top}px; left: ${position.left}px; ${position.width !== 'auto' ? `width: ${position.width}px;` : ''} transform-origin: ${position.isBottomHalf ? 'bottom' : 'top'} center;`
|
|
53
73
|
);
|
|
@@ -165,11 +185,11 @@
|
|
|
165
185
|
});
|
|
166
186
|
</script>
|
|
167
187
|
|
|
168
|
-
<nav class={cn('navmenu', sizeClasses[size], className)}>
|
|
188
|
+
<nav class={cn('navmenu', sizeClasses[size], solidClass, variantClasses[variant], className)}>
|
|
169
189
|
{#each items as item, index}
|
|
170
190
|
{#if item.href && !item.subitems && !item.megamenu}
|
|
171
191
|
<a href={item.href} class={cn('navmenu-item', isItemActive(item.href) && 'is-active')}>
|
|
172
|
-
<span class="navmenu-label">{item.label}</span>
|
|
192
|
+
<span class="navmenu-label" data-text={item.label}>{item.label}</span>
|
|
173
193
|
</a>
|
|
174
194
|
{:else}
|
|
175
195
|
<button
|
|
@@ -182,7 +202,7 @@
|
|
|
182
202
|
bind:this={triggerElements[index]}
|
|
183
203
|
onclick={() => handleItemClick(item, index)}
|
|
184
204
|
>
|
|
185
|
-
<span class="navmenu-label">{item.label}</span>
|
|
205
|
+
<span class="navmenu-label" data-text={item.label}>{item.label}</span>
|
|
186
206
|
{#if item.subitems || item.megamenu}
|
|
187
207
|
<Icon
|
|
188
208
|
icon={ChevronDown24RegularIcon}
|
|
@@ -199,6 +219,7 @@
|
|
|
199
219
|
<div
|
|
200
220
|
class={cn(
|
|
201
221
|
'navmenu-popover',
|
|
222
|
+
sizeClasses[size],
|
|
202
223
|
openSubmenuIndex !== null && 'is-active',
|
|
203
224
|
position.isMegamenu && 'is-megamenu'
|
|
204
225
|
)}
|
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
isWide?: boolean;
|
|
37
37
|
isCompact?: boolean;
|
|
38
38
|
isCollapsible?: boolean;
|
|
39
|
+
isSolid?: boolean;
|
|
40
|
+
variant?: 'primary' | 'secondary' | 'muted' | 'success' | 'info' | 'warning' | 'danger';
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
const {
|
|
@@ -44,7 +46,9 @@
|
|
|
44
46
|
size = 'md',
|
|
45
47
|
isWide,
|
|
46
48
|
isCompact,
|
|
47
|
-
isCollapsible
|
|
49
|
+
isCollapsible,
|
|
50
|
+
isSolid = false,
|
|
51
|
+
variant = 'muted'
|
|
48
52
|
}: Props = $props();
|
|
49
53
|
|
|
50
54
|
let openSubmenus = $state<Record<number, boolean>>({});
|
|
@@ -74,13 +78,25 @@
|
|
|
74
78
|
lg: 'is-lg'
|
|
75
79
|
};
|
|
76
80
|
|
|
81
|
+
const solidClass = $derived(isSolid ? 'is-solid' : '');
|
|
82
|
+
|
|
83
|
+
const variantClasses = {
|
|
84
|
+
primary: 'is-primary',
|
|
85
|
+
secondary: 'is-secondary',
|
|
86
|
+
muted: 'is-muted',
|
|
87
|
+
success: 'is-success',
|
|
88
|
+
info: 'is-info',
|
|
89
|
+
warning: 'is-warning',
|
|
90
|
+
danger: 'is-danger'
|
|
91
|
+
};
|
|
92
|
+
|
|
77
93
|
function toggleSubmenu(index: number) {
|
|
78
94
|
openSubmenus[index] = !openSubmenus[index];
|
|
79
95
|
}
|
|
80
96
|
|
|
81
97
|
function isItemActive(href?: string): boolean {
|
|
82
98
|
if (!href) return false;
|
|
83
|
-
return page.url.pathname
|
|
99
|
+
return page.url.pathname === href;
|
|
84
100
|
}
|
|
85
101
|
|
|
86
102
|
function toggleExpand() {
|
|
@@ -112,6 +128,8 @@
|
|
|
112
128
|
class={cn(
|
|
113
129
|
'sidenav',
|
|
114
130
|
sizeClasses[size],
|
|
131
|
+
solidClass,
|
|
132
|
+
isSolid && variantClasses[variant],
|
|
115
133
|
isCompact && 'is-compact',
|
|
116
134
|
isCollapsible && 'is-collapsible',
|
|
117
135
|
!isExpanded && 'is-collapsed',
|
|
@@ -26,6 +26,8 @@ type Props = {
|
|
|
26
26
|
isWide?: boolean;
|
|
27
27
|
isCompact?: boolean;
|
|
28
28
|
isCollapsible?: boolean;
|
|
29
|
+
isSolid?: boolean;
|
|
30
|
+
variant?: 'primary' | 'secondary' | 'muted' | 'success' | 'info' | 'warning' | 'danger';
|
|
29
31
|
};
|
|
30
32
|
declare const SideNav: import("svelte").Component<Props, {}, "">;
|
|
31
33
|
type SideNav = ReturnType<typeof SideNav>;
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
@layer components {
|
|
2
2
|
.bottomnav {
|
|
3
|
-
@apply fixed bottom-0 left-0 right-0 z-50;
|
|
4
3
|
@apply flex items-center justify-around;
|
|
5
4
|
@apply bg-background text-on-background;
|
|
6
5
|
@apply border-t border-muted;
|
|
7
6
|
@apply shadow-lg;
|
|
8
|
-
|
|
7
|
+
|
|
8
|
+
&.is-fixed {
|
|
9
|
+
@apply fixed bottom-0 left-0 right-0 z-50;
|
|
10
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
11
|
+
}
|
|
9
12
|
|
|
10
13
|
.bottomnav-item {
|
|
11
14
|
@apply flex flex-col items-center justify-center gap-1;
|
|
12
|
-
@apply flex-1 py-
|
|
15
|
+
@apply flex-1 py-3 px-2;
|
|
13
16
|
@apply cursor-pointer select-none outline-none;
|
|
14
17
|
@apply transition-all duration-200;
|
|
15
18
|
@apply relative;
|
|
16
19
|
|
|
20
|
+
.bottomnav-icon-wrapper {
|
|
21
|
+
@apply relative inline-flex;
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
.bottomnav-icon {
|
|
18
25
|
@apply h-6 w-6 shrink-0;
|
|
19
26
|
@apply transition-all duration-200;
|
|
@@ -24,22 +31,55 @@
|
|
|
24
31
|
@apply transition-all duration-200;
|
|
25
32
|
}
|
|
26
33
|
|
|
34
|
+
.bottomnav-badge {
|
|
35
|
+
@apply absolute -top-1.5 -right-2;
|
|
36
|
+
@apply min-w-4 h-4 px-1;
|
|
37
|
+
@apply flex items-center justify-center;
|
|
38
|
+
@apply text-[10px] font-bold;
|
|
39
|
+
@apply bg-danger text-on-danger;
|
|
40
|
+
@apply rounded-full;
|
|
41
|
+
}
|
|
42
|
+
|
|
27
43
|
&:hover {
|
|
28
44
|
@apply bg-muted/50;
|
|
29
45
|
}
|
|
30
46
|
|
|
31
|
-
|
|
32
|
-
|
|
47
|
+
/* FAB Style */
|
|
48
|
+
&.is-fab {
|
|
49
|
+
@apply flex-none;
|
|
50
|
+
|
|
51
|
+
&:hover {
|
|
52
|
+
@apply bg-transparent;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.bottomnav-icon-wrapper {
|
|
56
|
+
@apply w-12 h-12 -mt-6;
|
|
57
|
+
@apply flex items-center justify-center;
|
|
58
|
+
@apply bg-primary text-on-primary;
|
|
59
|
+
@apply rounded-full shadow-lg;
|
|
60
|
+
@apply transition-all duration-200;
|
|
61
|
+
}
|
|
33
62
|
|
|
34
63
|
.bottomnav-icon {
|
|
35
|
-
@apply text-primary;
|
|
64
|
+
@apply h-6 w-6 text-on-primary;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&:hover .bottomnav-icon-wrapper {
|
|
68
|
+
@apply shadow-xl shadow-primary/30;
|
|
69
|
+
transform: translateY(-2px);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
&:active .bottomnav-icon-wrapper {
|
|
73
|
+
transform: translateY(0);
|
|
74
|
+
@apply shadow-md;
|
|
36
75
|
}
|
|
37
76
|
}
|
|
38
77
|
}
|
|
39
78
|
|
|
79
|
+
/* Size Variants */
|
|
40
80
|
&.is-sm {
|
|
41
81
|
.bottomnav-item {
|
|
42
|
-
@apply gap-0.5 py-1
|
|
82
|
+
@apply gap-0.5 py-2 px-1;
|
|
43
83
|
|
|
44
84
|
.bottomnav-icon {
|
|
45
85
|
@apply h-5 w-5;
|
|
@@ -48,12 +88,16 @@
|
|
|
48
88
|
.bottomnav-label {
|
|
49
89
|
@apply text-[10px];
|
|
50
90
|
}
|
|
91
|
+
|
|
92
|
+
&.is-fab .bottomnav-icon-wrapper {
|
|
93
|
+
@apply w-10 h-10 -mt-5;
|
|
94
|
+
}
|
|
51
95
|
}
|
|
52
96
|
}
|
|
53
97
|
|
|
54
98
|
&.is-md {
|
|
55
99
|
.bottomnav-item {
|
|
56
|
-
@apply gap-1 py-2;
|
|
100
|
+
@apply gap-1 py-3 px-2;
|
|
57
101
|
|
|
58
102
|
.bottomnav-icon {
|
|
59
103
|
@apply h-6 w-6;
|
|
@@ -67,7 +111,7 @@
|
|
|
67
111
|
|
|
68
112
|
&.is-lg {
|
|
69
113
|
.bottomnav-item {
|
|
70
|
-
@apply gap-1.5 py-3;
|
|
114
|
+
@apply gap-1.5 py-4 px-3;
|
|
71
115
|
|
|
72
116
|
.bottomnav-icon {
|
|
73
117
|
@apply h-7 w-7;
|
|
@@ -76,6 +120,14 @@
|
|
|
76
120
|
.bottomnav-label {
|
|
77
121
|
@apply text-sm;
|
|
78
122
|
}
|
|
123
|
+
|
|
124
|
+
&.is-fab .bottomnav-icon-wrapper {
|
|
125
|
+
@apply w-14 h-14 -mt-7;
|
|
126
|
+
|
|
127
|
+
.bottomnav-icon {
|
|
128
|
+
@apply h-7 w-7;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
79
131
|
}
|
|
80
132
|
}
|
|
81
133
|
|
|
@@ -89,7 +141,8 @@
|
|
|
89
141
|
}
|
|
90
142
|
}
|
|
91
143
|
|
|
92
|
-
|
|
144
|
+
/* Variant: Primary */
|
|
145
|
+
&.is-primary {
|
|
93
146
|
.bottomnav-item.is-active {
|
|
94
147
|
@apply text-primary;
|
|
95
148
|
|
|
@@ -101,9 +154,14 @@
|
|
|
101
154
|
@apply text-primary;
|
|
102
155
|
}
|
|
103
156
|
}
|
|
157
|
+
|
|
158
|
+
.bottomnav-item.is-fab .bottomnav-icon-wrapper {
|
|
159
|
+
@apply bg-primary;
|
|
160
|
+
}
|
|
104
161
|
}
|
|
105
162
|
|
|
106
|
-
|
|
163
|
+
/* Variant: Secondary */
|
|
164
|
+
&.is-secondary {
|
|
107
165
|
.bottomnav-item.is-active {
|
|
108
166
|
@apply text-secondary;
|
|
109
167
|
|
|
@@ -115,20 +173,86 @@
|
|
|
115
173
|
@apply text-secondary;
|
|
116
174
|
}
|
|
117
175
|
}
|
|
176
|
+
|
|
177
|
+
.bottomnav-item.is-fab .bottomnav-icon-wrapper {
|
|
178
|
+
@apply bg-secondary;
|
|
179
|
+
}
|
|
118
180
|
}
|
|
119
181
|
|
|
120
|
-
|
|
182
|
+
/* Variant: Ghost - just color change, no indicator */
|
|
183
|
+
&.is-ghost {
|
|
121
184
|
.bottomnav-item.is-active {
|
|
122
|
-
@apply
|
|
185
|
+
@apply text-on-surface;
|
|
123
186
|
|
|
124
187
|
.bottomnav-icon {
|
|
125
|
-
@apply text-on-
|
|
188
|
+
@apply text-on-surface;
|
|
126
189
|
}
|
|
127
190
|
|
|
128
191
|
.bottomnav-label {
|
|
129
|
-
@apply text-on-
|
|
192
|
+
@apply text-on-surface font-semibold;
|
|
130
193
|
}
|
|
131
194
|
}
|
|
132
195
|
}
|
|
196
|
+
|
|
197
|
+
/* Variant: Line - underline indicator */
|
|
198
|
+
&.is-line {
|
|
199
|
+
.bottomnav-item {
|
|
200
|
+
&::after {
|
|
201
|
+
content: '';
|
|
202
|
+
@apply absolute bottom-0 left-1/2 -translate-x-1/2;
|
|
203
|
+
@apply w-0 h-0.5 rounded-full;
|
|
204
|
+
@apply bg-primary;
|
|
205
|
+
@apply transition-all duration-200;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
&.is-active {
|
|
209
|
+
@apply text-primary;
|
|
210
|
+
|
|
211
|
+
.bottomnav-icon {
|
|
212
|
+
@apply text-primary;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.bottomnav-label {
|
|
216
|
+
@apply text-primary;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
&::after {
|
|
220
|
+
@apply w-8;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* Solid modifier - adds background pill on active */
|
|
227
|
+
&.is-solid {
|
|
228
|
+
.bottomnav-item {
|
|
229
|
+
@apply relative isolate;
|
|
230
|
+
|
|
231
|
+
&::before {
|
|
232
|
+
content: '';
|
|
233
|
+
@apply absolute inset-x-2 top-1 bottom-1;
|
|
234
|
+
@apply rounded-xl;
|
|
235
|
+
@apply bg-transparent;
|
|
236
|
+
@apply transition-all duration-200;
|
|
237
|
+
z-index: -1;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
&.is-primary .bottomnav-item.is-active:not(.is-fab)::before {
|
|
242
|
+
@apply bg-primary/10;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
&.is-secondary .bottomnav-item.is-active:not(.is-fab)::before {
|
|
246
|
+
@apply bg-secondary/10;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
&.is-ghost .bottomnav-item.is-active:not(.is-fab)::before {
|
|
250
|
+
@apply bg-muted;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
&.is-line .bottomnav-item.is-active:not(.is-fab)::before {
|
|
254
|
+
@apply bg-primary/10;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
133
257
|
}
|
|
134
258
|
}
|