modularScale.js.flow 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // @flow
  2. import getValueAndUnit from './getValueAndUnit'
  3. import PolishedError from '../internalHelpers/_errors'
  4. import type { ModularScaleRatio } from '../types/modularScaleRatio'
  5. export const ratioNames = {
  6. minorSecond: 1.067,
  7. majorSecond: 1.125,
  8. minorThird: 1.2,
  9. majorThird: 1.25,
  10. perfectFourth: 1.333,
  11. augFourth: 1.414,
  12. perfectFifth: 1.5,
  13. minorSixth: 1.6,
  14. goldenSection: 1.618,
  15. majorSixth: 1.667,
  16. minorSeventh: 1.778,
  17. majorSeventh: 1.875,
  18. octave: 2,
  19. majorTenth: 2.5,
  20. majorEleventh: 2.667,
  21. majorTwelfth: 3,
  22. doubleOctave: 4,
  23. }
  24. function getRatio(ratioName: string): number {
  25. return ratioNames[ratioName]
  26. }
  27. /**
  28. * Establish consistent measurements and spacial relationships throughout your projects by incrementing an em or rem value up or down a defined scale. We provide a list of commonly used scales as pre-defined variables.
  29. * @example
  30. * // Styles as object usage
  31. * const styles = {
  32. * // Increment two steps up the default scale
  33. * 'fontSize': modularScale(2)
  34. * }
  35. *
  36. * // styled-components usage
  37. * const div = styled.div`
  38. * // Increment two steps up the default scale
  39. * fontSize: ${modularScale(2)}
  40. * `
  41. *
  42. * // CSS in JS Output
  43. *
  44. * element {
  45. * 'fontSize': '1.77689em'
  46. * }
  47. */
  48. export default function modularScale(
  49. steps: number,
  50. base?: number | string = '1em',
  51. ratio?: ModularScaleRatio = 1.333,
  52. ): string {
  53. if (typeof steps !== 'number') {
  54. throw new PolishedError(42)
  55. }
  56. if (typeof ratio === 'string' && !ratioNames[ratio]) {
  57. throw new PolishedError(43)
  58. }
  59. const [realBase, unit] = typeof base === 'string' ? getValueAndUnit(base) : [base, '']
  60. const realRatio = typeof ratio === 'string' ? getRatio(ratio) : ratio
  61. if (typeof realBase === 'string') {
  62. throw new PolishedError(44, base)
  63. }
  64. return `${realBase * realRatio ** steps}${unit || ''}`
  65. }