@sybilion/uilib 1.2.5 → 1.2.8
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/assets/standalone-global.css +12 -11
- package/dist/esm/components/ui/AppHeader/AppHeader.styl.js +1 -1
- package/dist/esm/components/ui/Logo/Logo.js +7 -2
- package/dist/esm/components/ui/Logo/Logo.styl.js +1 -1
- package/dist/esm/components/ui/NavUserHeader/NavUserHeader.js +4 -2
- package/dist/esm/components/ui/Sidebar/Sidebar.styl.js +1 -1
- package/dist/esm/components/widgets/SybilionAppHeader/SybilionAppHeader.js +4 -2
- package/dist/esm/components/widgets/SybilionAppHeader/SybilionAppHeader.styl.js +2 -2
- package/dist/esm/docs/contexts/theme-context.js +14 -0
- package/dist/esm/docs/lib/theme.js +23 -0
- package/dist/esm/types/src/components/ui/Logo/Logo.d.ts +5 -0
- package/dist/esm/types/src/components/ui/NavUserHeader/NavUserHeader.d.ts +1 -1
- package/dist/esm/types/src/components/ui/NavUserHeader/NavUserHeader.types.d.ts +0 -4
- package/dist/esm/types/src/components/widgets/SybilionAppHeader/SybilionAppHeader.d.ts +7 -1
- package/dist/esm/types/src/docs/contexts/theme-context.d.ts +1 -0
- package/dist/esm/types/src/docs/pages/StandaloneAppLayoutPage/StandaloneAppLayoutPage.constants.d.ts +7 -0
- package/docs/standalone-apps.md +111 -12
- package/package.json +3 -2
- package/src/assets/logo.svg +3 -0
- package/src/components/ui/AppHeader/AppHeader.styl +5 -0
- package/src/components/ui/Logo/Logo.styl +2 -0
- package/src/components/ui/Logo/Logo.tsx +12 -1
- package/src/components/ui/NavUserHeader/NavUserHeader.tsx +15 -17
- package/src/components/ui/NavUserHeader/NavUserHeader.types.ts +0 -4
- package/src/components/ui/Sidebar/Sidebar.styl +1 -1
- package/src/components/widgets/SybilionAppHeader/SybilionAppHeader.styl +46 -0
- package/src/components/widgets/SybilionAppHeader/SybilionAppHeader.styl.d.ts +3 -0
- package/src/components/widgets/SybilionAppHeader/SybilionAppHeader.tsx +23 -0
- package/src/docs/config/webpack.config.js +4 -3
- package/src/docs/contexts/theme-context.tsx +14 -1
- package/src/docs/pages/NavUserHeaderPage.tsx +1 -20
- package/src/docs/pages/StandaloneAppLayoutPage/StandaloneAppLayoutPage.constants.ts +444 -0
- package/src/docs/pages/{StandaloneAppLayoutPage.styl → StandaloneAppLayoutPage/StandaloneAppLayoutPage.styl} +11 -21
- package/src/docs/pages/{StandaloneAppLayoutPage.styl.d.ts → StandaloneAppLayoutPage/StandaloneAppLayoutPage.styl.d.ts} +1 -0
- package/src/docs/pages/{StandaloneAppLayoutPage.tsx → StandaloneAppLayoutPage/StandaloneAppLayoutPage.tsx} +18 -116
- package/src/docs/registry.ts +2 -1
- /package/dist/esm/types/src/docs/pages/{StandaloneAppLayoutPage.d.ts → StandaloneAppLayoutPage/StandaloneAppLayoutPage.d.ts} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import cn from 'classnames';
|
|
2
2
|
|
|
3
|
+
import { useTheme } from '#uilib/docs/contexts/theme-context';
|
|
3
4
|
import {
|
|
4
5
|
MoonIcon,
|
|
5
6
|
SignOutIcon,
|
|
@@ -29,12 +30,11 @@ export function NavUserHeader({
|
|
|
29
30
|
isAuthenticated,
|
|
30
31
|
user = null,
|
|
31
32
|
menuItems,
|
|
32
|
-
theme,
|
|
33
|
-
onThemeToggle,
|
|
34
33
|
onLogout,
|
|
35
34
|
signInSlot,
|
|
36
35
|
onSignInClick,
|
|
37
36
|
}: NavUserHeaderProps) {
|
|
37
|
+
const { toggleTheme, theme } = useTheme();
|
|
38
38
|
const authenticated = isAuthenticated ?? true;
|
|
39
39
|
|
|
40
40
|
const avatarUrl = user?.avatar ?? '';
|
|
@@ -121,21 +121,19 @@ export function NavUserHeader({
|
|
|
121
121
|
<DropdownMenuSeparator />
|
|
122
122
|
<DropdownMenuGroup>
|
|
123
123
|
{menuItems}
|
|
124
|
-
{
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
</DropdownMenuItem>
|
|
138
|
-
) : null}
|
|
124
|
+
<DropdownMenuItem onSelect={toggleTheme}>
|
|
125
|
+
{theme === 'dark' ? (
|
|
126
|
+
<>
|
|
127
|
+
<SunIcon />
|
|
128
|
+
Light theme
|
|
129
|
+
</>
|
|
130
|
+
) : (
|
|
131
|
+
<>
|
|
132
|
+
<MoonIcon />
|
|
133
|
+
Dark theme
|
|
134
|
+
</>
|
|
135
|
+
)}
|
|
136
|
+
</DropdownMenuItem>
|
|
139
137
|
</DropdownMenuGroup>
|
|
140
138
|
<DropdownMenuSeparator />
|
|
141
139
|
<DropdownMenuItem variant="destructive" onSelect={() => onLogout()}>
|
|
@@ -16,10 +16,6 @@ export type NavUserHeaderProps = {
|
|
|
16
16
|
user?: NavUserHeaderUser | null;
|
|
17
17
|
/** Rows inside the menu above theme toggle and logout. Use `DropdownMenuItem` nodes. */
|
|
18
18
|
menuItems?: ReactNode;
|
|
19
|
-
/** Current theme drives the toggle row label/icons. */
|
|
20
|
-
theme: 'light' | 'dark';
|
|
21
|
-
/** When set, renders the light/dark theme menu row. */
|
|
22
|
-
onThemeToggle?: () => void;
|
|
23
19
|
onLogout: () => void;
|
|
24
20
|
/** Replaces default “Log in” control when signed out. */
|
|
25
21
|
signInSlot?: ReactNode;
|
|
@@ -5,3 +5,49 @@
|
|
|
5
5
|
align-items center
|
|
6
6
|
gap var(--p-4)
|
|
7
7
|
flex-shrink 0
|
|
8
|
+
|
|
9
|
+
.logoArea
|
|
10
|
+
position absolute
|
|
11
|
+
top 22px
|
|
12
|
+
left 40px
|
|
13
|
+
z-index 10
|
|
14
|
+
|
|
15
|
+
display flex
|
|
16
|
+
align-items center
|
|
17
|
+
gap var(--p-2)
|
|
18
|
+
|
|
19
|
+
@media (max-width MOBILE)
|
|
20
|
+
left 32px
|
|
21
|
+
@media (min-width MOBILE)
|
|
22
|
+
:global([data-slot='sidebar-wrapper'][data-state='expanded']) &
|
|
23
|
+
position fixed
|
|
24
|
+
|
|
25
|
+
.logoAreaWithBanner
|
|
26
|
+
top calc(22px + var(--welcome-banner-height, 0px))
|
|
27
|
+
|
|
28
|
+
@media (min-width MOBILE)
|
|
29
|
+
:global([data-slot='sidebar-wrapper'][data-state='collapsed']) &
|
|
30
|
+
top 22px
|
|
31
|
+
|
|
32
|
+
.logoLink
|
|
33
|
+
display flex
|
|
34
|
+
align-items center
|
|
35
|
+
gap 0.5rem
|
|
36
|
+
width fit-content
|
|
37
|
+
|
|
38
|
+
font-weight 400
|
|
39
|
+
font-size 1.5rem
|
|
40
|
+
color var(--color-foreground)
|
|
41
|
+
text-decoration none
|
|
42
|
+
white-space nowrap
|
|
43
|
+
|
|
44
|
+
svg
|
|
45
|
+
display inline-flex
|
|
46
|
+
height 32px
|
|
47
|
+
width auto
|
|
48
|
+
flex-shrink 0
|
|
49
|
+
transition transform 0.1s ease-in-out
|
|
50
|
+
|
|
51
|
+
&:hover svg
|
|
52
|
+
transform scale(1.05)
|
|
53
|
+
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import cn from 'classnames';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
2
4
|
|
|
3
5
|
import { AppHeaderPortal } from '#uilib/components/ui/AppHeader/AppHeader';
|
|
4
6
|
import { PAGE_HEADER_ACTIONS_ID } from '#uilib/components/ui/AppHeader/appChromeAnchors';
|
|
5
7
|
import { Gap } from '#uilib/components/ui/Gap/Gap';
|
|
8
|
+
import { Logo } from '#uilib/components/ui/Logo/Logo';
|
|
6
9
|
import { NavUserHeader } from '#uilib/components/ui/NavUserHeader';
|
|
7
10
|
import type { NavUserHeaderProps } from '#uilib/components/ui/NavUserHeader';
|
|
8
11
|
import {
|
|
@@ -17,6 +20,11 @@ export type SybilionAppHeaderProps = WorkspaceAppSwitcherProps &
|
|
|
17
20
|
pageHeaderId?: string;
|
|
18
21
|
actionsAnchorId?: string;
|
|
19
22
|
actionsAnchorClassName?: string;
|
|
23
|
+
/** Branded markup; omit for default lucide tile + «Sybilion». */
|
|
24
|
+
logo?: ReactNode;
|
|
25
|
+
logoAreaClassName?: string;
|
|
26
|
+
/** Applies vertical offset when a welcome banner consumes top space (CSS `--welcome-banner-height` on shell). */
|
|
27
|
+
welcomeBannerOffset?: boolean;
|
|
20
28
|
};
|
|
21
29
|
|
|
22
30
|
export function SybilionAppHeader({
|
|
@@ -28,10 +36,25 @@ export function SybilionAppHeader({
|
|
|
28
36
|
authenticated,
|
|
29
37
|
defaultApps,
|
|
30
38
|
appsStorageKey,
|
|
39
|
+
logo,
|
|
40
|
+
logoAreaClassName,
|
|
41
|
+
welcomeBannerOffset,
|
|
31
42
|
...navUserHeaderProps
|
|
32
43
|
}: SybilionAppHeaderProps) {
|
|
33
44
|
return (
|
|
34
45
|
<AppHeaderPortal pageHeaderId={pageHeaderId}>
|
|
46
|
+
<div
|
|
47
|
+
className={cn(
|
|
48
|
+
S.logoArea,
|
|
49
|
+
welcomeBannerOffset && S.logoAreaWithBanner,
|
|
50
|
+
logoAreaClassName,
|
|
51
|
+
)}
|
|
52
|
+
>
|
|
53
|
+
<Link to="/" className={S.logoLink}>
|
|
54
|
+
{logo ?? <Logo size="md" aria-hidden />}
|
|
55
|
+
</Link>
|
|
56
|
+
</div>
|
|
57
|
+
|
|
35
58
|
<WorkspaceAppSwitcher
|
|
36
59
|
pathname={pathname}
|
|
37
60
|
onNavigate={onNavigate}
|
|
@@ -20,6 +20,7 @@ const FaviconWebpackPlugin = require('favicons-webpack-plugin');
|
|
|
20
20
|
const pkg = require('../../../package.json');
|
|
21
21
|
|
|
22
22
|
const themeStyl = pathResolve(paths.src, 'theme.styl');
|
|
23
|
+
const logoSvgPath = pathResolve(paths.assets, 'logo.svg');
|
|
23
24
|
|
|
24
25
|
export default (env, argv) => {
|
|
25
26
|
const isDev = argv.mode === 'development';
|
|
@@ -148,7 +149,7 @@ export default (env, argv) => {
|
|
|
148
149
|
noErrorOnMissing: true,
|
|
149
150
|
},
|
|
150
151
|
{
|
|
151
|
-
from:
|
|
152
|
+
from: logoSvgPath,
|
|
152
153
|
to: paths.build,
|
|
153
154
|
noErrorOnMissing: true,
|
|
154
155
|
},
|
|
@@ -175,9 +176,9 @@ export default (env, argv) => {
|
|
|
175
176
|
minifyURLs: true,
|
|
176
177
|
},
|
|
177
178
|
}),
|
|
178
|
-
existsSync(
|
|
179
|
+
existsSync(logoSvgPath) &&
|
|
179
180
|
new FaviconWebpackPlugin({
|
|
180
|
-
logo:
|
|
181
|
+
logo: logoSvgPath,
|
|
181
182
|
mode: 'webapp',
|
|
182
183
|
devMode: 'webapp',
|
|
183
184
|
favicons: {
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useCallback,
|
|
4
|
+
useContext,
|
|
5
|
+
useEffect,
|
|
6
|
+
useState,
|
|
7
|
+
} from 'react';
|
|
2
8
|
|
|
3
9
|
import { Theme as ThemeRoot } from '@homecode/ui';
|
|
4
10
|
|
|
@@ -10,10 +16,12 @@ const ThemeContext = createContext<{
|
|
|
10
16
|
theme: ThemeMode;
|
|
11
17
|
isDarkMode: boolean;
|
|
12
18
|
setTheme: (theme: ThemeMode) => void;
|
|
19
|
+
toggleTheme: () => void;
|
|
13
20
|
}>({
|
|
14
21
|
theme: 'light',
|
|
15
22
|
isDarkMode: false,
|
|
16
23
|
setTheme: () => {},
|
|
24
|
+
toggleTheme: () => {},
|
|
17
25
|
});
|
|
18
26
|
|
|
19
27
|
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
|
@@ -25,6 +33,10 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
|
|
25
33
|
getThemeConfig(theme === 'dark'),
|
|
26
34
|
);
|
|
27
35
|
|
|
36
|
+
const toggleTheme = useCallback(() => {
|
|
37
|
+
setTheme(theme === 'dark' ? 'light' : 'dark');
|
|
38
|
+
}, [theme, setTheme]);
|
|
39
|
+
|
|
28
40
|
useEffect(() => {
|
|
29
41
|
setCurrThemeConfig(getThemeConfig(theme === 'dark'));
|
|
30
42
|
}, [theme]);
|
|
@@ -44,6 +56,7 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
|
|
44
56
|
theme,
|
|
45
57
|
isDarkMode: theme === 'dark',
|
|
46
58
|
setTheme,
|
|
59
|
+
toggleTheme,
|
|
47
60
|
}}
|
|
48
61
|
>
|
|
49
62
|
<ThemeRoot config={currThemeConfig} />
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
1
|
import { DropdownMenuItem } from '#uilib/components/ui/DropdownMenu';
|
|
4
2
|
import { NavUserHeader } from '#uilib/components/ui/NavUserHeader';
|
|
5
3
|
import { PageContentSection } from '#uilib/components/ui/Page';
|
|
@@ -9,19 +7,6 @@ import { AppPageHeader } from '../components/AppPageHeader/AppPageHeader';
|
|
|
9
7
|
import { DocsHeaderActions } from '../docsHeaderActions';
|
|
10
8
|
|
|
11
9
|
export default function NavUserHeaderPage() {
|
|
12
|
-
const [theme, setTheme] = useState<'light' | 'dark'>('light');
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
document.documentElement.dataset.theme = theme;
|
|
16
|
-
return () => {
|
|
17
|
-
delete document.documentElement.dataset.theme;
|
|
18
|
-
};
|
|
19
|
-
}, [theme]);
|
|
20
|
-
|
|
21
|
-
const onThemeToggle = useCallback(() => {
|
|
22
|
-
setTheme(t => (t === 'dark' ? 'light' : 'dark'));
|
|
23
|
-
}, []);
|
|
24
|
-
|
|
25
10
|
const customMenuItems = (
|
|
26
11
|
<>
|
|
27
12
|
<DropdownMenuItem>
|
|
@@ -40,7 +25,7 @@ export default function NavUserHeaderPage() {
|
|
|
40
25
|
<AppPageHeader
|
|
41
26
|
breadcrumbs={[{ label: 'NavUserHeader' }]}
|
|
42
27
|
title="NavUserHeader"
|
|
43
|
-
subheader="User menu with label, custom rows, theme toggle, and logout."
|
|
28
|
+
subheader="User menu with label, custom rows, theme toggle (docs ThemeProvider), and logout."
|
|
44
29
|
actions={<DocsHeaderActions />}
|
|
45
30
|
/>
|
|
46
31
|
<PageContentSection
|
|
@@ -56,8 +41,6 @@ export default function NavUserHeaderPage() {
|
|
|
56
41
|
email: 'demo@sybilion.io',
|
|
57
42
|
avatar: '',
|
|
58
43
|
}}
|
|
59
|
-
theme={theme}
|
|
60
|
-
onThemeToggle={onThemeToggle}
|
|
61
44
|
onLogout={() => {
|
|
62
45
|
console.info('[docs] logout');
|
|
63
46
|
}}
|
|
@@ -75,8 +58,6 @@ export default function NavUserHeaderPage() {
|
|
|
75
58
|
email: 'compact@sybilion.io',
|
|
76
59
|
avatar: '',
|
|
77
60
|
}}
|
|
78
|
-
theme={theme}
|
|
79
|
-
onThemeToggle={onThemeToggle}
|
|
80
61
|
onLogout={() => {
|
|
81
62
|
console.info('[docs] logout compact');
|
|
82
63
|
}}
|