diff --git a/README.md b/README.md index 50376ab..28a0dbc 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ render( | options | Array | [] | options for choices | | value | string \| number | | value of segmented | | defaultValue | string \| number | | defaultValue of segmented | +| value | string \| number | | currently selected value of segmented | | onChange | (e: any) => void | | defaultValue of segmented | | disabled | boolean | false | disabled status of segmented | diff --git a/src/index.tsx b/src/index.tsx index ed5dafb..2b362af 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -88,6 +88,11 @@ const InternalSegmentedOption: React.FC<{ ); }; +interface ThumbMoveStatus { + from: React.CSSProperties | null; + to: React.CSSProperties | null; +} + const Segmented = React.forwardRef( (props, ref) => { const { @@ -95,6 +100,8 @@ const Segmented = React.forwardRef( direction, options, disabled, + defaultValue, + value, onChange, className = '', motionName = 'thumb-motion', @@ -104,9 +111,7 @@ const Segmented = React.forwardRef( const containerRef = React.useRef(null); const mergedRef = composeRef(containerRef, ref); - const thumbMoveStyles = React.useRef< - Record<'from' | 'to', React.CSSProperties | null> - >({ + const thumbMoveStatus = React.useRef({ from: null, to: null, }); @@ -115,9 +120,10 @@ const Segmented = React.forwardRef( return normalizeOptions(options); }, [options]); - const [selected, setSelected] = useMergedState( - props.defaultValue || segmentedOptions[0]?.value, - ); + const [selected, setSelected] = useMergedState(segmentedOptions[0]?.value, { + value, + defaultValue, + }); const [visualSelected, setVisualSelected] = React.useState< SegmentedRawOption | undefined @@ -125,18 +131,20 @@ const Segmented = React.forwardRef( const [thumbShow, setThumbShow] = React.useState(false); - const calcThumbMoveStyle = (event: React.ChangeEvent) => { + const calcThumbMoveStatus = ( + event: React.ChangeEvent, + ) => { const toElement = event.target.closest(`.${prefixCls}-item`); const fromElement = containerRef.current?.querySelector( `.${prefixCls}-item-selected`, ); - if (fromElement && toElement && thumbMoveStyles.current) { - thumbMoveStyles.current.from = calcThumbStyle( + if (fromElement && toElement && thumbMoveStatus.current) { + thumbMoveStatus.current.from = calcThumbStyle( fromElement as HTMLElement, ); - thumbMoveStyles.current.to = calcThumbStyle(toElement as HTMLElement); + thumbMoveStatus.current.to = calcThumbStyle(toElement as HTMLElement); setThumbShow(true); } @@ -144,22 +152,20 @@ const Segmented = React.forwardRef( const handleChange = ( event: React.ChangeEvent, - value: SegmentedRawOption, + val: SegmentedRawOption, ) => { if (disabled) { return; } - if (value !== selected) { - calcThumbMoveStyle(event); - } + calcThumbMoveStatus(event); - setSelected(value); + setSelected(val); if (onChange) { const mutatedTarget = Object.create(event.target, { value: { - value, + value: val, }, }); const mutatedEvent = Object.create(event, { @@ -173,7 +179,7 @@ const Segmented = React.forwardRef( // --- motion event handlers for thumb move const handleThumbEnterStart = () => { - const fromStyle = thumbMoveStyles.current.from; + const fromStyle = thumbMoveStatus.current.from; if (fromStyle) { setVisualSelected(undefined); return fromStyle; @@ -181,7 +187,7 @@ const Segmented = React.forwardRef( }; const handleThumbEnterActive = () => { - const toStyle = thumbMoveStyles.current.to; + const toStyle = thumbMoveStatus.current.to; if (toStyle) { return toStyle; } @@ -191,8 +197,8 @@ const Segmented = React.forwardRef( setThumbShow(false); setVisualSelected(selected); - if (thumbMoveStyles.current) { - thumbMoveStyles.current = { + if (thumbMoveStatus.current) { + thumbMoveStatus.current = { from: null, to: null, }; @@ -251,6 +257,8 @@ const Segmented = React.forwardRef( Segmented.displayName = 'Segmented'; -Segmented.defaultProps = {}; +Segmented.defaultProps = { + options: [], +}; export default Segmented; diff --git a/tests/__snapshots__/index.spec.tsx.snap b/tests/__snapshots__/index.spec.tsx.snap index 7043665..d700819 100644 --- a/tests/__snapshots__/index.spec.tsx.snap +++ b/tests/__snapshots__/index.spec.tsx.snap @@ -1,6 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`rc-segmented render 1`] = ` +exports[`rc-segmented render empty segmented 1`] = ` +
+`; + +exports[`rc-segmented render label with ReactNode 1`] = `
@@ -53,12 +59,6 @@ exports[`rc-segmented render 1`] = `
`; -exports[`rc-segmented render empty segmented 1`] = ` -
-`; - exports[`rc-segmented render segmented ok 1`] = `
{ ).toEqual([true, false, false]); }); - it('render', () => { + it('render label with ReactNode', () => { const wrapper = mount(