diff --git a/client/src/components/breakpoint-editor/BreakpointEditor.tsx b/client/src/components/breakpoint-editor/BreakpointEditor.tsx
index 034c8c63..e75f25f0 100644
--- a/client/src/components/breakpoint-editor/BreakpointEditor.tsx
+++ b/client/src/components/breakpoint-editor/BreakpointEditor.tsx
@@ -23,7 +23,7 @@ export function BreakpointEditor({
onChange?.({ ...value, ...next });
}
return (
-
+
);
diff --git a/client/src/components/breakpoint-editor/BreakpointListEditor.tsx b/client/src/components/breakpoint-editor/BreakpointListEditor.tsx
index 268c543c..e221ab59 100644
--- a/client/src/components/breakpoint-editor/BreakpointListEditor.tsx
+++ b/client/src/components/breakpoint-editor/BreakpointListEditor.tsx
@@ -7,6 +7,7 @@ import { useMemo } from "react";
import { useLayer } from "slices/layers";
import { BreakpointEditor } from "./BreakpointEditor";
import { comparators } from "./comparators";
+import { Scroll } from "components/generic/Scrollbars";
type BreakpointListEditorProps = {
breakpoints?: Breakpoint[];
@@ -42,27 +43,33 @@ export function BreakpointListEditor({
return (
-
-
- icon={null}
- value={breakpoints}
- deletable
- editable={false}
- editor={(v) => } //v = a breakpoint
- create={() => ({
- active: true,
- property: properties?.[0],
- condition: comparators?.[0],
- type: undefined,
- reference: 0,
- })}
- onChange={(updatedBreakpoints) =>
- handleBreakpointsChange(updatedBreakpoints)
- }
- addItemLabel="Breakpoint"
- placeholder="Click the button below to add a breakpoint."
- />
-
+
+
+
+ sortable
+ button={false}
+ icon={null}
+ value={breakpoints}
+ deletable
+ editable={false}
+ editor={(v) => (
+
+ )} //v = a breakpoint
+ create={() => ({
+ active: true,
+ property: properties?.[0],
+ condition: comparators?.[0],
+ type: undefined,
+ reference: 0,
+ })}
+ onChange={(updatedBreakpoints) =>
+ handleBreakpointsChange(updatedBreakpoints)
+ }
+ addItemLabel="Breakpoint"
+ placeholder="No breakpoints."
+ />
+
+
);
}
diff --git a/client/src/components/generic/LazyList.tsx b/client/src/components/generic/LazyList.tsx
index 82ada6b5..1bc37461 100644
--- a/client/src/components/generic/LazyList.tsx
+++ b/client/src/components/generic/LazyList.tsx
@@ -44,6 +44,7 @@ const Scroller = forwardRef>(
const containerRef = useRef(null);
const { palette, spacing } = useTheme();
const cls = useCss({
+ "--os-padding-perpendicular": "2px",
".os-scrollbar": { visibility: "visible", opacity: 1 },
".os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle": {
"min-height": spacing(12),
@@ -52,6 +53,16 @@ const Scroller = forwardRef>(
height: `calc(100% - ${spacing(6)})`,
marginTop: spacing(6),
},
+ "div > div.os-scrollbar-track": {
+ "--os-handle-perpendicular-size": "2px",
+ "--os-handle-perpendicular-size-hover": "6px",
+ "--os-handle-perpendicular-size-active": "6px",
+ "> div.os-scrollbar-handle": {
+ borderRadius: 0,
+ opacity: 0.5,
+ "&:hover": { opacity: 0.8 },
+ },
+ },
});
const [initialize] = useOverlayScrollbars({
options: {
diff --git a/client/src/components/generic/ListEditor.tsx b/client/src/components/generic/ListEditor.tsx
index e7f4da53..b61a8012 100644
--- a/client/src/components/generic/ListEditor.tsx
+++ b/client/src/components/generic/ListEditor.tsx
@@ -64,6 +64,7 @@ type Item = {
};
type Props = {
+ button?: boolean;
UNSAFE_label?: ReactNode;
UNSAFE_text?: ReactNode;
UNSAFE_extrasPlacement?: "flex-start" | "center" | "flex-end";
@@ -121,10 +122,9 @@ const defaultEditorRenderer: Props["renderEditor"] = ({
);
export function ListEditorField({
- icon = ,
- toggleable: useSwitch,
- deletable: useDelete,
- editable: useEditButton = true,
+ toggleable,
+ deletable,
+ editable = true,
onChangeItem = () => {},
onDeleteItem = () => {},
extras: getExtras,
@@ -135,11 +135,13 @@ export function ListEditorField({
i = 0,
autoFocus,
sortable,
+ button = true,
renderEditor = defaultEditorRenderer,
}: Props & ListEditorFieldProps & Item) {
const acrylic = useAcrylic();
const paper = usePaper();
const [field, setField] = useState(null);
+ const ListElement = (button ? ButtonBase : Box) as typeof Box;
return (
{(provided, snapshot) => (
@@ -148,10 +150,14 @@ export function ListEditorField({
direction="row"
alignItems="center"
sx={{
- transition: (t) => t.transitions.create("background"),
- "&:hover": {
- background: (t) => t.palette.action.hover,
- },
+ ...(button
+ ? {
+ transition: (t) => t.transitions.create("background"),
+ "&:hover": {
+ background: (t) => t.palette.action.hover,
+ },
+ }
+ : undefined),
...(snapshot.isDragging
? ({
...paper(1),
@@ -176,7 +182,7 @@ export function ListEditorField({
),
content: (
- setField(e),
})}
-
+
),
extras: (
- {useSwitch && (
+ {toggleable && (
)}
- {useEditButton && (
+ {editable && (
{
@@ -219,7 +225,7 @@ export function ListEditorField({
)}
- {useDelete && (
+ {deletable && (
onDeleteItem(id ?? i)}>
diff --git a/client/src/components/generic/Modal.tsx b/client/src/components/generic/Modal.tsx
index 5dccd9da..685cac6c 100644
--- a/client/src/components/generic/Modal.tsx
+++ b/client/src/components/generic/Modal.tsx
@@ -305,7 +305,15 @@ export function ManagedModal({
diff --git a/client/src/components/generic/Scrollbars.tsx b/client/src/components/generic/Scrollbars.tsx
index 3fc84927..6a0a86b3 100644
--- a/client/src/components/generic/Scrollbars.tsx
+++ b/client/src/components/generic/Scrollbars.tsx
@@ -29,6 +29,7 @@ export const Scroll = forwardRef(
) => {
const { palette, spacing } = useTheme();
const cls = useCss({
+ "--os-padding-perpendicular": "2px",
"div.os-scrollbar-vertical > div.os-scrollbar-track": {
height: `calc(100% - ${spacing(px)})`,
marginTop: spacing(px),
@@ -37,6 +38,16 @@ export const Scroll = forwardRef(
width: `calc(100% - ${spacing(py * 2)})`,
marginLeft: spacing(py),
},
+ "div > div.os-scrollbar-track": {
+ "--os-handle-perpendicular-size": "2px",
+ "--os-handle-perpendicular-size-hover": "6px",
+ "--os-handle-perpendicular-size-active": "6px",
+ "> div.os-scrollbar-handle": {
+ borderRadius: 0,
+ opacity: 0.5,
+ "&:hover": { opacity: 0.8 },
+ },
+ },
});
const handleRef = useCallback(
(instance: OverlayScrollbars) => {
diff --git a/client/src/components/inspector/FileDropZone.tsx b/client/src/components/inspector/FileDropZone.tsx
index 5c54dc2e..5e5d219a 100644
--- a/client/src/components/inspector/FileDropZone.tsx
+++ b/client/src/components/inspector/FileDropZone.tsx
@@ -5,7 +5,7 @@ import { useWorkspace } from "hooks/useWorkspace";
import { layerHandlers } from "layers/layerHandlers";
import { entries, head } from "lodash";
import { nanoid as id } from "nanoid";
-import pluralize, { plural } from "pluralize";
+import pluralize from "pluralize";
import { producify } from "produce";
import { useState } from "react";
import { FileDrop } from "react-file-drop";
@@ -16,7 +16,7 @@ import { useAcrylic } from "theme";
export function FileDropZone() {
const acrylic = useAcrylic() as any;
const { load: loadWorkspace } = useWorkspace();
- const [open, setOpen] = useState(false);
+ const [itemCount, setItemCount] = useState(0);
const [, setLayers] = useLayers();
const usingBusyState = useBusyState("file-drop-import");
const notify = useSnackbar();
@@ -37,7 +37,7 @@ export function FileDropZone() {
})
)
);
- }, `${i + 1} of ${fs.length}: Opening ${type} (${formatByte(file.size)})`);
+ }, `${i + 1} of ${fs.length}: Importing ${type} (${formatByte(file.size)})`);
totalClaimed += 1;
continue;
}
@@ -55,10 +55,12 @@ export function FileDropZone() {
return (
<>
setOpen(false)}
- onFrameDragEnter={() => setOpen(true)}
- onFrameDrop={() => setOpen(false)}
- onDragLeave={() => setOpen(false)}
+ onFrameDragLeave={() => setItemCount(0)}
+ onFrameDragEnter={(e) =>
+ setItemCount(e?.dataTransfer?.items.length ?? 0)
+ }
+ onFrameDrop={() => setItemCount(0)}
+ onDragLeave={() => setItemCount(0)}
onDrop={(f) => f && importFiles(Array.from(f as any))}
>
t.zIndex.tooltip + 1,
}}
- open={open}
+ open={!!itemCount}
>
- Import
+ {itemCount ? `Import ${pluralize("item", itemCount, true)}` : ""}
diff --git a/client/src/components/layer-editor/LayerListEditor.tsx b/client/src/components/layer-editor/LayerListEditor.tsx
index f04411bb..1d976ee6 100644
--- a/client/src/components/layer-editor/LayerListEditor.tsx
+++ b/client/src/components/layer-editor/LayerListEditor.tsx
@@ -69,10 +69,12 @@ export function LayerListEditor() {
source: { type: "trace", trace: {} },
})}
onChange={(v) =>
- requestIdleCallback(() => setLayers(() => ({ layers: v })))
+ requestIdleCallback(() => setLayers(() => ({ layers: v })), {
+ timeout: 300,
+ })
}
addItemLabel="Layer"
- placeholder={Click the button below to add a layer.}
+ placeholder={Get started by adding a layer.}
onFocus={(key) => {
const element = head(document.getElementsByClassName(key));
if (
diff --git a/client/src/components/settings-editor/RendererListEditor.tsx b/client/src/components/settings-editor/RendererListEditor.tsx
index 3b206c10..cf8d3529 100644
--- a/client/src/components/settings-editor/RendererListEditor.tsx
+++ b/client/src/components/settings-editor/RendererListEditor.tsx
@@ -13,6 +13,7 @@ export function RendererListEditor() {
sortable
+ button={false}
editor={(v) => }
icon={null}
value={renderer}
diff --git a/client/src/components/settings-editor/ServerListEditor.tsx b/client/src/components/settings-editor/ServerListEditor.tsx
index a25b1c8a..31f7282f 100644
--- a/client/src/components/settings-editor/ServerListEditor.tsx
+++ b/client/src/components/settings-editor/ServerListEditor.tsx
@@ -13,6 +13,7 @@ export function ServerListEditor() {
sortable
+ button={false}
editor={(v) => }
icon={null}
value={remote}
diff --git a/client/src/pages/DebugPage.tsx b/client/src/pages/DebugPage.tsx
index 44c13673..de0e7d31 100644
--- a/client/src/pages/DebugPage.tsx
+++ b/client/src/pages/DebugPage.tsx
@@ -1,4 +1,7 @@
-import { LayersOutlined as LayersIcon } from "@mui/icons-material";
+import {
+ BugReportOutlined,
+ LayersOutlined as LayersIcon,
+} from "@mui/icons-material";
import { TabContext, TabList, TabPanel } from "@mui/lab";
import { Box, Divider, Tab, Typography as Type } from "@mui/material";
import { FeaturePicker } from "components/app-bar/FeaturePicker";
@@ -14,6 +17,7 @@ import { ReactNode, useState } from "react";
import { useLayer } from "slices/layers";
import { BreakpointListEditor } from "../components/breakpoint-editor/BreakpointListEditor";
import { PageContentProps } from "./PageMeta";
+import { Placeholder } from "components/inspector/Placeholder";
const divider = (
{divider}
setTab(v)}>
-
-
+
+
-
-
-
-
- {renderHeading("Breakpoints")}
-
-
-
-
-
- layer &&
- setLayer(
- produce(layer, (layer) => set(layer, "source.code", v))
- )
- }
- />
-
+ {layer ? (
+
+
+
+
+ {renderHeading("Breakpoints")}
+
+
+
+
+
+ layer &&
+ setLayer(
+ produce(layer, (layer) => set(layer, "source.code", v))
+ )
+ }
+ />
+
+
-
+ ) : (
+ } label="Debugger" />
+ )}
{controls}
diff --git a/client/src/public/manifest.json b/client/src/public/manifest.json
index 82a9ea70..beabe13a 100644
--- a/client/src/public/manifest.json
+++ b/client/src/public/manifest.json
@@ -1,9 +1,9 @@
{
"short_name": "Visualiser",
"name": "Visualiser",
- "version": "1.1.11",
+ "version": "1.1.11-1",
"description": "Visualise pathfinding search and more",
- "version_name": "1.1.11; late February 2024",
+ "version_name": "1.1.11-1; late February 2024",
"repository": "https://github.com/path-visualiser/app",
"docs": "https://github.com/path-visualiser/app/blob/master/docs",
"homepage": "https://path-visualiser.github.io/",