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

[tsc] Enable strict mode #39

Merged
merged 1 commit into from Dec 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
155 changes: 74 additions & 81 deletions src/Breakpoints.ts
@@ -1,5 +1,5 @@
import { MediaBreakpointProps } from "./Media"
import { propKey, createRuleSet, createClassName } from "./Utils"
import { createRuleSet, createClassName } from "./Utils"

/**
* A union of possible breakpoint props.
Expand Down Expand Up @@ -42,12 +42,12 @@ export class Breakpoints<B extends string> {
.map(breakpointAndValue => breakpointAndValue[0] as string)

// List of all possible and valid `between` combinations
const betweenCombinations: Tuple[] = this._sortedBreakpoints
const betweenCombinations = this._sortedBreakpoints
.slice(0, -1)
.reduce(
(acc, b1, i) => [
(acc: Tuple[], b1, i) => [
...acc,
...this._sortedBreakpoints.slice(i + 1).map(b2 => [b1, b2]),
...this._sortedBreakpoints.slice(i + 1).map(b2 => [b1, b2] as Tuple),
],
[]
)
Expand Down Expand Up @@ -119,65 +119,64 @@ export class Breakpoints<B extends string> {
}

public toRuleSets() {
return Object.entries(this._mediaQueries).reduce((acc, [type, queries]) => {
queries.forEach((query, breakpoint) => {
// We need to invert the query, such that it matches when we want the
// element to be hidden.
acc.push(
createRuleSet(
createClassName(type, breakpoint),
`not all and ${query}`
return Object.entries(this._mediaQueries).reduce(
(acc: string[], [type, queries]) => {
queries.forEach((query, breakpoint) => {
// We need to invert the query, such that it matches when we want the
// element to be hidden.
acc.push(
createRuleSet(
createClassName(type, breakpoint),
`not all and ${query}`
)
)
)
})
return acc
}, [])
})
return acc
},
[]
)
}

public shouldRenderMediaQuery(
breakpointProps: MediaBreakpointProps,
onlyRenderAt: string[]
): boolean {
breakpointProps = this._normalizeProps(breakpointProps)
switch (propKey(breakpointProps)) {
case "lessThan": {
const width = this._breakpoints[breakpointProps.lessThan]
const lowestAllowedWidth = Math.min(
...onlyRenderAt.map(breakpoint => this._breakpoints[breakpoint])
)
return lowestAllowedWidth < width
}
case "greaterThan": {
const width = this._breakpoints[
this._findNextBreakpoint(breakpointProps.greaterThan)
]
const highestAllowedWidth = Math.max(
...onlyRenderAt.map(breakpoint => this._breakpoints[breakpoint])
)
return highestAllowedWidth >= width
}
case "greaterThanOrEqual": {
const width = this._breakpoints[breakpointProps.greaterThanOrEqual]
const highestAllowedWidth = Math.max(
...onlyRenderAt.map(breakpoint => this._breakpoints[breakpoint])
)
return highestAllowedWidth >= width
}
case "between": {
// TODO: This is the only useful breakpoint to negate, but we’ll
// we’ll see when/if we need it. We could then also decide
// to add `oustide`.
const fromWidth = this._breakpoints[breakpointProps.between[0]]
const toWidth = this._breakpoints[breakpointProps.between[1]]
const allowedWidths = onlyRenderAt.map(
breakpoint => this._breakpoints[breakpoint]
)
return !(
Math.max(...allowedWidths) < fromWidth ||
Math.min(...allowedWidths) >= toWidth
)
}
if (breakpointProps.lessThan) {
const width = this._breakpoints[breakpointProps.lessThan]
const lowestAllowedWidth = Math.min(
...onlyRenderAt.map(breakpoint => this._breakpoints[breakpoint])
)
return lowestAllowedWidth < width
} else if (breakpointProps.greaterThan) {
const width = this._breakpoints[
this._findNextBreakpoint(breakpointProps.greaterThan)
]
const highestAllowedWidth = Math.max(
...onlyRenderAt.map(breakpoint => this._breakpoints[breakpoint])
)
return highestAllowedWidth >= width
} else if (breakpointProps.greaterThanOrEqual) {
const width = this._breakpoints[breakpointProps.greaterThanOrEqual]
const highestAllowedWidth = Math.max(
...onlyRenderAt.map(breakpoint => this._breakpoints[breakpoint])
)
return highestAllowedWidth >= width
} else if (breakpointProps.between) {
// TODO: This is the only useful breakpoint to negate, but we’ll
// we’ll see when/if we need it. We could then also decide
// to add `oustide`.
const fromWidth = this._breakpoints[breakpointProps.between[0]]
const toWidth = this._breakpoints[breakpointProps.between[1]]
const allowedWidths = onlyRenderAt.map(
breakpoint => this._breakpoints[breakpoint]
)
return !(
Math.max(...allowedWidths) < fromWidth ||
Math.min(...allowedWidths) >= toWidth
)
}
return false
}

public valuesWithBreakpointProps = <T>(
Expand Down Expand Up @@ -229,34 +228,28 @@ export class Breakpoints<B extends string> {
breakpointProps: MediaBreakpointProps
): string {
breakpointProps = this._normalizeProps(breakpointProps)
switch (propKey(breakpointProps)) {
case "lessThan": {
const width = this._breakpoints[breakpointProps.lessThan]
return `(max-width:${width - 1}px)`
}
case "greaterThan": {
const width = this._breakpoints[
this._findNextBreakpoint(breakpointProps.greaterThan)
]
return `(min-width:${width}px)`
}
case "greaterThanOrEqual": {
const width = this._breakpoints[breakpointProps.greaterThanOrEqual]
return `(min-width:${width}px)`
}
case "between": {
// TODO: This is the only useful breakpoint to negate, but we’ll
// we’ll see when/if we need it. We could then also decide
// to add `outside`.
const fromWidth = this._breakpoints[breakpointProps.between[0]]
const toWidth = this._breakpoints[breakpointProps.between[1]]
return `(min-width:${fromWidth}px) and (max-width:${toWidth - 1}px)`
}
default:
throw new Error(
`Unexpected breakpoint props: ${JSON.stringify(breakpointProps)}`
)
if (breakpointProps.lessThan) {
const width = this._breakpoints[breakpointProps.lessThan]
return `(max-width:${width - 1}px)`
} else if (breakpointProps.greaterThan) {
const width = this._breakpoints[
this._findNextBreakpoint(breakpointProps.greaterThan)
]
return `(min-width:${width}px)`
} else if (breakpointProps.greaterThanOrEqual) {
const width = this._breakpoints[breakpointProps.greaterThanOrEqual]
return `(min-width:${width}px)`
} else if (breakpointProps.between) {
// TODO: This is the only useful breakpoint to negate, but we’ll
// we’ll see when/if we need it. We could then also decide
// to add `outside`.
const fromWidth = this._breakpoints[breakpointProps.between[0]]
const toWidth = this._breakpoints[breakpointProps.between[1]]
return `(min-width:${fromWidth}px) and (max-width:${toWidth - 1}px)`
}
throw new Error(
`Unexpected breakpoint props: ${JSON.stringify(breakpointProps)}`
)
}

private _createBreakpointQueries(
Expand Down
8 changes: 4 additions & 4 deletions src/DynamicResponsive.tsx
Expand Up @@ -55,19 +55,19 @@ export function createResponsiveComponents<M extends string>() {
> {
constructor(props: ResponsiveProviderProps<M>) {
super(props)
let mediaQueryMatchers: MediaQueryMatchers
let mediaQueryMatchers: MediaQueryMatchers | undefined = undefined
let mediaQueryMatches: MediaQueryMatches

if (this.isSupportedEnvironment()) {
mediaQueryMatchers = this.setupMatchers(props.mediaQueries)
mediaQueryMatches = this.checkMatchers(mediaQueryMatchers)
} else {
mediaQueryMatches = Object.keys(props.mediaQueries).reduce(
(matches, key: M) => ({
(matches, key) => ({
...matches,
[key]:
!!props.initialMatchingMediaQueries &&
props.initialMatchingMediaQueries.includes(key),
props.initialMatchingMediaQueries.includes(key as M),
}),
{}
)
Expand Down Expand Up @@ -119,7 +119,7 @@ export function createResponsiveComponents<M extends string>() {
*/
mediaQueryStatusChangedCallback = () => {
const mediaQueryMatches = this.checkMatchers(
this.state.mediaQueryMatchers
this.state.mediaQueryMatchers!
)
this.setState({
mediaQueryMatches,
Expand Down
15 changes: 9 additions & 6 deletions src/Interactions.ts
Expand Up @@ -16,12 +16,15 @@ export class Interactions {
}

public toRuleSets() {
return Object.entries(this._interactions).reduce((acc, [name, query]) => {
return [
...acc,
createRuleSet(createClassName("interaction", name), query),
]
}, [])
return Object.entries(this._interactions).reduce(
(acc: string[], [name, query]) => {
return [
...acc,
createRuleSet(createClassName("interaction", name), query),
]
},
[]
)
}

public get interactions() {
Expand Down
7 changes: 5 additions & 2 deletions src/Media.tsx
Expand Up @@ -246,7 +246,10 @@ export interface CreateMediaResults<B, I> {
* Creates a list of your application’s breakpoints that support the given
* widths and everything in between.
*/
findBreakpointsForWidths(fromWidth: number, throughWidth: number): B[]
findBreakpointsForWidths(
fromWidth: number,
throughWidth: number
): B[] | undefined

/**
* Finds the breakpoint that matches the given width.
Expand Down Expand Up @@ -403,7 +406,7 @@ export function createMedia<
}

const type = propKey(breakpointProps)
const breakpoint = breakpointProps[type]
const breakpoint = breakpointProps[type]!
className = createClassName(type, breakpoint)
}

Expand Down
2 changes: 1 addition & 1 deletion src/Utils.ts
Expand Up @@ -35,7 +35,7 @@ export function createClassName(
return [
"rrm",
...components.reduce(
(acc, breakpoint) =>
(acc: string[], breakpoint) =>
Array.isArray(breakpoint)
? [...acc, ...breakpoint]
: [...acc, breakpoint],
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Expand Up @@ -15,7 +15,8 @@
"outDir": "dist",
"rootDir": "src",
"skipLibCheck": true,
"target": "es2015"
"target": "es2015",
"strict": true
},
"exclude": ["node_modules/*", "dist", "example", "src/**/__test__/*"]
}
5 changes: 3 additions & 2 deletions tslint.json
Expand Up @@ -6,7 +6,7 @@
"jsx-boolean-value": [true, "never"],
"jsx-no-lambda": false,
"jsx-no-bind": false,
"max-classes-per-file": [false],
"max-classes-per-file": false,
"member-access": [false],
"member-ordering": false,
"no-console": [true, "log", "error"],
Expand All @@ -25,6 +25,7 @@
"types": { "visibilities": ["exported"] },
"variables": { "visibilities": ["exported"] }
}
]
],
"no-unnecessary-initializer": false
}
}