Skip to content

Commit 7f9eb8c

Browse files
committed
normalizeQuery: Parses query into a workable object
1 parent 30aee7f commit 7f9eb8c

File tree

4 files changed

+87
-45
lines changed

4 files changed

+87
-45
lines changed
Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
1-
import {
2-
Numeric,
3-
Breakpoint,
4-
BreakpointBehavior,
5-
} from '../../../const/defaultOptions'
1+
import { Breakpoint, BreakpointBehavior } from '../../../const/defaultOptions'
62
import transformNumeric from '../../math/transformNumeric'
7-
import normalizeQuery from '../../styles/normalizeQuery'
3+
import normalizeQuery, {
4+
NormalizedQueryParam,
5+
} from '../../styles/normalizeQuery'
86
import compose from '../../functions/compose'
97

10-
type MediaQueryPair = [string, Numeric]
11-
128
/**
139
* Determines whether a given media query param should be added
1410
* to the media query string based on a breakpoint's behavior.
1511
*/
1612
const shouldAppendProperty = (
17-
queryParam: string,
13+
queryParam: NormalizedQueryParam,
1814
behavior: BreakpointBehavior,
1915
): boolean => {
20-
const [prefix, splitPropName] = queryParam.split('-')
21-
const isDimensionalProp = ['height', 'width'].includes(splitPropName)
16+
const { prefix, name } = queryParam
17+
const isDimensionalProp = ['height', 'width'].includes(name)
2218

2319
if (!isDimensionalProp) {
2420
return true
@@ -31,31 +27,45 @@ const shouldAppendProperty = (
3127
}
3228

3329
const filterRelevantQueryParams = (behavior: BreakpointBehavior) => (
34-
queryList: MediaQueryPair[],
35-
): MediaQueryPair[] => {
36-
return queryList.filter(([queryParam]) =>
37-
shouldAppendProperty(queryParam, behavior),
30+
queryList: NormalizedQueryParam[],
31+
): NormalizedQueryParam[] => {
32+
return queryList.filter((normalizedQueryParam) =>
33+
shouldAppendProperty(normalizedQueryParam, behavior),
3834
)
3935
}
4036

4137
/**
4238
* Joins a given media query params list with the given transformer function.
4339
*/
44-
export const joinQueryList = (transformer: (pair: MediaQueryPair) => any) => (
45-
queryList: MediaQueryPair[],
40+
export const joinQueryList = (
41+
queryList: NormalizedQueryParam[],
42+
transformer: (pair: NormalizedQueryParam) => any,
4643
) => {
4744
return queryList.map(transformer).join(' and ')
4845
}
4946

50-
export default function createMediaQuery(
47+
export const createQueryList = (
5148
breakpoint: Breakpoint,
5249
behavior: BreakpointBehavior,
53-
): string {
50+
): NormalizedQueryParam[] => {
5451
return compose(
55-
joinQueryList(([dashedQueryProp, propValue]) => {
56-
return `(${dashedQueryProp}:${String(transformNumeric(propValue))})`
57-
}),
5852
filterRelevantQueryParams(behavior),
5953
normalizeQuery,
6054
)(breakpoint)
6155
}
56+
57+
export default function createMediaQuery(
58+
breakpoint: Breakpoint,
59+
behavior: BreakpointBehavior,
60+
): string {
61+
const queryList = createQueryList(breakpoint, behavior)
62+
63+
const mediaQueryString = joinQueryList(
64+
queryList,
65+
({ displayName, value }) => {
66+
return `(${displayName}:${String(transformNumeric(value))})`
67+
},
68+
)
69+
70+
return mediaQueryString
71+
}

packages/atomic-layout-core/src/utils/styles/normalizeQuery/normalizeQuery.spec.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,33 @@ import normalizeQuery from './normalizeQuery'
22

33
describe('normalizeQuery', () => {
44
describe('given a media query Object', () => {
5-
it('returns its [key, value] pairs', () => {
5+
it('returns its { prefix, name, value } data', () => {
66
expect(
77
normalizeQuery({
8+
height: 100,
89
minWidth: 120,
910
maxAspectRatio: '3/4',
1011
}),
11-
).toEqual([['min-width', 120], ['max-aspect-ratio', '3/4']])
12+
).toEqual([
13+
{
14+
prefix: undefined,
15+
name: 'height',
16+
displayName: 'height',
17+
value: 100,
18+
},
19+
{
20+
prefix: 'min',
21+
name: 'width',
22+
displayName: 'min-width',
23+
value: 120,
24+
},
25+
{
26+
prefix: 'max',
27+
name: 'aspectRatio',
28+
displayName: 'max-aspect-ratio',
29+
value: '3/4',
30+
},
31+
])
1232
})
1333
})
1434
})
Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
import { Numeric, Breakpoint } from '../../../const/defaultOptions'
22
import isset from '../../functions/isset'
33
import toDashedString from '../../strings/toDashedString'
4+
import toLowerCaseFirst from '../../strings/toLowerCaseFirst'
5+
6+
export interface NormalizedQueryParam {
7+
prefix: string
8+
name: string
9+
displayName: string
10+
value: Numeric
11+
}
412

513
/**
614
* Normalizes given media query object to a list of [propName, propValue].
7-
* @example
8-
* normalizeQuery({ minWidth: 120 })
9-
* // [['min-width', 120]]
1015
*/
1116
export default function normalizeQuery(
12-
queryProps: Breakpoint,
13-
): Array<[string, Numeric]> {
14-
return Object.entries<Numeric>(queryProps)
15-
.filter(([_, propValue]) => isset(propValue))
16-
.map<[string, Numeric]>(([propName, propValue]) => [
17-
toDashedString(propName),
18-
propValue,
19-
])
17+
breakpoint: Breakpoint,
18+
): NormalizedQueryParam[] {
19+
return Object.entries<Numeric>(breakpoint)
20+
.filter(([_, value]) => isset(value))
21+
.map(([propName, value]) => {
22+
const [_, prefix, restName] = propName.match(/(min|max)?(.+)/)
23+
const normalizedName = toLowerCaseFirst(restName)
24+
const displayName = [prefix, toDashedString(normalizedName)]
25+
.filter(Boolean)
26+
.join('-')
27+
28+
return { prefix, name: normalizedName, displayName, value }
29+
})
2030
}

packages/atomic-layout/src/hooks/useMediaQuery.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { useState, useMemo, useEffect, useLayoutEffect } from 'react'
22
import {
33
MediaQuery as MediaQueryParams,
4-
compose,
54
joinQueryList,
65
normalizeQuery,
76
transformNumeric,
@@ -11,8 +10,10 @@ import {
1110
* Creates a media querty string based on the given params.
1211
*/
1312
export const createMediaQuery = (queryParams: MediaQueryParams): string => {
14-
return compose(
15-
joinQueryList(([paramName, paramValue]) => {
13+
const queryList = normalizeQuery(queryParams)
14+
const mediaQueryString = joinQueryList(
15+
queryList,
16+
({ displayName, value }) => {
1617
/**
1718
* Transform values that begin with a number to prevent
1819
* transformations of "calc" expressions.
@@ -21,14 +22,15 @@ export const createMediaQuery = (queryParams: MediaQueryParams): string => {
2122
*
2223
* (min-width: 750) ==> (min-width: 750px)
2324
*/
24-
const resolvedParamValue = /^\d/.test(String(paramValue))
25-
? transformNumeric(paramValue)
26-
: paramValue
25+
const resolvedParamValue = /^\d/.test(String(value))
26+
? transformNumeric(value)
27+
: value
2728

28-
return `(${paramName}:${resolvedParamValue})`
29-
}),
30-
normalizeQuery,
31-
)(queryParams)
29+
return `(${displayName}:${resolvedParamValue})`
30+
},
31+
)
32+
33+
return mediaQueryString
3234
}
3335

3436
type UseMediaQuery = (

0 commit comments

Comments
 (0)