提交 c7c7bde1 编写于 作者: K Kamran Ahmed

Add type definitions

上级 25d2d75a
......@@ -3,6 +3,7 @@
"version": "0.2.4",
"description": "A light-weight, no-dependency, vanilla JavaScript library to drive the user's focus across the page",
"main": "dist/driver.min.js",
"types": "types/index.d.ts",
"scripts": {
"start": "node server.js",
"build": "webpack --config webpack.config.prod.js"
......
......@@ -179,8 +179,6 @@ export default class Element {
/**
* Is called when the element is about to be highlighted
* i.e. either if overlay has started moving the highlight towards
* this element of has just decided to highlight it
*/
onHighlightStarted() {
if (this.options.onHighlightStarted) {
......
......@@ -39,21 +39,15 @@ export default class Stage extends Element {
}
}
removeNode() {
if (!this.node) {
return;
}
this.node.parentElement.removeChild(this.node);
}
/**
* Simply hides the stage
*/
hide() {
this.node.style.display = 'none';
if (!this.node || !this.node.parentElement) {
return;
}
this.removeNode();
this.node.parentElement.removeChild(this.node);
}
/**
......@@ -67,6 +61,10 @@ export default class Stage extends Element {
this.node.style.right = '';
}
/**
* Shows the stage at provided position
* @param {Position} position
*/
show(position) {
this.makeNode();
......
......@@ -60,6 +60,7 @@ export default class Driver {
/**
* Binds any DOM events listeners
* @todo: add throttling in all the listeners
* @private
*/
bind() {
this.window.addEventListener('resize', this.onResize, false);
......@@ -71,6 +72,7 @@ export default class Driver {
* Removes the popover if clicked outside the highlighted element
* or outside the
* @param e
* @private
*/
onClick(e) {
if (!this.isActivated || !this.hasHighlightedElement()) {
......@@ -105,9 +107,50 @@ export default class Driver {
}
}
/**
* Handler for the onResize DOM event
* Makes sure highlighted element stays at valid position
* @private
*/
onResize() {
if (!this.isActivated) {
return;
}
this.overlay.refresh();
}
/**
* Clears the overlay on escape key process
* @param event
* @private
*/
onKeyUp(event) {
if (!this.isActivated) {
return;
}
// If escape was pressed and it is allowed to click outside to close
if (event.keyCode === ESC_KEY_CODE && this.options.allowClose) {
this.reset();
return;
}
// Arrow keys to only perform if it is stepped introduction
if (this.steps.length !== 0) {
if (event.keyCode === RIGHT_KEY_CODE) {
this.moveNext();
} else if (event.keyCode === LEFT_KEY_CODE) {
this.movePrevious();
}
}
}
/**
* Moves to the previous step if possible
* otherwise resets the overlay
* @public
*/
movePrevious() {
this.currentStep -= 1;
......@@ -121,6 +164,7 @@ export default class Driver {
/**
* Moves to the next step if possible
* otherwise resets the overlay
* @public
*/
moveNext() {
this.currentStep += 1;
......@@ -133,6 +177,7 @@ export default class Driver {
/**
* @returns {boolean}
* @public
*/
hasNextStep() {
return !!this.steps[this.currentStep + 1];
......@@ -140,6 +185,7 @@ export default class Driver {
/**
* @returns {boolean}
* @public
*/
hasPreviousStep() {
return !!this.steps[this.currentStep - 1];
......@@ -147,6 +193,8 @@ export default class Driver {
/**
* Resets the steps if any and clears the overlay
* @param {boolean} immediate
* @public
*/
reset(immediate = false) {
this.currentStep = 0;
......@@ -157,6 +205,7 @@ export default class Driver {
/**
* Checks if there is any highlighted element or not
* @returns {boolean}
* @public
*/
hasHighlightedElement() {
const highlightedElement = this.overlay.getHighlightedElement();
......@@ -166,6 +215,7 @@ export default class Driver {
/**
* Gets the currently highlighted element in overlay
* @returns {Element}
* @public
*/
getHighlightedElement() {
return this.overlay.getHighlightedElement();
......@@ -174,51 +224,16 @@ export default class Driver {
/**
* Gets the element that was highlighted before currently highlighted element
* @returns {Element}
* @public
*/
getLastHighlightedElement() {
return this.overlay.getLastHighlightedElement();
}
/**
* Handler for the onResize DOM event
* Makes sure highlighted element stays at valid position
*/
onResize() {
if (!this.isActivated) {
return;
}
this.overlay.refresh();
}
/**
* Clears the overlay on escape key process
* @param event
*/
onKeyUp(event) {
if (!this.isActivated) {
return;
}
// If escape was pressed and it is allowed to click outside to close
if (event.keyCode === ESC_KEY_CODE && this.options.allowClose) {
this.reset();
return;
}
// Arrow keys to only perform if it is stepped introduction
if (this.steps.length !== 0) {
if (event.keyCode === RIGHT_KEY_CODE) {
this.moveNext();
} else if (event.keyCode === LEFT_KEY_CODE) {
this.movePrevious();
}
}
}
/**
* Defines steps to be highlighted
* @param {array} steps
* @public
*/
defineSteps(steps) {
this.steps = [];
......@@ -245,6 +260,7 @@ export default class Driver {
* @param allSteps List of all the steps
* @param index Index of the current step
* @returns {null|Element}
* @private
*/
prepareElementFromStep(currentStep, allSteps = [], index = 0) {
let querySelector = '';
......@@ -302,6 +318,7 @@ export default class Driver {
/**
* Initiates highlighting steps from first step
* @param {number} index at which highlight is to be started
* @public
*/
start(index = 0) {
if (!this.steps || this.steps.length === 0) {
......@@ -317,6 +334,7 @@ export default class Driver {
/**
* Highlights the given element
* @param {string|{element: string, popover: {}}} selector Query selector or a step definition
* @public
*/
highlight(selector) {
this.isActivated = true;
......
declare module 'driver.js' {
export class Driver {
/**
* Refers to the global document object
*/
private document: Document;
/**
* Refers to the global window object
*/
private window: Window;
/**
* If the driver is active or not
*/
public isActivated: boolean;
/**
* Refers to the array of steps to be presented if any
*/
private steps: Array<Driver.Step>;
/**
* Refers to step index that is currently active
*/
private currentStep: number;
/**
* Refers to the overlay for the screen
*/
private overlay: Driver.Overlay;
/**
* @param {DriverOptions} options
*/
public constructor(options?: Driver.DriverOptions);
/**
* Does the required bindings for DOM Events
*/
private bind();
/**
* Listener for the click event, to decide if
* to next/previous step, reset the overlay etc
* @param {Event} e
*/
private onClick(e: Event);
/**
* Refreshes the driver and resets the position for stage
* and popover on resizing the window
*/
private onResize();
/**
* Makes it operable with keyboard
* @param {Event} e
*/
private onKeyUp(e: Event);
/**
* Moves to the previous step if possible
* otherwise resets the overlay
*/
public movePrevious();
/**
* Moves to the next step if possible
* otherwise resets the overlay
*/
public moveNext();
/**
* Checks if can be moved to next step
* @return {boolean}
*/
public hasNextStep(): boolean;
/**
* Checks if can be moved to previous step
* @return {boolean}
*/
public hasPreviousStep(): boolean;
/**
* Resets the steps and clears the overlay
*/
public reset();
/**
* Checks if there is any highlighted element or not
* @return {boolean}
*/
public hasHighlightedElement(): boolean;
/**
* Gets the currently highlighted element if any
* @return {Driver.Element}
*/
public getHighlightedElement(): Driver.Element | null;
/**
* Gets the last highlighted element if any
* @return {Driver.Element}
*/
public getLastHighlightedElement(): Driver.Element | null;
/**
* Defines the steps to be used in multi-step driver
* @param {Array<Driver.Step>} steps
*/
public defineSteps(steps: Array<Driver.Step>);
/**
* Prepares {Driver.Element} from the given step definition
* @param {Driver.Step | string} step query selector or step definition for the step
* @param {Array<Driver.Step>} allSteps all the given steps
* @param {number} stepIndex array index for the current step
*/
private prepareElementFromStep(step: Driver.Step | string, allSteps: Array<Driver.Step>, stepIndex: number);
/**
* Starts presenting the set steps from the given index
* @param {number} index
*/
public start(index?: number);
/**
* Highlights the given element. Element can be a query selector or a step definition
* @param {string | Driver.Step} element
*/
public highlight(element: string | Driver.Step);
}
namespace Driver {
export interface Step {
/**
* Query selector representing the DOM Element
*/
element: string;
/**
* Color of stage when this step is active
* @default #ffffff
*/
stageBackground?: string;
/**
* Options representing popover for this step
*/
popover: Driver.PopoverOptions;
}
export class Element {
/**
* Refers to the DOM element that this class wraps
*/
private node: Node | HTMLElement;
/**
* Refers to the global Document object
*/
private document: Document;
/**
* Refers to the global window object
*/
private window: Window;
/**
* Options for this element
*/
private options: Driver.ElementOptions;
/**
* Refers to the overlay that wraps the body
*/
private overlay: Driver.Overlay;
/**
* Refers to the Popover object to be displayed against this element
*/
private popover: Driver.Popover;
/**
* Refers to the stage that will be displayed behind this element
*/
private stage: Driver.Stage;
/**
* @param {HTMLElement | Node} node
* @param {Driver.DriverOptions} options
* @param {Driver.Popover} popover
* @param {Driver.Stage} stage
* @param {Driver.Overlay} overlay
* @param {Window} window
* @param {Document} document
*/
constructor(node: HTMLElement | Node,
options: Driver.DriverOptions,
popover: Driver.Popover,
stage: Driver.Stage,
overlay: Driver.Overlay,
window: Window,
document: Document);
/**
* Gets the screen coordinates for the current DOM Element
* @return {Driver.ScreenCoordinates}
*/
public getScreenCoordinates(): Driver.ScreenCoordinates;
/**
* Checks if the give element is in view port or not
* @return {boolean}
*/
public isInView(): boolean;
/**
* Brings the current DOMElement in view
*/
public bringInView();
/**
* Gets the position of element on screen
* @return {Driver.Position}
*/
public getCalculatedPosition(): Driver.Position;
/**
* Manually scrolls to current element if scrollInToView is not supported
*/
private scrollManually();
/**
* Is called when the current element is deselected
* @param {boolean} hideStage
*/
private onDeselected(hideStage?: boolean = false);
/**
* Is called when element is about to be highlighted
*/
private onHighlightStarted();
/**
* Is called when element has been successfully highlighted
*/
private onHighlighted();
/**
* Shows the stage on the current element
*/
private showStage();
/**
* Hides the popover from the current element if visible
*/
private hidePopover();
/**
* Shows the popover on current element if possible
*/
private showPopover();
/**
* Gets the full page size
*/
private getFullPageSize(): Driver.ElementSize;
/**
* Checks if the current element is same as passed element
* @param {Driver.Element} element
*/
private isSame(element: Driver.Element);
/**
* Gets the node that this element refers to
* @return {Node | HTMLElement}
*/
public getNode(): Node | HTMLElement;
/**
* Gets the size of current element
* @return {Driver.ElementSize}
*/
public getSize(): Driver.ElementSize;
}
export class Overlay {
/**
* Options to modify the overlay behavior
*/
private options: Driver.DriverOptions;
/**
* Refers to currently highlighted element
*/
private highlightedElement: Driver.Element | null;
/**
* Refers to element highlighted before currently highlighted element
*/
private lastHighlightedElement: Driver.Element | null;
/**
* Refers to timeout handler used to animate while resetting
*/
private hideTimer: number | null;
/**
* Refers to global object Window
*/
private window: Window;
/**
* Refers to global object Document
*/
private document: Document;
/**
* Prepares the DOM element for overlay and appends to body
*/
private makeNode();
/**
* Highlights the given Element while resetting the existing one
* @param {Driver.Element} element
*/
public highlight(element: Driver.Element);
/**
* Shows the overlay while appending to body if it is not there already
*/
public show();
/**
* Gets the highlighted element in overlay if any
* @return {Driver.Element | null}
*/
public getHighlightedElement(): Driver.Element | null;
/**
* Gets the element highlighted before current element if any
* @return {Driver.Element | null}
*/
public getLastHighlightedElement(): Driver.Element | null;
/**
* Removes the overlay and deselects the highlighted element. Does that with animation
* by default or without animation if immediate is set to false
* @param {boolean} immediate
*/
public clear(immediate: boolean = false);
/**
* Removes the overlay node if it exists
*/
private removeNode();
/**
* Refreshes the overlay i.e. sets the size according to current window size
* And moves the highlight around if necessary
*/
public refresh();
}
export class Popover {
private node: Node | HTMLElement;
private tipNode: Node | HTMLElement;
private titleNode: Node | HTMLElement;
private descriptionNode: Node | HTMLElement;
private footerNode: Node | HTMLElement;
private nextBtnNode: Node | HTMLElement;
private prevBtnNode: Node | HTMLElement;
private closeBtnNode: Node | HTMLElement;
private window: Window;
private document: Document;
/**
* @param {Driver.PopoverOptions} options
* @param {Window} window
* @param {Document} document
*/
constructor(options: Driver.PopoverOptions,
window: Window,
document: Document);
/**
* Prepares the DOM element for popover and appends to the body
*/
private makeNode();
/**
* Hides the popover if visible
*/
public hide();
/**
* Sets the initial state for popover before changing position
*/
private setInitialState();
/**
* Shows the popover at the given position
* @param {Driver.Position} position
*/
public show(position: Driver.Position);
/**
* Renders the buttons in the footer of the popover
*/
private renderButtons();
/**
* Positions the popover to the left of the given element position
* @param {Driver.Position} position
*/
private positionOnLeft(position: Driver.Position);
/**
* Positions the popover to the right of the given element position
* @param {Driver.Position} position
*/
private positionOnRight(position: Driver.Position);
/**
* Positions the popover to the top of the given element position
* @param {Driver.Position} position
*/
private positionOnTop(position: Driver.Position);
/**
* Positions the popover to the bottom of the given element position
* @param {Driver.Position} position
*/
private positionOnBottom(position: Driver.Position);
/**
* Positions the popover automatically around the element position
* @param {Driver.Position} position
*/
private autoPosition(position: Driver.Position);
}
export class Stage extends Element {
private options: Driver.StageOptions;
private window: Window;
private document: Document;
/**
* @param {Driver.StageOptions} options
* @param {Window} window
* @param {Document} document
*/
constructor(options: Driver.StageOptions,
window: Window,
document: Document);
/**
* Prepares the node and appends to body if not there already
*/
private makeNode();
/**
* Hides the stage by removing the node
*/
public hide();
/**
* Sets the default properties on the node
*/
private setInitialStyle();
/**
* Shows the stage at provided position
* @param {Driver.Position} position
*/
public show(position: Driver.Position);
}
export class Position {
top: number;
left: number;
right: number;
bottom: number;
constructor({
left: number = 0,
top: number = 0,
bottom: number = 0,
right: number = 0,
} = {});
/**
* Checks if the given position is valid and can be highlighted
* @return {boolean}
*/
canHighlight(): boolean;
/**
* Checks if the given position is same as the passed position
* @param {Driver.Position} position
*/
equals(position: Driver.Position);
}
interface ScreenCoordinates {
x: number;
y: number;
}
interface ElementSize {
width: number;
height: number;
}
interface PopoverOptions {
/**
* Title for the popover
*/
title?: string;
/**
* Description for the popover
*/
description: string;
/**
* Whether to show control buttons or not
* @default true
*/
showButtons: boolean;
/**
* Text on the button in the final step
* @default 'Done'
*/
doneBtnText: string;
/**
* Text on the close button
* @default 'Close'
*/
closeBtnText: string;
/**
* Text on the next button
* @default 'Next'
*/
nextBtnText: string;
/**
* Text on the previous button
* @default 'Previous'
*/
prevBtnText: string;
}
interface DriverOptions {
/**
* Whether to animate while transitioning from one highlighted
* element to another
* @default true
*/
animate?: boolean;
/**
* Opacity for the overlay
* @default 0.75
*/
opacity?: number,
/**
* Distance of elements corner from the edges of the overlay
* @default 10
*/
padding?: number,
/**
* Options to be passed to scrollIntoView if supported by browser
* @default { behavior: 'instant', block: 'center' }
*/
scrollIntoViewOptions?: ScrollIntoViewOptions,
/**
* Clicking outside the highlighted element should reset driver or not
* @default true
*/
allowClose?: boolean,
/**
* Background color for the stage behind the highlighted element
* @default '#ffffff'
*/
stageBackground?: string,
/**
* Whether to show control buttons or not
* @default true
*/
showButtons: boolean;
/**
* Text on the button in the final step
* @default 'Done'
*/
doneBtnText: string;
/**
* Text on the close button
* @default 'Close'
*/
closeBtnText: string;
/**
* Text on the next button
* @default 'Next'
*/
nextBtnText: string;
/**
* Text on the previous button
* @default 'Previous'
*/
prevBtnText: string;
/**
* Callback to be called when element is about to be highlighted
* @param {Driver.Element} element
* @returns any
*/
onHighlightStarted: (element: Driver.Element) => void;
/**
* Callback to be called when element has been highlighted
* @param {Driver.Element} element
* @returns any
*/
onHighlighted: (element: Driver.Element) => void,
/**
* Callback to be called when element has been deselected
* @param {Driver.Element} element
* @returns any
*/
onDeselected: (element: Driver.Element) => void,
}
interface ElementOptions extends Driver.DriverOptions {
}
interface StageOptions extends ElementOptions {
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册