Skip to content

Commit

Permalink
feat: allow passing tabIndex to both view and input elements
Browse files Browse the repository at this point in the history
Fixes #86
  • Loading branch information
alioguzhan committed May 31, 2020
1 parent 1f1ccac commit c2d7eb2
Show file tree
Hide file tree
Showing 3 changed files with 270 additions and 142 deletions.
322 changes: 182 additions & 140 deletions index.d.ts
@@ -1,147 +1,189 @@
declare module 'react-editext' {
import * as React from 'react';
import * as React from 'react'

export type EdiTextType = "text" | "textarea" | "email" | "number" | "date" | "datetime-local" | "time" | "month" | "url" | "week" | "tel";
export type ButtonsAlignment = "after" | "before";
export type EdiTextType =
| 'text'
| 'textarea'
| 'email'
| 'number'
| 'date'
| 'datetime-local'
| 'time'
| 'month'
| 'url'
| 'week'
| 'tel'
export type ButtonsAlignment = 'after' | 'before'

export interface EdiTextProps {
/**
* Props to be passed to input element.
* Any kind of valid DOM attributes are welcome
*/
inputProps?:React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>;
/**
* Props to be passed to div element that shows the text.
* You can specify your own `styles` or `className`
*/
viewProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
/**
* Value of the content [in view mode] and input [in edit mode]
*/
value: string;
/**
* A simple hint message appears at the bottom of input element.
* Any valid element is allowed.
*/
hint?: React.ReactNode;
/**
export interface EdiTextProps {
/**
* Props to be passed to input element.
* Any kind of valid DOM attributes are welcome
*/
inputProps?: React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>
/**
* Props to be passed to div element that shows the text.
* You can specify your own `styles` or `className`
*/
viewProps?: React.DetailedHTMLProps<
React.HTMLAttributes<HTMLDivElement>,
HTMLDivElement
>
/**
* Value of the content [in view mode] and input [in edit mode]
*/
value: string
/**
* A simple hint message appears at the bottom of input element.
* Any valid element is allowed.
*/
hint?: React.ReactNode
/**
If validation fails this message will appear
*/
validationMessage?: any;
/** Pass your own validation function.
* takes one param -> `value`.
* It must return `true` or `false`
*/
validation?: (...args: string[]) => boolean;
/**
* will be called when validation fails.
* takes one param <value> which is the current value of input
*/
onValidationFail?: (...args: string[]) => any;
/**
* Input type. Possible options are:
* `text`, `number`, `email`, `textarea`, `date`,
* `datetime-local`, `time`, `month`, `url`, `week`, `tel`
*/
type: EdiTextType;
/**
* will be called when user clicked cancel button
* @param value the current value of input when cancelled.
* @param inputProps inputProps that passed to the element.
*/
onCancel?: (value: any, inputProps: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) => any;
/**
* will be called when user clicked save button.
* @param value the current value of input
* @param inputProps inputProps that passed to the element.
*/
onSave: (value: any, inputProps: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) => any;
/**
* Custom class name for SAVE button.
* */
saveButtonClassName?: string;
/**
* Custom class name for EDIT button.
* */
editButtonClassName?: string;
/**
* Custom class name for CANCEL button. */
cancelButtonClassName?: string;
/**
* Content for CANCEL button. Any valid element and node are allowed. */
cancelButtonContent?: any;
/**
* Content for SAVE button. Any valid element and node are allowed. */
saveButtonContent?: any;
/**
* Content for EDIT button. Any valid element and node are allowed. */
editButtonContent?: any;
/**
* Set it to `true` if you don't want to see default icons
* on action buttons.See Examples page for more details.
*/
hideIcons?: boolean;
/**
* Decides whether buttons will be located _BEFORE_ or _AFTER_
* the input element. Default is `after`.
*/
buttonsAlign?: ButtonsAlignment;
/**
* Custom class name for the container in view mode.
*/
viewContainerClassName?: string;
/**
* Custom class name for the container in edit mode.
* Will be set to viewContainerClassName if you set it and omit this.
*/
editContainerClassName?: string;
/**
* Custom class name for the top-level main container.
*/
mainContainerClassName?: string;
/**
* Set it to `true` if you want clicking on the view to activate the editor.
*/
editOnViewClick?: boolean;
/**
* Set it to `true` if you want the view state to be edit mode
*/
editing?: boolean;
/**
* Will be called when the editing mode is active.
*
* @param value the value of the input at the time when editing started.
* @param inputProps inputProps that passed to the element.
*/
onEditingStart?: (value: any, inputProps: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> ) => any;
/**
* Set it to `true` if you want to display action buttons **only**
* when the text hovered by the user.
*/
showButtonsOnHover?: boolean;
/**
* Set it to `true` if you want to submit the form when `Enter`
* is pressed.
*/
submitOnEnter?: boolean;
/**
* Set it to `true` if you want to cancel the form when `Escape`
* is pressed.
*/
cancelOnEscape?: boolean;
/**
* Set it to `true` if you want to cancel the form when the input
* is unfocused.
*/
cancelOnUnfocus?: boolean;
/**
* Set it to `true` if you want to save the form when the input
* is unfocused.
*/
submitOnUnfocus?: boolean;
}
validationMessage?: any
/** Pass your own validation function.
* takes one param -> `value`.
* It must return `true` or `false`
*/
validation?: (...args: string[]) => boolean
/**
* will be called when validation fails.
* takes one param <value> which is the current value of input
*/
onValidationFail?: (...args: string[]) => any
/**
* Input type. Possible options are:
* `text`, `number`, `email`, `textarea`, `date`,
* `datetime-local`, `time`, `month`, `url`, `week`, `tel`
*/
type: EdiTextType
/**
* will be called when user clicked cancel button
* @param value the current value of input when cancelled.
* @param inputProps inputProps that passed to the element.
*/
onCancel?: (
value: any,
inputProps: React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>
) => any
/**
* will be called when user clicked save button.
* @param value the current value of input
* @param inputProps inputProps that passed to the element.
*/
onSave: (
value: any,
inputProps: React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>
) => any
/**
* Custom class name for SAVE button.
* */
saveButtonClassName?: string
/**
* Custom class name for EDIT button.
* */
editButtonClassName?: string
/**
* Custom class name for CANCEL button. */
cancelButtonClassName?: string
/**
* Content for CANCEL button. Any valid element and node are allowed. */
cancelButtonContent?: any
/**
* Content for SAVE button. Any valid element and node are allowed. */
saveButtonContent?: any
/**
* Content for EDIT button. Any valid element and node are allowed. */
editButtonContent?: any
/**
* Set it to `true` if you don't want to see default icons
* on action buttons.See Examples page for more details.
*/
hideIcons?: boolean
/**
* Decides whether buttons will be located _BEFORE_ or _AFTER_
* the input element. Default is `after`.
*/
buttonsAlign?: ButtonsAlignment
/**
* Custom class name for the container in view mode.
*/
viewContainerClassName?: string
/**
* Custom class name for the container in edit mode.
* Will be set to viewContainerClassName if you set it and omit this.
*/
editContainerClassName?: string
/**
* Custom class name for the top-level main container.
*/
mainContainerClassName?: string
/**
* Set it to `true` if you want clicking on the view to activate the editor.
*/
editOnViewClick?: boolean
/**
* Set it to `true` if you want the view state to be edit mode
*/
editing?: boolean
/**
* Will be called when the editing mode is active.
*
* @param value the value of the input at the time when editing started.
* @param inputProps inputProps that passed to the element.
*/
onEditingStart?: (
value: any,
inputProps: React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>
) => any
/**
* Set it to `true` if you want to display action buttons **only**
* when the text hovered by the user.
*/
showButtonsOnHover?: boolean
/**
* Set it to `true` if you want to submit the form when `Enter`
* is pressed.
*/
submitOnEnter?: boolean
/**
* Set it to `true` if you want to cancel the form when `Escape`
* is pressed.
*/
cancelOnEscape?: boolean
/**
* Set it to `true` if you want to cancel the form when the input
* is unfocused.
*/
cancelOnUnfocus?: boolean
/**
* Set it to `true` if you want to save the form when the input
* is unfocused.
*/
submitOnUnfocus?: boolean
/** An helper shortcut in case you want to pass the same tabIndex to both
* `viewProps` and `inputProps`.
*
* NOTE: This will be overriden if you pass the tabIndex in `viewProps`
* or `inputProps`.
*/
tabIndex?: number
}

