UNPKG

@equinor/eds-core-react

Version:

The React implementation of the Equinor Design System

136 lines (132 loc) 4.17 kB
import styled from 'styled-components'; import { tokens } from '@equinor/eds-tokens'; import { forwardRef, useEffect } from 'react'; import { Popover } from '../../Popover/index.js'; import { filterDOMProps } from '@react-aria/utils'; import { jsxs, Fragment, jsx } from 'react/jsx-runtime'; import { InputWrapper } from '../../InputWrapper/InputWrapper.js'; import { useEds } from '../../EdsProvider/eds.context.js'; const getVariant = variant => { if (variant === 'error') { return tokens.colors.interactive.danger__resting.rgba; } if (variant === 'success') { return tokens.colors.interactive.success__resting.rgba; } if (variant === 'warning') { return tokens.colors.interactive.warning__resting.rgba; } return tokens.colors.interactive.primary__resting.rgba; }; const getVariantText = variant => { if (variant === 'error') { return tokens.colors.interactive.danger__text.rgba; } if (variant === 'success') { return tokens.colors.interactive.success__text.rgba; } if (variant === 'warning') { return tokens.colors.interactive.warning__text.rgba; } return tokens.typography.input.text.color; }; const StyledInputFieldWrapper = styled.div.withConfig({ displayName: "FieldWrapper__StyledInputFieldWrapper", componentId: "sc-1h0kqs9-0" })(["display:flex;align-items:center;background-color:", ";height:", ";padding:0 8px;", " ", " color:", ";cursor:default;"], tokens.colors.ui.background__light.rgba, ({ $density }) => $density === 'compact' ? '24px' : '36px', ({ $variant, $disabled, $readonly }) => { if (!$variant && !$readonly) { return `&:focus-within:not(.invalid) { outline: 2px solid ${tokens.colors.interactive.primary__resting.rgba}; } ${!$disabled && `&:not(:focus-within) { box-shadow: inset 0 -1px 0 0 ${tokens.colors.text.static_icons__tertiary.rgba};`} } `; } return `outline: 2px solid ${getVariant($variant)};`; }, ({ $readonly }) => { return $readonly && `background-color: ${tokens.colors.ui.background__default.rgba}; outline: none;`; }, p => getVariantText(p.$variant)); /** * Applies styles around the date input fields (density, color etc.) */ const InputFieldWrapper = /*#__PURE__*/forwardRef(({ children, color, disabled, readonly, ...props }, ref) => { const { density } = useEds(); // As the props returned are designed for react-aria, some of them are not valid DOM props (i.e. onPress). // The filterDOMProps-method strips out the invalid props, but it also removes event listeners due to casing const filteredProps = filterDOMProps(props); // filterDOMProps also strips event handlers const eventHandlers = Object.keys(props).filter(k => k.startsWith('on')).reduce((a, b) => ({ ...a, [b]: props[b] }), {}); return /*#__PURE__*/jsx(StyledInputFieldWrapper, { ref: ref, $density: density, $variant: color, $disabled: disabled ?? false, $readonly: readonly ?? false, ...filteredProps, ...eventHandlers, children: children }); }); const FieldWrapper = /*#__PURE__*/forwardRef(({ children, pickerRef, calendar, isOpen, setIsOpen, label, readonly, ...props }, ref) => { useEffect(() => { if (isOpen === false) { // Focus the first segment in the input field const segment = ref.current?.querySelector('.segment'); segment?.focus(); } }, [ref, isOpen, pickerRef]); return /*#__PURE__*/jsxs(Fragment, { children: [/*#__PURE__*/jsx(InputWrapper, { readOnly: readonly, label: label, onKeyDownCapture: event => { const isIconTarget = event.target instanceof SVGSVGElement; if (!isIconTarget && (event.code === 'Space' || event.code === 'Enter')) { setIsOpen(true); } }, ...props, children: children }), /*#__PURE__*/jsx(Popover, { open: isOpen ?? false, onClose: () => setIsOpen(false), anchorEl: ref.current, placement: 'bottom-start', children: calendar })] }); }); InputFieldWrapper.displayName = 'InputFieldWrapper'; FieldWrapper.displayName = 'FieldWrapper'; export { FieldWrapper, InputFieldWrapper };