@unisim/sdk 0.105.1 → 0.107.0
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/README.md +8 -0
- package/dist/AccountLimits.d.ts +7 -0
- package/dist/AccountLimits.d.ts.map +1 -0
- package/dist/AccountLimits.js +145 -0
- package/dist/AccountLimits.js.map +1 -0
- package/dist/ChangelogMenu.d.ts +11 -1
- package/dist/ChangelogMenu.d.ts.map +1 -1
- package/dist/ChangelogMenu.js +94 -72
- package/dist/ChangelogMenu.js.map +1 -1
- package/dist/DropdownSurface.d.ts +24 -1
- package/dist/DropdownSurface.d.ts.map +1 -1
- package/dist/DropdownSurface.js +33 -3
- package/dist/DropdownSurface.js.map +1 -1
- package/dist/SuiteSwitcher.d.ts +19 -5
- package/dist/SuiteSwitcher.d.ts.map +1 -1
- package/dist/SuiteSwitcher.js +111 -112
- package/dist/SuiteSwitcher.js.map +1 -1
- package/dist/UniversalAppsNavBar.d.ts +60 -1
- package/dist/UniversalAppsNavBar.d.ts.map +1 -1
- package/dist/UniversalAppsNavBar.js +75 -33
- package/dist/UniversalAppsNavBar.js.map +1 -1
- package/dist/UserProfile.d.ts +49 -3
- package/dist/UserProfile.d.ts.map +1 -1
- package/dist/UserProfile.js +215 -63
- package/dist/UserProfile.js.map +1 -1
- package/dist/appMarks.d.ts +1 -1
- package/dist/appMarks.d.ts.map +1 -1
- package/dist/appMarks.js +19 -0
- package/dist/appMarks.js.map +1 -1
- package/dist/entitlements.d.ts +55 -0
- package/dist/entitlements.d.ts.map +1 -0
- package/dist/entitlements.js +116 -0
- package/dist/entitlements.js.map +1 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +119 -0
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/menuTheme.d.ts +85 -0
- package/dist/menuTheme.d.ts.map +1 -0
- package/dist/menuTheme.js +195 -0
- package/dist/menuTheme.js.map +1 -0
- package/dist/mockAuth.d.ts.map +1 -1
- package/dist/mockAuth.js +19 -2
- package/dist/mockAuth.js.map +1 -1
- package/dist/types.d.ts +7 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownSurface.d.ts","sourceRoot":"","sources":["../src/DropdownSurface.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AA2Bd;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,aAAgB,CAAA;AAEhD,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,IAAI,EAAE,OAAO,CAAA;IACb,qEAAqE;IACrE,SAAS,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IACxC
|
|
1
|
+
{"version":3,"file":"DropdownSurface.d.ts","sourceRoot":"","sources":["../src/DropdownSurface.tsx"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AA2Bd;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,aAAgB,CAAA;AAEhD,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,IAAI,EAAE,OAAO,CAAA;IACb,qEAAqE;IACrE,SAAS,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IACxC;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACxB;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;IAC5B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACvB,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,YAAY,CAAC,EAAE,aAAa,CAAA;IAC5B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAA;IACzB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;IAC3B,QAAQ,EAAE,SAAS,CAAA;CACpB;AAmCD,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,SAAS,EACT,KAAc,EACd,SAAmB,EACnB,IAAa,EACb,GAAO,EACP,MAAU,EACV,KAAa,EACb,YAAY,EACZ,IAAa,EACb,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,EAAE,oBAAoB,sCAoOtB"}
|
package/dist/DropdownSurface.js
CHANGED
|
@@ -50,7 +50,7 @@ function clamp(value, lo, hi) {
|
|
|
50
50
|
// server so the positioning pass stays warning-free. On the client we want the
|
|
51
51
|
// layout variant so the panel is positioned before the browser paints.
|
|
52
52
|
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
53
|
-
export function DropdownSurface({ open, anchorRef, align = 'left', gap = 8, margin = 8, arrow = false, surfaceStyle, role = 'menu', className, onMouseEnter, onMouseLeave, onRequestClose, children, }) {
|
|
53
|
+
export function DropdownSurface({ open, anchorRef, align = 'left', placement = 'below', side = 'left', gap = 8, margin = 8, arrow = false, surfaceStyle, role = 'menu', className, onMouseEnter, onMouseLeave, onRequestClose, children, }) {
|
|
54
54
|
const menuRef = useRef(null);
|
|
55
55
|
const [mounted, setMounted] = useState(false);
|
|
56
56
|
const [pos, setPos] = useState(null);
|
|
@@ -77,6 +77,36 @@ export function DropdownSurface({ open, anchorRef, align = 'left', gap = 8, marg
|
|
|
77
77
|
// lift, it would overflow again, and the ResizeObserver would flip it
|
|
78
78
|
// back and forth forever. scrollHeight is the content, capped or not.
|
|
79
79
|
const mh = Math.max(menu.scrollHeight, menu.offsetHeight);
|
|
80
|
+
// ── Side placement ──────────────────────────────────────────────────
|
|
81
|
+
// A flyout beside its anchor rather than under it. Same two ideas as the
|
|
82
|
+
// below/above case, rotated 90°: take the preferred side if the panel
|
|
83
|
+
// fits there, else the other side if it fits, else whichever has more
|
|
84
|
+
// room and let the clamp deal with the shortfall.
|
|
85
|
+
if (placement === 'side') {
|
|
86
|
+
const roomLeft = a.left - gap - margin;
|
|
87
|
+
const roomRight = vw - a.right - gap - margin;
|
|
88
|
+
const onLeft = side === 'left'
|
|
89
|
+
? (mw <= roomLeft ? true : mw <= roomRight ? false : roomLeft >= roomRight)
|
|
90
|
+
: (mw <= roomRight ? false : mw <= roomLeft ? true : roomLeft > roomRight);
|
|
91
|
+
const sideLeft = clamp(onLeft ? a.left - gap - mw : a.right + gap, margin, Math.max(margin, vw - mw - margin));
|
|
92
|
+
// Top-aligned to the anchor row, like every submenu, then slid up if
|
|
93
|
+
// the panel would run off the bottom. There is no "flip" on this axis —
|
|
94
|
+
// a flyout is beside its row, so the room it has is the whole viewport
|
|
95
|
+
// height rather than the gap on one side of the trigger.
|
|
96
|
+
const sideMaxHeight = Math.max(MIN_PANEL_HEIGHT, vh - margin * 2);
|
|
97
|
+
const sideHeight = Math.min(mh, sideMaxHeight);
|
|
98
|
+
const sideTop = clamp(a.top, margin, Math.max(margin, vh - sideHeight - margin));
|
|
99
|
+
setPos({
|
|
100
|
+
left: sideLeft,
|
|
101
|
+
top: sideTop,
|
|
102
|
+
// The caret points back at a trigger directly above the panel, which
|
|
103
|
+
// is not this geometry. `arrow` is left unsupported for side flyouts.
|
|
104
|
+
arrowLeft: 16,
|
|
105
|
+
above: false,
|
|
106
|
+
maxHeight: sideMaxHeight,
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
80
110
|
// ── Horizontal ──────────────────────────────────────────────────────
|
|
81
111
|
// Width needs no special case any more: the surface is capped to the
|
|
82
112
|
// viewport in CSS, so `mw` can't exceed it and the clamp always has a
|
|
@@ -123,7 +153,7 @@ export function DropdownSurface({ open, anchorRef, align = 'left', gap = 8, marg
|
|
|
123
153
|
window.removeEventListener('resize', onReflow);
|
|
124
154
|
ro.disconnect();
|
|
125
155
|
};
|
|
126
|
-
}, [open, mounted, align, gap, margin, anchorRef]);
|
|
156
|
+
}, [open, mounted, align, placement, side, gap, margin, anchorRef]);
|
|
127
157
|
// Outside-click + Escape, centralised. The trigger and the portaled panel
|
|
128
158
|
// both count as "inside" so neither dismisses the menu.
|
|
129
159
|
useEffect(() => {
|
|
@@ -202,7 +232,7 @@ export function DropdownSurface({ open, anchorRef, align = 'left', gap = 8, marg
|
|
|
202
232
|
// top edge). Positioned in the same viewport coordinates, painted one layer
|
|
203
233
|
// up so it covers the panel's own border, it looks identical to the child it
|
|
204
234
|
// replaces — and survives the panel becoming scrollable.
|
|
205
|
-
const showArrow = arrow && pos && !pos.above;
|
|
235
|
+
const showArrow = arrow && placement === 'below' && pos && !pos.above;
|
|
206
236
|
const arrowFixedStyle = showArrow
|
|
207
237
|
? {
|
|
208
238
|
...arrowStyle(pos.arrowLeft),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownSurface.js","sourceRoot":"","sources":["../src/DropdownSurface.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EACL,SAAS,EACT,eAAe,EACf,MAAM,EACN,QAAQ,GAIT,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC,iFAAiF;AACjF,2DAA2D;AAC3D,EAAE;AACF,qEAAqE;AACrE,8EAA8E;AAC9E,4CAA4C;AAC5C,EAAE;AACF,wEAAwE;AACxE,8EAA8E;AAC9E,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAC7E,4EAA4E;AAC5E,8EAA8E;AAC9E,gDAAgD;AAChD,EAAE;AACF,8EAA8E;AAC9E,6EAA6E;AAC7E,8EAA8E;AAC9E,4EAA4E;AAC5E,+EAA+E;AAC/E,oEAAoE;AACpE,iFAAiF;AAEjF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"DropdownSurface.js","sourceRoot":"","sources":["../src/DropdownSurface.tsx"],"names":[],"mappings":"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"}
|
package/dist/SuiteSwitcher.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { type ReactNode, type CSSProperties } from 'react';
|
|
2
|
+
import { type MenuTheme } from './menuTheme.js';
|
|
2
3
|
/**
|
|
3
|
-
* Which product the suite menu is being rendered *for*.
|
|
4
|
-
* `ProductCode
|
|
5
|
-
*
|
|
4
|
+
* Which product the suite menu is being rendered *for*. Historically a superset
|
|
5
|
+
* of `ProductCode` — it named the apps that recorded no usage and so had no
|
|
6
|
+
* Postgres enum value (`ai`, `screens`) — but migration 0125 closed that gap,
|
|
7
|
+
* so the two lists now hold the same ids.
|
|
6
8
|
*
|
|
7
9
|
* ⚠️ **`| (string & {})` means every string type-checks here.** That escape
|
|
8
10
|
* hatch is deliberate — the menu should not fail to compile because a new app
|
|
@@ -13,7 +15,7 @@ import { type ReactNode, type CSSProperties } from 'react';
|
|
|
13
15
|
* exact on purpose. Keep this list complete anyway, so nobody ever needs to
|
|
14
16
|
* lean on the hatch.
|
|
15
17
|
*/
|
|
16
|
-
export type SuiteProductId = 'ergo_assess' | 'cyber_assess' | 'workplace_assess' | 'fire_assess' | 'coshh_assess' | 'risk_assess' | 'pdf' | 'webinar' | 'images' | 'exports' | 'qr' | 'polling' | 'signatures' | 'recorder' | 'ai' | 'screens' | 'usb' | 'converter' | 'diy' | 'beam' | 'video' | 'compress' | 'charts' | 'palspayin' | 'central' | (string & {});
|
|
18
|
+
export type SuiteProductId = 'ergo_assess' | 'cyber_assess' | 'workplace_assess' | 'fire_assess' | 'coshh_assess' | 'risk_assess' | 'pdf' | 'webinar' | 'images' | 'exports' | 'qr' | 'polling' | 'signatures' | 'recorder' | 'ai' | 'screens' | 'usb' | 'converter' | 'diy' | 'beam' | 'video' | 'compress' | 'charts' | 'palspayin' | 'blackbook' | 'central' | (string & {});
|
|
17
19
|
export interface SuiteProduct {
|
|
18
20
|
id: SuiteProductId;
|
|
19
21
|
name: string;
|
|
@@ -125,6 +127,18 @@ export interface SuiteSwitcherProps {
|
|
|
125
127
|
* Simulation org. Omit for the Assess suite (closed-source).
|
|
126
128
|
*/
|
|
127
129
|
githubHref?: string;
|
|
130
|
+
/**
|
|
131
|
+
* Colourway for the trigger button and the dropdown panel. `'light'`
|
|
132
|
+
* (default) is what every consumer rendered before 0.107.0;
|
|
133
|
+
* `UniversalAppsNavBar` passes its own `theme` through.
|
|
134
|
+
*
|
|
135
|
+
* ⚠️ The product GLYPHS are not themed and must not be. Each one is a
|
|
136
|
+
* miniature of that product's own app mark, drawn on its own dark tile — so
|
|
137
|
+
* they already read on either surface, and re-colouring them would mean
|
|
138
|
+
* showing somebody a different logo depending on which app they happened to
|
|
139
|
+
* open the menu from.
|
|
140
|
+
*/
|
|
141
|
+
theme?: MenuTheme;
|
|
128
142
|
/**
|
|
129
143
|
* Extra product families shown as collapsible (collapsed by default) groups
|
|
130
144
|
* below the main product list — used by the Assess switcher to surface the
|
|
@@ -206,5 +220,5 @@ export declare const APP_CATEGORY_ORDER: {
|
|
|
206
220
|
label: string;
|
|
207
221
|
}[];
|
|
208
222
|
export declare const DEFAULT_APP_GROUPS: AppGroup[];
|
|
209
|
-
export declare function SuiteSwitcher({ current, products, iconSrc, ariaLabel, children, align, chip, portalHref, portalLabel, githubHref, appGroups, groupedDisplay, hideOtherProducts, disableOpen, style, className, }: SuiteSwitcherProps): import("react/jsx-runtime").JSX.Element;
|
|
223
|
+
export declare function SuiteSwitcher({ current, products, iconSrc, ariaLabel, children, align, chip, portalHref, portalLabel, githubHref, appGroups, groupedDisplay, hideOtherProducts, disableOpen, theme, style, className, }: SuiteSwitcherProps): import("react/jsx-runtime").JSX.Element;
|
|
210
224
|
//# sourceMappingURL=SuiteSwitcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuiteSwitcher.d.ts","sourceRoot":"","sources":["../src/SuiteSwitcher.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"SuiteSwitcher.d.ts","sourceRoot":"","sources":["../src/SuiteSwitcher.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,OAAO,CAAA;AAMd,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAMrD;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,cAAc,GACd,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,aAAa,GACb,KAAK,GACL,SAAS,GACT,QAAQ,GACR,SAAS,GACT,IAAI,GACJ,SAAS,GACT,YAAY,GACZ,UAAU,GACV,IAAI,GACJ,SAAS,GACT,KAAK,GACL,WAAW,GACX,KAAK,GACL,MAAM,GACN,OAAO,GACP,UAAU,GACV,QAAQ,GACR,WAAW,GACX,WAAW,GACX,SAAS,GACT,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAEjB,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,cAAc,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAA;IACZ,sEAAsE;IACtE,KAAK,EAAE,SAAS,CAAA;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,EAAE,UAAU,GAAG,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;CAC/E;AAED,8EAA8E;AAC9E,MAAM,WAAW,QAAQ;IACvB,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,QAAQ,EAAE,YAAY,EAAE,CAAA;IACxB,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,OAAO,EAAE,cAAc,CAAA;IACvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAA;IACzB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACxB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAChD;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,SAAS,CAAA;IACjB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;IACtB;;;;;;;;;;;OAWG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;;;;;;;;;;;;;;OAeG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,uEAAuE;IACvE,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAeD,wBAAgB,MAAM,CAAC,EAAE,KAAU,EAAE,MAAW,EAAE,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,2CAoBtF;AA8ID,eAAO,MAAM,sBAAsB,EAAE,YAAY,EA+ChD,CAAA;AAuBD,eAAO,MAAM,+BAA+B,EAAE,YAAY,EAgMzD,CAAA;AAuBD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,kBAAkB,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAMnE,CAAA;AAED,eAAO,MAAM,kBAAkB,EAAE,QAAQ,EAGD,CAAA;AAuFxC,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,QAAiC,EACjC,OAA8B,EAC9B,SAAS,EACT,QAAQ,EACR,KAAe,EACf,IAAI,EACJ,UAA0C,EAC1C,WAAW,EACX,UAAU,EACV,SAAS,EACT,cAAsB,EACtB,iBAAyB,EACzB,WAAmB,EACnB,KAAe,EACf,KAAK,EACL,SAAS,GACV,EAAE,kBAAkB,2CAyNpB"}
|
package/dist/SuiteSwitcher.js
CHANGED
|
@@ -6,6 +6,7 @@ import { useLanguage } from './provider.js';
|
|
|
6
6
|
import { DropdownSurface } from './DropdownSurface.js';
|
|
7
7
|
import { APP_MARKS, APP_MARK_CSS } from './appMarks.js';
|
|
8
8
|
import { useCanHover } from './hover.js';
|
|
9
|
+
import { MENU } from './menuTheme.js';
|
|
9
10
|
// ──────────────────────────────────────────────────────────────────────────────
|
|
10
11
|
// Default product catalogue
|
|
11
12
|
//
|
|
@@ -199,6 +200,16 @@ export const DEFAULT_UNIVERSAL_APPS_PRODUCTS = [
|
|
|
199
200
|
// The whole of "Handy Apps" for now — see APP_CATEGORY_ORDER.
|
|
200
201
|
category: 'handy',
|
|
201
202
|
},
|
|
203
|
+
{
|
|
204
|
+
id: 'blackbook',
|
|
205
|
+
name: 'Universal BlackBook',
|
|
206
|
+
desc: 'A private address book — your people, your categories, your pace',
|
|
207
|
+
href: 'https://opensource.unisim.co.uk/blackbook',
|
|
208
|
+
glyph: APP_MARKS['blackbook'],
|
|
209
|
+
// Alongside PalsPayIn: both are personal-life admin rather than a document
|
|
210
|
+
// tool (Everyday) or a hobbyist's errand (Geeky).
|
|
211
|
+
category: 'handy',
|
|
212
|
+
},
|
|
202
213
|
{
|
|
203
214
|
id: 'diy',
|
|
204
215
|
name: 'Universal DIY',
|
|
@@ -443,7 +454,7 @@ const DEFAULT_TRIGGER_ICON = 'data:image/svg+xml;utf8,' +
|
|
|
443
454
|
// ──────────────────────────────────────────────────────────────────────────────
|
|
444
455
|
// Component
|
|
445
456
|
// ──────────────────────────────────────────────────────────────────────────────
|
|
446
|
-
export function SuiteSwitcher({ current, products = DEFAULT_SUITE_PRODUCTS, iconSrc = DEFAULT_TRIGGER_ICON, ariaLabel, children, align = 'right', chip, portalHref = 'https://assess.unisim.co.uk', portalLabel, githubHref, appGroups, groupedDisplay = false, hideOtherProducts = false, disableOpen = false, style, className, }) {
|
|
457
|
+
export function SuiteSwitcher({ current, products = DEFAULT_SUITE_PRODUCTS, iconSrc = DEFAULT_TRIGGER_ICON, ariaLabel, children, align = 'right', chip, portalHref = 'https://assess.unisim.co.uk', portalLabel, githubHref, appGroups, groupedDisplay = false, hideOtherProducts = false, disableOpen = false, theme = 'light', style, className, }) {
|
|
447
458
|
useGlyphHoverAnimation();
|
|
448
459
|
const { language } = useLanguage();
|
|
449
460
|
const resolvedAriaLabel = ariaLabel ?? t(language, 'suite.switch_product');
|
|
@@ -521,79 +532,67 @@ export function SuiteSwitcher({ current, products = DEFAULT_SUITE_PRODUCTS, icon
|
|
|
521
532
|
// wrapper — a flex item defaults to min-width:auto and would keep
|
|
522
533
|
// the trigger at its intrinsic width, hard-clipping the product name
|
|
523
534
|
// instead of letting it ellipsize.
|
|
524
|
-
style: { cursor: disableOpen ? 'default' : 'pointer', display: 'inline-flex', alignItems: 'center', gap: 6, minWidth: 0 }, children: [children, !disableOpen && _jsx(SwitcherChevron, { open: open })] })) : (_jsx("button", { type: "button", "aria-label": resolvedAriaLabel, "aria-expanded": open, "aria-haspopup": "true", onClick: () => { if (!disableOpen)
|
|
525
|
-
setOpen((v) => !v); }, onFocus: hoverOpen, style: triggerStyle(open), children: _jsx("img", { src: iconSrc, alt: "", "aria-hidden": true, style: { width: 28, height: 28, display: 'block' } }) })), _jsxs(DropdownSurface, { open: open, anchorRef: wrapRef, align: align, arrow: true, role: "menu", surfaceStyle: menuSurfaceStyle, onMouseEnter: hoverOpen, onMouseLeave: hoverClose, onRequestClose: () => setOpen(false), children: [!hideOtherProducts && (_jsxs(_Fragment, { children: [_jsxs("a", { role: "menuitem", href: portalHref, className: "unisim-suite-row", style: portalItemStyle, onMouseEnter: (e) => { e.currentTarget.style.background =
|
|
535
|
+
style: { cursor: disableOpen ? 'default' : 'pointer', display: 'inline-flex', alignItems: 'center', gap: 6, minWidth: 0 }, children: [children, !disableOpen && _jsx(SwitcherChevron, { open: open, theme: theme })] })) : (_jsx("button", { type: "button", "aria-label": resolvedAriaLabel, "aria-expanded": open, "aria-haspopup": "true", onClick: () => { if (!disableOpen)
|
|
536
|
+
setOpen((v) => !v); }, onFocus: hoverOpen, style: triggerStyle(open, theme), children: _jsx("img", { src: iconSrc, alt: "", "aria-hidden": true, style: { width: 28, height: 28, display: 'block' } }) })), _jsxs(DropdownSurface, { open: open, anchorRef: wrapRef, align: align, arrow: true, role: "menu", surfaceStyle: menuSurfaceStyle(theme), onMouseEnter: hoverOpen, onMouseLeave: hoverClose, onRequestClose: () => setOpen(false), children: [!hideOtherProducts && (_jsxs(_Fragment, { children: [_jsxs("a", { role: "menuitem", href: portalHref, className: "unisim-suite-row", style: portalItemStyle, onMouseEnter: (e) => { e.currentTarget.style.background = MENU[theme].accentBg; }, onMouseLeave: (e) => { e.currentTarget.style.background = 'transparent'; }, children: [_jsx("span", { className: "unisim-suite-glyph", style: glyphStyle, children: iconSrc && iconSrc !== DEFAULT_TRIGGER_ICON
|
|
526
537
|
? _jsx("img", { src: iconSrc, alt: "", "aria-hidden": true, style: portalIconImgStyle })
|
|
527
|
-
: UNISIM_GLYPH }), _jsxs("span", { style: { flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx("span", { style: portalEyebrowStyle, children: resolvedPortalLabel.eyebrow }), _jsx("span", { style: portalTitleStyle, children: resolvedPortalLabel.title })] }), chip && _jsx("div", { style: { flexShrink: 0 }, children: chip })] }), _jsx("div", { style: portalDividerStyle, "aria-hidden": true })] })), visibleProducts.map((p) => {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
return (_jsxs(Wrapper, { role: "menuitem", ...wrapperProps, className: "unisim-suite-row", style: itemStyle(isCurrent, isComingSoon), onMouseEnter: (e) => { if (!isDisabled)
|
|
580
|
-
e.currentTarget.style.background = '#f8fafc'; }, onMouseLeave: (e) => { if (!isDisabled)
|
|
581
|
-
e.currentTarget.style.background = 'transparent'; }, children: [_jsx("span", { className: "unisim-suite-glyph", style: glyphStyle, children: p.glyph }), _jsxs("span", { style: { flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsxs("span", { style: {
|
|
582
|
-
fontSize: 14,
|
|
583
|
-
fontWeight: 600,
|
|
584
|
-
color: isComingSoon ? '#64748b' : '#0f172a',
|
|
585
|
-
lineHeight: 1.2,
|
|
586
|
-
display: 'inline-flex',
|
|
587
|
-
alignItems: 'center',
|
|
588
|
-
gap: 6,
|
|
589
|
-
}, children: [p.name, p.flag] }), _jsx("span", { style: { fontSize: 11, color: '#94a3b8', lineHeight: 1.3 }, children: p.desc })] }), isCurrent && _jsx("span", { style: badgeStyle, children: t(language, 'suite.youre_here') }), isComingSoon && _jsx("span", { style: comingSoonBadgeStyle, children: t(language, 'suite.coming_soon') })] }, p.id));
|
|
590
|
-
})] }, group.label)))] })), _jsxs("div", { style: { ...footerStyle, justifyContent: githubHref ? 'space-between' : 'flex-end' }, children: [githubHref && (_jsxs("a", { href: githubHref, target: "_blank", rel: "noreferrer", style: footerLinkStyle, children: [_jsx(GitHubMark, {}), "GitHub \u2197"] })), _jsx("a", { href: "https://www.unisim.co.uk", target: "_blank", rel: "noreferrer", style: footerLinkStyle, children: "unisim.co.uk \u2197" })] })] })] }));
|
|
538
|
+
: UNISIM_GLYPH }), _jsxs("span", { style: { flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx("span", { style: portalEyebrowStyle(theme), children: resolvedPortalLabel.eyebrow }), _jsx("span", { style: portalTitleStyle(theme), children: resolvedPortalLabel.title })] }), chip && _jsx("div", { style: { flexShrink: 0 }, children: chip })] }), _jsx("div", { style: portalDividerStyle(theme), "aria-hidden": true })] })), visibleProducts.map((p) => (_jsx(ProductRow, { product: p, current: current, language: language, theme: theme }, p.id))), appGroups && appGroups.length > 0 && (_jsxs(_Fragment, { children: [!useGroupedDisplay && _jsx("div", { style: portalDividerStyle(theme), "aria-hidden": true }), appGroups.map((group) => (_jsxs("details", { open: group.defaultOpen, style: groupDetailsStyle, children: [_jsxs("summary", { style: groupSummaryStyle(theme), children: [_jsx("span", { children: group.label }), _jsx("span", { style: groupChevronStyle(theme), "aria-hidden": true, children: "\u25B8" })] }), group.products.map((p) => (_jsx(ProductRow, { product: p, current: current, language: language, theme: theme }, p.id)))] }, group.label)))] })), _jsxs("div", { style: { ...footerStyle(theme), justifyContent: githubHref ? 'space-between' : 'flex-end' }, children: [githubHref && (_jsxs("a", { href: githubHref, target: "_blank", rel: "noreferrer", style: footerLinkStyle(theme), children: [_jsx(GitHubMark, {}), "GitHub \u2197"] })), _jsx("a", { href: "https://www.unisim.co.uk", target: "_blank", rel: "noreferrer", style: footerLinkStyle(theme), children: "unisim.co.uk \u2197" })] })] })] }));
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* One product row in the dropdown.
|
|
542
|
+
*
|
|
543
|
+
* Extracted in 0.107.0 because the flat list and the grouped (`groupedDisplay`)
|
|
544
|
+
* list held two byte-identical copies of this markup, indented differently —
|
|
545
|
+
* and the theming pass would have made that two copies to keep in step
|
|
546
|
+
* forever. They were already drifting: only one of them carried the "render
|
|
547
|
+
* <a> only for navigable items" comment explaining why the element type
|
|
548
|
+
* changes.
|
|
549
|
+
*
|
|
550
|
+
* The element type is the accessibility-carrying part. A coming-soon row is a
|
|
551
|
+
* `div` (nothing to activate), the current product is a `button` with
|
|
552
|
+
* `aria-current`, and everything else is a real `<a href>` — so a keyboard
|
|
553
|
+
* user tabs past the rows that go nowhere instead of landing on a link that
|
|
554
|
+
* does not navigate.
|
|
555
|
+
*/
|
|
556
|
+
function ProductRow({ product: p, current, language, theme, }) {
|
|
557
|
+
const isCurrent = p.id === current;
|
|
558
|
+
const isComingSoon = p.comingSoon === true;
|
|
559
|
+
const isDisabled = isCurrent || isComingSoon;
|
|
560
|
+
let Wrapper;
|
|
561
|
+
let wrapperProps;
|
|
562
|
+
if (isComingSoon) {
|
|
563
|
+
Wrapper = 'div';
|
|
564
|
+
wrapperProps = { 'aria-disabled': 'true' };
|
|
565
|
+
}
|
|
566
|
+
else if (isCurrent) {
|
|
567
|
+
Wrapper = 'button';
|
|
568
|
+
wrapperProps = { type: 'button', 'aria-current': 'page' };
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
Wrapper = 'a';
|
|
572
|
+
wrapperProps = { href: p.href };
|
|
573
|
+
}
|
|
574
|
+
return (_jsxs(Wrapper, { role: "menuitem", ...wrapperProps, className: "unisim-suite-row", style: itemStyle(isCurrent, isComingSoon, theme),
|
|
575
|
+
// Written straight to the node rather than held in state: a hover that
|
|
576
|
+
// re-rendered the menu would re-run every row on every pointer move
|
|
577
|
+
// across it. `isDisabled` rows keep their resting fill — the current
|
|
578
|
+
// product's row is already tinted and a coming-soon row is not a target.
|
|
579
|
+
onMouseEnter: (e) => { if (!isDisabled)
|
|
580
|
+
e.currentTarget.style.background = MENU[theme].rowHover; }, onMouseLeave: (e) => { if (!isDisabled)
|
|
581
|
+
e.currentTarget.style.background = 'transparent'; }, children: [_jsx("span", { className: "unisim-suite-glyph", style: glyphStyle, children: p.glyph }), _jsxs("span", { style: { flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsxs("span", { style: {
|
|
582
|
+
fontSize: 14,
|
|
583
|
+
fontWeight: 600,
|
|
584
|
+
color: isComingSoon ? MENU[theme].muted : MENU[theme].text,
|
|
585
|
+
lineHeight: 1.2,
|
|
586
|
+
display: 'inline-flex',
|
|
587
|
+
alignItems: 'center',
|
|
588
|
+
gap: 6,
|
|
589
|
+
}, children: [p.name, p.flag] }), _jsx("span", { style: { fontSize: 11, color: MENU[theme].faint, lineHeight: 1.3 }, children: p.desc })] }), isCurrent && _jsx("span", { style: badgeStyle(theme), children: t(language, 'suite.youre_here') }), isComingSoon && _jsx("span", { style: comingSoonBadgeStyle(theme), children: t(language, 'suite.coming_soon') })] }));
|
|
591
590
|
}
|
|
592
591
|
// ──────────────────────────────────────────────────────────────────────────────
|
|
593
592
|
// Inline styles (kept here rather than in a CSS file so the SDK works in any
|
|
594
593
|
// React host — Tailwind, plain CSS, CSS-in-JS, doesn't matter).
|
|
595
594
|
// ──────────────────────────────────────────────────────────────────────────────
|
|
596
|
-
function triggerStyle(open) {
|
|
595
|
+
function triggerStyle(open, theme) {
|
|
597
596
|
return {
|
|
598
597
|
display: 'inline-flex',
|
|
599
598
|
alignItems: 'center',
|
|
@@ -601,32 +600,32 @@ function triggerStyle(open) {
|
|
|
601
600
|
width: 38,
|
|
602
601
|
height: 38,
|
|
603
602
|
borderRadius: 10,
|
|
604
|
-
border: `1px solid ${open ?
|
|
605
|
-
background: open ?
|
|
603
|
+
border: `1px solid ${open ? MENU[theme].triggerOpenBorder : MENU[theme].triggerBorder}`,
|
|
604
|
+
background: open ? MENU[theme].triggerOpenBg : MENU[theme].triggerBg,
|
|
606
605
|
cursor: 'pointer',
|
|
607
606
|
transition: 'all 150ms cubic-bezier(0.16,1,0.3,1)',
|
|
608
607
|
padding: 0,
|
|
609
|
-
boxShadow: open ?
|
|
608
|
+
boxShadow: open ? MENU[theme].triggerOpenRing : 'none',
|
|
610
609
|
};
|
|
611
610
|
}
|
|
612
611
|
// Visual styling only — positioning, stacking, the caret and the open/close
|
|
613
612
|
// transition are owned by <DropdownSurface />.
|
|
614
|
-
const menuSurfaceStyle = {
|
|
613
|
+
const menuSurfaceStyle = (theme) => ({
|
|
615
614
|
width: 320,
|
|
616
|
-
background:
|
|
617
|
-
border:
|
|
615
|
+
background: MENU[theme].surface,
|
|
616
|
+
border: `1px solid ${MENU[theme].border}`,
|
|
618
617
|
borderRadius: 16,
|
|
619
|
-
boxShadow:
|
|
618
|
+
boxShadow: MENU[theme].shadow,
|
|
620
619
|
padding: 12,
|
|
621
|
-
color:
|
|
622
|
-
};
|
|
620
|
+
color: MENU[theme].text,
|
|
621
|
+
});
|
|
623
622
|
// Small ▾ chevron rendered next to a custom trigger so it visually reads as
|
|
624
623
|
// a dropdown. Rotates 180° when open.
|
|
625
|
-
function SwitcherChevron({ open }) {
|
|
624
|
+
function SwitcherChevron({ open, theme }) {
|
|
626
625
|
return (_jsx("svg", { width: "10", height: "10", viewBox: "0 0 12 12", "aria-hidden": true, style: {
|
|
627
626
|
transition: 'transform 150ms cubic-bezier(0.16,1,0.3,1)',
|
|
628
627
|
transform: open ? 'rotate(180deg)' : 'rotate(0deg)',
|
|
629
|
-
color:
|
|
628
|
+
color: MENU[theme].faint,
|
|
630
629
|
flexShrink: 0,
|
|
631
630
|
}, children: _jsx("path", { d: "M2.5 4.5 L6 8 L9.5 4.5", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
632
631
|
}
|
|
@@ -654,25 +653,25 @@ const portalItemStyle = {
|
|
|
654
653
|
color: 'inherit',
|
|
655
654
|
fontFamily: 'inherit',
|
|
656
655
|
};
|
|
657
|
-
const portalEyebrowStyle = {
|
|
656
|
+
const portalEyebrowStyle = (theme) => ({
|
|
658
657
|
fontSize: 11,
|
|
659
|
-
color:
|
|
658
|
+
color: MENU[theme].muted,
|
|
660
659
|
fontWeight: 600,
|
|
661
660
|
letterSpacing: '0.06em',
|
|
662
661
|
textTransform: 'uppercase',
|
|
663
662
|
lineHeight: 1.2,
|
|
664
|
-
};
|
|
665
|
-
const portalTitleStyle = {
|
|
663
|
+
});
|
|
664
|
+
const portalTitleStyle = (theme) => ({
|
|
666
665
|
fontSize: 13,
|
|
667
|
-
color:
|
|
666
|
+
color: MENU[theme].body,
|
|
668
667
|
lineHeight: 1.3,
|
|
669
|
-
};
|
|
670
|
-
const portalDividerStyle = {
|
|
668
|
+
});
|
|
669
|
+
const portalDividerStyle = (theme) => ({
|
|
671
670
|
height: 1,
|
|
672
|
-
background:
|
|
671
|
+
background: MENU[theme].divider,
|
|
673
672
|
margin: '6px 0 8px',
|
|
674
|
-
};
|
|
675
|
-
function itemStyle(isCurrent, isComingSoon
|
|
673
|
+
});
|
|
674
|
+
function itemStyle(isCurrent, isComingSoon, theme) {
|
|
676
675
|
return {
|
|
677
676
|
display: 'flex',
|
|
678
677
|
alignItems: 'center',
|
|
@@ -680,7 +679,7 @@ function itemStyle(isCurrent, isComingSoon = false) {
|
|
|
680
679
|
padding: '10px 10px',
|
|
681
680
|
borderRadius: 10,
|
|
682
681
|
border: 0,
|
|
683
|
-
background: isCurrent ?
|
|
682
|
+
background: isCurrent ? MENU[theme].accentBg : 'transparent',
|
|
684
683
|
cursor: isCurrent || isComingSoon ? 'default' : 'pointer',
|
|
685
684
|
opacity: isComingSoon ? 0.7 : 1,
|
|
686
685
|
width: '100%',
|
|
@@ -712,7 +711,7 @@ const portalIconImgStyle = {
|
|
|
712
711
|
const groupDetailsStyle = {
|
|
713
712
|
marginTop: 2,
|
|
714
713
|
};
|
|
715
|
-
const groupSummaryStyle = {
|
|
714
|
+
const groupSummaryStyle = (theme) => ({
|
|
716
715
|
display: 'flex',
|
|
717
716
|
alignItems: 'center',
|
|
718
717
|
justifyContent: 'space-between',
|
|
@@ -723,53 +722,53 @@ const groupSummaryStyle = {
|
|
|
723
722
|
fontWeight: 700,
|
|
724
723
|
letterSpacing: '0.06em',
|
|
725
724
|
textTransform: 'uppercase',
|
|
726
|
-
color:
|
|
725
|
+
color: MENU[theme].muted,
|
|
727
726
|
userSelect: 'none',
|
|
728
727
|
borderRadius: 8,
|
|
729
|
-
};
|
|
730
|
-
const groupChevronStyle = {
|
|
728
|
+
});
|
|
729
|
+
const groupChevronStyle = (theme) => ({
|
|
731
730
|
fontSize: 10,
|
|
732
|
-
color:
|
|
733
|
-
};
|
|
734
|
-
const badgeStyle = {
|
|
731
|
+
color: MENU[theme].faint,
|
|
732
|
+
});
|
|
733
|
+
const badgeStyle = (theme) => ({
|
|
735
734
|
fontSize: 9,
|
|
736
735
|
fontWeight: 700,
|
|
737
736
|
letterSpacing: '0.08em',
|
|
738
737
|
textTransform: 'uppercase',
|
|
739
738
|
padding: '2px 7px',
|
|
740
739
|
borderRadius: 999,
|
|
741
|
-
background:
|
|
742
|
-
color:
|
|
743
|
-
border:
|
|
740
|
+
background: MENU[theme].accentBg,
|
|
741
|
+
color: MENU[theme].accentText,
|
|
742
|
+
border: `1px solid ${MENU[theme].accentBorder}`,
|
|
744
743
|
flexShrink: 0,
|
|
745
|
-
};
|
|
746
|
-
const comingSoonBadgeStyle = {
|
|
744
|
+
});
|
|
745
|
+
const comingSoonBadgeStyle = (theme) => ({
|
|
747
746
|
fontSize: 9,
|
|
748
747
|
fontWeight: 700,
|
|
749
748
|
letterSpacing: '0.08em',
|
|
750
749
|
textTransform: 'uppercase',
|
|
751
750
|
padding: '2px 7px',
|
|
752
751
|
borderRadius: 999,
|
|
753
|
-
background:
|
|
754
|
-
color:
|
|
755
|
-
border:
|
|
752
|
+
background: MENU[theme].chipBg,
|
|
753
|
+
color: MENU[theme].chipText,
|
|
754
|
+
border: `1px solid ${MENU[theme].chipBorder}`,
|
|
756
755
|
flexShrink: 0,
|
|
757
|
-
};
|
|
758
|
-
const footerStyle = {
|
|
756
|
+
});
|
|
757
|
+
const footerStyle = (theme) => ({
|
|
759
758
|
display: 'flex',
|
|
760
759
|
justifyContent: 'flex-end',
|
|
761
760
|
alignItems: 'center',
|
|
762
761
|
paddingTop: 10,
|
|
763
762
|
marginTop: 6,
|
|
764
|
-
borderTop:
|
|
765
|
-
};
|
|
766
|
-
const footerLinkStyle = {
|
|
763
|
+
borderTop: `1px solid ${MENU[theme].divider}`,
|
|
764
|
+
});
|
|
765
|
+
const footerLinkStyle = (theme) => ({
|
|
767
766
|
display: 'inline-flex',
|
|
768
767
|
alignItems: 'center',
|
|
769
768
|
gap: 4,
|
|
770
769
|
fontSize: 11,
|
|
771
|
-
color:
|
|
770
|
+
color: MENU[theme].accentText,
|
|
772
771
|
fontWeight: 600,
|
|
773
772
|
textDecoration: 'none',
|
|
774
|
-
};
|
|
773
|
+
});
|
|
775
774
|
//# sourceMappingURL=SuiteSwitcher.js.map
|