Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: input 和 input number 的实现 #794

Merged
merged 1 commit into from
Aug 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions tdesign/desktop/site/src/components/web/input/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { OmiProps, WeElement, define, h, tag } from "omi";

import '../../../../../src/input'
import observable from "../../../../../src/utils/observable";

@tag('page-input')
export default class extends WeElement {

static css = '';

inputValue = ''

render(props: {} | OmiProps<{}, any>, store: any) {

return (
<div style="padding:24px">
<div style="display:flex;">
<div style="width:500px;margin:auto;text-align:center;">
<t-input
status="error"
tips="这是 tips 文本信息"
align="center"
value={this.inputValue}
onChange={
(val: any) => {
this.inputValue = val
// this.update()
}
}
/>
</div>
<div>
{this.inputValue}
</div>
</div>
</div>

);
}
}
2 changes: 1 addition & 1 deletion tdesign/desktop/site/src/components/web/slider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ define('page-slider', class extends WeElement {
render(props: {} | OmiProps<{}, any>, store: any) {
return (
<div style="padding:24px">
<t-slider />
<t-slider inputNumberProps />
</div>


Expand Down
11 changes: 9 additions & 2 deletions tdesign/desktop/site/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ const charts = ['bar', 'line', 'scatter', 'pie', 'doughnut', 'radar', 'polar-are

export function registerRouting(rootEl: any) {
route('/', () => {
import('../docs/overview.tsx').then(() => {
import('../docs/overview').then(() => {
rootEl.data.tagName = 'page-overview'
rootEl.update()
})
})

route('/welcome', () => {
import('../docs/overview.tsx').then(() => {
import('../docs/overview').then(() => {
rootEl.data.tagName = 'page-overview'
rootEl.update()
})
Expand All @@ -75,6 +75,13 @@ export function registerRouting(rootEl: any) {
})
})

route('/input', () => {
import('./components/web/input').then(() => {
rootEl.data.tagName = 'page-input'
rootEl.update()
})
})

route('/link', () => {
import('./components/web/link/index').then(() => {
rootEl.data.tagName = 'page-link'
Expand Down
18 changes: 6 additions & 12 deletions tdesign/desktop/src/common.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
import { WeElement } from 'omi'

// TElement 表示 API 只接受传入组件
export type TElement<T = undefined> = T extends undefined
? WeElement
: (props: T) => WeElement
export type TElement<T = undefined> = T extends undefined ? WeElement : (props: T) => WeElement
// 1. TNode = ReactNode; 2. TNode<T> = (props: T) => ReactNode
export type TNode<T = undefined> = T extends undefined
? WeElement
: WeElement | ((props: T) => WeElement)
export type TNode<T = undefined> = T extends undefined ? WeElement : WeElement | ((props: T) => WeElement)

export type AttachNodeReturnValue = HTMLElement | Element | Document
export type AttachNode =
| CSSSelector
| ((triggerNode?: HTMLElement) => AttachNodeReturnValue)
export type AttachNode = CSSSelector | ((triggerNode?: HTMLElement) => AttachNodeReturnValue)

// 与滚动相关的容器类型,因为 document 上没有 scroll 相关属性, 因此排除 document
export type ScrollContainerElement = Window | HTMLElement
export type ScrollContainer = (() => ScrollContainerElement) | CSSSelector


// 组件 TS 类型,暂定 any,可能调整为 () => JSX.Element
export type ComponentType = any

export type Styles = JSX.SVGAttributes;
export type Styles = JSX.SVGAttributes

export interface StyledProps {
className?: string
Expand Down Expand Up @@ -118,4 +111,5 @@ export interface ScrollToElementParams {
behavior?: 'auto' | 'smooth'
}

export type ThemeCommon = 'default' | 'primary' | 'danger' | 'warning' | 'success'
export type ThemeCommon = 'default' | 'primary' | 'danger' | 'warning' | 'success'
export type StatusEnum = 'default' | 'error' | 'warning' | 'success'
55 changes: 55 additions & 0 deletions tdesign/desktop/src/input-number/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { h, OmiProps, tag, WeElement, render, classNames } from 'omi'
import { InputProps } from './types';
import styles from './sytle'
import { TdClassNamePefix } from '../../src/utils';

import '../input'

const InputNumebrClassNamePefix = (name: string) => TdClassNamePefix('input') + name;

@tag('t-input-number')
export default class InputNumber extends WeElement<InputProps> {

static css = styles;

handleChange = (val: number) => {
//@ts-ignore
this.props?.onChangeValue?.(val)
}

render(props: InputProps, store: any) {

const { value } = props;

return (
<>
<div class="t-slider__input-container">
<div class="t-input-number t-size-m t-is-controls-right t-input-number--column t-slider-input">
<button
onClick={() => {
this.handleChange(value - 1)
}}
type="button" class="t-input-number__decrease t-button t-button--theme-default t-button--variant-outline t-button--shape-square">
<svg fill="none" viewBox="0 0 24 24" width="1em" height="1em" class="t-icon t-icon-chevron-down t-size-m">
<path fill="currentColor" d="M17.5 8.09l-5.5 5.5-5.5-5.5L5.09 9.5 12 16.41l6.91-6.91-1.41-1.41z"></path>
</svg>
</button>

<t-input autocomplete="off" value={value || 0} />

<button
onClick={() => {
this.handleChange(value + 1)
}}
type="button" class="t-input-number__increase t-button t-button--theme-default t-button--variant-outline t-button--shape-square">
<svg fill="none" viewBox="0 0 24 24" width="1em" height="1em" class="t-icon t-icon-chevron-up t-size-m">
<path fill="currentColor" d="M17.5 15.91l-5.5-5.5-5.5 5.5-1.41-1.41L12 7.59l6.91 6.91-1.41 1.41z">
</path>
</svg>
</button>
</div>
</div>
</>
);
}
}
3 changes: 3 additions & 0 deletions tdesign/desktop/src/input-number/sytle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import inputSyle from '../../_common/style/web/components/input-number/_index.less'

export default inputSyle
12 changes: 12 additions & 0 deletions tdesign/desktop/src/input-number/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { HorizontalAlignEnum, SizeEnum, StatusEnum, TNode } from '@src/common'

export type InputProps = {
autoWidth: boolean;
showClearIconOnEmpty: boolean;
clearable: boolean;
align: HorizontalAlignEnum;
size: SizeEnum;
status: StatusEnum;
tips: TNode;
onChangeValue: (value: any) => void;
} & HTMLInputElement
67 changes: 67 additions & 0 deletions tdesign/desktop/src/input/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { h, OmiProps, tag, WeElement, render, classNames } from 'omi'
import { InputProps } from './types';
import styles from './sytle'
import { TdClassNamePefix } from '../../src/utils';

const InputClassNamePefix = (name: string) => TdClassNamePefix('input') + name;

@tag('t-input')
export default class Input extends WeElement<InputProps> {

static css = styles;



render(props: InputProps, store: any) {

const { autofocus, disabled, readOnly, showClearIconOnEmpty, align, size, status, type, autoWidth } = props;
const { placeholder, value, tips, autocomplete } = props;
const { onChange } = props;

const curStatus = status || 'default'

return (
<>
<div>
<div class={classNames(
InputClassNamePefix('__wrap'),
{
[InputClassNamePefix('--auto-width')]: autoWidth
}
)}>
<div class={
classNames(
't-input',
TdClassNamePefix(`is-${curStatus}`),
TdClassNamePefix(`align-${align}`),
{
[TdClassNamePefix(`is-readonly`)]: readOnly,
[TdClassNamePefix(`is-disabled`)]: disabled,
}
)
}
>
<input
autocomplete={autocomplete}
autofocus={autofocus}
disabled={disabled}
readonly={readOnly}
placeholder={placeholder || '请输入'} type={type || 'text'}
class={InputClassNamePefix('__inner')}
onchange={(evt: any) => {
const target = evt.target;
(onChange as any)?.(target.value);
}}
value={value} />
</div>
<div class={
classNames('t-input__tips', InputClassNamePefix(`__tips--${curStatus}`))
}>
{tips}
</div>
</div>
</div >
</>
);
}
}
3 changes: 3 additions & 0 deletions tdesign/desktop/src/input/sytle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import inputSyle from '../../_common/style/web/components/input/_index.less'

export default inputSyle
13 changes: 13 additions & 0 deletions tdesign/desktop/src/input/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { HorizontalAlignEnum, SizeEnum, StatusEnum, TNode } from '@src/common'

export type InputProps = HTMLInputElement &
HTMLTextAreaElement & {
autoWidth: boolean
showClearIconOnEmpty: boolean
clearable: boolean
align: HorizontalAlignEnum
size: SizeEnum
status: StatusEnum
tips: TNode
onChange: (value: any) => void
}
41 changes: 20 additions & 21 deletions tdesign/desktop/src/slider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { TdClassNamePefix } from '../utils'
import { SliderProps } from './types'
import { ceil, clamp } from 'lodash'

import '../input-number'

const SliderClassNamePefix = (className: string) => TdClassNamePefix('slider__') + className;

@tag('t-slider')
Expand All @@ -18,7 +20,7 @@ export default class Slider extends WeElement<SliderProps> {
track: [number, number] = [0, 0];

static defaultProps = {
range: true
range: false
};


Expand Down Expand Up @@ -55,9 +57,19 @@ export default class Slider extends WeElement<SliderProps> {
window.addEventListener('pointerup', pointerUp);
}

handleChangeValue(val: any) {
if (this.props.range) {

} else {
this.curLeft[1] = Math.min(100, val);
this.track = [this.curLeft[0], this.curLeft[1] - this.curLeft[0]]
this.update();
}
}

render(props: OmiProps<SliderProps>) {

const { range } = props;
const { range, inputNumberProps } = props;

return (
<>
Expand Down Expand Up @@ -101,26 +113,13 @@ export default class Slider extends WeElement<SliderProps> {
</div>
</div>

{/* <div class="t-slider__input-container">
<div class="t-input-number t-size-m t-is-controls-right t-input-number--column t-slider-input">
<button type="button" class="t-input-number__decrease t-button t-button--theme-default t-button--variant-outline t-button--shape-square">
<svg fill="none" viewBox="0 0 24 24" width="1em" height="1em" class="t-icon t-icon-chevron-down t-size-m">
<path fill="currentColor" d="M17.5 8.09l-5.5 5.5-5.5-5.5L5.09 9.5 12 16.41l6.91-6.91-1.41-1.41z"></path>
</svg>
</button>
<div class="t-input__wrap" value="35">
<div class="t-input t-align-left">
<input placeholder="请输入" type="text" class="t-input__inner" autocomplete="off" value={this.curLeft[0]} />
</div>
{
inputNumberProps && (
<div class='t-slider__input-container'>
<t-input-number value={this.curLeft[1] - this.curLeft[0]} onChangeValue={this.handleChangeValue.bind(this)} />
</div>
<button type="button" class="t-input-number__increase t-button t-button--theme-default t-button--variant-outline t-button--shape-square">
<svg fill="none" viewBox="0 0 24 24" width="1em" height="1em" class="t-icon t-icon-chevron-up t-size-m">
<path fill="currentColor" d="M17.5 15.91l-5.5-5.5-5.5 5.5-1.41-1.41L12 7.59l6.91 6.91-1.41 1.41z">
</path>
</svg>
</button>
</div>
</div> */}
)
}
</div>

</>
Expand Down
21 changes: 21 additions & 0 deletions tdesign/desktop/src/utils/observable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export default function observable(target: any, propertyKey: string) {
// 保存原始属性值
let original = target[propertyKey]

Object.defineProperty(target, propertyKey, {
get() {
console.log('Getting ', propertyKey)
return original
},
set(value) {
console.log('Setting ', propertyKey)
original = value
try {
// target.update()
} catch (err) {
console.warn(err)
}
},
})

}