antd-solid 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/index.css +69 -0
  2. package/dist/index.esm.js +2369 -0
  3. package/dist/index.umd.js +1 -0
  4. package/package.json +32 -14
  5. package/src/index.ts +12 -5
  6. package/.eslintrc.cjs +0 -36
  7. package/.prettierrc +0 -11
  8. package/.vscode/settings.json +0 -13
  9. package/docs/.vitepress/components/Code.vue +0 -59
  10. package/docs/.vitepress/config.ts +0 -49
  11. package/docs/.vitepress/theme/index.css +0 -15
  12. package/docs/.vitepress/theme/index.ts +0 -13
  13. package/docs/components/Button.tsx +0 -20
  14. package/docs/components/Table.tsx +0 -34
  15. package/docs/components/button.md +0 -23
  16. package/docs/components/table.md +0 -23
  17. package/docs/index.md +0 -28
  18. package/rollup.config.js +0 -25
  19. package/src/Button.css +0 -14
  20. package/src/Button.tsx +0 -86
  21. package/src/ColorPicker.tsx +0 -66
  22. package/src/DatePicker.tsx +0 -12
  23. package/src/Form.tsx +0 -98
  24. package/src/Image.tsx +0 -29
  25. package/src/Input.tsx +0 -110
  26. package/src/InputNumber.test.tsx +0 -46
  27. package/src/InputNumber.tsx +0 -119
  28. package/src/Modal.tsx +0 -168
  29. package/src/Popconfirm.tsx +0 -73
  30. package/src/Popover.tsx +0 -30
  31. package/src/Progress.tsx +0 -4
  32. package/src/Radio.tsx +0 -132
  33. package/src/Result.tsx +0 -38
  34. package/src/Select.tsx +0 -6
  35. package/src/Skeleton.tsx +0 -14
  36. package/src/Spin.tsx +0 -23
  37. package/src/Switch.tsx +0 -34
  38. package/src/Table.tsx +0 -46
  39. package/src/Tabs.tsx +0 -88
  40. package/src/Timeline.tsx +0 -33
  41. package/src/Tooltip.tsx +0 -209
  42. package/src/Tree.tsx +0 -246
  43. package/src/Upload.tsx +0 -10
  44. package/src/hooks/createControllableValue.ts +0 -65
  45. package/src/hooks/createUpdateEffect.ts +0 -16
  46. package/src/hooks/index.ts +0 -2
  47. package/src/hooks/useClickAway.ts +0 -18
  48. package/src/hooks/useSize.ts +0 -26
  49. package/src/index.css +0 -21
  50. package/src/utils/ReactToSolid.tsx +0 -38
  51. package/src/utils/SolidToReact.tsx +0 -27
  52. package/src/utils/array.ts +0 -21
  53. package/src/utils/component.tsx +0 -85
  54. package/src/utils/solid.ts +0 -48
  55. package/tsconfig.json +0 -23
  56. package/unocss.config.ts +0 -92
