Skip to content

Commit

Permalink
feat(InputFile): migrate to Tailwind
Browse files Browse the repository at this point in the history
  • Loading branch information
DSil committed Oct 2, 2023
1 parent 8787569 commit 960c846
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 562 deletions.
157 changes: 43 additions & 114 deletions packages/orbit-components/src/InputFile/index.tsx
@@ -1,114 +1,18 @@
"use client";

import * as React from "react";
import styled, { css } from "styled-components";
import cx from "clsx";

import type * as Common from "../common/types";
import defaultTheme from "../defaultTheme";
import Button from "../Button";
import ButtonLink from "../ButtonLink";
import FormLabel from "../FormLabel";
import ErrorFormTooltip from "../ErrorFormTooltip";
import Attachment from "../icons/Attachment";
import CloseCircle from "../icons/CloseCircle";
import { rtlSpacing } from "../utils/rtl";
import getSpacingToken from "../common/getSpacingToken";
import getFieldDataState from "../common/getFieldDataState";
import formElementFocus from "../InputField/helpers/formElementFocus";
import useErrorTooltip from "../ErrorFormTooltip/hooks/useErrorTooltip";
import mq from "../utils/mediaQuery";
import type { Props } from "./types";

const Field = styled.label<{ $width: Props["width"]; spaceAfter?: Common.SpaceAfterSizes }>`
${({ theme, $width }) => css`
font-family: ${theme.orbit.fontFamily};
display: block;
position: relative;
width: ${$width};
margin-bottom: ${getSpacingToken};
`}
`;

Field.defaultProps = {
theme: defaultTheme,
};

const FakeInput = styled(({ children, className }) => <div className={className}>{children}</div>)`
${({ theme, $disabled, error }) => css`
box-sizing: border-box;
display: flex;
align-items: center;
padding: ${rtlSpacing(theme.orbit.paddingInputFile)};
height: ${theme.orbit.heightInputNormal};
box-shadow: inset 0 0 0
${`${theme.orbit.borderWidthInput} ${
error ? theme.orbit.borderColorInputError : theme.orbit.borderColorInput
}`};
background-color: $ ${theme.backgroundInput};
transition: box-shadow ${theme.orbit.durationFast} ease-in-out;
border-radius: ${theme.orbit.borderRadiusNormal};
${mq.tablet(css`
border-radius: ${theme.orbit.borderRadiusNormal};
`)};
${$disabled &&
css`
cursor: not-allowed;
background-color: ${theme.orbit.backgroundInputDisabled};
`};
&:hover {
box-shadow: inset 0 0 0
${`${theme.orbit.borderWidthInput} ${
error ? theme.orbit.paletteRedNormalHover : theme.orbit.borderColorInputHover
}`};
}
`}
`;

FakeInput.defaultProps = {
theme: defaultTheme,
};

// we need to hide the input, but not with display or visibility so we can trigger the focus
const Input = styled.input<{ error?: Props["error"] }>`
opacity: 0;
position: absolute;
height: 0;
pointer-events: none;
&:focus ~ ${FakeInput} {
${formElementFocus}
}
`;

Input.defaultProps = {
theme: defaultTheme,
};

const getFileInputColor = ({ error, fileName }, theme) => {
if (error) {
return theme.orbit.paletteRedNormal;
}
if (fileName) {
return theme.orbit.colorTextInput;
}
return theme.orbit.paletteInkNormal;
};

const StyledFileInput = styled.div<Pick<Props, "error" | "fileName">>`
font-family: ${({ theme }) => theme.orbit.fontFamily};
color: ${({ error, fileName, theme }) => getFileInputColor({ error, fileName }, theme)};
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: ${({ theme }) => rtlSpacing(`0 0 0 ${theme.orbit.spaceSmall}`)};
`;

StyledFileInput.defaultProps = {
theme: defaultTheme,
};
import { spaceAfterClasses } from "../common/tailwind";

const InputFile = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
const {
Expand Down Expand Up @@ -150,19 +54,23 @@ const InputFile = React.forwardRef<HTMLDivElement, Props>((props, ref) => {

const shown = tooltipShown || tooltipShownHover;

const onClick = e => {
if (iconRef && iconRef.current && iconRef.current.contains(e.target as Node)) {
e.preventDefault();
e.stopPropagation();
}
};

return (
<Field
spaceAfter={spaceAfter}
// Disabling because the onClick exists just to stop propagation of events
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions
<label
onClick={onClick}
ref={labelRef}
$width={width}
onClick={e => {
if (iconRef && iconRef.current && iconRef.current.contains(e.target as Node)) {
e.preventDefault();
e.stopPropagation();
}
}}
className={cx("font-base relative block w-full", spaceAfter && spaceAfterClasses[spaceAfter])}
style={{ width }}
>
<Input
<input
data-test={dataTest}
id={id}
disabled={disabled}
Expand All @@ -175,16 +83,17 @@ const InputFile = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
}
type="file"
name={name}
error={error}
onChange={onChange}
onFocus={handleFocus}
onBlur={onBlur}
accept={Array.isArray(allowedFileTypes) ? allowedFileTypes.join(",") : allowedFileTypes}
tabIndex={tabIndex ? Number(tabIndex) : undefined}
className="peer pointer-events-none absolute h-0 opacity-0"
/>
{label && (
<FormLabel
filled={!!fileName}
required={required}
error={!!error}
help={!!help}
labelRef={labelRef}
Expand All @@ -195,7 +104,21 @@ const InputFile = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
{label}
</FormLabel>
)}
<FakeInput error={error} $disabled={disabled}>
<div
className={cx(
"peer-focus:outline-blue-normal peer-focus:outline peer-focus:outline-[2px]",
"box-border flex items-center",
"h-form-box-normal ps-[6px]",
error ? "shadow-form-element-error" : "shadow-form-element",
!disabled &&
(error ? "hover:shadow-form-element-error-hover" : "hover:shadow-form-element-hover"),
"duration-fast transition-shadow ease-in-out",
"rounded-normal",
disabled
? "bg-form-element-disabled-background cursor-not-allowed"
: "bg-form-element-background cursor-pointer",
)}
>
<Button
type="secondary"
disabled={disabled}
Expand All @@ -206,9 +129,15 @@ const InputFile = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
>
{buttonLabel}
</Button>
<StyledFileInput fileName={fileName} error={error} ref={ref}>
<div
className={cx(
"font-base ps-sm w-full truncate",
error ? "text-red-normal" : "text-ink-normal",
)}
ref={ref}
>
{fileName || placeholder}
</StyledFileInput>
</div>
{fileName && (
<ButtonLink
type="primary"
Expand All @@ -223,7 +152,7 @@ const InputFile = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
}}
/>
)}
</FakeInput>
</div>
{!insideInputGroup && hasTooltip && (
<ErrorFormTooltip
help={help}
Expand All @@ -235,7 +164,7 @@ const InputFile = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
onShown={setTooltipShown}
/>
)}
</Field>
</label>
);
});

Expand Down

0 comments on commit 960c846

Please sign in to comment.