From 4ba1c7c2a76259e88f96eae83f2e5f25ddffc874 Mon Sep 17 00:00:00 2001 From: Joren Broekema <36734656+undefined@users.noreply.github.com> Date: Wed, 24 Nov 2021 15:50:09 +0000 Subject: [PATCH] feat: refactor all tokens to use style-dictionary BREAKING CHANGE: importing tokens has a new syntax now, no more mixins, made better for treeshaking. --- README.md | 4 + borders/index.js | 1 - borders/src/index.js | 1 - borders/src/radius.css.js | 68 ----- button/doc/index.md | 57 +++- button/src/styles.css.js | 61 ++-- checkbox-group/doc/index.md | 16 ++ .../src/indeterminate-styles.css.js | 4 +- checkbox-group/src/styles.css.js | 13 +- collapsible/doc/index.md | 13 +- collapsible/src/SimbaCollapsible.js | 9 +- collapsible/src/SimbaCollapsibleButton.js | 16 +- collapsible/src/styles.css.js | 19 +- colors/doc/index.md | 91 ++++-- colors/index.js | 2 +- colors/src/_colors.js | 87 ++++++ colors/src/colors.css.js | 105 ------- colors/src/colors.tokens.js | 260 ++++++++++++++++++ dialog/doc/index.md | 114 +++++--- dialog/src/SimbaDialogFrame.js | 35 ++- doc-layout/src/color-toggler.js | 46 ++-- doc-styles/src/DocsMenu.js | 38 +++ form-core/src/choice-box-styles.css.js | 16 +- form-core/src/input-styles.css.js | 58 ++-- icons/doc/index.md | 15 +- index.html | 12 + index.js | 28 ++ input-amount/doc/index.md | 10 +- input-date/doc/index.md | 10 +- input-datepicker/doc/index.md | 10 +- input-datepicker/src/SimbaCalendar.js | 6 +- input-datepicker/src/styles.css.js | 97 ++++--- input-email/doc/index.md | 10 +- input-iban/doc/index.md | 10 +- input-range/doc/index.md | 10 +- input-range/src/styles.css.js | 10 +- input-stepper/doc/index.md | 11 +- input-stepper/src/styles.css.js | 30 +- input/doc/index.md | 10 +- migration.md | 114 ++++++++ {borders => radii}/design/figma.link | 0 radii/doc/index.md | 65 +++++ radii/index.js | 1 + radii/src/_radii.js | 16 ++ radii/src/radii.tokens.js | 13 + radio-group/doc/index.md | 13 +- radio-group/src/styles.css.js | 14 +- sd.config.js | 56 ++++ select/doc/index.md | 17 +- select/src/styles.css.js | 40 +-- spacing/doc/index.md | 23 +- spacing/index.js | 2 +- spacing/src/_spacing.js | 42 +++ spacing/src/index.js | 1 - spacing/src/spacing.css.js | 39 --- spacing/src/spacing.tokens.js | 39 +++ studio.config.json | 95 +++---- switch/doc/index.md | 17 +- switch/src/button-styles.css.js | 18 +- switch/src/styles.css.js | 4 +- textarea/doc/index.md | 10 +- themes/src/theme.js | 76 +++-- token-display/src/index.js | 118 +++++--- tokens/index.js | 4 + tokens/package.json | 1 + tokens/tokens.css | 169 ++++++++++++ tooltip/doc/index.md | 39 ++- tooltip/src/SimbaTooltip.js | 12 +- tsconfig.json | 9 +- typography/doc/index.md | 143 ++++------ typography/index.js | 2 +- typography/src/_typography.js | 45 +++ typography/src/index.js | 1 - typography/src/typography.css.js | 101 ------- typography/src/typography.tokens.js | 82 ++++++ validation-feedback/doc/index.md | 8 +- validation-feedback/src/styles.css.js | 55 ++-- 77 files changed, 2049 insertions(+), 868 deletions(-) delete mode 100644 borders/index.js delete mode 100644 borders/src/index.js delete mode 100644 borders/src/radius.css.js create mode 100644 colors/src/_colors.js delete mode 100644 colors/src/colors.css.js create mode 100644 colors/src/colors.tokens.js create mode 100644 doc-styles/src/DocsMenu.js create mode 100644 index.html create mode 100644 index.js create mode 100644 migration.md rename {borders => radii}/design/figma.link (100%) create mode 100644 radii/doc/index.md create mode 100644 radii/index.js create mode 100644 radii/src/_radii.js create mode 100644 radii/src/radii.tokens.js create mode 100644 sd.config.js create mode 100644 spacing/src/_spacing.js delete mode 100644 spacing/src/index.js delete mode 100644 spacing/src/spacing.css.js create mode 100644 spacing/src/spacing.tokens.js create mode 100644 tokens/index.js create mode 100644 tokens/package.json create mode 100644 tokens/tokens.css create mode 100644 typography/src/_typography.js delete mode 100644 typography/src/index.js delete mode 100644 typography/src/typography.css.js create mode 100644 typography/src/typography.tokens.js diff --git a/README.md b/README.md index a14862d..174690c 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,10 @@ Click the "Edit" button to also see the source code in the Backlight editor. > In case you don't use Backlight.dev but use straight from NPM, refer to our [usage from NPM guide](./UsingNPM.md). +## Migration + +Migrating to a new minor (since this is alpha), see [Migration Docs](./migration.md). + ## Usage ### Duplicate in Backlight diff --git a/borders/index.js b/borders/index.js deleted file mode 100644 index 4df73b3..0000000 --- a/borders/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './src/index.js'; diff --git a/borders/src/index.js b/borders/src/index.js deleted file mode 100644 index f626bd1..0000000 --- a/borders/src/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './radius.css.js'; diff --git a/borders/src/radius.css.js b/borders/src/radius.css.js deleted file mode 100644 index 81e7532..0000000 --- a/borders/src/radius.css.js +++ /dev/null @@ -1,68 +0,0 @@ -import { css } from '~/core'; - -export const borderRadiusMixin = (size, corner) => { - if (!size) { - size = ''; - } - - if (!corner) { - corner = ''; - } - - const sizeMap = { - none: css`0`, - sm: css`0.125rem`, - '': css`0.25rem`, - md: css`0.375rem`, - lg: css`0.5rem`, - xl: css`0.75rem`, - '2xl': css`1rem`, - '3xl': css`1.5rem`, - full: css`9999px`, - }; - - let cornerMap = { - '': [css`border-radius`], - tl: [css`border-top-left-radius`], - tr: [css`border-top-right-radius`], - bl: [css`border-bottom-left-radius`], - br: [css`border-bottom-right-radius`], - }; - - cornerMap = { - ...cornerMap, - t: [...cornerMap['tl'], ...cornerMap['tr']], - b: [...cornerMap['bl'], ...cornerMap['br']], - l: [...cornerMap['tl'], ...cornerMap['bl']], - r: [...cornerMap['tr'], ...cornerMap['br']], - }; - - let cornersToApplyZero = []; - if (corner) { - // If corner is specified, get a list of the corners - // that were not specified by "corner" arg, so we can - // apply a border-radius of 0 to those corners - cornersToApplyZero = [ - css`border-top-left-radius`, - css`border-top-right-radius`, - css`border-bottom-left-radius`, - css`border-bottom-right-radius`, - ].filter( - (cssDecl) => - !cornerMap[corner].find((decl) => decl.cssText === cssDecl.cssText) - ); - } - - // prettier-ignore - const output = [ - ...cornerMap[corner].map((corn) => - css`${corn}: ${sizeMap[size]};` - ), - ...cornersToApplyZero.map((corn) => - css`${corn}: ${sizeMap['none']};` - ), - ].reduce((acc, curr) => css`${acc} -${curr}`); - - return output; -}; diff --git a/button/doc/index.md b/button/doc/index.md index 7655df9..80ae5dd 100644 --- a/button/doc/index.md +++ b/button/doc/index.md @@ -3,8 +3,16 @@ Button web component. ```js script -import { html } from '~/core' -import '../simba-button.js'; +import { html } from '~/core'; +import '@divriots/starter-simba/button/simba-button.js'; +``` + +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/button/simba-button.js'; ``` ```js preview-story @@ -20,19 +28,22 @@ Text buttons don't have outlines and are the least priority buttons. ### Secondary ```js preview-story -export const secondaryButton = () => html`Submit`; +export const secondaryButton = () => + html`Submit`; ``` ### Outline ```js preview-story -export const outlineButton = () => html`Submit`; +export const outlineButton = () => + html`Submit`; ``` ### Text ```js preview-story -export const textButton = () => html`Submit`; +export const textButton = () => + html`Submit`; ``` ## Sizes @@ -42,23 +53,27 @@ Apart from the default size, there is also a small and large variation. ### Small ```js preview-story -export const smallButton = () => html`Submit`; +export const smallButton = () => + html`Submit`; ``` ### Large ```js preview-story -export const largeButton = () => html`Submit`; +export const largeButton = () => + html`Submit`; ``` ## Rounded ```js preview-story -export const roundedButton = () => html`Submit`; +export const roundedButton = () => + html`Submit`; ``` ```js preview-story -export const circularButton = () => html`+`; +export const circularButton = () => + html`+`; ``` ## Prefix & Suffix slots @@ -68,8 +83,15 @@ The simba-button supports having a prefix or a suffix, through content projectio ```js preview-story export const prefixButton = () => html` - - + + Submit @@ -80,8 +102,15 @@ export const prefixButton = () => html` export const suffixButton = () => html` Submit - - + + `; @@ -90,7 +119,7 @@ export const suffixButton = () => html` ## Disabled ```js preview-story -export const disabledButton = () =>html` +export const disabledButton = () => html` Submit Submit Submit diff --git a/button/src/styles.css.js b/button/src/styles.css.js index 6fb2117..324f359 100644 --- a/button/src/styles.css.js +++ b/button/src/styles.css.js @@ -1,18 +1,37 @@ import { css } from '~/core'; -import { borderRadiusMixin } from '~/borders'; -import { coolGray } from '~/colors'; -import { typographyMixin } from '~/typography'; -import { spacing } from '~/spacing'; +import { base, full } from '~/radii'; +import { + coolGray50, + coolGray100, + coolGray200, + coolGray300, + coolGray600, + coolGray700, +} from '~/colors'; +import { + familySans, + sizeBaseSize, + sizeBaseLineHeight, + weightMedium, + sizeSmSize, + sizeSmLineHeight, + sizeXlSize, + sizeXlLineHeight, +} from '~/typography'; +import { s1_5, s2_5, s3, s4, s5 } from '~/spacing'; export default css` :host { display: inline-block; cursor: pointer; background-color: var(--simba-color-primary-500); - color: ${coolGray[50]}; - ${borderRadiusMixin()} - ${typographyMixin('sans', 'base', 'medium')} - padding: ${spacing['2.5']} ${spacing['4']}; + color: ${coolGray50}; + border-radius: ${base}; + font-family: ${familySans}; + font-size: ${sizeBaseSize}; + line-height: ${sizeBaseLineHeight}; + font-weight: ${weightMedium}; + padding: ${s2_5} ${s4}; transition: var(--theme-background-transition), var(--theme-color-transition); } @@ -46,7 +65,7 @@ export default css` :host([variation='outline']), :host([variation='text']) { - box-shadow: 0 0 1px 1px ${coolGray[300]}; + box-shadow: 0 0 1px 1px ${coolGray300}; color: var(--simba-text-color); } @@ -64,32 +83,34 @@ export default css` :host([variation='outline']:hover), :host([variation='text']:hover) { - background-color: ${coolGray[100]}; + background-color: ${coolGray100}; } :host([variation='outline']:active), :host([variation='text']:active) { - background-color: ${coolGray[200]}; + background-color: ${coolGray200}; } :host([variation='outline']:focus), :host([variation='text']:focus) { - box-shadow: 0 0 1px 1px ${coolGray[300]}, + box-shadow: 0 0 1px 1px ${coolGray300}, 0 0 0 3px var(--simba-focus-ring-color); } :host([size='small']) { - ${typographyMixin('sans', 'sm', 'medium')} - padding: ${spacing['1.5']} ${spacing['3']}; + font-size: ${sizeSmSize}; + line-height: ${sizeSmLineHeight}; + padding: ${s1_5} ${s3}; } :host([size='large']) { - ${typographyMixin('sans', 'xl', 'medium')} - padding: ${spacing['3']} ${spacing['5']}; + font-size: ${sizeXlSize}; + line-height: ${sizeXlLineHeight}; + padding: ${s3} ${s5}; } :host([rounded]) { - ${borderRadiusMixin('full')} + border-radius: ${full}; } :host([disabled]) { @@ -112,16 +133,16 @@ export default css` :host([theme='dark'][variation='text']), :host([theme='dark'][variation='outline']) { - color: ${coolGray[50]}; + color: ${coolGray50}; } :host([theme='dark'][variation='text']:hover), :host([theme='dark'][variation='outline']:hover) { - background-color: ${coolGray[700]}; + background-color: ${coolGray700}; } :host([theme='dark'][variation='text']:active), :host([theme='dark'][variation='outline']:active) { - background-color: ${coolGray[600]}; + background-color: ${coolGray600}; } `; diff --git a/checkbox-group/doc/index.md b/checkbox-group/doc/index.md index 281ea38..c42eefc 100644 --- a/checkbox-group/doc/index.md +++ b/checkbox-group/doc/index.md @@ -6,13 +6,29 @@ Checkbox group Webcomponent. import { html } from '~/core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; +<<<<<<< HEAD import '../simba-checkbox.js'; import '../simba-checkbox-indeterminate.js'; import '../simba-checkbox-group.js'; +======= +import '@divriots/starter-simba/checkbox-group/simba-checkbox.js'; +import '@divriots/starter-simba/checkbox-group/simba-checkbox-indeterminate.js'; +import '@divriots/starter-simba/checkbox-group/simba-checkbox-group.js'; +>>>>>>> restructure tokens, improve documentation loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/checkbox-group/simba-checkbox.js'; +import '@divriots/starter-simba/checkbox-group/simba-checkbox-indeterminate.js'; +import '@divriots/starter-simba/checkbox-group/simba-checkbox-group.js'; +``` + ```js preview-story export const input = () => html` html` diff --git a/collapsible/src/SimbaCollapsible.js b/collapsible/src/SimbaCollapsible.js index 6272b6f..b789780 100644 --- a/collapsible/src/SimbaCollapsible.js +++ b/collapsible/src/SimbaCollapsible.js @@ -1,5 +1,5 @@ import { LionCollapsible } from '@lion/collapsible'; -import { spacing } from '~/spacing'; +import { s3_5 } from '~/spacing'; import { SimbaCollapsibleButton } from './SimbaCollapsibleButton.js'; import styles from './styles.css.js'; @@ -109,10 +109,7 @@ export class SimbaCollapsible extends LionCollapsible { } __addPadding() { - this._contentNode.style.setProperty('padding-top', spacing['3.5'].cssText); - this._contentNode.style.setProperty( - 'padding-bottom', - spacing['3.5'].cssText - ); + this._contentNode.style.setProperty('padding-top', s3_5.cssText); + this._contentNode.style.setProperty('padding-bottom', s3_5.cssText); } } diff --git a/collapsible/src/SimbaCollapsibleButton.js b/collapsible/src/SimbaCollapsibleButton.js index 47c370e..982a9d9 100644 --- a/collapsible/src/SimbaCollapsibleButton.js +++ b/collapsible/src/SimbaCollapsibleButton.js @@ -1,7 +1,12 @@ import { html, css } from '~/core'; import { SimbaButton } from '~/button'; -import { typographyMixin } from '~/typography'; -import { borderRadiusMixin } from '~/borders'; +import { + familyMono, + size2xlSize, + size2xlLineHeight, + weightBold, +} from '~/typography'; +import { none } from '~/radii'; export class SimbaCollapsibleButton extends SimbaButton { static get styles() { @@ -10,7 +15,7 @@ export class SimbaCollapsibleButton extends SimbaButton { css` :host { width: 100%; - ${borderRadiusMixin('none')}; + border-radius: ${none}; } .button-content { @@ -18,7 +23,10 @@ export class SimbaCollapsibleButton extends SimbaButton { } .suffix { - ${typographyMixin('mono', '2xl', 'bold')}; + font-family: ${familyMono}; + font-size: ${size2xlSize}; + line-height: ${size2xlLineHeight}; + font-weight: ${weightBold}; } `, ]; diff --git a/collapsible/src/styles.css.js b/collapsible/src/styles.css.js index 888cc99..98950d4 100644 --- a/collapsible/src/styles.css.js +++ b/collapsible/src/styles.css.js @@ -1,26 +1,25 @@ import { css } from '~/core'; -import { coolGray } from '~/colors'; -import { spacing } from '~/spacing'; +import { coolGray50, coolGray300 } from '~/colors'; +import { s0_5, s3_5 } from '~/spacing'; export default css` ::slotted([slot='content']) { - margin-top: ${spacing['0.5']}; - padding-right: ${spacing['3.5']}; - padding-left: ${spacing['3.5']}; - box-shadow: 0 0 0 1px ${coolGray['300']}; + margin-top: ${s0_5}; + padding-right: ${s3_5}; + padding-left: ${s3_5}; + box-shadow: 0 0 0 1px ${coolGray300}; } ::slotted([slot='content']:focus-within) { - box-shadow: 0 0 0 1px ${coolGray['300']}, + box-shadow: 0 0 0 1px ${coolGray300}, 0 0 0 3px var(--simba-focus-ring-color); } :host([theme='dark']) ::slotted([slot='content']) { - box-shadow: 0 0 0 1px ${coolGray['50']}; + box-shadow: 0 0 0 1px ${coolGray50}; } :host([theme='dark']) ::slotted([slot='content']:focus-within) { - box-shadow: 0 0 0 1px ${coolGray['50']}, - 0 0 0 3px var(--simba-focus-ring-color); + box-shadow: 0 0 0 1px ${coolGray50}, 0 0 0 3px var(--simba-focus-ring-color); } `; diff --git a/colors/doc/index.md b/colors/doc/index.md index 965b363..632b98b 100644 --- a/colors/doc/index.md +++ b/colors/doc/index.md @@ -1,37 +1,39 @@ # Colors ```js script -import { html } from '~/core' +import { html } from '~/core'; import '~/token-display'; -import { - coolGray as coolGrayTokens, - red as redTokens, - amber as amberTokens, - emerald as emeraldTokens, - blue as blueTokens, - indigo as indigoTokens, - purple as purpleTokens, - pink as pinkTokens, -} from '../src/colors.css.js'; - +import * as _colors from '~/colors'; ``` ## Usage The color palettes are tokenized as CSS tagged literals (CSSResult) which can be used directly inside `static get styles`. +You can import the token group from the main entrypoint (or `/tokens`): + +```js +import { colors } from '@divriots/starter-simba'; // colors.red500 +``` + +or a specific color from the token entrypoint: + +```js +import { red500 } from '@divriots/starter-simba/colors'; +``` + ```js preview-story -import { css, LitElement } from '~/core'; -import { red } from '../src/colors.css.js'; +import { css, LitElement } from '@divriots/starter-simba'; +import { red500 } from '@divriots/starter-simba/colors'; -class DemoRed extends LitElement { +class DemoRed extends LitElement { static get styles() { return css` :host { display: block; width: 50px; height: 50px; - background-color: ${red[500]}; + background-color: ${red500}; } `; } @@ -47,53 +49,94 @@ export const usageInCE = () => html``; ```js story export const coolGray = () => - html``; + html` + entry[0].startsWith('coolGray') + )} + >`; ``` ### Red ```js story export const redd = () => - html``; + html` + entry[0].startsWith('red') + )} + >`; ``` ### Amber ```js story export const amber = () => - html``; + html` + entry[0].startsWith('amber') + )} + >`; ``` ### Emerald ```js story export const emerald = () => - html``; + html` + entry[0].startsWith('emerald') + )} + >`; ``` ### Blue ```js story export const blue = () => - html``; + html` + entry[0].startsWith('blue') + )} + >`; ``` ### Indigo ```js story export const indigo = () => - html``; + html` + entry[0].startsWith('indigo') + )} + >`; ``` ### Purple ```js story export const purple = () => - html``; + html` + entry[0].startsWith('purple') + )} + >`; ``` ### Pink ```js story -export const pink = () => html``; +export const pink = () => + html` + entry[0].startsWith('pink') + )} + >`; ``` diff --git a/colors/index.js b/colors/index.js index 9f27716..b96d6f2 100644 --- a/colors/index.js +++ b/colors/index.js @@ -1 +1 @@ -export * from './src/colors.css.js'; +export * from './src/_colors.js'; diff --git a/colors/src/_colors.js b/colors/src/_colors.js new file mode 100644 index 0000000..e820fbe --- /dev/null +++ b/colors/src/_colors.js @@ -0,0 +1,87 @@ +/** + * Do not edit directly + * Generated on Thu, 02 Dec 2021 13:44:16 GMT + */ + +import { css } from '@lion/core'; + +export const coolGray50 = css`#F9FAFB`; +export const coolGray100 = css`#F3F4F6`; +export const coolGray200 = css`#E5E7EB`; +export const coolGray300 = css`#D1D5DB`; +export const coolGray400 = css`#9CA3AF`; +export const coolGray500 = css`#6B7280`; +export const coolGray600 = css`#4B5563`; +export const coolGray700 = css`#374151`; +export const coolGray800 = css`#1F2937`; +export const coolGray900 = css`#111827`; +export const red50 = css`#FEF2F2`; +export const red100 = css`#FEE2E2`; +export const red200 = css`#FECACA`; +export const red300 = css`#FCA5A5`; +export const red400 = css`#F87171`; +export const red500 = css`#EF4444`; +export const red600 = css`#DC2626`; +export const red700 = css`#B91C1C`; +export const red800 = css`#991B1B`; +export const red900 = css`#7F1D1D`; +export const amber50 = css`#FFFBEB`; +export const amber100 = css`#FEF3C7`; +export const amber200 = css`#FDE68A`; +export const amber300 = css`#FCD34D`; +export const amber400 = css`#FBBF24`; +export const amber500 = css`#F59E0B`; +export const amber600 = css`#D97706`; +export const amber700 = css`#B45309`; +export const amber800 = css`#92400E`; +export const amber900 = css`#78350F`; +export const emerald50 = css`#ECFDF5`; +export const emerald100 = css`#D1FAE5`; +export const emerald200 = css`#A7F3D0`; +export const emerald300 = css`#6EE7B7`; +export const emerald400 = css`#34D399`; +export const emerald500 = css`#10B981`; +export const emerald600 = css`#059669`; +export const emerald700 = css`#047857`; +export const emerald800 = css`#065F46`; +export const emerald900 = css`#064E3B`; +export const blue50 = css`#EFF6FF`; +export const blue100 = css`#DBEAFE`; +export const blue200 = css`#BFDBFE`; +export const blue300 = css`#93C5FD`; +export const blue400 = css`#60A5FA`; +export const blue500 = css`#3B82F6`; +export const blue600 = css`#2563EB`; +export const blue700 = css`#1D4ED8`; +export const blue800 = css`#1E40AF`; +export const blue900 = css`#1E3A8A`; +export const indigo50 = css`#EEF2FF`; +export const indigo100 = css`#E0E7FF`; +export const indigo200 = css`#C7D2FE`; +export const indigo300 = css`#A5B4FC`; +export const indigo400 = css`#818CF8`; +export const indigo500 = css`#6366F1`; +export const indigo600 = css`#4F46E5`; +export const indigo700 = css`#4338CA`; +export const indigo800 = css`#3730A3`; +export const indigo900 = css`#312E81`; +export const purple50 = css`#F5F3FF`; +export const purple100 = css`#EDE9FE`; +export const purple200 = css`#DDD6FE`; +export const purple300 = css`#C4B5FD`; +export const purple400 = css`#A78BFA`; +export const purple500 = css`#8B5CF6`; +export const purple600 = css`#7C3AED`; +export const purple700 = css`#6D28D9`; +export const purple800 = css`#5B21B6`; +export const purple900 = css`#4C1D95`; +export const pink50 = css`#FDF2F8`; +export const pink100 = css`#FCE7F3`; +export const pink200 = css`#FBCFE8`; +export const pink300 = css`#F9A8D4`; +export const pink400 = css`#F472B6`; +export const pink500 = css`#EC4899`; +export const pink600 = css`#DB2777`; +export const pink700 = css`#BE185D`; +export const pink800 = css`#9D174D`; +export const pink900 = css`#831843`; diff --git a/colors/src/colors.css.js b/colors/src/colors.css.js deleted file mode 100644 index 6e5be95..0000000 --- a/colors/src/colors.css.js +++ /dev/null @@ -1,105 +0,0 @@ -import { css } from '~/core'; - -export const coolGray = { - 50: css`#F9FAFB`, - 100: css`#F3F4F6`, - 200: css`#E5E7EB`, - 300: css`#D1D5DB`, - 400: css`#9CA3AF`, - 500: css`#6B7280`, - 600: css`#4B5563`, - 700: css`#374151`, - 800: css`#1F2937`, - 900: css`#111827`, -}; - -export const red = { - 50: css`#FEF2F2`, - 100: css`#FEE2E2`, - 200: css`#FECACA`, - 300: css`#FCA5A5`, - 400: css`#F87171`, - 500: css`#EF4444`, - 600: css`#DC2626`, - 700: css`#B91C1C`, - 800: css`#991B1B`, - 900: css`#7F1D1D`, -}; - -export const amber = { - 50: css`#FFFBEB`, - 100: css`#FEF3C7`, - 200: css`#FDE68A`, - 300: css`#FCD34D`, - 400: css`#FBBF24`, - 500: css`#F59E0B`, - 600: css`#D97706`, - 700: css`#B45309`, - 800: css`#92400E`, - 900: css`#78350F`, -}; - -export const emerald = { - 50: css`#ECFDF5`, - 100: css`#D1FAE5`, - 200: css`#A7F3D0`, - 300: css`#6EE7B7`, - 400: css`#34D399`, - 500: css`#10B981`, - 600: css`#059669`, - 700: css`#047857`, - 800: css`#065F46`, - 900: css`#064E3B`, -}; - -export const blue = { - 50: css`#EFF6FF`, - 100: css`#DBEAFE`, - 200: css`#BFDBFE`, - 300: css`#93C5FD`, - 400: css`#60A5FA`, - 500: css`#3B82F6`, - 600: css`#2563EB`, - 700: css`#1D4ED8`, - 800: css`#1E40AF`, - 900: css`#1E3A8A`, -}; - -export const indigo = { - 50: css`#EEF2FF`, - 100: css`#E0E7FF`, - 200: css`#C7D2FE`, - 300: css`#A5B4FC`, - 400: css`#818CF8`, - 500: css`#6366F1`, - 600: css`#4F46E5`, - 700: css`#4338CA`, - 800: css`#3730A3`, - 900: css`#312E81`, -}; - -export const purple = { - 50: css`#F5F3FF`, - 100: css`#EDE9FE`, - 200: css`#DDD6FE`, - 300: css`#C4B5FD`, - 400: css`#A78BFA`, - 500: css`#8B5CF6`, - 600: css`#7C3AED`, - 700: css`#6D28D9`, - 800: css`#5B21B6`, - 900: css`#4C1D95`, -}; - -export const pink = { - 50: css`#FDF2F8`, - 100: css`#FCE7F3`, - 200: css`#FBCFE8`, - 300: css`#F9A8D4`, - 400: css`#F472B6`, - 500: css`#EC4899`, - 600: css`#DB2777`, - 700: css`#BE185D`, - 800: css`#9D174D`, - 900: css`#831843`, -}; diff --git a/colors/src/colors.tokens.js b/colors/src/colors.tokens.js new file mode 100644 index 0000000..fc5c20f --- /dev/null +++ b/colors/src/colors.tokens.js @@ -0,0 +1,260 @@ +export default { + colors: { + coolGray: { + 50: { + value: '#F9FAFB', + }, + 100: { + value: '#F3F4F6', + }, + 200: { + value: '#E5E7EB', + }, + 300: { + value: '#D1D5DB', + }, + 400: { + value: '#9CA3AF', + }, + 500: { + value: '#6B7280', + }, + 600: { + value: '#4B5563', + }, + 700: { + value: '#374151', + }, + 800: { + value: '#1F2937', + }, + 900: { + value: '#111827', + }, + }, + red: { + 50: { + value: '#FEF2F2', + }, + 100: { + value: '#FEE2E2', + }, + 200: { + value: '#FECACA', + }, + 300: { + value: '#FCA5A5', + }, + 400: { + value: '#F87171', + }, + 500: { + value: '#EF4444', + }, + 600: { + value: '#DC2626', + }, + 700: { + value: '#B91C1C', + }, + 800: { + value: '#991B1B', + }, + 900: { + value: '#7F1D1D', + }, + }, + amber: { + 50: { + value: '#FFFBEB', + }, + 100: { + value: '#FEF3C7', + }, + 200: { + value: '#FDE68A', + }, + 300: { + value: '#FCD34D', + }, + 400: { + value: '#FBBF24', + }, + 500: { + value: '#F59E0B', + }, + 600: { + value: '#D97706', + }, + 700: { + value: '#B45309', + }, + 800: { + value: '#92400E', + }, + 900: { + value: '#78350F', + }, + }, + emerald: { + 50: { + value: '#ECFDF5', + }, + 100: { + value: '#D1FAE5', + }, + 200: { + value: '#A7F3D0', + }, + 300: { + value: '#6EE7B7', + }, + 400: { + value: '#34D399', + }, + 500: { + value: '#10B981', + }, + 600: { + value: '#059669', + }, + 700: { + value: '#047857', + }, + 800: { + value: '#065F46', + }, + 900: { + value: '#064E3B', + }, + }, + blue: { + 50: { + value: '#EFF6FF', + }, + 100: { + value: '#DBEAFE', + }, + 200: { + value: '#BFDBFE', + }, + 300: { + value: '#93C5FD', + }, + 400: { + value: '#60A5FA', + }, + 500: { + value: '#3B82F6', + }, + 600: { + value: '#2563EB', + }, + 700: { + value: '#1D4ED8', + }, + 800: { + value: '#1E40AF', + }, + 900: { + value: '#1E3A8A', + }, + }, + indigo: { + 50: { + value: '#EEF2FF', + }, + 100: { + value: '#E0E7FF', + }, + 200: { + value: '#C7D2FE', + }, + 300: { + value: '#A5B4FC', + }, + 400: { + value: '#818CF8', + }, + 500: { + value: '#6366F1', + }, + 600: { + value: '#4F46E5', + }, + 700: { + value: '#4338CA', + }, + 800: { + value: '#3730A3', + }, + 900: { + value: '#312E81', + }, + }, + purple: { + 50: { + value: '#F5F3FF', + }, + 100: { + value: '#EDE9FE', + }, + 200: { + value: '#DDD6FE', + }, + 300: { + value: '#C4B5FD', + }, + 400: { + value: '#A78BFA', + }, + 500: { + value: '#8B5CF6', + }, + 600: { + value: '#7C3AED', + }, + 700: { + value: '#6D28D9', + }, + 800: { + value: '#5B21B6', + }, + 900: { + value: '#4C1D95', + }, + }, + pink: { + 50: { + value: '#FDF2F8', + }, + 100: { + value: '#FCE7F3', + }, + 200: { + value: '#FBCFE8', + }, + 300: { + value: '#F9A8D4', + }, + 400: { + value: '#F472B6', + }, + 500: { + value: '#EC4899', + }, + 600: { + value: '#DB2777', + }, + 700: { + value: '#BE185D', + }, + 800: { + value: '#9D174D', + }, + 900: { + value: '#831843', + }, + }, + }, +}; diff --git a/dialog/doc/index.md b/dialog/doc/index.md index bc773c9..e4a8091 100644 --- a/dialog/doc/index.md +++ b/dialog/doc/index.md @@ -11,12 +11,21 @@ The frame acts as a visual container and allows adding an easy to use close butt ```js script import { html } from '~/core'; import '~/button/simba-button.js'; -import '../simba-dialog.js'; -import '../simba-dialog-frame.js'; -import { emerald, coolGray } from '~/colors'; -import { spacing } from '~/spacing'; -import { borderRadiusMixin } from '~/borders'; -import { typographyMixin } from '~/typography'; +import '@divriots/starter-simba/dialog/simba-dialog.js'; +import '@divriots/starter-simba/dialog/simba-dialog-frame.js'; +import { emerald100, emerald500, coolGray500 } from '~/colors'; +import { s1_5 } from '~/spacing'; +import { full } from '~/radii'; +import { sizeXlSize, sizeXlLineHeight, weightSemibold } from '~/typography'; +``` + +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/dialog/simba-dialog.js'; +import '@divriots/starter-simba/dialog/simba-dialog-frame.js'; ``` ```js preview-story @@ -24,16 +33,17 @@ export const dialogFrame = () => html` Open -
- Dialog Frame Title -
-
- Hello, World! -
+
Dialog Frame Title
+
Hello, World!
- { - ev.target.dispatchEvent(new Event('close-overlay', { bubbles: true })); - }}>Close + { + ev.target.dispatchEvent( + new Event('close-overlay', { bubbles: true }) + ); + }} + >Close
@@ -49,9 +59,7 @@ export const simple = () => html` Open -
- Hello, World! -
+
Hello, World!
`; @@ -68,9 +76,15 @@ export const noPadding = () => html`
Hello, World! - { - ev.target.dispatchEvent(new Event('close-overlay', { bubbles: true })); - }}>Close + { + ev.target.dispatchEvent( + new Event('close-overlay', { bubbles: true }) + ); + }} + >Close
@@ -89,25 +103,53 @@ export const noHeader = () => html` Open
-
-

