Skip to content

Commit

Permalink
refactor(field): onClick
Browse files Browse the repository at this point in the history
  • Loading branch information
webyom committed Sep 14, 2020
1 parent 1f6b4cf commit 1c0c26f
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 11 deletions.
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"preact": ">=10.2.1"
},
"dependencies": {
"closest": "0.0.1",
"clsx": "^1.1.0"
}
}
40 changes: 29 additions & 11 deletions src/field/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as preact from 'preact';
import { isDef } from '../utils';
import { closest } from '../utils/dom';
import { createBEM } from '../utils/bem';
import { Icon } from '../icon';
import { Cell, CellProps } from '../cell';
Expand Down Expand Up @@ -71,6 +72,7 @@ export type FieldProps<T> = Omit<CellProps, 'onClick'> & {
onClosePopup?(field: Field<T>, confirm?: boolean): void;
onInputKeyDown?(evt: Event): void;
onInputChange?(evt: Event): string | void;
onClick?: (evt: Event) => void;
};

type FieldState<T> = {
Expand Down Expand Up @@ -108,6 +110,7 @@ const NO_MATCHED_RULE_FLAG = '__NO_MATCHED_RULE_FLAG__';
export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState<T>> {
private isPopup = false;
private readonly inputRef = preact.createRef();
private readonly bodyRef = preact.createRef<HTMLDivElement>();

constructor(props: preact.RenderableProps<FieldProps<T>>) {
super(props);
Expand Down Expand Up @@ -253,11 +256,17 @@ export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState
});
}

private openPopup(): void {
openPopup(): void {
if (!this.isPopup) {
return;
}
this.setState({ showPopup: true });
}

private closePopup(confirm?: boolean): void {
closePopup(confirm?: boolean): void {
if (!this.isPopup) {
return;
}
const { onClosePopup } = this.props;
if (confirm) {
this.setState({ showPopup: false, popupValue: this.formatReturnValue(this.inputRef.current.getValue()) }, () => {
Expand All @@ -276,7 +285,12 @@ export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState
private onPopupControlClick(evt: Event): void {
if (this.isPopup && !this.props.disabled) {
const target = evt.target as HTMLElement;
if (target.className.indexOf('pant-field__control') !== -1) {
const field = closest(target, '.pant-field', true);
if (
field &&
field.querySelector('.pant-field__body') === this.bodyRef.current &&
!closest(target, '.pant-popup, .pant-overlay', true)
) {
this.openPopup();
}
}
Expand Down Expand Up @@ -406,7 +420,7 @@ export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState
});
}

genInput(): preact.JSX.Element {
private genInput(): preact.JSX.Element {
const { props } = this;
const { type, name, inputAlign, children } = props;
const { showPopup, popupValue, isInputType, value } = this.state;
Expand All @@ -428,7 +442,6 @@ export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState
class={bem('control', [inputAlign, 'custom'])}
value={this.formatDisplayValue(popupValue)}
placeholder={props.placeholder}
onClick={this.onPopupControlClick}
readOnly
/>
{childrenWithProps}
Expand Down Expand Up @@ -487,7 +500,7 @@ export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState
}
}

genRightIcon(): preact.JSX.Element {
private genRightIcon(): preact.JSX.Element {
const { rightIcon } = this.props;
if (typeof rightIcon === 'string') {
return <Icon name={rightIcon} />;
Expand All @@ -496,7 +509,7 @@ export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState
}
}

genWordLimit(): preact.JSX.Element {
private genWordLimit(): preact.JSX.Element {
const { showWordLimit, maxlength } = this.props;
const { isInputType, value } = this.state;
if (isInputType && showWordLimit && maxlength) {
Expand All @@ -511,7 +524,7 @@ export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState
}
}

genMessage(): preact.JSX.Element {
private genMessage(): preact.JSX.Element {
const { errorMessage, errorMessageAlign } = this.props;
const { validateMessage } = this.state;
const message = validateMessage || errorMessage;
Expand All @@ -522,6 +535,10 @@ export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState

render(): preact.JSX.Element {
const { props } = this;
const { disabled } = props;
const input = this.genInput();
const onClick =
typeof props.onClick === 'function' ? props.onClick : this.isPopup ? this.onPopupControlClick : null;
return (
<Cell
label={props.label}
Expand All @@ -532,14 +549,15 @@ export class Field<T = never> extends preact.Component<FieldProps<T>, FieldState
required={props.required}
className={bem({
error: this.showError,
disabled: props.disabled,
disabled: disabled,
'min-height': props.type === 'textarea' && !props.autosize,
})}
titleClassName={bem('title')}
valueClassName={bem('value')}
onClick={(!disabled && onClick) || null}
>
<div className={bem('body')}>
{this.genInput()}
<div ref={this.bodyRef} className={bem('body')}>
{input}
{this.showClear && <Icon name="clear" className={bem('clear')} onTouchStart={this.clearInput} />}
{this.genRightIcon()}
{props.button && <div class={bem('button')}>{props.button}</div>}
Expand Down
7 changes: 7 additions & 0 deletions src/form/demo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@ export class FormRouteComponent extends preact.Component {
title="Switch"
rules={[{ pattern: 'required', message: 'Required field', trigger: ['change'] }]}
></Field>
<Field<boolean>
type="checkbox"
defaultValue={true}
name="checkbox"
title="Checkbox"
rules={[{ pattern: 'required', message: 'Required field', trigger: ['change'] }]}
></Field>
<Field<[]>
name="checkbox-group"
title="Checkbox Group"
Expand Down
6 changes: 6 additions & 0 deletions src/utils/dom.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import closestx from 'closest';

export function removeNode(el: Node): void {
const parent = el.parentNode;

Expand All @@ -17,3 +19,7 @@ export function isHidden(el: HTMLElement): boolean {

return hidden || parentHidden;
}

export function closest(element: Element | EventTarget, selector: string, checkYoSelf?: boolean): Element | null {
return closestx(element, selector, checkYoSelf);
}
7 changes: 7 additions & 0 deletions types/closest.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare module 'closest' {
export default function closest(
element: Element | EventTarget,
selector: string,
checkYoSelf?: boolean,
): Element | null;
}

0 comments on commit 1c0c26f

Please sign in to comment.