Skip to content

Commit acecbe6

Browse files
loci table changes (#256)
## Description Closes #233 Enhancements to loci page ## Major Changes - allow filtering by min/max motif length - make checkboxes tri-state: true, false, or "mixed" (either) - move downloads section lower, and make into table ## Minor Changes - number boxes for motif length "snap" to available lengths - add icons for more headings ## Checklist - [x] All changes are well summarized - [x] Check all tests pass - [x] Check that the website preview looks good - [x] Update the STRchive version in `CITATION.cff`, format X.Y.Z. If any major changes, increment Y. If only minor changes, increment Z. If the breaking change (rare), increment X. - [x] Ask someone to review this PR
1 parent d14b01a commit acecbe6

File tree

15 files changed

+217
-114
lines changed

15 files changed

+217
-114
lines changed

site/src/assets/check.svg

Lines changed: 3 additions & 3 deletions
Loading

site/src/assets/x.svg

Lines changed: 10 additions & 0 deletions
Loading

site/src/components/CheckBox.jsx

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,41 @@
1+
import { useEffect, useRef } from "react";
12
import clsx from "clsx";
23
import classes from "./CheckBox.module.css";
34

45
/** checkbox with label */
5-
const CheckBox = ({ label, onChange, tooltip, className, ...props }) => (
6-
<label data-tooltip={tooltip}>
7-
<input
8-
type="checkbox"
9-
className={clsx(className, classes.box)}
10-
onChange={(event) => onChange?.(event.target.checked)}
11-
aria-label={tooltip}
12-
{...props}
13-
/>
14-
<span>{label}</span>
15-
</label>
16-
);
6+
const CheckBox = ({
7+
label,
8+
checked,
9+
onChange,
10+
tooltip,
11+
className,
12+
...props
13+
}) => {
14+
const ref = useRef(null);
15+
16+
useEffect(() => {
17+
ref.current.indeterminate = checked === "mixed";
18+
}, [checked]);
19+
20+
return (
21+
<label data-tooltip={tooltip}>
22+
<input
23+
ref={ref}
24+
type="checkbox"
25+
className={clsx(className, classes.box)}
26+
checked={!!checked}
27+
onChange={() => {
28+
if (checked === "mixed") onChange?.(true);
29+
else if (checked === true) onChange?.(false);
30+
else onChange?.("mixed");
31+
}}
32+
aria-checked={checked}
33+
aria-label={tooltip}
34+
{...props}
35+
/>
36+
{label && <span>{label}</span>}
37+
</label>
38+
);
39+
};
1740

1841
export default CheckBox;

site/src/components/CheckBox.module.css

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,20 @@
33
width: 20px;
44
height: 20px;
55
border-radius: calc(var(--rounded) / 2);
6-
background: var(--white);
6+
background-position: center;
7+
background-size: 100%;
8+
background-repeat: no-repeat;
9+
background-color: var(--white);
710
box-shadow: inset 0 0 0 2px var(--dark-gray);
811
accent-color: var(--primary);
912
}
1013

11-
.box:checked {
14+
.box[aria-checked="true"] {
1215
background-image: url("../assets/check.svg");
13-
background-position: center;
14-
background-size: 65%;
15-
background-repeat: no-repeat;
1616
background-color: var(--primary);
1717
}
18+
19+
.box[aria-checked="false"] {
20+
background-image: url("../assets/x.svg");
21+
background-color: var(--secondary);
22+
}

site/src/components/Heading.astro

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ const Component = `h${level}`;
2222

2323
<style>
2424
.heading {
25+
--gap: 0.5em;
2526
display: flex;
2627
align-items: center;
27-
gap: 0.5em;
28+
gap: var(--gap);
2829
overflow-wrap: anywhere;
2930
}
3031

@@ -34,6 +35,8 @@ const Component = `h${level}`;
3435

3536
.anchor {
3637
width: 0;
38+
margin-left: calc(-1 * var(--gap));
39+
translate: var(--gap) 0;
3740
color: var(--primary);
3841
white-space: nowrap;
3942
opacity: 0;

site/src/components/NumberBox.jsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,33 @@
11
import clsx from "clsx";
2+
import { sortBy, uniq } from "lodash-es";
23
import classes from "./NumberBox.module.css";
34

45
/** number input with label */
5-
const NumberBox = ({ label, value, onChange, className, ...props }) => (
6+
const NumberBox = ({
7+
label,
8+
value,
9+
onChange,
10+
className,
11+
snapValues,
12+
...props
13+
}) => (
614
<label>
7-
<span>{label}</span>
15+
{label && <span>{label}</span>}
816
<input
917
type="number"
1018
className={clsx(className, classes.box)}
1119
value={typeof value === "number" && !Number.isNaN(value) ? value : ""}
12-
onChange={(event) => onChange?.(Number(event.target.value) || 0)}
20+
onChange={(event) => {
21+
let newValue = Number(event.target.value) || 0;
22+
if (snapValues?.length) {
23+
snapValues = sortBy(uniq(snapValues));
24+
if (newValue < value)
25+
newValue = snapValues.findLast((v) => v <= newValue);
26+
if (newValue > value)
27+
newValue = snapValues.find((v) => v >= newValue);
28+
}
29+
onChange?.(newValue);
30+
}}
1331
{...props}
1432
/>
1533
</label>

site/src/components/Select.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import classes from "./Select.module.css";
44
/** dropdown select with label */
55
const Select = ({ label, options, onChange, ...props }) => (
66
<label>
7-
<span>{label}</span>
7+
{label && <span>{label}</span>}
88
<div className={classes.container}>
99
<select
1010
className={classes.select}

site/src/components/TableOfContents.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Button from "./Button";
66
import classes from "./TableOfContents.module.css";
77

88
/** all used heading elements */
9-
const headingSelector = "h2, h3, h4";
9+
const headingSelector = "h1, h2, h3, h4";
1010

1111
/**
1212
* floating table of contents that outlines sections/headings on page. can be
@@ -33,7 +33,7 @@ const TableOfContents = () => {
3333
clone.querySelector("a").remove();
3434
const { innerHTML, id, tagName } = clone;
3535
const html = innerHTML.trim();
36-
const level = (parseInt(tagName.slice(1)) || 0) - 1;
36+
const level = parseInt(tagName.slice(1)) || 0;
3737
return { element, html, id, level };
3838
}),
3939
);

site/src/components/TableOfContents.module.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
top: 0;
55
}
66

7-
.aside svg {
8-
opacity: 0.5;
9-
}
10-
117
.table {
128
display: flex;
139
position: absolute;
@@ -52,3 +48,7 @@
5248
.link[data-active] {
5349
font-weight: var(--bold);
5450
}
51+
52+
.link svg {
53+
opacity: 0.25;
54+
}

site/src/components/TextBox.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const TextBox = ({ label, multi, onChange, ...props }) => {
1111

1212
return (
1313
<label>
14-
<span>{label}</span>
14+
{label && <span>{label}</span>}
1515
<div className={classes.container}>
1616
<Component
1717
ref={ref}

0 commit comments

Comments
 (0)