export default class EdiText extends React.Component<EdiTextProps, any> {
render(): JSX.Element;
}
export default class EdiText extends React.Component<EdiTextProps, any> {
render(): JSX.Element
}
}
29 changes: 27 additions & 2 deletions src/index.js
Expand Up @@ -130,6 +130,10 @@ export default class EdiText extends Component {
ref={this.input}
className={styles.Editext__input}
editext={dataAttributes.input}
// this is here because,
// we still allow people to pass the tabIndex via inputProps
// also backward compatibility.
tabIndex={this.props.tabIndex}
{...this.props.inputProps}
onBlur={this.handleOnBlur}
value={this.state.value}
Expand All @@ -143,6 +147,10 @@ export default class EdiText extends Component {
ref={this.input}
className={styles.Editext__input}
editext={dataAttributes.input}
// this is here because,
// we still allow people to pass the tabIndex via inputProps
// also backward compatibility.
tabIndex={this.props.tabIndex}
{...this.props.inputProps}
onKeyDown={this.handleKeyDown}
onBlur={this.handleOnBlur}
Expand Down Expand Up @@ -272,7 +280,15 @@ export default class EdiText extends Component {
editext={dataAttributes.viewContainer}
>
{buttonsAlign === 'after' && (
<div {...viewProps} onClick={viewClickHandler} editext='view'>
<div
// this is here because,
// we still allow people to pass the tabIndex via inputProps
// also backward compatibility.
tabIndex={this.props.tabIndex}
{...viewProps}
onClick={viewClickHandler}
editext='view'
>
{this.state.value}
</div>
)}
Expand All @@ -288,6 +304,10 @@ export default class EdiText extends Component {
</div>
{buttonsAlign === 'before' && (
<div
// this is here because,
// we still allow people to pass the tabIndex via inputProps
// also backward compatibility.
tabIndex={this.props.tabIndex}
{...viewProps}
onClick={viewClickHandler}
editext={dataAttributes.viewContainer}
Expand Down Expand Up @@ -375,5 +395,10 @@ EdiText.propTypes = {
submitOnEnter: PropTypes.bool,
cancelOnEscape: PropTypes.bool,
cancelOnUnfocus: PropTypes.bool,
submitOnUnfocus: PropTypes.bool
submitOnUnfocus: PropTypes.bool,
// navigating between inputs via tabbing is common.
// And tabIndex will probably be same for both view and input props
// here we are adding a new prop just for this special case to save people
// from creating duplicate code for both `inputProps` and `viewProps`
tabIndex: PropTypes.any
}

0 comments on commit c2d7eb2

Please sign in to comment.