diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/settings/components/site.scss | 8 | ||||
| -rw-r--r-- | src/settings/components/ui/AddButton.scss | 13 | ||||
| -rw-r--r-- | src/settings/components/ui/AddButton.tsx | 31 | ||||
| -rw-r--r-- | src/settings/components/ui/DeleteButton.scss | 13 | ||||
| -rw-r--r-- | src/settings/components/ui/DeleteButton.tsx | 30 | ||||
| -rw-r--r-- | src/settings/components/ui/Input.scss | 29 | ||||
| -rw-r--r-- | src/settings/components/ui/Radio.tsx | 59 | ||||
| -rw-r--r-- | src/settings/components/ui/Text.tsx | 70 | ||||
| -rw-r--r-- | src/settings/components/ui/TextArea.tsx | 76 | 
9 files changed, 145 insertions, 184 deletions
diff --git a/src/settings/components/site.scss b/src/settings/components/site.scss index c0c4f9e..e8415e8 100644 --- a/src/settings/components/site.scss +++ b/src/settings/components/site.scss @@ -1,12 +1,6 @@  .vimvixen-settings-form {    padding: 2px; - -  textarea[name=json] { -    font-family: monospace; -    width: 100%; -    min-height: 64ex; -    resize: vertical; -  } +  font-family: system-ui;    fieldset {      margin: 0; diff --git a/src/settings/components/ui/AddButton.scss b/src/settings/components/ui/AddButton.scss deleted file mode 100644 index beb5688..0000000 --- a/src/settings/components/ui/AddButton.scss +++ /dev/null @@ -1,13 +0,0 @@ -.ui-add-button { -  border: none; -  padding: 4; -  display: inline; -  background: none; -  font-weight: bold; -  color: green; -  cursor: pointer; - -  &:hover { -    color: darkgreen; -  } -} diff --git a/src/settings/components/ui/AddButton.tsx b/src/settings/components/ui/AddButton.tsx index c15a732..8cf4300 100644 --- a/src/settings/components/ui/AddButton.tsx +++ b/src/settings/components/ui/AddButton.tsx @@ -1,19 +1,24 @@ -import "./AddButton.scss";  import React from "react"; +import styled from "styled-components"; -type Props = React.AllHTMLAttributes<HTMLInputElement>; +const Button = styled.input` +  border: none; +  padding: 4; +  display: inline; +  background: none; +  font-weight: bold; +  color: green; +  cursor: pointer; -class AddButton extends React.Component<Props> { -  render() { -    return ( -      <input -        className="ui-add-button" -        type="button" -        value="✚" -        {...this.props} -      /> -    ); +  &:hover { +    color: darkgreen;    } -} +`; + +type Props = React.InputHTMLAttributes<HTMLInputElement>; + +const AddButton: React.FC<Props> = (props) => ( +  <Button type="button" value="✚" {...props} /> +);  export default AddButton; diff --git a/src/settings/components/ui/DeleteButton.scss b/src/settings/components/ui/DeleteButton.scss deleted file mode 100644 index 5932a72..0000000 --- a/src/settings/components/ui/DeleteButton.scss +++ /dev/null @@ -1,13 +0,0 @@ - -.ui-delete-button { -  border: none; -  padding: 4; -  display: inline; -  background: none; -  color: red; -  cursor: pointer; - -  &:hover { -    color: darkred; -  } -} diff --git a/src/settings/components/ui/DeleteButton.tsx b/src/settings/components/ui/DeleteButton.tsx index df8976e..ce0183b 100644 --- a/src/settings/components/ui/DeleteButton.tsx +++ b/src/settings/components/ui/DeleteButton.tsx @@ -1,19 +1,23 @@ -import "./DeleteButton.scss";  import React from "react"; +import styled from "styled-components"; -type Props = React.AllHTMLAttributes<HTMLInputElement>; +const Button = styled.input` +  border: none; +  padding: 4; +  display: inline; +  background: none; +  color: red; +  cursor: pointer; -class DeleteButton extends React.Component<Props> { -  render() { -    return ( -      <input -        className="ui-delete-button" -        type="button" -        value="✖" -        {...this.props} -      /> -    ); +  &:hover { +    color: darkred;    } -} +`; + +type Props = React.InputHTMLAttributes<HTMLInputElement>; + +const DeleteButton: React.FC<Props> = (props) => ( +  <Button type="button" value="✖" {...props} /> +);  export default DeleteButton; diff --git a/src/settings/components/ui/Input.scss b/src/settings/components/ui/Input.scss deleted file mode 100644 index ad4daf8..0000000 --- a/src/settings/components/ui/Input.scss +++ /dev/null @@ -1,29 +0,0 @@ -.settings-ui-input { -  page-break-inside: avoid; - -  * { -    page-break-inside: avoid; -  } - -  label { -    font-weight: bold; -    min-width: 14rem; -    display: inline-block; -  } - -  input[type='text'] { -    padding: 4px; -    width: 8rem; -  } - -  input.input-crror, -  textarea.input-error { -    box-shadow: 0 0 2px red; -  } - -  &-error { -    font-weight: bold; -    color: red; -    min-height: 1.5em; -  } -} diff --git a/src/settings/components/ui/Radio.tsx b/src/settings/components/ui/Radio.tsx index 20d4ad6..c0d4dd9 100644 --- a/src/settings/components/ui/Radio.tsx +++ b/src/settings/components/ui/Radio.tsx @@ -1,44 +1,33 @@  import React from "react"; -import "./Input.scss"; +import styled from "styled-components"; -interface Props extends React.AllHTMLAttributes<HTMLElement> { -  name: string; -  error?: string; +const Container = styled.div` +  font-family: system-ui; +`; + +interface Props extends React.InputHTMLAttributes<HTMLInputElement> {    label: string; -  value: string;    onValueChange?: (name: string, value: string) => void; -  onBlur?: (e: React.FocusEvent<Element>) => void;  } -class Input extends React.Component<Props> { -  renderRadio(props: Props) { -    const inputClassName = props.error ? "input-error" : ""; -    const pp = { ...props }; -    delete pp.onValueChange; -    return ( -      <div className="settings-ui-input"> -        <label> -          <input -            type="radio" -            className={inputClassName} -            onChange={this.bindOnChange.bind(this)} -            {...pp} -          /> -          {props.label} -        </label> -      </div> -    ); -  } +const Radio: React.FC<Props> = (props) => { +  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => { +    if (props.onValueChange) { +      props.onValueChange(e.target.name, e.target.value); +    } +  }; -  render() { -    return this.renderRadio(this.props); -  } +  const pp = { ...props }; +  delete pp.onValueChange; -  bindOnChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) { -    if (this.props.onValueChange) { -      this.props.onValueChange(e.target.name, e.target.value); -    } -  } -} +  return ( +    <Container> +      <label htmlFor={props.id}> +        <input type="radio" onChange={onChange} {...pp} /> +        {props.label} +      </label> +    </Container> +  ); +}; -export default Input; +export default Radio; diff --git a/src/settings/components/ui/Text.tsx b/src/settings/components/ui/Text.tsx index 7ecef88..700b08a 100644 --- a/src/settings/components/ui/Text.tsx +++ b/src/settings/components/ui/Text.tsx @@ -1,42 +1,54 @@  import React from "react"; -import "./Input.scss"; +import styled from "styled-components"; -interface Props extends React.AllHTMLAttributes<HTMLElement> { +const Container = styled.div` +  page-break-inside: avoid; +`; + +const Input = styled.input<{ hasError: boolean }>` +  padding: 4px; +  width: 8rem; +  box-shadow: ${({ hasError }) => (hasError ? "0 0 2px red" : "none")}; +`; + +const Label = styled.label` +  font-weight: bold; +  min-width: 14rem; +  display: inline-block; +`; + +interface Props extends React.HTMLAttributes<HTMLElement> {    name: string;    error?: string;    label: string;    value: string;    onValueChange?: (name: string, value: string) => void; -  onBlur?: (e: React.FocusEvent<Element>) => void;  } -class Input extends React.Component<Props> { -  renderText(props: Props) { -    const inputClassName = props.error ? "input-error" : ""; -    const pp = { ...props }; -    delete pp.onValueChange; -    return ( -      <div className="settings-ui-input"> -        <label htmlFor={props.id}>{props.label}</label> -        <input +const Text: React.FC<Props> = (props) => { +  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => { +    if (props.onValueChange) { +      props.onValueChange(e.target.name, e.target.value); +    } +  }; + +  const pp = { ...props }; +  delete pp.onValueChange; + +  return ( +    <Container> +      <Label> +        {props.label} +        <br /> +        <Input            type="text" -          className={inputClassName} -          onChange={this.bindOnChange.bind(this)} +          hasError={props.error !== undefined} +          onChange={onChange}            {...pp}          /> -      </div> -    ); -  } - -  render() { -    return this.renderText(this.props); -  } - -  bindOnChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) { -    if (this.props.onValueChange) { -      this.props.onValueChange(e.target.name, e.target.value); -    } -  } -} +      </Label> +    </Container> +  ); +}; -export default Input; +export default Text; diff --git a/src/settings/components/ui/TextArea.tsx b/src/settings/components/ui/TextArea.tsx index f2b832f..58b7bd3 100644 --- a/src/settings/components/ui/TextArea.tsx +++ b/src/settings/components/ui/TextArea.tsx @@ -1,42 +1,54 @@  import React from "react"; -import "./Input.scss"; +import styled from "styled-components"; -interface Props extends React.AllHTMLAttributes<HTMLElement> { -  name: string; +const Container = styled.div` +  page-break-inside: avoid; +`; + +const Label = styled.label` +  font-weight: bold; +  min-width: 14rem; +  display: inline-block; +`; + +const ErrorableTextArea = styled.textarea<{ hasError: boolean }>` +  box-shadow: ${({ hasError }) => (hasError ? "0 0 2px red" : "none")}; +  font-family: monospace; +  font-family: monospace; +  width: 100%; +  min-height: 64ex; +  resize: vertical; +`; + +const ErrorMessage = styled.p` +  font-weight: bold; +  color: red; +  min-height: 1.5em; +`; + +interface Props extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {    error?: string;    label: string; -  value: string;    onValueChange?: (name: string, value: string) => void; -  onBlur?: (e: React.FocusEvent<Element>) => void;  } -class TextArea extends React.Component<Props> { -  renderTextArea(props: Props) { -    const inputClassName = props.error ? "input-error" : ""; -    const pp = { ...props }; -    delete pp.onValueChange; -    return ( -      <div className="settings-ui-input"> -        <label htmlFor={props.id}>{props.label}</label> -        <textarea -          className={inputClassName} -          onChange={this.bindOnChange.bind(this)} -          {...pp} -        /> -        <p className="settings-ui-input-error">{this.props.error}</p> -      </div> -    ); -  } - -  render() { -    return this.renderTextArea(this.props); -  } - -  bindOnChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) { -    if (this.props.onValueChange) { -      this.props.onValueChange(e.target.name, e.target.value); +const TextArea: React.FC<Props> = (props) => { +  const onChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { +    if (props.onValueChange) { +      props.onValueChange(e.target.name, e.target.value);      } -  } -} +  }; + +  const hasError = typeof props.error !== "undefined" && props.error !== ""; +  const pp = { ...props }; +  delete pp.onValueChange; +  return ( +    <Container> +      <Label htmlFor={props.id}>{props.label}</Label> +      <ErrorableTextArea hasError={hasError} onChange={onChange} {...pp} /> +      {hasError ? <ErrorMessage>{props.error}</ErrorMessage> : null} +    </Container> +  ); +};  export default TextArea;  | 
