diff --git a/.sass-lint.yml b/.sass-lint.yml new file mode 100644 index 000000000..51034a887 --- /dev/null +++ b/.sass-lint.yml @@ -0,0 +1,9 @@ +options: + config-file: ./node_modules/@springernature/sasslint-config/config/.sass-lint.yml +rules: + # Design tokens need to be in long form for design tool integration + # Allow both styles to fit with existing formatting + hex-length: + - 2 + - + style: off \ No newline at end of file diff --git a/context/brand-context/HISTORY.md b/context/brand-context/HISTORY.md index 9833984ef..58b0573d0 100644 --- a/context/brand-context/HISTORY.md +++ b/context/brand-context/HISTORY.md @@ -1,4 +1,8 @@ # History +## 25.0.0 (2022-06-29) + * UDPATES: + * updates generated Sass from Design Tokens + * Long form hex codes for Design Tokens - allows design tool integration ## 24.1.0 (2022-06-29) * UPDATES: * Normalizer from v5 to v8 inline with our own IE support matrix. diff --git a/context/brand-context/default/scss/00-tokens/_background.variables.scss b/context/brand-context/default/scss/00-tokens/_background.variables.scss index 592a4216c..3f7cfd64b 100644 --- a/context/brand-context/default/scss/00-tokens/_background.variables.scss +++ b/context/brand-context/default/scss/00-tokens/_background.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--background-page: #f8f8f8; $tokens--background-container: #ffffff; diff --git a/context/brand-context/default/scss/00-tokens/_border.variables.scss b/context/brand-context/default/scss/00-tokens/_border.variables.scss index f24344183..62ece0d40 100644 --- a/context/brand-context/default/scss/00-tokens/_border.variables.scss +++ b/context/brand-context/default/scss/00-tokens/_border.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--border-color-primary: #222222; $tokens--border-color-input: #555555; diff --git a/context/brand-context/default/scss/00-tokens/_breakpoints.variables.scss b/context/brand-context/default/scss/00-tokens/_breakpoints.variables.scss index 02adbde44..eb1b02de6 100644 --- a/context/brand-context/default/scss/00-tokens/_breakpoints.variables.scss +++ b/context/brand-context/default/scss/00-tokens/_breakpoints.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--breakpoints-xs: 320px; // mobile $tokens--breakpoints-sm: 580px; // small tablet diff --git a/context/brand-context/default/scss/00-tokens/_button.variables.scss b/context/brand-context/default/scss/00-tokens/_button.variables.scss index e338cadbf..780a1d0ab 100644 --- a/context/brand-context/default/scss/00-tokens/_button.variables.scss +++ b/context/brand-context/default/scss/00-tokens/_button.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--button-background-primary-resting: #01324b; $tokens--button-background-primary-hover: #ffffff; diff --git a/context/brand-context/default/scss/00-tokens/_color.variables.scss b/context/brand-context/default/scss/00-tokens/_color.variables.scss new file mode 100644 index 000000000..2c973b461 --- /dev/null +++ b/context/brand-context/default/scss/00-tokens/_color.variables.scss @@ -0,0 +1,33 @@ + +// Do not edit directly +// Generated on Fri, 01 Jul 2022 16:01:55 GMT + +$tokens--color-white: #ffffff; +$tokens--color-black: #000000; +$tokens--color-grayscale-200: #f8f8f8; +$tokens--color-grayscale-300: #f3f3f3; +$tokens--color-grayscale-400: #dadada; +$tokens--color-grayscale-500: #999999; +$tokens--color-grayscale-600: #666666; +$tokens--color-grayscale-700: #555555; +$tokens--color-grayscale-800: #222222; +$tokens--color-blue-100: #ebf1f5; +$tokens--color-blue-200: #cedbe0; +$tokens--color-blue-300: #0088cc; +$tokens--color-blue-400: #025e8d; +$tokens--color-blue-700: #003f8d; +$tokens--color-blue-900: #01324b; +$tokens--color-primary-universal-dark-blue: #01324b; +$tokens--color-primary-medium-blue: #025e8d; +$tokens--color-primary-bright-blue: #0088cc; +$tokens--color-primary-grey-blue-light-1: #ebf1f5; +$tokens--color-primary-grey-blue-light-2: #cedbe0; +$tokens--color-primary-black: #000000; +$tokens--color-primary-white: #ffffff; +$tokens--color-information-red: #c40606; +$tokens--color-information-orange: #f58220; +$tokens--color-information-blue: #000000; +$tokens--color-information-green: #00a69d; +$tokens--color-interaction-hover: #025e8d; +$tokens--color-interaction-visited: #a345c9; +$tokens--color-interaction-focus: #ffcc00; \ No newline at end of file diff --git a/context/brand-context/default/scss/00-tokens/_font-weight.variables.scss b/context/brand-context/default/scss/00-tokens/_font-weight.variables.scss new file mode 100644 index 000000000..a50aa7e8a --- /dev/null +++ b/context/brand-context/default/scss/00-tokens/_font-weight.variables.scss @@ -0,0 +1,8 @@ + +// Do not edit directly +// Generated on Fri, 01 Jul 2022 16:01:55 GMT + +$tokens--font-weight-light: 300; // normal +$tokens--font-weight-normal: 400; // The normal, or ‘regular’, font weight. +$tokens--font-weight-regular: 400; // The normal, or ‘regular’, font weight. +$tokens--font-weight-bold: 700; // The bold font weight. \ No newline at end of file diff --git a/context/brand-context/default/scss/00-tokens/_icon.variables.scss b/context/brand-context/default/scss/00-tokens/_icon.variables.scss new file mode 100644 index 000000000..9224e527d --- /dev/null +++ b/context/brand-context/default/scss/00-tokens/_icon.variables.scss @@ -0,0 +1,7 @@ + +// Do not edit directly +// Generated on Fri, 01 Jul 2022 16:01:55 GMT + +$tokens--icon-checkbox-checked-stroke: #ffffff; +$tokens--icon-checkbox-checked-fill: #01324b; +$tokens--icon-select-stroke: #000000; \ No newline at end of file diff --git a/context/brand-context/default/scss/00-tokens/_index.scss b/context/brand-context/default/scss/00-tokens/_index.scss index c4d8bdf50..47d31f2e5 100644 --- a/context/brand-context/default/scss/00-tokens/_index.scss +++ b/context/brand-context/default/scss/00-tokens/_index.scss @@ -2,8 +2,13 @@ @import '_border.variables.scss'; @import '_breakpoints.variables.scss'; @import '_button.variables.scss'; +@import '_color.variables.scss'; +@import '_font-weight.variables.scss'; +@import '_icon.variables.scss'; @import '_link.variables.scss'; @import '_sizing.variables.scss'; @import '_spacing.variables.scss'; @import '_state.variables.scss'; -@import '_text.variables.scss'; \ No newline at end of file +@import '_text.variables.scss'; +@import '_typography.variables.scss'; +@import '_ui.variables.scss'; \ No newline at end of file diff --git a/context/brand-context/default/scss/00-tokens/_link.variables.scss b/context/brand-context/default/scss/00-tokens/_link.variables.scss index 8e83e5f02..33afd3179 100644 --- a/context/brand-context/default/scss/00-tokens/_link.variables.scss +++ b/context/brand-context/default/scss/00-tokens/_link.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--link-color: #025e8d; $tokens--link-hover: #01324b; diff --git a/context/brand-context/default/scss/00-tokens/_sizing.variables.scss b/context/brand-context/default/scss/00-tokens/_sizing.variables.scss index ac813c2c9..12a20f208 100644 --- a/context/brand-context/default/scss/00-tokens/_sizing.variables.scss +++ b/context/brand-context/default/scss/00-tokens/_sizing.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--sizing-relative-0: 0; // no spacing, zero. $tokens--sizing-relative-25: .0625; // .0625rem, 1px diff --git a/context/brand-context/default/scss/00-tokens/_spacing.variables.scss b/context/brand-context/default/scss/00-tokens/_spacing.variables.scss index ca32a7ef4..ff94d926f 100644 --- a/context/brand-context/default/scss/00-tokens/_spacing.variables.scss +++ b/context/brand-context/default/scss/00-tokens/_spacing.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--spacing-relative-0: 0; // no spacing, zero. $tokens--spacing-relative-100: .25rem; // .25rem, 4px. diff --git a/context/brand-context/default/scss/00-tokens/_state.variables.scss b/context/brand-context/default/scss/00-tokens/_state.variables.scss index 7ac9a40ab..bfd4355d7 100644 --- a/context/brand-context/default/scss/00-tokens/_state.variables.scss +++ b/context/brand-context/default/scss/00-tokens/_state.variables.scss @@ -1,9 +1,9 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT -$tokens--state-focus: #0088cc; +$tokens--state-focus: #ffcc00; $tokens--state-error: #c40606; $tokens--state-warning: #f58220; $tokens--state-success: #00a69d; -$tokens--state-information: #003f8d; \ No newline at end of file +$tokens--state-information: #000000; \ No newline at end of file diff --git a/context/brand-context/default/scss/00-tokens/_text.variables.scss b/context/brand-context/default/scss/00-tokens/_text.variables.scss index c53358ce4..27ad80bbe 100644 --- a/context/brand-context/default/scss/00-tokens/_text.variables.scss +++ b/context/brand-context/default/scss/00-tokens/_text.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--text-primary: #000000; $tokens--text-secondary: #666666; diff --git a/context/brand-context/default/scss/00-tokens/_typography.variables.scss b/context/brand-context/default/scss/00-tokens/_typography.variables.scss new file mode 100644 index 000000000..6b23cf0a9 --- /dev/null +++ b/context/brand-context/default/scss/00-tokens/_typography.variables.scss @@ -0,0 +1,22 @@ + +// Do not edit directly +// Generated on Fri, 01 Jul 2022 16:01:55 GMT + +$tokens--typography-heading-font-family: serif; +$tokens--typography-heading-letter-spacing: 0.2rem; +$tokens--typography-heading-line-height: 1.2; +$tokens--typography-heading-level-1-default-font-size: 2.5rem; +$tokens--typography-heading-level-1-default-font-weight: 400; +$tokens--typography-heading-level-1-fluid-font-size: clamp(1.875rem, 4vw, 2.5rem); +$tokens--typography-heading-level-2-default-font-size: 1.875rem; +$tokens--typography-heading-level-2-default-font-weight: 400; +$tokens--typography-heading-level-2-fluid-font-size: clamp(1.5rem, 4vw, 1.875rem); +$tokens--typography-heading-level-3-default-font-size: 1.5rem; +$tokens--typography-heading-level-3-fluid-font-size: clamp(1.25rem, 4vw, 1.5rem); +$tokens--typography-heading-level-4-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; +$tokens--typography-heading-level-4-default-font-size: 1.25rem; +$tokens--typography-heading-level-4-fluid-font-size: clamp(1.125rem, 4vw, 1.25rem); +$tokens--typography-heading-level-4-font-weight: 700; +$tokens--typography-heading-level-5-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; +$tokens--typography-heading-level-5-font-size: 1.125rem; +$tokens--typography-heading-level-5-font-weight: 700; \ No newline at end of file diff --git a/context/brand-context/default/scss/00-tokens/_ui.variables.scss b/context/brand-context/default/scss/00-tokens/_ui.variables.scss new file mode 100644 index 000000000..8c7c42f2d --- /dev/null +++ b/context/brand-context/default/scss/00-tokens/_ui.variables.scss @@ -0,0 +1,7 @@ + +// Do not edit directly +// Generated on Fri, 01 Jul 2022 16:01:55 GMT + +$tokens--ui-font-size: 1rem; +$tokens--ui-focus-outline-color: #025e8d; +$tokens--ui-content-width: 70ch; \ No newline at end of file diff --git a/context/brand-context/nature/scss/00-tokens/_illustration.variables.scss b/context/brand-context/nature/scss/00-tokens/_illustration.variables.scss index decb305e5..2d64dc09a 100644 --- a/context/brand-context/nature/scss/00-tokens/_illustration.variables.scss +++ b/context/brand-context/nature/scss/00-tokens/_illustration.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--illustration-background-001: #29303C; $tokens--illustration-background-002: #536179; diff --git a/context/brand-context/nature/scss/00-tokens/_typography.variables.scss b/context/brand-context/nature/scss/00-tokens/_typography.variables.scss index a0c4525a6..8e0f35482 100644 --- a/context/brand-context/nature/scss/00-tokens/_typography.variables.scss +++ b/context/brand-context/nature/scss/00-tokens/_typography.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:22 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--typography-heading-font-family: serif; $tokens--typography-heading-letter-spacing: 0.2rem; diff --git a/context/brand-context/package.json b/context/brand-context/package.json index 9d1829148..6205d0857 100644 --- a/context/brand-context/package.json +++ b/context/brand-context/package.json @@ -1,6 +1,6 @@ { "name": "@springernature/brand-context", - "version": "24.1.0", + "version": "25.0.0", "license": "MIT", "description": "Bootstrapping for all components and products", "keywords": [], diff --git a/context/brand-context/springer/scss/00-tokens/_typography.variables.scss b/context/brand-context/springer/scss/00-tokens/_typography.variables.scss index aff336d50..6b23cf0a9 100644 --- a/context/brand-context/springer/scss/00-tokens/_typography.variables.scss +++ b/context/brand-context/springer/scss/00-tokens/_typography.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--typography-heading-font-family: serif; $tokens--typography-heading-letter-spacing: 0.2rem; diff --git a/context/brand-context/springernature/scss/00-tokens/_breakpoints.variables.scss b/context/brand-context/springernature/scss/00-tokens/_breakpoints.variables.scss index 1aa70da4b..f84f967b7 100644 --- a/context/brand-context/springernature/scss/00-tokens/_breakpoints.variables.scss +++ b/context/brand-context/springernature/scss/00-tokens/_breakpoints.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--breakpoints-tablet-width: 480px; // tablet-width $tokens--breakpoints-tablet-wide-width: 768px; // tablet-wide-width diff --git a/context/brand-context/springernature/scss/00-tokens/_typography.variables.scss b/context/brand-context/springernature/scss/00-tokens/_typography.variables.scss index 712330af6..75c310b48 100644 --- a/context/brand-context/springernature/scss/00-tokens/_typography.variables.scss +++ b/context/brand-context/springernature/scss/00-tokens/_typography.variables.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Tue, 28 Jun 2022 10:44:21 GMT +// Generated on Fri, 01 Jul 2022 16:01:55 GMT $tokens--typography-heading-font-family: serif; $tokens--typography-heading-letter-spacing: 0.2rem; diff --git a/context/design-tokens/alias/default/color/color.json b/context/design-tokens/alias/default/color/color.json new file mode 100644 index 000000000..9a9abfaaf --- /dev/null +++ b/context/design-tokens/alias/default/color/color.json @@ -0,0 +1,52 @@ +{ + "color": { + "primary": { + "universal-dark-blue": { + "value": "{color.blue.900}" + }, + "medium-blue": { + "value": "{color.blue.400}" + }, + "bright-blue": { + "value": "{color.blue.300}" + }, + "grey-blue-light-1": { + "value": "{color.blue.100}" + }, + "grey-blue-light-2": { + "value": "{color.blue.200}" + }, + "black": { + "value": "{color.black}" + }, + "white": { + "value": "{color.white}" + } + }, + "information": { + "red": { + "value": "#C40606" + }, + "orange": { + "value": "#F58220" + }, + "blue": { + "value": "{color.blue.700" + }, + "green": { + "value": "#00A69D" + } + }, + "interaction": { + "hover": { + "value": "{color.blue.400}" + }, + "visited": { + "value": "#A345C9" + }, + "focus": { + "value": "#FFCC00" + } + } + } +} \ No newline at end of file diff --git a/context/design-tokens/alias/default/icon/icon.json b/context/design-tokens/alias/default/icon/icon.json new file mode 100644 index 000000000..49f8f5e5c --- /dev/null +++ b/context/design-tokens/alias/default/icon/icon.json @@ -0,0 +1,19 @@ +{ + "icon": { + "checkbox": { + "checked": { + "stroke": { + "value": "{color.white}" + }, + "fill": { + "value": "{color.primary.universal-dark-blue}" + } + } + }, + "select": { + "stroke": { + "value": "{color.black}" + } + } + } +} \ No newline at end of file diff --git a/context/design-tokens/alias/default/typography/typography.json b/context/design-tokens/alias/default/typography/typography.json new file mode 100644 index 000000000..73589b78f --- /dev/null +++ b/context/design-tokens/alias/default/typography/typography.json @@ -0,0 +1,86 @@ +{ + "typography": { + "heading": { + "font-family": { + "value": "{font-family.serif}" + }, + "letter-spacing": { + "value": "{letter-spacing.080}" + }, + "line-height": { + "value": "{line-height.tighter}" + }, + "level-1": { + "default": { + "font-size": { + "value": "{font-size.900}" + }, + "font-weight": { + "value": "{font-weight.regular}" + } + }, + "fluid": { + "font-size": { + "value": "clamp({font-size.650}, 4vw, {typography.heading.level-1.default.font-size.value})" + } + } + }, + "level-2": { + "default": { + "font-size": { + "value": "{font-size.650}" + }, + "font-weight": { + "value": "{font-weight.regular.value}" + } + }, + "fluid": { + "font-size": { + "value": "clamp({font-size.600}, 4vw, {typography.heading.level-2.default.font-size.value})" + } + } + }, + "level-3": { + "default": { + "font-size": { + "value": "{font-size.600.value}" + } + }, + "fluid": { + "font-size": { + "value": "clamp({font-size.500.value}, 4vw, {typography.heading.level-3.default.font-size.value})" + } + } + }, + "level-4": { + "font-family": { + "value": "{font-family.sans}" + }, + "default": { + "font-size": { + "value": "{font-size.500.value}" + } + }, + "fluid": { + "font-size": { + "value": "clamp({font-size.450.value}, 4vw, {typography.heading.level-4.default.font-size.value})" + } + }, + "font-weight": { + "value": "{font-weight.bold.value}" + } + }, + "level-5": { + "font-family": { + "value": "{font-family.sans}" + }, + "font-size": { + "value": "{font-size.450.value}" + }, + "font-weight": { + "value": "{font-weight.bold.value}" + } + } + } + } +} \ No newline at end of file diff --git a/context/design-tokens/alias/default/ui/ui.json b/context/design-tokens/alias/default/ui/ui.json new file mode 100644 index 000000000..b452294af --- /dev/null +++ b/context/design-tokens/alias/default/ui/ui.json @@ -0,0 +1,17 @@ +{ + "ui": { + "font-size": { + "value": "{font-size.400}" + }, + "focus": { + "outline": { + "color": { + "value": "{color.primary.medium-blue}" + } + } + }, + "content-width": { + "value": "70ch" + } + } +} \ No newline at end of file diff --git a/context/design-tokens/build-component-global.js b/context/design-tokens/build-component-global.js new file mode 100644 index 000000000..4432844d5 --- /dev/null +++ b/context/design-tokens/build-component-global.js @@ -0,0 +1,89 @@ +const fs = require('fs'); +const StyleDictionaryPackage = require('style-dictionary'); +const { readdirSync } = require('fs'); + +// this will return a filtering function based on brand and component +function tokenFilter(brand, component) { + return function (token) { + return ( + token.filePath.includes(brand) && token.attributes.category === component + ); + }; +} + +function getStyleDictionaryConfig(brand, components) { + let dest = `./toolkits/global/packages/`; + + let brand2 = brand; + // if brand2 equal global let brand2 equal default + if (brand2 === 'global') { + brand2 = 'default'; + } + + return { + // we want to include the default tokens first and override them with brand tokens if available + include: [ + `${__dirname}/literal/default/**/*.json`, + `${__dirname}/literal/${brand2}/**/*.json`, + `${__dirname}/alias/default/**/*.json`, + `${__dirname}/alias/${brand2}/**/*.json` + ], + // for each brand want to generate the Sass variables from this components tokens file + source: [ + `${__dirname}/components/**/${brand2}.json` + ], + platforms: { + scssVariables: { + transformGroup: 'web', + buildPath: `${dest}/`, + files: components.map(component => { + return { + destination: `${component}/scss/00-tokens/_${brand2}.tokens.scss`, + format: 'scss/variables', + filter: tokenFilter(brand, component), + "options": { + "outputReferences": false, + "showFileHeader": false + } + } + }) + } + } + } +} + + + +['global', 'springer', 'nature', 'springer-nature'].map(function (brand) { + console.log('Build started...'); + let dir = `${__dirname}/components/global` + const components = readdirSync(dir); + const brands = StyleDictionaryPackage.extend(getStyleDictionaryConfig(brand, components)); + + brands.buildAllPlatforms(); + + components.map(component => { + let dir = `./toolkits/global/packages/${component}/scss/00-tokens`; + let brand2 = brand; + // if brand2 equal global let brand2 equal default + if (brand2 === 'global') { + brand2 = 'default'; + } + if (fs.existsSync(`${dir}/_${brand2}.tokens.scss`)) { + + let filePath = `${dir}/_${brand2}.tokens.scss` + let content = fs.readFileSync(filePath, 'utf8'); + let sortedContent = content.split('\n').sort().join('\n'); + + let replacedContent = sortedContent.replace(/: \$/g, ': $tokens--'); + + let GeneratedContent = `// Generated on ${new Date().toLocaleString()}\n// Source: design-tokens/componenets/${brand}/${component}/${brand2}.json\n// DO NOT edit directly\n\n${replacedContent}`; + + fs.writeFileSync(filePath, GeneratedContent); + + } + }); + + console.log('\nEnd processing'); +}); + diff --git a/context/design-tokens/build-component.js b/context/design-tokens/build-component.js index 419d72aff..716d68572 100644 --- a/context/design-tokens/build-component.js +++ b/context/design-tokens/build-component.js @@ -18,11 +18,13 @@ function getStyleDictionaryConfig(brand, components) { return { include: [ - `${__dirname}/literal/**/*.json`, - `${__dirname}/alias/**/*.json` + `${__dirname}/literal/default/**/*.json`, + `${__dirname}/literal/${brand}/**/*.json`, + `${__dirname}/alias/default/**/*.json`, + `${__dirname}/alias/${brand}/**/*.json` ], source: [ - `${__dirname}/component/**/*.json` + `${__dirname}/components/${brand}/**/*.json` ], platforms: { scssVariables: { @@ -30,11 +32,12 @@ function getStyleDictionaryConfig(brand, components) { buildPath: `${dest}/`, files: components.map(component => { return { - destination: `${component}/scss/10-settings/_${component}.variables.scss`, + destination: `${component}/scss/00-tokens/_${component}.tokens.scss`, format: 'scss/variables', filter: tokenFilter(brand, component), "options": { - "outputReferences": true + "outputReferences": true, + "showFileHeader": false } } }) @@ -42,16 +45,34 @@ function getStyleDictionaryConfig(brand, components) { } } } -// TODO: see if I can combine this with an existing Sass file console.log('Build started...'); -['global'].map(function (brand) { - let dir = `${__dirname}/component/${brand}` +// the following array needs to be manually updated when more brand speicifc components are added to brands not on this list. Otherwise this will not build. This is why it is currently not part of +['springer'].map(function (brand) { + + let dir = `${__dirname}/components/${brand}` const components = readdirSync(dir); const brands = StyleDictionaryPackage.extend(getStyleDictionaryConfig(brand, components)); brands.buildAllPlatforms(); + components.map(component => { + let dir = `./toolkits/${brand}/packages/${component}/scss/00-tokens` + const files = readdirSync(dir); + + files.map(file => { + let filePath = `${dir}/${file}` + let content = fs.readFileSync(filePath, 'utf8'); + let sortedContent = content.split('\n').sort().join('\n'); + fs.writeFileSync(filePath, sortedContent); + let date = new Date(); + let dateString = date.toLocaleString(); + let newContent = `// Created: ${dateString}\n// Source: design-tokens/componenets/${brand}/${component}/${brand}.json\n// DO NOT edit directly\n\n${sortedContent}`; + let addedContent = newContent.replace(/: \$/g, ': $tokens--'); + fs.writeFileSync(filePath, addedContent); + }) + }); + console.log('\nEnd processing'); }); diff --git a/context/design-tokens/build-json.js b/context/design-tokens/build-json.js new file mode 100644 index 000000000..419d72aff --- /dev/null +++ b/context/design-tokens/build-json.js @@ -0,0 +1,57 @@ +const fs = require('fs'); +const StyleDictionaryPackage = require('style-dictionary'); +const { readdirSync } = require('fs'); + +// this will return a filtering function based on brand and component +function tokenFilter(brand, component) { + return function (token) { + return ( + // Added in 3.0: filePath to help with filtering + // So this will only include tokens of a given brand + token.filePath.includes(brand) && token.attributes.category === component + ); + }; +} + +function getStyleDictionaryConfig(brand, components) { + let dest = `./toolkits/${brand}/packages/`; + + return { + include: [ + `${__dirname}/literal/**/*.json`, + `${__dirname}/alias/**/*.json` + ], + source: [ + `${__dirname}/component/**/*.json` + ], + platforms: { + scssVariables: { + transformGroup: 'web', + buildPath: `${dest}/`, + files: components.map(component => { + return { + destination: `${component}/scss/10-settings/_${component}.variables.scss`, + format: 'scss/variables', + filter: tokenFilter(brand, component), + "options": { + "outputReferences": true + } + } + }) + } + } + } +} +// TODO: see if I can combine this with an existing Sass file + +console.log('Build started...'); + +['global'].map(function (brand) { + let dir = `${__dirname}/component/${brand}` + const components = readdirSync(dir); + const brands = StyleDictionaryPackage.extend(getStyleDictionaryConfig(brand, components)); + + brands.buildAllPlatforms(); + + console.log('\nEnd processing'); +}); diff --git a/context/design-tokens/build-literal.js b/context/design-tokens/build-literal.js index 31036c3e0..0a47a013b 100644 --- a/context/design-tokens/build-literal.js +++ b/context/design-tokens/build-literal.js @@ -27,6 +27,7 @@ function getStyleDictionaryConfig(brand, categories) { return { source: [ + `${__dirname}/literal/${brand}/font-weight/font-weight.json`, `${__dirname}/literal/${brand}/spacing/spacing.json`, `${__dirname}/literal/${brand}/breakpoints/breakpoints.json`, `${__dirname}/literal/${brand}/sizing/sizing.json` diff --git a/context/design-tokens/components/global/global-forms/default.json b/context/design-tokens/components/global/global-forms/default.json new file mode 100644 index 000000000..4b39d2168 --- /dev/null +++ b/context/design-tokens/components/global/global-forms/default.json @@ -0,0 +1,147 @@ +{ + "global-forms": { + "field": { + "stack": { + "spacing": { + "value": "{spacing.relative.600}" + } + } + }, + "label": { + "font": { + "size": { + "value": "{ui.font-size}" + }, + "weight": { + "value": "{font-weight.bold}" + } + }, + "color": { + "value": "{text.primary}" + } + }, + "hint": { + "color": { + "value": "{color.grayscale.600}" + }, + "font": { + "weight": { + "value": "{font-weight.regular}" + } + } + }, + "message": { + "color": { + "error": { + "value": "{state.error}" + } + }, + "icon": { + "color": { + "resting": { + "value": "{text.primary}" + }, + "error": { + "value": "{state.error}" + } + }, + "size": { + "value": "{sizing.relative.400}" + } + } + }, + "input": { + "padding": { + "inline": { + "value": "{spacing.relative.200.value}" + }, + "block": { + "value": "{spacing.relative.200.value}" + } + }, + "stack": { + "spacing": { + "value": "{spacing.relative.100}" + } + }, + "border": { + "color": { + "resting": { + "value": "{border.color.primary}" + }, + "error": { + "value": "{state.error}" + }, + "disabled": { + "value": "{color.grayscale.400}" + } + }, + "width": { + "value": "{border.width.25}" + } + }, + "focus": { + "outline": { + "color": { + "value": "{ui.focus.outline.color}", + "description": "TODO: needs to be coming from an alias or literal token" + } + } + }, + "font": { + "size": { + "value": "{ui.font-size}" + }, + "weight": { + "value": "{font-weight.regular}" + }, + "color": { + "value": "{text.primary}" + } + }, + "background": { + "color": { + "value": "{background.container}" + } + }, + "width": { + "maximum": { + "value": "{ui.content-width}", + "description": "TODO: needs to be coming from an alias or literal token" + } + } + }, + "indent": { + "border": { + "color": { + "value": "{border.color.indent}" + }, + "radius": { + "value": "{border.radius.100}" + } + } + }, + "checkbox": { + "size": { + "value": "{sizing.relative.400}", + "type": "sizing" + }, + "spacing": { + "value": "{sizing.relative.200}" + }, + "checked": { + "icon": { + "stroke": { + "value": "{color.primary.universal-dark-blue}" + }, + "fill": { + "value": "{color.primary.universal-dark-blue}" + }, + "data uri": { + "value": "'data:image/svg+xml;utf8,'" + } + } + } + } + } +} \ No newline at end of file diff --git a/context/design-tokens/components/global/global-forms/springer.json b/context/design-tokens/components/global/global-forms/springer.json new file mode 100644 index 000000000..eb40f88fb --- /dev/null +++ b/context/design-tokens/components/global/global-forms/springer.json @@ -0,0 +1,11 @@ +{ + "global-forms": { + "field": { + "stack": { + "spacing": { + "value": "{spacing.relative.100}" + } + } + } + } +} \ No newline at end of file diff --git a/context/design-tokens/literal/default/color/color.json b/context/design-tokens/literal/default/color/color.json index e7e2568bb..793523b64 100644 --- a/context/design-tokens/literal/default/color/color.json +++ b/context/design-tokens/literal/default/color/color.json @@ -2,11 +2,11 @@ "color": { "white": { "name": "white", - "value": "#ffffff" + "value": "#fff" }, "black": { "name": "black", - "value": "#000000" + "value": "#000" }, "grayscale": { "200": { @@ -23,67 +23,45 @@ }, "500": { "name": "grayscale-500", - "value": "#999999" + "value": "#999" }, "600": { "name": "grayscale-600", - "value": "#666666" + "value": "#666" }, "700": { "name": "grayscale-700", - "value": "#555555" + "value": "#555" }, "800": { "name": "grayscale-800", - "value": "#222222" + "value": "#222" } }, - "primary": { - "universal-dark-blue": { - "value": "#01324B" - }, - "medium-blue": { - "value": "#025E8D" - }, - "bright-blue": { - "value": "#0088CC" - }, - "grey-blue-light-1": { + "blue": { + "100": { + "name": "blue-100", "value": "#EBF1F5" }, - "grey-blue-light-2": { + "200": { + "name": "blue-200", "value": "#CEDBE0" }, - "black": { - "value": "{color.black}" - }, - "white": { - "value": "{color.white}" - } - }, - "information": { - "red": { - "value": "#C40606" - }, - "orange": { - "value": "#F58220" - }, - "blue": { - "value": "#003F8D" + "300": { + "name": "blue-300", + "value": "#08C" }, - "green": { - "value": "#00A69D" - } - }, - "interaction": { - "hover": { + "400": { + "name": "blue-600", "value": "#025E8D" }, - "visited": { - "value": "#A345C9" + "700": { + "name": "blue-700", + "value": "#003F8D" }, - "focus": { - "value": "{color.primary.bright-blue}" + "900": { + "name": "blue-900", + "value": "#01324B" } } } diff --git a/package.json b/package.json index f94893a92..a85fcd846 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,10 @@ "test:ci": "jest --passWithNoTests --runInBand", "tokens:alias": "npm run tokens:clean && npm run tokens:literal && node ./context/design-tokens/build-alias.js", "tokens:clean": "npx rimraf **/00-tokens/", - "tokens:component": "npm run tokens:clean && npm run tokens:literal && npm run tokens:alias node ./context/design-tokens/build-component.js", + "tokens:components": "npm run tokens:global-components && npm run tokens:brand-components", "tokens:literal": "node ./context/design-tokens/build-literal.js", + "tokens:global-components": "npm run tokens:clean && npm run tokens:literal && npm run tokens:alias && node ./context/design-tokens/build-component-global.js", + "tokens:brand-components": "node ./context/design-tokens/build-component.js", "validate": "sn-package-validate", "validate:global": "sn-package-validate -t global", "validate:nature": "sn-package-validate -t nature", @@ -89,5 +91,5 @@ "/node_modules/(?!(@springernature/global-context))/" ] }, - "sasslintConfig": "./node_modules/@springernature/sasslint-config/config/.sass-lint.yml" + "sasslintConfig": "./.sass-lint.yml" } \ No newline at end of file diff --git a/toolkits/global/packages/global-forms/HISTORY.md b/toolkits/global/packages/global-forms/HISTORY.md index 7df9ccdcc..ae99f2da2 100644 --- a/toolkits/global/packages/global-forms/HISTORY.md +++ b/toolkits/global/packages/global-forms/HISTORY.md @@ -1,5 +1,11 @@ # History +## 5.0.0-rc.1 (2022-07-01) + * BREAKING: + * Form fields now available as a suite of templates/partials + * Major changes to styling and styling API + * Design tokens support + ## 4.0.1 (2022-02-18) * Remove post install step that was causing issues with CI diff --git a/toolkits/global/packages/global-forms/README.md b/toolkits/global/packages/global-forms/README.md index b2e8e50f4..007e0f667 100644 --- a/toolkits/global/packages/global-forms/README.md +++ b/toolkits/global/packages/global-forms/README.md @@ -1,10 +1,14 @@ # Global Forms -This module gives you some generic styles for text, checkbox, radio button, textarea and select inputs. +**IMPORTANT:** _This is a **release candidate** representing an ambitious reworking of the global-forms component, including design tokens integration, at a component level, for the first time. It is expected to need some additional work before a full release can be made. Tokens are generated to the `scss/00-tokens` folder and cannot be edited directly. If you need to temporarily add or override variables, please do this in a `10-settings` folder, one level down. The Elements Design System team will assess these changes for making these variables tokens later._ -## Branding +This component includes a number of form fields and related templates. It is designed to make it as simple as possible to create an HTML form. -The `global-forms` component currently uses the `DEFAULT` brand only. +The component does not include any JavaScript. States (such as an invalid/error state) are defined at a data level. If you're using client-side processing, you might benefit from compiling the form’s handlebars template in the browser. + +## Usage + +First, include the necessary Sass files in your project. ```scss // Include this with your settings @@ -13,3 +17,279 @@ The `global-forms` component currently uses the `DEFAULT` brand only. // Include this with your other components @import '@springernature/global-forms/scss/50-components/forms'; ``` + +Then you will need to register the handlebars partials in the `/view` folder. + +There are two options for rendering form fields: + +1. Compile fields independently, using their respective templates from the `view/fields` folder. +2. Organise multiple related fields into fieldsets using the data structure like that shown in `demo/context.json`. For example, a group of fields used to let someone enter their address. In this case, you’ll have to iterate over a `fieldsets` array something like this: + +```html +
+``` + +### Fieldsets + +Fieldsets are used to group fields itemised under their `fields` property. If you do not want to include a (visible; screen reader identifiable) fieldset element or legend, simply omit the `legend` property. The following example shows a simple form body with a single, unlabelled fieldset containing two text inputs: + +```json +"fieldsets": { + [ + { + "fields": [ + { + "template": "text", + "label": "Your name", + "id": "your-name", + "name": "your-name" + }, + { + "template": "text", + "label": "Your email", + "id": "your-email", + "name": "your-email" + } + ] + } + ] +} +``` + +If you do wish to include a legend, you can use HTML to style it and add semantic meaning. In most cases, legends should be headings, with the heading level determined by the page structure. + +```json +"fieldsets": { + [ + { + "legend": "