@sybilion/uilib 1.3.70 → 1.3.72

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.
@@ -1,6 +1,6 @@
1
1
  import styleInject from 'style-inject';
2
2
 
3
- var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.ChatChrome_root__oh4Ay{border-radius:var(--p-4);display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden;position:relative}.ChatChrome_chatResizeHandle__epfiT{background-color:var(--page-color);border-radius:2.5px;height:calc(100vh + 200px);left:0;opacity:0;position:absolute;right:auto;top:-200px;touch-action:none;transition:opacity .15s ease-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:5px;z-index:30}.ChatChrome_chatResizeHandle__epfiT:before{left:0;right:auto}.ChatChrome_panelHeader__Hkfit{align-items:center;display:flex;flex-shrink:0;justify-content:flex-end;min-height:70px;padding:var(--p-2) var(--p-3);position:absolute;width:100%;z-index:100}.ChatChrome_panelClose__DbKxz{flex-shrink:0}.ChatChrome_content__5qFEi{display:flex;flex:1;flex-direction:column;min-height:0;position:relative}.ChatChrome_attachmentDropzone__OC8UI{inset:0;position:absolute;z-index:200}.ChatChrome_scrollWrapper__m4HMu{flex:1;min-height:0;position:relative}.ChatChrome_scroll__oCxoJ{align-items:flex-end;height:100%;max-height:100%;max-width:100%;padding-bottom:var(--p-2);position:absolute;width:100%;z-index:3}.ChatChrome_scrollbar__Hu0aG{right:0!important}.ChatChrome_scrollInner__K9hIy{min-height:100%;padding-top:var(--p-10)}.ChatChrome_scrollInner__K9hIy:after{content:\"\";display:block;height:170px}.ChatChrome_footer__a5Bpp{backdrop-filter:blur(30px);background-color:var(--background-alpha-800);border-top:1px solid var(--border);bottom:0;box-shadow:0 0 20px 16px var(--background);display:flex;flex-direction:column;position:absolute;width:100%;z-index:50}.ChatChrome_notice__JACIw{color:var(--muted-foreground);font-size:var(--text-xs);left:0;margin-bottom:var(--p-1);pointer-events:none;position:absolute;right:0;text-align:center;top:calc(var(--p-7)*-1)}@media (max-width:768px){.ChatChrome_notice__JACIw{font-size:10px}}.ChatChrome_loader__9-lnf{color:var(--muted-foreground);margin:var(--p-2) var(--p-6) var(--p-10)}.ChatChrome_branchRow__NMDNv{display:flex;flex-wrap:wrap;gap:8px;margin-top:var(--p-6);padding:0 var(--p-6);width:100%}.ChatChrome_branchBtnWrap__aOSVP{display:inline-flex;vertical-align:middle}";
3
+ var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.ChatChrome_root__oh4Ay{border-radius:var(--p-4);display:flex;flex-direction:column;height:100%;min-height:0;overflow:hidden;position:relative}.ChatChrome_chatResizeHandle__epfiT{background-color:var(--page-color);border-radius:2.5px;height:calc(100vh + 200px);left:0;opacity:0;position:absolute;right:auto;top:-200px;touch-action:none;transition:opacity .15s ease-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:5px;z-index:30}.ChatChrome_chatResizeHandle__epfiT:before{left:0;right:auto}.ChatChrome_panelHeader__Hkfit{align-items:center;display:flex;flex-shrink:0;justify-content:flex-end;min-height:70px;padding:var(--p-2) var(--p-3);position:absolute;width:100%;z-index:100}.ChatChrome_panelClose__DbKxz{flex-shrink:0}.ChatChrome_content__5qFEi{display:flex;flex:1;flex-direction:column;min-height:0;position:relative}.ChatChrome_attachmentDropzone__OC8UI{inset:0;position:absolute;z-index:200}.ChatChrome_scrollWrapper__m4HMu{flex:1;min-height:0;position:relative}.ChatChrome_scroll__oCxoJ{align-items:flex-end;height:100%;max-height:100%;max-width:100%;padding-bottom:var(--p-2);position:absolute;width:100%;z-index:3}.ChatChrome_scrollbar__Hu0aG{right:0!important}.ChatChrome_scrollInner__K9hIy{min-height:100%;padding-top:var(--p-10)}.ChatChrome_scrollInner__K9hIy:after{content:\"\";display:block;height:260px}.ChatChrome_footer__a5Bpp{backdrop-filter:blur(30px);background-color:var(--background-alpha-800);border-top:1px solid var(--border);bottom:0;box-shadow:0 0 20px 16px var(--background);display:flex;flex-direction:column;position:absolute;width:100%;z-index:50}.ChatChrome_notice__JACIw{color:var(--muted-foreground);font-size:var(--text-xs);left:0;margin-bottom:var(--p-1);pointer-events:none;position:absolute;right:0;text-align:center;top:calc(var(--p-7)*-1)}@media (max-width:768px){.ChatChrome_notice__JACIw{font-size:10px}}.ChatChrome_loader__9-lnf{color:var(--muted-foreground);margin:var(--p-2) var(--p-6) var(--p-10)}.ChatChrome_branchRow__NMDNv{display:flex;flex-wrap:wrap;gap:8px;margin-top:var(--p-6);padding:0 var(--p-6);width:100%}.ChatChrome_branchBtnWrap__aOSVP{display:inline-flex;vertical-align:middle}";
4
4
  var S = {"root":"ChatChrome_root__oh4Ay","chatResizeHandle":"ChatChrome_chatResizeHandle__epfiT","panelHeader":"ChatChrome_panelHeader__Hkfit","panelClose":"ChatChrome_panelClose__DbKxz","content":"ChatChrome_content__5qFEi","attachmentDropzone":"ChatChrome_attachmentDropzone__OC8UI","scrollWrapper":"ChatChrome_scrollWrapper__m4HMu","scroll":"ChatChrome_scroll__oCxoJ","scrollbar":"ChatChrome_scrollbar__Hu0aG","scrollInner":"ChatChrome_scrollInner__K9hIy","footer":"ChatChrome_footer__a5Bpp","notice":"ChatChrome_notice__JACIw","loader":"ChatChrome_loader__9-lnf","branchRow":"ChatChrome_branchRow__NMDNv","branchBtnWrap":"ChatChrome_branchBtnWrap__aOSVP"};
5
5
  styleInject(css_248z);
6
6
 
@@ -45,17 +45,18 @@ function Renamer({ value = '', onInput, onChange, children, className, placehold
45
45
  setName(value);
46
46
  setIsRenaming(true);
47
47
  }, [value]);
48
- const sizeMap = {
48
+ const inputSizeMap = {
49
49
  sm: 'sm',
50
50
  md: 'md',
51
- lg: 'lg',
51
+ // lg typography comes from Renamer `.size-lg`; avoid Input size-lg (text-base).
52
+ lg: 'md',
52
53
  };
53
54
  const buttonSizeMap = {
54
55
  sm: 'sm',
55
56
  md: 'md',
56
57
  lg: 'lg',
57
58
  };
58
- return (jsx("div", { className: cn(S.root, !value && S.empty, className), onKeyDown: onKeyDown, children: isRenaming ? (jsx(Input, { className: S.input, autoFocus: !isMobile, variant: "clean", size: sizeMap[size], placeholder: placeholder, value: name, onChange: handleInputChange, onBlur: handleBlur, onKeyDown: onKeyDown })) : (jsxs(Fragment, { children: [jsx("span", { className: S.value, children: children }), jsxs(Tooltip, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx(Button, { className: S.button, variant: "ghost", onPointerDown: e => {
59
+ return (jsx("div", { className: cn(S.root, S[`size-${size}`], !value && S.empty, className), onKeyDown: onKeyDown, children: isRenaming ? (jsx(Input, { className: S.input, autoFocus: !isMobile, variant: "clean", size: inputSizeMap[size], placeholder: placeholder, value: name, onChange: handleInputChange, onBlur: handleBlur, onKeyDown: onKeyDown })) : (jsxs(Fragment, { children: [jsx("span", { className: S.value, children: children }), jsxs(Tooltip, { children: [jsx(TooltipTrigger, { asChild: true, children: jsx(Button, { className: S.button, variant: "ghost", onPointerDown: e => {
59
60
  e.preventDefault();
60
61
  e.stopPropagation();
61
62
  }, onClick: e => {
@@ -1,7 +1,7 @@
1
1
  import styleInject from 'style-inject';
2
2
 
3
- var css_248z = ".Renamer_root__26OvT{align-items:center;display:flex}.Renamer_value__G8b1D{padding-right:var(--p-2)}.Renamer_input__KRnGn label{border-radius:var(--p-2)!important;font-size:18px!important}.Renamer_empty__A7xx1 .Renamer_input__KRnGn label{background-color:var(--accent)/.1}.Renamer_button__jKMLc{opacity:.5;padding-left:0;transition:opacity .2s ease-out}.Renamer_root__26OvT:hover .Renamer_button__jKMLc{opacity:1}";
4
- var S = {"root":"Renamer_root__26OvT","value":"Renamer_value__G8b1D","input":"Renamer_input__KRnGn","empty":"Renamer_empty__A7xx1","button":"Renamer_button__jKMLc"};
3
+ var css_248z = ".Renamer_root__26OvT{align-items:center;display:flex}.Renamer_value__G8b1D{padding-right:var(--p-2)}.Renamer_size-lg__dfVhW.Renamer_root__26OvT .Renamer_input__KRnGn,.Renamer_size-lg__dfVhW.Renamer_root__26OvT .Renamer_value__G8b1D{color:var(--foreground);font-family:var(--font-family-heading);font-size:var(--text-2xl);font-weight:300;line-height:var(--text-2xl)}.Renamer_size-lg__dfVhW.Renamer_root__26OvT .Renamer_input__KRnGn{border-radius:var(--p-4);box-shadow:0 0 0 1px var(--border);height:auto;min-height:var(--text-2xl);padding:4px 12px 4px 0}.Renamer_empty__A7xx1.Renamer_size-lg__dfVhW.Renamer_root__26OvT .Renamer_input__KRnGn{background-color:var(--accent)/.1}.Renamer_button__jKMLc{opacity:.5;padding-left:0;transition:opacity .2s ease-out}.Renamer_root__26OvT:hover .Renamer_button__jKMLc{opacity:1}";
4
+ var S = {"root":"Renamer_root__26OvT","value":"Renamer_value__G8b1D","size-lg":"Renamer_size-lg__dfVhW","input":"Renamer_input__KRnGn","empty":"Renamer_empty__A7xx1","button":"Renamer_button__jKMLc"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { S as default };
@@ -12,12 +12,23 @@ import S from './WorkspaceAppSwitcher.styl.js';
12
12
  function entryKey(entry) {
13
13
  return entry.id;
14
14
  }
15
- function IconTile({ iconKey, accentMuted, accent, }) {
16
- const IconComponent = WORKSPACE_APP_ICONS[iconKey];
15
+ function renderIconContent(icon, iconKey) {
16
+ if (icon != null) {
17
+ return (jsx("span", { className: S.icon, "aria-hidden": true, children: icon }));
18
+ }
19
+ if (iconKey != null) {
20
+ const IconComponent = WORKSPACE_APP_ICONS[iconKey];
21
+ if (IconComponent) {
22
+ return jsx(IconComponent, { className: S.icon, "aria-hidden": true });
23
+ }
24
+ }
25
+ return null;
26
+ }
27
+ function IconTile({ icon, iconKey, accentMuted, accent, }) {
17
28
  return (jsx("span", { className: S.iconTile, style: {
18
29
  '--bg-color': accentMuted,
19
30
  '--fg-color': accent,
20
- }, children: jsx(IconComponent, { className: S.icon, "aria-hidden": true }) }));
31
+ }, children: renderIconContent(icon, iconKey) }));
21
32
  }
22
33
  function useResolvedApps(appsStorageKey, defaultApps) {
23
34
  const [apps, setApps] = useState(() => {
@@ -51,11 +62,11 @@ function WorkspaceAppSwitcher({ pathname, onNavigate, authenticated = true, defa
51
62
  if (!displayApp) {
52
63
  return null;
53
64
  }
54
- return (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs(Button, { variant: "ghost", className: S.trigger, "aria-label": "Select workspace app", children: [jsx(IconTile, { iconKey: displayApp.iconKey, accentMuted: displayApp.accentMuted, accent: displayApp.accent }), jsxs("span", { className: S.textCol, children: [jsx("span", { className: S.name, children: displayApp.displayName }), jsx("span", { className: S.sub, children: displayApp.subtitle })] }), jsx(ChevronDown, { className: S.chevron, size: 12, "aria-hidden": true })] }) }), jsx(DropdownMenuContent, { className: S.menuContent, align: "start", sideOffset: 8, elevation: "md", children: apps.map(entry => {
65
+ return (jsxs(DropdownMenu, { children: [jsx(DropdownMenuTrigger, { asChild: true, children: jsxs(Button, { variant: "ghost", className: S.trigger, "aria-label": "Select workspace app", children: [jsx(IconTile, { icon: displayApp.icon, iconKey: displayApp.iconKey, accentMuted: displayApp.accentMuted, accent: displayApp.accent }), jsxs("span", { className: S.textCol, children: [jsx("span", { className: S.name, children: displayApp.displayName }), jsx("span", { className: S.sub, children: displayApp.subtitle })] }), jsx(ChevronDown, { className: S.chevron, size: 12, "aria-hidden": true })] }) }), jsx(DropdownMenuContent, { className: S.menuContent, align: "start", sideOffset: 8, elevation: "md", children: apps.map(entry => {
55
66
  const active = current != null ? entryKey(entry) === entryKey(current) : false;
56
67
  return (jsxs(DropdownMenuItem, { className: cn(S.item, active && S.itemActive), onSelect: () => {
57
68
  onNavigate(entry.href);
58
- }, children: [jsx(IconTile, { iconKey: entry.iconKey, accentMuted: entry.accentMuted, accent: entry.accent }), jsxs("span", { className: S.textCol, children: [jsx("span", { className: S.name, children: entry.displayName }), jsx("span", { className: S.sub, children: entry.subtitle })] })] }, entry.id));
69
+ }, children: [jsx(IconTile, { icon: entry.icon, iconKey: entry.iconKey, accentMuted: entry.accentMuted, accent: entry.accent }), jsxs("span", { className: S.textCol, children: [jsx("span", { className: S.name, children: entry.displayName }), jsx("span", { className: S.sub, children: entry.subtitle })] })] }, entry.id));
59
70
  }) })] }));
60
71
  }
61
72
 
@@ -1,6 +1,6 @@
1
1
  import styleInject from 'style-inject';
2
2
 
3
- var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.WorkspaceAppSwitcher_trigger__s6qYT{align-items:center;background:transparent;border:none;border-radius:12px;color:inherit;cursor:pointer;display:flex;font:inherit;gap:var(--p-2);height:auto;margin-left:var(--p-3)!important;max-width:320px;padding:var(--p-1)!important;padding-right:var(--p-3)!important;text-align:left}.WorkspaceAppSwitcher_trigger__s6qYT:hover{background-color:var(--muted)}@media (max-width:768px){.WorkspaceAppSwitcher_trigger__s6qYT{gap:0;margin-left:0!important;max-width:none;padding-right:var(--p-1)!important}.WorkspaceAppSwitcher_trigger__s6qYT .WorkspaceAppSwitcher_chevron__7kAqO,.WorkspaceAppSwitcher_trigger__s6qYT .WorkspaceAppSwitcher_textCol__K1gfI{display:none}}.WorkspaceAppSwitcher_iconTile__tVDr8{align-items:center;border-radius:10px;color:var(--fg-color);display:flex;flex-shrink:0;height:40px;justify-content:center;position:relative;width:40px}.WorkspaceAppSwitcher_iconTile__tVDr8:after,.WorkspaceAppSwitcher_iconTile__tVDr8:before{border-radius:inherit;content:\"\";display:block;height:100%;position:absolute;width:100%}.WorkspaceAppSwitcher_iconTile__tVDr8:before{background-color:var(--background)}.WorkspaceAppSwitcher_iconTile__tVDr8:after{background-color:var(--bg-color)}.WorkspaceAppSwitcher_icon__Jgw14{color:var(--fg-color)!important;height:22px!important;width:22px!important;z-index:1}.WorkspaceAppSwitcher_textCol__K1gfI{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.WorkspaceAppSwitcher_name__ewMYP{color:var(--foreground);font-size:var(--text-sm);font-weight:600}.WorkspaceAppSwitcher_name__ewMYP,.WorkspaceAppSwitcher_sub__b7w1p{line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.WorkspaceAppSwitcher_sub__b7w1p{color:var(--muted-foreground);font-size:var(--text-xs)}.WorkspaceAppSwitcher_menuContent__4-UNY{max-width:360px;min-width:280px}.WorkspaceAppSwitcher_item__nnufY{align-items:center;cursor:pointer;display:flex;gap:var(--p-3);outline:none;padding:var(--p-3)}.WorkspaceAppSwitcher_itemActive__3mPlO{background-color:var(--muted)}";
3
+ var css_248z = "@media (max-width:768px){:root{--page-x-padding:var(--p-6);--page-y-padding:var(--p-6)}}.WorkspaceAppSwitcher_trigger__s6qYT{align-items:center;background:transparent;border:none;border-radius:12px;color:inherit;cursor:pointer;display:flex;font:inherit;gap:var(--p-2);height:auto;margin-left:var(--p-3)!important;max-width:320px;padding:var(--p-1)!important;padding-right:var(--p-3)!important;text-align:left}.WorkspaceAppSwitcher_trigger__s6qYT:hover{background-color:var(--muted)}@media (max-width:768px){.WorkspaceAppSwitcher_trigger__s6qYT{gap:0;margin-left:0!important;max-width:none;padding-right:var(--p-1)!important}.WorkspaceAppSwitcher_trigger__s6qYT .WorkspaceAppSwitcher_chevron__7kAqO,.WorkspaceAppSwitcher_trigger__s6qYT .WorkspaceAppSwitcher_textCol__K1gfI{display:none}}.WorkspaceAppSwitcher_iconTile__tVDr8{align-items:center;border-radius:10px;color:var(--fg-color);display:flex;flex-shrink:0;height:40px;justify-content:center;position:relative;width:40px}.WorkspaceAppSwitcher_iconTile__tVDr8:after,.WorkspaceAppSwitcher_iconTile__tVDr8:before{border-radius:inherit;content:\"\";display:block;height:100%;position:absolute;width:100%}.WorkspaceAppSwitcher_iconTile__tVDr8:before{background-color:var(--background)}.WorkspaceAppSwitcher_iconTile__tVDr8:after{background-color:var(--bg-color)}.WorkspaceAppSwitcher_icon__Jgw14{align-items:center;display:flex;justify-content:center;z-index:1}.WorkspaceAppSwitcher_icon__Jgw14,.WorkspaceAppSwitcher_icon__Jgw14 svg{color:var(--fg-color)!important;height:22px!important;width:22px!important}.WorkspaceAppSwitcher_textCol__K1gfI{display:flex;flex:1;flex-direction:column;gap:2px;min-width:0}.WorkspaceAppSwitcher_name__ewMYP{color:var(--foreground);font-size:var(--text-sm);font-weight:600}.WorkspaceAppSwitcher_name__ewMYP,.WorkspaceAppSwitcher_sub__b7w1p{line-height:1.2;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.WorkspaceAppSwitcher_sub__b7w1p{color:var(--muted-foreground);font-size:var(--text-xs)}.WorkspaceAppSwitcher_menuContent__4-UNY{max-width:360px;min-width:280px}.WorkspaceAppSwitcher_item__nnufY{align-items:center;cursor:pointer;display:flex;gap:var(--p-3);outline:none;padding:var(--p-3)}.WorkspaceAppSwitcher_itemActive__3mPlO{background-color:var(--muted)}";
4
4
  var S = {"trigger":"WorkspaceAppSwitcher_trigger__s6qYT","textCol":"WorkspaceAppSwitcher_textCol__K1gfI","chevron":"WorkspaceAppSwitcher_chevron__7kAqO","iconTile":"WorkspaceAppSwitcher_iconTile__tVDr8","icon":"WorkspaceAppSwitcher_icon__Jgw14","name":"WorkspaceAppSwitcher_name__ewMYP","sub":"WorkspaceAppSwitcher_sub__b7w1p","menuContent":"WorkspaceAppSwitcher_menuContent__4-UNY","item":"WorkspaceAppSwitcher_item__nnufY","itemActive":"WorkspaceAppSwitcher_itemActive__3mPlO"};
5
5
  styleInject(css_248z);
6
6
 
@@ -1,3 +1,4 @@
1
+ import type { ReactNode } from 'react';
1
2
  import type { WorkspaceAppIconKey } from './workspaceAppIcons';
2
3
  /** Path segment for slug apps: pathname matches `/apps/{id}` */
3
4
  export declare const WORKSPACE_APP_SLUG_BASE_PATH = "/apps";
@@ -7,7 +8,10 @@ export type WorkspaceAppEntry = {
7
8
  id: string;
8
9
  displayName: string;
9
10
  subtitle: string;
10
- iconKey: WorkspaceAppIconKey;
11
+ /** Custom icon for display; not persisted to localStorage. */
12
+ icon?: ReactNode;
13
+ /** Built-in icon lookup when `icon` is omitted (required for localStorage entries). */
14
+ iconKey?: WorkspaceAppIconKey;
11
15
  accent: string;
12
16
  accentMuted: string;
13
17
  href: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sybilion/uilib",
3
- "version": "1.3.70",
3
+ "version": "1.3.72",
4
4
  "description": "Sybilion Design System — React UI components (Webpack + Stylus)",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -88,7 +88,7 @@
88
88
  &::after
89
89
  content ''
90
90
  display block
91
- height 170px
91
+ height 260px
92
92
 
93
93
 
94
94
  // ---------------
@@ -5,12 +5,28 @@
5
5
  .value
6
6
  padding-right var(--p-2)
7
7
 
8
- .input
9
- label
10
- font-size 18px !important
11
- border-radius var(--p-2) !important
8
+ // Matches PageHeader .title h1 typography (page title context).
9
+ .size-lg.root
10
+ .value
11
+ font-family var(--font-family-heading)
12
+ font-weight 300
13
+ font-size var(--text-2xl)
14
+ line-height var(--text-2xl)
15
+ color var(--foreground)
12
16
 
13
- .empty .input label
17
+ .input
18
+ font-family var(--font-family-heading)
19
+ font-weight 300
20
+ font-size var(--text-2xl)
21
+ line-height var(--text-2xl)
22
+ color var(--foreground)
23
+ height auto
24
+ min-height var(--text-2xl)
25
+ padding 4px 12px 4px 0
26
+ border-radius var(--p-4)
27
+ box-shadow 0 0 0 1px var(--border)
28
+
29
+ .empty.size-lg.root .input
14
30
  background-color var(--accent) / 0.1
15
31
 
16
32
  .button
@@ -5,6 +5,7 @@ interface CssExports {
5
5
  'empty': string;
6
6
  'input': string;
7
7
  'root': string;
8
+ 'size-lg': string;
8
9
  'value': string;
9
10
  }
10
11
  export const cssExports: CssExports;
@@ -74,10 +74,11 @@ export function Renamer({
74
74
  setIsRenaming(true);
75
75
  }, [value]);
76
76
 
77
- const sizeMap = {
77
+ const inputSizeMap = {
78
78
  sm: 'sm' as const,
79
79
  md: 'md' as const,
80
- lg: 'lg' as const,
80
+ // lg typography comes from Renamer `.size-lg`; avoid Input size-lg (text-base).
81
+ lg: 'md' as const,
81
82
  };
82
83
 
83
84
  const buttonSizeMap = {
@@ -88,7 +89,7 @@ export function Renamer({
88
89
 
89
90
  return (
90
91
  <div
91
- className={cn(S.root, !value && S.empty, className)}
92
+ className={cn(S.root, S[`size-${size}`], !value && S.empty, className)}
92
93
  onKeyDown={onKeyDown}
93
94
  >
94
95
  {isRenaming ? (
@@ -96,7 +97,7 @@ export function Renamer({
96
97
  className={S.input}
97
98
  autoFocus={!isMobile}
98
99
  variant="clean"
99
- size={sizeMap[size]}
100
+ size={inputSizeMap[size]}
100
101
  placeholder={placeholder}
101
102
  value={name}
102
103
  onChange={handleInputChange}
@@ -59,10 +59,18 @@
59
59
 
60
60
  .icon
61
61
  z-index 1
62
+ display flex
63
+ align-items center
64
+ justify-content center
62
65
  width 22px !important
63
66
  height 22px !important
64
67
  color var(--fg-color) !important
65
68
 
69
+ :global(svg)
70
+ width 22px !important
71
+ height 22px !important
72
+ color var(--fg-color) !important
73
+
66
74
  .textCol
67
75
  display flex
68
76
  flex-direction column
@@ -1,5 +1,5 @@
1
1
  import cn from 'classnames';
2
- import type { CSSProperties } from 'react';
2
+ import type { CSSProperties, ReactNode } from 'react';
3
3
  import { useEffect, useState } from 'react';
4
4
 
5
5
  import { Button } from '#uilib/components/ui/Button/Button';
@@ -32,16 +32,37 @@ function entryKey(entry: WorkspaceAppEntry): string {
32
32
  return entry.id;
33
33
  }
34
34
 
35
+ function renderIconContent(
36
+ icon: ReactNode | undefined,
37
+ iconKey: WorkspaceAppEntry['iconKey'],
38
+ ): ReactNode {
39
+ if (icon != null) {
40
+ return (
41
+ <span className={S.icon} aria-hidden>
42
+ {icon}
43
+ </span>
44
+ );
45
+ }
46
+ if (iconKey != null) {
47
+ const IconComponent = WORKSPACE_APP_ICONS[iconKey];
48
+ if (IconComponent) {
49
+ return <IconComponent className={S.icon} aria-hidden />;
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+
35
55
  function IconTile({
56
+ icon,
36
57
  iconKey,
37
58
  accentMuted,
38
59
  accent,
39
60
  }: {
40
- iconKey: WorkspaceAppEntry['iconKey'];
61
+ icon?: ReactNode;
62
+ iconKey?: WorkspaceAppEntry['iconKey'];
41
63
  accentMuted: string;
42
64
  accent: string;
43
65
  }) {
44
- const IconComponent = WORKSPACE_APP_ICONS[iconKey];
45
66
  return (
46
67
  <span
47
68
  className={S.iconTile}
@@ -52,7 +73,7 @@ function IconTile({
52
73
  } as CSSProperties
53
74
  }
54
75
  >
55
- <IconComponent className={S.icon} aria-hidden />
76
+ {renderIconContent(icon, iconKey)}
56
77
  </span>
57
78
  );
58
79
  }
@@ -116,6 +137,7 @@ export function WorkspaceAppSwitcher({
116
137
  aria-label="Select workspace app"
117
138
  >
118
139
  <IconTile
140
+ icon={displayApp.icon}
119
141
  iconKey={displayApp.iconKey}
120
142
  accentMuted={displayApp.accentMuted}
121
143
  accent={displayApp.accent}
@@ -146,6 +168,7 @@ export function WorkspaceAppSwitcher({
146
168
  }}
147
169
  >
148
170
  <IconTile
171
+ icon={entry.icon}
149
172
  iconKey={entry.iconKey}
150
173
  accentMuted={entry.accentMuted}
151
174
  accent={entry.accent}
@@ -1,3 +1,5 @@
1
+ import type { ReactNode } from 'react';
2
+
1
3
  import type { WorkspaceAppIconKey } from './workspaceAppIcons';
2
4
 
3
5
  /** Path segment for slug apps: pathname matches `/apps/{id}` */
@@ -9,7 +11,10 @@ export type WorkspaceAppEntry = {
9
11
  id: string;
10
12
  displayName: string;
11
13
  subtitle: string;
12
- iconKey: WorkspaceAppIconKey;
14
+ /** Custom icon for display; not persisted to localStorage. */
15
+ icon?: ReactNode;
16
+ /** Built-in icon lookup when `icon` is omitted (required for localStorage entries). */
17
+ iconKey?: WorkspaceAppIconKey;
13
18
  accent: string;
14
19
  accentMuted: string;
15
20
  href: string;