Skip to content

Commit

Permalink
FOrmat
Browse files Browse the repository at this point in the history
  • Loading branch information
sverhoeven committed Aug 6, 2024
1 parent 7d3716a commit 7eed696
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 127 deletions.
29 changes: 18 additions & 11 deletions src/HiddenFileInput.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import { action, Story } from "@ladle/react";
import { Story, action } from "@ladle/react";
import { HiddenFileInput } from "./HiddenFileInput";

const file = new File(["Hello, world!"], "hello-world.txt", {
type: "text/plain",
type: "text/plain",
});

export const Default: Story = () => (
<form onSubmit={(e) => {
e.preventDefault();
const form = e.target as HTMLFormElement;
const formData = new FormData(form);
action("submit")(formData)
}}>
<HiddenFileInput name="myfile" file={file} />
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" type="submit">Submit</button>
</form>
<form
onSubmit={(e) => {
e.preventDefault();
const form = e.target as HTMLFormElement;
const formData = new FormData(form);
action("submit")(formData);
}}
>
<HiddenFileInput name="myfile" file={file} />
<button
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
type="submit"
>
Submit
</button>
</form>
);
18 changes: 9 additions & 9 deletions src/HiddenFileInput.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { useEffect, useRef } from "react";

export function HiddenFileInput({ name, file }: { name: string; file: File }) {
const ref = useRef<HTMLInputElement>(null);
const ref = useRef<HTMLInputElement>(null);

useEffect(() => {
if (ref.current) {
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);
ref.current.files = dataTransfer.files;
}
}, [file]);
useEffect(() => {
if (ref.current) {
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);
ref.current.files = dataTransfer.files;
}
}, [file]);

return <input ref={ref} type="file" name={name} className="hidden" />;
return <input ref={ref} type="file" name={name} className="hidden" />;
}
19 changes: 10 additions & 9 deletions src/LinkToFile.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ import { Story } from "@ladle/react";
import { LinkToFile } from "./LinkToFile";

const file = new File(["Hello, world!"], "hello-world.txt", {
type: "text/plain",
type: "text/plain",
});

export const Default: Story = () => (
<LinkToFile file={file}>
A link to a text file with hello world.
</LinkToFile>
)
<LinkToFile file={file}>A link to a text file with hello world.</LinkToFile>
);

export const Styled: Story = () => (
<LinkToFile file={file} className="bg-green-400 no-underline hover:bg-green-500 p-4">
A link to a text file with hello world.
</LinkToFile>
)
<LinkToFile
file={file}
className="bg-green-400 no-underline hover:bg-green-500 p-4"
>
A link to a text file with hello world.
</LinkToFile>
);
46 changes: 23 additions & 23 deletions src/LinkToFile.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
import { useState, useEffect, ReactNode } from "react";
import { ReactNode, useEffect, useState } from "react";
import { cn } from "./cn";

// TODO allow other a tag attributes like title or target to be passed in

export function LinkToFile({
file,
children,
className = undefined,
file,
children,
className = undefined,
}: {
file: File;
children: ReactNode;
className?: string;
file: File;
children: ReactNode;
className?: string;
}) {
const [url, setUrl] = useState("#");
const [url, setUrl] = useState("#");

useEffect(() => {
const url = URL.createObjectURL(file);
setUrl(url);
return () => URL.revokeObjectURL(url);
}, [file]);
useEffect(() => {
const url = URL.createObjectURL(file);
setUrl(url);
return () => URL.revokeObjectURL(url);
}, [file]);

return (
<a
className={cn("underline", className)}
download={file.name}
href={url}
type={file.type}
>
{children}
</a>
);
return (
<a
className={cn("underline", className)}
download={file.name}
href={url}
type={file.type}
>
{children}
</a>
);
}
32 changes: 16 additions & 16 deletions src/getResName1.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ import { useMemo, useState } from "react";
import { getResName1 } from "./getResName1";

