theme-color.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. let themeColors = {}
  2. //
  3. // Helper Functions
  4. //
  5. function lookupVariable(context, variableName) {
  6. const { frames, importantScope } = context
  7. return tree.Variable.prototype.find(frames, frame => {
  8. const { value, important } = frame.variable(variableName) || {}
  9. if (value === undefined)
  10. return
  11. if (important && importantScope[importantScope.length - 1])
  12. importantScope[importantScope.length - 1].important = important
  13. return value.eval(context)
  14. })
  15. }
  16. // @TODO: [@calvinjuarez] unify this function between files, maybe even canonize it as a
  17. // `Ruleset`/`DetachedRuleset` method at some point.
  18. function rulesetToMap(context, { ruleset: { rules } } = { ruleset: { rules: [] } }) {
  19. const map = {}
  20. rules.forEach(rule => {
  21. // Not exactly sure how to handle other types (or if they should be handled at all).
  22. if (! (rule instanceof tree.Declaration))
  23. return
  24. const { name: key, value } = rule.eval(context)
  25. map[key] = value
  26. })
  27. return map
  28. }
  29. //
  30. // Less Functions
  31. //
  32. functions.add('theme-color', function ({ value: colorName } = { value: 'primary' }) {
  33. // If `themeColors` hasn’t been defined yet, set it to the value of `@theme-colors`.
  34. if (Object.keys(themeColors).length === 0)
  35. themeColors = rulesetToMap(this.context, lookupVariable(this.context, '@theme-colors'))
  36. return themeColors[colorName]
  37. })