Skip to content

Commit

Permalink
Improved typings
Browse files Browse the repository at this point in the history
  • Loading branch information
squidfunk committed Mar 26, 2018
1 parent 0a5ba9b commit 2dcdca2
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 16 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
karma-viewport-1.0.1 (2018-03-27)

* Improved typings

karma-viewport-1.0.0 (2018-03-26)

* Refactored complete code base into TypeScript
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "karma-viewport",
"version": "1.0.0",
"version": "1.0.1",
"description": "A Karma plugin for testing responsive layouts",
"keywords": [
"breakpoint",
Expand Down
55 changes: 40 additions & 15 deletions src/adapter/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export interface ViewportConfiguration {
/**
* Viewport callback
*/
export type ViewportCallback = (breakpoint: string) => Promise<any> | any
export type ViewportCallback<T> = (breakpoint: string) => T

/**
* Extend window element with missing types
Expand All @@ -75,8 +75,7 @@ declare global {
* @return Selected breakpoints
*/
export function range(
breakpoints: ViewportBreakpoint[],
first: string, last: string = first
breakpoints: ViewportBreakpoint[], first: string, last: string = first
) {
const [from, to] = [first, last].map(name => {
const index = breakpoints.findIndex(
Expand All @@ -90,6 +89,17 @@ export function range(
return breakpoints.slice(from, to + 1)
}

/**
* Type guard for Promise
*
* @param value - Value to be checked
*
* @return Whether the value is a Promise
*/
function isPromise(value: any): value is Promise<any> {
return Promise.resolve(value) === value
}

/* ----------------------------------------------------------------------------
* Class
* ------------------------------------------------------------------------- */
Expand All @@ -99,7 +109,7 @@ export class Viewport {
/**
* Viewport configuration
*/
public config: ViewportConfiguration
public config: Readonly<ViewportConfiguration>

/**
* Viewport context
Expand Down Expand Up @@ -165,6 +175,7 @@ export class Viewport {
* Set viewport to width (and height) or breakpoint name
*
* @param widthOrBreakpoint - Width in pixels or breakpoint name
* @param height - Height in pixels
*/
public set(width: number, height?: number): void
public set(breakpoint: string): void
Expand All @@ -177,13 +188,14 @@ export class Viewport {

/* Set viewport width (and height) */
} else {
if (typeof widthOrBreakpoint !== "number" || widthOrBreakpoint <= 0)
throw new TypeError(`Invalid breakpoint width: ${widthOrBreakpoint}`)
const width = widthOrBreakpoint
if (typeof width !== "number" || width <= 0)
throw new TypeError(`Invalid breakpoint width: ${width}`)
if (height && (typeof height !== "number" || height <= 0))
throw new TypeError(`Invalid breakpoint height: ${height}`)

/* Set width and height */
this.context.style.width = `${widthOrBreakpoint}px`
this.context.style.width = `${width}px`
if (height)
this.context.style.height = `${height}px`
}
Expand Down Expand Up @@ -219,9 +231,12 @@ export class Viewport {
* @param {string} last - Last breakpoint name
* @param {Function} cb - Callback to execute after resizing
*/
public between(
first: string, last: string,
cb: ViewportCallback
public between<T extends Promise<any>>(
first: string, last: string, cb: ViewportCallback<T>
): Promise<void>
public between<T>(first: string, last: string, cb: ViewportCallback<T>): void
public between<T>(
first: string, last: string, cb: ViewportCallback<T>
): void | Promise<void> {
const [initial, ...rest] = range(this.config.breakpoints, first, last)

Expand All @@ -234,11 +249,11 @@ export class Viewport {
/* Execute the first callback and check if it returns a Promise, as we
need to make sure that everything is executed sequentially */
const result = invoke(initial)
if (Promise.resolve(result) === result)
if (isPromise(result))
return rest

/* Resolve breakpoints and execute callback after resizing */
.reduce<Promise<any>>((promise, breakpoint) => {
.reduce((promise: Promise<any>, breakpoint) => {
return promise.then(() => breakpoint).then(invoke)
}, result)

Expand All @@ -262,7 +277,9 @@ export class Viewport {
*
* @return Promise resolving with no result
*/
public each(cb: ViewportCallback) {
public each<T extends Promise<any>>(cb: ViewportCallback<T>): Promise<void>
public each<T>(cb: ViewportCallback<T>): void
public each<T>(cb: ViewportCallback<T>): void | Promise<void> {
return this.between(this.config.breakpoints[0].name,
this.config.breakpoints[this.config.breakpoints.length - 1].name, cb)
}
Expand All @@ -280,7 +297,11 @@ export class Viewport {
*
* @return Promise resolving with no result
*/
public from(first: string, cb: ViewportCallback) {
public from<T extends Promise<any>>(
first: string, cb: ViewportCallback<T>
): Promise<void>
public from<T>(first: string, cb: ViewportCallback<T>): void
public from<T>(first: string, cb: ViewportCallback<T>): void | Promise<void> {
return this.between(first,
this.config.breakpoints[this.config.breakpoints.length - 1].name, cb)
}
Expand All @@ -298,7 +319,11 @@ export class Viewport {
*
* @return Promise resolving with no result
*/
public to(last: string, cb: ViewportCallback) {
public to<T extends Promise<any>>(
last: string, cb: ViewportCallback<T>
): Promise<void>
public to<T>(last: string, cb: ViewportCallback<T>): void
public to<T>(last: string, cb: ViewportCallback<T>): void | Promise<void> {
return this.between(this.config.breakpoints[0].name, last, cb)
}
}
1 change: 1 addition & 0 deletions webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export default (env?: { prod?: boolean }) => {
compilerOptions: {
declaration: true,
declarationDir: "..",
removeComments: false,
target: "es2015" /* Use ES modules for tree-shaking */
}
}
Expand Down

0 comments on commit 2dcdca2

Please sign in to comment.