From ffd452b0d4d81bf5f2916c6bac1d504d82505537 Mon Sep 17 00:00:00 2001 From: Dan Rader Date: Wed, 10 Aug 2022 17:07:05 -0400 Subject: [PATCH 1/4] Initial commit for Additional Theming Variables This addition is meant to add a layer of theming into Apollo without disrupting current Apollo implementation. Theme variables are meant to be updated at the base values (50-1000) and the semantically named colors will update automatically. This is also meant to work in conjunction with luminosity testing to identify colors for text on colors that provide sufficient contrast See a demo for the colors in use here: https://codepen.io/burnt-rocket/pen/bGvjJxW?editors=1100 --- config.json | 69 +++++++++++++++++++++++++++++++++++++++-- tokens/color/text.json | 4 +-- tokens/color/theme.json | 65 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 tokens/color/theme.json diff --git a/config.json b/config.json index df2e808..3866dfe 100644 --- a/config.json +++ b/config.json @@ -5,6 +5,31 @@ "transformGroup": "css", "buildPath": "build/css/", "prefix": "xpl", + "files": [ + { + "destination": "variables.css", + "format": "css/variables", + "fileHeader": "myFileHeader", + "options": { + "showFileHeader": false, + "outputReferences": true + } + }, + { + "destination": "theme.css", + "format": "css/variables", + "fileHeader": "myFileHeader", + "filter": { + "attributes": { + "category": "theme" + } + }, + "options": { + "showFileHeader": false, + "outputReferences": true + } + } + ], "files": [ { "destination": "variables.css", @@ -29,9 +54,23 @@ "showFileHeader": true, "outputReferences": true } + }, + { + "destination": "_theme.scss", + "format": "scss/variables", + "filter": { + "attributes": { + "category": "theme" + } + }, + "options": { + "showFileHeader": true, + "outputReferences": true + } } ] }, + "js": { "buildPath": "build/js/", "transformGroup": "js", @@ -87,6 +126,18 @@ "category": "color" } } + }, + { + "destination": "theme.xml", + "format": "android/resources", + "options": { + "outputReferences": true + }, + "filter": { + "attributes": { + "category": "theme" + } + } } ] }, @@ -96,7 +147,7 @@ "prefix": "xpl", "files": [ { - "destination": "StyleDictionaryColor.swift", + "destination": "ApolloFoundationColor.swift", "format": "ios-swift/enum.swift", "className": "StyleDictionaryColor", "options": { @@ -109,7 +160,7 @@ } }, { - "destination": "StyleDictionaryFont.swift", + "destination": "ApolloFoundationSize.swift", "format": "ios-swift/enum.swift", "className": "StyleDictionaryFont", "type": "float", @@ -121,6 +172,20 @@ "category": "size" } } + }, + { + "destination": "ApolloFoundationTheme.swift", + "format": "ios-swift/enum.swift", + "className": "StyleDictionaryFont", + "type": "float", + "options": { + "outputReferences": true + }, + "filter": { + "attributes": { + "category": "theme" + } + } } ] } diff --git a/tokens/color/text.json b/tokens/color/text.json index 103601e..d34cdba 100644 --- a/tokens/color/text.json +++ b/tokens/color/text.json @@ -18,8 +18,8 @@ "dm": {"value": "{color.red.300.value}"} }, "action": { - "lm": {"value": "{color.primary.lm.value}","comment": "uses themable token"}, - "dm": {"value": "{color.primary.dm.value}","comment": "uses themable token"} + "lm": {"value": "{color.primary.lm.value}"}, + "dm": {"value": "{color.primary.dm.value}"} }, "reverse": { "lm": {"value": "{color.gray.0.value}"}, diff --git a/tokens/color/theme.json b/tokens/color/theme.json new file mode 100644 index 0000000..3e382b4 --- /dev/null +++ b/tokens/color/theme.json @@ -0,0 +1,65 @@ +{ + "theme": { + "color": { + "primary": { + "main": { + "lm": {"value": "{theme.color.primary.500.value}"}, + "dm": {"value": "{theme.color.primary.200.value}"} + }, + "focus": { + "lm": {"value": "{theme.color.primary.600.value}"}, + "dm": {"value": "{theme.color.primary.300.value}"} + }, + "surface": { + "lm": {"value": "{theme.color.primary.50.value}"}, + "dm": {"value": "{color.background-2.dm.value}"} + }, + "textOn": { + "lm": {"value": "{color.text.reverse.lm.value}"}, + "dm": {"value": "{color.text.reverse.dm.value}"} + }, + "50": {"value": "#F0E9FEff","comment": "primary.calc(10L)"}, + "100": {"value": "#D2BDFCff","comment": "primary.calc(30L)"}, + "200": {"value": "#C3A7FBff","comment": "primary.calc(40L)"}, + "300": {"value": "#A57BF8ff","comment": "primary.calc(60L)"}, + "400": {"value": "#874FF6ff","comment": "primary.calc(80L)"}, + "500": {"value": "#6923F4ff","comment": "primary"}, + "600": {"value": "#541CC3ff","comment": "primary.calc(80D)"}, + "700": {"value": "#3F1592ff","comment": "primary.calc(60D)"}, + "800": {"value": "#2A0E62ff","comment": "primary.calc(40D)"}, + "900": {"value": "#1F0A49ff","comment": "primary.calc(30D)"}, + "1000": {"value": "#0A0318ff","comment": "primary.calc(10D)"} + }, + "secondary": { + "main": { + "lm": {"value": "{theme.color.secondary.500.value}"}, + "dm": {"value": "{theme.color.secondary.200.value}"} + }, + "focus": { + "lm": {"value": "{theme.color.secondary.600.value}"}, + "dm": {"value": "{theme.color.secondary.300.value}"} + }, + "surface": { + "lm": {"value": "{theme.color.secondary.50.value}"}, + "dm": {"value": "{color.background-2.dm.value}"} + }, + "textOn": { + "lm": {"value": "{color.text.primary.lm.value}"}, + "dm": {"value": "{color.text.reverse.dm.value}"} + }, + "50": {"value": "#FEF4F1FF","comment": "secondary.calc(10L)"}, + "100": {"value": "#FDDED4FF","comment": "secondary.calc(30L)"}, + "200": {"value": "#FDD3C6FF","comment": "secondary.calc(40L)"}, + "300": {"value": "#FBBDA9FF","comment": "secondary.calc(60L)"}, + "400": {"value": "#FAA78DFF","comment": "secondary.calc(80L)"}, + "500": {"value": "#F99170FF","comment": "secondary"}, + "600": {"value": "#C7745AFF","comment": "secondary.calc(80D)"}, + "700": {"value": "#955743FF","comment": "secondary.calc(60D)"}, + "800": {"value": "#643A2DFF","comment": "secondary.calc(40D)"}, + "900": {"value": "#4B2B22FF","comment": "secondary.calc(30D)"}, + "1000": {"value": "#190E0BFF","comment": "secondary.calc(10D)"} + + } + } + } +} \ No newline at end of file From ce3e3258baae352e8d1701e17a2200810490fdb3 Mon Sep 17 00:00:00 2001 From: Dan Rader Date: Wed, 24 Aug 2022 11:04:15 -0400 Subject: [PATCH 2/4] Added Blue. Added Theming Export in JS --- config.json | 30 +++++++++++++++--------------- tokens/color/SemanticPalette.json | 6 +++--- tokens/color/accentPalette.json | 3 ++- tokens/color/base.json | 12 ++++++++++++ tokens/color/primaryPalette.json | 20 ++++++++++---------- 5 files changed, 42 insertions(+), 29 deletions(-) diff --git a/config.json b/config.json index 3866dfe..be428bc 100644 --- a/config.json +++ b/config.json @@ -15,28 +15,16 @@ "outputReferences": true } }, - { + { "destination": "theme.css", - "format": "css/variables", - "fileHeader": "myFileHeader", + "format": "scss/variables", "filter": { "attributes": { "category": "theme" } }, "options": { - "showFileHeader": false, - "outputReferences": true - } - } - ], - "files": [ - { - "destination": "variables.css", - "format": "css/variables", - "fileHeader": "myFileHeader", - "options": { - "showFileHeader": false, + "showFileHeader": true, "outputReferences": true } } @@ -98,6 +86,18 @@ "options": { "outputReferences": true } + }, + { + "destination": "theme.js", + "format": "javascript/umd", + "filter": { + "attributes": { + "category": "theme" + } + }, + "options": { + "outputReferences": true + } } ] }, diff --git a/tokens/color/SemanticPalette.json b/tokens/color/SemanticPalette.json index 015564a..b9d331c 100644 --- a/tokens/color/SemanticPalette.json +++ b/tokens/color/SemanticPalette.json @@ -25,11 +25,11 @@ "dm": {"value": "{color.transparent.value}"} }, "information": { - "lm": {"value": "{color.secondary.lm.value}","comment": "uses themable token"}, - "dm": {"value": "{color.secondary.dm.value}","comment": "uses themable token"} + "lm": {"value": "{color.secondary.lm.value}"}, + "dm": {"value": "{color.secondary.dm.value}"} }, "information-bg": { - "lm": {"value": "{color.secondary-bg.lm.value}","comment": "uses themable token"}, + "lm": {"value": "{color.secondary-bg.lm.value}"}, "dm": {"value": "{color.transparent.value}"} }, "trivial": { diff --git a/tokens/color/accentPalette.json b/tokens/color/accentPalette.json index 56c2083..769ba33 100644 --- a/tokens/color/accentPalette.json +++ b/tokens/color/accentPalette.json @@ -4,7 +4,8 @@ "green": {"value": "{color.green.200.value}"}, "yellow": {"value": "{color.yellow.200.value}"}, "pink": {"value": "{color.pink.300.value}"}, - "purple": {"value": "{color.purple.300.value}"} + "purple": {"value": "{color.purple.300.value}"}, + "blue": {"value": "{color.blue.200.value}"} } } } diff --git a/tokens/color/base.json b/tokens/color/base.json index c4cc267..84bb478 100644 --- a/tokens/color/base.json +++ b/tokens/color/base.json @@ -88,6 +88,18 @@ "800": {"value": "#961305ff"}, "900": {"value": "#731409ff"} }, + "blue": { + "50": {"value": "#0F3999FF"}, + "100": {"value": "#2253B3FF"}, + "200": {"value": "#356CCCFF"}, + "300": {"value": "#5088D6FF"}, + "400": {"value": "#6AA3E0FF"}, + "500": {"value": "#85BFEBFF"}, + "600": {"value": "#9FDAF5FF"}, + "700": {"value": "##BAF6FFFF"}, + "800": {"value": "#D1F9FFFF"}, + "900": {"value": "#E8FCFFFF"} + }, "transparent": {"value": "#ffffff00"} } } diff --git a/tokens/color/primaryPalette.json b/tokens/color/primaryPalette.json index 9e29cdd..9ce0238 100644 --- a/tokens/color/primaryPalette.json +++ b/tokens/color/primaryPalette.json @@ -21,24 +21,24 @@ "dm": {"value": "{color.gray.600.value}"} }, "primary": { - "lm": {"value": "{color.orange.600.value}", "themable": true, "comment": "themable"}, - "dm": {"value": "{color.orange.400.value}", "themable": true, "comment": "themable"} + "lm": {"value": "{color.orange.600.value}"}, + "dm": {"value": "{color.orange.400.value}"} }, "primary-bg": { - "lm": {"value": "{color.orange.50.value}", "themable": true, "comment": "themable"}, - "dm": {"value": "{color.gray.900.value}", "themable": true, "comment": "themable"} + "lm": {"value": "{color.orange.50.value}"}, + "dm": {"value": "{color.gray.900.value}"} }, "secondary": { - "lm": {"value": "{color.purple.700.value}", "themable": true, "comment": "themable"}, - "dm": {"value": "{color.purple.300.value}", "themable": true, "comment": "themable"} + "lm": {"value": "{color.purple.700.value}"}, + "dm": {"value": "{color.purple.300.value}"} }, "secondary-hover": { - "lm": {"value": "{color.purple.800.value}", "themable": true, "comment": "themable"}, - "dm": {"value": "{color.purple.400.value}", "themable": true, "comment": "themable"} + "lm": {"value": "{color.purple.800.value}"}, + "dm": {"value": "{color.purple.400.value}"} }, "secondary-bg": { - "lm": {"value": "{color.purple.50.value}", "themable": true, "comment": "themable"}, - "dm": {"value": "{color.gray.900.value}", "themable": true, "comment": "themable"} + "lm": {"value": "{color.purple.50.value}"}, + "dm": {"value": "{color.gray.900.value}"} } } } From a41c4ebc46ea5ed8be684d3acbe99b04e8d3334c Mon Sep 17 00:00:00 2001 From: Dan Rader Date: Wed, 7 Sep 2022 17:37:03 -0400 Subject: [PATCH 3/4] Added ColorGen.js File. Changed JS output to ES6 to be more straightforward This could be a possible breaking change if there is someone out there using the other style of js variables --- config.json | 6 +- theming/colorGen.js | 142 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 theming/colorGen.js diff --git a/config.json b/config.json index be428bc..1f5d7bf 100644 --- a/config.json +++ b/config.json @@ -65,7 +65,7 @@ "files": [ { "destination": "colors.js", - "format": "javascript/umd", + "format": "javascript/es6", "filter": { "attributes": { "category": "color" @@ -77,7 +77,7 @@ }, { "destination": "font.js", - "format": "javascript/umd", + "format": "javascript/es6", "filter": { "attributes": { "category": "font" @@ -89,7 +89,7 @@ }, { "destination": "theme.js", - "format": "javascript/umd", + "format": "javascript/es6", "filter": { "attributes": { "category": "theme" diff --git a/theming/colorGen.js b/theming/colorGen.js new file mode 100644 index 0000000..900df79 --- /dev/null +++ b/theming/colorGen.js @@ -0,0 +1,142 @@ +function generateColorList(primaryColor, secondaryColor) { + + const themePrimary200 = chroma.mix(primaryColor, 'white', 0.6, 'hsl').hex(); + const themePrimary300 = chroma.mix(primaryColor, 'white', 0.4, 'hsl').hex(); + const themePrimary400 = chroma.mix(primaryColor, 'white', 0.2, 'hsl').hex(); + const themePrimary500 = chroma(primaryColor).hex(); + const themePrimary600 = chroma.mix(primaryColor, 'black', 0.2, 'hsl').hex(); + const themePrimaryGradStart = chroma.mix(primaryColor, 'white', 0.2, 'hsl').alpha(.2).hex(); + const themePrimaryGradEnd = chroma.mix(primaryColor, 'white', 0.2, 'hsl').alpha(.0).hex(); + + const themeSecondary200 = chroma.mix(secondaryColor, 'white', 0.6, 'hsl').hex(); + const themeSecondary300 = chroma.mix(secondaryColor, 'white', 0.4, 'hsl').hex(); + const themeSecondary400 = chroma.mix(secondaryColor, 'white', 0.2, 'hsl').hex(); + const themeSecondary500 = chroma(secondaryColor).hex(); + const themeSecondary600 = chroma.mix(secondaryColor, 'black', 0.2, 'hsl').hex(); + const themeSecondaryGradStart = chroma.mix(secondaryColor, 'white', 0.2, 'hsl').alpha(.2).hex(); + const themeSecondaryGradEnd = chroma.mix(secondaryColor, 'white', 0.2, 'hsl').alpha(.0).hex(); + + // contrast + + const contrastTarget = 4.5 + const textPrimary = _styleDictionary.color.text.primary.lm.value + var themePrimaryTextOn = "" + var themeSecondaryTextOn = "" + + const primaryContrast = chroma.contrast(textPrimary, primaryColor); + const secondaryContrast = chroma.contrast(textPrimary, secondaryColor); + + if (primaryContrast > contrastTarget) { + themePrimaryTextOn = _styleDictionary.color.text.primary.lm.value + } else { + themePrimaryTextOn = _styleDictionary.color.text.reverse.lm.value + } + + if (secondaryContrast > contrastTarget) { + themeSecondaryTextOn = _styleDictionary.color.text.primary.lm.value + } else { + themeSecondaryTextOn = _styleDictionary.color.text.reverse.lm.value + } + + const colorList = { + theme: { + primary: { + main: { + lm: themePrimary500, + dm: themePrimary200 + }, + focus: { + lm: themePrimary600, + dm: themePrimary300 + }, + surface: { + lm: themePrimary500, + dm: themePrimary200 + }, + textOn: { + lm: themePrimary500, + dm: themePrimary200 + }, + gradientStart: { + lm: themePrimary400, + dm: themePrimaryGradStart + }, + gradientEnd: { + lm: themePrimary500, + dm: themePrimaryGradEnd + }, + textOn: { + lm: themePrimaryTextOn, + dm: ColorTextPrimaryDm + }, + }, + secondary: { + main: { + lm: themeSecondary500, + dm: themeSecondary200 + }, + focus: { + lm: themeSecondary600, + dm: themeSecondary300 + }, + surface: { + lm: themeSecondary500, + dm: themeSecondary200 + }, + textOn: { + lm: themeSecondary500, + dm: themeSecondary200 + }, + gradientStart: { + lm: themeSecondary400, + dm: themeSecondaryGradStart + }, + gradientEnd: { + lm: themeSecondary500, + dm: themeSecondaryGradEnd + }, + textOn: { + lm: themeSecondaryTextOn, + dm: ColorTextPrimaryDm + }, + } + }, + fixed: { + foreground: { + lm: ColorForegroundLm, + dm: ColorForegroundDm + }, + background: { + lm: ColorBackgroundLm, + dm: ColorBackgroundDm + }, + background2: { + lm: ColorBackground2Lm, + dm: ColorBackground2Dm + }, + stroke: { + lm: ColorStrokeLm, + dm: ColorStrokeDm + }, + text: { + primary: { + lm: ColorTextPrimaryLm, + dm: ColorTextPrimaryDm + }, + secondary: { + lm: ColorTextSecondaryLm, + dm: ColorTextSecondaryDm + }, + reverse: { + lm: ColorTextReverseLm, + dm: ColorTextReverseDm + }, + warning: { + lm: ColorTextWarningLm, + dm: ColorTextWarningDm + } + } + } + } + return colorList; + } \ No newline at end of file From 6f82c99cadd4b020c526ad63ccb70dd31b57aa6d Mon Sep 17 00:00:00 2001 From: Dan Rader Date: Thu, 8 Sep 2022 16:48:43 -0400 Subject: [PATCH 4/4] added values to colorgen --- theming/colorGen.js | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/theming/colorGen.js b/theming/colorGen.js index 900df79..33311ca 100644 --- a/theming/colorGen.js +++ b/theming/colorGen.js @@ -1,5 +1,6 @@ function generateColorList(primaryColor, secondaryColor) { + const themePrimary50 = chroma.mix(primaryColor, 'white', 0.9, 'hsl').hex(); const themePrimary200 = chroma.mix(primaryColor, 'white', 0.6, 'hsl').hex(); const themePrimary300 = chroma.mix(primaryColor, 'white', 0.4, 'hsl').hex(); const themePrimary400 = chroma.mix(primaryColor, 'white', 0.2, 'hsl').hex(); @@ -8,6 +9,7 @@ function generateColorList(primaryColor, secondaryColor) { const themePrimaryGradStart = chroma.mix(primaryColor, 'white', 0.2, 'hsl').alpha(.2).hex(); const themePrimaryGradEnd = chroma.mix(primaryColor, 'white', 0.2, 'hsl').alpha(.0).hex(); + const themeSecondary50 = chroma.mix(secondaryColor, 'white', 0.9, 'hsl').hex(); const themeSecondary200 = chroma.mix(secondaryColor, 'white', 0.6, 'hsl').hex(); const themeSecondary300 = chroma.mix(secondaryColor, 'white', 0.4, 'hsl').hex(); const themeSecondary400 = chroma.mix(secondaryColor, 'white', 0.2, 'hsl').hex(); @@ -50,8 +52,8 @@ function generateColorList(primaryColor, secondaryColor) { dm: themePrimary300 }, surface: { - lm: themePrimary500, - dm: themePrimary200 + lm: themePrimary50, + dm: ColorBackground2Dm }, textOn: { lm: themePrimary500, @@ -80,8 +82,8 @@ function generateColorList(primaryColor, secondaryColor) { dm: themeSecondary300 }, surface: { - lm: themeSecondary500, - dm: themeSecondary200 + lm: themeSecondary50, + dm: ColorBackground2Dm }, textOn: { lm: themeSecondary500, @@ -95,6 +97,14 @@ function generateColorList(primaryColor, secondaryColor) { lm: themeSecondary500, dm: themeSecondaryGradEnd }, + surfaceGradientStart: { + lm: themeSecondary50, + dm: themeSecondaryGradStart + }, + surfaceGradientEnd: { + lm: themeSecondary50, + dm: themeSecondaryGradEnd + }, textOn: { lm: themeSecondaryTextOn, dm: ColorTextPrimaryDm @@ -118,6 +128,14 @@ function generateColorList(primaryColor, secondaryColor) { lm: ColorStrokeLm, dm: ColorStrokeDm }, + disabled: { + lm: ColorActionDisabledLm, + dm: ColorActionDisabledDm + }, + buttontextprimary: { + lm: ColorTextPrimaryLm, + dm: ColorTextPrimaryLm + }, text: { primary: { lm: ColorTextPrimaryLm, @@ -134,6 +152,10 @@ function generateColorList(primaryColor, secondaryColor) { warning: { lm: ColorTextWarningLm, dm: ColorTextWarningDm + }, + success: { + lm: ColorPositiveLm, + dm: ColorPositiveDm } } }