123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- import {forwardRef} from 'react';
- import isPropValid from '@emotion/is-prop-valid';
- import {css} from '@emotion/react';
- import styled from '@emotion/styled';
- import {FormSize, Theme} from 'sentry/utils/theme';
- export interface InputProps
- extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {
- monospace?: boolean;
- nativeSize?: React.InputHTMLAttributes<HTMLInputElement>['size'];
- size?: FormSize;
- type?: React.HTMLInputTypeAttribute;
- }
- export const inputStyles = (p: InputProps & {theme: Theme}) => css`
- display: block;
- width: 100%;
- color: ${p.theme.formText};
- background: ${p.theme.background};
- border: 1px solid ${p.theme.border};
- border-radius: ${p.theme.borderRadius};
- box-shadow: inset ${p.theme.dropShadowLight};
- resize: vertical;
- transition: border 0.1s, box-shadow 0.1s;
- ${p.monospace ? `font-family: ${p.theme.text.familyMono};` : ''}
- ${p.readOnly ? 'cursor: default;' : ''}
- ${p.theme.form[p.size ?? 'md']}
- ${p.theme.formPadding[p.size ?? 'md']}
- &::placeholder {
- color: ${p.theme.formPlaceholder};
- opacity: 1;
- }
- &[disabled] {
- background: ${p.theme.backgroundSecondary};
- color: ${p.theme.disabled};
- cursor: not-allowed;
- &::placeholder {
- color: ${p.theme.disabled};
- }
- }
- &:focus,
- &.focus-visible {
- outline: none;
- border-color: ${p.theme.focusBorder};
- box-shadow: ${p.theme.focusBorder} 0 0 0 1px;
- }
- `;
- /**
- * Basic input component.
- *
- * Use the `size` prop ('md', 'sm', 'xs') to control the input's height &
- * padding. To use the native size attribute (which controls the number of
- * characters the input should fit), use the `nativeSize` prop instead.
- *
- * To add leading/trailing items (e.g. a search icon on the left side), use
- * InputControl (components/inputControl) instead.
- */
- const Input = styled(
- forwardRef<HTMLInputElement, InputProps>(
- (
- {
- // Do not forward `required` to avoid default browser behavior
- required: _required,
- // Do not forward `size` since it's used for custom styling, not as the
- // native `size` attribute (for that, use `nativeSize` instead)
- size: _size,
- // Use `nativeSize` as the native `size` attribute
- nativeSize,
- ...props
- },
- ref
- ) => <input {...props} ref={ref} size={nativeSize} />
- ),
- {shouldForwardProp: prop => typeof prop === 'string' && isPropValid(prop)}
- )`
- ${inputStyles}
- `;
- export default Input;
|