@vuu-ui/vuu-shell 2.1.19-beta.1 → 2.1.19-beta.2

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 (64) hide show
  1. package/package.json +15 -16
  2. package/src/ShellContextProvider.js +20 -0
  3. package/src/app-header/AppHeader.css.js +21 -0
  4. package/src/app-header/AppHeader.js +97 -0
  5. package/src/app-header/index.js +1 -0
  6. package/src/application-provider/ApplicationContext.js +9 -0
  7. package/src/application-provider/ApplicationProvider.js +77 -0
  8. package/src/application-provider/index.js +1 -0
  9. package/src/feature/Feature.js +37 -0
  10. package/src/feature/FeatureErrorBoundary.js +33 -0
  11. package/src/feature/Loader.js +5 -0
  12. package/src/feature/index.js +1 -0
  13. package/src/feature-and-layout-provider/FeatureAndLayoutProvider.js +42 -0
  14. package/src/feature-and-layout-provider/index.js +1 -0
  15. package/src/feature-list/FeatureList.css.js +62 -0
  16. package/src/feature-list/FeatureList.js +128 -0
  17. package/src/feature-list/index.js +1 -0
  18. package/src/get-layout-history.js +7 -0
  19. package/src/index.js +14 -0
  20. package/src/left-nav/LeftNav.css.js +177 -0
  21. package/src/left-nav/LeftNav.js +193 -0
  22. package/src/left-nav/index.js +1 -0
  23. package/src/login/LoginPanel.css.js +72 -0
  24. package/src/login/LoginPanel.js +124 -0
  25. package/src/login/VuuLogo.js +108 -0
  26. package/src/persistence-manager/LocalPersistenceManager.js +156 -0
  27. package/src/persistence-manager/PersistenceManager.js +0 -0
  28. package/src/persistence-manager/PersistenceProvider.js +14 -0
  29. package/src/persistence-manager/RemotePersistenceManager.js +123 -0
  30. package/src/persistence-manager/StaticPersistenceManager.js +53 -0
  31. package/src/persistence-manager/index.js +5 -0
  32. package/src/shell-layout-templates/context-panel/ContextPanel.css.js +66 -0
  33. package/src/shell-layout-templates/context-panel/ContextPanel.js +92 -0
  34. package/src/shell-layout-templates/context-panel/index.js +1 -0
  35. package/src/shell-layout-templates/full-height-left-panel/useFullHeightLeftPanel.js +44 -0
  36. package/src/shell-layout-templates/index.js +3 -0
  37. package/src/shell-layout-templates/inlay-left-panel/useInlayLeftPanel.js +68 -0
  38. package/src/shell-layout-templates/left-main-tabs/useLeftMainTabs.js +32 -0
  39. package/src/shell-layout-templates/side-panel/SidePanel.css.js +9 -0
  40. package/src/shell-layout-templates/side-panel/SidePanel.js +31 -0
  41. package/src/shell-layout-templates/side-panel/index.js +1 -0
  42. package/src/shell-layout-templates/simple-content-pane/useSimpleContentPane.js +38 -0
  43. package/src/shell-layout-templates/useShellLayout.js +15 -0
  44. package/src/shell.css.js +59 -0
  45. package/src/shell.js +108 -0
  46. package/src/theme-switch/ThemeSwitch.css.js +34 -0
  47. package/src/theme-switch/ThemeSwitch.js +50 -0
  48. package/src/theme-switch/index.js +1 -0
  49. package/src/user-settings/SettingsForm.css.js +10 -0
  50. package/src/user-settings/SettingsForm.js +141 -0
  51. package/src/user-settings/UserSettingsPanel.css.js +9 -0
  52. package/src/user-settings/UserSettingsPanel.js +29 -0
  53. package/src/user-settings/index.js +2 -0
  54. package/src/workspace-management/LayoutList.css.js +74 -0
  55. package/src/workspace-management/LayoutList.js +130 -0
  56. package/src/workspace-management/LayoutTile.css.js +31 -0
  57. package/src/workspace-management/LayoutTile.js +41 -0
  58. package/src/workspace-management/SaveLayoutPanel.css.js +123 -0
  59. package/src/workspace-management/SaveLayoutPanel.js +141 -0
  60. package/src/workspace-management/WorkspaceProvider.js +209 -0
  61. package/src/workspace-management/defaultWorkspaceJSON.js +88 -0
  62. package/src/workspace-management/index.js +5 -0
  63. package/src/workspace-management/screenshot-utils.js +13 -0
  64. package/src/workspace-management/useWorkspaceContextMenuItems.js +58 -0
