diff --git a/src/components/control-label/__snapshots__/control-label.test.tsx.snap b/src/components/control-label/__snapshots__/control-label.test.tsx.snap index b7303935..51a34a4f 100644 --- a/src/components/control-label/__snapshots__/control-label.test.tsx.snap +++ b/src/components/control-label/__snapshots__/control-label.test.tsx.snap @@ -64,3 +64,32 @@ exports[`ControlLabel basic with optional renders 1`] = ` `; + +exports[`ControlLabel with ReactNode text renders 1`] = ` + +
+
+ + + This is an aside + +
+
+ +`; diff --git a/src/components/control-label/control-label.test.tsx b/src/components/control-label/control-label.test.tsx index e4640922..b041364e 100644 --- a/src/components/control-label/control-label.test.tsx +++ b/src/components/control-label/control-label.test.tsx @@ -3,7 +3,6 @@ import { render } from '@testing-library/react'; import ControlLabel from './control-label'; describe('ControlLabel', () => { - describe('basic', () => { const props = { text: 'basic label', @@ -11,7 +10,7 @@ describe('ControlLabel', () => { }; test('renders', () => { - const { baseElement } = render() + const { baseElement } = render(); expect(baseElement).toMatchSnapshot(); }); }); @@ -24,7 +23,7 @@ describe('ControlLabel', () => { }; test('renders', () => { - const { baseElement } = render() + const { baseElement } = render(); expect(baseElement).toMatchSnapshot(); }); }); @@ -39,7 +38,27 @@ describe('ControlLabel', () => { }; test('renders', () => { - const { baseElement } = render() + const { baseElement } = render(); + expect(baseElement).toMatchSnapshot(); + }); + }); + + describe('with ReactNode text', () => { + const props = { + text: ( + <> +
Something
+ Some text + + ), + id: 'label-id', + aside: 'This is an aside', + optional: true, + themeLabel: 'color-red' + }; + + test('renders', () => { + const { baseElement } = render(); expect(baseElement).toMatchSnapshot(); }); }); diff --git a/src/components/control-label/control-label.tsx b/src/components/control-label/control-label.tsx index 098c5326..4bd0c27e 100644 --- a/src/components/control-label/control-label.tsx +++ b/src/components/control-label/control-label.tsx @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; interface Props { id: string; - text: string; + text: string | ReactNode; aside?: ReactNode; optional?: boolean; themeLabel?: string; @@ -33,7 +33,7 @@ ControlLabel.propTypes = { /** Value should match the identifying id of the input element. */ id: PropTypes.string.isRequired, /** Label text */ - text: PropTypes.string.isRequired, + text: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), /** Additional content to provide aligned to the right of the label. */ aside: PropTypes.node, /** If true, label text adds (optional) alongside it. */ diff --git a/src/components/control-label/examples/control-label-example-with-icon.tsx b/src/components/control-label/examples/control-label-example-with-icon.tsx new file mode 100644 index 00000000..34da6a74 --- /dev/null +++ b/src/components/control-label/examples/control-label-example-with-icon.tsx @@ -0,0 +1,21 @@ +/* +With icon. +*/ +import React from 'react'; +import ControlLabel from '../control-label'; +import Icon from '../../icon/icon'; + +export default function Example() { + const getLabelWithIcon = ( + <> + + Your story + + ); + return ( + <> + + + + ); +} diff --git a/src/components/control-range/control-range.tsx b/src/components/control-range/control-range.tsx index afe30f6f..970d323f 100644 --- a/src/components/control-range/control-range.tsx +++ b/src/components/control-range/control-range.tsx @@ -1,4 +1,4 @@ -import React, {ReactElement, ReactNode} from 'react'; +import React, { ReactElement, ReactNode } from 'react'; import * as SliderPrimitive from '@radix-ui/react-slider'; import PropTypes from 'prop-types'; import omit from '../utils/omit'; @@ -24,11 +24,11 @@ const propNames = [ 'validator' ]; -interface Props extends Omit{ +interface Props extends Omit { id: string; onChange: (value: Array, id: string) => void; value?: Array; - label?: string; + label?: string | ReactNode; optional?: boolean; aside?: ReactNode; tooltip?: boolean; @@ -58,7 +58,6 @@ export default function ControlRange({ themeLabel, ...props }: Props): ReactElement { - const extraProps = omit(props, propNames); const rootProps = { @@ -76,7 +75,9 @@ export default function ControlRange({ } const renderThumb = (value: number, index: number) => { - return + return ( + + ); }; return ( @@ -97,7 +98,9 @@ export default function ControlRange({
- + {value.map(renderThumb)} @@ -114,7 +117,7 @@ ControlRange.propTypes = { /** Accepts an array of numbers, where each number matches a draggable thumb. */ value: PropTypes.array, /** Value passed to the label element. */ - label: PropTypes.string, + label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), /** If provided the text, "(optional)" is appended to the value of the label element. */ optional: PropTypes.bool, /** Additional content inserted alongside the label element. */ diff --git a/src/components/control-text/control-text.tsx b/src/components/control-text/control-text.tsx index 18c4ba72..11fa8e62 100644 --- a/src/components/control-text/control-text.tsx +++ b/src/components/control-text/control-text.tsx @@ -1,24 +1,32 @@ -import React, { ReactElement, ReactNode, useState, useRef, ChangeEvent, HTMLInputTypeAttribute, CSSProperties } from 'react'; +import React, { + ReactElement, + ReactNode, + useState, + useRef, + ChangeEvent, + HTMLInputTypeAttribute, + CSSProperties +} from 'react'; import PropTypes from 'prop-types'; import omit from '../utils/omit'; import ControlLabel from '../control-label'; import ControlWrapper from '../control-wrapper'; import Popover from '../popover'; import Icon from '../icon'; -import {InputProps, PopoverProps} from '../typings'; +import { InputProps, PopoverProps } from '../typings'; interface Props extends Omit { id: string; onChange: (value: string, id: string) => void; value?: string | number; type?: HTMLInputTypeAttribute; - label?: string; + label?: string | ReactNode; noAuto?: boolean; optional?: boolean; aside?: ReactNode; validationError?: ReactNode; errorStyle?: 'default' | 'inline'; - popoverProps?: PopoverProps; + popoverProps?: PopoverProps; themeControlInput?: string; themeControlWrapper?: string; themeLabel?: string; @@ -70,7 +78,7 @@ export default function ControlText({ }; const isActive = () => { - if (typeof window === 'undefined') return false + if (typeof window === 'undefined') return false; return ( window.document.activeElement === inputElement.current || @@ -101,22 +109,23 @@ export default function ControlText({ }; const inputProps: { - id: string, - name: string, - onChange: (e: ChangeEvent) => void, - value: string | number, - type: HTMLInputTypeAttribute, - className: string, - 'aria-required': boolean, - 'data-testid': string, - autoCapitalize?: string, - autoCorrect?: string, - spellCheck?: boolean, - style?: CSSProperties + id: string; + name: string; + onChange: (e: ChangeEvent) => void; + value: string | number; + type: HTMLInputTypeAttribute; + className: string; + 'aria-required': boolean; + 'data-testid': string; + autoCapitalize?: string; + autoCorrect?: string; + spellCheck?: boolean; + style?: CSSProperties; } = { id, name: id, - onChange: (e: ChangeEvent) => onChange(e.target.value, id), + onChange: (e: ChangeEvent) => + onChange(e.target.value, id), value, type, className: themeControlInput, @@ -166,7 +175,7 @@ export default function ControlText({ content={validationError} placement="top" aria-label="Validation error" - { ...props.popoverProps } + {...props.popoverProps} > @@ -223,7 +238,7 @@ ControlText.propTypes = { /** Type attribute to override the existing default of 'text' */ type: PropTypes.string, /** Label for the control. */ - label: PropTypes.string, + label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), /** Enable/Disable browser enabled autocorrect or spelling suggestions from the element. */ noAuto: PropTypes.bool, /** If provided, "(optional)" is appended to the value of the legend element. */ diff --git a/src/components/control-textarea/control-textarea.tsx b/src/components/control-textarea/control-textarea.tsx index 893e2994..fe294a1f 100644 --- a/src/components/control-textarea/control-textarea.tsx +++ b/src/components/control-textarea/control-textarea.tsx @@ -9,7 +9,7 @@ interface Props extends Omit { onChange: (value: string, id: string) => void; id?: string; value?: string; - label?: string; + label?: string | ReactNode; noAuto?: boolean; optional?: boolean; aside?: ReactNode; @@ -52,21 +52,22 @@ export default function ControlTextarea({ }: Props): ReactElement { const extraProps = omit(props, propNames); const textareaProps: { - id: string, - name: string, - onChange: (e: ChangeEvent) => void, - value: string, - className: string, - 'aria-required': boolean, - 'data-testid': string, - autoCapitalize?: string, - autoCorrect?: string, - spellCheck?: boolean, - 'aria-invalid'?: boolean + id: string; + name: string; + onChange: (e: ChangeEvent) => void; + value: string; + className: string; + 'aria-required': boolean; + 'data-testid': string; + autoCapitalize?: string; + autoCorrect?: string; + spellCheck?: boolean; + 'aria-invalid'?: boolean; } = { id, name: id, - onChange: (e: ChangeEvent) => onChange(e.target.value, id), + onChange: (e: ChangeEvent) => + onChange(e.target.value, id), value, className: themeControlTextarea, 'aria-required': optional ? false : true, @@ -114,7 +115,7 @@ ControlTextarea.propTypes = { */ onChange: PropTypes.func.isRequired, /** Label for the control. */ - label: PropTypes.string, + label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), /** If `true`, autocorrect and spelling suggestions will be disabled. */ noAuto: PropTypes.bool, /** If `true`, the text `(optional)` is appended to the label element. */ @@ -130,4 +131,3 @@ ControlTextarea.propTypes = { /** Classes to apply to the label element. */ themeLabel: PropTypes.string }; -