export const Default: Story = () => {
const [resName, setResName] = useState("ALA");
const seq = useMemo(() => getResName1(resName), [resName]);
const [resName, setResName] = useState("ALA");
const seq = useMemo(() => getResName1(resName), [resName]);

return (
<div className="prose">
<label className="flex gap-2">
3 letter residue name
<input
type="text"
value={resName}
onChange={(e) => setResName(e.target.value)}
className="border-2"
/>
</label>
<p>Single letter sequence: {seq}</p>
</div>
);
return (
<div className="prose">
<label className="flex gap-2">
3 letter residue name
<input
type="text"
value={resName}
onChange={(e) => setResName(e.target.value)}
className="border-2"
/>
</label>
<p>Single letter sequence: {seq}</p>
</div>
);
};
112 changes: 56 additions & 56 deletions src/getResName1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,59 +4,59 @@ Use molstar implementation from
https://github.com/molstar/molstar/blob/5a2ee03b48e1822c8843d65eb18d578af0579b9f/src/mol-model/sequence/constants.ts#L18-L85
*/
const Name2OneLetter = {
HIS: "H",
ARG: "R",
LYS: "K",
ILE: "I",
PHE: "F",
LEU: "L",
TRP: "W",
ALA: "A",
MET: "M",
PRO: "P",
CYS: "C",
ASN: "N",
VAL: "V",
GLY: "G",
SER: "S",
GLN: "Q",
TYR: "Y",
ASP: "D",
GLU: "E",
THR: "T",
SEC: "U", // as per IUPAC definition
PYL: "O", // as per IUPAC definition
// charmm ff
HSD: "H",
HSE: "H",
HSP: "H",
LSN: "K",
ASPP: "D",
GLUP: "E",
// amber ff
HID: "H",
HIE: "H",
HIP: "H",
LYN: "K",
ASH: "D",
GLH: "E",
// DNA
DA: "A",
DC: "C",
DG: "G",
DT: "T",
DU: "U",
// RNA
A: "A",
C: "C",
G: "G",
T: "T",
U: "U",
} as const;
export function getResName1(resname: string) {
return Name2OneLetter[resname as keyof typeof Name2OneLetter] || "X";
}
HIS: "H",
ARG: "R",
LYS: "K",
ILE: "I",
PHE: "F",
LEU: "L",
TRP: "W",
ALA: "A",
MET: "M",
PRO: "P",
CYS: "C",
ASN: "N",
VAL: "V",
GLY: "G",
SER: "S",
GLN: "Q",
TYR: "Y",
ASP: "D",
GLU: "E",
THR: "T",

SEC: "U", // as per IUPAC definition
PYL: "O", // as per IUPAC definition

// charmm ff
HSD: "H",
HSE: "H",
HSP: "H",
LSN: "K",
ASPP: "D",
GLUP: "E",

// amber ff
HID: "H",
HIE: "H",
HIP: "H",
LYN: "K",
ASH: "D",
GLH: "E",
// DNA
DA: "A",
DC: "C",
DG: "G",
DT: "T",
DU: "U",
// RNA
A: "A",
C: "C",
G: "G",
T: "T",
U: "U",
} as const;

export function getResName1(resname: string) {
return Name2OneLetter[resname as keyof typeof Name2OneLetter] || "X";
}
6 changes: 3 additions & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export { PickIn3D, ResiduesSelect } from "./toggles";
export { useChunked } from "./useChunked";
export { ResiduesHeader, residueVariants };
export type { Variant };
export {LinkToFile} from "./LinkToFile";
export {HiddenFileInput} from "./HiddenFileInput";
export {getResName1} from "./getResName1";
export { LinkToFile } from "./LinkToFile";
export { HiddenFileInput } from "./HiddenFileInput";
export { getResName1 } from "./getResName1";

0 comments on commit 7eed696

Please sign in to comment.