@xenide-io/the-old-ui-theme 0.5.2 → 0.5.4
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 +47 -34
- package/dist/{index-Od4pIP4F.d.mts → Chip-C5hRFAhe.d.mts} +10 -606
- package/dist/{index-Od4pIP4F.d.ts → Chip-C5hRFAhe.d.ts} +10 -606
- package/dist/{chunk-G53YLHVE.mjs → chunk-E5ZBQYEX.mjs} +59 -9
- package/dist/{chunk-RZXHZWUB.mjs → chunk-SBBKXV35.mjs} +174 -222
- package/dist/index.d.mts +4 -80
- package/dist/index.d.ts +4 -80
- package/dist/index.js +562 -3746
- package/dist/index.mjs +3 -765
- package/dist/suite.d.mts +56 -25
- package/dist/suite.d.ts +56 -25
- package/dist/suite.js +248 -107
- package/dist/suite.mjs +217 -105
- package/dist/ui.d.mts +608 -2
- package/dist/ui.d.ts +608 -2
- package/dist/ui.js +232 -230
- package/dist/ui.mjs +2 -2
- package/package.json +2 -6
- package/scripts/install-theme-dev.sh +60 -0
- package/scripts/sync-posthog-icons.mjs +75 -0
- package/src/app/globals.css +1 -0
- package/src/components/ui/Chip.tsx +36 -18
- package/src/components/ui/CommandPalette.test.tsx +41 -0
- package/src/components/ui/CommandPalette.tsx +58 -9
- package/src/components/ui/DropdownMenu.tsx +50 -11
- package/src/components/ui/SegmentedControl.tsx +2 -1
- package/src/components/ui/SettingsLayout.tsx +19 -5
- package/src/components/ui/ThemeSwitcher.tsx +12 -3
- package/src/components/ui/interaction-primitives.test.tsx +52 -0
- package/src/styles/suite-skin.css +53 -1
- package/src/styles/themes.css +445 -1656
- package/src/suite/components/app-switcher.tsx +32 -25
- package/src/suite/components/command-palette-host.tsx +20 -8
- package/src/suite/components/suite-app-layout.tsx +31 -10
- package/src/suite/components/suite-bottom-nav.tsx +23 -18
- package/src/suite/components/suite-layout.test.tsx +44 -0
- package/src/suite/components/suite-layout.tsx +3 -3
- package/src/suite/components/suite-mobile-drawer.tsx +12 -0
- package/src/suite/components/suite-mobile-header.tsx +15 -9
- package/src/suite/components/suite-notification-bell.tsx +23 -11
- package/src/suite/components/suite-settings-mobile-nav.tsx +2 -0
- package/src/suite/components/suite-sidebar.tsx +54 -43
- package/src/suite/components/suite-user-menu.tsx +54 -26
- package/src/suite/components/today-page-frame.tsx +1 -1
- package/src/suite/icons/app-accents.ts +38 -43
- package/src/suite/icons/glyph-parts.tsx +16 -9
- package/src/suite/icons/glyphs.ts +130 -99
- package/src/suite/lib/apps.ts +1 -1
- package/src/suite/lib/injected.ts +12 -11
- package/src/suite/lib/use-sidebar-width.ts +23 -8
- package/src/components/charts/index.ts +0 -9
- package/src/components/charts/quill/BarChart.tsx +0 -85
- package/src/components/charts/quill/FunnelChart.tsx +0 -49
- package/src/components/charts/quill/InsightShell.tsx +0 -27
- package/src/components/charts/quill/MetricCard.tsx +0 -44
- package/src/components/charts/quill/PieChart.tsx +0 -81
- package/src/components/charts/quill/Sparkline.tsx +0 -57
- package/src/components/charts/quill/TimeSeriesLineChart.tsx +0 -62
- package/src/components/charts/quill/index.ts +0 -9
|
@@ -7,6 +7,7 @@ export interface SuiteSettingsNavItem {
|
|
|
7
7
|
label: string;
|
|
8
8
|
href: string;
|
|
9
9
|
icon: ElementType | ReactNode;
|
|
10
|
+
id?: string;
|
|
10
11
|
testId?: string;
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -59,6 +60,7 @@ export function SuiteSettingsMobileNav({
|
|
|
59
60
|
<button
|
|
60
61
|
key={item.href}
|
|
61
62
|
type="button"
|
|
63
|
+
id={item.id}
|
|
62
64
|
data-test={item.testId}
|
|
63
65
|
onClick={() => onSelect(item.href)}
|
|
64
66
|
aria-current={active ? "page" : undefined}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import Link from
|
|
4
|
-
import { type ReactNode } from
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { type ReactNode } from "react";
|
|
5
5
|
|
|
6
|
-
import { cn } from
|
|
7
|
-
import { Tooltip } from
|
|
8
|
-
import type { SuiteNavIcon } from
|
|
6
|
+
import { cn } from "../lib/cn";
|
|
7
|
+
import { Tooltip } from "../../components/ui/Tooltip";
|
|
8
|
+
import type { SuiteNavIcon } from "./suite-bottom-nav";
|
|
9
9
|
|
|
10
10
|
type CollapsedNode = ReactNode | ((collapsed: boolean) => ReactNode);
|
|
11
11
|
|
|
@@ -13,6 +13,8 @@ export interface SuiteSidebarNavItem {
|
|
|
13
13
|
href: string;
|
|
14
14
|
label: string;
|
|
15
15
|
icon: SuiteNavIcon;
|
|
16
|
+
id?: string;
|
|
17
|
+
dataTest?: string;
|
|
16
18
|
active?: boolean;
|
|
17
19
|
onClick?: () => void;
|
|
18
20
|
badge?: ReactNode;
|
|
@@ -38,8 +40,11 @@ export interface SuiteSidebarProps {
|
|
|
38
40
|
surface?: boolean;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
function renderNode(
|
|
42
|
-
|
|
43
|
+
function renderNode(
|
|
44
|
+
node: CollapsedNode | undefined,
|
|
45
|
+
collapsed: boolean,
|
|
46
|
+
): ReactNode {
|
|
47
|
+
if (typeof node === "function") return node(collapsed);
|
|
43
48
|
return node;
|
|
44
49
|
}
|
|
45
50
|
|
|
@@ -66,42 +71,41 @@ export function SuiteSidebar({
|
|
|
66
71
|
return (
|
|
67
72
|
<div
|
|
68
73
|
className={cn(
|
|
69
|
-
|
|
70
|
-
surface ?
|
|
74
|
+
"flex h-full w-full min-w-0 flex-col text-ph-ink",
|
|
75
|
+
surface ? "bg-ph-surface" : "bg-ph-canvas",
|
|
71
76
|
className,
|
|
72
77
|
)}
|
|
73
78
|
>
|
|
74
79
|
{/* Header */}
|
|
75
80
|
<div
|
|
76
81
|
className={cn(
|
|
77
|
-
|
|
78
|
-
surface ?
|
|
82
|
+
"flex shrink-0 border-b border-ph-border",
|
|
83
|
+
surface ? "bg-ph-surface" : "bg-ph-canvas",
|
|
79
84
|
collapsed
|
|
80
|
-
?
|
|
81
|
-
:
|
|
85
|
+
? "flex-col items-center gap-1 px-1 py-2"
|
|
86
|
+
: "h-14 items-center justify-between gap-2 px-3",
|
|
82
87
|
)}
|
|
83
88
|
>
|
|
84
|
-
<div className={cn(
|
|
89
|
+
<div className={cn("min-w-0", collapsed ? "shrink-0" : "flex-1")}>
|
|
85
90
|
{renderNode(appSwitcher, collapsed)}
|
|
86
91
|
</div>
|
|
87
92
|
{collapsed ? null : (
|
|
88
|
-
<div className="shrink-0">
|
|
93
|
+
<div className="shrink-0">
|
|
94
|
+
{renderNode(notificationBell, collapsed)}
|
|
95
|
+
</div>
|
|
89
96
|
)}
|
|
90
97
|
</div>
|
|
91
98
|
|
|
92
99
|
{/* Nav body */}
|
|
93
100
|
<div
|
|
94
101
|
className={cn(
|
|
95
|
-
|
|
96
|
-
surface ?
|
|
97
|
-
collapsed ?
|
|
102
|
+
"flex min-h-0 flex-1 flex-col overflow-y-auto",
|
|
103
|
+
surface ? "bg-ph-surface" : "bg-ph-canvas",
|
|
104
|
+
collapsed ? "px-1.5 py-2" : "p-2",
|
|
98
105
|
)}
|
|
99
106
|
>
|
|
100
|
-
<nav
|
|
101
|
-
|
|
102
|
-
className="shrink-0 space-y-0.5"
|
|
103
|
-
>
|
|
104
|
-
<div className={cn('mb-3', collapsed && 'flex justify-center')}>
|
|
107
|
+
<nav aria-label="Pages" className="shrink-0 space-y-0.5">
|
|
108
|
+
<div className={cn("mb-3", collapsed && "flex justify-center")}>
|
|
105
109
|
{renderNode(contextSwitcher, collapsed)}
|
|
106
110
|
</div>
|
|
107
111
|
|
|
@@ -113,22 +117,23 @@ export function SuiteSidebar({
|
|
|
113
117
|
<Link
|
|
114
118
|
key={item.label}
|
|
115
119
|
href={item.href}
|
|
116
|
-
|
|
117
|
-
|
|
120
|
+
id={item.id}
|
|
121
|
+
data-test={item.dataTest ?? "nav-link"}
|
|
122
|
+
aria-current={active ? "page" : undefined}
|
|
118
123
|
onClick={item.onClick}
|
|
119
124
|
className={cn(
|
|
120
|
-
|
|
125
|
+
"group relative flex min-h-11 touch-manipulation items-center gap-2.5 rounded-[var(--ph-radius-app)] text-sm font-medium transition-colors",
|
|
121
126
|
active
|
|
122
|
-
?
|
|
123
|
-
:
|
|
127
|
+
? "bg-ph-muted"
|
|
128
|
+
: "text-ph-subtle hover:bg-ph-muted hover:text-ph-ink",
|
|
124
129
|
collapsed
|
|
125
|
-
?
|
|
126
|
-
:
|
|
130
|
+
? "mx-auto size-11 shrink-0 justify-center gap-0 px-0 py-0"
|
|
131
|
+
: "w-full px-2.5 py-2",
|
|
127
132
|
)}
|
|
128
133
|
>
|
|
129
134
|
<span
|
|
130
135
|
className={cn(
|
|
131
|
-
|
|
136
|
+
"relative flex h-4 w-4 shrink-0 items-center justify-center",
|
|
132
137
|
item.iconClassName,
|
|
133
138
|
)}
|
|
134
139
|
aria-hidden
|
|
@@ -140,15 +145,19 @@ export function SuiteSidebar({
|
|
|
140
145
|
</span>
|
|
141
146
|
<span
|
|
142
147
|
className={cn(
|
|
143
|
-
|
|
144
|
-
active
|
|
145
|
-
|
|
148
|
+
"relative truncate",
|
|
149
|
+
active
|
|
150
|
+
? "text-ph-ink"
|
|
151
|
+
: "text-ph-subtle group-hover:text-ph-ink",
|
|
152
|
+
collapsed && "sr-only",
|
|
146
153
|
)}
|
|
147
154
|
>
|
|
148
155
|
{item.label}
|
|
149
156
|
</span>
|
|
150
157
|
{!collapsed && item.badge ? (
|
|
151
|
-
<span className="relative ml-auto shrink-0">
|
|
158
|
+
<span className="relative ml-auto shrink-0">
|
|
159
|
+
{item.badge}
|
|
160
|
+
</span>
|
|
152
161
|
) : null}
|
|
153
162
|
</Link>
|
|
154
163
|
);
|
|
@@ -176,20 +185,22 @@ export function SuiteSidebar({
|
|
|
176
185
|
{/* Footer */}
|
|
177
186
|
<div
|
|
178
187
|
className={cn(
|
|
179
|
-
|
|
180
|
-
surface ?
|
|
181
|
-
collapsed ?
|
|
188
|
+
"shrink-0 border-t border-ph-border",
|
|
189
|
+
surface ? "bg-ph-surface" : "bg-ph-canvas",
|
|
190
|
+
collapsed ? "p-1.5" : "p-3",
|
|
182
191
|
)}
|
|
183
192
|
>
|
|
184
193
|
<div
|
|
185
194
|
className={cn(
|
|
186
|
-
|
|
187
|
-
collapsed
|
|
195
|
+
"flex items-center gap-2",
|
|
196
|
+
collapsed ? "flex-col justify-center" : "min-w-0",
|
|
188
197
|
)}
|
|
189
198
|
>
|
|
190
199
|
{renderNode(userMenu, collapsed)}
|
|
191
|
-
{
|
|
192
|
-
<div className="
|
|
200
|
+
{footerExtras ? (
|
|
201
|
+
<div className={cn("shrink-0", collapsed ? "mt-2" : "ml-auto")}>
|
|
202
|
+
{renderNode(footerExtras, collapsed)}
|
|
203
|
+
</div>
|
|
193
204
|
) : null}
|
|
194
205
|
</div>
|
|
195
206
|
</div>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import Image from
|
|
4
|
-
import { useRouter } from
|
|
5
|
-
import { LogOut, Settings } from
|
|
3
|
+
import Image from "next/image";
|
|
4
|
+
import { useRouter } from "next/navigation";
|
|
5
|
+
import { LogOut, Settings } from "iconoir-react";
|
|
6
6
|
|
|
7
|
-
import { cn } from
|
|
8
|
-
import { DropdownMenu, DropdownItem } from
|
|
7
|
+
import { cn } from "../lib/cn";
|
|
8
|
+
import { DropdownMenu, DropdownItem } from "../../components/ui/DropdownMenu";
|
|
9
9
|
|
|
10
10
|
export interface SuiteUserMenuProps {
|
|
11
11
|
name?: string | null;
|
|
@@ -16,26 +16,32 @@ export interface SuiteUserMenuProps {
|
|
|
16
16
|
onSignOut: () => void;
|
|
17
17
|
/** Fallback letter(s) when there is no avatar image. */
|
|
18
18
|
fallbackInitials?: string;
|
|
19
|
+
/** Show the old desktop sidebar sign-out action beside the avatar. */
|
|
20
|
+
showSignOutAction?: boolean;
|
|
19
21
|
dataTest?: string;
|
|
22
|
+
triggerId?: string;
|
|
23
|
+
triggerDataTest?: string;
|
|
20
24
|
className?: string;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
|
-
function computeInitials(
|
|
24
|
-
|
|
27
|
+
function computeInitials(
|
|
28
|
+
name: string | null | undefined,
|
|
29
|
+
email: string | null | undefined,
|
|
30
|
+
): string {
|
|
31
|
+
const source = (name || email || "?").trim();
|
|
25
32
|
return source
|
|
26
33
|
.split(/[\s@]+/)
|
|
27
34
|
.filter(Boolean)
|
|
28
35
|
.slice(0, 2)
|
|
29
36
|
.map((part) => part[0])
|
|
30
|
-
.join(
|
|
37
|
+
.join("")
|
|
31
38
|
.toUpperCase();
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
/**
|
|
35
|
-
* Suite account context menu — one tap on the avatar opens a small menu
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* logout icon cluttering the mobile chrome).
|
|
42
|
+
* Suite account context menu — one tap on the avatar opens a small menu with
|
|
43
|
+
* profile settings and sign out. Desktop sidebars can also expose the legacy
|
|
44
|
+
* adjacent sign-out action without adding it to mobile chrome.
|
|
39
45
|
*/
|
|
40
46
|
export function SuiteUserMenu({
|
|
41
47
|
name,
|
|
@@ -44,46 +50,51 @@ export function SuiteUserMenu({
|
|
|
44
50
|
settingsHref,
|
|
45
51
|
onSignOut,
|
|
46
52
|
fallbackInitials,
|
|
47
|
-
|
|
53
|
+
showSignOutAction = false,
|
|
54
|
+
dataTest = "suite-user-menu",
|
|
55
|
+
triggerId,
|
|
56
|
+
triggerDataTest,
|
|
48
57
|
className,
|
|
49
58
|
}: SuiteUserMenuProps) {
|
|
50
59
|
const router = useRouter();
|
|
51
60
|
const initials = fallbackInitials ?? computeInitials(name, email);
|
|
52
61
|
|
|
53
62
|
const avatar = (
|
|
54
|
-
<span className="inline-flex h-11 w-11 items-center justify-center rounded-full transition-colors hover:bg-ph-muted">
|
|
63
|
+
<span className="inline-flex h-11 w-11 items-center justify-center rounded-full ring-2 ring-ph-border ring-offset-1 ring-offset-ph-canvas transition-colors hover:bg-ph-muted">
|
|
55
64
|
{image ? (
|
|
56
65
|
<Image
|
|
57
66
|
src={image}
|
|
58
67
|
alt=""
|
|
59
|
-
width={
|
|
60
|
-
height={
|
|
61
|
-
className="h-
|
|
68
|
+
width={40}
|
|
69
|
+
height={40}
|
|
70
|
+
className="h-10 w-10 rounded-full object-cover"
|
|
62
71
|
unoptimized
|
|
63
72
|
/>
|
|
64
73
|
) : (
|
|
65
|
-
<span className="flex h-
|
|
74
|
+
<span className="flex h-10 w-10 items-center justify-center rounded-full bg-ph-muted text-sm font-semibold text-ph-brand">
|
|
66
75
|
{initials}
|
|
67
76
|
</span>
|
|
68
77
|
)}
|
|
69
78
|
</span>
|
|
70
79
|
);
|
|
71
80
|
|
|
72
|
-
|
|
81
|
+
const accountMenu = (
|
|
73
82
|
<DropdownMenu
|
|
74
83
|
trigger={avatar}
|
|
84
|
+
triggerId={triggerId ?? `${dataTest}-trigger`}
|
|
85
|
+
triggerDataTest={triggerDataTest ?? `${dataTest}-trigger`}
|
|
75
86
|
aria-label="Account menu"
|
|
76
87
|
align="end"
|
|
77
88
|
side="bottom"
|
|
78
89
|
sideOffset={6}
|
|
79
90
|
collisionPadding={16}
|
|
80
91
|
modal={false}
|
|
81
|
-
className={className}
|
|
92
|
+
className={showSignOutAction ? undefined : className}
|
|
82
93
|
data-test={dataTest}
|
|
83
94
|
>
|
|
84
95
|
<div className="px-2 py-1.5">
|
|
85
96
|
<p className="truncate text-sm font-medium text-ph-ink">
|
|
86
|
-
{name || email ||
|
|
97
|
+
{name || email || "Account"}
|
|
87
98
|
</p>
|
|
88
99
|
{email ? (
|
|
89
100
|
<p className="truncate text-xs text-ph-mutedtext">{email}</p>
|
|
@@ -97,13 +108,30 @@ export function SuiteUserMenu({
|
|
|
97
108
|
<Settings className="h-4 w-4 text-ph-mutedtext" aria-hidden />
|
|
98
109
|
Profile settings
|
|
99
110
|
</DropdownItem>
|
|
100
|
-
<DropdownItem
|
|
101
|
-
data-test={`${dataTest}-sign-out`}
|
|
102
|
-
onClick={onSignOut}
|
|
103
|
-
>
|
|
111
|
+
<DropdownItem data-test={`${dataTest}-sign-out`} onClick={onSignOut}>
|
|
104
112
|
<LogOut className="h-4 w-4 text-ph-mutedtext" aria-hidden />
|
|
105
113
|
Sign out
|
|
106
114
|
</DropdownItem>
|
|
107
115
|
</DropdownMenu>
|
|
108
116
|
);
|
|
117
|
+
|
|
118
|
+
if (!showSignOutAction) {
|
|
119
|
+
return accountMenu;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<div className={cn("flex min-w-0 items-center gap-2", className)}>
|
|
124
|
+
{accountMenu}
|
|
125
|
+
<button
|
|
126
|
+
type="button"
|
|
127
|
+
data-test={`${dataTest}-visible-sign-out`}
|
|
128
|
+
title="Sign out"
|
|
129
|
+
aria-label="Sign out"
|
|
130
|
+
className="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-lg text-ph-mutedtext transition-colors hover:bg-ph-muted hover:text-ph-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ph-focus-ring"
|
|
131
|
+
onClick={onSignOut}
|
|
132
|
+
>
|
|
133
|
+
<LogOut className="h-4 w-4" aria-hidden />
|
|
134
|
+
</button>
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
109
137
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import type { ReactNode } from "react";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Today page content wrapper with soft
|
|
6
|
+
* Today page content wrapper with a soft themed visual treatment.
|
|
7
7
|
* Does not own scrolling — `#main-content` is the scrollport so sticky headers work.
|
|
8
8
|
* Glow/clouds are absolute and do not create a nested scrollport.
|
|
9
9
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SuiteIconName } from
|
|
1
|
+
import type { SuiteIconName } from "./glyphs";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Per-app brand colours for the suite icon system — the single place hexes
|
|
@@ -8,12 +8,7 @@ import type { SuiteIconName } from './glyphs';
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
export type SuiteAccentSlug =
|
|
11
|
-
|
|
|
12
|
-
| 'tides'
|
|
13
|
-
| 'kraken'
|
|
14
|
-
| 'shellstack'
|
|
15
|
-
| 'crew'
|
|
16
|
-
| 'nakama';
|
|
11
|
+
"turtletime" | "tides" | "kraken" | "shellstack" | "crew" | "nakama";
|
|
17
12
|
|
|
18
13
|
export interface SuiteAppAccent {
|
|
19
14
|
/** Display name (default aria label for app marks). */
|
|
@@ -30,55 +25,55 @@ export interface SuiteAppAccent {
|
|
|
30
25
|
|
|
31
26
|
export const APP_ACCENTS: Record<SuiteAccentSlug, SuiteAppAccent> = {
|
|
32
27
|
turtletime: {
|
|
33
|
-
label:
|
|
34
|
-
accent:
|
|
35
|
-
tile:
|
|
36
|
-
onTile:
|
|
37
|
-
onTileAccent:
|
|
28
|
+
label: "TurtleTime",
|
|
29
|
+
accent: "#3f8f57",
|
|
30
|
+
tile: "#173521",
|
|
31
|
+
onTile: "#f7ead0",
|
|
32
|
+
onTileAccent: "#f3c24e",
|
|
38
33
|
},
|
|
39
34
|
tides: {
|
|
40
|
-
label:
|
|
41
|
-
accent:
|
|
42
|
-
tile:
|
|
43
|
-
onTile:
|
|
44
|
-
onTileAccent:
|
|
35
|
+
label: "Tides",
|
|
36
|
+
accent: "#a63bb5",
|
|
37
|
+
tile: "#8f2d96",
|
|
38
|
+
onTile: "#ffffff",
|
|
39
|
+
onTileAccent: "#bfe3ff",
|
|
45
40
|
},
|
|
46
41
|
kraken: {
|
|
47
|
-
label:
|
|
48
|
-
accent:
|
|
49
|
-
tile:
|
|
50
|
-
onTile:
|
|
51
|
-
onTileAccent:
|
|
42
|
+
label: "Kraken",
|
|
43
|
+
accent: "#737373",
|
|
44
|
+
tile: "#191919",
|
|
45
|
+
onTile: "#ffffff",
|
|
46
|
+
onTileAccent: "#d4d4d4",
|
|
52
47
|
},
|
|
53
48
|
shellstack: {
|
|
54
|
-
label:
|
|
55
|
-
accent:
|
|
56
|
-
tile:
|
|
57
|
-
onTile:
|
|
58
|
-
onTileAccent:
|
|
49
|
+
label: "ShellStack",
|
|
50
|
+
accent: "#5e5893",
|
|
51
|
+
tile: "#5e5893",
|
|
52
|
+
onTile: "#ffffff",
|
|
53
|
+
onTileAccent: "#c4a7e7",
|
|
59
54
|
},
|
|
60
55
|
crew: {
|
|
61
|
-
label:
|
|
62
|
-
accent:
|
|
63
|
-
tile:
|
|
64
|
-
onTile:
|
|
65
|
-
onTileAccent:
|
|
56
|
+
label: "Crew",
|
|
57
|
+
accent: "#0891b2",
|
|
58
|
+
tile: "#155e75",
|
|
59
|
+
onTile: "#ffffff",
|
|
60
|
+
onTileAccent: "#a5f3fc",
|
|
66
61
|
},
|
|
67
62
|
nakama: {
|
|
68
|
-
label:
|
|
69
|
-
accent:
|
|
70
|
-
tile:
|
|
71
|
-
onTile:
|
|
72
|
-
onTileAccent:
|
|
63
|
+
label: "Nakama",
|
|
64
|
+
accent: "#b8eb44",
|
|
65
|
+
tile: "#17101f",
|
|
66
|
+
onTile: "#fff2e2",
|
|
67
|
+
onTileAccent: "#f54b87",
|
|
73
68
|
},
|
|
74
69
|
};
|
|
75
70
|
|
|
76
71
|
/** Which glyph represents each app. */
|
|
77
72
|
export const APP_GLYPHS: Record<SuiteAccentSlug, SuiteIconName> = {
|
|
78
|
-
turtletime:
|
|
79
|
-
tides:
|
|
80
|
-
kraken:
|
|
81
|
-
shellstack:
|
|
82
|
-
crew:
|
|
83
|
-
nakama:
|
|
73
|
+
turtletime: "timer-shell",
|
|
74
|
+
tides: "kanban-wave",
|
|
75
|
+
kraken: "squid-doc",
|
|
76
|
+
shellstack: "stack-hex",
|
|
77
|
+
crew: "crew-bot",
|
|
78
|
+
nakama: "nakama-fist",
|
|
84
79
|
};
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import type { SuiteGlyphElement } from
|
|
3
|
+
import type { SuiteGlyphElement } from "./glyphs";
|
|
4
4
|
|
|
5
5
|
function GlyphElement({ element }: { element: SuiteGlyphElement }) {
|
|
6
|
-
const fill = element.filled ?
|
|
7
|
-
const stroke = element.filled ?
|
|
6
|
+
const fill = element.filled ? "currentColor" : "none";
|
|
7
|
+
const stroke = element.filled ? "none" : undefined;
|
|
8
8
|
switch (element.kind) {
|
|
9
|
-
case
|
|
10
|
-
return
|
|
11
|
-
|
|
9
|
+
case "path":
|
|
10
|
+
return (
|
|
11
|
+
<path
|
|
12
|
+
d={element.d}
|
|
13
|
+
fill={fill}
|
|
14
|
+
stroke={stroke}
|
|
15
|
+
transform={element.transform}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
case "circle":
|
|
12
19
|
return (
|
|
13
20
|
<circle
|
|
14
21
|
cx={element.cx}
|
|
@@ -18,7 +25,7 @@ function GlyphElement({ element }: { element: SuiteGlyphElement }) {
|
|
|
18
25
|
stroke={stroke}
|
|
19
26
|
/>
|
|
20
27
|
);
|
|
21
|
-
case
|
|
28
|
+
case "rect":
|
|
22
29
|
return (
|
|
23
30
|
<rect
|
|
24
31
|
x={element.x}
|
|
@@ -55,7 +62,7 @@ export function GlyphParts({
|
|
|
55
62
|
{accented.length > 0 ? (
|
|
56
63
|
<g
|
|
57
64
|
className={accentClassName}
|
|
58
|
-
style={{ color:
|
|
65
|
+
style={{ color: "var(--suite-icon-accent, currentColor)" }}
|
|
59
66
|
>
|
|
60
67
|
{accented.map((el, i) => (
|
|
61
68
|
<GlyphElement key={i} element={el} />
|