Skip to content

Commit 143f4ba

Browse files
committed
editor shortcuts, adjust color of adding new layout segment
1 parent 7ddc965 commit 143f4ba

File tree

7 files changed

+213
-124
lines changed

7 files changed

+213
-124
lines changed

apps/desktop/src/components/Tooltip.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,44 @@
11
import { Tooltip as KTooltip } from "@kobalte/core";
2+
import { type as ostype } from "@tauri-apps/plugin-os";
23
import { cx } from "cva";
34
import type { ComponentProps, JSX } from "solid-js";
45

56
interface Props extends ComponentProps<typeof KTooltip.Root> {
67
content: JSX.Element;
78
childClass?: string;
9+
kbd?: string[];
810
}
911

12+
type Os = "android" | "ios" | "linux" | "macos" | "windows";
13+
14+
const kbdSymbolModifier = (key: string, os: Os) => {
15+
const obj = {
16+
meta: os === "macos" ? "⌘" : "ctrl",
17+
shift: "⇧",
18+
alt: os === "macos" ? "⌥" : "⎇",
19+
};
20+
return obj[key as keyof typeof obj] || key;
21+
};
22+
1023
export default function Tooltip(props: Props) {
24+
const os = ostype();
1125
return (
1226
<KTooltip.Root {...props} openDelay={props.openDelay ?? 200}>
1327
<KTooltip.Trigger class={cx(props.childClass)}>
1428
{props.children}
1529
</KTooltip.Trigger>
1630
<KTooltip.Portal>
17-
<KTooltip.Content class="z-50 px-1.5 py-1 text-xs border border-gray-3 bg-gray-12 text-gray-1 rounded shadow-lg duration-100 animate-in fade-in slide-in-from-top-1 min-w-6 text-center">
18-
{props.content}
31+
<KTooltip.Content class="z-50 px-1.5 flex items-center py-1 text-xs border border-gray-3 bg-gray-12 text-gray-1 rounded-md shadow-lg duration-100 animate-in fade-in slide-in-from-top-1 min-w-6 gap-1.5 text-center">
32+
<span>{props.content}</span>
33+
{props.kbd?.length && (
34+
<div class="space-x-1">
35+
{props.kbd.map((kbd) => (
36+
<kbd class="py-0.5 px-[5px] text-[10px] rounded-md text-gray-12 bg-gray-1">
37+
{kbdSymbolModifier(kbd, os)}
38+
</kbd>
39+
))}
40+
</div>
41+
)}
1942
<KTooltip.Arrow size={16} />
2043
</KTooltip.Content>
2144
</KTooltip.Portal>

apps/desktop/src/routes/editor/AspectRatioSelect.tsx

Lines changed: 87 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Select as KSelect } from "@kobalte/core/select";
2-
import { Show } from "solid-js";
3-
2+
import { createEventListener } from "@solid-primitives/event-listener";
3+
import { createSignal, Show } from "solid-js";
4+
import Tooltip from "~/components/Tooltip";
45
import type { AspectRatio } from "~/utils/tauri";
56
import { useEditorContext } from "./context";
67
import { ASPECT_RATIOS } from "./projectConfig";
@@ -14,80 +15,94 @@ import {
1415

1516
function AspectRatioSelect() {
1617
const { project, setProject } = useEditorContext();
17-
return (
18-
<KSelect<AspectRatio | "auto">
19-
value={project.aspectRatio ?? "auto"}
20-
onChange={(v) => {
21-
if (v === null) return;
22-
setProject("aspectRatio", v === "auto" ? null : v);
23-
}}
24-
defaultValue="auto"
25-
options={
26-
["auto", "wide", "vertical", "square", "classic", "tall"] as const
27-
}
28-
multiple={false}
29-
itemComponent={(props) => {
30-
const item = () =>
31-
props.item.rawValue === "auto"
32-
? null
33-
: ASPECT_RATIOS[props.item.rawValue];
18+
const [open, setOpen] = createSignal(false);
19+
let triggerSelect: HTMLDivElement | undefined;
20+
createEventListener(document, "keydown", (e: KeyboardEvent) => {
21+
if (e.code === "KeyA" && e.target === document.body) {
22+
e.preventDefault();
23+
setOpen((prev) => !prev);
24+
}
25+
});
3426

35-
return (
36-
<MenuItem<typeof KSelect.Item> as={KSelect.Item} item={props.item}>
37-
<KSelect.ItemLabel class="flex-1">
38-
{props.item.rawValue === "auto"
39-
? "Auto"
40-
: ASPECT_RATIOS[props.item.rawValue].name}
41-
<Show when={item()}>
42-
{(item) => (
43-
<span class="text-gray-11">
44-
{"⋅"}
45-
{item().ratio[0]}:{item().ratio[1]}
46-
</span>
47-
)}
48-
</Show>
49-
</KSelect.ItemLabel>
50-
<KSelect.ItemIndicator class="ml-auto">
51-
<IconCapCircleCheck />
52-
</KSelect.ItemIndicator>
53-
</MenuItem>
54-
);
55-
}}
56-
placement="top-start"
57-
>
58-
<EditorButton<typeof KSelect.Trigger>
59-
as={KSelect.Trigger}
60-
class="w-28"
61-
leftIcon={<IconCapLayout />}
62-
rightIcon={
63-
<KSelect.Icon>
64-
<IconCapChevronDown />
65-
</KSelect.Icon>
27+
return (
28+
<Tooltip kbd={["A"]} content="Aspect Ratio">
29+
<KSelect<AspectRatio | "auto">
30+
open={open()}
31+
onOpenChange={setOpen}
32+
ref={triggerSelect}
33+
value={project.aspectRatio ?? "auto"}
34+
onChange={(v) => {
35+
if (v === null) return;
36+
setProject("aspectRatio", v === "auto" ? null : v);
37+
}}
38+
defaultValue="auto"
39+
options={
40+
["auto", "wide", "vertical", "square", "classic", "tall"] as const
6641
}
67-
rightIconEnd={true}
42+
multiple={false}
43+
itemComponent={(props) => {
44+
const item = () =>
45+
props.item.rawValue === "auto"
46+
? null
47+
: ASPECT_RATIOS[props.item.rawValue];
48+
49+
return (
50+
<MenuItem<typeof KSelect.Item> as={KSelect.Item} item={props.item}>
51+
<KSelect.ItemLabel class="flex-1">
52+
{props.item.rawValue === "auto"
53+
? "Auto"
54+
: ASPECT_RATIOS[props.item.rawValue].name}
55+
<Show when={item()}>
56+
{(item) => (
57+
<span class="text-gray-11">
58+
{"⋅"}
59+
{item().ratio[0]}:{item().ratio[1]}
60+
</span>
61+
)}
62+
</Show>
63+
</KSelect.ItemLabel>
64+
<KSelect.ItemIndicator class="ml-auto">
65+
<IconCapCircleCheck />
66+
</KSelect.ItemIndicator>
67+
</MenuItem>
68+
);
69+
}}
70+
placement="top-start"
6871
>
69-
<KSelect.Value<AspectRatio | "auto">>
70-
{(state) => {
71-
const text = () => {
72-
const option = state.selectedOption();
73-
return option === "auto" ? "Auto" : ASPECT_RATIOS[option].name;
74-
};
75-
return <>{text()}</>;
76-
}}
77-
</KSelect.Value>
78-
</EditorButton>
79-
<KSelect.Portal>
80-
<PopperContent<typeof KSelect.Content>
81-
as={KSelect.Content}
82-
class={topLeftAnimateClasses}
72+
<EditorButton<typeof KSelect.Trigger>
73+
as={KSelect.Trigger}
74+
class="w-28"
75+
leftIcon={<IconCapLayout />}
76+
rightIcon={
77+
<KSelect.Icon>
78+
<IconCapChevronDown />
79+
</KSelect.Icon>
80+
}
81+
rightIconEnd={true}
8382
>
84-
<MenuItemList<typeof KSelect.Listbox>
85-
as={KSelect.Listbox}
86-
class="w-[12.5rem]"
87-
/>
88-
</PopperContent>
89-
</KSelect.Portal>
90-
</KSelect>
83+
<KSelect.Value<AspectRatio | "auto">>
84+
{(state) => {
85+
const text = () => {
86+
const option = state.selectedOption();
87+
return option === "auto" ? "Auto" : ASPECT_RATIOS[option].name;
88+
};
89+
return <>{text()}</>;
90+
}}
91+
</KSelect.Value>
92+
</EditorButton>
93+
<KSelect.Portal>
94+
<PopperContent<typeof KSelect.Content>
95+
as={KSelect.Content}
96+
class={topLeftAnimateClasses}
97+
>
98+
<MenuItemList<typeof KSelect.Listbox>
99+
as={KSelect.Listbox}
100+
class="w-[12.5rem]"
101+
/>
102+
</PopperContent>
103+
</KSelect.Portal>
104+
</KSelect>
105+
</Tooltip>
91106
);
92107
}
93108

apps/desktop/src/routes/editor/ExportDialog.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,8 @@ export function ExportDialog() {
409409
)}
410410
>
411411
<p class="flex gap-4 items-center">
412-
<span class="flex items-center text-[--gray-500]">
413-
<IconCapCamera class="w-[14px] h-[14px] mr-1.5 text-[--gray-500]" />
412+
<span class="flex items-center text-gray-12">
413+
<IconCapCamera class="w-[14px] h-[14px] mr-1.5 text-gray-12" />
414414
{(() => {
415415
const totalSeconds = Math.round(
416416
est().duration_seconds,
@@ -433,16 +433,16 @@ export function ExportDialog() {
433433
.padStart(2, "0")}`;
434434
})()}
435435
</span>
436-
<span class="flex items-center text-[--gray-500]">
437-
<IconLucideMonitor class="w-[14px] h-[14px] mr-1.5 text-[--gray-500]" />
436+
<span class="flex items-center text-gray-12">
437+
<IconLucideMonitor class="w-[14px] h-[14px] mr-1.5 text-gray-12" />
438438
{settings.resolution.width}×{settings.resolution.height}
439439
</span>
440-
<span class="flex items-center text-[--gray-500]">
441-
<IconLucideHardDrive class="w-[14px] h-[14px] mr-1.5 text-[--gray-500]" />
440+
<span class="flex items-center text-gray-12">
441+
<IconLucideHardDrive class="w-[14px] h-[14px] mr-1.5 text-gray-12" />
442442
{est().estimated_size_mb.toFixed(2)} MB
443443
</span>
444-
<span class="flex items-center text-[--gray-500]">
445-
<IconLucideClock class="w-[14px] h-[14px] mr-1.5 text-[--gray-500]" />
444+
<span class="flex items-center text-gray-12">
445+
<IconLucideClock class="w-[14px] h-[14px] mr-1.5 text-gray-12" />
446446
{(() => {
447447
const totalSeconds = Math.round(
448448
est().estimated_time_seconds,
@@ -474,7 +474,7 @@ export function ExportDialog() {
474474
>
475475
<div class="flex flex-wrap gap-3">
476476
{/* Export to */}
477-
<div class="flex-1 p-4 rounded-xl bg-gray-2">
477+
<div class="flex-1 p-4 rounded-xl dark:bg-gray-2 bg-gray-3">
478478
<div class="flex flex-col gap-3">
479479
<h3 class="text-gray-12">Export to</h3>
480480
<div class="flex gap-2">
@@ -497,7 +497,7 @@ export function ExportDialog() {
497497
</div>
498498
</div>
499499
{/* Format */}
500-
<div class="p-4 rounded-xl bg-gray-2">
500+
<div class="p-4 rounded-xl dark:bg-gray-2 bg-gray-3">
501501
<div class="flex flex-col gap-3">
502502
<h3 class="text-gray-12">Format</h3>
503503
<div class="flex flex-row gap-2">
@@ -552,7 +552,7 @@ export function ExportDialog() {
552552
</div>
553553
</div>
554554
{/* Frame rate */}
555-
<div class="overflow-hidden relative p-4 rounded-xl bg-gray-2">
555+
<div class="overflow-hidden relative p-4 rounded-xl dark:bg-gray-2 bg-gray-3">
556556
<div class="flex flex-col gap-3">
557557
<h3 class="text-gray-12">Frame rate</h3>
558558
<KSelect<{ label: string; value: number }>
@@ -585,7 +585,7 @@ export function ExportDialog() {
585585
</MenuItem>
586586
)}
587587
>
588-
<KSelect.Trigger class="flex flex-row gap-2 items-center px-3 w-full h-10 rounded-xl transition-colors bg-gray-3 disabled:text-gray-11">
588+
<KSelect.Trigger class="flex flex-row gap-2 items-center px-3 w-full h-10 rounded-xl transition-colors dark:bg-gray-3 bg-gray-4 disabled:text-gray-11">
589589
<KSelect.Value<
590590
(typeof FPS_OPTIONS)[number]
591591
> class="flex-1 text-sm text-left truncate tabular-nums text-[--gray-500]">
@@ -606,7 +606,7 @@ export function ExportDialog() {
606606
class={cx(topSlideAnimateClasses, "z-50")}
607607
>
608608
<MenuItemList<typeof KSelect.Listbox>
609-
class="overflow-y-auto max-h-32"
609+
class="max-h-32 custom-scroll"
610610
as={KSelect.Listbox}
611611
/>
612612
</PopperContent>
@@ -615,7 +615,7 @@ export function ExportDialog() {
615615
</div>
616616
</div>
617617
{/* Compression */}
618-
<div class="p-4 rounded-xl bg-gray-2">
618+
<div class="p-4 rounded-xl dark:bg-gray-2 bg-gray-3">
619619
<div class="flex flex-col gap-3">
620620
<h3 class="text-gray-12">Compression</h3>
621621
<div class="flex gap-2">
@@ -642,7 +642,7 @@ export function ExportDialog() {
642642
</div>
643643
</div>
644644
{/* Resolution */}
645-
<div class="flex-1 p-4 rounded-xl bg-gray-2">
645+
<div class="flex-1 p-4 rounded-xl dark:bg-gray-2 bg-gray-3">
646646
<div class="flex flex-col gap-3">
647647
<h3 class="text-gray-12">Resolution</h3>
648648
<div class="flex gap-2">

0 commit comments

Comments
 (0)