@@ -0,0 +1,177 @@
1
+ const css = `
2
+ .vuuLeftNav {
3
+ --vuuOverflowContainer-height: auto;
4
+ --vuuFeatureList-padding: 195px 32px 16px 24px;
5
+ --salt-navigable-fontWeight-active: 700;
6
+ --vuuTab-background-selected: #ffffff1a;
7
+ --vuuTab-hover-background: #ffffff1a;
8
+ --vuuTab-before-content: none;
9
+ --vuuTab-borderRadius: 6px;
10
+ --vuuTab-height: 40px;
11
+ --vuuTabstrip-fontWeight: 700;
12
+ --vuuTabstrip-width: 100%;
13
+ --svg-demo: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path d=\"M11.3333 11C11.52 11 11.6667 10.8533 11.6667 10.6667C11.6667 10.48 11.52 10.3333 11.3333 10.3333C11.1467 10.3333 11 10.48 11 10.6667C11 10.8533 11.1467 11 11.3333 11Z\"/><path d=\"M5.99999 8.66667C6.36818 8.66667 6.66666 8.36819 6.66666 8C6.66666 7.63181 6.36818 7.33334 5.99999 7.33334C5.63181 7.33334 5.33333 7.63181 5.33333 8C5.33333 8.36819 5.63181 8.66667 5.99999 8.66667Z\"/><path d=\"M8.66667 6C9.03486 6 9.33333 5.70152 9.33333 5.33333C9.33333 4.96514 9.03486 4.66667 8.66667 4.66667C8.29848 4.66667 8 4.96514 8 5.33333C8 5.70152 8.29848 6 8.66667 6Z\"/><path d=\"M8.66667 11.3333C9.03486 11.3333 9.33333 11.0349 9.33333 10.6667C9.33333 10.2985 9.03486 10 8.66667 10C8.29848 10 8 10.2985 8 10.6667C8 11.0349 8.29848 11.3333 8.66667 11.3333Z\"/><path d=\"M11.3333 8.33333C11.52 8.33333 11.6667 8.18666 11.6667 8C11.6667 7.81333 11.52 7.66666 11.3333 7.66666C11.1467 7.66666 11 7.81333 11 8C11 8.18666 11.1467 8.33333 11.3333 8.33333Z\"/><path d=\"M8.66667 8.66667C9.03486 8.66667 9.33333 8.36819 9.33333 8C9.33333 7.63181 9.03486 7.33334 8.66667 7.33334C8.29848 7.33334 8 7.63181 8 8C8 8.36819 8.29848 8.66667 8.66667 8.66667Z\"/><path d=\"M2 2H14V3.33333H2V2Z\"/><path d=\"M3.33333 6.33333C3.88561 6.33333 4.33333 5.88562 4.33333 5.33333C4.33333 4.78105 3.88561 4.33333 3.33333 4.33333C2.78104 4.33333 2.33333 4.78105 2.33333 5.33333C2.33333 5.88562 2.78104 6.33333 3.33333 6.33333Z\"/><path d=\"M3.33333 9C3.88561 9 4.33333 8.55228 4.33333 8C4.33333 7.44772 3.88561 7 3.33333 7C2.78104 7 2.33333 7.44772 2.33333 8C2.33333 8.55228 2.78104 9 3.33333 9Z\"/><path d=\"M3.33333 11.6667C3.88561 11.6667 4.33333 11.2189 4.33333 10.6667C4.33333 10.1144 3.88561 9.66666 3.33333 9.66666C2.78104 9.66666 2.33333 10.1144 2.33333 10.6667C2.33333 11.2189 2.78104 11.6667 3.33333 11.6667Z\"/><path d=\"M11.3333 5.66667C11.52 5.66667 11.6667 5.52 11.6667 5.33333C11.6667 5.14667 11.52 5 11.3333 5C11.1467 5 11 5.14667 11 5.33333C11 5.52 11.1467 5.66667 11.3333 5.66667Z\"/><path d=\"M5.99999 11.3333C6.36818 11.3333 6.66666 11.0349 6.66666 10.6667C6.66666 10.2985 6.36818 10 5.99999 10C5.63181 10 5.33333 10.2985 5.33333 10.6667C5.33333 11.0349 5.63181 11.3333 5.99999 11.3333Z\"/><path d=\"M5.99999 6C6.36818 6 6.66666 5.70152 6.66666 5.33333C6.66666 4.96514 6.36818 4.66667 5.99999 4.66667C5.63181 4.66667 5.33333 4.96514 5.33333 5.33333C5.33333 5.70152 5.63181 6 5.99999 6Z\"/><path d=\"M2 12.6667H14V14H2V12.6667Z\"/></svg>");
14
+ --svg-features: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path d=\"M15.3333 12.6667H14L14 3.33334H15.3333L15.3333 12.6667ZM12.6667 12.6667H11.3333L11.3333 3.33334H12.6667L12.6667 12.6667ZM1.33333 12.6667L9.33333 12.6667C9.69999 12.6667 9.99999 12.3667 9.99999 12V4.00001C9.99999 3.63334 9.69999 3.33334 9.33333 3.33334L1.33333 3.33334C0.966661 3.33334 0.666661 3.63334 0.666661 4.00001L0.666661 12C0.666661 12.3667 0.966661 12.6667 1.33333 12.6667ZM1.99999 4.66667L8.66666 4.66667V11.3333L1.99999 11.3333L1.99999 4.66667Z\"/></svg>");
15
+ --svg-tables: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path d=\"M2 6H4.66667V3.33334H3.33333C2.6 3.33334 2 3.93334 2 4.66667V6ZM2 9.33334H4.66667V6.66667H2V9.33334ZM5.33333 9.33334H8V6.66667H5.33333V9.33334ZM8.66667 9.33334H11.3333V6.66667H8.66667V9.33334ZM5.33333 6H8V3.33334H5.33333V6ZM8.66667 3.33334V6H11.3333V3.33334H8.66667ZM12 9.33334H14.6667V6.66667H12V9.33334ZM3.33333 12.6667H4.66667V10H2V11.3333C2 12.0667 2.6 12.6667 3.33333 12.6667ZM5.33333 12.6667H8V10H5.33333V12.6667ZM8.66667 12.6667H11.3333V10H8.66667V12.6667ZM12 12.6667H13.3333C14.0667 12.6667 14.6667 12.0667 14.6667 11.3333V10H12V12.6667ZM12 3.33334V6H14.6667V4.66667C14.6667 3.93334 14.0667 3.33334 13.3333 3.33334H12Z\"/></svg>");
16
+ --svg-layouts: url("data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\"><path d=\"M15.3333 10H14V11.3333H15.3333V10ZM15.3333 12.6667H14V14H15.3333V12.6667ZM15.3333 7.33333H14V8.66667H15.3333V7.33333ZM10 2H8.66667V3.33333H10V2ZM15.3333 4.66667H14V6H15.3333V4.66667ZM0.666672 14H7.33334V10H0.666672V14ZM2.00001 4.66667H0.666672V6H2.00001V4.66667ZM10 12.6667H8.66667V14H10V12.6667ZM12.6667 2H11.3333V3.33333H12.6667V2ZM15.3333 2H14V3.33333H15.3333V2ZM12.6667 12.6667H11.3333V14H12.6667V12.6667ZM2.00001 7.33333H0.666672V8.66667H2.00001V7.33333ZM7.33334 2H6.00001V3.33333H7.33334V2ZM4.66667 2H3.33334V3.33333H4.66667V2ZM2.00001 2H0.666672V3.33333H2.00001V2Z\"/></svg>");
17
+ --vuu-light-text-primary: #15171b;
18
+ --menu-level-2-width: 0px;
19
+ z-index: 0;
20
+ height: calc(100% - 4px);
21
+ margin-bottom: 4px;
22
+ transition: width .2s ease-out;
23
+ display: flex;
24
+ position: relative;
25
+ overflow: hidden;
26
+ box-shadow: 3px 4px 4px #00000026;
27
+ }
28
+
29
+ .vuuLeftNav-menu-full {
30
+ --menu-width: var(--nav-menu-expanded-width);
31
+ }
32
+
33
+ .vuuLeftNav-menu-icons {
34
+ --menu-width: var(--nav-menu-collapsed-width);
35
+ }
36
+
37
+ .vuuLeftNav-menu-icons-content {
38
+ --menu-width: var(--nav-menu-collapsed-width);
39
+ --menu-level-2-width: var(--nav-menu-content-width);
40
+ }
41
+
42
+ .vuuLeftNav-menu-full-content {
43
+ --menu-width: var(--nav-menu-expanded-width);
44
+ --menu-level-2-width: var(--nav-menu-content-width);
45
+ }
46
+
47
+ .vuuLeftNav-menu-icons-content .vuuLeftNav-menu-secondary, .vuuLeftNav-menu-full-content .vuuLeftNav-menu-secondary {
48
+ display: flex;
49
+ }
50
+
51
+ .vuuLeftNav-menu-primary {
52
+ flex-direction: column;
53
+ flex-grow: 0;
54
+ flex-shrink: 0;
55
+ flex-basis: var(--menu-width);
56
+ background-color: #2a015f;
57
+ height: 100%;
58
+ padding: 32px 16px;
59
+ transition: flex-basis .2s ease-out;
60
+ display: flex;
61
+ container-type: inline-size;
62
+ }
63
+
64
+ .vuuLeftNav-menu-secondary {
65
+ flex: none;
66
+ flex-basis: var(--nav-menu-content-width, 240px);
67
+ z-index: -1;
68
+ display: none;
69
+ top: 0;
70
+ right: 0;
71
+
72
+ & .vuuTabs-tabPanel {
73
+ background: var(--salt-container-primary-background);
74
+ height: 100%;
75
+ padding: 34px 32px 8px 24px;
76
+ }
77
+ }
78
+
79
+ .vuuLeftNav .vuuTabstrip {
80
+ margin-top: 102px;
81
+ }
82
+
83
+ .vuuLeftNav .vuuTab {
84
+ --vuuTab-focusVisible-color: pink;
85
+ --vuu-icon-color: white;
86
+ --vuu-icon-left: 12px;
87
+ --vuu-icon-size: 16px;
88
+ border-left: 4px solid #0000;
89
+ padding: 0 0 0 48px;
90
+ }
91
+
92
+ .vuuLeftNav .vuuTab-selected {
93
+ --vuu-icon-color: var(--salt-navigable-indicator-active);
94
+ border-left: solid 4px var(--salt-navigable-indicator-active);
95
+ }
96
+
97
+ .vuuLeftNav-logo {
98
+ flex: none;
99
+ justify-content: center;
100
+ display: flex;
101
+ }
102
+
103
+ .vuuLeftNav-main {
104
+ flex: auto;
105
+ }
106
+
107
+ .vuuLeftNav-menu {
108
+ color: #fff;
109
+ margin-top: 102px;
110
+ padding: 0;
111
+ }
112
+
113
+ .vuuLeftNav [data-icon="demo"] {
114
+ --vuu-icon-svg: var(--svg-demo);
115
+ }
116
+
117
+ .vuuLeftNav [data-icon="tables"] {
118
+ --vuu-icon-svg: var(--svg-tables);
119
+ }
120
+
121
+ .vuuLeftNav [data-icon="features"] {
122
+ --vuu-icon-svg: var(--svg-features);
123
+ }
124
+
125
+ .vuuLeftNav [data-icon="layouts"] {
126
+ --vuu-icon-svg: var(--svg-layouts);
127
+ }
128
+
129
+ @container (width <= 100px) {
130
+ .vuuTab {
131
+ --vuuTab-padding: 0 0 0 42px;
132
+ }
133
+
134
+ .vuuTab-main {
135
+ display: none !important;
136
+ }
137
+ }
138
+
139
+ .vuuLeftNav-buttonBar {
140
+ flex: 0 0 100px;
141
+ justify-content: center;
142
+ align-items: center;
143
+ display: flex;
144
+ }
145
+
146
+ .vuuLeftNav-toggleButton {
147
+ --vuu-icon-color: var(--vuu-light-text-primary);
148
+ --vuu-icon-left: 11px;
149
+ --vuu-icon-top: 10px;
150
+ --vuu-icon-size: 16px;
151
+ background-color: var(--salt-navigable-indicator-active);
152
+ border-width: 0;
153
+ border-radius: 18px;
154
+ width: 36px;
155
+ height: 36px;
156
+ position: relative;
157
+ }
158
+
159
+ .vuuLeftNav-toggleButton-open {
160
+ --vuu-icon-left: 9px;
161
+ }
162
+
163
+ .vuuLeftNav-drawer {
164
+ background: #fff;
165
+ flex-direction: column;
166
+ flex-shrink: 0;
167
+ align-self: stretch;
168
+ align-items: flex-start;
169
+ height: 100%;
170
+ padding: 0 0 0 24px;
171
+ display: flex;
172
+ box-shadow: 3px 4px 4px #00000026;
173
+ }
174
+
175
+
176
+ `;
177
+ export default css;
@@ -0,0 +1,193 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { VuuLogo } from "@vuu-ui/vuu-icons";
3
+ import { Stack, useLayoutProviderDispatch } from "@vuu-ui/vuu-layout";
4
+ import { Tab, Tabstrip } from "@vuu-ui/vuu-ui-controls";
5
+ import { hasFilterTableFeatureProps } from "@vuu-ui/vuu-utils";
6
+ import { useComponentCssInjection } from "@salt-ds/styles";
7
+ import { useWindow } from "@salt-ds/window";
8
+ import clsx from "clsx";
9
+ import { useCallback, useMemo, useState } from "react";
10
+ import { FeatureList } from "../feature-list/index.js";
11
+ import { LayoutList } from "../workspace-management/index.js";
12
+ import LeftNav from "./LeftNav.css";
13
+ import { useFeatures } from "../feature-and-layout-provider/index.js";
14
+ const classBase = "vuuLeftNav";
15
+ const getDisplayStatus = (activeTabIndex, expanded)=>{
16
+ if (0 === activeTabIndex) return expanded ? "menu-full" : "menu-icons";
17
+ return expanded ? "menu-full-content" : "menu-icons-content";
18
+ };
19
+ const byModule = (f1, f2)=>{
20
+ const t1 = f1.ComponentProps?.tableSchema.table;
21
+ const t2 = f2.ComponentProps?.tableSchema.table;
22
+ if (t1 && t2) {
23
+ const m1 = t1.module.toLowerCase();
24
+ const m2 = t2.module.toLowerCase();
25
+ if (m1 < m2) return -1;
26
+ if (m1 > m2) return 1;
27
+ if (t1.table < t2.table) return -1;
28
+ else if (t1.table > t2.table) return 1;
29
+ else return 0;
30
+ }
31
+ throw Error("Invalid tableFeature");
32
+ };
33
+ const LeftNav_LeftNav = (props)=>{
34
+ const dispatch = useLayoutProviderDispatch();
35
+ const { "data-path": path, defaultExpanded = true, defaultActiveTabIndex = 0, onActiveChange, onTogglePrimaryMenu, sizeCollapsed = 80, sizeContent = 300, sizeExpanded = 240, style: styleProp, ...htmlAttributes } = props;
36
+ const targetWindow = useWindow();
37
+ useComponentCssInjection({
38
+ testId: "vuu-left-nav",
39
+ css: LeftNav,
40
+ window: targetWindow
41
+ });
42
+ const { dynamicFeatures = [], tableFeatures = [] } = useFeatures();
43
+ const [navState, setNavState] = useState({
44
+ activeTabIndex: defaultActiveTabIndex,
45
+ expanded: defaultExpanded
46
+ });
47
+ const tableFeaturesByGroup = useMemo(()=>tableFeatures?.sort(byModule).reduce((acc, filterTableFeature)=>{
48
+ if (!hasFilterTableFeatureProps(filterTableFeature)) return acc;
49
+ {
50
+ const { table } = filterTableFeature.ComponentProps.tableSchema;
51
+ const key = `${table.module} Tables`;
52
+ if (!acc[key]) acc[key] = [];
53
+ return {
54
+ ...acc,
55
+ [key]: acc[key].concat(filterTableFeature)
56
+ };
57
+ }
58
+ }, {}), [
59
+ tableFeatures
60
+ ]);
61
+ const getFullWidth = useCallback((tabIndex, expanded)=>{
62
+ if (0 === tabIndex) return expanded ? sizeExpanded : sizeCollapsed;
63
+ return expanded ? sizeExpanded + sizeContent : sizeCollapsed + sizeContent;
64
+ }, [
65
+ sizeCollapsed,
66
+ sizeContent,
67
+ sizeExpanded
68
+ ]);
69
+ const handleTabSelection = useCallback((activeTabIndex)=>{
70
+ const { activeTabIndex: currentIndex, expanded } = navState;
71
+ const newState = {
72
+ activeTabIndex,
73
+ expanded
74
+ };
75
+ setNavState(newState);
76
+ if (0 === activeTabIndex || 0 === currentIndex) {
77
+ const width = getFullWidth(activeTabIndex, expanded);
78
+ dispatch({
79
+ type: "layout-resize",
80
+ path: "#vuu-side-panel",
81
+ size: width
82
+ });
83
+ }
84
+ onActiveChange?.(activeTabIndex);
85
+ }, [
86
+ dispatch,
87
+ getFullWidth,
88
+ navState,
89
+ onActiveChange
90
+ ]);
91
+ const displayStatus = getDisplayStatus(navState.activeTabIndex, navState.expanded);
92
+ const toggleExpanded = useCallback(()=>{
93
+ const { activeTabIndex, expanded } = navState;
94
+ const primaryMenuExpanded = !expanded;
95
+ const newState = {
96
+ activeTabIndex,
97
+ expanded: primaryMenuExpanded
98
+ };
99
+ setNavState(newState);
100
+ dispatch({
101
+ type: "layout-resize",
102
+ path: "#vuu-side-panel",
103
+ size: getFullWidth(activeTabIndex, primaryMenuExpanded)
104
+ });
105
+ onTogglePrimaryMenu?.(primaryMenuExpanded);
106
+ }, [
107
+ dispatch,
108
+ getFullWidth,
109
+ navState,
110
+ onTogglePrimaryMenu
111
+ ]);
112
+ const style = {
113
+ ...styleProp,
114
+ "--nav-menu-collapsed-width": `${sizeCollapsed}px`,
115
+ "--nav-menu-expanded-width": `${sizeExpanded}px`,
116
+ "--nav-menu-content-width": `${sizeContent}px`
117
+ };
118
+ return /*#__PURE__*/ jsxs("div", {
119
+ ...htmlAttributes,
120
+ className: clsx(classBase, `${classBase}-${displayStatus}`),
121
+ style: style,
122
+ children: [
123
+ /*#__PURE__*/ jsxs("div", {
124
+ className: clsx(`${classBase}-menu-primary`),
125
+ "data-mode": "dark",
126
+ children: [
127
+ /*#__PURE__*/ jsx("div", {
128
+ className: "vuuLeftNav-logo",
129
+ children: /*#__PURE__*/ jsx(VuuLogo, {})
130
+ }),
131
+ /*#__PURE__*/ jsx("div", {
132
+ className: `${classBase}-main`,
133
+ children: /*#__PURE__*/ jsxs(Tabstrip, {
134
+ activeTabIndex: navState.activeTabIndex,
135
+ animateSelectionThumb: false,
136
+ className: `${classBase}-Tabstrip`,
137
+ onActiveChange: handleTabSelection,
138
+ orientation: "vertical",
139
+ children: [
140
+ /*#__PURE__*/ jsx(Tab, {
141
+ "data-icon": "demo",
142
+ label: "DEMO"
143
+ }),
144
+ /*#__PURE__*/ jsx(Tab, {
145
+ "data-icon": "features",
146
+ label: "VUU FEATURES"
147
+ }),
148
+ /*#__PURE__*/ jsx(Tab, {
149
+ "data-icon": "tables",
150
+ label: "VUU TABLES"
151
+ }),
152
+ /*#__PURE__*/ jsx(Tab, {
153
+ "data-icon": "layouts",
154
+ label: "MY LAYOUTS"
155
+ })
156
+ ]
157
+ })
158
+ }),
159
+ /*#__PURE__*/ jsx("div", {
160
+ className: "vuuLeftNav-buttonBar",
161
+ children: /*#__PURE__*/ jsx("button", {
162
+ className: clsx("vuuLeftNav-toggleButton", {
163
+ "vuuLeftNav-toggleButton-open": displayStatus.startsWith("menu-full"),
164
+ "vuuLeftNav-toggleButton-closed": displayStatus.startsWith("menu-icons")
165
+ }),
166
+ "data-icon": displayStatus.startsWith("menu-full") ? "chevron-left" : "chevron-right",
167
+ onClick: toggleExpanded
168
+ })
169
+ })
170
+ ]
171
+ }),
172
+ /*#__PURE__*/ jsxs(Stack, {
173
+ active: navState.activeTabIndex - 1,
174
+ className: `${classBase}-menu-secondary`,
175
+ showTabs: false,
176
+ children: [
177
+ /*#__PURE__*/ jsx(FeatureList, {
178
+ features: dynamicFeatures,
179
+ title: "VUU FEATURES"
180
+ }),
181
+ /*#__PURE__*/ jsx(FeatureList, {
182
+ features: tableFeaturesByGroup,
183
+ title: "VUU TABLES"
184
+ }),
185
+ /*#__PURE__*/ jsx(LayoutList, {
186
+ title: "MY LAYOUTS"
187
+ })
188
+ ]
189
+ })
190
+ ]
191
+ });
192
+ };
193
+ export { LeftNav_LeftNav as LeftNav };
@@ -0,0 +1 @@
1
+ export * from "./LeftNav.js";
@@ -0,0 +1,72 @@
1
+ const css = `
2
+ .vuuLoginPanel {
3
+ --saltInput-paddingLeft: 8px;
4
+ --login-width: 856px;
5
+ --login-height: 550px;
6
+ --hwTextInput-border: solid 1px #ccc;
7
+ --hwTextInput-height: 28px;
8
+ --hwTextInput-padding: 0 12px;
9
+ --hwTextInput-width: 100%;
10
+ --login-row-height: 60px;
11
+ height: var(--login-height);
12
+ width: var(--login-width);
13
+ border-radius: 16px;
14
+ margin: 0 auto;
15
+ display: flex;
16
+ box-shadow: 0 24px 44px #00000040;
17
+ }
18
+
19
+ .vuuLoginPanel .saltInput-primary {
20
+ --saltInput-height: 36px;
21
+ }
22
+
23
+ .vuuLoginPanel-title {
24
+ justify-content: center;
25
+ font-size: 28px;
26
+ font-weight: 400;
27
+ display: flex;
28
+ }
29
+
30
+ .vuuLoginPanel-branding {
31
+ background-color: var(--vuu-color-deep-purple);
32
+ border-radius: 16px 0 0 16px;
33
+ flex-direction: column;
34
+ flex: 0 0 368px;
35
+ justify-content: center;
36
+ align-items: center;
37
+ gap: 40px;
38
+ padding: 40px 100px;
39
+ display: flex;
40
+ }
41
+
42
+ .vuuLoginPanel-form {
43
+ background-color: #fff;
44
+ border-radius: 0 16px 16px 0;
45
+ flex-direction: column;
46
+ flex: auto;
47
+ justify-content: center;
48
+ gap: 32px;
49
+ padding: 0 40px;
50
+ display: flex;
51
+ }
52
+
53
+ .vuuLoginPanel-password {
54
+ --vuu-icon-size: 16px;
55
+ }
56
+
57
+ .vuuLoginPanel-appName {
58
+ color: #fff;
59
+ text-transform: uppercase;
60
+ font-size: 18px;
61
+ font-weight: 700;
62
+ }
63
+
64
+ .vuuLoginPanel-login {
65
+ --saltButton-height: 36px;
66
+ --saltButton-borderRadius: 6px;
67
+ width: 100%;
68
+ }
69
+
70
+
71
+ `;
72
+ export default css;
@@ -0,0 +1,124 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { VuuInput } from "@vuu-ui/vuu-ui-controls";
3
+ import { Button, FormField, FormFieldLabel } from "@salt-ds/core";
4
+ import { useComponentCssInjection } from "@salt-ds/styles";
5
+ import { useWindow } from "@salt-ds/window";
6
+ import clsx from "clsx";
7
+ import { useCallback, useEffect, useRef, useState } from "react";
8
+ import { VuuLogo } from "./VuuLogo.js";
9
+ import LoginPanel from "./LoginPanel.css";
10
+ const classBase = "vuuLoginPanel";
11
+ const LoginPanel_LoginPanel = ({ appName = "Demo App", className, onSubmit, ...htmlAttributes })=>{
12
+ const targetWindow = useWindow();
13
+ useComponentCssInjection({
14
+ testId: "vuu-login-panel",
15
+ css: LoginPanel,
16
+ window: targetWindow
17
+ });
18
+ const [username, setUserName] = useState("");
19
+ const [password, setPassword] = useState("");
20
+ const inputRef = useRef(null);
21
+ const login = ()=>{
22
+ onSubmit(username, password);
23
+ };
24
+ const handleUsername = (evt)=>{
25
+ setUserName(evt.target.value);
26
+ };
27
+ const handlePassword = (evt)=>{
28
+ setPassword(evt.target.value);
29
+ };
30
+ const handleCommitName = useCallback(()=>{
31
+ if (password) onSubmit(username, password);
32
+ }, [
33
+ onSubmit,
34
+ password,
35
+ username
36
+ ]);
37
+ const handleCommitPassword = useCallback(()=>{
38
+ if (username) onSubmit(username, password);
39
+ }, [
40
+ onSubmit,
41
+ password,
42
+ username
43
+ ]);
44
+ const dataIsValid = "" !== username.trim() && "" !== password.trim();
45
+ useEffect(()=>{
46
+ console.log("inputRef", {
47
+ input: inputRef.current
48
+ });
49
+ inputRef.current?.focus();
50
+ }, []);
51
+ return /*#__PURE__*/ jsxs("div", {
52
+ ...htmlAttributes,
53
+ className: clsx(classBase, className),
54
+ children: [
55
+ /*#__PURE__*/ jsxs("div", {
56
+ className: `${classBase}-branding`,
57
+ children: [
58
+ /*#__PURE__*/ jsx(VuuLogo, {}),
59
+ /*#__PURE__*/ jsx("div", {
60
+ className: `${classBase}-appName`,
61
+ children: appName
62
+ })
63
+ ]
64
+ }),
65
+ /*#__PURE__*/ jsxs("div", {
66
+ className: `${classBase}-form`,
67
+ children: [
68
+ /*#__PURE__*/ jsx("div", {
69
+ className: `${classBase}-title`,
70
+ children: "Welcome Back"
71
+ }),
72
+ /*#__PURE__*/ jsxs(FormField, {
73
+ children: [
74
+ /*#__PURE__*/ jsx(FormFieldLabel, {
75
+ children: "Username"
76
+ }),
77
+ /*#__PURE__*/ jsx(VuuInput, {
78
+ bordered: true,
79
+ value: username,
80
+ id: "text-username",
81
+ inputRef: inputRef,
82
+ onChange: handleUsername,
83
+ onCommit: handleCommitName
84
+ })
85
+ ]
86
+ }),
87
+ /*#__PURE__*/ jsxs(FormField, {
88
+ children: [
89
+ /*#__PURE__*/ jsx(FormFieldLabel, {
90
+ children: "Password"
91
+ }),
92
+ /*#__PURE__*/ jsx(VuuInput, {
93
+ bordered: true,
94
+ className: `${classBase}-password`,
95
+ inputProps: {
96
+ type: "password"
97
+ },
98
+ value: password,
99
+ id: "text-password",
100
+ onChange: handlePassword,
101
+ onCommit: handleCommitPassword,
102
+ endAdornment: /*#__PURE__*/ jsx("span", {
103
+ "data-icon": "eye",
104
+ style: {
105
+ cursor: "pointer"
106
+ }
107
+ })
108
+ })
109
+ ]
110
+ }),
111
+ /*#__PURE__*/ jsx(Button, {
112
+ appearance: "solid",
113
+ className: `${classBase}-login`,
114
+ disabled: !dataIsValid,
115
+ onClick: login,
116
+ sentiment: "accented",
117
+ children: "Login"
118
+ })
119
+ ]
120
+ })
121
+ ]
122
+ });
123
+ };
124
+ export { LoginPanel_LoginPanel as LoginPanel };