Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

feat(pxToRem): remove global overrides for document styles #789

Merged
merged 13 commits into from
Jan 30, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

### Features
- Export `triangle-down` and `triangle-right` icons in Teams theme @codepretty ([#785](https://github.com/stardust-ui/react/pull/785))
- Add rtl examples for `Button` and `Divider` components @mnajdova ([#792](https://github.com/stardust-ui/react/pull/792))
- Add mechanism for marking icons that should rotate in rtl in Teams theme; marked icons: `send`, `bullets`, `leave`, `outdent`, `redo`, `undo`, `send` @mnajdova ([#788](https://github.com/stardust-ui/react/pull/788))
- Add RTL examples for `Button` and `Divider` components @mnajdova ([#792](https://github.com/stardust-ui/react/pull/792))
- Add mechanism for marking icons that should rotate in RTL in Teams theme; marked icons: `send`, `bullets`, `leave`, `outdent`, `redo`, `undo`, `send` @mnajdova ([#788](https://github.com/stardust-ui/react/pull/788))
- Remove ability to introduce global style overrides for HTML document from `pxToRem` @kuzhelov ([#789](https://github.com/stardust-ui/react/pull/789))

### Fixes
- Handle `onClick` and `onFocus` on ListItems correctly @layershifter ([#779](https://github.com/stardust-ui/react/pull/779))
Expand Down
66 changes: 17 additions & 49 deletions src/lib/fontSizeUtility.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import * as _ from 'lodash'
import isBrowser from './isBrowser'

const DEFAULT_FONT_SIZE_IN_PX = 16
const DEFAULT_REM_SIZE_IN_PX = 10
let _htmlFontSizeInPx: number | null = null
const DEFAULT_REM_SIZE_IN_PX = 16

const getComputedFontSize = (): number => {
let _documentRemSize: number | null = null

const getDocumentRemSize = (): number => {
return isBrowser()
? getFontSizeValue(getComputedStyle(document.documentElement).fontSize) ||
DEFAULT_REM_SIZE_IN_PX
: DEFAULT_FONT_SIZE_IN_PX
: DEFAULT_REM_SIZE_IN_PX
}

const getFontSizeValue = (size?: string | null): number | null => {
Expand All @@ -19,55 +19,23 @@ const getFontSizeValue = (size?: string | null): number | null => {
/**
* Converts the provided px size to rem based on the default font size of 10px unless
* the HTML font size has been previously defined with setHTMLFontSize().
* @param {number} value The px value to convert to rem.
* @param {number} valueInPx - The px value to convert to rem.
* @param {number} baseRemSize - Rem size to use for convertions. Optional - document's font size will be taken otherwise.
* @example
* // Returns '1rem'
* pxToRem(10)
* // Returns '1rem' for default document font size (16px).
* pxToRem(16)
*
* // Returns '2rem'.
* pxToRem(32, 16)
* @returns {string} The value converted to the rem.
*/
export const pxToRem = (value: number = 0): string => {
if (!_htmlFontSizeInPx) {
_htmlFontSizeInPx = getComputedFontSize()
export const pxToRem = (valueInPx: number, baseRemSize?: number): string => {
if (!baseRemSize && !_documentRemSize) {
_documentRemSize = getDocumentRemSize()
}

if (process.env.NODE_ENV !== 'production') {
if (value < 0) {
throw new Error(`Invalid value of: '${value}'.`)
}
}
const convertedValueInRems = value / _htmlFontSizeInPx
const remSize = baseRemSize || _documentRemSize || DEFAULT_REM_SIZE_IN_PX
const convertedValueInRems = valueInPx / remSize

return `${_.round(convertedValueInRems, 4)}rem`
}

/**
* Sets the HTML font size for use for px to rem conversion.
* Providing null for fontSize will get the computed font size based on the document, or set it to DEFAULT_REM_SIZE_IN_PX.
* @param {string} [fontSize] The font size in px, to set as the HTML font size in the fontSizeUtility.
* @example
* // Sets the HTML font size to 10px.
* setHTMLFontSize('10px')
* @example
* // Sets the HTML font size based on document.fontSize.
* setHTMLFontSize()
*/
export const setHTMLFontSize = (fontSize?: string): void => {
if (!fontSize) {
throw new Error('fontSize is not defined')
}

const htmlFontSizeValue = getFontSizeValue(fontSize) || 0
const htmlFontSizeUnit = fontSize.replace(htmlFontSizeValue.toString(), '')

if (process.env.NODE_ENV !== 'production') {
if (htmlFontSizeValue <= 0) {
throw new Error(`Invalid htmlFontSizeValue of: '${htmlFontSizeValue}'.`)
}

if (htmlFontSizeUnit !== 'px') {
throw new Error(`Expected htmlFontSize to be in px, but got: '${htmlFontSizeUnit}'.`)
}
}

_htmlFontSizeInPx = htmlFontSizeValue || getComputedFontSize()
}
2 changes: 1 addition & 1 deletion src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export { default as isBrowser } from './isBrowser'
export { default as doesNodeContainClick } from './doesNodeContainClick'
export { default as leven } from './leven'

export { pxToRem, setHTMLFontSize } from './fontSizeUtility'
export { pxToRem } from './fontSizeUtility'
export { customPropTypes }
export { default as createAnimationStyles } from './createAnimationStyles'
export { default as createComponent } from './createStardustComponent'
Expand Down
37 changes: 8 additions & 29 deletions test/specs/lib/fontSizeUtility-test.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,29 @@
import { pxToRem, setHTMLFontSize } from 'src/lib'
import { pxToRem } from 'src/lib'

describe('fontSizeUtility', () => {
describe('pxToRem', () => {
it('returns 1rem for 10px with a default HTML font size of 10px.', () => {
expect(pxToRem(10)).toEqual('1rem')
})

it('should throw error when called with a negative number.', () => {
expect(() => pxToRem(-1)).toThrowError()
it('returns 1rem for 16px with a default HTML font size of 16px.', () => {
expect(pxToRem(16)).toEqual('1rem')
})

it('returns 1rem with base font size of 10px.', () => {
setHTMLFontSize('10px')
expect(pxToRem(10)).toEqual('1rem')
expect(pxToRem(10, 10)).toEqual('1rem')
})

it('returns 0.714rem with a base font size of 14px.', () => {
setHTMLFontSize('14px')

expect(pxToRem(10)).toEqual('0.7143rem')
expect(pxToRem(10, 14)).toEqual('0.7143rem')
})

it('returns 1.25rem with a base font size of 8px.', () => {
setHTMLFontSize('8px')

expect(pxToRem(10)).toEqual('1.25rem')
})

it('returns 0rem when pxToRem is called without a value.', () => {
expect(pxToRem()).toEqual('0rem')
expect(pxToRem(10, 8)).toEqual('1.25rem')
})

it('returns 0rem when pxToRem is called with 0.', () => {
expect(pxToRem(0)).toEqual('0rem')
})
})

describe('setHTMLFontSize', () => {
it('throws when htmlFontSize is in rems.', () => {
expect(() => setHTMLFontSize('8rem')).toThrowError()
})

it('throws when htmlFontSize is <= 0px.', () => {
expect(() => setHTMLFontSize('0px')).toThrowError()

expect(() => setHTMLFontSize('-1px')).toThrowError()
it('should handle negative input values and return negative conversion result.', () => {
expect(pxToRem(-16, 16)).toEqual('-1rem')
})
})
})