@equinor/eds-core-react
Version:
The React implementation of the Equinor Design System
140 lines (137 loc) • 5.19 kB
JavaScript
import { forwardRef, useState, useCallback } from 'react';
import styled, { css } from 'styled-components';
import { useToken, outlineTemplate, spacingsTemplate, typographyMixin } from '@equinor/eds-utils';
import { inputToken } from './Input.tokens.js';
import { jsxs, jsx } from 'react/jsx-runtime';
import { useEds } from '../EdsProvider/eds.context.js';
const Container = styled.div.withConfig({
displayName: "Input__Container",
componentId: "sc-1ykv024-0"
})(({
$token,
disabled,
readOnly
}) => {
const {
states,
entities
} = $token;
return css(["--eds-input-adornment-color:", ";--eds-input-color:", ";position:relative;height:", ";width:", ";display:flex;flex-direction:row;border:none;box-sizing:border-box;box-shadow:", ";background:var(--eds-input-background,", ");", " &:focus-within{--eds-input-adornment-color:", ";box-shadow:none;", "}", " ", " & > input{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}"], entities.adornment.typography.color, $token.typography.color, $token.height, $token.width, $token.boxShadow, $token.background, outlineTemplate($token.outline), entities.adornment?.states.focus?.outline.color, outlineTemplate(states.focus.outline), disabled && css(["--eds-input-adornment-color:", ";--eds-input-color:", ";cursor:not-allowed;box-shadow:none;"], states.disabled.typography.color, states.disabled.typography.color), readOnly && css({
background: states.readOnly.background,
boxShadow: states.readOnly.boxShadow
}));
});
const StyledInput = styled.input.withConfig({
displayName: "Input__StyledInput",
componentId: "sc-1ykv024-1"
})(({
$token,
$paddingLeft,
$paddingRight
}) => {
return css(["width:100%;border:none;background:transparent;", " ", " outline:none;padding-left:", ";padding-right:", ";&::placeholder{color:", ";}&:disabled{color:var(--eds-input-color);cursor:not-allowed;}"], spacingsTemplate($token.spacings), typographyMixin($token.typography), $paddingLeft, $paddingRight, $token.entities.placeholder.typography.color);
});
const Adornments = styled.div.withConfig({
displayName: "Input__Adornments",
componentId: "sc-1ykv024-2"
})(({
$token
}) => {
return css(["position:absolute;top:", ";bottom:", ";display:flex;align-items:center;", " color:var(--eds-input-adornment-color);"], $token.spacings.top, $token.spacings.bottom, typographyMixin($token.entities.adornment.typography));
});
const LeftAdornments = styled(Adornments).withConfig({
displayName: "Input__LeftAdornments",
componentId: "sc-1ykv024-3"
})(({
$token
}) => css(["left:0;padding-left:", ";"], $token.entities.adornment.spacings.left));
const RightAdornments = styled(Adornments).withConfig({
displayName: "Input__RightAdornments",
componentId: "sc-1ykv024-4"
})(({
$token
}) => css(["right:0;padding-right:", ";"], $token.entities.adornment.spacings.right));
const Input = /*#__PURE__*/forwardRef(function Input({
variant,
disabled = false,
type = 'text',
leftAdornments,
rightAdornments,
readOnly,
className,
style,
leftAdornmentsProps,
rightAdornmentsProps,
leftAdornmentsWidth,
rightAdornmentsWidth,
...other
}, ref) {
const inputVariant = inputToken[variant] ? inputToken[variant] : inputToken.input;
const {
density
} = useEds();
const _token = useToken({
density
}, inputVariant)();
const [rightAdornmentsRef, setRightAdornmentsRef] = useState();
const [leftAdornmentsRef, setLeftAdornmentsRef] = useState();
const token = useCallback(() => {
const _leftAdornmentsWidth = leftAdornmentsWidth || (leftAdornmentsRef ? leftAdornmentsRef.clientWidth : 0);
const _rightAdornmentsWidth = rightAdornmentsWidth || (rightAdornmentsRef ? rightAdornmentsRef.clientWidth : 0);
return {
..._token,
spacings: {
..._token.spacings,
left: `${_leftAdornmentsWidth + parseInt(_token.spacings.left)}px`,
right: `${_rightAdornmentsWidth + parseInt(_token.spacings.right)}px`
}
};
}, [leftAdornmentsWidth, leftAdornmentsRef, rightAdornmentsWidth, rightAdornmentsRef, _token])();
const inputProps = {
ref,
type,
disabled,
readOnly,
$token: token,
style: {
resize: 'none'
},
...other
};
const containerProps = {
disabled,
readOnly,
className,
style,
$token: token
};
const _leftAdornmentProps = {
...leftAdornmentsProps,
ref: setLeftAdornmentsRef,
$token: token
};
const _rightAdornmentProps = {
...rightAdornmentsProps,
ref: setRightAdornmentsRef,
$token: token
};
return (
/*#__PURE__*/
// Not using <ThemeProvider> because of cascading styling messing with adornments
jsxs(Container, {
...containerProps,
children: [leftAdornments ? /*#__PURE__*/jsx(LeftAdornments, {
..._leftAdornmentProps,
children: leftAdornments
}) : null, /*#__PURE__*/jsx(StyledInput, {
$paddingLeft: token.spacings.left,
$paddingRight: token.spacings.right,
...inputProps
}), rightAdornments ? /*#__PURE__*/jsx(RightAdornments, {
..._rightAdornmentProps,
children: rightAdornments
}) : null]
})
);
});
export { Input };