Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(website): [playground] update options selector #6736

Merged
merged 2 commits into from
Mar 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 0 additions & 75 deletions packages/website/src/components/OptionsSelector.module.css

This file was deleted.

82 changes: 27 additions & 55 deletions packages/website/src/components/OptionsSelector.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
/* eslint-disable jsx-a11y/label-has-associated-control */
import {
NavbarSecondaryMenuFiller,
useWindowSize,
} from '@docusaurus/theme-common';
import CopyIcon from '@site/src/icons/copy.svg';
import IconExternalLink from '@theme/Icon/ExternalLink';
import React, { useCallback } from 'react';

import useDebouncedToggle from './hooks/useDebouncedToggle';
import { useClipboard } from '../hooks/useClipboard';
import Checkbox from './inputs/Checkbox';
import Dropdown from './inputs/Dropdown';
import Tooltip from './inputs/Tooltip';
import ActionLabel from './layout/ActionLabel';
import Expander from './layout/Expander';
import InputLabel from './layout/InputLabel';
import { createMarkdown, createMarkdownParams } from './lib/markdown';
import styles from './OptionsSelector.module.css';
import type { ConfigModel } from './types';

export interface OptionsSelectorParams {
Expand All @@ -28,8 +29,12 @@ function OptionsSelectorContent({
tsVersions,
isLoading,
}: OptionsSelectorParams): JSX.Element {
const [copyLink, setCopyLink] = useDebouncedToggle<boolean>(false);
const [copyMarkdown, setCopyMarkdown] = useDebouncedToggle<boolean>(false);
const [copyLink, copyLinkToClipboard] = useClipboard(() =>
document.location.toString(),
);
const [copyMarkdown, copyMarkdownToClipboard] = useClipboard(() =>
createMarkdown(state),
);

const updateTS = useCallback(
(version: string) => {
Expand All @@ -38,23 +43,6 @@ function OptionsSelectorContent({
[setState],
);

const copyLinkToClipboard = useCallback(() => {
void navigator.clipboard
.writeText(document.location.toString())
.then(() => {
setCopyLink(true);
});
}, [setCopyLink]);

const copyMarkdownToClipboard = useCallback(() => {
if (isLoading) {
return;
}
void navigator.clipboard.writeText(createMarkdown(state)).then(() => {
setCopyMarkdown(true);
});
}, [isLoading, state, setCopyMarkdown]);

const openIssue = useCallback(() => {
if (isLoading) {
return;
Expand All @@ -72,8 +60,7 @@ function OptionsSelectorContent({
return (
<>
<Expander label="Info">
<label className={styles.optionLabel}>
TypeScript
<InputLabel name="TypeScript">
<Dropdown
name="ts"
className="text--right"
Expand All @@ -82,56 +69,41 @@ function OptionsSelectorContent({
onChange={updateTS}
options={(tsVersions.length && tsVersions) || [state.ts]}
/>
</label>
<label className={styles.optionLabel}>
Eslint
<span>{process.env.ESLINT_VERSION}</span>
</label>
<label className={styles.optionLabel}>
TSEslint
<span>{process.env.TS_ESLINT_VERSION}</span>
</label>
</InputLabel>
<InputLabel name="Eslint">{process.env.ESLINT_VERSION}</InputLabel>
<InputLabel name="TSEslint">{process.env.TS_ESLINT_VERSION}</InputLabel>
</Expander>
<Expander label="Options">
<label className={styles.optionLabel}>
Enable jsx
<InputLabel name="Enable jsx">
<Checkbox
name="jsx"
checked={state.jsx}
onChange={(e): void => setState({ jsx: e })}
className={styles.optionCheckbox}
/>
</label>
<label className={styles.optionLabel}>
Source type
</InputLabel>
<InputLabel name="Source type">
<Dropdown
name="sourceType"
value={state.sourceType}
onChange={(e): void => setState({ sourceType: e })}
options={['script', 'module']}
/>
</label>
</InputLabel>
</Expander>
<Expander label="Actions">
<button className={styles.optionLabel} onClick={copyLinkToClipboard}>
Copy Link
<ActionLabel name="Copy link" onClick={copyLinkToClipboard}>
<Tooltip open={copyLink} text="Copied">
<CopyIcon />
<CopyIcon width="13.5" height="13.5" />
</Tooltip>
</button>
<button
className={styles.optionLabel}
onClick={copyMarkdownToClipboard}
>
Copy Markdown
</ActionLabel>
<ActionLabel name="Copy Markdown" onClick={copyMarkdownToClipboard}>
<Tooltip open={copyMarkdown} text="Copied">
<CopyIcon />
<CopyIcon width="13.5" height="13.5" />
</Tooltip>
</button>
<button className={styles.optionLabel} onClick={openIssue}>
Report as Issue
<CopyIcon />
</button>
</ActionLabel>
<ActionLabel name="Report as Issue" onClick={openIssue}>
<IconExternalLink width="13.5" height="13.5" />
</ActionLabel>
</Expander>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.search {
border-radius: 0.2rem;
}

.searchResult,
.searchResultGroup {
align-items: center;
Expand Down
3 changes: 1 addition & 2 deletions packages/website/src/components/config/ConfigEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,9 @@ function ConfigEditor(props: ConfigEditorProps): JSX.Element {
<div className={styles.searchBar}>
<Text
ref={filterInput}
type="text"
type="search"
name="config-filter"
value={filter}
className={styles.search}
onChange={setFilter}
/>
</div>
Expand Down
20 changes: 20 additions & 0 deletions packages/website/src/components/inputs/Dropdown.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.dropdown {
line-height: 1;
font-size: 0.8rem;
font-weight: 500;
border-radius: 6px;
font-family: inherit;
width: 50%;
box-shadow: none;
padding: 0.4rem 0.6rem;
appearance: none;
color: var(--ifm-font-color-secondary);
border: 1px solid var(--ifm-color-emphasis-100);
background: var(--ifm-color-emphasis-200);
transition: border 0.3s ease;
}

.dropdown:focus {
outline: none;
border-color: var(--ifm-color-primary);
}
4 changes: 2 additions & 2 deletions packages/website/src/components/inputs/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import clsx from 'clsx';
import React from 'react';

import styles from '../OptionsSelector.module.css';
import styles from './Dropdown.module.css';

export interface DropdownOption<T> {
readonly value: T;
Expand All @@ -28,10 +28,10 @@ function Dropdown<T extends boolean | string | number>(

return (
<select
className={clsx(styles.dropdown, props.className)}
name={props.name}
disabled={props.disabled}
value={String(props.value)}
className={clsx(styles.optionSelect, props.className)}
onChange={(e): void => {
const selected = options.find(
item => String(item.value) === e.target.value,
Expand Down
5 changes: 3 additions & 2 deletions packages/website/src/components/inputs/Text.module.css
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
.textInput {
appearance: none;
background-color: var(--ifm-color-emphasis-200);
border: 1px solid var(--ifm-color-emphasis-100);
color: var(--ifm-font-color-secondary);
transition: border 0.3s ease;
cursor: text;
display: inline-block;
height: 2rem;
padding: 0 0.5rem 0 2.25rem;
padding: 0 0.5rem;
font-size: 0.9rem;
border-radius: 0.2rem;
flex: 1;
}

.textInput[type='search'] {
padding-left: 2.25rem;
background: var(--ifm-color-emphasis-200) var(--ifm-navbar-search-input-icon)
no-repeat 0.75rem center / 1rem 1rem;
}
Expand Down
1 change: 1 addition & 0 deletions packages/website/src/components/inputs/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const Text = React.forwardRef<HTMLInputElement, DropdownProps>(
name={props.name}
className={clsx(styles.textInput, props.className)}
type={props.type ?? 'text'}
autoComplete="off"
placeholder={props.placeholder}
ref={ref}
/>
Expand Down
20 changes: 20 additions & 0 deletions packages/website/src/components/layout/ActionLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';

import styles from './InputLabel.module.css';

export interface InputLabelProps {
readonly name: string;
readonly children: React.ReactNode;
readonly onClick: () => void;
}

function ActionLabel(props: InputLabelProps): JSX.Element {
return (
<button onClick={props.onClick} className={styles.optionLabel}>
<span>{props.name}</span>
{props.children}
</button>
);
}

export default ActionLabel;
25 changes: 25 additions & 0 deletions packages/website/src/components/layout/InputLabel.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
.optionLabel {
cursor: pointer;
align-items: center;
display: flex;
flex: 0 0 1.5rem;
flex-direction: row;
font-size: 0.75rem;
margin: 0;
padding: 0.4rem 0.8rem;
transition: background-color var(--ifm-transition-fast)
var(--ifm-transition-timing-default),
color var(--ifm-transition-fast) var(--ifm-transition-timing-default);
color: var(--ifm-font-color-secondary);
justify-content: space-between;
border: none;
background: transparent;
font-family: var(--ifm-font-family-base);
box-sizing: border-box;
line-height: var(--ifm-line-height-base);
}

.optionLabel:hover {
background-color: var(--ifm-color-emphasis-100);
color: var(--ifm-font-color-primary);
}
19 changes: 19 additions & 0 deletions packages/website/src/components/layout/InputLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';

import styles from './InputLabel.module.css';

export interface InputLabelProps {
readonly name: string;
readonly children: React.ReactNode;
}

function InputLabel(props: InputLabelProps): JSX.Element {
return (
<label className={styles.optionLabel}>
<span>{props.name}</span>
{props.children}
</label>
);
}

export default InputLabel;
17 changes: 17 additions & 0 deletions packages/website/src/hooks/useClipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useCallback } from 'react';

import { useDebouncedToggle } from './useDebouncedToggle';

export type useClipboardResult = [copied: boolean, copy: () => void];

export function useClipboard(code: () => string): useClipboardResult {
const [copied, setCopied] = useDebouncedToggle(false);

const copy = useCallback(() => {
void navigator.clipboard.writeText(code()).then(() => {
setCopied(true);
});
}, [setCopied, code]);

return [copied, copy];
}