Skip to content

Commit cf038a9

Browse files
authored
Merge pull request #13116 from gitbutlerapp/push-vqwpsruqkxzm
Lite: shortcut tooltips + basic dark mode
2 parents cd3b3c7 + d07fa27 commit cf038a9

18 files changed

Lines changed: 288 additions & 164 deletions

apps/lite/ui/src/App.module.css

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,4 @@
1111

1212
.toastRoot {
1313
padding: 8px;
14-
border: 1px solid;
15-
background-color: white;
1614
}

apps/lite/ui/src/App.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
33
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
44
import { RegisteredRouter, RouterProvider } from "@tanstack/react-router";
55
import { FC, StrictMode } from "react";
6+
import { classes } from "./classes";
67
import styles from "./App.module.css";
8+
import uiStyles from "./ui.module.css";
79

810
const Toasts: FC = () => {
911
const { toasts } = Toast.useToastManager();
@@ -12,7 +14,11 @@ const Toasts: FC = () => {
1214
<Toast.Portal>
1315
<Toast.Viewport className={styles.toastViewport}>
1416
{toasts.map((toast) => (
15-
<Toast.Root key={toast.id} toast={toast} className={styles.toastRoot}>
17+
<Toast.Root
18+
key={toast.id}
19+
toast={toast}
20+
className={classes(uiStyles.popup, styles.toastRoot)}
21+
>
1622
<Toast.Content>
1723
<Toast.Title />
1824
<Toast.Description
@@ -37,7 +43,12 @@ export const App: React.FC<{
3743
<StrictMode>
3844
<QueryClientProvider client={queryClient}>
3945
<Toast.Provider toastManager={toastManager}>
40-
<Tooltip.Provider>
46+
<Tooltip.Provider
47+
// Workaround for flicker issue when nesting tooltips
48+
// https://discord.com/channels/1287292451308048406/1287292451308048409/1488499829104443424
49+
// https://stackblitz.com/edit/zrcwexu5-k5ypazwg?file=src%2FApp.tsx
50+
delay={0}
51+
>
4152
<RouterProvider router={router} />
4253
<Toasts />
4354
</Tooltip.Provider>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { classes } from "#ui/classes.ts";
2+
import { mergeProps, Tooltip, useRender } from "@base-ui/react";
3+
import { FC } from "react";
4+
import { bindingButtonLabel, ShortcutActionBase, ShortcutBinding } from "#ui/shortcuts.ts";
5+
import uiStyles from "#ui/ui.module.css";
6+
7+
type ShortcutButtonProps = {
8+
binding: ShortcutBinding<ShortcutActionBase>;
9+
} & useRender.ComponentProps<"button">;
10+
11+
export const ShortcutButton: FC<ShortcutButtonProps> = ({ binding, render, ...props }) => {
12+
const tooltip = bindingButtonLabel(binding);
13+
const trigger = useRender({
14+
render,
15+
defaultTagName: "button",
16+
props: mergeProps<"button">({ "aria-label": tooltip }, props),
17+
});
18+
19+
return (
20+
<Tooltip.Root
21+
// Prevent tooltip from continuing to show when mouse moves from one
22+
// selected item to another.
23+
// [tag:tooltip-disable-hoverable-popup]
24+
disableHoverablePopup
25+
>
26+
<Tooltip.Trigger render={trigger} />
27+
<Tooltip.Portal>
28+
<Tooltip.Positioner sideOffset={8}>
29+
<Tooltip.Popup className={classes(uiStyles.popup, uiStyles.tooltip)}>
30+
{tooltip}
31+
</Tooltip.Popup>
32+
</Tooltip.Positioner>
33+
</Tooltip.Portal>
34+
</Tooltip.Root>
35+
);
36+
};

apps/lite/ui/src/global.css

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,47 @@
11
:root {
2+
color-scheme: light dark;
23
font-family: system-ui;
34

4-
--pane-padding: 16px;
5+
--color-white: light-dark(#fff, #121212);
6+
--color-gray-50: light-dark(#f5f5f5, #1a1a1a);
7+
--color-gray-100: light-dark(#e8e8e8, #242424);
8+
--color-gray-200: light-dark(#dcdcdc, #303030);
9+
--color-gray-400: light-dark(#adacac, #8f8f8f);
10+
--color-gray-700: light-dark(#626262, #c5c5c5);
11+
--color-gray-900: light-dark(#2b2b2b, #ececec);
12+
--color-black: light-dark(#000, #fff);
13+
14+
--color-bg: var(--color-white);
15+
--color-button-bg: var(--color-gray-50);
16+
--color-button-hover-bg: var(--color-gray-100);
17+
--color-button-disabled-fg: var(--color-gray-700);
18+
--color-dialog-backdrop: light-dark(rgb(0 0 0 / 0.35), rgb(0 0 0 / 0.65));
19+
--color-drag-over-outline: var(--color-black);
20+
--color-file-selected-bg: var(--color-gray-200);
21+
--color-input-bg: var(--color-gray-50);
22+
--color-item-action-hover-bg: var(--color-gray-200);
23+
--color-item-highlighted-bg: #63cdc7;
24+
--color-item-hover-bg: var(--color-gray-100);
25+
--color-item-selected-action-hover-bg: var(--color-gray-900);
26+
--color-item-selected-bg: var(--color-black);
27+
--color-item-selected-fg: var(--color-white);
28+
--color-menu-item-highlighted-bg: var(--color-gray-50);
29+
--color-move-indicator: var(--color-black);
30+
--color-section-selected-bg: var(--color-gray-50);
31+
--color-separator: var(--color-gray-400);
32+
--color-text-secondary-inverse: var(--color-gray-400);
33+
--color-text-secondary: var(--color-gray-700);
34+
--color-text: var(--color-black);
535
--item-block-padding: 4px;
636
--item-inline-padding: 8px;
737
--item-line-height: 19px;
38+
--pane-padding: 16px;
839
}
940

1041
body {
1142
margin: 0;
43+
background-color: var(--color-bg);
44+
color: var(--color-text);
1245
font-size: 16px;
1346
}
1447

apps/lite/ui/src/routes/__root.module.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
grid-area: topBar;
1515
align-items: center;
1616
padding: 4px;
17-
border-bottom: 1px solid;
17+
border-bottom: 1px solid var(--color-separator);
1818
}
1919

2020
.topBarActions {
@@ -29,7 +29,7 @@
2929
grid-area: sidebar;
3030
flex-direction: column;
3131
padding: var(--pane-padding);
32-
border-right: 1px solid;
32+
border-right: 1px solid var(--color-separator);
3333
}
3434

3535
.sidebarNav {
@@ -39,12 +39,12 @@
3939
}
4040

4141
.navLink {
42-
color: grey;
42+
color: var(--color-text-secondary);
4343
text-decoration: none;
4444
}
4545

4646
.navLinkActive {
47-
color: black;
47+
color: var(--color-text);
4848
}
4949

5050
.content {

apps/lite/ui/src/routes/__root.tsx

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { QueryClient } from "@tanstack/react-query";
55
import { createRootRouteWithContext } from "@tanstack/react-router";
66
import { useFullscreenPreview } from "../hooks/useFullscreenPreview";
77
import { usePreviewPanel } from "../hooks/usePreviewPanel";
8+
import { ShortcutButton } from "#ui/ShortcutButton.tsx";
89
import { ShortcutsBarPortalContext } from "#ui/routes/project/$id/-ShortcutsBar.tsx";
9-
import { bindingButtonLabel } from "#ui/shortcuts.ts";
1010
import {
1111
openFullscreenPreviewBinding,
1212
togglePreviewBinding,
@@ -98,21 +98,23 @@ const TopBarActions: FC<{
9898

9999
return (
100100
<div className={styles.topBarActions}>
101-
<button
101+
<ShortcutButton
102+
binding={togglePreviewBinding}
102103
type="button"
103104
className={uiStyles.button}
104105
aria-pressed={previewPanel}
105106
onClick={() => setPreviewPanel((visible) => !visible)}
106107
>
107-
{bindingButtonLabel(togglePreviewBinding)}
108-
</button>
109-
<button
108+
{togglePreviewBinding.description}
109+
</ShortcutButton>
110+
<ShortcutButton
111+
binding={openFullscreenPreviewBinding}
110112
type="button"
111113
className={uiStyles.button}
112114
onClick={() => setShowFullscreenPreview(true)}
113115
>
114-
{bindingButtonLabel(openFullscreenPreviewBinding)}
115-
</button>
116+
{openFullscreenPreviewBinding.description}
117+
</ShortcutButton>
116118
</div>
117119
);
118120
};

apps/lite/ui/src/routes/project/$id/-ProjectPreviewLayout.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { Dialog } from "@base-ui/react";
22
import { FC, ReactNode, use, useState } from "react";
33
import { Group, Panel, Separator, useDefaultLayout } from "react-resizable-panels";
4+
import { ShortcutButton } from "#ui/ShortcutButton.tsx";
45
import { ShortcutsBarPortalContext } from "#ui/routes/project/$id/-ShortcutsBar.tsx";
56
import { useFullscreenPreview } from "#ui/hooks/useFullscreenPreview.ts";
67
import { usePreviewPanel } from "#ui/hooks/usePreviewPanel.ts";
7-
import { bindingButtonLabel } from "#ui/shortcuts.ts";
88
import uiStyles from "#ui/ui.module.css";
99
import { closeFullscreenPreviewBinding } from "./workspace/-WorkspaceShortcuts.ts";
1010
import sharedStyles from "./-shared.module.css";
@@ -58,13 +58,14 @@ export const ProjectPreviewLayout: FC<{
5858
<Dialog.Portal>
5959
<Dialog.Popup aria-label="Preview" className={sharedStyles.previewDialogPopup}>
6060
<div className={sharedStyles.previewDialogBody}>
61-
<button
61+
<ShortcutButton
62+
binding={closeFullscreenPreviewBinding}
6263
type="button"
6364
className={uiStyles.button}
6465
onClick={() => setShowFullscreenPreview(false)}
6566
>
66-
{bindingButtonLabel(closeFullscreenPreviewBinding)}
67-
</button>
67+
{closeFullscreenPreviewBinding.description}
68+
</ShortcutButton>
6869
{preview}
6970
</div>
7071
<footer ref={setDialogShortcutsBarPortalNode} />

apps/lite/ui/src/routes/project/$id/-ShortcutsBar.module.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
flex-wrap: wrap;
66
align-items: baseline;
77
padding: 4px var(--pane-padding);
8-
border-top: 1px solid;
9-
color: #555;
8+
border-top: 1px solid var(--color-separator);
9+
color: var(--color-text-secondary);
1010
text-transform: lowercase;
1111
}
1212

1313
.scope {
14-
color: #111;
14+
color: var(--color-text);
1515
font-weight: 600;
1616
}
1717

@@ -22,6 +22,6 @@
2222
}
2323

2424
.keys {
25-
color: #111;
25+
color: var(--color-text);
2626
font-family: monospace;
2727
}

apps/lite/ui/src/routes/project/$id/-shared.module.css

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
flex-direction: column;
2626
inset: 0;
2727
overflow: hidden;
28-
background-color: white;
28+
background-color: var(--color-bg);
2929
}
3030

3131
.previewDialogBody {
@@ -36,7 +36,7 @@
3636

3737
.previewResizeHandle {
3838
width: 1px;
39-
background-color: black;
39+
background-color: var(--color-separator);
4040
}
4141

4242
.laneDiffColumn {
@@ -48,29 +48,29 @@
4848
align-items: start;
4949

5050
&:where(:hover) {
51-
background-color: #e8e8e8;
51+
background-color: var(--color-item-hover-bg);
5252
}
5353
}
5454

5555
.itemEmpty {
5656
padding-inline: var(--item-inline-padding);
5757
padding-block: var(--item-block-padding);
58-
color: gray;
58+
color: var(--color-text-secondary);
5959
line-height: var(--item-line-height);
6060
}
6161

6262
.selected {
63-
background-color: black;
64-
color: white;
63+
background-color: var(--color-item-selected-bg);
64+
color: var(--color-item-selected-fg);
6565
}
6666

6767
.highlighted {
68-
background-color: burlywood;
69-
color: black;
68+
background-color: var(--color-item-highlighted-bg);
69+
color: var(--color-text);
7070
}
7171

7272
.sectionSelected {
73-
background-color: #f5f5f5;
73+
background-color: var(--color-section-selected-bg);
7474
}
7575

7676
.itemAction {
@@ -80,10 +80,10 @@
8080
padding-block: var(--item-block-padding);
8181

8282
&:enabled:hover {
83-
background-color: #dcdcdc;
83+
background-color: var(--color-item-action-hover-bg);
8484

8585
.item.selected & {
86-
background-color: #2b2b2b;
86+
background-color: var(--color-item-selected-action-hover-bg);
8787
}
8888
}
8989

@@ -137,7 +137,7 @@
137137
}
138138

139139
.selectedFile {
140-
background-color: lightgray;
140+
background-color: var(--color-file-selected-bg);
141141
}
142142

143143
.hunkHeaderRow {
@@ -153,22 +153,5 @@
153153
}
154154

155155
.dragPreview {
156-
padding: 4px 8px;
157-
border: 1px solid;
158-
background-color: white;
159-
}
160-
161-
.menuPopup {
162-
border: 1px solid;
163-
background-color: white;
164-
}
165-
166-
.menuItem {
167-
padding: 4px;
168-
border: 1px solid;
169-
cursor: default;
170-
171-
&[data-disabled] {
172-
opacity: 0.5;
173-
}
156+
padding: 8px;
174157
}

apps/lite/ui/src/routes/project/$id/-shared.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export const HunkDiff: FC<{
9191
patch={`${patchHeaderForChange(change, lineEndingForDiff(diff))}${diff}`}
9292
options={{
9393
diffStyle: "unified",
94-
themeType: "light",
94+
themeType: "system",
9595
disableFileHeader: true,
9696
}}
9797
/>

0 commit comments

Comments
 (0)