Skip to content

Commit 8f2f1cc

Browse files
committed
Refactor to get a11y back and simplify code
1 parent 6512ff7 commit 8f2f1cc

File tree

3 files changed

+43
-85
lines changed

3 files changed

+43
-85
lines changed

app/styles/resources.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@
4141
}
4242

4343
& [data-code-block-copy] {
44-
@apply absolute top-[1.125rem] h-5 w-5 cursor-pointer bg-white/80 opacity-0 dark:bg-gray-900/80;
44+
@apply absolute right-4 top-[1.125rem] h-5 w-5 cursor-pointer bg-white/80 opacity-0 dark:bg-gray-900/80;
4545
}
4646

4747
&:hover [data-code-block-copy],
48-
& [data-code-block-copy]:focus {
48+
& [data-code-block-copy]:focus-within {
4949
@apply opacity-100;
5050
}
5151

app/ui/details-menu.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,21 +81,19 @@ DetailsMenu.displayName = "DetailsMenu";
8181

8282
type DetailsPopupProps = {
8383
className?: string;
84-
childrenClassName?: string;
8584
};
8685

8786
export function DetailsPopup({
8887
children,
89-
className = "",
90-
childrenClassName = "",
88+
className,
9189
}: PropsWithChildren<DetailsPopupProps>) {
9290
return (
93-
<div className={cx(className, "absolute right-0 z-20 md:left-0")}>
91+
// TODO: remove the width being defined here. Seems like it should be a min-width: fit-content or something, and anything more specific defined by the children passed in (or a className)
92+
<div className={cx("absolute right-0 z-20 w-40 md:left-0", className)}>
9493
<div
95-
className={cx(
96-
childrenClassName,
97-
"relative top-1 w-40 rounded-md border border-gray-100 bg-white p-1 shadow-sm dark:border-gray-800 dark:bg-gray-900",
98-
)}
94+
className={
95+
"relative top-1 rounded-md border border-gray-100 bg-white p-1 shadow-sm dark:border-gray-800 dark:bg-gray-900"
96+
}
9997
>
10098
{children}
10199
</div>

app/ui/resources.tsx

Lines changed: 35 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { transformNpmCommand } from "~/lib/transformNpmCommand";
44
import type { PackageManager } from "~/lib/transformNpmCommand";
55
import { DetailsMenu, DetailsPopup } from "./details-menu";
66

7-
import { Form, Link, useSearchParams, useSubmit } from "@remix-run/react";
7+
import { Link, useSearchParams, useSubmit } from "@remix-run/react";
88
import cx from "clsx";
99
import iconsHref from "~/icons.svg";
1010

@@ -70,12 +70,18 @@ export function InitCodeblock({
7070
// Probably a more elegant solution, but this is what I've got
7171
let [npxOrNpmMaybe, ...otherCode] = initCommand.trim().split(" ");
7272
let [copied, setCopied] = useState(false);
73+
const submit = useSubmit();
7374

74-
function handleCopied(copied: boolean, packageManager: PackageManager) {
75-
setCopied(copied);
75+
function handleCopy(packageManager: PackageManager) {
76+
setCopied(true);
7677
navigator.clipboard.writeText(
7778
transformNpmCommand(npxOrNpmMaybe, otherCode.join(" "), packageManager),
7879
);
80+
// This is a hack to close the details menu after clicking
81+
submit(null, {
82+
preventScrollReset: true,
83+
replace: true,
84+
});
7985
}
8086

8187
// Reset copied state after 4 seconds
@@ -117,35 +123,24 @@ export function InitCodeblock({
117123
</code>
118124
</pre>
119125

120-
<CopyCodeBlock setCopied={handleCopied} copied={copied} />
126+
<CopyCodeBlock copied={copied} onCopy={handleCopy} />
121127
</div>
122128
);
123129
}
124130

125131
type CopyCodeBlockProps = {
126132
copied: boolean;
127-
setCopied: (copied: boolean, packageManager: PackageManager) => void;
133+
onCopy: (packageManager: PackageManager) => void;
128134
};
129135

130-
function CopyCodeBlock({ copied, setCopied }: CopyCodeBlockProps) {
131-
const [isMenuOpen, setIsMenuOpen] = useState(false);
132-
const [searchParams] = useSearchParams();
133-
136+
function CopyCodeBlock({ copied, onCopy }: CopyCodeBlockProps) {
134137
return (
135-
<DetailsMenu
136-
className="absolute right-4 top-0 !opacity-100"
137-
data-copied={copied}
138-
onToggle={() => setIsMenuOpen((oldValue) => !oldValue)}
139-
>
138+
<DetailsMenu className="absolute" data-copied={copied} data-code-block-copy>
140139
<summary
141-
className="_no-triangle absolute top-0 grid"
140+
className="_no-triangle block outline-offset-2"
142141
data-copied={copied}
143142
>
144-
<span
145-
data-code-block-copy
146-
data-copied={copied}
147-
className={`absolute right-0 top-0 opacity-0 hover:opacity-100 ${copied || isMenuOpen ? "!opacity-100" : ""}`}
148-
>
143+
<span data-copied={copied}>
149144
<svg
150145
aria-hidden
151146
className="h-5 w-5 text-gray-500 hover:text-black dark:text-gray-400 dark:hover:text-gray-100"
@@ -160,61 +155,26 @@ function CopyCodeBlock({ copied, setCopied }: CopyCodeBlockProps) {
160155
<span className="sr-only">Copy code to clipboard</span>
161156
</span>
162157
</summary>
163-
<DetailsPopup
164-
className="!left-auto !right-0 top-10"
165-
childrenClassName="!w-[110px]"
166-
>
167-
<Form preventScrollReset replace className="flex flex-col">
168-
<input
169-
type="hidden"
170-
name="category"
171-
value={searchParams.get("category") || ""}
172-
/>
173-
174-
<PackageManagerButton
175-
packageManager="npm"
176-
setCopied={(copied) => setCopied(copied, "npm")}
177-
/>
178-
<PackageManagerButton
179-
packageManager="yarn"
180-
setCopied={(copied) => setCopied(copied, "yarn")}
181-
/>
182-
<PackageManagerButton
183-
packageManager="pnpm"
184-
setCopied={(copied) => setCopied(copied, "pnpm")}
185-
/>
186-
<PackageManagerButton
187-
packageManager="bun"
188-
setCopied={(copied) => setCopied(copied, "bun")}
189-
/>
190-
</Form>
191-
</DetailsPopup>
158+
<div className="absolute left-auto right-0 top-10 w-[110px]">
159+
<DetailsPopup
160+
// TODO: remove when we get the DetailsPopup figured out
161+
className="w-full" // ehhh, we'll see
162+
>
163+
<div className="flex flex-col">
164+
{(["npm", "yarn", "pnpm", "bun"] as const).map((packageManager) => (
165+
<button
166+
key={packageManager}
167+
className="rounded-md p-1.5 text-left text-sm text-gray-700 hover:bg-blue-200/50 hover:text-black dark:text-gray-400 dark:hover:bg-blue-800/50 dark:hover:text-gray-100"
168+
onClick={() => {
169+
onCopy(packageManager);
170+
}}
171+
>
172+
{packageManager}
173+
</button>
174+
))}
175+
</div>
176+
</DetailsPopup>
177+
</div>
192178
</DetailsMenu>
193179
);
194180
}
195-
196-
type PackageManagerButtonProps = {
197-
packageManager: PackageManager;
198-
setCopied: (copied: boolean) => void;
199-
};
200-
201-
function PackageManagerButton({
202-
packageManager,
203-
setCopied,
204-
}: PackageManagerButtonProps) {
205-
const submit = useSubmit();
206-
return (
207-
<button
208-
className="rounded-md p-1.5 text-left text-sm hover:cursor-pointer hover:bg-gray-50"
209-
type="submit"
210-
onClick={() => {
211-
submit({
212-
preventScrollReset: false,
213-
});
214-
setCopied(true);
215-
}}
216-
>
217-
{packageManager}
218-
</button>
219-
);
220-
}

0 commit comments

Comments
 (0)