Use a native select instead of VSCodeDropdown

This commit is contained in:
Robert
2023-07-06 11:03:59 +01:00
parent f75b358e6c
commit d5c4f33d6e
3 changed files with 76 additions and 51 deletions

View File

@@ -0,0 +1,21 @@
import styled from "styled-components";
/**
* Styled to look like a `VSCodeDropdown`.
*
* The reason for doing this is that `VSCodeDropdown` doesn't handle fitting into
* available space and truncating content, and this leads to breaking the
* `VSCodeDataGrid` layout. This version using `select` directly will truncate the
* content as necessary and fit into whatever space is available.
* See https://github.com/github/vscode-codeql/pull/2582#issuecomment-1622164429
* for more info on the problem and other potential solutions.
*/
export const Dropdown = styled.select`
width: 100%;
height: calc(var(--input-height) * 1px);
background: var(--dropdown-background);
color: var(--foreground);
font-family: var(--font-family);
border: none;
padding: 2px 6px 2px 8px;
`;

View File

@@ -1,13 +1,8 @@
import * as React from "react";
import { useCallback, useEffect } from "react";
import styled from "styled-components";
import { VSCodeDropdown, VSCodeOption } from "@vscode/webview-ui-toolkit/react";
import { ChangeEvent, useCallback, useEffect } from "react";
import type { ModeledMethod } from "../../data-extensions-editor/modeled-method";
const Dropdown = styled(VSCodeDropdown)`
width: 100%;
`;
import { Dropdown } from "../common/Dropdown";
type Props = {
kinds: Array<ModeledMethod["kind"]>;
@@ -19,7 +14,7 @@ type Props = {
export const KindInput = ({ kinds, value, disabled, onChange }: Props) => {
const handleInput = useCallback(
(e: InputEvent) => {
(e: ChangeEvent<HTMLSelectElement>) => {
const target = e.target as HTMLSelectElement;
onChange(target.value as ModeledMethod["kind"]);
@@ -38,12 +33,16 @@ export const KindInput = ({ kinds, value, disabled, onChange }: Props) => {
}, [value, kinds, onChange]);
return (
<Dropdown value={value} disabled={disabled} onInput={handleInput}>
{kinds.map((kind) => (
<VSCodeOption key={kind} value={kind}>
{kind}
</VSCodeOption>
))}
<Dropdown value={value} disabled={disabled} onChange={handleInput}>
{!disabled && (
<>
{kinds.map((kind) => (
<option key={kind} value={kind}>
{kind}
</option>
))}
</>
)}
</Dropdown>
);
};

View File

@@ -2,12 +2,10 @@ import {
VSCodeCheckbox,
VSCodeDataGridCell,
VSCodeDataGridRow,
VSCodeDropdown,
VSCodeLink,
VSCodeOption,
} from "@vscode/webview-ui-toolkit/react";
import * as React from "react";
import { useCallback, useMemo } from "react";
import { ChangeEvent, useCallback, useMemo } from "react";
import styled from "styled-components";
import { vscode } from "../vscode-api";
@@ -20,10 +18,7 @@ import {
import { KindInput } from "./KindInput";
import { extensiblePredicateDefinitions } from "../../data-extensions-editor/predicates";
import { Mode } from "../../data-extensions-editor/shared/mode";
const Dropdown = styled(VSCodeDropdown)`
width: 100%;
`;
import { Dropdown } from "../common/Dropdown";
const ApiOrMethodCell = styled(VSCodeDataGridCell)`
display: flex;
@@ -66,9 +61,7 @@ export const MethodRow = ({
}, [externalApiUsage.methodParameters]);
const handleTypeInput = useCallback(
(e: InputEvent) => {
const target = e.target as HTMLSelectElement;
(e: ChangeEvent<HTMLSelectElement>) => {
let newProvenance: Provenance = "manual";
if (modeledMethod?.provenance === "df-generated") {
newProvenance = "df-manual";
@@ -82,14 +75,14 @@ export const MethodRow = ({
output: "ReturnType",
kind: "value",
...modeledMethod,
type: target.value as ModeledMethodType,
type: e.target.value as ModeledMethodType,
provenance: newProvenance,
});
},
[onChange, externalApiUsage, modeledMethod, argumentsList],
);
const handleInputInput = useCallback(
(e: InputEvent) => {
(e: ChangeEvent<HTMLSelectElement>) => {
if (!modeledMethod) {
return;
}
@@ -104,7 +97,7 @@ export const MethodRow = ({
[onChange, externalApiUsage, modeledMethod],
);
const handleOutputInput = useCallback(
(e: InputEvent) => {
(e: ChangeEvent<HTMLSelectElement>) => {
if (!modeledMethod) {
return;
}
@@ -172,44 +165,56 @@ export const MethodRow = ({
</ApiOrMethodCell>
<VSCodeDataGridCell gridColumn={2}>
<Dropdown
value={showModelTypeCell && (modeledMethod?.type ?? "none")}
value={showModelTypeCell ? modeledMethod?.type ?? "none" : undefined}
disabled={!showModelTypeCell}
onInput={handleTypeInput}
onChange={handleTypeInput}
>
<VSCodeOption value="none">Unmodeled</VSCodeOption>
<VSCodeOption value="source">Source</VSCodeOption>
<VSCodeOption value="sink">Sink</VSCodeOption>
<VSCodeOption value="summary">Flow summary</VSCodeOption>
<VSCodeOption value="neutral">Neutral</VSCodeOption>
{showModelTypeCell && (
<>
<option value="none">Unmodeled</option>
<option value="source">Source</option>
<option value="sink">Sink</option>
<option value="summary">Flow summary</option>
<option value="neutral">Neutral</option>
</>
)}
</Dropdown>
</VSCodeDataGridCell>
<VSCodeDataGridCell gridColumn={3}>
<Dropdown
value={showInputCell && modeledMethod?.input}
value={showInputCell ? modeledMethod?.input : undefined}
disabled={!showInputCell}
onInput={handleInputInput}
onChange={handleInputInput}
>
<VSCodeOption value="Argument[this]">Argument[this]</VSCodeOption>
{argumentsList.map((argument, index) => (
<VSCodeOption key={argument} value={`Argument[${index}]`}>
Argument[{index}]: {argument}
</VSCodeOption>
))}
{showInputCell && (
<>
<option value="Argument[this]">Argument[this]</option>
{argumentsList.map((argument, index) => (
<option key={argument} value={`Argument[${index}]`}>
Argument[{index}]: {argument}
</option>
))}
</>
)}
</Dropdown>
</VSCodeDataGridCell>
<VSCodeDataGridCell gridColumn={4}>
<Dropdown
value={showOutputCell && modeledMethod?.output}
value={showOutputCell ? modeledMethod?.output : undefined}
disabled={!showOutputCell}
onInput={handleOutputInput}
onChange={handleOutputInput}
>
<VSCodeOption value="ReturnValue">ReturnValue</VSCodeOption>
<VSCodeOption value="Argument[this]">Argument[this]</VSCodeOption>
{argumentsList.map((argument, index) => (
<VSCodeOption key={argument} value={`Argument[${index}]`}>
Argument[{index}]: {argument}
</VSCodeOption>
))}
{showOutputCell && (
<>
<option value="ReturnValue">ReturnValue</option>
<option value="Argument[this]">Argument[this]</option>
{argumentsList.map((argument, index) => (
<option key={argument} value={`Argument[${index}]`}>
Argument[{index}]: {argument}
</option>
))}
</>
)}
</Dropdown>
</VSCodeDataGridCell>
<VSCodeDataGridCell gridColumn={5}>