Skip to content

Commit

Permalink
feat(sdds-acore/theme-builder): Setup xml color attributes (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
raininforest authored and malilex committed Apr 25, 2024
1 parent 01e69d2 commit 5eb7613
Show file tree
Hide file tree
Showing 25 changed files with 440 additions and 40 deletions.
Binary file modified playground/theme-builder/json/plasma_b2c.zip
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ abstract class GenerateThemeTask : DefaultTask() {
@get:Input
abstract val resourcesPrefix: Property<String>

/**
* Префикс атрибутов родительской темы
*/
@get:Input
abstract val parentThemePrefix: Property<String>

/**
* Название родительской темы, от которой будет унаследована генерируемая тема
*/
@get:Input
abstract val parentThemeName: Property<String>

/**
* Целевой фреймворк
*/
Expand All @@ -117,21 +129,26 @@ abstract class GenerateThemeTask : DefaultTask() {
private val dimensAggregator by unsafeLazy { DimensAggregator() }
private val generatorFactory by unsafeLazy {
GeneratorFactory(
outputDir.get().asFile,
outputResDir.get().asFile,
target.get(),
dimensAggregator,
XmlResourcesDocumentBuilderFactory(resourcesPrefix.get()),
XmlFontFamilyDocumentBuilderFactory(),
FontDownloaderFactory(),
KtFileBuilderFactory(packageName.get()),
ResourceReferenceProvider(resourcesPrefix.get()),
namespace.get(),
resourcesPrefix.get(),
outputDir = outputDir.get().asFile,
outputResDir = outputResDir.get().asFile,
target = target.get(),
dimensAggregator = dimensAggregator,
xmlResourcesDocumentBuilderFactory = XmlResourcesDocumentBuilderFactory(resourcesPrefix.get()),
xmlFontFamilyDocumentBuilderFactory = XmlFontFamilyDocumentBuilderFactory(),
fontDownloaderFactory = FontDownloaderFactory(),
ktFileBuilderFactory = KtFileBuilderFactory(packageName.get()),
resourceReferenceProvider = ResourceReferenceProvider(resourcesPrefix.get()),
namespace = namespace.get(),
resPrefix = resourcesPrefix.get(),
parentThemeName = parentThemeName.get(),
parentThemePrefix = parentThemePrefix.get(),
)
}

private val colorGenerator by unsafeLazy { generatorFactory.createColorGenerator(colors) }
private val themeGenerator by unsafeLazy { generatorFactory.createThemeGenerator() }
private val colorGenerator by unsafeLazy {
generatorFactory.createColorGenerator(colors, themeGenerator)
}
private val gradientGenerator by unsafeLazy { generatorFactory.createGradientGenerator(gradients) }
private val fontGenerator by unsafeLazy { generatorFactory.createFontGenerator(fonts) }
private val typographyGenerator by unsafeLazy {
Expand Down Expand Up @@ -171,13 +188,16 @@ abstract class GenerateThemeTask : DefaultTask() {
shadowGenerator.generate()
dimensGenerator.generate()
fontGenerator.generate()

themeGenerator.generate()
}

private fun decodeBase(): Theme =
baseFile.get().asFile.decode<Theme>().also { logger.debug("decoded base $it") }

private val colors: Map<String, String> by unsafeLazy {
colorFile.get().asFile.decode<Map<String, String>>().also { logger.debug("decoded colors $it") }
colorFile.get().asFile.decode<Map<String, String>>()
.also { logger.debug("decoded colors $it") }
}

private val shapes: Map<String, ShapeTokenValue> by unsafeLazy {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,14 @@ interface ThemeBuilderExtension {
* Префикс для названий ресурсов токенов
*/
val resourcesPrefix: Property<String>

/**
* Префикс атрибутов родительской темы
*/
val parentThemePrefix: Property<String>

/**
* Название родительской темы, от которой будет унаследована генерируемая тема
*/
val parentThemeName: Property<String>
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class ThemeBuilderPlugin : Plugin<Project> {

project.afterEvaluate {
extension.resourcesPrefix.convention(project.getDefaultResourcePrefix())
extension.parentThemeName.convention(DEFAULT_PARENT_THEME_NAME)
extension.parentThemePrefix.convention(DEFAULT_PARENT_THEME_PREFIX)

val fetchThemeTask = registerThemeFetcher(
extension = extension,
themeOutput = themeOutputZip,
Expand Down Expand Up @@ -135,6 +138,8 @@ class ThemeBuilderPlugin : Plugin<Project> {
packageName.set(extension.packageName)
target.set(extension.target)
resourcesPrefix.set(extension.resourcesPrefix)
parentThemePrefix.set(extension.parentThemePrefix)
parentThemeName.set(extension.parentThemeName)
outputDir.set(project.layout.projectDirectory.dir(OUTPUT_PATH))
outputResDir.set(project.layout.projectDirectory.dir(OUTPUT_RESOURCE_PATH))
namespace.set(getProjectNameSpace())
Expand Down Expand Up @@ -170,5 +175,8 @@ class ThemeBuilderPlugin : Plugin<Project> {
private companion object {
const val OUTPUT_RESOURCE_PATH = "build/generated/theme-builder-res"
const val OUTPUT_PATH = "build/generated/theme-builder"

const val DEFAULT_PARENT_THEME_NAME = "Sdds.Theme"
const val DEFAULT_PARENT_THEME_PREFIX = "sdds"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ import org.w3c.dom.Element
*/
internal open class XmlResourcesDocumentBuilder(
private val tokenPrefix: String,
private val rootAttributes: Map<String, String>,
) : XmlBaseDocumentBuilder() {

override val rootContent: Element by unsafeLazy {
document.createElement("resources")
.apply { setAttribute("xmlns:tools", "http://schemas.android.com/tools") }
.apply {
rootAttributes.forEach {
setAttribute(it.key, it.value)
}
}
.also { document.appendChild(it) }
}

Expand Down Expand Up @@ -78,12 +83,18 @@ internal open class XmlResourcesDocumentBuilder(
/**
* Добавляет стиль с названием [styleName] в документ
* @param styleName название стиля
* @param styleParent наследуемый стиль
* @param content содержание стиля
*/
fun appendStyle(styleName: String, content: Element.() -> Unit = {}) {
fun appendStyle(
styleName: String,
styleParent: String? = null,
content: Element.() -> Unit = {},
) {
val nameAttr = styleName.withPrefixIfNeed(capitalizedPrefix, ".")
document.createElement("style").apply {
setAttribute("name", nameAttr)
styleParent?.let { setAttribute("parent", it) }
content(this)
rootContent.appendChild(this)
}
Expand Down Expand Up @@ -126,4 +137,8 @@ internal open class XmlResourcesDocumentBuilder(
*/
P("p"),
}

internal companion object {
val DEFAULT_ROOT_ATTRIBUTES = mapOf("xmlns:tools" to "http://schemas.android.com/tools")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import com.sdds.plugin.themebuilder.internal.generator.GradientGenerator
import com.sdds.plugin.themebuilder.internal.generator.ShadowGenerator
import com.sdds.plugin.themebuilder.internal.generator.ShapeGenerator
import com.sdds.plugin.themebuilder.internal.generator.TypographyGenerator
import com.sdds.plugin.themebuilder.internal.generator.theme.ThemeGenerator
import com.sdds.plugin.themebuilder.internal.token.FontTokenValue
import com.sdds.plugin.themebuilder.internal.token.GradientTokenValue
import com.sdds.plugin.themebuilder.internal.token.ShadowTokenValue
Expand Down Expand Up @@ -45,19 +46,41 @@ internal class GeneratorFactory(
private val resourceReferenceProvider: ResourceReferenceProvider,
private val namespace: String,
private val resPrefix: String,
private val parentThemeName: String,
private val parentThemePrefix: String,
) {

/**
* Создает генератор темы [ThemeGenerator]
*/
fun createThemeGenerator(): ThemeGenerator = ThemeGenerator(
xmlBuilderFactory = xmlResourcesDocumentBuilderFactory,
resourceReferenceProvider = resourceReferenceProvider,
target = target,
outputResDir = outputResDir,
parentThemeName = parentThemeName,
parentThemePrefix = parentThemePrefix,
)

/**
* Создает генератор цветов [ColorGenerator]
*
* @param colors словарь значений токенов цвета
* @param themeGenerator генератор темы
* @return [ColorGenerator] генератор токенов цвета
*/
fun createColorGenerator(colors: Map<String, String>): ColorGenerator {
fun createColorGenerator(
colors: Map<String, String>,
themeGenerator: ThemeGenerator,
): ColorGenerator {
return ColorGenerator(
OutputLocation.Directory(outputDir),
outputResDir,
target,
xmlResourcesDocumentBuilderFactory,
ktFileBuilderFactory,
colors,
outputLocation = OutputLocation.Directory(outputDir),
outputResDir = outputResDir,
target = target,
xmlBuilderFactory = xmlResourcesDocumentBuilderFactory,
ktFileBuilderFactory = ktFileBuilderFactory,
colorTokenValues = colors,
themeGenerator = themeGenerator,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ internal class XmlResourcesDocumentBuilderFactory(private val tokenPrefix: Strin

/**
* Создает [XmlResourcesDocumentBuilder]
*
* @param rootAttributes атрибуты корневого элемента документа
*/
fun create(): XmlResourcesDocumentBuilder = XmlResourcesDocumentBuilder(tokenPrefix)
fun create(rootAttributes: Map<String, String> = emptyMap()): XmlResourcesDocumentBuilder =
XmlResourcesDocumentBuilder(tokenPrefix, rootAttributes)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.sdds.plugin.themebuilder.internal.generator

import com.sdds.plugin.themebuilder.ThemeBuilderTarget
import com.sdds.plugin.themebuilder.internal.builder.KtFileBuilder
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.Companion.DEFAULT_ROOT_ATTRIBUTES
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.ElementName
import com.sdds.plugin.themebuilder.internal.factory.KtFileBuilderFactory
import com.sdds.plugin.themebuilder.internal.factory.XmlResourcesDocumentBuilderFactory
import com.sdds.plugin.themebuilder.internal.generator.theme.ThemeGenerator
import com.sdds.plugin.themebuilder.internal.token.ColorToken
import com.sdds.plugin.themebuilder.internal.utils.FileProvider.colorsXmlFile
import com.sdds.plugin.themebuilder.internal.utils.colorToArgbHex
Expand All @@ -18,6 +20,8 @@ import java.io.File
* @param target целевой фреймворк
* @param xmlBuilderFactory фабрика делегата построения xml файлов
* @param ktFileBuilderFactory фабрика делегата построения kt файлов
* @param colorTokenValues словарь значений токенов цвета
* @param themeGenerator генератор атрибутов темы
* @author Малышев Александр on 07.03.2024
*/
internal class ColorGenerator(
Expand All @@ -27,9 +31,10 @@ internal class ColorGenerator(
private val xmlBuilderFactory: XmlResourcesDocumentBuilderFactory,
private val ktFileBuilderFactory: KtFileBuilderFactory,
private val colorTokenValues: Map<String, String>,
private val themeGenerator: ThemeGenerator,
) : TokenGenerator<ColorToken>(target) {

private val xmlDocumentBuilder by unsafeLazy { xmlBuilderFactory.create() }
private val xmlDocumentBuilder by unsafeLazy { xmlBuilderFactory.create(DEFAULT_ROOT_ATTRIBUTES) }
private val ktFileBuilder by unsafeLazy { ktFileBuilderFactory.create("ColorTokens") }
private val lightBuilder by unsafeLazy { ktFileBuilder.rootObject("LightColorTokens") }
private val darkBuilder by unsafeLazy { ktFileBuilder.rootObject("DarkColorTokens") }
Expand All @@ -53,8 +58,20 @@ internal class ColorGenerator(
*/
override fun addViewSystemToken(token: ColorToken): Boolean {
val tokenValue = colorTokenValues[token.name] ?: return false
val themeMode = if (token.tags.contains("dark")) {
ThemeGenerator.ThemeMode.DARK
} else if (token.tags.contains("light")) {
ThemeGenerator.ThemeMode.LIGHT
} else {
return false
}
xmlDocumentBuilder.appendComment(token.description)
xmlDocumentBuilder.appendElement(ElementName.COLOR, token.xmlName, tokenValue)
themeGenerator.addXmlColorAttribute(
colorName = token.displayName,
colorTokenName = token.xmlName,
themeMode = themeMode,
)
return true
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sdds.plugin.themebuilder.internal.generator

import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.Companion.DEFAULT_ROOT_ATTRIBUTES
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.ElementName
import com.sdds.plugin.themebuilder.internal.dimens.DimenData
import com.sdds.plugin.themebuilder.internal.dimens.DimensAggregator
Expand All @@ -22,7 +23,9 @@ internal class DimenGenerator(
private val xmlBuilderFactory: XmlResourcesDocumentBuilderFactory,
) : BaseGenerator {

private val xmlResourcesDocumentBuilder: XmlResourcesDocumentBuilder by unsafeLazy { xmlBuilderFactory.create() }
private val xmlResourcesDocumentBuilder: XmlResourcesDocumentBuilder by unsafeLazy {
xmlBuilderFactory.create(DEFAULT_ROOT_ATTRIBUTES)
}

/**
* @see BaseGenerator.generate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.sdds.plugin.themebuilder.ThemeBuilderTarget
import com.sdds.plugin.themebuilder.internal.builder.KtFileBuilder
import com.sdds.plugin.themebuilder.internal.builder.KtFileBuilder.Companion.appendObject
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.Companion.DEFAULT_ROOT_ATTRIBUTES
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.ElementFormat
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.ElementName
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.ElementType
Expand Down Expand Up @@ -37,7 +38,7 @@ internal class GradientGenerator(
private val gradientTokenValues: Map<String, List<GradientTokenValue>>,
) : TokenGenerator<GradientToken>(target) {

private val xmlDocumentBuilder by unsafeLazy { xmlBuilderFactory.create() }
private val xmlDocumentBuilder by unsafeLazy { xmlBuilderFactory.create(DEFAULT_ROOT_ATTRIBUTES) }
private val ktFileBuilder by unsafeLazy { ktFileBuilderFactory.create("GradientTokens") }
private val lightBuilder by unsafeLazy { ktFileBuilder.rootObject("LightGradientTokens") }
private val darkBuilder by unsafeLazy { ktFileBuilder.rootObject("DarkGradientTokens") }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.sdds.plugin.themebuilder.internal.generator
import com.sdds.plugin.themebuilder.ThemeBuilderTarget
import com.sdds.plugin.themebuilder.internal.builder.KtFileBuilder
import com.sdds.plugin.themebuilder.internal.builder.KtFileBuilder.Companion.appendObject
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.Companion.DEFAULT_ROOT_ATTRIBUTES
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.ElementName
import com.sdds.plugin.themebuilder.internal.factory.KtFileBuilderFactory
import com.sdds.plugin.themebuilder.internal.factory.XmlResourcesDocumentBuilderFactory
Expand Down Expand Up @@ -30,7 +31,7 @@ internal class ShadowGenerator(
private val shadowTokenValues: Map<String, ShadowTokenValue>,
) : TokenGenerator<ShadowToken>(target) {

private val xmlDocumentBuilder by unsafeLazy { xmlBuilderFactory.create() }
private val xmlDocumentBuilder by unsafeLazy { xmlBuilderFactory.create(DEFAULT_ROOT_ATTRIBUTES) }
private val ktFileBuilder by unsafeLazy { ktFileBuilderFactory.create("ShadowTokens") }
private val rootShadows by unsafeLazy { ktFileBuilder.rootObject("ShadowTokens") }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.sdds.plugin.themebuilder.internal.generator

import com.sdds.plugin.themebuilder.ThemeBuilderTarget
import com.sdds.plugin.themebuilder.internal.builder.KtFileBuilder
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.Companion.DEFAULT_ROOT_ATTRIBUTES
import com.sdds.plugin.themebuilder.internal.builder.XmlResourcesDocumentBuilder.ElementName
import com.sdds.plugin.themebuilder.internal.dimens.DimenData
import com.sdds.plugin.themebuilder.internal.dimens.DimensAggregator
Expand Down Expand Up @@ -38,7 +39,7 @@ internal class ShapeGenerator(
private val shapeTokenValues: Map<String, ShapeTokenValue>,
) : TokenGenerator<ShapeToken>(target) {

private val xmlDocumentBuilder by unsafeLazy { xmlBuilderFactory.create() }
private val xmlDocumentBuilder by unsafeLazy { xmlBuilderFactory.create(DEFAULT_ROOT_ATTRIBUTES) }
private val ktFileBuilder by unsafeLazy { ktFileBuilderFactory.create("ShapeTokens") }
private val rootRoundShapes by unsafeLazy { ktFileBuilder.rootObject("RoundShapeTokens") }
private var needCreateStyle: Boolean = true
Expand All @@ -65,7 +66,8 @@ internal class ShapeGenerator(
* @see TokenGenerator.addViewSystemToken
*/
override fun addViewSystemToken(token: ShapeToken): Boolean = with(xmlDocumentBuilder) {
val roundedShapeTokenValue = shapeTokenValues[token.name] as? RoundedShapeTokenValue ?: return@with false
val roundedShapeTokenValue =
shapeTokenValues[token.name] as? RoundedShapeTokenValue ?: return@with false
val cornerSize = DimenData(
name = "${token.name.techToSnakeCase()}_corner_size",
value = roundedShapeTokenValue.cornerRadius,
Expand Down Expand Up @@ -95,14 +97,20 @@ internal class ShapeGenerator(
* @see TokenGenerator.addComposeToken
*/
override fun addComposeToken(token: ShapeToken): Boolean = with(ktFileBuilder) {
val roundedShapeTokenValue = shapeTokenValues[token.name] as? RoundedShapeTokenValue ?: return@with false
val roundedShapeTokenValue =
shapeTokenValues[token.name] as? RoundedShapeTokenValue ?: return@with false

val value = "${roundedShapeTokenValue.cornerRadius}.dp"
val initializer = KtFileBuilder.createConstructorCall(
"RoundedCornerShape",
"CornerSize($value)",
)
rootRoundShapes.appendProperty(token.ktName, KtFileBuilder.TypeRoundRectShape, initializer, token.description)
rootRoundShapes.appendProperty(
token.ktName,
KtFileBuilder.TypeRoundRectShape,
initializer,
token.description,
)
return@with true
}
}
Loading

0 comments on commit 5eb7613

Please sign in to comment.