@sybilion/uilib 1.0.26 → 1.0.27
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/mini-app-global.css +12 -12
- package/dist/esm/index.js +1 -0
- package/dist/esm/mini-app/MiniAppRoot.js +9 -5
- package/dist/esm/mini-app/miniAppThemeConfig.js +40 -0
- package/dist/esm/types/src/mini-app/MiniAppRoot.d.ts +4 -1
- package/dist/esm/types/src/mini-app/index.d.ts +4 -2
- package/dist/esm/types/src/mini-app/miniAppThemeConfig.d.ts +3 -0
- package/docs/workspace-mini-apps.md +3 -1
- package/package.json +1 -1
- package/src/docs/pages/MiniAppRootPage.tsx +6 -1
- package/src/mini-app/MiniAppRoot.tsx +19 -1
- package/src/mini-app/index.ts +4 -8
- package/src/mini-app/miniAppThemeConfig.ts +45 -0
|
@@ -139,12 +139,12 @@
|
|
|
139
139
|
--header-height: 94px;
|
|
140
140
|
--page-x-padding: var(--p-16);
|
|
141
141
|
--page-y-padding: var(--p-12);
|
|
142
|
-
--page-color:
|
|
143
|
-
--page-color-alpha-800:
|
|
144
|
-
--background:
|
|
145
|
-
--background-alpha-800: oklch(
|
|
146
|
-
--background-alpha-700: oklch(
|
|
147
|
-
--background-alpha-500: oklch(
|
|
142
|
+
--page-color: var(--sb-slate-100);
|
|
143
|
+
--page-color-alpha-800: var(--sb-slate-100);
|
|
144
|
+
--background: oklch(1 0 0);
|
|
145
|
+
--background-alpha-800: oklch(0.99 0 0 / 0.8);
|
|
146
|
+
--background-alpha-700: oklch(0.99 0 0 / 0.7);
|
|
147
|
+
--background-alpha-500: oklch(0.99 0 0 / 0.5);
|
|
148
148
|
--foreground: oklch(0.15 0 0);
|
|
149
149
|
--card: oklch(1 0 0);
|
|
150
150
|
--card-foreground: oklch(0.15 0 0);
|
|
@@ -196,12 +196,12 @@
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
.dark {
|
|
199
|
-
--page-color: oklch(0.
|
|
200
|
-
--page-color-alpha-800: oklch(
|
|
201
|
-
--background: oklch(0.
|
|
202
|
-
--background-alpha-800: oklch(
|
|
203
|
-
--background-alpha-700: oklch(
|
|
204
|
-
--background-alpha-500: oklch(
|
|
199
|
+
--page-color: oklch(0.22 0 0);
|
|
200
|
+
--page-color-alpha-800: oklch(0.2242 0 0 / 0.8);
|
|
201
|
+
--background: oklch(0.14 0 0);
|
|
202
|
+
--background-alpha-800: oklch(0.14 0 0 / 0.95);
|
|
203
|
+
--background-alpha-700: oklch(0.14 0 0 / 0.7);
|
|
204
|
+
--background-alpha-500: oklch(0.14 0 0 / 0.5);
|
|
205
205
|
--foreground: oklch(0.95 0 0);
|
|
206
206
|
--card: oklch(0.1 0 0);
|
|
207
207
|
--card-foreground: oklch(0.95 0 0);
|
package/dist/esm/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { MINIAPP_CHANNEL, MINIAPP_VERSION, applyThemeToDocument, buildReadyMessage, parseThemeSyncMessage, resolveParentOriginFromReferrer } from './mini-app/miniAppProtocol.js';
|
|
2
|
+
export { getDefaultMiniAppThemeConfig } from './mini-app/miniAppThemeConfig.js';
|
|
2
3
|
export { MiniAppRoot, useMiniAppShellTheme } from './mini-app/MiniAppRoot.js';
|
|
3
4
|
export { ChatContext, ChatProvider, useChat, useChats, useChatsForDataset, useChatsForScopeId, useCurrentChat } from './contexts/chat-context.js';
|
|
4
5
|
export { AnalysesSelector } from './components/ui/AnalysesSelector/AnalysesSelector.js';
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { jsx } from 'react/jsx-runtime';
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import cn from 'classnames';
|
|
3
|
-
import { createContext, useContext, useState, useRef, useCallback, useEffect
|
|
4
|
-
import { Scroll } from '@homecode/ui';
|
|
3
|
+
import { createContext, useContext, useState, useRef, useMemo, useCallback, useEffect } from 'react';
|
|
4
|
+
import { Theme, Scroll } from '@homecode/ui';
|
|
5
5
|
import S from './MiniAppRoot.styl.js';
|
|
6
6
|
import { resolveParentOriginFromReferrer, applyThemeToDocument, buildReadyMessage, parseThemeSyncMessage } from './miniAppProtocol.js';
|
|
7
|
+
import { getDefaultMiniAppThemeConfig } from './miniAppThemeConfig.js';
|
|
7
8
|
|
|
8
9
|
const defaultTheme = {
|
|
9
10
|
mode: 'light',
|
|
@@ -45,10 +46,13 @@ function isTrustedParentMessage(event) {
|
|
|
45
46
|
return false;
|
|
46
47
|
return true;
|
|
47
48
|
}
|
|
48
|
-
function MiniAppRoot({ children, className, appId, onThemeChange, }) {
|
|
49
|
+
function MiniAppRoot({ children, className, appId, onThemeChange, getThemeConfig, }) {
|
|
49
50
|
const [theme, setTheme] = useState(() => isEmbeddedMiniApp() ? defaultTheme : themeFromDocument());
|
|
50
51
|
const onThemeChangeRef = useRef(onThemeChange);
|
|
51
52
|
onThemeChangeRef.current = onThemeChange;
|
|
53
|
+
const getThemeConfigRef = useRef(getThemeConfig ?? getDefaultMiniAppThemeConfig);
|
|
54
|
+
getThemeConfigRef.current = getThemeConfig ?? getDefaultMiniAppThemeConfig;
|
|
55
|
+
const currThemeConfig = useMemo(() => getThemeConfigRef.current(theme.isDarkMode), [theme.isDarkMode]);
|
|
52
56
|
const sendReady = useCallback(() => {
|
|
53
57
|
if (!window.parent || window.parent === window)
|
|
54
58
|
return;
|
|
@@ -88,7 +92,7 @@ function MiniAppRoot({ children, className, appId, onThemeChange, }) {
|
|
|
88
92
|
return () => window.removeEventListener('load', sendReady);
|
|
89
93
|
}, [sendReady]);
|
|
90
94
|
const ctx = useMemo(() => ({ theme }), [theme]);
|
|
91
|
-
return (
|
|
95
|
+
return (jsxs(MiniAppShellContext.Provider, { value: ctx, children: [jsx(Theme, { config: currThemeConfig }), jsx(Scroll, { y: true, fadeSize: "l", className: cn(S.root, className), innerClassName: S.inner, offset: { y: { before: 50, after: 50 } }, autoHide: true, children: children })] }));
|
|
92
96
|
}
|
|
93
97
|
|
|
94
98
|
export { MiniAppRoot, useMiniAppShellTheme };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ThemeHelpers, ThemeDefaults } from '@homecode/ui';
|
|
2
|
+
|
|
3
|
+
const { colors, getColors, getConfig } = ThemeDefaults;
|
|
4
|
+
const defaultPalette = getColors();
|
|
5
|
+
const colorsConfig = {
|
|
6
|
+
light: {
|
|
7
|
+
...ThemeHelpers.colorsConfigToVars({
|
|
8
|
+
...getColors({
|
|
9
|
+
accent: colors.dark,
|
|
10
|
+
decent: colors.light,
|
|
11
|
+
}),
|
|
12
|
+
}),
|
|
13
|
+
},
|
|
14
|
+
dark: {
|
|
15
|
+
...ThemeHelpers.colorsConfigToVars({
|
|
16
|
+
...getColors({
|
|
17
|
+
accent: colors.light,
|
|
18
|
+
decent: colors.dark,
|
|
19
|
+
}),
|
|
20
|
+
}),
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
/** Homecode `<Theme config={...}>` shape for workspace mini-apps (generic palette). */
|
|
24
|
+
function getDefaultMiniAppThemeConfig(isDarkMode) {
|
|
25
|
+
return {
|
|
26
|
+
...getConfig(),
|
|
27
|
+
...colorsConfig[isDarkMode ? 'dark' : 'light'],
|
|
28
|
+
...ThemeHelpers.colorsConfigToVars({
|
|
29
|
+
active: {
|
|
30
|
+
color: '#00a9c7',
|
|
31
|
+
mods: {
|
|
32
|
+
// @ts-ignore — extend defaults so --active-color-alpha-* variants match Homecode
|
|
33
|
+
alpha: [0, 50, 100, 200, ...defaultPalette.active.mods.alpha],
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { getDefaultMiniAppThemeConfig };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { type ThemeSyncPayload } from './miniAppProtocol';
|
|
4
|
+
import { type MiniAppThemeConfig } from './miniAppThemeConfig';
|
|
4
5
|
export type MiniAppShellContextValue = {
|
|
5
6
|
theme: ThemeSyncPayload;
|
|
6
7
|
};
|
|
@@ -11,5 +12,7 @@ export type MiniAppRootProps = {
|
|
|
11
12
|
/** Included in READY payload when set. */
|
|
12
13
|
appId?: string;
|
|
13
14
|
onThemeChange?: (theme: ThemeSyncPayload) => void;
|
|
15
|
+
/** Overrides `@homecode/ui` `<Theme config>` builder (defaults to generic mini-app palette). */
|
|
16
|
+
getThemeConfig?: (isDarkMode: boolean) => MiniAppThemeConfig;
|
|
14
17
|
};
|
|
15
|
-
export declare function MiniAppRoot({ children, className, appId, onThemeChange, }: MiniAppRootProps): React.ReactElement;
|
|
18
|
+
export declare function MiniAppRoot({ children, className, appId, onThemeChange, getThemeConfig, }: MiniAppRootProps): React.ReactElement;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { applyThemeToDocument, buildReadyMessage, MINIAPP_CHANNEL, MINIAPP_VERSION, parseThemeSyncMessage, resolveParentOriginFromReferrer, } from './miniAppProtocol';
|
|
2
2
|
export type { MiniAppMessageReady, MiniAppMessageThemeSync, ThemeSyncPayload, } from './miniAppProtocol';
|
|
3
|
-
export {
|
|
4
|
-
export type {
|
|
3
|
+
export { getDefaultMiniAppThemeConfig } from './miniAppThemeConfig';
|
|
4
|
+
export type { MiniAppThemeConfig } from './miniAppThemeConfig';
|
|
5
|
+
export { MiniAppRoot, useMiniAppShellTheme } from './MiniAppRoot';
|
|
6
|
+
export type { MiniAppRootProps, MiniAppShellContextValue } from './MiniAppRoot';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Workspace mini-apps (Sybilion iframe)
|
|
2
2
|
|
|
3
|
-
The Sybilion client embeds mini-apps in an **iframe** and syncs theme with `postMessage`. Use **`MiniAppRoot`** so this document’s `<html>` gets **`light` / `dark`** (uilib uses `.dark { … }` for tokens).
|
|
3
|
+
The Sybilion client embeds mini-apps in an **iframe** and syncs theme with `postMessage`. Use **`MiniAppRoot`** so this document’s `<html>` gets **`light` / `dark`** (uilib uses `.dark { … }` for tokens), and so **`@homecode/ui`’s `<Theme />`** runs with vars matching that mode (`getDefaultMiniAppThemeConfig`; override via props if needed).
|
|
4
4
|
|
|
5
5
|
1. Import **`@sybilion/uilib/mini-app-global.css`** (slim tokens + font imports; ships in this package).
|
|
6
6
|
2. Wrap the React root:
|
|
@@ -18,4 +18,6 @@ createRoot(document.getElementById('root')!).render(
|
|
|
18
18
|
|
|
19
19
|
3. Optional: **`useMiniAppShellTheme()`** for **`{ theme: { mode, isDarkMode } }`** under the provider (object leaves room for more shell fields later).
|
|
20
20
|
|
|
21
|
+
4. Optional: **`getThemeConfig`** on **`MiniAppRoot`** — passed **`(isDarkMode) => config`** like the Sybilion app’s **`getThemeConfig`** from **`src/lib/theme.ts`**, so iframe UI matches host accent/danger tokens.
|
|
22
|
+
|
|
21
23
|
**Bridge:** `MiniAppRoot` handles `THEME_SYNC`, sends `READY` on mount/load, and checks `event.source === window.parent` plus `document.referrer` origin when present. If the referrer is missing (strict `Referrer-Policy`), `READY` may use `targetOrigin` `*` — document that for your host.
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PageContentSection } from '#uilib/components/ui/Page';
|
|
2
|
+
import { getThemeConfig } from '#uilib/docs/lib/theme';
|
|
2
3
|
import { MiniAppRoot, useMiniAppShellTheme } from '#uilib/mini-app';
|
|
3
4
|
|
|
4
5
|
import { AppPageHeader } from '../components/AppPageHeader/AppPageHeader';
|
|
@@ -44,7 +45,11 @@ export default function MiniAppRootPage() {
|
|
|
44
45
|
}
|
|
45
46
|
`}</style>
|
|
46
47
|
<PageContentSection style={{ maxHeight: '500px' }}>
|
|
47
|
-
<MiniAppRoot
|
|
48
|
+
<MiniAppRoot
|
|
49
|
+
appId="uilib-docs"
|
|
50
|
+
className="mini-app-root-page"
|
|
51
|
+
getThemeConfig={isDarkMode => getThemeConfig(isDarkMode)}
|
|
52
|
+
>
|
|
48
53
|
<MiniAppThemeDemo />
|
|
49
54
|
</MiniAppRoot>
|
|
50
55
|
</PageContentSection>
|
|
@@ -10,7 +10,7 @@ import React, {
|
|
|
10
10
|
useState,
|
|
11
11
|
} from 'react';
|
|
12
12
|
|
|
13
|
-
import { Scroll } from '@homecode/ui';
|
|
13
|
+
import { Scroll, Theme } from '@homecode/ui';
|
|
14
14
|
|
|
15
15
|
import S from './MiniAppRoot.styl';
|
|
16
16
|
import {
|
|
@@ -20,6 +20,10 @@ import {
|
|
|
20
20
|
parseThemeSyncMessage,
|
|
21
21
|
resolveParentOriginFromReferrer,
|
|
22
22
|
} from './miniAppProtocol';
|
|
23
|
+
import {
|
|
24
|
+
type MiniAppThemeConfig,
|
|
25
|
+
getDefaultMiniAppThemeConfig,
|
|
26
|
+
} from './miniAppThemeConfig';
|
|
23
27
|
|
|
24
28
|
const defaultTheme: ThemeSyncPayload = {
|
|
25
29
|
mode: 'light',
|
|
@@ -76,6 +80,8 @@ export type MiniAppRootProps = {
|
|
|
76
80
|
/** Included in READY payload when set. */
|
|
77
81
|
appId?: string;
|
|
78
82
|
onThemeChange?: (theme: ThemeSyncPayload) => void;
|
|
83
|
+
/** Overrides `@homecode/ui` `<Theme config>` builder (defaults to generic mini-app palette). */
|
|
84
|
+
getThemeConfig?: (isDarkMode: boolean) => MiniAppThemeConfig;
|
|
79
85
|
};
|
|
80
86
|
|
|
81
87
|
export function MiniAppRoot({
|
|
@@ -83,6 +89,7 @@ export function MiniAppRoot({
|
|
|
83
89
|
className,
|
|
84
90
|
appId,
|
|
85
91
|
onThemeChange,
|
|
92
|
+
getThemeConfig,
|
|
86
93
|
}: MiniAppRootProps): React.ReactElement {
|
|
87
94
|
const [theme, setTheme] = useState<ThemeSyncPayload>(() =>
|
|
88
95
|
isEmbeddedMiniApp() ? defaultTheme : themeFromDocument(),
|
|
@@ -90,6 +97,16 @@ export function MiniAppRoot({
|
|
|
90
97
|
const onThemeChangeRef = useRef(onThemeChange);
|
|
91
98
|
onThemeChangeRef.current = onThemeChange;
|
|
92
99
|
|
|
100
|
+
const getThemeConfigRef = useRef(
|
|
101
|
+
getThemeConfig ?? getDefaultMiniAppThemeConfig,
|
|
102
|
+
);
|
|
103
|
+
getThemeConfigRef.current = getThemeConfig ?? getDefaultMiniAppThemeConfig;
|
|
104
|
+
|
|
105
|
+
const currThemeConfig = useMemo(
|
|
106
|
+
() => getThemeConfigRef.current(theme.isDarkMode),
|
|
107
|
+
[theme.isDarkMode],
|
|
108
|
+
);
|
|
109
|
+
|
|
93
110
|
const sendReady = useCallback(() => {
|
|
94
111
|
if (!window.parent || window.parent === window) return;
|
|
95
112
|
const payload = appId ? { appId } : {};
|
|
@@ -131,6 +148,7 @@ export function MiniAppRoot({
|
|
|
131
148
|
|
|
132
149
|
return (
|
|
133
150
|
<MiniAppShellContext.Provider value={ctx}>
|
|
151
|
+
<Theme config={currThemeConfig} />
|
|
134
152
|
<Scroll
|
|
135
153
|
y
|
|
136
154
|
fadeSize="l"
|
package/src/mini-app/index.ts
CHANGED
|
@@ -11,11 +11,7 @@ export type {
|
|
|
11
11
|
MiniAppMessageThemeSync,
|
|
12
12
|
ThemeSyncPayload,
|
|
13
13
|
} from './miniAppProtocol';
|
|
14
|
-
export {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} from './MiniAppRoot';
|
|
18
|
-
export type {
|
|
19
|
-
MiniAppRootProps,
|
|
20
|
-
MiniAppShellContextValue,
|
|
21
|
-
} from './MiniAppRoot';
|
|
14
|
+
export { getDefaultMiniAppThemeConfig } from './miniAppThemeConfig';
|
|
15
|
+
export type { MiniAppThemeConfig } from './miniAppThemeConfig';
|
|
16
|
+
export { MiniAppRoot, useMiniAppShellTheme } from './MiniAppRoot';
|
|
17
|
+
export type { MiniAppRootProps, MiniAppShellContextValue } from './MiniAppRoot';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ThemeDefaults, ThemeHelpers } from '@homecode/ui';
|
|
2
|
+
|
|
3
|
+
const { colors, getColors, getConfig } = ThemeDefaults;
|
|
4
|
+
|
|
5
|
+
const defaultPalette = getColors();
|
|
6
|
+
|
|
7
|
+
const colorsConfig = {
|
|
8
|
+
light: {
|
|
9
|
+
...ThemeHelpers.colorsConfigToVars({
|
|
10
|
+
...getColors({
|
|
11
|
+
accent: colors.dark,
|
|
12
|
+
decent: colors.light,
|
|
13
|
+
}),
|
|
14
|
+
}),
|
|
15
|
+
},
|
|
16
|
+
dark: {
|
|
17
|
+
...ThemeHelpers.colorsConfigToVars({
|
|
18
|
+
...getColors({
|
|
19
|
+
accent: colors.light,
|
|
20
|
+
decent: colors.dark,
|
|
21
|
+
}),
|
|
22
|
+
}),
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** Homecode `<Theme config={...}>` shape for workspace mini-apps (generic palette). */
|
|
27
|
+
export function getDefaultMiniAppThemeConfig(isDarkMode: boolean) {
|
|
28
|
+
return {
|
|
29
|
+
...getConfig(),
|
|
30
|
+
...colorsConfig[isDarkMode ? 'dark' : 'light'],
|
|
31
|
+
...ThemeHelpers.colorsConfigToVars({
|
|
32
|
+
active: {
|
|
33
|
+
color: '#00a9c7',
|
|
34
|
+
mods: {
|
|
35
|
+
// @ts-ignore — extend defaults so --active-color-alpha-* variants match Homecode
|
|
36
|
+
alpha: [0, 50, 100, 200, ...defaultPalette.active.mods.alpha],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export type MiniAppThemeConfig = ReturnType<
|
|
44
|
+
typeof getDefaultMiniAppThemeConfig
|
|
45
|
+
>;
|