UNPKG

@zendeskgarden/container-field

Version:

Containers relating to field in the Garden Design System

104 lines (99 loc) 2.69 kB
/** * Copyright Zendesk, Inc. * * Use of this source code is governed under the Apache License, Version 2.0 * found at http://www.apache.org/licenses/LICENSE-2.0. */ import React, { useCallback, useMemo } from 'react'; import { useId } from '@zendeskgarden/container-utilities'; import PropTypes from 'prop-types'; const useField = ({ idPrefix, hasHint, hasMessage }) => { const prefix = useId(idPrefix); const inputId = `${prefix}--input`; const labelId = `${prefix}--label`; const hintId = `${prefix}--hint`; const messageId = `${prefix}--message`; const getLabelProps = useCallback(({ id = labelId, htmlFor = inputId, ...other } = {}) => ({ 'data-garden-container-id': 'containers.field.label', 'data-garden-container-version': '3.0.22', id, htmlFor, ...other }), [labelId, inputId]); const getHintProps = useCallback(({ id = hintId, ...other } = {}) => ({ 'data-garden-container-id': 'containers.field.hint', 'data-garden-container-version': '3.0.22', id, ...other }), [hintId]); const getInputProps = useCallback(({ id = inputId, 'aria-describedby': ariaDescribedBy, ...other } = {}) => { const getDescribedBy = () => { if (ariaDescribedBy) { return ariaDescribedBy; } const describedBy = []; if (hasHint) { describedBy.push(hintId); } if (hasMessage) { describedBy.push(messageId); } return describedBy.length > 0 ? describedBy.join(' ') : undefined; }; return { 'data-garden-container-id': 'containers.field.input', 'data-garden-container-version': '3.0.22', id, 'aria-labelledby': labelId, 'aria-describedby': getDescribedBy(), ...other }; }, [inputId, labelId, hintId, messageId, hasHint, hasMessage]); const getMessageProps = useCallback(({ id = messageId, role = 'alert', ...other } = {}) => ({ 'data-garden-container-id': 'containers.field.message', 'data-garden-container-version': '3.0.22', role: role === null ? undefined : role, id, ...other }), [messageId]); return useMemo(() => ({ getLabelProps, getHintProps, getInputProps, getMessageProps }), [getLabelProps, getHintProps, getInputProps, getMessageProps]); }; const FieldContainer = ({ children, render = children, ...options }) => { return React.createElement(React.Fragment, null, render(useField(options))); }; FieldContainer.propTypes = { children: PropTypes.func, render: PropTypes.func, idPrefix: PropTypes.string, hasHint: PropTypes.bool, hasMessage: PropTypes.bool }; export { FieldContainer, useField };