Skip to content

Commit

Permalink
cmin / cmax unit support
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeeCoder committed Feb 27, 2017
1 parent c6174a5 commit 7720a8a
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.1.0 (2017-02-27)

- cmin / cmax unit support

## 1.0.4 (2017-02-27)

- Fixed the aspect-ratio query
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": "@zeecoder/container-query",
"version": "1.0.4",
"version": "1.1.0",
"description": "A PostCSS plugin and Javascript runtime combination, which allows you to write @container queries in your CSS the same way you would write @media queries.",
"main": "index.js",
"author": "Viktor Hubert <[email protected]>",
Expand Down
2 changes: 2 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const HEIGHT_UNIT = 'ch';
export const WIDTH_UNIT = 'cw';
export const MIN_UNIT = 'cmin';
export const MAX_UNIT = 'cmax';
export const DEFINE_CONTAINER_NAME = 'define-container';
9 changes: 8 additions & 1 deletion src/postcss/isValueUsingContainerUnits.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
HEIGHT_UNIT,
WIDTH_UNIT,
MIN_UNIT,
MAX_UNIT,
} from '../constants';

/**
Expand All @@ -13,6 +15,7 @@ export default function isValueUsingContainerUnits (value) {
return false;
}

// Matching numbers followed by alphanumeric characters and %
const match = value.toLowerCase().match(/(\d+(\.\d+)?)([a-z%]+)/i);

if (match === null) {
Expand All @@ -24,9 +27,13 @@ export default function isValueUsingContainerUnits (value) {
return (
unit !== HEIGHT_UNIT &&
unit !== WIDTH_UNIT &&
unit !== MIN_UNIT &&
unit !== MAX_UNIT &&
(
unit.indexOf(HEIGHT_UNIT) === 0 ||
unit.indexOf(WIDTH_UNIT) === 0
unit.indexOf(WIDTH_UNIT) === 0 ||
unit.indexOf(MIN_UNIT) === 0 ||
unit.indexOf(MAX_UNIT) === 0
)
);
}
8 changes: 8 additions & 0 deletions src/postcss/isValueUsingContainerUnits.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
HEIGHT_UNIT,
WIDTH_UNIT,
MIN_UNIT,
MAX_UNIT,
} from '../constants';
import isValueUsingContainerUnits from './isValueUsingContainerUnits';

Expand All @@ -18,3 +20,9 @@ test('should report true for values using either or both container units', () =>
expect(isValueUsingContainerUnits(`42${WIDTH_UNIT}px`)).toBe(true);
expect(isValueUsingContainerUnits(`42${WIDTH_UNIT}px 42${HEIGHT_UNIT}px 42${WIDTH_UNIT}px`)).toBe(true);
});

test('should report cmin cmax units too', () => {
expect(isValueUsingContainerUnits(`42${MIN_UNIT}px`)).toBe(true);
expect(isValueUsingContainerUnits(`42${MAX_UNIT}px`)).toBe(true);
expect(isValueUsingContainerUnits(`42${MIN_UNIT}px 42${MAX_UNIT}px 42${MIN_UNIT}px`)).toBe(true);
});
4 changes: 2 additions & 2 deletions src/runtime/adjustValueObjectByContainerDimensions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import convertCompositValuesToPixel from './convertCompositValue';
import convertCompositValue from './convertCompositValue';

/**
* @param {ContainerDimensions} containerDimensions
Expand All @@ -20,7 +20,7 @@ export default function adjustValueObjectByContainerDimensions (containerDimensi
let values = Object.assign({}, valueDefinition);

for (let cssRule in values) {
values[cssRule] = convertCompositValuesToPixel(containerDimensions, values[cssRule]);
values[cssRule] = convertCompositValue(containerDimensions, values[cssRule]);
}

return values;
Expand Down
52 changes: 43 additions & 9 deletions src/runtime/convertSingleValue.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import {
HEIGHT_UNIT,
WIDTH_UNIT,
MIN_UNIT,
MAX_UNIT,
} from '../constants';

/**
* Normalise unit by removing height or width container unit from the
* beginning of the string.
* Normalise unit by removing the container unit from the beginning of the
* string.
* Ex: "chpx" => "px", "cwem" => "em", etc.
*
* @param {string} unit
*/
Expand All @@ -18,6 +21,14 @@ function normaliseUnit (unit) {
return unit.substr(WIDTH_UNIT.length);
}

if (unit.indexOf(MIN_UNIT) === 0) {
return unit.substr(MIN_UNIT.length);
}

if (unit.indexOf(MAX_UNIT) === 0) {
return unit.substr(MAX_UNIT.length);
}

return unit;
}

Expand All @@ -39,20 +50,43 @@ export default function convertSingleValue (dimensions, value) {
const num = match[1];
const unit = match[3];

if (unit === HEIGHT_UNIT || unit === WIDTH_UNIT) {
if (
unit === HEIGHT_UNIT ||
unit === WIDTH_UNIT ||
unit === MIN_UNIT ||
unit === MAX_UNIT
) {
return value;
}

const relativeToHeight = unit.indexOf(HEIGHT_UNIT) === 0;
const normalisedUnit = normaliseUnit(unit);

const relativeToHeight = (
unit.indexOf(HEIGHT_UNIT) === 0 ||
(
unit.indexOf(MIN_UNIT) === 0 &&
dimensions.height < dimensions.width
) ||
(
unit.indexOf(MAX_UNIT) === 0 &&
dimensions.height > dimensions.width
)
);
const relativeToWidth = (
unit.indexOf(WIDTH_UNIT) === 0 ||
(
unit.indexOf(MIN_UNIT) === 0 &&
dimensions.height >= dimensions.width
) ||
(
unit.indexOf(MAX_UNIT) === 0 &&
dimensions.height <= dimensions.width
)
);

if (relativeToHeight) {
return (dimensions.height * parseFloat(num) / 100) + normalisedUnit;
}

const relativeToWidth = unit.indexOf(WIDTH_UNIT) === 0;

if (relativeToWidth) {
} else if (relativeToWidth) {
return (dimensions.width * parseFloat(num) / 100) + normalisedUnit;
}

Expand Down
45 changes: 45 additions & 0 deletions src/runtime/convertSingleValue.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,49 @@ test('single container value should be properly converted to px', () => {
{ width: 1000 },
`55.5px`
)).toBe('55.5px');

expect(convertSingleValue(
{ width: 1200, height: 100 },
`1cminpx`
)).toBe('1px');

expect(convertSingleValue(
{ width: 1200, height: 120 },
`1cminpx`
)).toBe('1.2px');

expect(convertSingleValue(
{ width: 1200, height: 1200 },
`1cminpx`
)).toBe('12px');

expect(convertSingleValue(
{ width: 900, height: 1200 },
`1cminpx`
)).toBe('9px');

expect(convertSingleValue(
{ width: 900, height: 1200 },
`5cminem`
)).toBe('45em');

expect(convertSingleValue(
{ width: 900, height: 1200 },
`1cmaxpx`
)).toBe('12px');

expect(convertSingleValue(
{ width: 900, height: 1200 },
`2cmaxpx`
)).toBe('24px');

expect(convertSingleValue(
{ width: 100, height: 99 },
`1cmaxem`
)).toBe('1em');

expect(convertSingleValue(
{ width: 120, height: 99 },
`5cmaxem`
)).toBe('6em');
});

0 comments on commit 7720a8a

Please sign in to comment.