Skip to content

Commit

Permalink
feat: improve component select
Browse files Browse the repository at this point in the history
  • Loading branch information
mebtte committed Aug 14, 2023
1 parent 78aa469 commit f3d05c0
Show file tree
Hide file tree
Showing 17 changed files with 701 additions and 323 deletions.
2 changes: 1 addition & 1 deletion apps/pwa/src/components/file_select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function FileSelect({
});

return (
<Label label={label} disabled={disabled}>
<Label label={label}>
<Style onClick={onSelectFile} disabled={disabled}>
{value ? value.name : placeholder}
</Style>
Expand Down
36 changes: 5 additions & 31 deletions apps/pwa/src/components/input.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import {
FocusEventHandler,
ForwardedRef,
forwardRef,
HtmlHTMLAttributes,
InputHTMLAttributes,
ReactNode,
useImperativeHandle,
useRef,
useState,
} from 'react';
import styled from 'styled-components';
import { ComponentSize } from '../constants/style';
import { CSSVariable } from '../global_style';
import useEvent from '../utils/use_event';
import Label from './label';

const Input = styled.input`
Expand Down Expand Up @@ -42,54 +39,31 @@ const Input = styled.input`
`;

type Ref = {
root: HTMLDivElement;
root: HTMLLabelElement;
input: HTMLInputElement;
};
type Props = {
label?: string;
inputProps: InputHTMLAttributes<HTMLInputElement>;
disabled?: boolean;
addon?: ReactNode;
} & HtmlHTMLAttributes<HTMLDivElement>;
} & HtmlHTMLAttributes<HTMLLabelElement>;

function Wrapper(
{ label, inputProps, disabled = false, addon, ...props }: Props,
ref: ForwardedRef<Ref>,
) {
const rootRef = useRef<HTMLDivElement>(null);
const rootRef = useRef<HTMLLabelElement>(null);
const inputRef = useRef<HTMLInputElement>(null);

const [active, setActive] = useState(false);
const onFocus: FocusEventHandler<HTMLInputElement> = useEvent((e) => {
setActive(true);
return inputProps.onFocus && inputProps.onFocus(e);
});
const onBlur: FocusEventHandler<HTMLInputElement> = useEvent((e) => {
setActive(false);
return inputProps.onBlur && inputProps.onBlur(e);
});

useImperativeHandle(ref, () => ({
root: rootRef.current!,
input: inputRef.current!,
}));

return (
<Label
{...props}
ref={rootRef}
active={active}
disabled={disabled}
label={label}
addon={addon}
>
<Input
{...inputProps}
disabled={disabled}
onFocus={onFocus}
onBlur={onBlur}
ref={inputRef}
/>
<Label {...props} ref={rootRef} label={label} addon={addon}>
<Input {...inputProps} disabled={disabled} ref={inputRef} />
</Label>
);
}
Expand Down
37 changes: 19 additions & 18 deletions apps/pwa/src/components/label.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import upperCaseFirstLetter from '@/style/capitalize';
import { ForwardedRef, forwardRef, HtmlHTMLAttributes, ReactNode } from 'react';
import styled, { css } from 'styled-components';
import styled from 'styled-components';
import { CSSVariable } from '../global_style';

const Style = styled.div<{ active: boolean; disabled: boolean }>`
transition: 300ms ease-in-out;
const Style = styled.label`
> .top {
margin-bottom: 5px;
Expand All @@ -23,37 +21,40 @@ const Style = styled.div<{ active: boolean; disabled: boolean }>`
flex: 1;
min-width: 0;
color: ${CSSVariable.TEXT_COLOR_PRIMARY};
font-size: 12px;
transition: inherit;
${upperCaseFirstLetter}
}
}
${({ active, disabled }) => css`
&:focus-within {
> .top {
> .label {
color: ${CSSVariable.COLOR_PRIMARY};
}
}
}
&:disabled {
> .top {
> .label {
color: ${disabled
? CSSVariable.TEXT_COLOR_DISABLED
: active
? CSSVariable.COLOR_PRIMARY
: CSSVariable.TEXT_COLOR_PRIMARY};
color: ${CSSVariable.TEXT_COLOR_DISABLED} !important;
}
}
`}
}
`;
type Props = HtmlHTMLAttributes<HTMLDivElement> & {
type Props = HtmlHTMLAttributes<HTMLLabelElement> & {
label?: string;
disabled?: boolean;
active?: boolean;
addon?: ReactNode;
};

function Label(
{ label, active = false, disabled = false, addon, children, ...props }: Props,
ref: ForwardedRef<HTMLDivElement>,
{ label, addon, children, ...props }: Props,
ref: ForwardedRef<HTMLLabelElement>,
) {
return (
<Style {...props} active={active} disabled={disabled} ref={ref}>
<Style {...props} ref={ref}>
<div className="top">
{label ? <div className="label">{label}</div> : null}
{addon}
Expand All @@ -63,4 +64,4 @@ function Label(
);
}

export default forwardRef<HTMLDivElement, Props>(Label);
export default forwardRef<HTMLLabelElement, Props>(Label);
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function MultipleSelect<Value>({

const selectedKeys = value.map((i) => i.key);
return (
<Label label={label} active={active} disabled={disabled} addon={addon}>
<Label label={label} addon={addon}>
<Input active={active} disabled={disabled}>
{value.map((option) => (
<ValueItem
Expand Down
7 changes: 3 additions & 4 deletions apps/pwa/src/components/select/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export interface Option<Value> {
key: string | number;
label: string;
export type Option<Value> = {
value: Value;
}
label: string;
};
4 changes: 2 additions & 2 deletions apps/pwa/src/components/select/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Select from './select';
import type { Option } from './constants';

export { Option };
export type { Option } from './constants';

export default Select;
86 changes: 0 additions & 86 deletions apps/pwa/src/components/select/options.tsx

This file was deleted.

Loading

0 comments on commit f3d05c0

Please sign in to comment.