@vuu-ui/vuu-shell 0.8.35 → 0.8.36

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.
Files changed (151) hide show
  1. package/README.md +0 -0
  2. package/cjs/ShellContextProvider.js +31 -0
  3. package/cjs/ShellContextProvider.js.map +1 -0
  4. package/cjs/app-header/AppHeader.css +24 -0
  5. package/cjs/app-header/AppHeader.js +57 -0
  6. package/cjs/app-header/AppHeader.js.map +1 -0
  7. package/cjs/connection-status/ConnectionStatusIcon.css +68 -0
  8. package/cjs/connection-status/ConnectionStatusIcon.js +42 -0
  9. package/cjs/connection-status/ConnectionStatusIcon.js.map +1 -0
  10. package/cjs/feature/Feature.js +56 -0
  11. package/cjs/feature/Feature.js.map +1 -0
  12. package/cjs/feature/FeatureErrorBoundary.js +30 -0
  13. package/cjs/feature/FeatureErrorBoundary.js.map +1 -0
  14. package/cjs/feature/Loader.js +8 -0
  15. package/cjs/feature/Loader.js.map +1 -0
  16. package/cjs/feature/css-module-loader.js +9 -0
  17. package/cjs/feature/css-module-loader.js.map +1 -0
  18. package/cjs/feature-list/FeatureList.css +21 -0
  19. package/cjs/feature-list/FeatureList.js +43 -0
  20. package/cjs/feature-list/FeatureList.js.map +1 -0
  21. package/cjs/index.js.map +1 -0
  22. package/cjs/layout-management/LayoutList.css +86 -0
  23. package/cjs/layout-management/LayoutList.js +66 -0
  24. package/cjs/layout-management/LayoutList.js.map +1 -0
  25. package/cjs/layout-management/LayoutTile.css +28 -0
  26. package/cjs/layout-management/LayoutTile.js +27 -0
  27. package/cjs/layout-management/LayoutTile.js.map +1 -0
  28. package/cjs/layout-management/SaveLayoutPanel.css +130 -0
  29. package/cjs/layout-management/SaveLayoutPanel.js +140 -0
  30. package/cjs/layout-management/SaveLayoutPanel.js.map +1 -0
  31. package/cjs/layout-management/screenshot-utils.js +25 -0
  32. package/cjs/layout-management/screenshot-utils.js.map +1 -0
  33. package/cjs/layout-management/useLayoutContextMenuItems.js +72 -0
  34. package/cjs/layout-management/useLayoutContextMenuItems.js.map +1 -0
  35. package/cjs/layout-management/useLayoutManager.js +218 -0
  36. package/cjs/layout-management/useLayoutManager.js.map +1 -0
  37. package/cjs/left-nav/LeftNav.css +178 -0
  38. package/cjs/left-nav/LeftNav.js +157 -0
  39. package/cjs/left-nav/LeftNav.js.map +1 -0
  40. package/cjs/login/LoginPanel.css +70 -0
  41. package/cjs/login/LoginPanel.js +99 -0
  42. package/cjs/login/LoginPanel.js.map +1 -0
  43. package/cjs/login/VuuLogo.js +134 -0
  44. package/cjs/login/VuuLogo.js.map +1 -0
  45. package/cjs/login/login-utils.js +31 -0
  46. package/cjs/login/login-utils.js.map +1 -0
  47. package/cjs/persistence-management/LocalPersistenceManager.js +183 -0
  48. package/cjs/persistence-management/LocalPersistenceManager.js.map +1 -0
  49. package/cjs/persistence-management/RemotePersistenceManager.js +162 -0
  50. package/cjs/persistence-management/RemotePersistenceManager.js.map +1 -0
  51. package/cjs/persistence-management/defaultApplicationJson.js +42 -0
  52. package/cjs/persistence-management/defaultApplicationJson.js.map +1 -0
  53. package/cjs/session-editing-form/SessionEditingForm.css +53 -0
  54. package/cjs/session-editing-form/SessionEditingForm.js +271 -0
  55. package/cjs/session-editing-form/SessionEditingForm.js.map +1 -0
  56. package/cjs/shell-layouts/context-panel/ContextPanel.css +58 -0
  57. package/cjs/shell-layouts/context-panel/ContextPanel.js +61 -0
  58. package/cjs/shell-layouts/context-panel/ContextPanel.js.map +1 -0
  59. package/cjs/shell-layouts/side-panel/SidePanel.css +4 -0
  60. package/cjs/shell-layouts/side-panel/SidePanel.js +27 -0
  61. package/cjs/shell-layouts/side-panel/SidePanel.js.map +1 -0
  62. package/cjs/shell-layouts/useFullHeightLeftPanel.js +41 -0
  63. package/cjs/shell-layouts/useFullHeightLeftPanel.js.map +1 -0
  64. package/cjs/shell-layouts/useInlayLeftPanel.js +78 -0
  65. package/cjs/shell-layouts/useInlayLeftPanel.js.map +1 -0
  66. package/cjs/shell-layouts/useShellLayout.js +15 -0
  67. package/cjs/shell-layouts/useShellLayout.js.map +1 -0
  68. package/cjs/shell.css +49 -0
  69. package/cjs/shell.js +130 -0
  70. package/cjs/shell.js.map +1 -0
  71. package/cjs/shellTypes.js +8 -0
  72. package/cjs/shellTypes.js.map +1 -0
  73. package/cjs/theme-switch/ThemeSwitch.css +30 -0
  74. package/cjs/theme-switch/ThemeSwitch.js +47 -0
  75. package/cjs/theme-switch/ThemeSwitch.js.map +1 -0
  76. package/esm/ShellContextProvider.js +28 -0
  77. package/esm/ShellContextProvider.js.map +1 -0
  78. package/esm/app-header/AppHeader.css +24 -0
  79. package/esm/app-header/AppHeader.js +55 -0
  80. package/esm/app-header/AppHeader.js.map +1 -0
  81. package/esm/connection-status/ConnectionStatusIcon.css +68 -0
  82. package/esm/connection-status/ConnectionStatusIcon.js +40 -0
  83. package/esm/connection-status/ConnectionStatusIcon.js.map +1 -0
  84. package/esm/feature/Feature.js +54 -0
  85. package/esm/feature/Feature.js.map +1 -0
  86. package/esm/feature/FeatureErrorBoundary.js +28 -0
  87. package/esm/feature/FeatureErrorBoundary.js.map +1 -0
  88. package/esm/feature/Loader.js +6 -0
  89. package/esm/feature/Loader.js.map +1 -0
  90. package/esm/feature/css-module-loader.js +7 -0
  91. package/esm/feature/css-module-loader.js.map +1 -0
  92. package/esm/feature-list/FeatureList.css +21 -0
  93. package/esm/feature-list/FeatureList.js +41 -0
  94. package/esm/feature-list/FeatureList.js.map +1 -0
  95. package/esm/index.js +20 -0
  96. package/esm/index.js.map +1 -0
  97. package/esm/layout-management/LayoutList.css +86 -0
  98. package/esm/layout-management/LayoutList.js +64 -0
  99. package/esm/layout-management/LayoutList.js.map +1 -0
  100. package/esm/layout-management/LayoutTile.css +28 -0
  101. package/esm/layout-management/LayoutTile.js +25 -0
  102. package/esm/layout-management/LayoutTile.js.map +1 -0
  103. package/esm/layout-management/SaveLayoutPanel.css +130 -0
  104. package/esm/layout-management/SaveLayoutPanel.js +138 -0
  105. package/esm/layout-management/SaveLayoutPanel.js.map +1 -0
  106. package/esm/layout-management/screenshot-utils.js +23 -0
  107. package/esm/layout-management/screenshot-utils.js.map +1 -0
  108. package/esm/layout-management/useLayoutContextMenuItems.js +70 -0
  109. package/esm/layout-management/useLayoutContextMenuItems.js.map +1 -0
  110. package/esm/layout-management/useLayoutManager.js +214 -0
  111. package/esm/layout-management/useLayoutManager.js.map +1 -0
  112. package/esm/left-nav/LeftNav.css +178 -0
  113. package/esm/left-nav/LeftNav.js +155 -0
  114. package/esm/left-nav/LeftNav.js.map +1 -0
  115. package/esm/login/LoginPanel.css +70 -0
  116. package/esm/login/LoginPanel.js +97 -0
  117. package/esm/login/LoginPanel.js.map +1 -0
  118. package/esm/login/VuuLogo.js +132 -0
  119. package/esm/login/VuuLogo.js.map +1 -0
  120. package/esm/login/login-utils.js +26 -0
  121. package/esm/login/login-utils.js.map +1 -0
  122. package/esm/persistence-management/LocalPersistenceManager.js +181 -0
  123. package/esm/persistence-management/LocalPersistenceManager.js.map +1 -0
  124. package/esm/persistence-management/RemotePersistenceManager.js +160 -0
  125. package/esm/persistence-management/RemotePersistenceManager.js.map +1 -0
  126. package/esm/persistence-management/defaultApplicationJson.js +39 -0
  127. package/esm/persistence-management/defaultApplicationJson.js.map +1 -0
  128. package/esm/session-editing-form/SessionEditingForm.css +53 -0
  129. package/esm/session-editing-form/SessionEditingForm.js +269 -0
  130. package/esm/session-editing-form/SessionEditingForm.js.map +1 -0
  131. package/esm/shell-layouts/context-panel/ContextPanel.css +58 -0
  132. package/esm/shell-layouts/context-panel/ContextPanel.js +59 -0
  133. package/esm/shell-layouts/context-panel/ContextPanel.js.map +1 -0
  134. package/esm/shell-layouts/side-panel/SidePanel.css +4 -0
  135. package/esm/shell-layouts/side-panel/SidePanel.js +25 -0
  136. package/esm/shell-layouts/side-panel/SidePanel.js.map +1 -0
  137. package/esm/shell-layouts/useFullHeightLeftPanel.js +39 -0
  138. package/esm/shell-layouts/useFullHeightLeftPanel.js.map +1 -0
  139. package/esm/shell-layouts/useInlayLeftPanel.js +76 -0
  140. package/esm/shell-layouts/useInlayLeftPanel.js.map +1 -0
  141. package/esm/shell-layouts/useShellLayout.js +13 -0
  142. package/esm/shell-layouts/useShellLayout.js.map +1 -0
  143. package/esm/shell.css +49 -0
  144. package/esm/shell.js +128 -0
  145. package/esm/shell.js.map +1 -0
  146. package/esm/shellTypes.js +5 -0
  147. package/esm/shellTypes.js.map +1 -0
  148. package/esm/theme-switch/ThemeSwitch.css +30 -0
  149. package/esm/theme-switch/ThemeSwitch.js +45 -0
  150. package/esm/theme-switch/ThemeSwitch.js.map +1 -0
  151. package/package.json +14 -12
