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

Enable flipping tools via standalone class #830

Merged
merged 15 commits into from
Jul 15, 2019
12 changes: 6 additions & 6 deletions dist/editor.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
### 2.16

- `Refactoring` — Constants of tools settings separated by internal and external to correspond API
- `Refactoring` — Created universal Flipper class that responses for navigation by keyboard inside of any Toolbars

### 2.15

Expand Down
79 changes: 0 additions & 79 deletions src/components/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,85 +519,6 @@ export default class Dom {
}, []);
}

/**
* Leafs nodes inside the target list from active element
*
* @param {HTMLElement[]} nodeList - target list of nodes
* @param {number} activeIndex — index of active node. By default it must be -1
* @param {string} direction - leaf direction. Can be 'left' or 'right'
* @param {string} activeCSSClass - css class that will be added
*
* @return {Number} index of active node
*/
public static leafNodesAndReturnIndex(
nodeList: HTMLElement[],
activeIndex: number,
direction: string,
activeCSSClass: string,
): number {
/**
* If activeButtonIndex === -1 then we have no chosen Tool in Toolbox
*/
if (activeIndex === -1) {
/**
* Normalize "previous" Tool index depending on direction.
* We need to do this to highlight "first" Tool correctly
*
* Order of Tools: [0] [1] ... [n - 1]
* [0 = n] because of: n % n = 0 % n
*
* Direction 'right': for [0] the [n - 1] is a previous index
* [n - 1] -> [0]
*
* Direction 'left': for [n - 1] the [0] is a previous index
* [n - 1] <- [0]
*
* @type {number}
*/
activeIndex = direction === 'right' ? -1 : 0;
} else {
/**
* If we have chosen Tool then remove highlighting
*/
nodeList[activeIndex].classList.remove(activeCSSClass);
}

/**
* Count index for next Tool
*/
if (direction === 'right') {
/**
* If we go right then choose next (+1) Tool
* @type {number}
*/
activeIndex = (activeIndex + 1) % nodeList.length;
} else {
/**
* If we go left then choose previous (-1) Tool
* Before counting module we need to add length before because of "The JavaScript Modulo Bug"
* @type {number}
*/
activeIndex = (nodeList.length + activeIndex - 1) % nodeList.length;
}

if (Dom.isNativeInput(nodeList[activeIndex])) {
/**
* Focus input
*/
nodeList[activeIndex].focus();
}

/**
* Highlight new chosen Tool
*/
nodeList[activeIndex].classList.add(activeCSSClass);

/**
* Return Active index
*/
return activeIndex;
}

/*
* Helper for get holder from {string} or return HTMLElement
* @param element
Expand Down
163 changes: 163 additions & 0 deletions src/components/domIterator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import Dom from './dom';

/**
* Iterator above passed Elements list.
* Each next or previous action adds provides CSS-class and sets cursor to this item
*/
export default class DomIterator {
/**
* This is a static property that defines iteration directions
* @type {{RIGHT: string, LEFT: string}}
*/
public static directions = {
RIGHT: 'right',
LEFT: 'left',
};

/**
* User-provided CSS-class name for focused button
*/
private focusedCssClass: string;

/**
* Focused button index.
* Default is -1 which means nothing is active
* @type {number}
*/
private cursor: number = -1;

/**
* Items to flip
*/
private items: HTMLElement[] = [];

/**
* @param {HTMLElement[]} nodeList — the list of iterable HTML-items
* @param {string} focusedCssClass - user-provided CSS-class that will be set in flipping process
*/
constructor(
nodeList: HTMLElement[],
focusedCssClass: string,
) {
this.items = nodeList;
this.focusedCssClass = focusedCssClass;
}

/**
* Returns Focused button Node
* @return {HTMLElement}
*/
public get currentItem(): HTMLElement {
if (this.cursor === -1) {
return null;
}

return this.items[this.cursor];
}

/**
* Sets items. Can be used when iterable items changed dynamically
* @param {HTMLElement[]} nodeList
*/
public setItems(nodeList: HTMLElement[]): void {
this.items = nodeList;
}

/**
* Sets cursor next to the current
*/
public next(): void {
this.cursor = this.leafNodesAndReturnIndex(DomIterator.directions.RIGHT);
}

/**
* Sets cursor before current
*/
public previous(): void {
this.cursor = this.leafNodesAndReturnIndex(DomIterator.directions.LEFT);
}

/**
* Sets cursor to the default position and removes CSS-class from previously focused item
*/
public dropCursor(): void {
if (this.cursor === -1) {
return;
}

this.items[this.cursor].classList.remove(this.focusedCssClass);
this.cursor = -1;
}

/**
* Leafs nodes inside the target list from active element
*
* @param {string} direction - leaf direction. Can be 'left' or 'right'
* @return {Number} index of focused node
*/
private leafNodesAndReturnIndex(direction: string): number {
let focusedButtonIndex = this.cursor;

/**
* If activeButtonIndex === -1 then we have no chosen Tool in Toolbox
*/
if (focusedButtonIndex === -1) {
/**
* Normalize "previous" Tool index depending on direction.
* We need to do this to highlight "first" Tool correctly
*
* Order of Tools: [0] [1] ... [n - 1]
* [0 = n] because of: n % n = 0 % n
*
* Direction 'right': for [0] the [n - 1] is a previous index
* [n - 1] -> [0]
*
* Direction 'left': for [n - 1] the [0] is a previous index
* [n - 1] <- [0]
*
* @type {number}
*/
focusedButtonIndex = direction === DomIterator.directions.RIGHT ? -1 : 0;
} else {
/**
* If we have chosen Tool then remove highlighting
*/
this.items[focusedButtonIndex].classList.remove(this.focusedCssClass);
}

/**
* Count index for next Tool
*/
if (direction === DomIterator.directions.RIGHT) {
/**
* If we go right then choose next (+1) Tool
* @type {number}
*/
focusedButtonIndex = (focusedButtonIndex + 1) % this.items.length;
} else {
/**
* If we go left then choose previous (-1) Tool
* Before counting module we need to add length before because of "The JavaScript Modulo Bug"
* @type {number}
*/
focusedButtonIndex = (this.items.length + focusedButtonIndex - 1) % this.items.length;
}

if (Dom.isNativeInput(this.items[focusedButtonIndex])) {
/**
* Focus input
*/
this.items[focusedButtonIndex].focus();
}

/**
* Highlight new chosen Tool
*/
this.items[focusedButtonIndex].classList.add(this.focusedCssClass);

/**
* Return focused button's index
*/
return focusedButtonIndex;
}
}
Loading