From 6001a884e23017746d8a07f1648188cbfca6d606 Mon Sep 17 00:00:00 2001 From: oasis Date: Thu, 21 Nov 2024 19:34:06 +0800 Subject: [PATCH 1/5] feat(radio): v14 --- src/packages/radio/icon.tsx | 24 ++++++++++++ src/packages/radio/radio.scss | 61 +++++++++++++++++++++++++++++++ src/packages/radio/radio.taro.tsx | 35 ++++++++++-------- src/packages/radio/radio.tsx | 31 ++++++++++------ 4 files changed, 123 insertions(+), 28 deletions(-) create mode 100644 src/packages/radio/icon.tsx diff --git a/src/packages/radio/icon.tsx b/src/packages/radio/icon.tsx new file mode 100644 index 0000000000..8844d0618d --- /dev/null +++ b/src/packages/radio/icon.tsx @@ -0,0 +1,24 @@ +import { createElement } from 'react' +import { mergeProps } from '@/utils/merge-props' + +interface IconProps { + tag: any + classPrefix: string + name: 'normal' | 'disabled' | 'checked' | 'checked-disabled' +} + +const Icon = (props: Partial) => { + const { tag, classPrefix, name } = mergeProps( + { + tag: 'div', + classPrefix: 'nut-radio-self', + name: 'normal', + }, + props + ) + return createElement<{ className: string }>(tag, { + className: `${classPrefix} ${classPrefix}-${name}`, + }) +} + +export default Icon diff --git a/src/packages/radio/radio.scss b/src/packages/radio/radio.scss index ebd765a7dd..62cdf87e2f 100644 --- a/src/packages/radio/radio.scss +++ b/src/packages/radio/radio.scss @@ -1,5 +1,66 @@ @import '../radiogroup/radiogroup.scss'; +.nut-radio-self { + width: 16px; + height: 16px; + position: relative; + box-sizing: border-box; + border-radius: 50%; + + &-normal { + border: 0.5px solid $color-text-disabled; + background: $color-background-overlay; + } + + &-checked, + &-disabled, + &-checked-disabled { + &:after { + display: block; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + content: ' '; + background: $color-primary-text; + } + } + + &-checked { + background: linear-gradient( + 90deg, + $color-primary-stop-1 0%, + $color-primary-stop-2 100% + ); + box-shadow: 0px 2px 4px 0px rgba(255, 15, 35, 0.2); + + &:after { + width: 8px; + height: 8px; + border-radius: 50%; + } + } + + &-disabled { + background: $color-text-disabled; + + &:after { + width: 8px; + height: 1.5px; + } + } + + &-checked-disabled { + background: $color-primary-disabled-special; + + &:after { + width: 8px; + height: 8px; + border-radius: 50%; + } + } +} + .nut-radio { display: flex; align-items: center; diff --git a/src/packages/radio/radio.taro.tsx b/src/packages/radio/radio.taro.tsx index 1b4b46eb5e..839033643c 100644 --- a/src/packages/radio/radio.taro.tsx +++ b/src/packages/radio/radio.taro.tsx @@ -1,15 +1,11 @@ import React, { FC, useContext } from 'react' -import { - CheckChecked, - CheckDisabled, - CheckNormal, -} from '@nutui/icons-react-taro' import classNames, { Mapping } from 'classnames' import { ITouchEvent, View } from '@tarojs/components' import RadioContext from '../radiogroup/context' import { BasicComponent, ComponentDefaults } from '@/utils/typings' import { usePropsValue } from '@/utils/use-props-value' import { RadioPosition, RadioShape } from '@/packages/radio/types' +import Icon from '@/packages/radio/icon' export interface RadioProps extends BasicComponent { disabled: boolean @@ -88,18 +84,25 @@ export const Radio: FC< } const renderIcon = () => { const { icon, activeIcon } = props + + function renderIconByDisabledProperty() { + return disabled ? ( + + ) : ( + + ) + } + if (disabled && !checkedStatement) { - return + return } if (checkedStatement) { - return React.isValidElement(activeIcon) ? ( - React.cloneElement(activeIcon, { - ...activeIcon.props, - className: classNames(color()), - }) - ) : ( - - ) + return React.isValidElement(activeIcon) + ? React.cloneElement(activeIcon, { + ...activeIcon.props, + className: classNames(color()), + }) + : renderIconByDisabledProperty() } return React.isValidElement(icon) ? ( React.cloneElement(icon, { @@ -107,7 +110,7 @@ export const Radio: FC< className: classNames(color()), }) ) : ( - + ) } const renderLabel = () => { @@ -117,7 +120,7 @@ export const Radio: FC< return ( <> {renderIcon()} - {children} + {children ? {children} : null} ) } diff --git a/src/packages/radio/radio.tsx b/src/packages/radio/radio.tsx index 5eeab9ba28..0c9c4f4f27 100644 --- a/src/packages/radio/radio.tsx +++ b/src/packages/radio/radio.tsx @@ -1,10 +1,10 @@ import React, { FunctionComponent, MouseEventHandler, useContext } from 'react' -import { CheckChecked, CheckNormal, CheckDisabled } from '@nutui/icons-react' import classNames from 'classnames' import RadioContext from '../radiogroup/context' import { BasicComponent, ComponentDefaults } from '@/utils/typings' import { usePropsValue } from '@/utils/use-props-value' import { RadioPosition, RadioShape } from '@/packages/radio/types' +import Icon from '@/packages/radio/icon' export interface RadioProps extends BasicComponent { disabled: boolean @@ -83,18 +83,25 @@ export const Radio: FunctionComponent< } const renderIcon = () => { const { icon, activeIcon } = props + + function renderIconByDisabledProperty() { + return disabled ? ( + + ) : ( + + ) + } + if (disabled && !checkedStatement) { - return + return } if (checkedStatement) { - return React.isValidElement(activeIcon) ? ( - React.cloneElement(activeIcon, { - ...activeIcon.props, - className: classNames(color()), - }) - ) : ( - - ) + return React.isValidElement(activeIcon) + ? React.cloneElement(activeIcon, { + ...activeIcon.props, + className: classNames(color()), + }) + : renderIconByDisabledProperty() } return React.isValidElement(icon) ? ( React.cloneElement(icon, { @@ -102,7 +109,7 @@ export const Radio: FunctionComponent< className: classNames(color()), }) ) : ( - + ) } const renderLabel = () => { @@ -112,7 +119,7 @@ export const Radio: FunctionComponent< return ( <> {renderIcon()} -
{children}
+ {children ?
{children}
: null} ) } From c08869acc4c3edc5be151d98ad5f3a667578046a Mon Sep 17 00:00:00 2001 From: oasis Date: Thu, 21 Nov 2024 19:36:06 +0800 Subject: [PATCH 2/5] =?UTF-8?q?feat(radio):=20=E6=97=A0=E8=87=AA=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E5=B0=BA=E5=AF=B8=E7=9A=84=E8=A7=86=E8=A7=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/packages/radio/demo.taro.tsx | 8 -------- src/packages/radio/demo.tsx | 8 -------- src/packages/radio/demos/h5/demo7.tsx | 16 ---------------- src/packages/radio/demos/taro/demo7.tsx | 16 ---------------- 4 files changed, 48 deletions(-) delete mode 100644 src/packages/radio/demos/h5/demo7.tsx delete mode 100644 src/packages/radio/demos/taro/demo7.tsx diff --git a/src/packages/radio/demo.taro.tsx b/src/packages/radio/demo.taro.tsx index a9f5baec2f..59556e4c4b 100644 --- a/src/packages/radio/demo.taro.tsx +++ b/src/packages/radio/demo.taro.tsx @@ -10,7 +10,6 @@ import Demo3 from './demos/taro/demo3' import Demo4 from './demos/taro/demo4' import Demo5 from './demos/taro/demo5' import Demo6 from './demos/taro/demo6' -import Demo7 from './demos/taro/demo7' import Demo8 from './demos/taro/demo8' import Demo9 from './demos/taro/demo9' import Demo10 from './demos/taro/demo10' @@ -23,7 +22,6 @@ const RadioDemo = () => { '74fc5d8a': '基础用法', bb7486f4: '选项', c1bae1ec: '水平使用', - '8a2e2847': '自定义尺寸', '70ffa5d8': '自定义图标', '70ffa5d9': '自定义图标,通过Group实现列表形式', '0f261484': '触发事件', @@ -37,7 +35,6 @@ const RadioDemo = () => { '74fc5d8a': '基礎用法', bb7486f4: '選項', c1bae1ec: '水準使用', - '8a2e2847': '自定義尺寸', '70ffa5d8': '自定義圖標', '70ffa5d9': '自定義圖標,通過Group實現列表形式', '0f261484': '觸發事件', @@ -51,7 +48,6 @@ const RadioDemo = () => { '74fc5d8a': 'Basic Usage', bb7486f4: 'Options', c1bae1ec: 'Horizontal use', - '8a2e2847': 'Custom size', '70ffa5d8': 'Custom Icon', '70ffa5d9': 'Custom Icon, render list in Group mode', '0f261484': 'Trigger Event', @@ -87,10 +83,6 @@ const RadioDemo = () => { {translated.c1bae1ec} - {translated['8a2e2847']} - - - {translated['70ffa5d8']} diff --git a/src/packages/radio/demo.tsx b/src/packages/radio/demo.tsx index 868a64f3c7..2bcdf67d8e 100644 --- a/src/packages/radio/demo.tsx +++ b/src/packages/radio/demo.tsx @@ -7,7 +7,6 @@ import Demo3 from './demos/h5/demo3' import Demo4 from './demos/h5/demo4' import Demo5 from './demos/h5/demo5' import Demo6 from './demos/h5/demo6' -import Demo7 from './demos/h5/demo7' import Demo8 from './demos/h5/demo8' import Demo9 from './demos/h5/demo9' import Demo10 from './demos/h5/demo10' @@ -20,7 +19,6 @@ const RadioDemo = () => { '74fc5d8a': '基础用法', bb7486f4: '选项', c1bae1ec: '水平使用', - '8a2e2847': '自定义尺寸', '70ffa5d8': '自定义图标', '70ffa5d9': '自定义图标,通过Group实现列表形式', '0f261484': '触发事件', @@ -34,7 +32,6 @@ const RadioDemo = () => { '74fc5d8a': '基礎用法', bb7486f4: '選項', c1bae1ec: '水準使用', - '8a2e2847': '自定義尺寸', '70ffa5d8': '自定義圖標', '70ffa5d9': '自定義圖標,通過Group實現列表形式', '0f261484': '觸發事件', @@ -48,7 +45,6 @@ const RadioDemo = () => { '74fc5d8a': 'Basic Usage', bb7486f4: 'Options', c1bae1ec: 'Horizontal use', - '8a2e2847': 'Custom size', '70ffa5d8': 'Custom Icon', '70ffa5d9': 'Custom Icon, render list in Group mode', '0f261484': 'Trigger Event', @@ -83,10 +79,6 @@ const RadioDemo = () => {

{translated.c1bae1ec}

-

{translated['8a2e2847']}

- - -

{translated['70ffa5d8']}

diff --git a/src/packages/radio/demos/h5/demo7.tsx b/src/packages/radio/demos/h5/demo7.tsx deleted file mode 100644 index a8c58125d7..0000000000 --- a/src/packages/radio/demos/h5/demo7.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { Radio } from '@nutui/nutui-react' - -const Demo7 = () => { - return ( - - 自定义尺寸 - - ) -} -export default Demo7 diff --git a/src/packages/radio/demos/taro/demo7.tsx b/src/packages/radio/demos/taro/demo7.tsx deleted file mode 100644 index 64a9bbbf85..0000000000 --- a/src/packages/radio/demos/taro/demo7.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { Radio } from '@nutui/nutui-react-taro' - -const Demo7 = () => { - return ( - - 自定义尺寸 - - ) -} -export default Demo7 From 2e3a0798d0bd01d2ed66822303ff18bc39709ac6 Mon Sep 17 00:00:00 2001 From: oasis Date: Wed, 27 Nov 2024 18:50:03 +0800 Subject: [PATCH 3/5] feat(radio): v14 --- scripts/build-taro.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/build-taro.mjs b/scripts/build-taro.mjs index 0d7de9d4b4..6a590bea97 100644 --- a/scripts/build-taro.mjs +++ b/scripts/build-taro.mjs @@ -68,6 +68,7 @@ async function buildES(p) { [ 'src/packages/**/*.taro.{ts,tsx}', 'src/packages/**/types.ts', + 'src/packages/**/icon.tsx', 'src/packages/**/context.ts', 'src/packages/**/utils.ts', 'src/utils/**/*.{ts,tsx}', From b93ff795164419455f9bb6893e409da69b34bd4e Mon Sep 17 00:00:00 2001 From: oasis Date: Wed, 27 Nov 2024 18:55:41 +0800 Subject: [PATCH 4/5] feat(radio): update test --- src/packages/radio/__test__/radio.spec.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/packages/radio/__test__/radio.spec.tsx b/src/packages/radio/__test__/radio.spec.tsx index 05ed9a8076..a7f5d71f59 100644 --- a/src/packages/radio/__test__/radio.spec.tsx +++ b/src/packages/radio/__test__/radio.spec.tsx @@ -16,16 +16,12 @@ describe('radio', () => { test('radio disable', () => { const { container } = render(Test Case) - expect(container.querySelector('.nut-icon')).toHaveClass( - 'nut-radio-icon-disabled' - ) + expect(container.querySelector('.nut-radio-self-disabled')).toBeTruthy() }) test('radio checked', () => { const { container } = render(Test Case) - expect(container.querySelector('.nut-icon')).toHaveClass( - 'nut-icon-CheckChecked' - ) + expect(container.querySelector('.nut-radio-self-checked')).toBeTruthy() }) test('radio custom icon', () => { From 75fdcc7d99eb5470ff5e90081225d4231baf331f Mon Sep 17 00:00:00 2001 From: oasis Date: Wed, 27 Nov 2024 19:01:08 +0800 Subject: [PATCH 5/5] feat(radio): update test --- src/packages/radio/__test__/radio.spec.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/packages/radio/__test__/radio.spec.tsx b/src/packages/radio/__test__/radio.spec.tsx index a7f5d71f59..c99aef1654 100644 --- a/src/packages/radio/__test__/radio.spec.tsx +++ b/src/packages/radio/__test__/radio.spec.tsx @@ -1,7 +1,7 @@ import * as React from 'react' -import { render, fireEvent, screen } from '@testing-library/react' -import '@testing-library/jest-dom' import { useState } from 'react' +import { fireEvent, render, screen } from '@testing-library/react' +import '@testing-library/jest-dom' import { Checklist } from '@nutui/icons-react' import Radio from '@/packages/radio' import RadioGroup from '@/packages/radiogroup' @@ -24,6 +24,17 @@ describe('radio', () => { expect(container.querySelector('.nut-radio-self-checked')).toBeTruthy() }) + test('radio checked-disabled', () => { + const { container } = render( + + Test Case + + ) + expect( + container.querySelector('.nut-radio-self-checked-disabled') + ).toBeTruthy() + }) + test('radio custom icon', () => { const { container } = render( } activeIcon={}>