Repository: ant-design/ant-design-mobile
Pull request #5454 (2022-07-07 13:15:30)

refactor(NumberKeyboard): adjust className with prefix

codecov[bot]: # [Codecov](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design) Report
> Merging [#5454](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design) (7720c11) into [master](https://codecov.io/gh/ant-design/ant-design-mobile/commit/ea463ee9bb45b79f9767472a5cbdb24d45f5bdd8?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design) (ea463ee) will **increase** coverage by `0.41%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##           master    #5454      +/-   ##
==========================================
+ Coverage   85.89%   86.30%   +0.41%     
==========================================
  Files         290      290              
  Lines        6081     6081              
  Branches     1473     1473              
==========================================
+ Hits         5223     5248      +25     
+ Misses        794      770      -24     
+ Partials       64       63       -1     
```


| [Impacted Files](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design) | Coverage Δ | |
|---|---|---|
| [src/components/number-keyboard/number-keyboard.tsx](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design#diff-c3JjL2NvbXBvbmVudHMvbnVtYmVyLWtleWJvYXJkL251bWJlci1rZXlib2FyZC50c3g=) | `97.77% <100.00%> (+21.11%)` | :arrow_up: |
| [src/components/image-uploader/image-uploader.tsx](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design#diff-c3JjL2NvbXBvbmVudHMvaW1hZ2UtdXBsb2FkZXIvaW1hZ2UtdXBsb2FkZXIudHN4) | `86.53% <0.00%> (-6.74%)` | :arrow_down: |
| [src/utils/use-touch.ts](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design#diff-c3JjL3V0aWxzL3VzZS10b3VjaC50cw==) | `64.86% <0.00%> (+21.62%)` | :arrow_up: |
| [src/utils/shuffle.ts](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design#diff-c3JjL3V0aWxzL3NodWZmbGUudHM=) | `100.00% <0.00%> (+83.33%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design). Last update [ea463ee...7720c11](https://codecov.io/gh/ant-design/ant-design-mobile/pull/5454?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ant-design).

github-actions[bot]: PR preview has been successfully built and deployed to https://antd-mobile-preview-pr-5454.surge.sh

Patch:
diff --git a/src/components/number-keyboard/number-keyboard.less b/src/components/number-keyboard/number-keyboard.less
index 29091cfec..7cb791d94 100644
--- a/src/components/number-keyboard/number-keyboard.less
+++ b/src/components/number-keyboard/number-keyboard.less
@@ -5,7 +5,7 @@
     display: flex;
     flex-wrap: wrap;
     flex: 1;
-    &.confirmed-style .sign-key {
+    &&-confirmed-style .@{class-prefix-number-keyboard}-key-sign {
       background-color: var(--adm-color-white);
     }
   }
@@ -37,7 +37,7 @@
       padding: 0 12px;
       font-size: 16px;
     }
-    &.with-title {
+    &&-with-title {
       justify-content: space-between;
       .@{class-prefix-number-keyboard}-header-close-button {
         padding-right: 0;
@@ -93,28 +93,28 @@
       box-sizing: content-box;
     }
 
-    &.mid-key {
+    &&-mid {
       flex-basis: 66.67%;
     }
 
-    &.sign-key:active::before {
+    &&-sign:active::before {
       opacity: 0.1;
     }
 
-    &.extra-key {
+    &&-extra {
       border-left: solid 1px var(--adm-color-border);
       border-right: none;
     }
 
-    &.extra-key,
-    &.number-key {
+    &&-extra,
+    &&-number {
       background-color: var(--adm-color-background);
       &:active::before {
         opacity: 0.1;
       }
     }
 
-    &.ok-key {
+    &&-ok {
       background-color: var(--adm-color-primary);
       color: var(--adm-color-white);
       height: 144px;
@@ -122,8 +122,4 @@
       border: none;
     }
   }
-
-  &-bs-key {
-    height: 20px;
-  }
 }
diff --git a/src/components/number-keyboard/number-keyboard.tsx b/src/components/number-keyboard/number-keyboard.tsx
index dfe187db1..e76a6da7b 100644
--- a/src/components/number-keyboard/number-keyboard.tsx
+++ b/src/components/number-keyboard/number-keyboard.tsx
@@ -121,7 +121,7 @@ export const NumberKeyboard: React.FC<NumberKeyboardProps> = p => {
     return (
       <div
         className={classNames(`${classPrefix}-header`, {
-          'with-title': !!title,
+          [`${classPrefix}-header-with-title`]: !!title,
         })}
       >
         {title && <div className={`${classPrefix}-title`}>{title}</div>}
@@ -145,9 +145,9 @@ export const NumberKeyboard: React.FC<NumberKeyboardProps> = p => {
   const renderKey = (key: string, index: number) => {
     const isNumberKey = /^\d$/.test(key)
     const className = classNames(`${classPrefix}-key`, {
-      'number-key': isNumberKey,
-      'sign-key': !isNumberKey && key,
-      'mid-key': index === 9 && !!confirmText,
+      [`${classPrefix}-key-number`]: isNumberKey,
+      [`${classPrefix}-key-sign`]: !isNumberKey && key,
+      [`${classPrefix}-key-mid`]: index === 9 && !!confirmText,
     })
 
     const ariaProps = key
@@ -204,7 +204,7 @@ export const NumberKeyboard: React.FC<NumberKeyboardProps> = p => {
           <div className={`${classPrefix}-wrapper`}>
             <div
               className={classNames(`${classPrefix}-main`, {
-                'confirmed-style': !!confirmText,
+                [`${classPrefix}-main-confirmed-style`]: !!confirmText,
               })}
             >
               {keys.map(renderKey)}
@@ -212,7 +212,7 @@ export const NumberKeyboard: React.FC<NumberKeyboardProps> = p => {
             {!!confirmText && (
               <div className={`${classPrefix}-confirm`}>
                 <div
-                  className={`${classPrefix}-key extra-key bs-key`}
+                  className={`${classPrefix}-key ${classPrefix}-key-extra ${classPrefix}-key-bs`}
                   onTouchStart={() => {
                     onBackspacePressStart()
                   }}
@@ -226,7 +226,7 @@ export const NumberKeyboard: React.FC<NumberKeyboardProps> = p => {
                   <TextDeletionOutline />
                 </div>
                 <div
-                  className={`${classPrefix}-key extra-key ok-key`}
+                  className={`${classPrefix}-key ${classPrefix}-key-extra ${classPrefix}-key-ok`}
                   onTouchEnd={e => onKeyPress(e, 'OK')}
                   role='button'
                 >


Test patch:
diff --git a/src/components/number-keyboard/tests/number-keyboard.test.tsx b/src/components/number-keyboard/tests/number-keyboard.test.tsx
new file mode 100644
index 000000000..d07c0d844
--- /dev/null
+++ b/src/components/number-keyboard/tests/number-keyboard.test.tsx
@@ -0,0 +1,136 @@
+import React, { useState } from 'react'
+import { fireEvent, render, testA11y, screen, waitFor } from 'testing'
+import NumberKeyboard from '..'
+
+const classPrefix = 'adm-number-keyboard'
+
+function mockClick(el: HTMLElement) {
+  fireEvent.touchStart(el, { touches: [{}] })
+  fireEvent.touchEnd(el, { touches: [{}] })
+}
+
+describe('NumberKeyboard', () => {
+  test('a11y', async () => {
+    await testA11y(<NumberKeyboard visible />)
+  })
+
+  test('renders with title', () => {
+    render(<NumberKeyboard visible title='title' />)
+    const title = screen.getByText('title')
+    expect(title).toBeInTheDocument()
+    expect(title).toHaveClass(`${classPrefix}-title`)
+    expect(document.querySelector(`.${classPrefix}-header`)).toHaveClass(
+      `${classPrefix}-header-with-title`
+    )
+  })
+
+  test('onClose should be called by close button', () => {
+    const onClose = jest.fn()
+    render(<NumberKeyboard visible onClose={onClose} />)
+    fireEvent.click(screen.getByTitle('CLOSE'))
+    expect(onClose).toBeCalledTimes(1)
+  })
+
+  test('onInput should be work', () => {
+    const onInput = jest.fn()
+    render(<NumberKeyboard visible onInput={onInput} />)
+    const keys = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
+    keys.forEach(key => {
+      const el = screen.getByTitle(key)
+      mockClick(el)
+    })
+    expect(onInput).toBeCalledTimes(10)
+  })
+
+  test('renders with customKey', () => {
+    const onDelete = jest.fn()
+    const onInput = jest.fn()
+    render(
+      <NumberKeyboard
+        customKey='-'
+        visible
+        onInput={onInput}
+        onDelete={onDelete}
+      />
+    )
+
+    mockClick(screen.getByTitle('BACKSPACE'))
+    expect(onDelete).toBeCalled()
+
+    mockClick(screen.getByText('-'))
+    expect(onInput).toBeCalledWith('-')
+  })
+
+  test('renders with confirmText', async () => {
+    const onConfirm = jest.fn()
+    const onClose = jest.fn()
+    const onDelete = jest.fn()
+    render(
+      <NumberKeyboard
+        visible
+        confirmText='confirm'
+        onConfirm={onConfirm}
+        onClose={onClose}
+        onDelete={onDelete}
+      />
+    )
+    const confirm = screen.getByText('confirm')
+    const del = screen.getByTitle('BACKSPACE')
+    expect(confirm).toBeInTheDocument()
+    expect(confirm).toHaveClass(
+      `${classPrefix}-key-extra ${classPrefix}-key-ok`
+    )
+    expect(del).toHaveClass(`${classPrefix}-key-extra ${classPrefix}-key-bs`)
+
+    mockClick(confirm)
+    expect(onConfirm).toBeCalled()
+    expect(onClose).toBeCalled()
+    mockClick(del)
+    expect(onDelete).toBeCalled()
+  })
+
+  test('renders witout close button', () => {
+    render(<NumberKeyboard visible showCloseButton={false} />)
+    expect(
+      document.querySelector(`.${classPrefix}-header`)
+    ).not.toBeInTheDocument()
+  })
+
+  test('renders with random order', async () => {
+    const App = () => {
+      const [visible, setVisible] = useState(false)
+      return (
+        <>
+          <NumberKeyboard
+            visible={visible}
+            randomOrder
+            onClose={() => {
+              setVisible(false)
+            }}
+          />
+          <button onClick={() => setVisible(true)}>open</button>
+        </>
+      )
+    }
+    render(<App />)
+    fireEvent.click(screen.getByText('open'))
+    const popup = document.querySelector(`.${classPrefix}-popup`)
+    const main = document.querySelector(`.${classPrefix}-main`)
+    expect(main).not.toHaveTextContent('1234567890')
+    fireEvent.click(screen.getByTitle('CLOSE'))
+    await waitFor(() => expect(popup).not.toBeVisible())
+  })
+
+  test('onDelete will be called when backspace press long time', () => {
+    jest.useFakeTimers()
+    const onDelete = jest.fn()
+    render(<NumberKeyboard visible onDelete={onDelete} />)
+    const del = screen.getByTitle('BACKSPACE')
+    fireEvent.touchStart(del, { touches: [{}] })
+    jest.runOnlyPendingTimers()
+    expect(onDelete).toBeCalledTimes(1)
+    jest.runOnlyPendingTimers()
+    expect(onDelete).toBeCalledTimes(2)
+    jest.useRealTimers()
+  })
+})
diff --git a/src/components/number-keyboard/tests/numberic-keyboard.test.tsx b/src/components/number-keyboard/tests/numberic-keyboard.test.tsx
deleted file mode 100644
index 1ecf36bbf..000000000
--- a/src/components/number-keyboard/tests/numberic-keyboard.test.tsx
+++ /dev/null
@@ -1,76 +0,0 @@
-import * as React from 'react'
-import { fireEvent, render, sleep, testA11y, waitFor } from 'testing'
-import NumberKeyboard from '..'
-
-const classPrefix = 'adm-number-keyboard'
-
-describe('NumberKeyboard', () => {
-  test('a11y', async () => {
-    await testA11y(<NumberKeyboard visible />)
-  })
-
-  test('renders with title & close button', async () => {
-    let inputValue = ''
-    const onClose = jest.fn()
-    const onInput = jest.fn(value => {
-      inputValue = value
-    })
-
-    const { getByTitle, getByText } = render(
-      <NumberKeyboard
-        visible
-        showCloseButton
-        onClose={onClose}
-        onInput={onInput}
-        title='title'
-      />
-    )
-
-    expect(getByText('title')).toHaveClass(`${classPrefix}-title`)
-
-    // 点击关闭箭头
-    fireEvent.click(getByTitle('CLOSE'))
-    await waitFor(() => {
-      expect(onClose).toBeCalledTimes(1)
-    })
-
-    // touch every key button
-    document.querySelectorAll(`.${classPrefix}-key`).forEach(element => {
-      fireEvent.touchEnd(element)
-    })
-
-    await sleep(100)
-    expect(onInput).toBeCalledTimes(10)
-    expect(inputValue).toEqual('0')
-  })
-
-  test('renders with customKey', async () => {
-    let inputValue = ''
-    const onDelete = jest.fn()
-    const onInput = jest.fn(value => {
-      inputValue = value
-    })
-
-    const { getByText, getByTitle } = render(
-      <NumberKeyboard
-        customKey='-'
-        visible
-        onInput={onInput}
-        onDelete={onDelete}
-      />
-    )
-
-    // 点击删除
-    fireEvent.touchEnd(getByTitle('BACKSPACE'))
-    await waitFor(() => {
-      expect(onDelete).toBeCalledTimes(1)
-    })
-
-    // 点击自定义按钮
-    fireEvent.touchEnd(getByText('-'))
-    await waitFor(() => {
-      expect(onInput).toBeCalledTimes(1)
-      expect(inputValue).toEqual('-')
-    })
-  })
-})