logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://anongit.hacktivis.me/git/pleroma-fe.git/

css_utils.js (4898B)


  1. import { convert } from 'chromatism'
  2. import { hex2rgb, rgba2css } from '../color_convert/color_convert.js'
  3. export const getCssColorString = (color, alpha = 1) => rgba2css({ ...convert(color).rgb, a: alpha })
  4. export const getCssShadow = (input, usesDropShadow) => {
  5. if (input.length === 0) {
  6. return 'none'
  7. }
  8. return input
  9. .filter(_ => usesDropShadow ? _.inset : _)
  10. .map((shad) => [
  11. shad.x,
  12. shad.y,
  13. shad.blur,
  14. shad.spread
  15. ].map(_ => _ + 'px ').concat([
  16. getCssColorString(shad.color, shad.alpha),
  17. shad.inset ? 'inset' : ''
  18. ]).join(' ')).join(', ')
  19. }
  20. export const getCssShadowFilter = (input) => {
  21. if (input.length === 0) {
  22. return 'none'
  23. }
  24. return input
  25. // drop-shadow doesn't support inset or spread
  26. .filter((shad) => !shad.inset && Number(shad.spread) === 0)
  27. .map((shad) => [
  28. shad.x,
  29. shad.y,
  30. // drop-shadow's blur is twice as strong compared to box-shadow
  31. shad.blur / 2
  32. ].map(_ => _ + 'px').concat([
  33. getCssColorString(shad.color, shad.alpha)
  34. ]).join(' '))
  35. .map(_ => `drop-shadow(${_})`)
  36. .join(' ')
  37. }
  38. // `debug` changes what backgrounds are used to "stacked" solid colors so you can see
  39. // what theme engine "thinks" is actual background color is for purposes of text color
  40. // generation and for when --stacked variable is used
  41. export const getCssRules = (rules, debug) => rules.map(rule => {
  42. let selector = rule.selector
  43. if (!selector) {
  44. selector = 'html'
  45. }
  46. const header = selector + ' {'
  47. const footer = '}'
  48. const virtualDirectives = Object.entries(rule.virtualDirectives || {}).map(([k, v]) => {
  49. return ' ' + k + ': ' + v
  50. }).join(';\n')
  51. const directives = Object.entries(rule.directives).map(([k, v]) => {
  52. switch (k) {
  53. case 'roundness': {
  54. return ' ' + [
  55. '--roundness: ' + v + 'px'
  56. ].join(';\n ')
  57. }
  58. case 'shadow': {
  59. if (!rule.dynamicVars.shadow) {
  60. return ''
  61. }
  62. return ' ' + [
  63. '--shadow: ' + getCssShadow(rule.dynamicVars.shadow),
  64. '--shadowFilter: ' + getCssShadowFilter(rule.dynamicVars.shadow),
  65. '--shadowInset: ' + getCssShadow(rule.dynamicVars.shadow, true)
  66. ].join(';\n ')
  67. }
  68. case 'background': {
  69. if (debug) {
  70. return `
  71. --background: ${getCssColorString(rule.dynamicVars.stacked)};
  72. background-color: ${getCssColorString(rule.dynamicVars.stacked)};
  73. `
  74. }
  75. if (v === 'transparent') {
  76. if (rule.component === 'Root') return null
  77. return [
  78. rule.directives.backgroundNoCssColor !== 'yes' ? ('background-color: ' + v) : '',
  79. ' --background: ' + v
  80. ].filter(x => x).join(';\n')
  81. }
  82. const color = getCssColorString(rule.dynamicVars.background, rule.directives.opacity)
  83. const cssDirectives = ['--background: ' + color]
  84. if (rule.directives.backgroundNoCssColor !== 'yes') {
  85. cssDirectives.push('background-color: ' + color)
  86. }
  87. return cssDirectives.filter(x => x).join(';\n')
  88. }
  89. case 'blur': {
  90. const cssDirectives = []
  91. if (rule.directives.opacity < 1) {
  92. cssDirectives.push(`--backdrop-filter: blur(${v}) `)
  93. if (rule.directives.backgroundNoCssColor !== 'yes') {
  94. cssDirectives.push(`backdrop-filter: blur(${v}) `)
  95. }
  96. }
  97. return cssDirectives.join(';\n')
  98. }
  99. case 'font': {
  100. return 'font-family: ' + v
  101. }
  102. case 'textColor': {
  103. if (rule.directives.textNoCssColor === 'yes') { return '' }
  104. return 'color: ' + v
  105. }
  106. default:
  107. if (k.startsWith('--')) {
  108. const [type, value] = v.split('|').map(x => x.trim())
  109. switch (type) {
  110. case 'color': {
  111. const color = rule.dynamicVars[k]
  112. if (typeof color === 'string') {
  113. return k + ': ' + rgba2css(hex2rgb(color))
  114. } else {
  115. return k + ': ' + rgba2css(color)
  116. }
  117. }
  118. case 'generic':
  119. return k + ': ' + value
  120. default:
  121. return null
  122. }
  123. }
  124. return null
  125. }
  126. }).filter(x => x).map(x => ' ' + x + ';').join('\n')
  127. return [
  128. header,
  129. directives,
  130. (rule.component === 'Text' && rule.state.indexOf('faint') < 0 && rule.directives.textNoCssColor !== 'yes') ? ' color: var(--text);' : '',
  131. virtualDirectives,
  132. footer
  133. ].filter(x => x).join('\n')
  134. }).filter(x => x)
  135. export const getScopedVersion = (rules, newScope) => {
  136. return rules.map(x => {
  137. if (x.startsWith('html')) {
  138. return x.replace('html', newScope)
  139. } else if (x.startsWith('#content')) {
  140. return x.replace('#content', newScope)
  141. } else {
  142. return newScope + ' > ' + x
  143. }
  144. })
  145. }