@@ -0,0 +1,15 @@
1
+ 'use strict';
2
+
3
+ var useFullHeightLeftPanel = require('./useFullHeightLeftPanel.js');
4
+ var useInlayLeftPanel = require('./useInlayLeftPanel.js');
5
+
6
+ const useShellLayout = ({
7
+ leftSidePanelLayout = "inlay",
8
+ ...props
9
+ }) => {
10
+ const useLayoutHook = leftSidePanelLayout === "inlay" ? useInlayLeftPanel.useInlayLeftPanel : useFullHeightLeftPanel.useFullHeightLeftPanel;
11
+ return useLayoutHook(props);
12
+ };
13
+
14
+ exports.useShellLayout = useShellLayout;
15
+ //# sourceMappingURL=useShellLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShellLayout.js","sources":["../../src/shell-layouts/useShellLayout.ts"],"sourcesContent":["import { ReactElement } from \"react\";\nimport { ShellProps } from \"../shell\";\nimport { useFullHeightLeftPanel } from \"./useFullHeightLeftPanel\";\nimport { useInlayLeftPanel } from \"./useInlayLeftPanel\";\n\nexport type ShellLayoutType = \"full-height\" | \"inlay\";\nexport interface ShellLayoutProps {\n LeftSidePanelProps: ShellProps[\"LeftSidePanelProps\"];\n appHeader: ReactElement;\n}\n\nexport const useShellLayout = ({\n leftSidePanelLayout = \"inlay\",\n ...props\n}:\n | ShellLayoutProps & {\n leftSidePanelLayout?: \"full-height\" | \"inlay\";\n }) => {\n const useLayoutHook =\n leftSidePanelLayout === \"inlay\"\n ? useInlayLeftPanel\n : useFullHeightLeftPanel;\n\n return useLayoutHook(props);\n};\n"],"names":["useInlayLeftPanel","useFullHeightLeftPanel"],"mappings":";;;;;AAWO,MAAM,iBAAiB,CAAC;AAAA,EAC7B,mBAAsB,GAAA,OAAA;AAAA,EACtB,GAAG,KAAA;AACL,CAGU,KAAA;AACR,EAAM,MAAA,aAAA,GACJ,mBAAwB,KAAA,OAAA,GACpBA,mCACA,GAAAC,6CAAA,CAAA;AAEN,EAAA,OAAO,cAAc,KAAK,CAAA,CAAA;AAC5B;;;;"}
package/cjs/shell.css ADDED
@@ -0,0 +1,49 @@
1
+ .vuuShell {
2
+ background-color: var(--vuu-color-gray-25);
3
+ height: var(--vuuShell-height, 100vh);
4
+ width: var(--vuuShell-width, 100vw);
5
+ }
6
+
7
+ .vuuShell-mainTabs {
8
+ background: var(--salt-container-primary-background);
9
+ }
10
+
11
+ .vuuShell-palette {
12
+ --vuuView-border: none;
13
+ --vuuView-margin: 0;
14
+ }
15
+
16
+ .vuuShell-warningPlaceholder {
17
+ background-color: var(--salt-container-background-high);
18
+ height: 100%;
19
+ }
20
+
21
+ /* until we reinstat5e the toolbar */
22
+ .vuuToolbarProxy {
23
+ background: var(--salt-container-primary-background);
24
+ }
25
+
26
+ .vuuShell-mainTabs > .vuuTabstrip > .vuuOverflowContainer-wrapContainer {
27
+ background: var(--vuu-color-gray-25);
28
+ }
29
+
30
+ .vuuShell-mainTabs {
31
+ --vuuTab-height: 28px;
32
+ border: solid 1px #D6D7DA;
33
+ border-top: none !important;
34
+ border-radius: 6px;
35
+ height: 100%;
36
+ padding: 36px 8px 8px 8px;
37
+ position: relative;
38
+ width: 100%;
39
+ }
40
+
41
+ .vuuShell-mainTabs > .vuuTabstrip {
42
+ left:-1px;
43
+ padding-bottom: 7px;
44
+ position: absolute !important;
45
+ right: 1px;
46
+ top: 0;
47
+ width: calc(100% + 2px) !important;
48
+ }
49
+
package/cjs/shell.js ADDED
@@ -0,0 +1,130 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var vuuDataRemote = require('@vuu-ui/vuu-data-remote');
5
+ var vuuLayout = require('@vuu-ui/vuu-layout');
6
+ var vuuPopups = require('@vuu-ui/vuu-popups');
7
+ var vuuUtils = require('@vuu-ui/vuu-utils');
8
+ var cx = require('clsx');
9
+ var React = require('react');
10
+ var AppHeader = require('./app-header/AppHeader.js');
11
+ require('@vuu-ui/vuu-ui-controls');
12
+ require('html-to-image');
13
+ require('@salt-ds/core');
14
+ var useLayoutManager = require('./layout-management/useLayoutManager.js');
15
+ var useLayoutContextMenuItems = require('./layout-management/useLayoutContextMenuItems.js');
16
+ var defaultApplicationJson = require('./persistence-management/defaultApplicationJson.js');
17
+ require('./persistence-management/LocalPersistenceManager.js');
18
+ require('./persistence-management/RemotePersistenceManager.js');
19
+ var useShellLayout = require('./shell-layouts/useShellLayout.js');
20
+
21
+ if (typeof vuuLayout.StackLayout !== "function") {
22
+ console.warn(
23
+ "StackLayout module not loaded, will be unsbale to deserialize from layout JSON"
24
+ );
25
+ }
26
+ const { error } = vuuUtils.logger("Shell");
27
+ const defaultLeftSidePanel = {};
28
+ const Shell = ({
29
+ LayoutProps,
30
+ LeftSidePanelProps = defaultLeftSidePanel,
31
+ children,
32
+ className: classNameProp,
33
+ leftSidePanelLayout,
34
+ loginUrl,
35
+ saveLocation: _,
36
+ saveUrl,
37
+ serverUrl,
38
+ user,
39
+ ...htmlAttributes
40
+ }) => {
41
+ const rootRef = React.useRef(null);
42
+ const { dialog, setDialogState } = vuuPopups.useDialog();
43
+ const layoutId = React.useRef("latest");
44
+ const { applicationJson, saveApplicationLayout, loadLayoutById } = useLayoutManager.useLayoutManager();
45
+ const { buildMenuOptions, handleMenuAction } = useLayoutContextMenuItems.useLayoutContextMenuItems(setDialogState);
46
+ const [connectionStatus, setConnectionStatus] = React.useState("connected");
47
+ const handleLayoutChange = React.useCallback(
48
+ (layout) => {
49
+ try {
50
+ saveApplicationLayout(layout);
51
+ } catch {
52
+ error?.("Failed to save layout");
53
+ }
54
+ },
55
+ [saveApplicationLayout]
56
+ );
57
+ const handleSwitchTheme = React.useCallback((mode) => {
58
+ if (rootRef.current) {
59
+ rootRef.current.dataset.mode = mode;
60
+ }
61
+ }, []);
62
+ const handleNavigate = React.useCallback(
63
+ (id) => {
64
+ layoutId.current = id;
65
+ loadLayoutById(id);
66
+ },
67
+ [loadLayoutById]
68
+ );
69
+ React.useMemo(async () => {
70
+ if (serverUrl && user.token) {
71
+ const connectionStatus2 = await vuuDataRemote.connectToServer({
72
+ authToken: user.token,
73
+ url: serverUrl,
74
+ username: user.username
75
+ });
76
+ setConnectionStatus(connectionStatus2);
77
+ }
78
+ }, [serverUrl, user.token, user.username]);
79
+ const [themeClass, densityClass, dataMode] = vuuUtils.useThemeAttributes();
80
+ const className = cx("vuuShell", classNameProp, themeClass, densityClass);
81
+ const isLoading = applicationJson === defaultApplicationJson.loadingApplicationJson;
82
+ const shellLayout = useShellLayout.useShellLayout({
83
+ LeftSidePanelProps,
84
+ leftSidePanelLayout,
85
+ appHeader: /* @__PURE__ */ jsxRuntime.jsx(
86
+ AppHeader.AppHeader,
87
+ {
88
+ layoutId: layoutId.current,
89
+ loginUrl,
90
+ user,
91
+ onNavigate: handleNavigate,
92
+ onSwitchTheme: handleSwitchTheme
93
+ }
94
+ )
95
+ });
96
+ if (connectionStatus === "rejected") {
97
+ console.log("game over, no connection to server");
98
+ }
99
+ return isLoading ? null : /* @__PURE__ */ jsxRuntime.jsx(vuuUtils.ThemeProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
100
+ vuuPopups.ContextMenuProvider,
101
+ {
102
+ menuActionHandler: handleMenuAction,
103
+ menuBuilder: buildMenuOptions,
104
+ children: [
105
+ /* @__PURE__ */ jsxRuntime.jsx(
106
+ vuuLayout.LayoutProvider,
107
+ {
108
+ ...LayoutProps,
109
+ layout: applicationJson.layout,
110
+ onLayoutChange: handleLayoutChange,
111
+ children: /* @__PURE__ */ jsxRuntime.jsx(
112
+ vuuLayout.DraggableLayout,
113
+ {
114
+ className,
115
+ "data-mode": dataMode,
116
+ ref: rootRef,
117
+ ...htmlAttributes,
118
+ children: shellLayout
119
+ }
120
+ )
121
+ }
122
+ ),
123
+ children || dialog
124
+ ]
125
+ }
126
+ ) });
127
+ };
128
+
129
+ exports.Shell = Shell;
130
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sources":["../src/shell.tsx"],"sourcesContent":["import { connectToServer } from \"@vuu-ui/vuu-data-remote\";\nimport {\n DraggableLayout,\n LayoutProvider,\n LayoutProviderProps,\n StackLayout,\n} from \"@vuu-ui/vuu-layout\";\nimport type { LayoutChangeHandler } from \"@vuu-ui/vuu-layout\";\nimport { ContextMenuProvider, useDialog } from \"@vuu-ui/vuu-popups\";\nimport {\n logger,\n ThemeMode,\n ThemeProvider,\n useThemeAttributes,\n} from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport {\n HTMLAttributes,\n ReactNode,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { AppHeader } from \"./app-header\";\nimport {\n useLayoutContextMenuItems,\n useLayoutManager,\n} from \"./layout-management\";\nimport { loadingApplicationJson } from \"./persistence-management\";\nimport { SidePanelProps, useShellLayout } from \"./shell-layouts\";\nimport { SaveLocation } from \"./shellTypes\";\n\nimport \"./shell.css\";\n\nif (typeof StackLayout !== \"function\") {\n console.warn(\n \"StackLayout module not loaded, will be unsbale to deserialize from layout JSON\"\n );\n}\n\nexport type VuuUser = {\n username: string;\n token: string;\n};\n\nconst { error } = logger(\"Shell\");\n\nconst defaultLeftSidePanel: ShellProps[\"LeftSidePanelProps\"] = {};\n\nexport type LayoutTemplateName = \"full-height\" | \"inlay\";\n\nexport interface ShellProps extends HTMLAttributes<HTMLDivElement> {\n LayoutProps?: Pick<\n LayoutProviderProps,\n \"createNewChild\" | \"pathToDropTarget\"\n >;\n LeftSidePanelProps?: SidePanelProps;\n children?: ReactNode;\n leftSidePanelLayout?: \"full-height\" | \"inlay\";\n loginUrl?: string;\n // paletteConfig: any;\n saveLocation?: SaveLocation;\n saveUrl?: string;\n serverUrl?: string;\n user: VuuUser;\n}\n\nexport const Shell = ({\n LayoutProps,\n LeftSidePanelProps = defaultLeftSidePanel,\n children,\n className: classNameProp,\n leftSidePanelLayout,\n loginUrl,\n saveLocation: _,\n saveUrl,\n serverUrl,\n user,\n ...htmlAttributes\n}: ShellProps) => {\n const rootRef = useRef<HTMLDivElement>(null);\n const { dialog, setDialogState } = useDialog();\n const layoutId = useRef(\"latest\");\n const { applicationJson, saveApplicationLayout, loadLayoutById } =\n useLayoutManager();\n const { buildMenuOptions, handleMenuAction } =\n useLayoutContextMenuItems(setDialogState);\n const [connectionStatus, setConnectionStatus] = useState<\n \"connected\" | \"rejected\"\n >(\"connected\");\n\n const handleLayoutChange = useCallback<LayoutChangeHandler>(\n (layout) => {\n try {\n saveApplicationLayout(layout);\n } catch {\n error?.(\"Failed to save layout\");\n }\n },\n [saveApplicationLayout]\n );\n\n const handleSwitchTheme = useCallback((mode: ThemeMode) => {\n if (rootRef.current) {\n rootRef.current.dataset.mode = mode;\n }\n }, []);\n\n // TODO this is out of date\n const handleNavigate = useCallback(\n (id) => {\n layoutId.current = id;\n loadLayoutById(id);\n },\n [loadLayoutById]\n );\n\n useMemo(async () => {\n if (serverUrl && user.token) {\n const connectionStatus = await connectToServer({\n authToken: user.token,\n url: serverUrl,\n username: user.username,\n });\n setConnectionStatus(connectionStatus);\n }\n }, [serverUrl, user.token, user.username]);\n\n const [themeClass, densityClass, dataMode] = useThemeAttributes();\n const className = cx(\"vuuShell\", classNameProp, themeClass, densityClass);\n\n const isLoading = applicationJson === loadingApplicationJson;\n\n const shellLayout = useShellLayout({\n LeftSidePanelProps,\n leftSidePanelLayout,\n appHeader: (\n <AppHeader\n layoutId={layoutId.current}\n loginUrl={loginUrl}\n user={user}\n onNavigate={handleNavigate}\n onSwitchTheme={handleSwitchTheme}\n />\n ),\n });\n\n if (connectionStatus === \"rejected\") {\n console.log(\"game over, no connection to server\");\n }\n\n return isLoading ? null : (\n <ThemeProvider>\n <ContextMenuProvider\n menuActionHandler={handleMenuAction}\n menuBuilder={buildMenuOptions}\n >\n <LayoutProvider\n {...LayoutProps}\n layout={applicationJson.layout}\n onLayoutChange={handleLayoutChange}\n >\n <DraggableLayout\n className={className}\n data-mode={dataMode}\n ref={rootRef}\n {...htmlAttributes}\n >\n {shellLayout}\n </DraggableLayout>\n </LayoutProvider>\n {children || dialog}\n </ContextMenuProvider>\n </ThemeProvider>\n );\n};\n"],"names":["StackLayout","logger","useRef","useDialog","useLayoutManager","useLayoutContextMenuItems","useState","useCallback","useMemo","connectionStatus","connectToServer","useThemeAttributes","loadingApplicationJson","useShellLayout","jsx","AppHeader","ThemeProvider","jsxs","ContextMenuProvider","LayoutProvider","DraggableLayout"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ const isWildcardSchema = (schema) => schema === "*";
4
+ const isTableSchema = (schema) => typeof schema === "object" && typeof schema.module === "string" && typeof schema.table === "string";
5
+
6
+ exports.isTableSchema = isTableSchema;
7
+ exports.isWildcardSchema = isWildcardSchema;
8
+ //# sourceMappingURL=shellTypes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shellTypes.js","sources":["../src/shellTypes.ts"],"sourcesContent":["import type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport type { ViewProps } from \"@vuu-ui/vuu-layout\";\n\ndeclare global {\n const vuuConfig: Promise<VuuConfig>;\n}\n\nexport type SaveLocation = \"local\" | \"remote\";\n\nexport interface FeatureConfig {\n name: string;\n title: string;\n url: string;\n css?: string;\n leftNavLocation: \"vuu-features\" | \"vuu-tables\";\n featureProps?: {\n schema?: \"*\" | VuuTable;\n schemas?: VuuTable[];\n ViewProps?: Partial<ViewProps>;\n };\n}\n\nexport type Features = {\n [key: string]: FeatureConfig;\n};\nexport interface VuuConfig {\n features: Features;\n authUrl?: string;\n websocketUrl: string;\n ssl: boolean;\n}\n\nexport const isWildcardSchema = (schema?: \"*\" | VuuTable): schema is \"*\" =>\n schema === \"*\";\nexport const isTableSchema = (schema?: \"*\" | VuuTable): schema is VuuTable =>\n typeof schema === \"object\" &&\n typeof schema.module === \"string\" &&\n typeof schema.table === \"string\";\n"],"names":[],"mappings":";;AAgCa,MAAA,gBAAA,GAAmB,CAAC,MAAA,KAC/B,MAAW,KAAA,IAAA;AACN,MAAM,aAAgB,GAAA,CAAC,MAC5B,KAAA,OAAO,MAAW,KAAA,QAAA,IAClB,OAAO,MAAA,CAAO,MAAW,KAAA,QAAA,IACzB,OAAO,MAAA,CAAO,KAAU,KAAA;;;;;"}
@@ -0,0 +1,30 @@
1
+
2
+ .vuuThemeSwitch {
3
+ --saltButton-minWidth: 22px;
4
+ --svg-light: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M24 31q2.9 0 4.95-2.05Q31 26.9 31 24q0-2.9-2.05-4.95Q26.9 17 24 17q-2.9 0-4.95 2.05Q17 21.1 17 24q0 2.9 2.05 4.95Q21.1 31 24 31Zm0 3q-4.15 0-7.075-2.925T14 24q0-4.15 2.925-7.075T24 14q4.15 0 7.075 2.925T34 24q0 4.15-2.925 7.075T24 34ZM3.5 25.5q-.65 0-1.075-.425Q2 24.65 2 24q0-.65.425-1.075Q2.85 22.5 3.5 22.5h5q.65 0 1.075.425Q10 23.35 10 24q0 .65-.425 1.075-.425.425-1.075.425Zm36 0q-.65 0-1.075-.425Q38 24.65 38 24q0-.65.425-1.075.425-.425 1.075-.425h5q.65 0 1.075.425Q46 23.35 46 24q0 .65-.425 1.075-.425.425-1.075.425ZM24 10q-.65 0-1.075-.425Q22.5 9.15 22.5 8.5v-5q0-.65.425-1.075Q23.35 2 24 2q.65 0 1.075.425.425.425.425 1.075v5q0 .65-.425 1.075Q24.65 10 24 10Zm0 36q-.65 0-1.075-.425-.425-.425-.425-1.075v-5q0-.65.425-1.075Q23.35 38 24 38q.65 0 1.075.425.425.425.425 1.075v5q0 .65-.425 1.075Q24.65 46 24 46ZM12 14.1l-2.85-2.8q-.45-.45-.425-1.075.025-.625.425-1.075.45-.45 1.075-.45t1.075.45L14.1 12q.4.45.4 1.05 0 .6-.4 1-.4.45-1.025.45-.625 0-1.075-.4Zm24.7 24.75L33.9 36q-.4-.45-.4-1.075t.45-1.025q.4-.45 1-.45t1.05.45l2.85 2.8q.45.45.425 1.075-.025.625-.425 1.075-.45.45-1.075.45t-1.075-.45ZM33.9 14.1q-.45-.45-.45-1.05 0-.6.45-1.05l2.8-2.85q.45-.45 1.075-.425.625.025 1.075.425.45.45.45 1.075t-.45 1.075L36 14.1q-.4.4-1.025.4-.625 0-1.075-.4ZM9.15 38.85q-.45-.45-.45-1.075t.45-1.075L12 33.9q.45-.45 1.05-.45.6 0 1.05.45.45.45.45 1.05 0 .6-.45 1.05l-2.8 2.85q-.45.45-1.075.425-.625-.025-1.075-.425ZM24 24Z"/></svg>');
5
+ --svg-dark: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M24 42q-7.5 0-12.75-5.25T6 24q0-7.5 5.25-12.75T24 6q.4 0 .85.025.45.025 1.15.075-1.8 1.6-2.8 3.95-1 2.35-1 4.95 0 4.5 3.15 7.65Q28.5 25.8 33 25.8q2.6 0 4.95-.925T41.9 22.3q.05.6.075.975Q42 23.65 42 24q0 7.5-5.25 12.75T24 42Zm0-3q5.45 0 9.5-3.375t5.05-7.925q-1.25.55-2.675.825Q34.45 28.8 33 28.8q-5.75 0-9.775-4.025T19.2 15q0-1.2.25-2.575.25-1.375.9-3.125-4.9 1.35-8.125 5.475Q9 18.9 9 24q0 6.25 4.375 10.625T24 39Zm-.2-14.85Z"/></svg>');
6
+ padding: 2px;
7
+ }
8
+
9
+ .salt-density-high .vuuThemeSwitch {
10
+ --saltButton-minWidth: 16px;
11
+ --saltButton-width: 18px;
12
+ --vuuThemeSwitch-iconSize: 16px;
13
+ }
14
+
15
+ .vuuThemeSwitch [data-icon] {
16
+ --vuu-icon-size: var(--vuuThemeSwitch-iconSize,18px);
17
+ }
18
+
19
+ .vuuThemeSwitch [data-icon='light'] {
20
+ --vuu-icon-svg: var(--svg-light);
21
+ }
22
+ .vuuThemeSwitch [data-icon='dark'] {
23
+ --vuu-icon-svg: var(--svg-dark);
24
+ }
25
+
26
+ .vuuThemeSwitch .saltToggleButton {
27
+ height: 20px;
28
+ width: 20px;
29
+ }
30
+
@@ -0,0 +1,47 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var cx = require('clsx');
5
+ var core = require('@salt-ds/core');
6
+ var React = require('react');
7
+
8
+ const classBase = "vuuThemeSwitch";
9
+ const ThemeSwitch = ({
10
+ className: classNameProp,
11
+ defaultMode: defaultModeProp,
12
+ mode: modeProp,
13
+ onChange,
14
+ ...htmlAttributes
15
+ }) => {
16
+ const [mode, setMode] = core.useControlled({
17
+ controlled: modeProp,
18
+ default: defaultModeProp ?? "light",
19
+ name: "ThemeSwitch",
20
+ state: "mode"
21
+ });
22
+ const handleChangeSecondary = React.useCallback(
23
+ (evt) => {
24
+ const { value } = evt.target;
25
+ setMode(value);
26
+ onChange(value);
27
+ },
28
+ [onChange, setMode]
29
+ );
30
+ const className = cx(classBase, classNameProp);
31
+ return /* @__PURE__ */ jsxRuntime.jsxs(
32
+ core.ToggleButtonGroup,
33
+ {
34
+ className,
35
+ ...htmlAttributes,
36
+ onChange: handleChangeSecondary,
37
+ value: mode,
38
+ children: [
39
+ /* @__PURE__ */ jsxRuntime.jsx(core.ToggleButton, { "aria-label": "alert", "data-icon": "light", value: "light" }),
40
+ /* @__PURE__ */ jsxRuntime.jsx(core.ToggleButton, { "aria-label": "home", "data-icon": "dark", value: "dark" })
41
+ ]
42
+ }
43
+ );
44
+ };
45
+
46
+ exports.ThemeSwitch = ThemeSwitch;
47
+ //# sourceMappingURL=ThemeSwitch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeSwitch.js","sources":["../../src/theme-switch/ThemeSwitch.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { ToggleButton, ToggleButtonGroup, useControlled } from \"@salt-ds/core\";\nimport { HTMLAttributes, SyntheticEvent, useCallback } from \"react\";\nimport { ThemeMode } from \"@vuu-ui/vuu-utils\";\n\nimport \"./ThemeSwitch.css\";\n\nconst classBase = \"vuuThemeSwitch\";\nexport interface ThemeSwitchProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n defaultMode?: ThemeMode;\n mode?: ThemeMode;\n onChange: (mode: ThemeMode) => void;\n}\n\nexport const ThemeSwitch = ({\n className: classNameProp,\n defaultMode: defaultModeProp,\n mode: modeProp,\n onChange,\n ...htmlAttributes\n}: ThemeSwitchProps) => {\n const [mode, setMode] = useControlled<ThemeMode>({\n controlled: modeProp,\n default: defaultModeProp ?? \"light\",\n name: \"ThemeSwitch\",\n state: \"mode\",\n });\n\n const handleChangeSecondary = useCallback(\n (evt: SyntheticEvent<HTMLButtonElement>) => {\n const { value } = evt.target as HTMLButtonElement;\n setMode(value as ThemeMode);\n onChange(value as ThemeMode);\n },\n [onChange, setMode]\n );\n const className = cx(classBase, classNameProp);\n return (\n <ToggleButtonGroup\n className={className}\n {...htmlAttributes}\n onChange={handleChangeSecondary}\n value={mode}\n >\n <ToggleButton aria-label=\"alert\" data-icon=\"light\" value=\"light\" />\n <ToggleButton aria-label=\"home\" data-icon=\"dark\" value=\"dark\" />\n </ToggleButtonGroup>\n );\n};\n"],"names":["useControlled","useCallback","jsxs","ToggleButtonGroup","jsx","ToggleButton"],"mappings":";;;;;;;AAOA,MAAM,SAAY,GAAA,gBAAA,CAAA;AAQX,MAAM,cAAc,CAAC;AAAA,EAC1B,SAAW,EAAA,aAAA;AAAA,EACX,WAAa,EAAA,eAAA;AAAA,EACb,IAAM,EAAA,QAAA;AAAA,EACN,QAAA;AAAA,EACA,GAAG,cAAA;AACL,CAAwB,KAAA;AACtB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,kBAAyB,CAAA;AAAA,IAC/C,UAAY,EAAA,QAAA;AAAA,IACZ,SAAS,eAAmB,IAAA,OAAA;AAAA,IAC5B,IAAM,EAAA,aAAA;AAAA,IACN,KAAO,EAAA,MAAA;AAAA,GACR,CAAA,CAAA;AAED,EAAA,MAAM,qBAAwB,GAAAC,iBAAA;AAAA,IAC5B,CAAC,GAA2C,KAAA;AAC1C,MAAM,MAAA,EAAE,KAAM,EAAA,GAAI,GAAI,CAAA,MAAA,CAAA;AACtB,MAAA,OAAA,CAAQ,KAAkB,CAAA,CAAA;AAC1B,MAAA,QAAA,CAAS,KAAkB,CAAA,CAAA;AAAA,KAC7B;AAAA,IACA,CAAC,UAAU,OAAO,CAAA;AAAA,GACpB,CAAA;AACA,EAAM,MAAA,SAAA,GAAY,EAAG,CAAA,SAAA,EAAW,aAAa,CAAA,CAAA;AAC7C,EACE,uBAAAC,eAAA;AAAA,IAACC,sBAAA;AAAA,IAAA;AAAA,MACC,SAAA;AAAA,MACC,GAAG,cAAA;AAAA,MACJ,QAAU,EAAA,qBAAA;AAAA,MACV,KAAO,EAAA,IAAA;AAAA,MAEP,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAACC,qBAAa,YAAW,EAAA,OAAA,EAAQ,WAAU,EAAA,OAAA,EAAQ,OAAM,OAAQ,EAAA,CAAA;AAAA,uCAChEA,iBAAa,EAAA,EAAA,YAAA,EAAW,QAAO,WAAU,EAAA,MAAA,EAAO,OAAM,MAAO,EAAA,CAAA;AAAA,OAAA;AAAA,KAAA;AAAA,GAChE,CAAA;AAEJ;;;;"}
@@ -0,0 +1,28 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { createContext, useContext } from 'react';
3
+
4
+ const defaultConfig = {};
5
+ const ShellContext = createContext(defaultConfig);
6
+ const Provider = ({
7
+ children,
8
+ context,
9
+ inheritedContext
10
+ }) => {
11
+ const mergedContext = {
12
+ ...inheritedContext,
13
+ ...context
14
+ };
15
+ return /* @__PURE__ */ jsx(ShellContext.Provider, { value: mergedContext, children });
16
+ };
17
+ const ShellContextProvider = ({
18
+ children,
19
+ value
20
+ }) => {
21
+ return /* @__PURE__ */ jsx(ShellContext.Consumer, { children: (context) => /* @__PURE__ */ jsx(Provider, { context: value, inheritedContext: context, children }) });
22
+ };
23
+ const useShellContext = () => {
24
+ return useContext(ShellContext);
25
+ };
26
+
27
+ export { ShellContextProvider, useShellContext };
28
+ //# sourceMappingURL=ShellContextProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShellContextProvider.js","sources":["../src/ShellContextProvider.tsx"],"sourcesContent":["import {\n DefaultColumnConfiguration,\n ListOption,\n} from \"@vuu-ui/vuu-table-types\";\nimport type { RpcResponseHandler } from \"@vuu-ui/vuu-data-types\";\nimport { createContext, ReactElement, ReactNode, useContext } from \"react\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\n\nexport type LookupTableProvider = (table: VuuTable) => ListOption[];\n\nexport interface ShellContextProps {\n getDefaultColumnConfig?: DefaultColumnConfiguration;\n getLookupValues?: LookupTableProvider;\n handleRpcResponse?: RpcResponseHandler;\n}\n\nconst defaultConfig = {};\n\nconst ShellContext = createContext<ShellContextProps>(defaultConfig);\n\nexport interface ShellProviderProps {\n children: ReactNode;\n value?: ShellContextProps;\n}\n\nconst Provider = ({\n children,\n context,\n inheritedContext,\n}: {\n children: ReactNode;\n context?: ShellContextProps;\n inheritedContext?: ShellContextProps;\n}) => {\n // TODO functions provided at multiple levels must be merged\n const mergedContext = {\n ...inheritedContext,\n ...context,\n };\n return (\n <ShellContext.Provider value={mergedContext}>\n {children}\n </ShellContext.Provider>\n );\n};\n\nexport const ShellContextProvider = ({\n children,\n value,\n}: ShellProviderProps): ReactElement => {\n return (\n <ShellContext.Consumer>\n {(context) => (\n <Provider context={value} inheritedContext={context}>\n {children}\n </Provider>\n )}\n </ShellContext.Consumer>\n );\n};\n\nexport const useShellContext = () => {\n return useContext(ShellContext);\n};\n"],"names":[],"mappings":";;;AAgBA,MAAM,gBAAgB,EAAC,CAAA;AAEvB,MAAM,YAAA,GAAe,cAAiC,aAAa,CAAA,CAAA;AAOnE,MAAM,WAAW,CAAC;AAAA,EAChB,QAAA;AAAA,EACA,OAAA;AAAA,EACA,gBAAA;AACF,CAIM,KAAA;AAEJ,EAAA,MAAM,aAAgB,GAAA;AAAA,IACpB,GAAG,gBAAA;AAAA,IACH,GAAG,OAAA;AAAA,GACL,CAAA;AACA,EAAA,2BACG,YAAa,CAAA,QAAA,EAAb,EAAsB,KAAA,EAAO,eAC3B,QACH,EAAA,CAAA,CAAA;AAEJ,CAAA,CAAA;AAEO,MAAM,uBAAuB,CAAC;AAAA,EACnC,QAAA;AAAA,EACA,KAAA;AACF,CAAwC,KAAA;AACtC,EAAA,uBACG,GAAA,CAAA,YAAA,CAAa,QAAb,EAAA,EACE,QAAC,EAAA,CAAA,OAAA,qBACC,GAAA,CAAA,QAAA,EAAA,EAAS,OAAS,EAAA,KAAA,EAAO,gBAAkB,EAAA,OAAA,EACzC,UACH,CAEJ,EAAA,CAAA,CAAA;AAEJ,EAAA;AAEO,MAAM,kBAAkB,MAAM;AACnC,EAAA,OAAO,WAAW,YAAY,CAAA,CAAA;AAChC;;;;"}
@@ -0,0 +1,24 @@
1
+ .vuuAppHeader {
2
+ --saltButton-borderRadius: 6px;
3
+ --saltButton-text-color: var(--vuu-color-gray-50);
4
+ --saltButton-padding: 12px;
5
+ --vuuToolbarItem-height: 26px;
6
+ --vuuOverflowContainer-gap: 8px;
7
+ --vuu-icon-color: var(--vuu-color-gray-45);
8
+ --vuu-icon-size: 16px;
9
+ --vuuToolbar-background: var(--vuuAppHeader-background, var(--vuu-color-gray-28));
10
+ --vuuToolbar-borderWidth: 1px;
11
+ --vuuToolbar-borderStyle: solid;
12
+ --vuuToolbar-borderColor: var(--vuu-color-gray-30);
13
+
14
+ align-items: center;
15
+ display: flex;
16
+ justify-content: flex-end;
17
+ }
18
+
19
+ .vuu-theme .vuuAppHeader {
20
+ border-radius: 8px;
21
+
22
+ margin-bottom: 8px;
23
+ }
24
+
@@ -0,0 +1,55 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useCallback } from 'react';
3
+ import { Toolbar } from '@vuu-ui/vuu-ui-controls';
4
+ import cx from 'clsx';
5
+ import { Button } from '@salt-ds/core';
6
+ import { logout } from '../login/login-utils.js';
7
+
8
+ const classBase = "vuuAppHeader";
9
+ const AppHeader = ({
10
+ className: classNameProp,
11
+ layoutId,
12
+ loginUrl,
13
+ onNavigate,
14
+ onSwitchTheme,
15
+ themeMode: _,
16
+ user,
17
+ ...htmlAttributes
18
+ }) => {
19
+ const className = cx(classBase, classNameProp);
20
+ const handleLogout = useCallback(() => {
21
+ logout(loginUrl);
22
+ }, [loginUrl]);
23
+ return /* @__PURE__ */ jsxs(
24
+ Toolbar,
25
+ {
26
+ alignItems: "end",
27
+ className,
28
+ showSeparators: true,
29
+ ...htmlAttributes,
30
+ children: [
31
+ /* @__PURE__ */ jsx(Button, { className: `${classBase}-menuItem`, variant: "secondary", children: "Help" }),
32
+ /* @__PURE__ */ jsxs(Button, { className: `${classBase}-menuItem`, variant: "secondary", children: [
33
+ "History ",
34
+ /* @__PURE__ */ jsx("span", { "data-icon": "history" })
35
+ ] }),
36
+ /* @__PURE__ */ jsxs(Button, { className: `${classBase}-menuItem`, variant: "secondary", children: [
37
+ "View ",
38
+ /* @__PURE__ */ jsx("span", { "data-icon": "settings" })
39
+ ] }),
40
+ /* @__PURE__ */ jsx(
41
+ Button,
42
+ {
43
+ className: `${classBase}-menuItem`,
44
+ onClick: handleLogout,
45
+ variant: "secondary",
46
+ children: "Log out"
47
+ }
48
+ )
49
+ ]
50
+ }
51
+ );
52
+ };
53
+
54
+ export { AppHeader };
55
+ //# sourceMappingURL=AppHeader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AppHeader.js","sources":["../../src/app-header/AppHeader.tsx"],"sourcesContent":["import { HTMLAttributes, useCallback } from \"react\";\nimport { VuuUser } from \"../shell\";\n// import { UserProfile } from \"../user-profile\";\n// import { ThemeSwitch } from \"../theme-switch\";\nimport { Toolbar } from \"@vuu-ui/vuu-ui-controls\";\nimport { ThemeMode } from \"@vuu-ui/vuu-utils\";\nimport cx from \"clsx\";\nimport { logout } from \"../login\";\n\nimport { Button } from \"@salt-ds/core\";\nimport \"./AppHeader.css\";\n\nconst classBase = \"vuuAppHeader\";\nexport interface AppHeaderProps extends HTMLAttributes<HTMLDivElement> {\n layoutId: string;\n loginUrl?: string;\n onNavigate: (id: string) => void;\n onSwitchTheme?: (mode: ThemeMode) => void;\n themeMode?: ThemeMode;\n user: VuuUser;\n}\n\nexport const AppHeader = ({\n className: classNameProp,\n layoutId,\n loginUrl,\n onNavigate,\n onSwitchTheme,\n themeMode: _,\n user,\n ...htmlAttributes\n}: AppHeaderProps) => {\n const className = cx(classBase, classNameProp);\n // const handleSwitchTheme = useCallback(\n // (mode: ThemeMode) => onSwitchTheme?.(mode),\n // [onSwitchTheme]\n // );\n\n const handleLogout = useCallback(() => {\n logout(loginUrl);\n }, [loginUrl]);\n\n return (\n <Toolbar\n alignItems=\"end\"\n className={className}\n showSeparators\n {...htmlAttributes}\n >\n <Button className={`${classBase}-menuItem`} variant=\"secondary\">\n Help\n </Button>\n <Button className={`${classBase}-menuItem`} variant=\"secondary\">\n History <span data-icon=\"history\" />\n </Button>\n <Button className={`${classBase}-menuItem`} variant=\"secondary\">\n View <span data-icon=\"settings\" />\n </Button>\n <Button\n className={`${classBase}-menuItem`}\n onClick={handleLogout}\n variant=\"secondary\"\n >\n Log out\n </Button>\n {/* <ThemeSwitch\n data-align=\"right\"\n defaultMode={themeMode}\n onChange={handleSwitchTheme}\n /> */}\n {/* <UserProfile\n layoutId={layoutId}\n loginUrl={loginUrl}\n onNavigate={onNavigate}\n user={user}\n /> */}\n </Toolbar>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAYA,MAAM,SAAY,GAAA,cAAA,CAAA;AAUX,MAAM,YAAY,CAAC;AAAA,EACxB,SAAW,EAAA,aAAA;AAAA,EACX,QAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAW,EAAA,CAAA;AAAA,EACX,IAAA;AAAA,EACA,GAAG,cAAA;AACL,CAAsB,KAAA;AACpB,EAAM,MAAA,SAAA,GAAY,EAAG,CAAA,SAAA,EAAW,aAAa,CAAA,CAAA;AAM7C,EAAM,MAAA,YAAA,GAAe,YAAY,MAAM;AACrC,IAAA,MAAA,CAAO,QAAQ,CAAA,CAAA;AAAA,GACjB,EAAG,CAAC,QAAQ,CAAC,CAAA,CAAA;AAEb,EACE,uBAAA,IAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,UAAW,EAAA,KAAA;AAAA,MACX,SAAA;AAAA,MACA,cAAc,EAAA,IAAA;AAAA,MACb,GAAG,cAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,UAAO,SAAW,EAAA,CAAA,EAAG,SAAS,CAAa,SAAA,CAAA,EAAA,OAAA,EAAQ,aAAY,QAEhE,EAAA,MAAA,EAAA,CAAA;AAAA,6BACC,MAAO,EAAA,EAAA,SAAA,EAAW,GAAG,SAAS,CAAA,SAAA,CAAA,EAAa,SAAQ,WAAY,EAAA,QAAA,EAAA;AAAA,UAAA,UAAA;AAAA,0BACtD,GAAA,CAAC,MAAK,EAAA,EAAA,WAAA,EAAU,SAAU,EAAA,CAAA;AAAA,SACpC,EAAA,CAAA;AAAA,6BACC,MAAO,EAAA,EAAA,SAAA,EAAW,GAAG,SAAS,CAAA,SAAA,CAAA,EAAa,SAAQ,WAAY,EAAA,QAAA,EAAA;AAAA,UAAA,OAAA;AAAA,0BACzD,GAAA,CAAC,MAAK,EAAA,EAAA,WAAA,EAAU,UAAW,EAAA,CAAA;AAAA,SAClC,EAAA,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAW,GAAG,SAAS,CAAA,SAAA,CAAA;AAAA,YACvB,OAAS,EAAA,YAAA;AAAA,YACT,OAAQ,EAAA,WAAA;AAAA,YACT,QAAA,EAAA,SAAA;AAAA,WAAA;AAAA,SAED;AAAA,OAAA;AAAA,KAAA;AAAA,GAYF,CAAA;AAEJ;;;;"}
@@ -0,0 +1,68 @@
1
+ .vuuStatus-container {
2
+ display: flex;
3
+ }
4
+
5
+ .vuuStatus-text {
6
+ align-self: center;
7
+ }
8
+
9
+
10
+ .vuuStatus {
11
+ --vuu-icon-height: 18px;
12
+ --vuu-icon-padding: var(--vuuStatus-padding, 6px);
13
+ --vuu-icon-width: var(--vuuStatus-width, auto);
14
+ --vuu-icon-min-width: var(--vuuStatus-min-width, 20px);
15
+ align-items: center;
16
+ display: inline-flex;
17
+ height: var(--vuu-icon-height);
18
+ justify-content: center;
19
+ min-width: var(--vuu-icon-min-width);
20
+ padding: 0 var(--vuu-icon-padding);
21
+ width: var(--vuu-icon-width);
22
+ position: relative;
23
+ }
24
+
25
+ .vuuStatus[data-icon]::after {
26
+ inset: 0 0 0 0;
27
+ content: '';
28
+ box-shadow: 0 0 0 0 black;
29
+ position: absolute;
30
+ mask: var(--vuu-icon-svg) center center/20px 20px no-repeat;
31
+ -webkit-mask: var(--vuu-icon-svg) center center/20px 20px no-repeat;
32
+ }
33
+
34
+ .vuuActiveStatus::after {
35
+ --vuu-icon-svg: var(--svg-active-status);
36
+ background-color: rgb(0, 255, 0);
37
+ }
38
+
39
+ .vuuConnectingStatus::after {
40
+ --vuu-icon-svg: var(--svg-connecting-status);
41
+ background-color: orange;
42
+ transform: scale(1);
43
+ animation: infinite pulse 1s;
44
+ }
45
+
46
+ .vuuDisconnectedStatus::after {
47
+ --vuu-icon-svg: var(--svg-disconnected-status);
48
+ background-color: red;
49
+ transform: scale(1);
50
+ animation: infinite pulse 0.5s;
51
+ }
52
+
53
+ @keyframes pulse {
54
+ 0% {
55
+ transform: scale(0.95);
56
+ box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.7);
57
+ }
58
+
59
+ 70% {
60
+ transform: scale(1);
61
+ box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
62
+ }
63
+
64
+ 100% {
65
+ transform: scale(0.95);
66
+ box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
67
+ }
68
+ }
@@ -0,0 +1,40 @@
1
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
+ import React, { useState, useEffect } from 'react';
3
+ import cx from 'clsx';
4
+
5
+ const ConnectionStatusIcon = ({
6
+ connectionStatus,
7
+ className,
8
+ element = "span",
9
+ ...props
10
+ }) => {
11
+ const [classBase, setClassBase] = useState("vuuConnectingStatus");
12
+ useEffect(() => {
13
+ switch (connectionStatus) {
14
+ case "connected":
15
+ case "reconnected":
16
+ setClassBase("vuuActiveStatus");
17
+ break;
18
+ case "connecting":
19
+ setClassBase("vuuConnectingStatus");
20
+ break;
21
+ case "disconnected":
22
+ setClassBase("vuuDisconnectedStatus");
23
+ break;
24
+ }
25
+ }, [connectionStatus]);
26
+ const statusIcon = React.createElement(element, {
27
+ ...props,
28
+ className: cx("vuuStatus vuuIcon", classBase, className)
29
+ });
30
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs("div", { className: "vuuStatus-container salt-theme", children: [
31
+ statusIcon,
32
+ /* @__PURE__ */ jsxs("div", { className: "vuuStatus-text", children: [
33
+ "Status: ",
34
+ connectionStatus.toUpperCase()
35
+ ] })
36
+ ] }) });
37
+ };
38
+
39
+ export { ConnectionStatusIcon };
40
+ //# sourceMappingURL=ConnectionStatusIcon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConnectionStatusIcon.js","sources":["../../src/connection-status/ConnectionStatusIcon.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport cx from \"clsx\";\n\nimport \"./ConnectionStatusIcon.css\";\n\ntype connectionStatus =\n | \"connected\"\n | \"reconnected\"\n | \"connecting\"\n | \"disconnected\";\n\ninterface ConnectionStatusProps {\n connectionStatus: connectionStatus;\n className?: string;\n props?: unknown;\n element?: string;\n}\n\nexport const ConnectionStatusIcon = ({\n connectionStatus,\n className,\n element = \"span\",\n ...props\n}: ConnectionStatusProps) => {\n const [classBase, setClassBase] = useState<string>(\"vuuConnectingStatus\");\n useEffect(() => {\n switch (connectionStatus) {\n case \"connected\":\n case \"reconnected\":\n setClassBase(\"vuuActiveStatus\");\n break;\n case \"connecting\":\n setClassBase(\"vuuConnectingStatus\");\n break;\n case \"disconnected\":\n setClassBase(\"vuuDisconnectedStatus\");\n break;\n default:\n break;\n }\n }, [connectionStatus]);\n\n const statusIcon = React.createElement(element, {\n ...props,\n className: cx(\"vuuStatus vuuIcon\", classBase, className),\n });\n\n return (\n <>\n <div className=\"vuuStatus-container salt-theme\">\n {statusIcon}\n <div className=\"vuuStatus-text\">\n Status: {connectionStatus.toUpperCase()}\n </div>\n </div>\n </>\n );\n};\n"],"names":[],"mappings":";;;;AAkBO,MAAM,uBAAuB,CAAC;AAAA,EACnC,gBAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAU,GAAA,MAAA;AAAA,EACV,GAAG,KAAA;AACL,CAA6B,KAAA;AAC3B,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAiB,qBAAqB,CAAA,CAAA;AACxE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,QAAQ,gBAAkB;AAAA,MACxB,KAAK,WAAA,CAAA;AAAA,MACL,KAAK,aAAA;AACH,QAAA,YAAA,CAAa,iBAAiB,CAAA,CAAA;AAC9B,QAAA,MAAA;AAAA,MACF,KAAK,YAAA;AACH,QAAA,YAAA,CAAa,qBAAqB,CAAA,CAAA;AAClC,QAAA,MAAA;AAAA,MACF,KAAK,cAAA;AACH,QAAA,YAAA,CAAa,uBAAuB,CAAA,CAAA;AACpC,QAAA,MAAA;AAEA,KACJ;AAAA,GACF,EAAG,CAAC,gBAAgB,CAAC,CAAA,CAAA;AAErB,EAAM,MAAA,UAAA,GAAa,KAAM,CAAA,aAAA,CAAc,OAAS,EAAA;AAAA,IAC9C,GAAG,KAAA;AAAA,IACH,SAAW,EAAA,EAAA,CAAG,mBAAqB,EAAA,SAAA,EAAW,SAAS,CAAA;AAAA,GACxD,CAAA,CAAA;AAED,EAAA,uBAEI,GAAA,CAAA,QAAA,EAAA,EAAA,QAAA,kBAAA,IAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAU,gCACZ,EAAA,QAAA,EAAA;AAAA,IAAA,UAAA;AAAA,oBACD,IAAA,CAAC,KAAI,EAAA,EAAA,SAAA,EAAU,gBAAiB,EAAA,QAAA,EAAA;AAAA,MAAA,UAAA;AAAA,MACrB,iBAAiB,WAAY,EAAA;AAAA,KACxC,EAAA,CAAA;AAAA,GAAA,EACF,CACF,EAAA,CAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,54 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import React, { Suspense, useEffect } from 'react';
3
+ import { registerComponent } from '@vuu-ui/vuu-layout';
4
+ import { FeatureErrorBoundary } from './FeatureErrorBoundary.js';
5
+ import { Loader } from './Loader.js';
6
+ import { importCSS } from './css-module-loader.js';
7
+
8
+ const componentsMap = /* @__PURE__ */ new Map();
9
+ const useCachedFeature = (url) => {
10
+ useEffect(
11
+ () => () => {
12
+ componentsMap.delete(url);
13
+ },
14
+ [url]
15
+ );
16
+ if (!componentsMap.has(url)) {
17
+ componentsMap.set(
18
+ url,
19
+ React.lazy(() => import(
20
+ /* @vite-ignore */
21
+ url
22
+ ))
23
+ );
24
+ }
25
+ const lazyFeature = componentsMap.get(url);
26
+ if (!lazyFeature) {
27
+ throw Error(`Unable to load Lazy Feature at url ${url}`);
28
+ } else {
29
+ return lazyFeature;
30
+ }
31
+ };
32
+ function RawFeature({
33
+ url,
34
+ css,
35
+ ComponentProps: params,
36
+ ...props
37
+ }) {
38
+ if (css) {
39
+ importCSS(css).then((styleSheet) => {
40
+ document.adoptedStyleSheets = [
41
+ ...document.adoptedStyleSheets,
42
+ styleSheet
43
+ ];
44
+ });
45
+ }
46
+ const LazyFeature = useCachedFeature(url);
47
+ return /* @__PURE__ */ jsx(FeatureErrorBoundary, { url, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Loader, {}), children: /* @__PURE__ */ jsx(LazyFeature, { ...props, ...params }) }) });
48
+ }
49
+ const Feature = React.memo(RawFeature);
50
+ Feature.displayName = "Feature";
51
+ registerComponent("Feature", Feature, "view");
52
+
53
+ export { Feature };
54
+ //# sourceMappingURL=Feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Feature.js","sources":["../../src/feature/Feature.tsx"],"sourcesContent":["import React, { Suspense, useEffect } from \"react\";\nimport { registerComponent, ViewProps } from \"@vuu-ui/vuu-layout\";\nimport { FeatureErrorBoundary } from \"./FeatureErrorBoundary\";\nimport { Loader } from \"./Loader\";\nimport { importCSS } from \"./css-module-loader\";\n\n/**\n * Ensure we never lazy load the same component more than once\n */\nconst componentsMap = new Map<string, ReturnType<typeof React.lazy>>();\nconst useCachedFeature = (url: string) => {\n useEffect(\n () => () => {\n componentsMap.delete(url);\n },\n [url]\n );\n\n if (!componentsMap.has(url)) {\n componentsMap.set(\n url,\n React.lazy(() => import(/* @vite-ignore */ url))\n );\n }\n\n const lazyFeature = componentsMap.get(url);\n\n if (!lazyFeature) {\n throw Error(`Unable to load Lazy Feature at url ${url}`);\n } else {\n return lazyFeature;\n }\n};\n\nexport interface FeatureProps<P extends object | undefined = any> {\n /**\n props that will be passed to the lazily loaded component.\n */\n ComponentProps?: P;\n ViewProps?: Partial<Pick<ViewProps, \"closeable\" | \"header\">>;\n css?: string;\n height?: number;\n title?: string;\n /** \n The url of javascript bundle to lazily load. Bundle must provide a default export\n and that export must be a React component.\n */\n url: string;\n width?: number;\n}\n\nfunction RawFeature<Params extends object | undefined>({\n url,\n css,\n ComponentProps: params,\n ...props\n}: FeatureProps<Params>) {\n // useEffect(() => {\n // console.log(\"%cFeature mount\", \"color: green;\");\n // return () => {\n // console.log(\"%cFeature unmount\", \"color:red;\");\n // };\n // }, []);\n\n if (css) {\n // import(/* @vite-ignore */ css, { assert: { type: \"css\" } }).then(\n // (cssModule) => {\n // console.log(\"%cInject Styles\", \"color: blue;font-weight: bold\");\n // document.adoptedStyleSheets = [\n // ...document.adoptedStyleSheets,\n // cssModule.default,\n // ];\n // }\n // );\n // Polyfill until cypress build supports import assertions\n // Note: already fully supported in esbuild and vite\n importCSS(css).then((styleSheet) => {\n document.adoptedStyleSheets = [\n ...document.adoptedStyleSheets,\n styleSheet,\n ];\n });\n }\n\n const LazyFeature = useCachedFeature(url);\n return (\n <FeatureErrorBoundary url={url}>\n <Suspense fallback={<Loader />}>\n <LazyFeature {...props} {...params} />\n </Suspense>\n </FeatureErrorBoundary>\n );\n}\n\n/**\n Feature is a wrapper around React Lazy Loading. It will load a component\n from the given url. That url must resolve to a javascript bundle with a\n single default export. That export must be a React component.\n */\nexport const Feature = React.memo(RawFeature);\nFeature.displayName = \"Feature\";\nregisterComponent(\"Feature\", Feature, \"view\");\n"],"names":[],"mappings":";;;;;;;AASA,MAAM,aAAA,uBAAoB,GAA2C,EAAA,CAAA;AACrE,MAAM,gBAAA,GAAmB,CAAC,GAAgB,KAAA;AACxC,EAAA,SAAA;AAAA,IACE,MAAM,MAAM;AACV,MAAA,aAAA,CAAc,OAAO,GAAG,CAAA,CAAA;AAAA,KAC1B;AAAA,IACA,CAAC,GAAG,CAAA;AAAA,GACN,CAAA;AAEA,EAAA,IAAI,CAAC,aAAA,CAAc,GAAI,CAAA,GAAG,CAAG,EAAA;AAC3B,IAAc,aAAA,CAAA,GAAA;AAAA,MACZ,GAAA;AAAA,MACA,KAAA,CAAM,KAAK,MAAM;AAAA;AAAA,QAA0B,GAAA;AAAA,OAAI,CAAA;AAAA,KACjD,CAAA;AAAA,GACF;AAEA,EAAM,MAAA,WAAA,GAAc,aAAc,CAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAEzC,EAAA,IAAI,CAAC,WAAa,EAAA;AAChB,IAAM,MAAA,KAAA,CAAM,CAAsC,mCAAA,EAAA,GAAG,CAAE,CAAA,CAAA,CAAA;AAAA,GAClD,MAAA;AACL,IAAO,OAAA,WAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AAmBA,SAAS,UAA8C,CAAA;AAAA,EACrD,GAAA;AAAA,EACA,GAAA;AAAA,EACA,cAAgB,EAAA,MAAA;AAAA,EAChB,GAAG,KAAA;AACL,CAAyB,EAAA;AAQvB,EAAA,IAAI,GAAK,EAAA;AAYP,IAAA,SAAA,CAAU,GAAG,CAAA,CAAE,IAAK,CAAA,CAAC,UAAe,KAAA;AAClC,MAAA,QAAA,CAAS,kBAAqB,GAAA;AAAA,QAC5B,GAAG,QAAS,CAAA,kBAAA;AAAA,QACZ,UAAA;AAAA,OACF,CAAA;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AAEA,EAAM,MAAA,WAAA,GAAc,iBAAiB,GAAG,CAAA,CAAA;AACxC,EAAA,2BACG,oBAAqB,EAAA,EAAA,GAAA,EACpB,QAAC,kBAAA,GAAA,CAAA,QAAA,EAAA,EAAS,0BAAW,GAAA,CAAA,MAAA,EAAA,EAAO,CAC1B,EAAA,QAAA,kBAAA,GAAA,CAAC,eAAa,GAAG,KAAA,EAAQ,GAAG,MAAA,EAAQ,GACtC,CACF,EAAA,CAAA,CAAA;AAEJ,CAAA;AAOa,MAAA,OAAA,GAAU,KAAM,CAAA,IAAA,CAAK,UAAU,EAAA;AAC5C,OAAA,CAAQ,WAAc,GAAA,SAAA,CAAA;AACtB,iBAAkB,CAAA,SAAA,EAAW,SAAS,MAAM,CAAA;;;;"}