Skip to content

Commit ba36558

Browse files
committed
Separate out VSCode style buttons to separate components
1 parent 603e59c commit ba36558

File tree

5 files changed

+199
-185
lines changed

5 files changed

+199
-185
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 4.0.3
2+
3+
### Fixed
4+
5+
- New Testcase button text cuts off if shrinked down
6+
17
# 4.0.2
28

39
### Added

src/webview/Button.svelte

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<script lang="ts">
2+
import type { ClassValue, HTMLButtonAttributes } from "svelte/elements";
3+
4+
interface Props extends HTMLButtonAttributes {
5+
text?: string;
6+
codicon?: string;
7+
class?: ClassValue;
8+
}
9+
10+
let { text, codicon, class: extraClass, ...rest }: Props = $props();
11+
</script>
12+
13+
<button type="button" class={["text-button", extraClass]} {...rest}>
14+
{#if codicon}
15+
<div class={"codicon " + codicon}></div>
16+
{/if}
17+
{#if text}
18+
{text}
19+
{/if}
20+
</button>
21+
22+
<style>
23+
.text-button {
24+
box-sizing: border-box;
25+
display: flex;
26+
width: 100%;
27+
padding: 4px;
28+
border-radius: 4px;
29+
text-align: center;
30+
cursor: pointer;
31+
justify-content: center;
32+
align-items: center;
33+
border: 1px solid var(--vscode-button-border, transparent);
34+
background: var(--vscode-button-background);
35+
color: var(--vscode-button-foreground);
36+
line-height: 18px;
37+
}
38+
39+
.text-button:hover {
40+
background: var(--vscode-button-hoverBackground);
41+
}
42+
43+
.text-button :global(.codicon) {
44+
margin-right: 4px;
45+
}
46+
</style>

src/webview/ButtonDropdown.svelte

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<script lang="ts">
2+
import type { ClassValue, HTMLButtonAttributes } from "svelte/elements";
3+
4+
import Button from "./Button.svelte";
5+
import { onMount } from "svelte";
6+
7+
interface DropdownItem {
8+
text: string;
9+
onclick: (event: Event) => void;
10+
}
11+
12+
interface Props extends HTMLButtonAttributes {
13+
text?: string;
14+
codicon?: string;
15+
class?: ClassValue;
16+
onclick?: (event: Event) => void;
17+
options: DropdownItem[];
18+
}
19+
20+
let { text, codicon, class: extraClass, onclick, options, ...rest }: Props = $props();
21+
let showDropdownMenu = $state(false);
22+
23+
onMount(() => {
24+
const handleClickOutside = (e: MouseEvent) => {
25+
const target = e.target as HTMLElement;
26+
const wrapper = document.querySelector(".dropdown-button");
27+
const dropdown = document.querySelector(".dropdown-menu");
28+
29+
if (
30+
showDropdownMenu &&
31+
wrapper &&
32+
dropdown &&
33+
!wrapper.contains(target) &&
34+
!dropdown.contains(target)
35+
) {
36+
showDropdownMenu = false;
37+
}
38+
};
39+
40+
document.addEventListener("click", handleClickOutside);
41+
return () => {
42+
document.removeEventListener("click", handleClickOutside);
43+
};
44+
});
45+
</script>
46+
47+
<div class="dropdown-button">
48+
<Button
49+
{text}
50+
{codicon}
51+
class={extraClass}
52+
onclick={(event: Event) => {
53+
onclick?.(event);
54+
showDropdownMenu = false;
55+
}}
56+
{...rest}
57+
/>
58+
<div class="dropdown-separator"></div>
59+
<Button
60+
class="dropdown-icon"
61+
codicon="codicon-chevron-down"
62+
onclick={() => (showDropdownMenu = !showDropdownMenu)}
63+
/>
64+
</div>
65+
{#if showDropdownMenu}
66+
<div class="dropdown-menu">
67+
{#each options as option (option.text)}
68+
<button
69+
type="button"
70+
class="dropdown-item"
71+
onclick={(event: Event) => {
72+
option.onclick(event);
73+
showDropdownMenu = false;
74+
}}>{option.text}</button
75+
>
76+
{/each}
77+
</div>
78+
{/if}
79+
80+
<style>
81+
.dropdown-button {
82+
display: flex;
83+
margin-top: 8px;
84+
border: 1px solid var(--vscode-button-border, transparent);
85+
background: var(--vscode-button-background);
86+
color: var(--vscode-button-foreground);
87+
border-radius: 4px;
88+
}
89+
90+
.dropdown-button > :global(.text-button) {
91+
border: none;
92+
}
93+
94+
.dropdown-separator {
95+
width: 1px;
96+
height: auto;
97+
margin: 4px 0;
98+
background-color: var(--vscode-button-separator);
99+
}
100+
101+
:global(.text-button.dropdown-icon) {
102+
width: auto;
103+
padding-left: 4px;
104+
padding-right: 0;
105+
}
106+
107+
.dropdown-menu {
108+
width: fit-content;
109+
margin-left: auto;
110+
background: var(--vscode-menu-background);
111+
border: 1px solid var(--vscode-menu-border);
112+
border-radius: 6px;
113+
box-shadow: 0 2px 8px var(--vscode-menu-shadow);
114+
padding: 3px;
115+
}
116+
117+
.dropdown-item {
118+
display: block;
119+
width: 100%;
120+
padding: 6px 24px;
121+
text-align: left;
122+
background: transparent;
123+
border: none;
124+
border-radius: 6px;
125+
color: var(--vscode-menu-foreground);
126+
cursor: pointer;
127+
}
128+
129+
.dropdown-item:hover {
130+
background: var(--vscode-menu-selectionBackground);
131+
color: var(--vscode-menu-selectionForeground);
132+
}
133+
</style>

0 commit comments

Comments
 (0)