Payment successful!

-

Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eius aliquam laudantium explicabo pariatur iste doorem animi vitae error totam. At sapiente aliquam accusamus facere veritatis.

+ background-color: ${emerald100}; + border-radius: ${full}; + " + > + ✓ +
+

+ Payment successful! +

+

+ Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eius aliquam + laudantium explicabo pariatur iste doorem animi vitae error totam. At + sapiente aliquam accusamus facere veritatis. +

-
- { - ev.target.dispatchEvent(new Event('close-overlay', { bubbles: true })); - }}>Cancel - { - ev.target.dispatchEvent(new Event('close-overlay', { bubbles: true })); - }}>Deactivate +
+ { + ev.target.dispatchEvent( + new Event('close-overlay', { bubbles: true }) + ); + }} + >Cancel + { + ev.target.dispatchEvent( + new Event('close-overlay', { bubbles: true }) + ); + }} + >Deactivate
diff --git a/dialog/src/SimbaDialogFrame.js b/dialog/src/SimbaDialogFrame.js index 8e6cda1..d3a1250 100644 --- a/dialog/src/SimbaDialogFrame.js +++ b/dialog/src/SimbaDialogFrame.js @@ -1,8 +1,13 @@ import { LitElement, html, css } from '~/core'; -import { coolGray } from '~/colors'; -import { spacing } from '~/spacing'; -import { borderRadiusMixin } from '~/borders'; -import { typographyMixin } from '~/typography'; +import { coolGray100, coolGray300 } from '~/colors'; +import { s0_5, s3, s4, s5 } from '~/spacing'; +import { md } from '~/radii'; +import { + weightSemibold, + sizeLgSize, + sizeLgLineHeight, + familyMono, +} from '~/typography'; import { ThemeMixin } from 'dark-theme-utils'; export class SimbaDialogFrame extends ThemeMixin(LitElement) { @@ -13,27 +18,31 @@ export class SimbaDialogFrame extends ThemeMixin(LitElement) { width: 600px; position: relative; box-shadow: 0 3px 5px 1px rgba(0, 0, 0, 0.4); - background-color: ${coolGray[100]}; - ${borderRadiusMixin('md')}; + background-color: ${coolGray100}; + border-radius: ${md}; } .close-btn { position: absolute; - top: ${spacing['0.5']}; - right: ${spacing['0.5']}; + top: ${s0_5}; + right: ${s0_5}; margin: 0; - ${typographyMixin('mono', 'lg', 'normal')} + font-family: ${familyMono}; + font-size: ${sizeLgSize}; + line-height: ${sizeLgLineHeight}; } :host(:not([no-padding])) .content-container { - padding: ${spacing['4']} ${spacing['5']}; + padding: ${s4} ${s5}; } ::slotted([slot='header']) { text-align: center; - padding: ${spacing['3']}; - border-bottom: 1px solid ${coolGray[300]}; - ${typographyMixin('sans', 'lg', 'semibold')} + padding: ${s3}; + border-bottom: 1px solid ${coolGray300}; + font-weight: ${weightSemibold}; + font-size: ${sizeLgSize}; + line-height: ${sizeLgLineHeight}; } :host([theme='dark']) { diff --git a/doc-layout/src/color-toggler.js b/doc-layout/src/color-toggler.js index 958ce19..e363f71 100644 --- a/doc-layout/src/color-toggler.js +++ b/doc-layout/src/color-toggler.js @@ -1,8 +1,15 @@ import { LitElement, html, css, unsafeCSS } from '~/core'; -import { spacing } from '~/spacing'; -import { theme, setTheme } from '~/themes'; +import { theme, setTheme, defaultThemes } from '~/themes'; +import { s5 } from '~/spacing'; import * as colors from '~/colors'; +// Get unique color values, "red", "purple", without the lightness suffixes (50, 100) +const colorKeys = [ + ...new Set( + Object.entries(colors).map(([clr, val]) => clr.replace(/\d/g, '')) + ), +]; + export class ColorToggler extends LitElement { static get styles() { return [ @@ -16,15 +23,15 @@ export class ColorToggler extends LitElement { .radio { -webkit-appearance: none; -moz-appearance: none; - width: ${spacing['5']}; - height: ${spacing['5']}; + width: ${s5}; + height: ${s5}; outline: none; display: inline-block; vertical-align: top; position: relative; margin: 4px; cursor: pointer; - border: 1px solid ${colors.coolGray[600]}; + border: 1px solid ${colors.coolGray600}; border-radius: 100%; transition: border-color 0.2s ease-in-out; } @@ -39,18 +46,18 @@ export class ColorToggler extends LitElement { } .radio:hover { - border-color: ${colors.coolGray[400]}; + border-color: ${colors.coolGray400}; } - ${Object.entries(colors) + ${colorKeys .map( (col) => css` - .${unsafeCSS(col[0])} { - background-color: ${col[1][500]}; + .${unsafeCSS(col)} { + background-color: ${colors[`${col}500`]}; } - .${unsafeCSS(col[0])}:checked { - border-color: ${col[1][500]}; + .${unsafeCSS(col)}:checked { + border-color: ${colors[`${col}500`]}; } ` ) @@ -66,24 +73,29 @@ export class ColorToggler extends LitElement { constructor() { super(); + // if the theme from local storage is a custom theme, don't do anything let colorTheme = localStorage.getItem('simba-color'); - if (!colorTheme || colorTheme === 'null') { + if (!colorTheme) { setTheme('indigo'); - } else { + } else if (defaultThemes.includes(colorTheme)) { setTheme(colorTheme); + } else { + console.warn( + `${colorTheme} is not a default color, this Toggler component doesn't know how to set custom themes` + ); } } render() { return html` - ${Object.entries(colors).map( + ${colorKeys.map( (col) => html`` )} diff --git a/doc-styles/src/DocsMenu.js b/doc-styles/src/DocsMenu.js new file mode 100644 index 0000000..b229555 --- /dev/null +++ b/doc-styles/src/DocsMenu.js @@ -0,0 +1,38 @@ +import { LitElement, html, css } from '~/core'; +import { coolGray50 } from '~/colors'; +import { s2, s2_5 } from '~/spacing'; +import 'dark-theme-utils/theme-toggler'; +import '../color-toggler.js'; + +export class DocsMenu extends LitElement { + static get styles() { + return [ + css` + :host { + position: fixed; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + background-color: rgba(0, 0, 0, 0.6); + top: 0; + left: 0; + padding: ${s2_5}; + } + + p { + color: ${coolGray50}; + padding-right: ${s2}; + } + `, + ]; + } + + render() { + return html` +

Themes

+ + + `; + } +} diff --git a/form-core/src/choice-box-styles.css.js b/form-core/src/choice-box-styles.css.js index f594aa1..8346b63 100644 --- a/form-core/src/choice-box-styles.css.js +++ b/form-core/src/choice-box-styles.css.js @@ -1,7 +1,7 @@ import { css } from '~/core'; -import { weight } from '~/typography'; -import { spacing } from '~/spacing'; -import { coolGray } from '~/colors'; +import { weightNormal } from '~/typography'; +import { s4 } from '~/spacing'; +import { coolGray50, coolGray100 } from '~/colors'; /** * Styles that apply to all choice groups: @@ -19,7 +19,7 @@ export const choiceBoxStyles = css` ::slotted([slot='label']) { cursor: pointer; margin-left: 6px; - font-weight: ${weight['normal']}; + font-weight: ${weightNormal}; } :host([disabled]) { @@ -35,8 +35,8 @@ export const choiceBoxStyles = css` ::slotted(.form-control) { -webkit-appearance: none; -moz-appearance: none; - width: ${spacing['4']}; - height: ${spacing['4']}; + width: ${s4}; + height: ${s4}; outline: none; display: inline-block; vertical-align: top; @@ -44,7 +44,7 @@ export const choiceBoxStyles = css` margin: 0; cursor: pointer; border: 1px solid var(--border, var(--simba-color-primary-200)); - background: var(--background, ${coolGray[50]}); + background: var(--background, ${coolGray50}); transition: background 0.3s, border-color 0.3s, box-shadow 0.2s; } @@ -93,7 +93,7 @@ export const choiceBoxStyles = css` } :host([theme='dark']) ::slotted([slot='label']) { - color: ${coolGray[100]}; + color: ${coolGray100}; } :host([theme='dark']) ::slotted(.form-control) { diff --git a/form-core/src/input-styles.css.js b/form-core/src/input-styles.css.js index cb66f00..c50c761 100644 --- a/form-core/src/input-styles.css.js +++ b/form-core/src/input-styles.css.js @@ -1,12 +1,20 @@ import { css } from '~/core'; -import { borderRadiusMixin } from '~/borders'; -import { coolGray } from '~/colors'; -import { typographyMixin, weight } from '~/typography'; -import { spacing } from '~/spacing'; +import { md } from '~/radii'; +import { + coolGray100, + coolGray300, + coolGray400, + coolGray500, + coolGray600, + coolGray700, + coolGray900, +} from '~/colors'; +import { sizeSmSize, sizeSmLineHeight, weightMedium } from '~/typography'; +import { s1, s2, s3 } from '~/spacing'; export const inputStyles = css` :host { - display: block; + display: block;~ } ::slotted(*:not(simba-select-invoker)) { @@ -15,11 +23,12 @@ export const inputStyles = css` } .input-group__container > .input-group__input ::slotted(.form-control) { - border: 1px solid ${coolGray[300]}; - ${borderRadiusMixin('md')}; - ${typographyMixin('sans', 'sm')}; - padding: ${spacing['2']} ${spacing['3']}; - margin-top: ${spacing['1']}; + border: 1px solid ${coolGray300}; + border-radius: ${md}; + font-size: ${sizeSmSize}; + line-height: ${sizeSmLineHeight}; + padding: ${s2} ${s3}; + margin-top: ${s1}; width: 100%; } @@ -33,52 +42,53 @@ export const inputStyles = css` } ::slotted([slot='label']) { - color: ${coolGray[700]}; - font-weight: ${weight['medium']}; + color: ${coolGray700}; + font-weight: ${weightMedium}; } ::slotted([slot='help-text']) { - color: ${coolGray[500]}; - ${typographyMixin('sans', 'sm', 'normal')} + color: ${coolGray500}; + font-size: ${sizeSmSize}; + line-height: ${sizeSmLineHeight}; } ::slotted(.form-control) { - color: ${coolGray[900]}; + color: ${coolGray900}; } :host([theme='dark']) ::slotted([slot='label']) { - color: ${coolGray[100]}; + color: ${coolGray100}; } :host([theme='dark']) ::slotted([slot='help-text']) { - color: ${coolGray[300]}; + color: ${coolGray300}; } :host([theme='dark']) ::slotted(.form-control:not([type='checkbox']):not([type='radio']):not([disabled])) { - color: ${coolGray[100]}; + color: ${coolGray100}; background-color: var(--simba-bg-color-dark); } :host([theme='dark']) ::slotted(.form-control:not([type='checkbox']):not([type='radio']):not(:focus)) { - border-color: ${coolGray[400]}; + border-color: ${coolGray400}; } :host([theme='dark']) ::slotted(.form-control)::placeholder { - color: ${coolGray[500]}; + color: ${coolGray500}; } :host([theme='dark'][disabled]) ::slotted(.form-control) { - background-color: ${coolGray[600]}; - color: ${coolGray[400]}; + background-color: ${coolGray600}; + color: ${coolGray400}; } :host([theme='dark'][disabled]) ::slotted([slot='label']) { - color: ${coolGray[500]}; + color: ${coolGray500}; } :host([theme='dark'][disabled]) ::slotted([slot='help-text']) { - color: ${coolGray[600]}; + color: ${coolGray600}; } `; diff --git a/icons/doc/index.md b/icons/doc/index.md index 03d1665..613e7f7 100644 --- a/icons/doc/index.md +++ b/icons/doc/index.md @@ -3,8 +3,16 @@ Icon resolution manager. Ensures icons are bundled into iconsets and asynchronously loaded for performance. ```js script -import { html } from '~/core' -import '../simba-icon.js'; +import { html } from '~/core'; +import '@divriots/starter-simba/icons/simba-icon.js'; +``` + +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/icons/simba-icon.js'; ``` ## Adding a resolver @@ -29,5 +37,6 @@ Where this `index.js` re-exports svgs inside lit templates from the different `. To load an icon: ```js preview-story -export const simbaIcon = () => html``; +export const simbaIcon = () => + html``; ``` diff --git a/index.html b/index.html new file mode 100644 index 0000000..5c744e1 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + + Document + + +

Hello, World!

+ + diff --git a/index.js b/index.js new file mode 100644 index 0000000..e8e81b2 --- /dev/null +++ b/index.js @@ -0,0 +1,28 @@ +export * from '~/tokens'; + +export * from '~/button'; +export * from '~/collapsible'; +export * from '~/checkbox-group'; +export * from '~/dialog'; +export * from '~/icons'; +export * from '~/input'; +export * from '~/input-amount'; +export * from '~/input-date'; +export * from '~/input-datepicker'; +export * from '~/input-email'; +export * from '~/input-iban'; +export * from '~/input-range'; +export * from '~/input-stepper'; +export * from '~/radio-group'; +export * from '~/select'; +export * from '~/switch'; +export * from '~/textarea'; +export * from '~/tooltip'; +export * from '~/validation-feedback'; + +export * from '~/form-core'; +export * from '~/themes'; + +export * from '~/core'; +export * from '~/localize'; +export * from '~/overlays'; diff --git a/input-amount/doc/index.md b/input-amount/doc/index.md index 90ab7a0..e400f61 100644 --- a/input-amount/doc/index.md +++ b/input-amount/doc/index.md @@ -7,11 +7,19 @@ import { html } from '~/core'; import { Required, Validator } from '~/form-core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; -import '../simba-input-amount.js'; +import '@divriots/starter-simba/input-amount/simba-input-amount.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/input-amount/simba-input-amount.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. Additionally, you can also see that the placeholder and the formatted value of the input gets reformatted on locale changes. diff --git a/input-date/doc/index.md b/input-date/doc/index.md index b603d38..b3c2372 100644 --- a/input-date/doc/index.md +++ b/input-date/doc/index.md @@ -7,11 +7,19 @@ import { html } from '~/core'; import { Required, Validator } from '~/form-core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; -import '../simba-input-date.js'; +import '@divriots/starter-simba/input-date/simba-input-date.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/input-date/simba-input-date.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. ```js preview-story diff --git a/input-datepicker/doc/index.md b/input-datepicker/doc/index.md index 18531b6..69dd054 100644 --- a/input-datepicker/doc/index.md +++ b/input-datepicker/doc/index.md @@ -7,11 +7,19 @@ import { html } from '~/core'; import { Required, Validator } from '~/form-core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; -import '../simba-input-datepicker.js'; +import '@divriots/starter-simba/input-datepicker/simba-input-datepicker.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/input-datepicker/simba-input-datepicker.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. ```js preview-story diff --git a/input-datepicker/src/SimbaCalendar.js b/input-datepicker/src/SimbaCalendar.js index ff457a7..24cae58 100644 --- a/input-datepicker/src/SimbaCalendar.js +++ b/input-datepicker/src/SimbaCalendar.js @@ -142,7 +142,11 @@ export class SimbaCalendar extends ScopedElementsMixin( } }); - monthNavHeading.style.setProperty('width', `${Math.ceil(maxWidth)}px`); + monthNavHeading.style.setProperty( + 'width', + // 8px extra padding + `${Math.ceil(maxWidth) + 8}px` + ); } } diff --git a/input-datepicker/src/styles.css.js b/input-datepicker/src/styles.css.js index d070665..19db60d 100644 --- a/input-datepicker/src/styles.css.js +++ b/input-datepicker/src/styles.css.js @@ -1,8 +1,20 @@ import { css } from '~/core'; -import { borderRadiusMixin } from '~/borders'; -import { spacing } from '~/spacing'; -import { coolGray } from '~/colors'; -import { typographyMixin } from '~/typography'; +import { base, md, none, full } from '~/radii'; +import { s0, s1, s1_5, s2, s2_5, s3, s4 } from '~/spacing'; +import { coolGray50, coolGray200, coolGray300, coolGray600 } from '~/colors'; +import { + familyMono, + weightBold, + weightMedium, + sizeBaseSize, + sizeBaseLineHeight, + sizeLgSize, + sizeLgLineHeight, + sizeXlSize, + sizeXlLineHeight, + size2xlSize, + size2xlLineHeight, +} from '~/typography'; export const pickerStyles = css` .input-group__container { @@ -13,12 +25,12 @@ export const pickerStyles = css` :host(:focus-within) .input-group__container { box-shadow: 0 0 0 2px var(--simba-color-primary-500); - ${borderRadiusMixin()}; + border-radius: ${base}; overflow: hidden; } :host(:focus-within) ::slotted([slot='suffix']) { - box-shadow: -1px 0 0 0 ${coolGray[300]}; + box-shadow: -1px 0 0 0 ${coolGray300}; } :host(:focus-within) @@ -31,14 +43,18 @@ export const pickerStyles = css` } .input-group__container > .input-group__input ::slotted(.form-control) { - ${borderRadiusMixin('', 'l')}; + border-radius: ${none}; + border-top-left-radius: ${base}; + border-bottom-left-radius: ${base}; margin-top: 0; } ::slotted([slot='suffix']) { transition: unset; - ${borderRadiusMixin('', 'r')}; - padding: ${spacing['1.5']} ${spacing['2.5']}; + border-radius: ${none}; + border-top-right-radius: ${base}; + border-bottom-right-radius: ${base}; + padding: ${s1_5} ${s2_5}; border: 0; } @@ -50,7 +66,7 @@ export const pickerStyles = css` } :host([disabled]) ::slotted([slot='suffix']) { - background-color: ${coolGray[50]}; + background-color: ${coolGray50}; filter: none; } @@ -63,7 +79,7 @@ export const pickerStyles = css` } :host([theme='dark'][disabled]) ::slotted([slot='suffix']) { - background-color: ${coolGray[600]}; + background-color: ${coolGray600}; } `; @@ -71,9 +87,9 @@ export const frameStyles = css` :host { display: block; box-shadow: 0 3px 5px 1px rgba(0, 0, 0, 0.4); - background: ${coolGray[50]}; + background: ${coolGray50}; position: relative; - ${borderRadiusMixin('md')}; + border-radius: ${md}; overflow: hidden; } @@ -88,23 +104,28 @@ export const frameStyles = css` .calendar-overlay__header { position: relative; background-color: var(--simba-color-primary-500); - color: ${coolGray[50]}; + color: ${coolGray50}; } .calendar-overlay__heading { - ${typographyMixin('sans', 'xl', 'bold')}; + font-size: ${sizeXlSize}; + line-height: ${sizeXlLineHeight}; + font-weight: ${weightBold}; margin: 0; - padding: ${spacing['1.5']} ${spacing['3']}; + padding: ${s1_5} ${s3}; } .calendar-overlay__close-button { position: absolute; top: 0; right: 0; - color: ${coolGray[50]}; - ${typographyMixin('mono', '2xl', 'bold')}; - ${borderRadiusMixin('none')}; - padding: ${spacing['1']} ${spacing['2']}; + color: ${coolGray50}; + font-family: ${familyMono}; + font-size: ${size2xlSize}; + line-height: ${size2xlLineHeight}; + font-weight: ${weightBold}; + border-radius: ${none}; + padding: ${s1} ${s2}; } .calendar-overlay__close-button:hover { @@ -113,9 +134,11 @@ export const frameStyles = css` .calendar-overlay__current { text-align: center; - padding-bottom: ${spacing['4']}; + padding-bottom: ${s4}; margin: 0; - ${typographyMixin('sans', 'lg', 'bold')}; + font-size: ${sizeLgSize}; + line-height: ${sizeLgLineHeight}; + font-weight: ${weightBold}; } `; @@ -127,10 +150,12 @@ export const calendarStyles = css` } .calendar__navigation simba-button { - ${typographyMixin('mono', 'xl', 'medium')}; - padding: ${spacing['0']}; - margin: -2 ${spacing['2']} 0 ${spacing['2']}; - margin-top: -2px; + font-family: ${familyMono}; + font-size: ${sizeXlSize}; + line-height: ${sizeXlLineHeight}; + font-weight: ${weightMedium}; + padding: ${s0}; + margin: -2px ${s2} 0 ${s2}; } .calendar__navigation__year, @@ -139,26 +164,32 @@ export const calendarStyles = css` } .calendar__navigation-heading { - ${typographyMixin('sans', '', 'bold')}; + font-weight: ${weightBold}; + font-size: ${sizeBaseSize}; + line-height: ${sizeBaseLineHeight}; text-align: center; } + .calendar__navigation__year .calendar__navigation-heading { + padding: ${s0} ${s2}; + } + .calendar__day-button, .calendar__day-button[disabled] { - background-color: ${coolGray[50]}; + background-color: ${coolGray50}; } .calendar__day-button { - ${borderRadiusMixin('full')}; + border-radius: ${full}; } .calendar__day-button[selected] { - color: ${coolGray[50]}; + color: ${coolGray50}; background-color: var(--simba-color-primary-500); } .calendar__day-button:active { - background-color: ${coolGray[200]}; + background-color: ${coolGray200}; } .calendar__day-button:hover { @@ -187,7 +218,7 @@ export const calendarStyles = css` :host([theme='dark']) .calendar__day-button { background-color: var(--simba-bg-color-dark); - color: ${coolGray[50]}; + color: ${coolGray50}; } :host([theme='dark']) .calendar__day-button[today] { @@ -209,6 +240,6 @@ export const calendarStyles = css` } :host([theme='dark']) .calendar__day-button[disabled] { - color: ${coolGray[600]}; + color: ${coolGray600}; } `; diff --git a/input-email/doc/index.md b/input-email/doc/index.md index 4c84b1a..dfa128b 100644 --- a/input-email/doc/index.md +++ b/input-email/doc/index.md @@ -7,11 +7,19 @@ import { html } from '~/core'; import { Required } from '~/form-core'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; import { localize } from '~/localize'; -import '../simba-input-email.js'; +import '@divriots/starter-simba/input-email/simba-input-email.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/input-email/simba-input-email.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. ```js preview-story diff --git a/input-iban/doc/index.md b/input-iban/doc/index.md index d5be169..bd33386 100644 --- a/input-iban/doc/index.md +++ b/input-iban/doc/index.md @@ -7,11 +7,19 @@ import { html } from '~/core'; import { Required, Validator } from '~/form-core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; -import '../simba-input-iban.js'; +import '@divriots/starter-simba/input-iban/simba-input-iban.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/input-iban/simba-input-iban.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. ```js preview-story diff --git a/input-range/doc/index.md b/input-range/doc/index.md index 1b55f06..dd80d44 100644 --- a/input-range/doc/index.md +++ b/input-range/doc/index.md @@ -7,11 +7,19 @@ import { html } from '~/core'; import { Required, Validator } from '~/form-core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; -import '../simba-input-range.js'; +import '@divriots/starter-simba/input-range/simba-input-range.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/input-range/simba-input-range.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. ```js preview-story diff --git a/input-range/src/styles.css.js b/input-range/src/styles.css.js index 6c79acf..d543c00 100644 --- a/input-range/src/styles.css.js +++ b/input-range/src/styles.css.js @@ -1,9 +1,9 @@ import { css } from '~/core'; -import { borderRadiusMixin } from '~/borders'; -import { spacing } from '~/spacing'; +import { full } from '~/radii'; +import { s0, s4 } from '~/spacing'; const thumbSize = css` - ${spacing['4']} + ${s4} `; const track = css` @@ -15,7 +15,7 @@ const track = css` const thumb = css` height: ${thumbSize}; width: ${thumbSize}; - ${borderRadiusMixin('full')}; + border-radius: ${full}; background-color: var(--simba-color-primary-500); cursor: pointer; `; @@ -80,7 +80,7 @@ export default css` } .input-group__container > .input-group__input ::slotted(.form-control) { - padding: ${spacing['0']}; + padding: ${s0}; border: none; } diff --git a/input-stepper/doc/index.md b/input-stepper/doc/index.md index f678dd8..0ab4719 100644 --- a/input-stepper/doc/index.md +++ b/input-stepper/doc/index.md @@ -4,14 +4,23 @@ Input stepper Webcomponent. ```js script import { html } from '~/core'; +import { setTheme } from '~/themes'; import { Required, Validator } from '~/form-core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; -import '../simba-input-stepper.js'; +import '@divriots/starter-simba/input-stepper/simba-input-stepper.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/input-stepper/simba-input-stepper.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. ```js preview-story diff --git a/input-stepper/src/styles.css.js b/input-stepper/src/styles.css.js index 91df53a..cd63a70 100644 --- a/input-stepper/src/styles.css.js +++ b/input-stepper/src/styles.css.js @@ -1,7 +1,7 @@ import { css } from '~/core'; -import { borderRadiusMixin } from '~/borders'; -import { spacing } from '~/spacing'; -import { coolGray } from '~/colors'; +import { base, none } from '~/radii'; +import { s1_5, s2_5 } from '~/spacing'; +import { coolGray100, coolGray300, coolGray600 } from '~/colors'; export default css` .input-group__container { @@ -11,7 +11,7 @@ export default css` :host(:focus-within) .input-group__container { box-shadow: 0 0 0 2px var(--simba-color-primary-500); - ${borderRadiusMixin()}; + border-radius: ${base}; overflow: hidden; } @@ -24,41 +24,45 @@ export default css` } .input-group__container > .input-group__input ::slotted(.form-control) { - ${borderRadiusMixin('none')}; + border-radius: ${none}; margin-top: 0; } ::slotted(simba-button) { - padding: ${spacing['1.5']} ${spacing['2.5']}; + padding: ${s1_5} ${s2_5}; } ::slotted(simba-button:focus) { - box-shadow: 0 0 1px 1px ${coolGray[300]}, + box-shadow: 0 0 1px 1px ${coolGray300}, 0 0 0 3px var(--simba-color-primary-500); } ::slotted(simba-button[slot='prefix']) { - ${borderRadiusMixin('', 'l')}; + border-radius: ${none}; + border-top-left-radius: ${base}; + border-bottom-left-radius: ${base}; } ::slotted(simba-button[slot='suffix']) { - ${borderRadiusMixin('', 'r')}; + border-radius: ${none}; + border-top-right-radius: ${base}; + border-bottom-right-radius: ${base}; } :host(:focus-within) ::slotted(simba-button[slot='prefix']) { - box-shadow: 1px 0 0 0 ${coolGray[300]}; + box-shadow: 1px 0 0 0 ${coolGray300}; } :host(:focus-within) ::slotted(simba-button[slot='suffix']) { - box-shadow: -1px 0 0 0 ${coolGray[300]}; + box-shadow: -1px 0 0 0 ${coolGray300}; } :host([theme='dark']) ::slotted(simba-button) { background-color: var(--simba-bg-color-dark); - color: ${coolGray[100]}; + color: ${coolGray100}; } :host([theme='dark'][disabled]) ::slotted(simba-button) { - background-color: ${coolGray[600]}; + background-color: ${coolGray600}; } `; diff --git a/input/doc/index.md b/input/doc/index.md index fd6d60e..f14fe6b 100644 --- a/input/doc/index.md +++ b/input/doc/index.md @@ -7,11 +7,19 @@ import { html } from '~/core'; import { Required, Validator } from '~/form-core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; -import '../simba-input.js'; +import '@divriots/starter-simba/input/simba-input.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/input/simba-input.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. ```js preview-story diff --git a/migration.md b/migration.md new file mode 100644 index 0000000..3d086bc --- /dev/null +++ b/migration.md @@ -0,0 +1,114 @@ +# Migration + +## 0.4.0 + +Biggest change here is the (base) tokens: + +- colors +- radii (previously borders) +- typography +- spacing + +They have been simplified and the syntax has changed. + +### Colors + +#### Before + +```js +import { coolGray } from '@divriots/starter-simba/colors'; + +coolGray[50]; // css`#F9FAFB` +``` + +#### After + +```js +import { coolGray50 } from '@divriots/starter-simba/colors'; +import { colors } from '@divriots/starter-simba/tokens'; + +coolGray50; // css`#F9FAFB` +colors.coolGray50; // css`#F9FAFB` +``` + +### Radii + +#### Before + +```js +import { borderRadiusMixin } from '@divriots/starter-simba/borders'; + +/** + * css` + * border-radius-top-left: 0.25rem; + * border-radius-bottom-left: 0.25rem; + * border-radius-top-right: 0; + * border-radius-bottom-right: 0; + * ` + */ +borderRadiusMixin('', 'l'); +``` + +##### After + +You just get the value now, the corners you are now responsible for yourself. +This is more simple and more descriptive. + +```js +import { base } from '@divriots/starter-simba/colors'; +import { radii } from '@divriots/starter-simba/tokens'; + +base; // css`0.25rem` +radii.base; // css`0.25rem` +``` + +### Typography + +#### Before + +```js +import { typographyMixin } from '@divriots/starter-simba/typography'; + +/** + * css` + * font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; + * font-weight: 500; + * line-height: 1.5rem; + * font-size: 1rem; + * ` + */ +typographyMixin('mono', 'base', 'medium'); +``` + +#### After + +You just get the value now, the font CSS rules you are now responsible for yourself. +This is more simple and more descriptive. + +```js +import { sizeXlSize } from '@divriots/starter-simba/typography'; +import { typography } from '@divriots/starter-simba/tokens'; + +sizeXlSize; // css`1.25rem` +typography.sizeXlSize; // css`1.25rem` +``` + +### Spacing + +#### Before + +```js +import { spacing } from '@divriots/starter-simba/spacing'; + +spacing['4']; // css`1rem` +``` + +#### After + +```js +import { s4 } from '@divriots/starter-simba/spacing'; +import { spacing } from '@divriots/starter-simba/tokens'; + +s4; // css`1rem` +spacing.s4; // css`1rem` +``` diff --git a/borders/design/figma.link b/radii/design/figma.link similarity index 100% rename from borders/design/figma.link rename to radii/design/figma.link diff --git a/radii/doc/index.md b/radii/doc/index.md new file mode 100644 index 0000000..5b3c89d --- /dev/null +++ b/radii/doc/index.md @@ -0,0 +1,65 @@ +# Borders + +```js script +import { html } from '~/core'; +import '~/token-display'; +import * as radii from '~/radii'; +``` + +## Usage + +The border radii are tokenized as CSS tagged literals (CSSResult) which can be used directly inside `static get styles`. + +You can import the token group from the main entrypoint (or `/tokens`): + +```js +import { radii } from '@divriots/starter-simba'; // radii.base +``` + +or a specific color from the token entrypoint: + +```js +import { base } from '@divriots/starter-simba/radii'; +``` + +```js preview-story +import { css, LitElement } from '@divriots/starter-simba'; +import { base } from '@divriots/starter-simba/radii'; +import { ThemeMixin } from 'dark-theme-utils'; + +class DemoRounded extends ThemeMixin(LitElement) { + static get styles() { + return css` + :host { + display: block; + width: 50px; + height: 50px; + background-color: var(--simba-color-primary-700); + border-radius: ${base}; + transition: var(--theme-background-transition); + } + + :host([theme='dark']) { + background-color: var(--simba-color-primary-200); + } + `; + } +} +customElements.define('demo-rounded', DemoRounded); + +export const usageInCE = () => html``; +``` + +## Sizes + +You can specify the size of the border-radius. + +```js story +export const sizes = () => + html` + + `; +``` diff --git a/radii/index.js b/radii/index.js new file mode 100644 index 0000000..dd2beca --- /dev/null +++ b/radii/index.js @@ -0,0 +1 @@ +export * from './src/_radii.js'; diff --git a/radii/src/_radii.js b/radii/src/_radii.js new file mode 100644 index 0000000..01f7409 --- /dev/null +++ b/radii/src/_radii.js @@ -0,0 +1,16 @@ +/** + * Do not edit directly + * Generated on Thu, 02 Dec 2021 13:44:16 GMT + */ + +import { css } from '@lion/core'; + +export const none = css`0`; +export const sm = css`0.125rem`; +export const base = css`0.25rem`; +export const md = css`0.375rem`; +export const lg = css`0.5rem`; +export const xl = css`0.75rem`; +export const xl2 = css`1rem`; +export const xl3 = css`1.5rem`; +export const full = css`9999px`; diff --git a/radii/src/radii.tokens.js b/radii/src/radii.tokens.js new file mode 100644 index 0000000..434324f --- /dev/null +++ b/radii/src/radii.tokens.js @@ -0,0 +1,13 @@ +export default { + radii: { + none: { value: '0' }, + sm: { value: '0.125rem' }, + base: { value: '0.25rem' }, + md: { value: '0.375rem' }, + lg: { value: '0.5rem' }, + xl: { value: '0.75rem' }, + xl2: { value: '1rem' }, + xl3: { value: '1.5rem' }, + full: { value: '9999px' }, + }, +}; diff --git a/radio-group/doc/index.md b/radio-group/doc/index.md index ee4ab1f..7b9a403 100644 --- a/radio-group/doc/index.md +++ b/radio-group/doc/index.md @@ -7,12 +7,21 @@ import { html } from '~/core'; import { Required, Validator } from '~/form-core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; -import '../simba-radio.js'; -import '../simba-radio-group.js'; +import '@divriots/starter-simba/radio-group/simba-radio.js'; +import '@divriots/starter-simba/radio-group/simba-radio-group.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/radio-group/simba-radio.js'; +import '@divriots/starter-simba/radio-group/simba-radio-group.js'; +``` + ```js preview-story export const input = () => html` (token) => token.attributes.category === cat; + +const generateFilesArr = (tokensCategories) => { + return tokensCategories.map((cat) => ({ + filter: tokenFilter(cat), + destination: `colors/src/_${cat}.js`, + format: 'cssLiterals', + })); +}; + +export default { + source: ['**/*.tokens.js'], + format: { + cssLiterals: (opts) => { + const { dictionary, file } = opts; + let output = formatHelpers.fileHeader(file); + output += `import { css } from '@lion/core';\n\n`; + + dictionary.allTokens.forEach((token) => { + const { path, original } = token; + const [, ..._path] = path; + const name = _path.reduce((acc, str, index) => { + // converts to camelCase + const _str = + index === 0 ? str : str.charAt(0).toUpperCase() + str.slice(1); + return acc.concat(_str); + }, ''); + output += `export const ${name} = css\`${original.value}\`;\n`; + }); + + return output; + }, + }, + platforms: { + css: { + transformGroup: 'css', + prefix: 'simba', + buildPath: '/tokens/', + files: [ + { + destination: 'tokens.css', + format: 'css/variables', + }, + ], + }, + js: { + transformGroup: 'js', + buildPath: '/', + files: generateFilesArr(['colors', 'typography', 'spacing', 'radii']), + }, + }, +}; diff --git a/select/doc/index.md b/select/doc/index.md index 9a75aba..47baf72 100644 --- a/select/doc/index.md +++ b/select/doc/index.md @@ -8,9 +8,9 @@ import { Required } from '~/form-core'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; import { localize } from '~/localize'; import { SimbaOption } from '../src/SimbaOption.js'; -import '../simba-select.js'; -import '../simba-select-rich.js'; -import '../simba-option.js'; +import '@divriots/starter-simba/select/simba-select.js'; +import '@divriots/starter-simba/select/simba-select-rich.js'; +import '@divriots/starter-simba/select/simba-option.js'; loadDefaultFeedbackMessages(); @@ -45,6 +45,17 @@ class ColorOption extends SimbaOption { customElements.define('color-option', ColorOption); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/select/simba-select.js'; + +import '@divriots/starter-simba/select/simba-select-rich.js'; +import '@divriots/starter-simba/select/simba-option.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. ```js preview-story diff --git a/select/src/styles.css.js b/select/src/styles.css.js index f6ea083..0a9bdbb 100644 --- a/select/src/styles.css.js +++ b/select/src/styles.css.js @@ -1,7 +1,15 @@ import { css } from '~/core'; -import { coolGray } from '~/colors'; -import { spacing } from '~/spacing'; -import { borderRadiusMixin } from '~/borders'; +import { + coolGray50, + coolGray100, + coolGray200, + coolGray300, + coolGray400, + coolGray600, + coolGray800, +} from '~/colors'; +import { s1, s3 } from '~/spacing'; +import { base } from '~/radii'; export const invokerStyles = css` :host(:focus:not([disabled])), @@ -10,15 +18,15 @@ export const invokerStyles = css` } :host { - ${borderRadiusMixin()}; - background-color: ${coolGray[50]}; - border: 1px solid ${coolGray[300]}; - margin-top: ${spacing['1']}; + border-radius: ${base}; + background-color: ${coolGray50}; + border: 1px solid ${coolGray300}; + margin-top: ${s1}; transition: background-color 0.3s ease-in-out; } :host(:hover) { - background-color: ${coolGray[50]}; + background-color: ${coolGray50}; } :host(:focus), @@ -29,12 +37,12 @@ export const invokerStyles = css` } :host(:active) { - background-color: ${coolGray[100]}; + background-color: ${coolGray100}; } ::slotted([slot='after']) { - width: ${spacing['3']}; - height: ${spacing['3']}; + width: ${s3}; + height: ${s3}; } :host([theme='dark']) { @@ -52,7 +60,7 @@ export const optionStyles = css` } :host([theme='dark']:hover) { - background-color: ${coolGray[600]}; + background-color: ${coolGray600}; } :host([theme='dark'][checked]) { @@ -63,7 +71,7 @@ export const optionStyles = css` export const optionsStyles = css` .input-group__container > .input-group__input ::slotted(.form-control) { display: block; - background-color: ${coolGray[50]}; + background-color: ${coolGray50}; padding: 0; overflow: hidden; } @@ -84,15 +92,15 @@ export const selectStyles = css` width: 14px; right: 10px; top: 15px; - fill: ${coolGray[800]}; + fill: ${coolGray800}; transition: var(--theme-fill-transition); } :host([disabled]) .input-group__arrow { - fill: ${coolGray[400]}; + fill: ${coolGray400}; } :host([theme='dark']) .input-group__arrow { - fill: ${coolGray[200]}; + fill: ${coolGray200}; } `; diff --git a/spacing/doc/index.md b/spacing/doc/index.md index f694711..2d1cde3 100644 --- a/spacing/doc/index.md +++ b/spacing/doc/index.md @@ -3,25 +3,36 @@ ```js script import { html } from '~/core'; import '~/token-display'; -import { spacing as spacingTokens } from '../src/spacing.css.js'; +import * as spacing from '~/spacing'; ``` ## Usage The spacings are tokenized as CSS tagged literals (CSSResult) which can be used directly inside `static get styles`. +You can import the token group from the main entrypoint (or `/tokens`): + +```js +import { spacing } from '@divriots/starter-simba'; // spacing.s48 +``` + +or a specific color from the token entrypoint: + +```js +import { s48 } from '@divriots/starter-simba/spacing'; +``` + ```js preview-story -import { css, LitElement } from '~/core'; -import { indigo } from '~/colors'; import { ThemeMixin } from 'dark-theme-utils'; -import { spacing } from '../src/spacing.css.js'; +import { css, LitElement } from '@divriots/starter-simba'; +import { s48 } from '@divriots/starter-simba/spacing'; class DemoSpacing extends ThemeMixin(LitElement) { static get styles() { return css` :host { display: block; - width: ${spacing[48]}; + width: ${s48}; height: 10px; background-color: var(--simba-color-primary-700); transition: var(--theme-background-transition); @@ -44,6 +55,6 @@ export const usageInCE = () => html``; export const spacings = () => html``; ``` diff --git a/spacing/index.js b/spacing/index.js index 4df73b3..92e775b 100644 --- a/spacing/index.js +++ b/spacing/index.js @@ -1 +1 @@ -export * from './src/index.js'; +export * from './src/_spacing.js'; diff --git a/spacing/src/_spacing.js b/spacing/src/_spacing.js new file mode 100644 index 0000000..9c45927 --- /dev/null +++ b/spacing/src/_spacing.js @@ -0,0 +1,42 @@ +/** + * Do not edit directly + * Generated on Thu, 02 Dec 2021 13:44:16 GMT + */ + +import { css } from '@lion/core'; + +export const s0 = css`0px`; +export const px = css`1px`; +export const s0_5 = css`0.125rem`; +export const s1 = css`0.25rem`; +export const s1_5 = css`0.375rem`; +export const s2 = css`0.5rem`; +export const s2_5 = css`0.625rem`; +export const s3 = css`0.75rem`; +export const s3_5 = css`0.875rem`; +export const s4 = css`1rem`; +export const s5 = css`1.25rem`; +export const s6 = css`1.5rem`; +export const s7 = css`1.75rem`; +export const s8 = css`2rem`; +export const s9 = css`2.25rem`; +export const s10 = css`2.5rem`; +export const s11 = css`2.75rem`; +export const s12 = css`3rem`; +export const s14 = css`3.5rem`; +export const s16 = css`4rem`; +export const s20 = css`5rem`; +export const s24 = css`6rem`; +export const s28 = css`7rem`; +export const s32 = css`8rem`; +export const s36 = css`9rem`; +export const s40 = css`10rem`; +export const s44 = css`11rem`; +export const s48 = css`12rem`; +export const s52 = css`13rem`; +export const s56 = css`14rem`; +export const s60 = css`15rem`; +export const s64 = css`16rem`; +export const s72 = css`18rem`; +export const s80 = css`20rem`; +export const s96 = css`24rem`; diff --git a/spacing/src/index.js b/spacing/src/index.js deleted file mode 100644 index b9319e4..0000000 --- a/spacing/src/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './spacing.css.js'; diff --git a/spacing/src/spacing.css.js b/spacing/src/spacing.css.js deleted file mode 100644 index e9453eb..0000000 --- a/spacing/src/spacing.css.js +++ /dev/null @@ -1,39 +0,0 @@ -import { css } from '~/core'; - -export const spacing = { - 0: css`0px`, - px: css`1px`, - 0.5: css`0.125rem`, - 1: css`0.25rem`, - 1.5: css`0.375rem`, - 2: css`0.5rem`, - 2.5: css`0.625rem`, - 3: css`0.75rem`, - 3.5: css`0.875rem`, - 4: css`1rem`, - 5: css`1.25rem`, - 6: css`1.5rem`, - 7: css`1.75rem`, - 8: css`2rem`, - 9: css`2.25rem`, - 10: css`2.5rem`, - 11: css`2.75rem`, - 12: css`3rem`, - 14: css`3.5rem`, - 16: css`4rem`, - 20: css`5rem`, - 24: css`6rem`, - 28: css`7rem`, - 32: css`8rem`, - 36: css`9rem`, - 40: css`10rem`, - 44: css`11rem`, - 48: css`12rem`, - 52: css`13rem`, - 56: css`14rem`, - 60: css`15rem`, - 64: css`16rem`, - 72: css`18rem`, - 80: css`20rem`, - 96: css`24rem`, -}; diff --git a/spacing/src/spacing.tokens.js b/spacing/src/spacing.tokens.js new file mode 100644 index 0000000..2cce7b7 --- /dev/null +++ b/spacing/src/spacing.tokens.js @@ -0,0 +1,39 @@ +export default { + spacing: { + s0: { value: '0px' }, + px: { value: '1px' }, + s0_5: { value: '0.125rem' }, + s1: { value: '0.25rem' }, + s1_5: { value: '0.375rem' }, + s2: { value: '0.5rem' }, + s2_5: { value: '0.625rem' }, + s3: { value: '0.75rem' }, + s3_5: { value: '0.875rem' }, + s4: { value: '1rem' }, + s5: { value: '1.25rem' }, + s6: { value: '1.5rem' }, + s7: { value: '1.75rem' }, + s8: { value: '2rem' }, + s9: { value: '2.25rem' }, + s10: { value: '2.5rem' }, + s11: { value: '2.75rem' }, + s12: { value: '3rem' }, + s14: { value: '3.5rem' }, + s16: { value: '4rem' }, + s20: { value: '5rem' }, + s24: { value: '6rem' }, + s28: { value: '7rem' }, + s32: { value: '8rem' }, + s36: { value: '9rem' }, + s40: { value: '10rem' }, + s44: { value: '11rem' }, + s48: { value: '12rem' }, + s52: { value: '13rem' }, + s56: { value: '14rem' }, + s60: { value: '15rem' }, + s64: { value: '16rem' }, + s72: { value: '18rem' }, + s80: { value: '20rem' }, + s96: { value: '24rem' }, + }, +}; diff --git a/studio.config.json b/studio.config.json index 5d79243..51d349d 100644 --- a/studio.config.json +++ b/studio.config.json @@ -1,63 +1,36 @@ { - "packages": { - "dir": "", - "menu": [ - "introduction", - [ - "tokens", - [ - "colors", - "borders", - "typography", - "spacing" + "packages": { + "dir": "", + "menu": [ + "introduction", + ["tokens", ["colors", "radii", "typography", "spacing", "tokens"]], + [ + "components", + [ + "button", + "collapsible", + "checkbox-group", + "dialog", + "icons", + "input", + "input-amount", + "input-date", + "input-datepicker", + "input-email", + "input-iban", + "input-range", + "input-stepper", + "radio-group", + "select", + "switch", + "textarea", + "tooltip", + "validation-feedback" + ] + ], + ["infrastructure", ["form-core", "themes"]], + ["docs", ["token-display", "doc-styles"]], + ["re-exports-only", ["core", "localize", "overlays"]] ] - ], - [ - "components", - [ - "button", - "collapsible", - "checkbox-group", - "dialog", - "icons", - "input", - "input-amount", - "input-date", - "input-datepicker", - "input-email", - "input-iban", - "input-range", - "input-stepper", - "radio-group", - "select", - "switch", - "textarea", - "tooltip", - "validation-feedback" - ] - ], - [ - "infrastructure", - [ - "form-core", - "themes" - ] - ], - [ - "docs", - [ - "token-display", - "doc-layout" - ] - ], - [ - "re-exports-only", - [ - "core", - "localize", - "overlays" - ] - ] - ] - } -} \ No newline at end of file + } +} diff --git a/switch/doc/index.md b/switch/doc/index.md index 3be8895..b1615e6 100644 --- a/switch/doc/index.md +++ b/switch/doc/index.md @@ -4,8 +4,17 @@ Switch button component. ```js script import { html } from '~/core'; -import '../simba-switch.js'; -import '../simba-switch-button.js'; +import '@divriots/starter-simba/switch/simba-switch.js'; +import '@divriots/starter-simba/switch/simba-switch-button.js'; +``` + +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/switch/simba-switch.js'; +import '@divriots/starter-simba/switch/simba-switch-button.js'; ``` This component has an optional label and help-text, and when present (e.g. inside a form), @@ -24,9 +33,7 @@ export const switchDemo = () => ```js preview-story export const switchStandalone = () => - html` - - `; + html` `; ``` ## Disabled diff --git a/switch/src/button-styles.css.js b/switch/src/button-styles.css.js index 6dabb07..b19b991 100644 --- a/switch/src/button-styles.css.js +++ b/switch/src/button-styles.css.js @@ -1,6 +1,6 @@ import { css } from '~/core'; -import { borderRadiusMixin } from '~/borders'; -import { coolGray } from '~/colors'; +import { full } from '~/radii'; +import { coolGray50, coolGray400, coolGray500, coolGray600 } from '~/colors'; const trackPadding = -4; const thumbDiameter = 20; @@ -10,7 +10,7 @@ export default css` :host { width: auto; height: auto; - --thumb-elevation: 0 1px 3px ${coolGray['600']}; + --thumb-elevation: 0 1px 3px ${coolGray600}; --thumb-shadow: var(--thumb-elevation); } @@ -19,21 +19,21 @@ export default css` } .switch-button__track { - ${borderRadiusMixin('full')}; + border-radius: ${full}; height: calc(${thumbDiameter}px + 2 * ${trackPadding}px); width: calc(2.1 * ${thumbDiameter}px + 2 * ${trackPadding}px); - background-color: ${coolGray['400']}; + background-color: ${coolGray400}; transition: background-color 0.3s ease-in-out; } .switch-button__thumb { - ${borderRadiusMixin('full')}; + border-radius: ${full}; width: ${thumbDiameter}px; height: ${thumbDiameter}px; left: ${trackPadding}px; top: 50%; transform: translateY(-50%); - background-color: ${coolGray['50']}; + background-color: ${coolGray50}; box-shadow: var(--thumb-shadow); outline: none; transition: left 0.3s ease-in-out, box-shadow 0.3s ease-in-out; @@ -79,11 +79,11 @@ export default css` } :host([disabled]) .switch-button__thumb { - background-color: ${coolGray['400']}; + background-color: ${coolGray400}; } :host([disabled]) .switch-button__track { - background-color: ${coolGray['500']}; + background-color: ${coolGray500}; } :host([disabled][checked]) .switch-button__track { diff --git a/switch/src/styles.css.js b/switch/src/styles.css.js index 8646dc3..6358d27 100644 --- a/switch/src/styles.css.js +++ b/switch/src/styles.css.js @@ -1,5 +1,5 @@ import { css } from '~/core'; -import { borderRadiusMixin } from '~/borders'; +import { full } from '~/radii'; export default css` :host { @@ -12,7 +12,7 @@ export default css` border: none; padding: 0; margin: 0; - ${borderRadiusMixin('full')}; + border-radius: ${full}; } .input-group__container > .input-group__input ::slotted(.form-control:focus) { diff --git a/textarea/doc/index.md b/textarea/doc/index.md index f451ba1..51bf9b4 100644 --- a/textarea/doc/index.md +++ b/textarea/doc/index.md @@ -7,11 +7,19 @@ import { html } from '~/core'; import { Required, Validator } from '~/form-core'; import { localize } from '~/localize'; import { loadDefaultFeedbackMessages } from '@lion/validate-messages'; -import '../simba-textarea.js'; +import '@divriots/starter-simba/textarea/simba-textarea.js'; loadDefaultFeedbackMessages(); ``` +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/textarea/simba-textarea.js'; +``` + Click the flip locale button to see localized default label in action as well as the validator messages, switching between Dutch and English. ```js preview-story diff --git a/themes/src/theme.js b/themes/src/theme.js index 64790bc..4838403 100644 --- a/themes/src/theme.js +++ b/themes/src/theme.js @@ -1,45 +1,69 @@ import * as colors from '~/colors'; -import { family } from '~/typography'; +import { familySans, familySerif, familyMono } from '~/typography'; export let theme; +export const defaultThemes = [ + 'coolGray', + 'red', + 'amber', + 'emerald', + 'blue', + 'indigo', + 'purple', + 'pink', +]; + let hasSetGlobalTransition = false; export const setTheme = (_theme, _colors) => { + if (!_theme) { + return; + } + + if (!colors[`${_theme}50`] && !_colors) { + console.error( + `${_theme} is not a default color, please pass a scheme e.g. {50: #fff, 100: #eee}` + ); + return; + } + theme = _theme; + localStorage.setItem('simba-color', theme); // Pick either a custom palette from the user if pass, or pick as predefined theme - const clrs = _colors || colors[theme]; + const clrs = _colors || {}; - localStorage.setItem('simba-color', theme); const obj = { - '--simba-font-sans': family['sans'], - '--simba-font-serif': family['serif'], - '--simba-font-mono': family['mono'], - '--simba-color-primary-50': clrs[50], - '--simba-color-primary-100': clrs[100], - '--simba-color-primary-200': clrs[200], - '--simba-color-primary-300': clrs[300], - '--simba-color-primary-400': clrs[400], - '--simba-color-primary-500': clrs[500], - '--simba-color-primary-600': clrs[600], - '--simba-color-primary-700': clrs[700], - '--simba-color-primary-800': clrs[800], - '--simba-color-primary-900': clrs[900], - '--simba-focus-ring-color': clrs[300], - '--simba-text-color': colors.coolGray[900], - '--simba-text-color-dark': colors.coolGray[50], + '--simba-font-sans': familySans, + '--simba-font-serif': familySerif, + '--simba-font-mono': familyMono, + '--simba-color-primary-50': clrs[50] || colors[`${theme}50`], + '--simba-color-primary-100': clrs[100] || colors[`${theme}100`], + '--simba-color-primary-200': clrs[200] || colors[`${theme}200`], + '--simba-color-primary-300': clrs[300] || colors[`${theme}300`], + '--simba-color-primary-400': clrs[400] || colors[`${theme}400`], + '--simba-color-primary-500': clrs[500] || colors[`${theme}500`], + '--simba-color-primary-600': clrs[600] || colors[`${theme}600`], + '--simba-color-primary-700': clrs[700] || colors[`${theme}700`], + '--simba-color-primary-800': clrs[800] || colors[`${theme}800`], + '--simba-color-primary-900': clrs[900] || colors[`${theme}900`], + '--simba-focus-ring-color': clrs[300] || colors[`${theme}300`], + '--simba-text-color': colors.coolGray900, + '--simba-text-color-dark': colors.coolGray50, '--simba-bg-color': 'white', '--simba-bg-color-dark': '#24292e', - '--simba-switch-color-hover': `${clrs[500]}30`, - '--simba-switch-color-focus': `${clrs[500]}70`, - '--theme-toggler-focus-color': clrs[300], + '--simba-switch-color-hover': `${clrs[500] || colors[`${theme}500`]}30`, + '--simba-switch-color-focus': `${clrs[500] || colors[`${theme}500`]}70`, + '--theme-toggler-focus-color': clrs[300] || colors[`${theme}300`], /** Used by docs only */ - '--simba-heading-color': colors.coolGray[900], - '--simba-heading-color-dark': colors.coolGray[50], - '--simba-blockquote-bg-color': clrs[50], - '--simba-blockquote-bg-color-dark': `${clrs[900]}30`, + '--simba-heading-color': colors.coolGray900, + '--simba-heading-color-dark': colors.coolGray50, + '--simba-blockquote-bg-color': clrs[50] || colors[`${theme}50`], + '--simba-blockquote-bg-color-dark': `${ + clrs[900] || colors[`${theme}900`] + }30`, }; for (let [key, value] of Object.entries(obj)) { diff --git a/token-display/src/index.js b/token-display/src/index.js index 4733112..f47b364 100644 --- a/token-display/src/index.js +++ b/token-display/src/index.js @@ -1,6 +1,6 @@ import { LitElement, html, css } from '~/core'; -import { coolGray } from '~/colors'; -import { borderRadiusMixin } from '~/borders'; +import { coolGray400, blue300, blue500 } from '~/colors'; +import { sm, none, base } from '~/radii'; import { ThemeMixin } from 'dark-theme-utils'; class TokenDisplay extends ThemeMixin(LitElement) { @@ -29,24 +29,28 @@ class TokenDisplay extends ThemeMixin(LitElement) { margin: 0; } + :host([token-type='typography']) .item p { + margin: 1em 0 0 0; + } + .item__css-text { - color: ${coolGray[400]}; + color: ${coolGray400}; } .cell { width: 50px; height: 25px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); - ${borderRadiusMixin('sm')}; + border-radius: ${sm}; transition: var(--simba-theme-transition); } .cell--border { width: 100px; - height: 50px; + height: 100px; background-color: var(--simba-color-primary-700); box-shadow: none; - ${borderRadiusMixin('none')}; + border-radius: ${none}; } :host([theme='dark']) .cell--border { @@ -60,15 +64,24 @@ class TokenDisplay extends ThemeMixin(LitElement) { color: var(--simba-color-primary-700); } + .cell--line-height { + border: 1px solid ${blue500}; + border-radius: ${base}; + } + :host([theme='dark']) .cell--typography { color: var(--simba-color-primary-200); } + :host([theme='dark']) .cell--line-height { + border-color: ${blue300}; + } + .cell--spacing { height: 10px; background-color: var(--simba-color-primary-700); box-shadow: none; - ${borderRadiusMixin('none')}; + border-radius: ${none}; } :host([theme='dark']) .cell--spacing { @@ -90,26 +103,63 @@ class TokenDisplay extends ThemeMixin(LitElement) { attribute: 'token-type', }, tokens: { attribute: false }, - cssKeyIncluded: { - type: Boolean, - reflect: true, - attribute: 'css-key-included', - }, - cssMixin: { - type: Boolean, - reflect: true, - attribute: 'css-mixin', - }, + cssProp: { attribute: false }, }; } constructor() { super(); this.tokenType = ''; + this.cssProp = ''; this.tokens = {}; this.cssKeyIncluded = false; } + sortTokens() { + switch (this.tokenType) { + case 'spacing': + return this.tokens.sort((a, b) => { + const spaceMatchA = a[1].cssText.match(/([\d.]+)(.+)/); + const spaceMatchB = b[1].cssText.match(/([\d.]+)(.+)/); + const pixelsA = + spaceMatchA[2] === 'rem' + ? parseFloat(spaceMatchA[1]) * 16 + : parseFloat(spaceMatchA); + const pixelsB = + spaceMatchB[2] === 'rem' + ? parseFloat(spaceMatchB[1]) * 16 + : parseFloat(spaceMatchB); + + return pixelsA - pixelsB; + }); + case 'color': + return this.tokens.sort((a, b) => { + const lightnessAMatch = a[0].match(/(.+?)(\d+)/); + const lightnessBMatch = b[0].match(/(.+?)(\d+)/); + if (lightnessAMatch[1] !== lightnessBMatch[1]) { + return a[0] - b[0]; + } + return ( + parseInt(lightnessAMatch[2], 10) - parseInt(lightnessBMatch[2], 10) + ); + }); + case 'typography': + if ( + this.tokens[0][0].endsWith('Size') || + this.tokens[0][0].endsWith('LineHeight') || + this.tokens[0][0].startsWith('weight') + ) { + return this.tokens.sort((a, b) => { + const aNumber = parseFloat(a[1].cssText.match(/[\d.]+/g)[0]); + const bNumber = parseFloat(b[1].cssText.match(/[\d.]+/g)[0]); + return aNumber - bNumber; + }); + } + return this.tokens; + } + return this.tokens; + } + colorTemplate(cssLiteral, opts) { return html`
+

${opts.param}

${cssLiteral.cssText}
`; @@ -131,11 +184,17 @@ class TokenDisplay extends ThemeMixin(LitElement) { typographyTemplate(cssLiteral, opts) { return html` -
+
The quick brown fox jumped over the lazy dog.
-

${opts.param}

-
${cssLiteral.cssText}
+

${opts.key}

+
${this
+        .cssProp}: ${cssLiteral.cssText}
`; } @@ -156,8 +215,8 @@ class TokenDisplay extends ThemeMixin(LitElement) { switch (this.tokenType) { case 'color': return this.colorTemplate(cssLiteral, opts); - case 'border': - return this.borderTemplate(cssLiteral, opts); + case 'radii': + return this.radiiTemplate(cssLiteral, opts); case 'typography': return this.typographyTemplate(cssLiteral, opts); case 'spacing': @@ -188,20 +247,11 @@ class TokenDisplay extends ThemeMixin(LitElement) { } render() { - let entries = Object.entries(this.tokens); - if (this.tokenType === 'spacing') { - entries = entries.sort((a, b) => { - let _a = a[0] === 'px' ? '0.25' : a[0]; - let _b = b[0] === 'px' ? '0.25' : b[0]; - return _a - _b; - }); - } - return html`
${this.cssMixin ? this.cssMixinTemplate() - : entries.map( + : this.sortTokens().map( (entry) => html`
${this.tokenTemplate(entry[1], { key: entry[0] })} diff --git a/tokens/index.js b/tokens/index.js new file mode 100644 index 0000000..2952a82 --- /dev/null +++ b/tokens/index.js @@ -0,0 +1,4 @@ +export * as colors from '~/colors/src/_colors.js'; +export * as radii from '~/radii/src/_radii.js'; +export * as typography from '~/typography/src/_typography.js'; +export * as spacing from '~/spacing/src/_spacing.js'; diff --git a/tokens/package.json b/tokens/package.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/tokens/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tokens/tokens.css b/tokens/tokens.css new file mode 100644 index 0000000..6bde19e --- /dev/null +++ b/tokens/tokens.css @@ -0,0 +1,169 @@ +/** + * Do not edit directly + * Generated on Mon, 29 Nov 2021 12:01:04 GMT + */ + +:root { + --simba-colors-cool-gray-50: #F9FAFB; + --simba-colors-cool-gray-100: #F3F4F6; + --simba-colors-cool-gray-200: #E5E7EB; + --simba-colors-cool-gray-300: #D1D5DB; + --simba-colors-cool-gray-400: #9CA3AF; + --simba-colors-cool-gray-500: #6B7280; + --simba-colors-cool-gray-600: #4B5563; + --simba-colors-cool-gray-700: #374151; + --simba-colors-cool-gray-800: #1F2937; + --simba-colors-cool-gray-900: #111827; + --simba-colors-red-50: #FEF2F2; + --simba-colors-red-100: #FEE2E2; + --simba-colors-red-200: #FECACA; + --simba-colors-red-300: #FCA5A5; + --simba-colors-red-400: #F87171; + --simba-colors-red-500: #EF4444; + --simba-colors-red-600: #DC2626; + --simba-colors-red-700: #B91C1C; + --simba-colors-red-800: #991B1B; + --simba-colors-red-900: #7F1D1D; + --simba-colors-amber-50: #FFFBEB; + --simba-colors-amber-100: #FEF3C7; + --simba-colors-amber-200: #FDE68A; + --simba-colors-amber-300: #FCD34D; + --simba-colors-amber-400: #FBBF24; + --simba-colors-amber-500: #F59E0B; + --simba-colors-amber-600: #D97706; + --simba-colors-amber-700: #B45309; + --simba-colors-amber-800: #92400E; + --simba-colors-amber-900: #78350F; + --simba-colors-emerald-50: #ECFDF5; + --simba-colors-emerald-100: #D1FAE5; + --simba-colors-emerald-200: #A7F3D0; + --simba-colors-emerald-300: #6EE7B7; + --simba-colors-emerald-400: #34D399; + --simba-colors-emerald-500: #10B981; + --simba-colors-emerald-600: #059669; + --simba-colors-emerald-700: #047857; + --simba-colors-emerald-800: #065F46; + --simba-colors-emerald-900: #064E3B; + --simba-colors-blue-50: #EFF6FF; + --simba-colors-blue-100: #DBEAFE; + --simba-colors-blue-200: #BFDBFE; + --simba-colors-blue-300: #93C5FD; + --simba-colors-blue-400: #60A5FA; + --simba-colors-blue-500: #3B82F6; + --simba-colors-blue-600: #2563EB; + --simba-colors-blue-700: #1D4ED8; + --simba-colors-blue-800: #1E40AF; + --simba-colors-blue-900: #1E3A8A; + --simba-colors-indigo-50: #EEF2FF; + --simba-colors-indigo-100: #E0E7FF; + --simba-colors-indigo-200: #C7D2FE; + --simba-colors-indigo-300: #A5B4FC; + --simba-colors-indigo-400: #818CF8; + --simba-colors-indigo-500: #6366F1; + --simba-colors-indigo-600: #4F46E5; + --simba-colors-indigo-700: #4338CA; + --simba-colors-indigo-800: #3730A3; + --simba-colors-indigo-900: #312E81; + --simba-colors-purple-50: #F5F3FF; + --simba-colors-purple-100: #EDE9FE; + --simba-colors-purple-200: #DDD6FE; + --simba-colors-purple-300: #C4B5FD; + --simba-colors-purple-400: #A78BFA; + --simba-colors-purple-500: #8B5CF6; + --simba-colors-purple-600: #7C3AED; + --simba-colors-purple-700: #6D28D9; + --simba-colors-purple-800: #5B21B6; + --simba-colors-purple-900: #4C1D95; + --simba-colors-pink-50: #FDF2F8; + --simba-colors-pink-100: #FCE7F3; + --simba-colors-pink-200: #FBCFE8; + --simba-colors-pink-300: #F9A8D4; + --simba-colors-pink-400: #F472B6; + --simba-colors-pink-500: #EC4899; + --simba-colors-pink-600: #DB2777; + --simba-colors-pink-700: #BE185D; + --simba-colors-pink-800: #9D174D; + --simba-colors-pink-900: #831843; + --simba-radii-none: 0; + --simba-radii-sm: 0.125rem; + --simba-radii-base: 0.25rem; + --simba-radii-md: 0.375rem; + --simba-radii-lg: 0.5rem; + --simba-radii-xl: 0.75rem; + --simba-radii-xl2: 1rem; + --simba-radii-xl3: 1.5rem; + --simba-radii-full: 9999px; + --simba-spacing-s0: 0px; + --simba-spacing-px: 1px; + --simba-spacing-s0-5: 0.125rem; + --simba-spacing-s1: 0.25rem; + --simba-spacing-s1-5: 0.375rem; + --simba-spacing-s2: 0.5rem; + --simba-spacing-s2-5: 0.625rem; + --simba-spacing-s3: 0.75rem; + --simba-spacing-s3-5: 0.875rem; + --simba-spacing-s4: 1rem; + --simba-spacing-s5: 1.25rem; + --simba-spacing-s6: 1.5rem; + --simba-spacing-s7: 1.75rem; + --simba-spacing-s8: 2rem; + --simba-spacing-s9: 2.25rem; + --simba-spacing-s10: 2.5rem; + --simba-spacing-s11: 2.75rem; + --simba-spacing-s12: 3rem; + --simba-spacing-s14: 3.5rem; + --simba-spacing-s16: 4rem; + --simba-spacing-s20: 5rem; + --simba-spacing-s24: 6rem; + --simba-spacing-s28: 7rem; + --simba-spacing-s32: 8rem; + --simba-spacing-s36: 9rem; + --simba-spacing-s40: 10rem; + --simba-spacing-s44: 11rem; + --simba-spacing-s48: 12rem; + --simba-spacing-s52: 13rem; + --simba-spacing-s56: 14rem; + --simba-spacing-s60: 15rem; + --simba-spacing-s64: 16rem; + --simba-spacing-s72: 18rem; + --simba-spacing-s80: 20rem; + --simba-spacing-s96: 24rem; + --simba-typography-family-sans: 'Inter var', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --simba-typography-family-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif; + --simba-typography-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; + --simba-typography-weight-thin: 100; + --simba-typography-weight-extralight: 200; + --simba-typography-weight-light: 300; + --simba-typography-weight-normal: 400; + --simba-typography-weight-medium: 500; + --simba-typography-weight-semibold: 600; + --simba-typography-weight-bold: 700; + --simba-typography-weight-extrabold: 800; + --simba-typography-weight-black: 900; + --simba-typography-size-xs-size: 0.75rem; + --simba-typography-size-xs-line-height: 1rem; + --simba-typography-size-sm-size: 0.875rem; + --simba-typography-size-sm-line-height: 1.25rem; + --simba-typography-size-base-size: 1rem; + --simba-typography-size-base-line-height: 1.5rem; + --simba-typography-size-lg-size: 1.125rem; + --simba-typography-size-lg-line-height: 1.75rem; + --simba-typography-size-xl-size: 1.25rem; + --simba-typography-size-xl-line-height: 1.75rem; + --simba-typography-size-2xl-size: 1.5rem; + --simba-typography-size-2xl-line-height: 2rem; + --simba-typography-size-3xl-size: 1.875rem; + --simba-typography-size-3xl-line-height: 2.25rem; + --simba-typography-size-4xl-size: 2.25rem; + --simba-typography-size-4xl-line-height: 2.5rem; + --simba-typography-size-5xl-size: 3rem; + --simba-typography-size-5xl-line-height: 1rem; + --simba-typography-size-6xl-size: 3.75rem; + --simba-typography-size-6xl-line-height: 1; + --simba-typography-size-7xl-size: 4.5rem; + --simba-typography-size-7xl-line-height: 1; + --simba-typography-size-8xl-size: 6rem; + --simba-typography-size-8xl-line-height: 1; + --simba-typography-size-9xl-size: 8rem; + --simba-typography-size-9xl-line-height: 1; +} diff --git a/tooltip/doc/index.md b/tooltip/doc/index.md index dc4be6a..cb5e727 100644 --- a/tooltip/doc/index.md +++ b/tooltip/doc/index.md @@ -7,8 +7,25 @@ Interactive content should not be placed in a tooltip content slot. Tooltips are ```js script import { html } from '~/core'; import '~/icons/simba-icon.js'; -import '../simba-tooltip.js'; -import { red, amber, emerald, blue } from '~/colors'; +import '@divriots/starter-simba/tooltip/simba-tooltip.js'; +import { + red400, + red700, + amber400, + amber700, + emerald400, + emerald700, + blue400, + blue700, +} from '~/colors'; +``` + +## Usage + +Import the custom element definition file. + +```js +import '@divriots/starter-simba/tooltip/simba-tooltip.js'; ``` ```js preview-story @@ -16,7 +33,7 @@ export const tooltip = () => html` @@ -42,35 +59,35 @@ export const placements = () => html` } [icon-id$='error'] { - fill: ${red[700]}; + fill: ${red700}; } [icon-id$='warning'] { - fill: ${amber[700]}; + fill: ${amber700}; } [icon-id$='success'] { - fill: ${emerald[700]}; + fill: ${emerald700}; } [icon-id$='info'] { - fill: ${blue[700]}; + fill: ${blue700}; } html[theme='dark'] [icon-id$='error'] { - fill: ${red[400]}; + fill: ${red400}; } html[theme='dark'] [icon-id$='warning'] { - fill: ${amber[400]}; + fill: ${amber400}; } html[theme='dark'] [icon-id$='success'] { - fill: ${emerald[400]}; + fill: ${emerald400}; } html[theme='dark'] [icon-id$='info'] { - fill: ${blue[400]}; + fill: ${blue400}; } diff --git a/tooltip/src/SimbaTooltip.js b/tooltip/src/SimbaTooltip.js index df8b972..8c3cd93 100644 --- a/tooltip/src/SimbaTooltip.js +++ b/tooltip/src/SimbaTooltip.js @@ -1,8 +1,8 @@ import { LionTooltip } from '@lion/tooltip'; import { css, html } from '~/core'; -import { coolGray } from '~/colors'; -import { spacing } from '~/spacing'; -import { borderRadiusMixin } from '~/borders'; +import { coolGray50 } from '~/colors'; +import { s1_5, s2 } from '~/spacing'; +import { base } from '~/radii'; export class SimbaTooltip extends LionTooltip { static get styles() { @@ -19,10 +19,10 @@ export class SimbaTooltip extends LionTooltip { } #overlay-content-node-wrapper { - padding: ${spacing['1.5']} ${spacing['2']}; + padding: ${s1_5} ${s2}; background-color: var(--simba-color-primary-900); - color: ${coolGray[50]}; - ${borderRadiusMixin()}; + color: ${coolGray50}; + border-radius: ${base}; } `, ]; diff --git a/tsconfig.json b/tsconfig.json index 246aa7c..8c4e3e2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,12 @@ "module": "ESNext", "moduleResolution": "Node", "paths": { - "~/*": ["/*"] + "~/*": [ + "/*" + ], + "@divriots/starter-simba/*": [ + "/*" + ] } } -} +} \ No newline at end of file diff --git a/typography/doc/index.md b/typography/doc/index.md index ec655c8..c8abbac 100644 --- a/typography/doc/index.md +++ b/typography/doc/index.md @@ -3,25 +3,44 @@ ```js script import { html } from '~/core'; import '~/token-display'; -import { typographyMixin as _typographyMixin } from '../src/typography.css.js'; +import * as typography from '~/typography'; ``` ## Usage -The color palettes are tokenized as CSS tagged literals (CSSResult) which can be used directly inside `static get styles`. +The typography parts are tokenized as CSS tagged literals (CSSResult) which can be used directly inside `static get styles`. + +You can import the token group from the main entrypoint (or `/tokens`): + +```js +import { typography } from '@divriots/starter-simba'; // typography.familyMono +``` + +or a specific color from the token entrypoint: + +```js +import { familyMono } from '@divriots/starter-simba/typography'; +``` ```js preview-story -import { css, LitElement } from '~/core'; -import { indigo } from '~/colors'; import { ThemeMixin } from 'dark-theme-utils'; -import { typographyMixin } from '../src/typography.css.js'; +import { css, LitElement } from '@divriots/starter-simba'; +import { + familySans, + sizeXlSize, + sizeXlLineHeight, + weightSemibold, +} from '@divriots/starter-simba/typography'; class DemoTypography extends ThemeMixin(LitElement) { static get styles() { return css` :host { color: var(--simba-color-primary-700); - ${typographyMixin('sans', 'xl', 'semibold')}; + font-family: ${familySans}; + font-size: ${sizeXlSize}; + line-height: ${sizeXlLineHeight}; + font-weight: ${weightSemibold}; transition: var(--theme-color-transition); } @@ -40,119 +59,71 @@ customElements.define('demo-typography', DemoTypography); export const usageInCE = () => html``; ``` -## CSS Values only - -It is also possible to only grab `family`, `size` or `weight` e.g. to create CSS custom properties, -instead of using the mixin to grab the full set of typography declarations. - -```js -import { css } from '~/core'; -import { family, size, weight } from '../src/typography.css.js'; - -css` - :host { - --simba-font-sans: ${family['sans']}; - --simba-font-serif: ${family['serif']}; - --simba-font-mono: ${family['mono']}; - --simba-font-size-base: ${size['base'].size}; - --simba-font-line-height-base: ${size['base'].lineHeight}; - --simba-font-weight-normal: ${weight['normal']}; - } -`; -``` - ## Family -You can specify the family of the font as the first parameter. - -E.g. for monospace: - -```js -typographyMixin('mono'); -``` +You can specify the family of the font. ```js story export const family = () => html` + entry[0].startsWith('family') + )} > `; ``` ## Sizes -You can specify the size of font as the second parameter. - -E.g. for large font-size: - -```js -typographyMixin('sans', 'lg'); -``` +You can specify the size of font, which goes hand in hand with line-height. ```js story export const sizes = () => html` entry[0].startsWith('size') && entry[0].endsWith('Size') + )} > `; ``` -## Weights - -You can specify the weight of font as the third parameter. +## Line Heights -E.g. for large font-size: +You can specify the line height, line heights and sizes go hand in hand. -```js -typographyMixin('sans', 'lg', 'bold'); +```js story +export const lineHeights = () => + html` + + entry[0].startsWith('size') && entry[0].endsWith('LineHeight') + )} + > + `; ``` +## Weights + +You can get different font weights. + ```js story export const weights = () => html` + entry[0].startsWith('weight') + )} > `; ``` diff --git a/typography/index.js b/typography/index.js index 4df73b3..545ab51 100644 --- a/typography/index.js +++ b/typography/index.js @@ -1 +1 @@ -export * from './src/index.js'; +export * from './src/_typography.js'; diff --git a/typography/src/_typography.js b/typography/src/_typography.js new file mode 100644 index 0000000..37feafe --- /dev/null +++ b/typography/src/_typography.js @@ -0,0 +1,45 @@ +/** + * Do not edit directly + * Generated on Thu, 02 Dec 2021 13:44:16 GMT + */ + +import { css } from '@lion/core'; + +export const familySans = css`'Inter var', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'`; +export const familySerif = css`ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif`; +export const familyMono = css`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace`; +export const weightThin = css`100`; +export const weightExtralight = css`200`; +export const weightLight = css`300`; +export const weightNormal = css`400`; +export const weightMedium = css`500`; +export const weightSemibold = css`600`; +export const weightBold = css`700`; +export const weightExtrabold = css`800`; +export const weightBlack = css`900`; +export const sizeXsSize = css`0.75rem`; +export const sizeXsLineHeight = css`1rem`; +export const sizeSmSize = css`0.875rem`; +export const sizeSmLineHeight = css`1.25rem`; +export const sizeBaseSize = css`1rem`; +export const sizeBaseLineHeight = css`1.5rem`; +export const sizeLgSize = css`1.125rem`; +export const sizeLgLineHeight = css`1.75rem`; +export const sizeXlSize = css`1.25rem`; +export const sizeXlLineHeight = css`1.75rem`; +export const size2xlSize = css`1.5rem`; +export const size2xlLineHeight = css`2rem`; +export const size3xlSize = css`1.875rem`; +export const size3xlLineHeight = css`2.25rem`; +export const size4xlSize = css`2.25rem`; +export const size4xlLineHeight = css`2.5rem`; +export const size5xlSize = css`3rem`; +export const size5xlLineHeight = css`1rem`; +export const size6xlSize = css`3.75rem`; +export const size6xlLineHeight = css`1`; +export const size7xlSize = css`4.5rem`; +export const size7xlLineHeight = css`1`; +export const size8xlSize = css`6rem`; +export const size8xlLineHeight = css`1`; +export const size9xlSize = css`8rem`; +export const size9xlLineHeight = css`1`; diff --git a/typography/src/index.js b/typography/src/index.js deleted file mode 100644 index 53363fc..0000000 --- a/typography/src/index.js +++ /dev/null @@ -1 +0,0 @@ -export * from './typography.css.js'; diff --git a/typography/src/typography.css.js b/typography/src/typography.css.js deleted file mode 100644 index 95ac2b7..0000000 --- a/typography/src/typography.css.js +++ /dev/null @@ -1,101 +0,0 @@ -import { css } from '~/core'; - -export const family = { - sans: css`'Inter var', ui-sans-serif, system-ui, -apple-system, - BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', - sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', - 'Noto Color Emoji'`, - serif: css` ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif`, - mono: css`ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, - 'Liberation Mono', 'Courier New', monospace`, -}; - -// prettier-ignore -export const size = { - xs: { - size: css`0.75rem`, - lineHeight: css`1rem` - }, - sm: { - size: css`0.875rem`, - lineHeight: css`1.25rem`, - }, - base: { - size: css`1rem`, - lineHeight: css`1.5rem`, - }, - lg:{ - size: css`1.125rem`, - lineHeight: css`1.75rem`, - }, - xl:{ - size: css`1.25rem`, - lineHeight: css`1.75rem`, - }, - '2xl': { - size: css`1.5rem`, - lineHeight: css`2rem`, - }, - '3xl': { - size: css`1.875rem`, - lineHeight: css`2.25rem`, - }, - '4xl':{ - size:css`2.25rem` , - lineHeight:css`2.5rem` , - }, - '5xl':{ - size: css`3rem`, - lineHeight: css`1`, - }, - '6xl':{ - size:css`3.75rem` , - lineHeight: css`1`, - }, - '7xl':{ - size: css`4.5rem`, - lineHeight: css`1`, - }, - '8xl':{ - size: css`6rem`, - lineHeight: css`1`, - }, - '9xl': { - size: css`8rem`, - lineHeight: css`1`, - }, -}; - -export const weight = { - thin: css`100`, - extralight: css`200`, - light: css`300`, - normal: css`400`, - medium: css`500`, - semibold: css`600`, - bold: css`700`, - extrabold: css`800`, - black: css`900`, -}; - -export const typographyMixin = (_family, _size, _weight) => { - if (!_family) { - _family = 'sans'; - } - - if (!_size) { - _size = 'base'; - } - - if (!_weight) { - _weight = 'normal'; - } - - // prettier-ignore - const output = css`font-family: ${family[_family]}; -font-size: ${size[_size].size}; -line-height: ${size[_size].lineHeight}; -font-weight: ${weight[_weight]};`; - - return output; -}; diff --git a/typography/src/typography.tokens.js b/typography/src/typography.tokens.js new file mode 100644 index 0000000..f684134 --- /dev/null +++ b/typography/src/typography.tokens.js @@ -0,0 +1,82 @@ +export default { + typography: { + family: { + sans: { + value: + "'Inter var', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'", + }, + serif: { + value: "ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif", + }, + mono: { + value: + "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace", + }, + }, + weight: { + thin: { value: 100 }, + extralight: { value: 200 }, + light: { value: 300 }, + normal: { value: 400 }, + medium: { value: 500 }, + semibold: { value: 600 }, + bold: { value: 700 }, + extrabold: { value: 800 }, + black: { value: 900 }, + }, + size: { + xs: { + size: { value: '0.75rem' }, + lineHeight: { value: '1rem' }, + }, + sm: { + size: { value: '0.875rem' }, + lineHeight: { value: '1.25rem' }, + }, + base: { + size: { value: '1rem' }, + lineHeight: { value: '1.5rem' }, + }, + lg: { + size: { value: '1.125rem' }, + lineHeight: { value: '1.75rem' }, + }, + xl: { + size: { value: '1.25rem' }, + lineHeight: { value: '1.75rem' }, + }, + '2xl': { + size: { value: '1.5rem' }, + lineHeight: { value: '2rem' }, + }, + '3xl': { + size: { value: '1.875rem' }, + lineHeight: { value: '2.25rem' }, + }, + '4xl': { + size: { value: '2.25rem' }, + lineHeight: { value: '2.5rem' }, + }, + '5xl': { + size: { value: '3rem' }, + lineHeight: { value: '1rem' }, + }, + '6xl': { + size: { value: '3.75rem' }, + lineHeight: { value: 1 }, + }, + '7xl': { + size: { value: '4.5rem' }, + lineHeight: { value: 1 }, + }, + '8xl': { + size: { value: '6rem' }, + lineHeight: { value: 1 }, + }, + '9xl': { + size: { value: '8rem' }, + lineHeight: { value: 1 }, + }, + }, + }, +}; diff --git a/validation-feedback/doc/index.md b/validation-feedback/doc/index.md index 42bae3d..4ec640e 100644 --- a/validation-feedback/doc/index.md +++ b/validation-feedback/doc/index.md @@ -2,7 +2,7 @@ ```js script import { html } from '~/core'; -import '../simba-validation-feedback.js'; +import '@divriots/starter-simba/validation-feedback/simba-validation-feedback.js'; ``` Validation feedback is useful for giving the user feedback about the values they assigned to input fields in a form. @@ -16,6 +16,12 @@ The component can be used standalone, but relies on `feedbackData` property to c Below is an example of using the component as standalone. +Import the custom element definition file. + +```js +import '@divriots/starter-simba/validation-feedback/simba-validation-feedback.js'; +``` + ```js preview-story export const feedback = () => html` diff --git a/validation-feedback/src/styles.css.js b/validation-feedback/src/styles.css.js index 7a06a48..b457a28 100644 --- a/validation-feedback/src/styles.css.js +++ b/validation-feedback/src/styles.css.js @@ -1,13 +1,28 @@ import { css } from '~/core'; -import { red, amber, emerald, blue } from '~/colors'; -import { typographyMixin } from '~/typography'; +import { + red400, + red500, + red600, + red700, + amber400, + amber500, + amber700, + emerald400, + emerald500, + emerald700, + blue400, + blue500, + blue700, +} from '~/colors'; +import { sizeSmSize, sizeSmLineHeight } from '~/typography'; export default css` :host { display: block; - color: ${red[600]}; + color: ${red600}; margin-top: 2px; - ${typographyMixin('sans', 'sm')}; + font-size: ${sizeSmSize}; + line-height: ${sizeSmLineHeight}; } .feedback-container { @@ -22,42 +37,42 @@ export default css` } .error { - fill: ${red[500]}; - color: ${red[700]}; + fill: ${red500}; + color: ${red700}; } .warning { - fill: ${amber[500]}; - color: ${amber[700]}; + fill: ${amber500}; + color: ${amber700}; } .success { - fill: ${emerald[500]}; - color: ${emerald[700]}; + fill: ${emerald500}; + color: ${emerald700}; } .info { - fill: ${blue[500]}; - color: ${blue[700]}; + fill: ${blue500}; + color: ${blue700}; } :host([theme='dark']) .error { - fill: ${red[400]}; - color: ${red[400]}; + fill: ${red400}; + color: ${red400}; } :host([theme='dark']) .warning { - fill: ${amber[400]}; - color: ${amber[400]}; + fill: ${amber400}; + color: ${amber400}; } :host([theme='dark']) .success { - fill: ${emerald[400]}; - color: ${emerald[400]}; + fill: ${emerald400}; + color: ${emerald400}; } :host([theme='dark']) .info { - fill: ${blue[400]}; - color: ${blue[400]}; + fill: ${blue400}; + color: ${blue400}; } `;