package/src/Button.css DELETED
@@ -1,14 +0,0 @@
1
- @keyframes button-border {
2
- from {
3
- opacity: 1;
4
- }
5
-
6
- 50% {
7
- opacity: 0;
8
- inset: -4px;
9
- }
10
-
11
- to {
12
- opacity: 0;
13
- }
14
- }
package/src/Button.tsx DELETED
@@ -1,86 +0,0 @@
1
- import {
2
- type Component,
3
- mergeProps,
4
- type ParentProps,
5
- type JSX,
6
- Show,
7
- createSignal,
8
- createMemo,
9
- } from 'solid-js'
10
- import cs from 'classnames'
11
- import './Button.css'
12
-
13
- interface ButtonProps extends ParentProps, JSX.CustomAttributes<HTMLButtonElement> {
14
- type?: 'default' | 'primary' | 'text' | 'link'
15
- onClick?: ((e: MouseEvent) => void) | ((e: MouseEvent) => Promise<unknown>)
16
- /**
17
- * 默认: middle
18
- * plain: 没有多余的 padding 和高度等
19
- */
20
- size?: 'large' | 'middle' | 'small' | 'plain'
21
- class?: string
22
- style?: JSX.CSSProperties
23
- loading?: boolean
24
- }
25
-
26
- const sizeClassMap = {
27
- large: 'ant-px-15px ant-py-6px ant-h-40px ant-rounded-8px',
28
- middle: 'ant-px-15px ant-py-4px ant-h-32px ant-rounded-6px',
29
- small: 'ant-px-7px ant-h-24px ant-rounded-4px',
30
- plain: 'ant-p-0',
31
- } as const
32
-
33
- const typeClassMap = {
34
- default:
35
- 'ant-[border:1px_solid_rgb(217,217,217)] ant-bg-white ant-text-[var(--dark-color)] hover:ant-[border-color:var(--light-primary-color)] hover:ant-text-[var(--light-primary-color)]',
36
- primary:
37
- 'ant-border-none ant-bg-[var(--primary-color)] hover:ant-bg-[var(--light-primary-color)] ant-text-white',
38
- text: 'ant-border-none ant-bg-transparent ant-text-[var(--dark-color)] hover:ant-bg-[rgba(0,0,0,0.06)] active:ant-bg-[rgba(0,0,0,.15)]',
39
- link: 'ant-border-none ant-bg-transparent ant-text-[var(--primary-color)] hover:ant-text-[var(--light-primary-color)] active:ant-text-[var(--dark-primary-color)]',
40
- } as const
41
-
42
- const Button: Component<ButtonProps> = props => {
43
- const mergedProps = mergeProps({ type: 'default', size: 'middle' } as ButtonProps, props)
44
- const [innerLoading, setLoading] = createSignal(false)
45
- const loading = createMemo(() => props.loading ?? innerLoading())
46
-
47
- return (
48
- <button
49
- ref={mergedProps.ref}
50
- class={cs(
51
- 'ant-relative ant-cursor-pointer',
52
- mergedProps.class,
53
- sizeClassMap[mergedProps.size!],
54
- typeClassMap[mergedProps.type!],
55
- loading() && 'ant-opacity-65',
56
- )}
57
- style={mergedProps.style}
58
- onClick={e => {
59
- const res = mergedProps.onClick?.(e)
60
- if (res instanceof Promise) {
61
- setLoading(true)
62
- res.finally(() => setLoading(false))
63
- }
64
-
65
- if (mergedProps.type === 'default' || mergedProps.type === 'primary') {
66
- const div = document.createElement('div')
67
- div.className =
68
- 'ant-absolute ant-inset-0 ant-rounded-inherit ant-[border:1px_solid_var(--light-primary-color)] ant-[animation:button-border_linear_1s]'
69
- const onAnimationEnd = () => {
70
- div.remove()
71
- div.removeEventListener('animationend', onAnimationEnd)
72
- }
73
- div.addEventListener('animationend', onAnimationEnd)
74
- e.currentTarget.insertBefore(div, e.currentTarget.childNodes[0])
75
- }
76
- }}
77
- >
78
- <Show when={loading()}>
79
- <span class="i-ant-design:loading ant-[vertical-align:-0.125em] keyframes-spin ant-[animation:spin_1s_linear_infinite] ant-mr-8px" />
80
- </Show>
81
- <span>{mergedProps.children}</span>
82
- </button>
83
- )
84
- }
85
-
86
- export default Button
@@ -1,66 +0,0 @@
1
- import { type Component, createSignal, mergeProps, untrack } from 'solid-js'
2
- import { type ColorResult, SketchPicker, type Color, type RGBColor, type HSLColor } from 'react-color'
3
- import { reactToSolidComponent } from './utils/component'
4
- import Button from './Button'
5
- import Popover from './Popover'
6
- import { get, isNil } from 'lodash-es'
7
-
8
- const _SketchPicker = reactToSolidComponent(SketchPicker)
9
-
10
- export interface ColorPickerProps {
11
- /**
12
- * 默认: rgba
13
- */
14
- type?: 'rgba' | 'hsla'
15
- defaultColor?: string
16
- onChange?: (colorString: string, color: ColorResult) => void
17
- }
18
-
19
- function isRGBColor(color: Color): color is RGBColor {
20
- return ['r', 'g', 'b'].every(k => !isNil(get(color, k)))
21
- }
22
-
23
- function isHSLColor(color: Color): color is HSLColor {
24
- return ['r', 'g', 'b'].every(k => !isNil(get(color, k)))
25
- }
26
-
27
- function colorStringify(color: Color | undefined) {
28
- if (!color) return
29
-
30
- if (isRGBColor(color)) return `rgba(${color.r},${color.g},${color.b},${color.a ?? 1})`
31
-
32
- if (isHSLColor(color)) return `hsla(${color.h},${color.s},${color.l},${color.a ?? 1})`
33
-
34
- return color
35
- }
36
-
37
- const ColorPicker: Component<ColorPickerProps> = _props => {
38
- const props = mergeProps({ type: 'rgba' } as ColorPickerProps, _props)
39
- const [color, setColor] = createSignal(props.defaultColor ?? 'black')
40
-
41
- return (
42
- <Popover
43
- content={
44
- <_SketchPicker
45
- color={color()}
46
- onChange={colorResult =>
47
- { untrack(() => {
48
- const colorString = colorStringify(
49
- props.type === 'rgba' ? colorResult.rgb : colorResult.hsl,
50
- )!
51
- setColor(colorString)
52
-
53
- props.onChange?.(colorString, colorResult)
54
- }); }
55
- }
56
- />
57
- }
58
- trigger="click"
59
- placement="bottomLeft"
60
- >
61
- <Button style={{ background: color() }} />
62
- </Popover>
63
- )
64
- }
65
-
66
- export default ColorPicker
@@ -1,12 +0,0 @@
1
- import { DatePicker as DatePickerAntd } from 'antd'
2
- import { reactToSolidComponent, replaceClassName } from './utils/component'
3
-
4
- const RangePicker = replaceClassName(reactToSolidComponent(DatePickerAntd.RangePicker))
5
-
6
- const _DatePicker = replaceClassName(reactToSolidComponent(DatePickerAntd))
7
- const DatePicker = _DatePicker as typeof _DatePicker & {
8
- RangePicker: typeof RangePicker
9
- }
10
- DatePicker.RangePicker = RangePicker
11
-
12
- export default DatePicker
package/src/Form.tsx DELETED
@@ -1,98 +0,0 @@
1
- import { set } from 'lodash-es'
2
- import {
3
- type JSXElement,
4
- type Component,
5
- type JSX,
6
- mergeProps,
7
- Show,
8
- Index,
9
- createMemo,
10
- } from 'solid-js'
11
- import { Dynamic } from 'solid-js/web'
12
- import { toArray } from './utils/array'
13
- import cs from 'classnames'
14
-
15
- export interface FormInstance<T extends {} = {}> {
16
- validateFields: () => Promise<T>
17
- }
18
-
19
- export interface FormProps<T extends {} = {}> {
20
- ref?: (form: FormInstance<T>) => void;
21
- /**
22
- * 表单布局
23
- * 默认: horizontal
24
- */
25
- layout?: 'horizontal' | 'vertical' | 'inline'
26
- /**
27
- * 提交按钮
28
- * @deprecated
29
- */
30
- submit?: (form: FormInstance<T>) => JSXElement
31
- children: JSXElement
32
- }
33
-
34
- export interface FormItemComponentProps<T = any> {
35
- defaultValue?: T
36
- onChange?: (value: T) => void
37
- }
38
-
39
- export interface FormItemProps {
40
- class?: string
41
- style?: JSX.CSSProperties
42
- required?: boolean
43
- label?: JSXElement
44
- name?: string
45
- initialValue?: any
46
- component: Component<FormItemComponentProps>
47
- }
48
-
49
- function Form<T extends {} = {}>(_props: FormProps<T>) {
50
- const props = mergeProps({ layout: 'horizontal' } as FormProps, _props)
51
-
52
- const resolvedChildren = createMemo(() => {
53
- return toArray(props.children) as unknown as FormItemProps[]
54
- })
55
-
56
- const values = Object.fromEntries(
57
- resolvedChildren().map(child => [child.name, child.initialValue]),
58
- ) as T
59
- const formInstance: FormInstance<T> = {
60
- async validateFields() {
61
- return await Promise.resolve(values)
62
- },
63
- }
64
- _props.ref?.(formInstance)
65
-
66
- return (
67
- <div>
68
- <Index each={resolvedChildren()}>
69
- {item => (
70
- <div class={cs('ant-flex ant-items-center ant-mb-16px', item().class)} style={item().style}>
71
- <span class="ant-flex-shrink-0 ant-mr-8px">
72
- <Show when={item().required}>
73
- <span class='ant-mr-4px ant-text-[var(--error-color)]'>*</span>
74
- </Show>
75
- <label>{item().label}</label>
76
- </span>
77
-
78
- <Dynamic
79
- component={item().component}
80
- defaultValue={item().initialValue}
81
- onChange={(value: any) => {
82
- set(values, item().name!, value)
83
- }}
84
- />
85
- </div>
86
- )}
87
- </Index>
88
-
89
- {props.submit?.(formInstance as FormInstance<T>)}
90
- </div>
91
- )
92
- }
93
-
94
- Form.Item = (props: FormItemProps) => props as any
95
-
96
- Form.createForm = () => {}
97
-
98
- export default Form
package/src/Image.tsx DELETED
@@ -1,29 +0,0 @@
1
- import { Image as ImageAntd } from 'antd'
2
- import { configProvider, reactToSolidComponent, replaceClassName } from './utils/component'
3
- import { solidToReact } from './utils/solid'
4
- import { type JSXElement, createMemo } from 'solid-js'
5
- import { mapValues } from 'lodash-es'
6
-
7
- const _Image = replaceClassName(
8
- reactToSolidComponent(configProvider(ImageAntd), () => (<div class="ant-inline-flex" />) as any),
9
- )
10
-
11
- type ImageProps = Omit<Parameters<typeof _Image>[0], 'placeholder'> & {
12
- placeholder?: JSXElement
13
- }
14
-
15
- function Image(_props: ImageProps) {
16
- const props = createMemo(() =>
17
- mapValues(_props, (value, key) => {
18
- switch (key) {
19
- case 'placeholder':
20
- return solidToReact(value)
21
- default:
22
- return value
23
- }
24
- }),
25
- )
26
- return <_Image {...(props() as any)} />
27
- }
28
-
29
- export default Image
package/src/Input.tsx DELETED
@@ -1,110 +0,0 @@
1
- import { omit } from 'lodash-es'
2
- import { Show, splitProps } from 'solid-js'
3
- import type { JSX, JSXElement, Component } from 'solid-js'
4
- import cs from 'classnames'
5
- import createControllableValue from './hooks/createControllableValue'
6
- import { Dynamic } from 'solid-js/web'
7
-
8
- type CommonInputProps<T extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement> = JSX.CustomAttributes<T> & {
9
- textarea?: boolean
10
- defaultValue?: string | undefined
11
- value?: string | undefined
12
- addonBefore?: JSXElement
13
- addonAfter?: JSXElement
14
- /**
15
- * 仅供 InputNumber 使用
16
- */
17
- inputAfter?: JSXElement
18
- placeholder?: string
19
- onChange?: JSX.InputEventHandler<T, InputEvent>
20
- onPressEnter?: JSX.EventHandler<T, KeyboardEvent>
21
- onKeyDown?: JSX.EventHandler<T, KeyboardEvent>
22
- }
23
-
24
- export function CommonInput<T extends HTMLInputElement | HTMLTextAreaElement = HTMLInputElement>(props: CommonInputProps<T> &
25
- Omit<JSX.InputHTMLAttributes<T>, 'onChange' | 'onInput' | 'onKeyDown'>) {
26
- const [{ onChange, onPressEnter, onKeyDown }, inputProps] = splitProps(props, [
27
- 'defaultValue',
28
- 'value',
29
- 'class',
30
- 'addonBefore',
31
- 'addonAfter',
32
- 'inputAfter',
33
- 'onChange',
34
- 'onPressEnter',
35
- 'onKeyDown',
36
- ])
37
-
38
- const [_, controllableProps] = splitProps(props, ['onChange'])
39
- const [value, setValue] = createControllableValue(controllableProps)
40
-
41
- return (
42
- <div class="ant-flex ant-w-full">
43
- <Show when={props.addonBefore}>
44
- <div class="ant-shrink-0 ant-flex ant-justify-center ant-items-center ant-px-11px ant-bg-[rgba(0,0,0,.02)] ant-[border:1px_solid_#d9d9d9] ant-border-r-0 ant-rounded-l-6px ant-text-14px">
45
- {props.addonBefore}
46
- </div>
47
- </Show>
48
-
49
- <div class="ant-w-full ant-relative ant-[--input-after-display:none] hover:ant-[--input-after-display:block] p-hover-child[input]:ant-border-[var(--primary-color)]">
50
- <Dynamic<Component<JSX.InputHTMLAttributes<HTMLInputElement>>>
51
- component={
52
- (props.textarea ? 'textarea' : 'input') as unknown as Component<
53
- JSX.InputHTMLAttributes<HTMLInputElement>
54
- >
55
- }
56
- {...inputProps as JSX.InputHTMLAttributes<HTMLInputElement>}
57
- class={cs(
58
- 'ant-w-full ant-py-0 ant-px-11px ant-[outline:none] ant-text-14px ant-rounded-6px ant-[border:1px_solid_#d9d9d9] focus:ant-border-[var(--primary-color)] focus:ant-[box-shadow:0_0_0_2px_rgba(5,145,255,0.1)] ant-py-8px',
59
- !props.textarea && 'ant-h-32px',
60
- props.class,
61
- props.addonBefore && 'ant-rounded-l-0',
62
- props.addonAfter && 'ant-rounded-r-0',
63
- )}
64
- value={value() ?? ''}
65
- onInput={e => {
66
- setValue(e.target.value)
67
- onChange?.(e as any)
68
- }}
69
- onKeyDown={e => {
70
- if (e.key === 'Enter') {
71
- onPressEnter?.(e as any)
72
- }
73
-
74
- onKeyDown?.(e as any)
75
- }}
76
- />
77
-
78
- <Show when={props.inputAfter}>
79
- <div class="ant-[display:var(--input-after-display)] ant-absolute ant-top-0 ant-bottom-0 ant-right-0 ant-h-[calc(100%-2px)] ant-translate-y-1px -ant-translate-x-1px">
80
- {props.inputAfter}
81
- </div>
82
- </Show>
83
- </div>
84
-
85
- <Show when={props.addonAfter}>
86
- <div class="ant-shrink-0 ant-flex ant-justify-center ant-items-center ant-px-11px ant-bg-[rgba(0,0,0,.02)] ant-[border:1px_solid_#d9d9d9] ant-border-l-0 ant-rounded-r-6px ant-text-14px">
87
- {props.addonAfter}
88
- </div>
89
- </Show>
90
- </div>
91
- )
92
- }
93
-
94
- export type InputProps = Omit<CommonInputProps, 'inputAfter' | 'textarea'> &
95
- Omit<JSX.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'onInput' | 'onKeyDown'>
96
-
97
- export type TextAreaProps = Omit<CommonInputProps<HTMLTextAreaElement>, 'inputAfter' | 'textarea'> &
98
- Omit<JSX.TextareaHTMLAttributes<HTMLTextAreaElement>, 'onChange' | 'onInput' | 'onKeyDown'>
99
-
100
- const Input: Component<InputProps> & {
101
- TextArea: Component<TextAreaProps>
102
- } = props => {
103
- return <CommonInput {...omit(props, ['inputAfter'])} />
104
- }
105
-
106
- Input.TextArea = props => {
107
- return <CommonInput<HTMLTextAreaElement> textarea {...omit(props, ['inputAfter'])} />
108
- }
109
-
110
- export default Input
@@ -1,46 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest'
2
- import { fireEvent, render } from '@solidjs/testing-library'
3
- import InputNumber from './InputNumber'
4
- import '@testing-library/jest-dom'
5
-
6
- describe('InputNumber component', () => {
7
- it('onChange', () => {
8
- const onChange = vi.fn()
9
- const { getByPlaceholderText } = render(() => (
10
- <InputNumber placeholder="input-number" onChange={onChange} />
11
- ))
12
-
13
- const input: HTMLInputElement = getByPlaceholderText('input-number')
14
- input.value = '123'
15
- fireEvent.input(input)
16
- expect(onChange).toHaveBeenLastCalledWith(123)
17
-
18
- input.value = '1234'
19
- fireEvent.input(input)
20
- expect(onChange).toBeCalledTimes(2)
21
- expect(onChange).toHaveBeenLastCalledWith(1234)
22
-
23
- input.value = '1234'
24
- fireEvent.input(input)
25
- expect(onChange).toBeCalledTimes(2)
26
-
27
- input.value = '1234.'
28
- fireEvent.input(input)
29
- expect(onChange).toBeCalledTimes(2)
30
-
31
- input.value = '1234.0'
32
- fireEvent.input(input)
33
- expect(onChange).toBeCalledTimes(2)
34
-
35
- input.value = '1234.01'
36
- fireEvent.input(input)
37
- expect(onChange).toBeCalledTimes(3)
38
-
39
- input.value = '123x'
40
- fireEvent.input(input)
41
- expect(onChange).toBeCalledTimes(3)
42
-
43
- fireEvent.blur(input)
44
- expect(onChange).toBeCalledTimes(3)
45
- })
46
- })
@@ -1,119 +0,0 @@
1
- import { type Component, createEffect, on, splitProps } from 'solid-js'
2
- import { CommonInput, type InputProps } from './Input'
3
- import { isNil } from 'lodash-es'
4
- import createControllableValue from './hooks/createControllableValue'
5
- import { dispatchEventHandlerUnion } from './utils/solid'
6
-
7
- export interface InputNumberProps
8
- extends Omit<InputProps, 'defaultValue' | 'value' | 'onChange' | 'inputAfter' | 'onKeyDown'> {
9
- defaultValue?: number | null | undefined
10
- value?: number | null | undefined
11
- onChange?: (value: number | null) => void
12
- }
13
-
14
- const isEmptyValue = (value: number | string | null | undefined) => isNil(value) || value === ''
15
-
16
- const formatNum = (
17
- v: number | string | null | undefined,
18
- prev?: number | null | undefined,
19
- ): number | null => {
20
- if (isEmptyValue(v)) {
21
- return null
22
- }
23
-
24
- const num = Number(v)
25
- if (prev !== undefined && Number.isNaN(num)) {
26
- return prev
27
- }
28
-
29
- return num
30
- }
31
-
32
- const actionBtnClass =
33
- 'ant-text-12px ant-flex ant-justify-center ant-items-center ant-h-1/2 ant-cursor-pointer ant-opacity-70 hover:ant-h-100% hover:ant-text-[var(--primary-color)] ant-transition-color ant-transition-height ant-transition-duration-500'
34
-
35
- const InputNumber: Component<InputNumberProps> = props => {
36
- const [{ onChange, onBlur }, inputProps] = splitProps(props, [
37
- 'defaultValue',
38
- 'value',
39
- 'onChange',
40
- 'onBlur',
41
- ])
42
-
43
- const [_, controllableProps] = splitProps(props, ['onChange'])
44
- const [value, setValue] = createControllableValue<number | string | null | undefined>(
45
- controllableProps,
46
- )
47
- const add = (addon: number) => {
48
- setValue(v => {
49
- if (isEmptyValue(v)) {
50
- return addon
51
- }
52
-
53
- const num = Number(v)
54
- if (Number.isNaN(num)) {
55
- return v
56
- }
57
- return num + addon
58
- })
59
- }
60
- const up = () => { add(1); }
61
- const down = () => { add(-1); }
62
-
63
- createEffect(
64
- on(
65
- value,
66
- (input, __, prev: number | null | undefined) => {
67
- const num = formatNum(input, prev)
68
- if (num !== prev) {
69
- prev = num
70
- onChange?.(num)
71
- }
72
- return num
73
- },
74
- {
75
- defer: true,
76
- },
77
- ),
78
- )
79
-
80
- return (
81
- <CommonInput
82
- {...inputProps}
83
- inputAfter={
84
- <div class="ant-flex ant-flex-col ant-h-full ant-w-24px ant-[border-left:1px_solid_#d9d9d9]">
85
- <div class={actionBtnClass} onClick={up}>
86
- <div class="i-ant-design:up-outlined" />
87
- </div>
88
- <div class={`ant-[border-top:1px_solid_#d9d9d9] ${actionBtnClass}`} onClick={down}>
89
- <div class="i-ant-design:down-outlined" />
90
- </div>
91
- </div>
92
- }
93
- value={`${value() ?? ''}`}
94
- onKeyDown={e => {
95
- switch (e.key) {
96
- case 'ArrowUp':
97
- up()
98
- e.preventDefault()
99
- return
100
- case 'ArrowDown':
101
- down()
102
- e.preventDefault()
103
- }
104
- }}
105
- onChange={e => {
106
- const newValue = e.target.value || null
107
- setValue(newValue)
108
- }}
109
- onBlur={e => {
110
- const newValue = e.target.value || null
111
- setValue(formatNum(newValue))
112
-
113
- dispatchEventHandlerUnion(onBlur, e)
114
- }}
115
- />
116
- )
117
- }
118
-
119
- export default InputNumber