diff --git a/packages/carbon-react/.storybook/styles.scss b/packages/carbon-react/.storybook/styles.scss index f3291663c7db..5f4c2d0df55a 100644 --- a/packages/carbon-react/.storybook/styles.scss +++ b/packages/carbon-react/.storybook/styles.scss @@ -5,12 +5,7 @@ // LICENSE file in the root directory of this source tree. // -@use '../index.scss' as styles with ( - $css--font-face: true, - $css--plex-arabic: true, -); -@use '../scss/components/button'; -@use '../scss/components/tag'; +@use '../index.scss' as styles; :root { @include styles.theme(styles.$white); @@ -31,16 +26,3 @@ body { background: styles.$background; } - -html[lang='en'] body { - font-family: 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif; -} - -html[lang='ar'] body { - font-family: 'IBM Plex Sans Arabic', 'Helvetica Neue', Arial, sans-serif; -} - -.text-mono { - font-family: 'IBM Plex Mono', Menlo, 'DejaVu Sans Mono', - 'Bitstream Vera Sans Mono', Courier, monospace; -} diff --git a/packages/carbon-react/scss/fonts/_index.scss b/packages/carbon-react/scss/fonts/_index.scss new file mode 100644 index 000000000000..8131757379e0 --- /dev/null +++ b/packages/carbon-react/scss/fonts/_index.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/fonts'; diff --git a/packages/carbon-react/scss/fonts/_mono.scss b/packages/carbon-react/scss/fonts/_mono.scss new file mode 100644 index 000000000000..5bc808190d86 --- /dev/null +++ b/packages/carbon-react/scss/fonts/_mono.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/fonts/mono'; diff --git a/packages/carbon-react/scss/fonts/_sans-arabic.scss b/packages/carbon-react/scss/fonts/_sans-arabic.scss new file mode 100644 index 000000000000..2efce12db25f --- /dev/null +++ b/packages/carbon-react/scss/fonts/_sans-arabic.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/fonts/sans-arabic'; diff --git a/packages/carbon-react/scss/fonts/_sans-devanagari.scss b/packages/carbon-react/scss/fonts/_sans-devanagari.scss new file mode 100644 index 000000000000..46d8ec6366e3 --- /dev/null +++ b/packages/carbon-react/scss/fonts/_sans-devanagari.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/fonts/sans-devanagari'; diff --git a/packages/carbon-react/scss/fonts/_sans-hebrew.scss b/packages/carbon-react/scss/fonts/_sans-hebrew.scss new file mode 100644 index 000000000000..29c89a3c815e --- /dev/null +++ b/packages/carbon-react/scss/fonts/_sans-hebrew.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/fonts/sans-hebrew'; diff --git a/packages/carbon-react/scss/fonts/_sans-thai-looped.scss b/packages/carbon-react/scss/fonts/_sans-thai-looped.scss new file mode 100644 index 000000000000..0f6c00cd136c --- /dev/null +++ b/packages/carbon-react/scss/fonts/_sans-thai-looped.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/fonts/sans-thai-looped'; diff --git a/packages/carbon-react/scss/fonts/_sans-thai.scss b/packages/carbon-react/scss/fonts/_sans-thai.scss new file mode 100644 index 000000000000..179702b41df7 --- /dev/null +++ b/packages/carbon-react/scss/fonts/_sans-thai.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/fonts/sans-thai'; diff --git a/packages/carbon-react/scss/fonts/_sans.scss b/packages/carbon-react/scss/fonts/_sans.scss new file mode 100644 index 000000000000..127ab690b990 --- /dev/null +++ b/packages/carbon-react/scss/fonts/_sans.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/fonts/sans'; diff --git a/packages/carbon-react/scss/fonts/_serif.scss b/packages/carbon-react/scss/fonts/_serif.scss new file mode 100644 index 000000000000..3e505e700ea8 --- /dev/null +++ b/packages/carbon-react/scss/fonts/_serif.scss @@ -0,0 +1,9 @@ +// Code generated by @carbon/react. DO NOT EDIT. +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@forward '@carbon/styles/scss/fonts/serif'; diff --git a/packages/carbon-react/src/components/Plex/Plex.stories.js b/packages/carbon-react/src/components/Plex/Plex.stories.js index 2279c3e7cbd5..dbd1fce7bc54 100644 --- a/packages/carbon-react/src/components/Plex/Plex.stories.js +++ b/packages/carbon-react/src/components/Plex/Plex.stories.js @@ -4,62 +4,98 @@ * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ + +import './story.scss'; + import React from 'react'; export default { - title: 'Elements/Plex', + title: 'Elements/IBM Plex', argTypes: { fontWeight: { + control: { + type: 'radio', + }, defaultValue: 'Regular', - options: [ - 'Thin', - 'Extra Light', - 'Light', - 'Regular', - 'Text', - 'Medium', - 'SemiBold', - 'Bold', - ], mapping: { - Thin: 100, - 'Extra Light': 200, Light: 300, Regular: 400, - Text: 450, - Medium: 500, SemiBold: 600, - Bold: 700, }, - control: { type: 'radio' }, - }, - fontSize: { - defaultValue: 16, - control: { type: 'range', min: 12, max: 54, step: 4 }, + options: ['Light', 'Regular', 'SemiBold'], }, }, }; -export const English = (args) => { +export const IBMPlexMono = (args) => { + return ( + + This paragraph is in English and goes left to right. + + ); +}; + +export const IBMPlexSansArabic = (args) => { return ( -

- This paragraph is in English and correctly goes left to right. +

+ هذه الفقرة باللغة العربية ، لذا يجب الانتقال من اليمين إلى اليسار.

); }; -export const Mono = (args) => { +export const IBMPlexSansDevanagari = (args) => { return ( - - This paragraph is in English and is monospaced. - +

+ कराना अपने सिद्धांत भेदनक्षमता गुजरना विनिमय पेदा ध्येय संपादक आशाआपस ।क + सक्षम नयेलिए सोफ़्टवेर सुस्पश्ट संभव जिसकी औषधिक संपादक प्रतिबध उपलब्धता + कैसे पढने विभाग पुर्णता गोपनीयता विवरन दिशामे प्रेरना व्याख्या भाषए ऎसाजीस + आधुनिक विकेन्द्रित कैसे बनाति परस्पर मुख्यतह अनुवादक उन्हे बारे लेकिन रखति + मानसिक जानकारी विभाग उसके जिम्मे सिद्धांत प्राथमिक समाज सारांश दुनिया + आवश्यकत ध्वनि विषय औषधिक ब्रौशर उसीएक् असक्षम आवश्यकत कार्यसिधान्तो देखने + जिवन +

); }; -export const Arabic = (args) => { +export const IBMPlexSansHebrew = (args) => { return ( -

- هذه الفقرة باللغة العربية ، لذا يجب الانتقال من اليمين إلى اليسار. +

+ גם החלה ואלקטרוניקה שער, כתב החול משפטית אדריכלות אם. אנא אודות חרטומים + דת, אחר תחבורה מדריכים דת. ראשי ומהימנה לרפובליקה כדי גם, של בקר מתוך + ביוני, ויקימדיה בהיסטוריה אם מלא. הבהרה הספרות האטמוספירה או אחר, את ביוני + תאולוגיה אנא, סדר ב לתרום בחירות בלשנות. +

+ ); +}; + +export const IBMPlexSansThaiLooped = (args) => { + return ( +

+ ลักษณะของตัวพิมพ์แต่ละตัวสามารถแสดงออกได้ถึงระดับเสียง +

+ ); +}; + +export const IBMPlexSansThai = (args) => { + return ( +

+ ลักษณะของตัวพิมพ์แต่ละตัวสามารถแสดงออกได้ถึงระดับเสียง +

+ ); +}; + +export const IBMPlexSans = (args) => { + return ( +

+ This paragraph is in English and goes left to right. +

+ ); +}; + +export const IBMPlexSerif = (args) => { + return ( +

+ This paragraph is in English and goes left to right.

); }; diff --git a/packages/carbon-react/src/components/Plex/story.scss b/packages/carbon-react/src/components/Plex/story.scss new file mode 100644 index 000000000000..1a668acacd50 --- /dev/null +++ b/packages/carbon-react/src/components/Plex/story.scss @@ -0,0 +1,51 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../../../scss/type'; +@use '../../../scss/fonts/sans-arabic'; +@use '../../../scss/fonts/sans-devanagari'; +@use '../../../scss/fonts/sans-hebrew'; +@use '../../../scss/fonts/sans-thai-looped'; +@use '../../../scss/fonts/sans-thai'; + +@include sans-arabic.default(); +@include sans-devanagari.default(); +@include sans-hebrew.default(); +@include sans-thai-looped.default(); +@include sans-thai.default(); + +.text-mono { + font-family: type.font-family('mono'); +} + +.text-sans-arabic { + font-family: type.font-family('sans-arabic'); +} + +.text-sans-devanagari { + font-family: type.font-family('sans-devanagari'); +} + +.text-sans-hebrew { + font-family: type.font-family('sans-hebrew'); +} + +.text-sans-thai-looped { + font-family: type.font-family('sans-thai-looped'); +} + +.text-sans-thai { + font-family: type.font-family('sans-thai'); +} + +.text-sans { + font-family: type.font-family('sans'); +} + +.text-serif { + font-family: type.font-family('serif'); +} diff --git a/packages/carbon-react/tasks/build-styles.js b/packages/carbon-react/tasks/build-styles.js index 21c0c3dbca5c..e525074f64cc 100644 --- a/packages/carbon-react/tasks/build-styles.js +++ b/packages/carbon-react/tasks/build-styles.js @@ -63,6 +63,20 @@ async function build() { type: 'file', filepath: '_zone.scss', }, + { + type: 'directory', + filepath: 'compat', + files: [ + { + type: 'file', + filepath: '_theme.scss', + }, + { + type: 'file', + filepath: '_themes.scss', + }, + ], + }, { type: 'directory', filepath: 'components', @@ -491,15 +505,43 @@ async function build() { }, { type: 'directory', - filepath: 'compat', + filepath: 'fonts', files: [ { type: 'file', - filepath: '_theme.scss', + filepath: '_index.scss', }, { type: 'file', - filepath: '_themes.scss', + filepath: '_mono.scss', + }, + { + type: 'file', + filepath: '_sans-arabic.scss', + }, + { + type: 'file', + filepath: '_sans-devanagari.scss', + }, + { + type: 'file', + filepath: '_sans-hebrew.scss', + }, + { + type: 'file', + filepath: '_sans-thai-looped.scss', + }, + { + type: 'file', + filepath: '_sans-thai.scss', + }, + { + type: 'file', + filepath: '_sans.scss', + }, + { + type: 'file', + filepath: '_serif.scss', }, ], }, diff --git a/packages/styles/__tests__/__snapshots__/styles-test.js.snap b/packages/styles/__tests__/__snapshots__/styles-test.js.snap index e68a84901dd0..b4f5672aca0c 100644 --- a/packages/styles/__tests__/__snapshots__/styles-test.js.snap +++ b/packages/styles/__tests__/__snapshots__/styles-test.js.snap @@ -2,11 +2,14 @@ exports[`Snapshot Tests should match snapshots 1`] = ` Array [ + "scss/compat/theme", + "scss/compat/themes", + "scss/components", + "scss/fonts", "scss/breakpoint", "scss/colors", "scss/config", "scss/feature-flags", - "scss/font-face", "scss/grid", "scss/motion", "scss/reset", diff --git a/packages/styles/__tests__/styles-test.js b/packages/styles/__tests__/styles-test.js index 02d5a5a95021..c74ee38d60d4 100644 --- a/packages/styles/__tests__/styles-test.js +++ b/packages/styles/__tests__/styles-test.js @@ -14,11 +14,14 @@ const { SassRenderer } = require('@carbon/test-utils/scss'); const { render } = SassRenderer.create(__dirname); const filepaths = [ + 'scss/compat/theme', + 'scss/compat/themes', + 'scss/components', + 'scss/fonts', 'scss/breakpoint', 'scss/colors', 'scss/config', 'scss/feature-flags', - 'scss/font-face', 'scss/grid', 'scss/motion', 'scss/reset', @@ -107,20 +110,17 @@ describe('@carbon/styles/scss/config', () => { @use '../scss/config' with ( $prefix: 'custom-prefix', $css--font-face: false, - $css--plex-arabic: true, ); $_: get('config', ( prefix: config.$prefix, css--font-face: config.$css--font-face, - css--plex-arabic: config.$css--plex-arabic, )); `); expect(get('config').value).toEqual({ prefix: 'custom-prefix', ['css--font-face']: false, - ['css--plex-arabic']: true, }); }); }); diff --git a/packages/styles/docs/sass.md b/packages/styles/docs/sass.md index 702c0862a3b3..dcb6181b0f4d 100644 --- a/packages/styles/docs/sass.md +++ b/packages/styles/docs/sass.md @@ -120,23 +120,6 @@ to `false`: ); ``` -### Emitting additional typefaces - -When using the font-face declarations, only `IBM Plex Sans` and `IBM Plex Mono` -are emitted. If you would like to emit additional typefaces, like -`IBM Plex Sans Arabic`, you can set additional config tokens: - -```scss -@use '@carbon/styles/scss/config' with ( - $css--plex-arabic: true, -); -``` - -| IBM Plex Language | Token | -| :---------------- | :------------------ | -| Arabic | `$css--plex-arabic` | -| TODO | `TODO` | - ## Grid | Import | Filepath | diff --git a/packages/styles/index.scss b/packages/styles/index.scss index 05b2ded8d900..1027b743edf5 100644 --- a/packages/styles/index.scss +++ b/packages/styles/index.scss @@ -7,7 +7,6 @@ @forward 'scss/config'; @forward 'scss/colors' hide $white; -@forward 'scss/font-face'; @forward 'scss/grid'; @forward 'scss/motion'; @forward 'scss/type'; @@ -15,4 +14,5 @@ @forward 'scss/theme'; @use 'scss/reset'; +@forward 'scss/fonts'; @use 'scss/components'; diff --git a/packages/styles/scss/__tests__/__snapshots__/config-test.js.snap b/packages/styles/scss/__tests__/__snapshots__/config-test.js.snap index 9cce668861f9..d1e46d930cd3 100644 --- a/packages/styles/scss/__tests__/__snapshots__/config-test.js.snap +++ b/packages/styles/scss/__tests__/__snapshots__/config-test.js.snap @@ -4,8 +4,9 @@ exports[`@carbon/styles/scss/config Public API 1`] = ` Object { "css--default-type": true, "css--font-face": true, - "css--plex-arabic": false, "css--reset": true, + "font-display": "swap", + "font-path": "~@ibm/plex", "prefix": "cds", } `; diff --git a/packages/styles/scss/_config.scss b/packages/styles/scss/_config.scss index 67382ec501cc..9ad66aa7d476 100644 --- a/packages/styles/scss/_config.scss +++ b/packages/styles/scss/_config.scss @@ -5,14 +5,7 @@ // LICENSE file in the root directory of this source tree. // -/// The value used to prefix selectors and CSS Custom Properties across the -/// codebase -/// @access public -/// @type String -/// @group config -$prefix: 'cds' !default; - -/// If true, includes font face mixins in `_css--font-face.scss` depending on the `css--plex` feature flag +/// If true, includes font face mixins from scss/fonts /// @access public /// @type Bool /// @group config @@ -30,8 +23,22 @@ $css--reset: true !default; /// @group config $css--default-type: true !default; -/// If true, include IBM Plex Arabic type +/// Specify the default value for the `font-display` property used for fonts +/// loaded with @font-face /// @access public -/// @type Bool +/// @type String +/// @group config +$font-display: 'swap' !default; + +/// Specify the base path for loading IBM Plex +/// @access public +/// @type String +/// @group config +$font-path: '~@ibm/plex' !default; + +/// The value used to prefix selectors and CSS Custom Properties across the +/// codebase +/// @access public +/// @type String /// @group config -$css--plex-arabic: false !default; +$prefix: 'cds' !default; diff --git a/packages/styles/scss/_font-face.scss b/packages/styles/scss/_font-face.scss deleted file mode 100644 index 013c3d86b193..000000000000 --- a/packages/styles/scss/_font-face.scss +++ /dev/null @@ -1,13 +0,0 @@ -@use 'config'; -@use '@ibm/plex/default' as sans; -@use '@ibm/plex/mono' as mono; -@use '@ibm/plex/arabic' as arabic; - -@if config.$css--font-face == true { - @include sans.all; - @include mono.all; - - @if config.$css--plex-arabic == true { - @include arabic.all; - } -} ; diff --git a/packages/styles/scss/fonts/README.md b/packages/styles/scss/fonts/README.md new file mode 100644 index 000000000000..9f052543ccc6 --- /dev/null +++ b/packages/styles/scss/fonts/README.md @@ -0,0 +1,148 @@ +# `scss/fonts` + +The `scss/fonts` folder provides a way to incorporate IBM Plex into your +project. Below is a table of what fonts are currently supported from IBM Plex in +Carbon: + +| Font | Available | Entrypoint | +| ------------------------- | --------- | ----------------------------- | +| IBM Plex Mono | ✅ | `scss/fonts/mono` | +| IBM Plex Sans Arabic | ✅ | `scss/fonts/sans-arabic` | +| IBM Plex Sans Devanagari | ✅ | `scss/fonts/sans-devanagari` | +| IBM Plex Sans Hebrew | ✅ | `scss/fonts/sans-hebrew` | +| IBM Plex Sans KR | | | +| IBM Plex Sans JP | | | +| IBM Plex Sans Thai Looped | ✅ | `scss/fonts/sans-thai-looped` | +| IBM Plex Sans Thai | ✅ | `scss/fonts/sans-thai` | +| IBM Plex Sans | ✅ | `scss/fonts/sans` | +| IBM Plex Serif | ✅ | `scss/fonts/serif` | + +By default, Carbon provides the default font weights for: IBM Plex Mono, IBM +Plex Sans, and IBM Plex Serif. To bring in additional fonts, you can include the +`@carbon/styles/scss/fonts` entrypoint and configure it: + +```scss +@use '@carbon/styles/scss/fonts' with ( + $fonts: ( + IBM-Plex-Sans-Arabic: true, + ), +); +``` + +You can also configure it to disable specific fonts: + +```scss +@use '@carbon/styles/scss/fonts' with ( + $fonts: ( + IBM-Plex-Sans: false, + ), +); +``` + +If you would like to disable all fonts, you can use the `$css--font-face` flag +in: + +```scss +@use '@carbon/styles/scss/config' with ( + $css--font-face: false, +); +``` + +## Features + +Each font is available as an entrypoint in the `fonts` folder. You can use these +entrypoints to include specific font weights, styles, and more for IBM Plex. For +example, if you only want to include the regular font weight for IBM Plex Sans +then you could do the following: + +```scss +@use '@carbon/styles/scss/fonts/sans'; + +@include sans.regular($styles: normal); +``` + +Each font entrypoint supports the following weights: + +- `thin` +- `extralight` +- `light` +- `regular` +- `tex` +- `medium` +- `semibold` +- `bold` + +All fonts support the `normal` font style, some fonts include support for the +`italic` font style, as well. + +### Custom font src resolver + +By default, `@carbon/styles/scss/fonts` attempts to resolve fonts directly from +the `@ibm/plex` package. You can configure the location of these font files in +two ways: + +- Use the `$font-path` option to define a path "prefix" +- Provide a custom resolver to point to where your font files are hosted + +The `$font-path` options is available in `scss/config`: + +```scss +@use '@carbon/styles/scss/config' with ( + $font-path: 'https://cdn.custom-font-path.com/fonts', +); +``` + +And allows you to change the beginning part of each `src` URL that is generated. +You can also completely override the default behavior and provide your own URL +resolver through `scss/fonts/src`: + +```scss +@use 'sass:meta'; +@use './my-custom-resolver' as resolver; +@use '@carbon/styles/scss/fonts/src' with ( + // Here, "resolve" is the name of the function in the "resolver" module + $resolver: meta.get-function('resolve', 'resolver') +); +``` + +This can be particularly useful for self-hosted projects that are not using +webpack. This custom resolver should follow the signature: + +```scss +/// @param {String} $name +/// @param {String} $weight +/// @param {String} $style +/// @param {String} $unicode-range +/// @param {List} $formats +/// @returns List +@function resolver($name, $weight, $style, $unicode-range, $formats) { + // Here, you will need to return a list of url() format() that will be used in + // the src property +} +``` + +## Contributing + +**How do I add support for a font?** + +You will need to do the following: + +- [ ] Create a file for the font under `scss/fonts/`, for example + `scss/fonts/_sans-arabic.scss` +- [ ] Define all available weights as mixins in that file +- [ ] Emit `@font-face` blocks in each font weight mixin +- [ ] Add a `default` mixin for the default font weights to include for a font +- [ ] Add an `all` mixin which emits all font weights +- [ ] Export a `$name` variable for the name of the font to be used to detect if + a font should be auto-included +- [ ] Add the base font name to the `$-filenames` map in `fonts/_src.scss`. This + will be used in the font src resolver to get the correct path from + `@ibm/plex` +- [ ] In `fonts/_index.scss` + - [ ] Update the `$-fonts` map to include the `$name` for the font and specify + whether it should be included automatically + - [ ] Update the block at the end of the file to call the default mixin of the + file if the font is enabled +- [ ] Update `packages/carbon-react/tasks/build-styles.js` to include the font + file as a re-export +- [ ] Add a story for the font in `Plex.stories.js` diff --git a/packages/styles/scss/fonts/__tests__/fonts-test.js b/packages/styles/scss/fonts/__tests__/fonts-test.js new file mode 100644 index 000000000000..529add231c09 --- /dev/null +++ b/packages/styles/scss/fonts/__tests__/fonts-test.js @@ -0,0 +1,142 @@ +/** + * Copyright IBM Corp. 2018, 2018 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + * + * @jest-environment node + */ + +'use strict'; + +const { SassRenderer } = require('@carbon/test-utils/scss'); +const css = require('css'); + +const { render } = SassRenderer.create(__dirname); + +const fonts = [ + 'mono', + 'sans-arabic', + 'sans-devanagari', + 'sans-hebrew', + 'sans-thai-looped', + 'sans-thai', + 'sans', + 'serif', +]; +const weights = [ + 'thin', + 'extralight', + 'light', + 'regular', + 'text', + 'medium', + 'semibold', + 'bold', +]; + +describe('@carbon/styles/scss/fonts', () => { + it('should emit default fonts, weights, and styles', async () => { + const { result } = await render(`@use '../' as fonts;`); + const { stylesheet } = css.parse(result.css.toString()); + const atRules = stylesheet.rules.filter((rule) => { + return rule.type === 'font-face'; + }); + const emitted = new Map(); + + for (const rule of atRules) { + const fontFamily = rule.declarations + .find((declaration) => { + return declaration.property === 'font-family'; + }) + .value.replace(/['"]/g, ''); + + if (!emitted.has(fontFamily)) { + emitted.set(fontFamily, { + weights: new Set(), + styles: new Set(), + }); + } + + const entry = emitted.get(fontFamily); + + for (const declaration of rule.declarations) { + if (declaration.property === 'font-weight') { + entry.weights.add(declaration.value); + } + + if (declaration.property === 'font-style') { + entry.styles.add(declaration.value); + } + } + } + + expect(emitted.has('IBM Plex Mono')).toBe(true); + const mono = emitted.get('IBM Plex Mono'); + expect(mono.weights).toEqual(new Set(['300', '400', '600'])); + expect(mono.styles).toEqual(new Set(['normal', 'italic'])); + + expect(emitted.has('IBM Plex Sans')).toBe(true); + expect(emitted.get('IBM Plex Sans').weights).toEqual( + new Set(['300', '400', '600']) + ); + expect(emitted.get('IBM Plex Sans').styles).toEqual( + new Set(['normal', 'italic']) + ); + + expect(emitted.has('IBM Plex Serif')).toBe(true); + expect(emitted.get('IBM Plex Serif').weights).toEqual( + new Set(['300', '400', '600']) + ); + expect(emitted.get('IBM Plex Serif').styles).toEqual( + new Set(['normal', 'italic']) + ); + }); + + it('should emit no @font-face blocks if $css--font-face is false', async () => { + const { result } = await render(` + @use '../../config' with ( + $css--font-face: false, + ); + @use '../' as fonts; + `); + expect(result.css.toString()).toBe(''); + }); + + it('should not emit fonts set to false', async () => { + const { result } = await render(` + @use '../' as fonts with ( + $fonts: ( + IBM-Plex-Mono: false, + IBM-Plex-Sans: false, + IBM-Plex-Serif: false, + ), + ); + `); + expect(result.css.toString()).toBe(''); + }); + + describe.each(fonts)('scss/fonts/_%s.scss', (font) => { + it('should export all font weights as mixins', async () => { + const weightMixins = weights.map((weight) => { + return `$_: get('${weight}', meta.mixin-exists('${weight}', '${font}'));`; + }); + + const { unwrap } = await render(` + @use 'sass:meta'; + @use '../${font}'; + + ${weightMixins.join('\n')} + $_: get('all', meta.mixin-exists('all', '${font}')); + $_: get('default', meta.mixin-exists('default', '${font}')); + `); + + for (const weight of weights) { + expect(unwrap(weight)).toBe(true); + } + + expect(unwrap('all')).toBe(true); + expect(unwrap('default')).toBe(true); + }); + }); +}); diff --git a/packages/styles/scss/fonts/_index.scss b/packages/styles/scss/fonts/_index.scss new file mode 100644 index 000000000000..c5d40126e757 --- /dev/null +++ b/packages/styles/scss/fonts/_index.scss @@ -0,0 +1,75 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use 'sass:meta'; +@use 'sass:map'; +@use '../config'; +@use './mono'; +@use './sans-arabic'; +@use './sans-devanagari'; +@use './sans-hebrew'; +@use './sans-thai-looped'; +@use './sans-thai'; +@use './sans'; +@use './serif'; + +$-fonts: ( + IBM-Plex-Mono: true, + IBM-Plex-Sans-Arabic: false, + IBM-Plex-Sans-Devanagari: false, + IBM-Plex-Sans-Hebrew: false, + IBM-Plex-Sans-Thai-Looped: false, + IBM-Plex-Sans-Thai: false, + IBM-Plex-Sans: true, + IBM-Plex-Serif: true, +); +$fonts: () !default; +$fonts: map.merge($-fonts, $fonts); + +/// Determine if the given font has been enabled or not +/// @param String $name +/// @returns Boolean +@function enabled($name) { + @if map.has-key($fonts, $name) { + @return map.get($fonts, $name); + } + @return false; +} + +@if config.$css--font-face == true { + @if enabled(mono.$name) { + @include mono.default(); + } + + @if enabled(sans-arabic.$name) { + @include sans-arabic.default(); + } + + @if enabled(sans-devanagari.$name) { + @include sans-devanagari.default(); + } + + @if enabled(sans-hebrew.$name) { + @include sans-hebrew.default(); + } + + @if enabled(sans-thai-looped.$name) { + @include sans-thai-looped.default(); + } + + @if enabled(sans-thai.$name) { + @include sans-thai.default(); + } + + @if enabled(sans.$name) { + @include sans.default(); + } + + @if enabled(serif.$name) { + @include serif.default(); + } +} diff --git a/packages/styles/scss/fonts/_mono.scss b/packages/styles/scss/fonts/_mono.scss new file mode 100644 index 000000000000..868ef604750a --- /dev/null +++ b/packages/styles/scss/fonts/_mono.scss @@ -0,0 +1,153 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../config'; +@use './src'; +@use './unicode'; + +$font-family: 'IBM Plex Mono'; +$name: 'IBM-Plex-Mono'; +$styles: (normal, italic); +$unicode-ranges: (Cyrillic, Pi, Latin3, Latin2, Latin1); +$formats: (woff2, woff); + +@mixin thin($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 100; + src: src.get($name, Thin, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin extralight($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 200; + src: src.get($name, ExtraLight, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin light($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 300; + src: src.get($name, Light, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin regular($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 400; + src: src.get($name, Regular, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin text($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 450; + src: src.get($name, Text, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin medium($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 500; + src: src.get($name, Medium, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin semibold($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 600; + src: src.get($name, SemiBold, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin bold($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 700; + src: src.get($name, Bold, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin all($styles: $styles, $unicode-ranges: $unicode-ranges) { + @include thin($styles, $unicode-ranges); + @include extralight($styles, $unicode-ranges); + @include light($styles, $unicode-ranges); + @include regular($styles, $unicode-ranges); + @include text($styles, $unicode-ranges); + @include medium($styles, $unicode-ranges); + @include semibold($styles, $unicode-ranges); + @include bold($styles, $unicode-ranges); +} + +@mixin default() { + @include light(); + @include regular(); + @include semibold(); +} diff --git a/packages/styles/scss/fonts/_sans-arabic.scss b/packages/styles/scss/fonts/_sans-arabic.scss new file mode 100644 index 000000000000..a517101b61e2 --- /dev/null +++ b/packages/styles/scss/fonts/_sans-arabic.scss @@ -0,0 +1,151 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../config'; +@use './src'; + +$font-family: 'IBM Plex Sans Arabic'; +$name: 'IBM-Plex-Sans-Arabic'; +$styles: (normal); +$formats: (woff2, woff); + +@mixin thin() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 100; + src: src.get( + $name: $name, + $weight: Thin, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin extralight() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 200; + src: src.get( + $name: $name, + $weight: ExtraLight, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin light() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 300; + src: src.get( + $name: $name, + $weight: Light, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin regular() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 400; + src: src.get( + $name: $name, + $weight: Regular, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin text() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 450; + src: src.get( + $name: $name, + $weight: Text, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin medium() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Medium, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin semibold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: SemiBold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin bold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Bold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin all() { + @include thin(); + @include extralight(); + @include light(); + @include regular(); + @include text(); + @include medium(); + @include semibold(); + @include bold(); +} + +@mixin default() { + @include light(); + @include regular(); + @include semibold(); +} diff --git a/packages/styles/scss/fonts/_sans-devanagari.scss b/packages/styles/scss/fonts/_sans-devanagari.scss new file mode 100644 index 000000000000..dc39da3974db --- /dev/null +++ b/packages/styles/scss/fonts/_sans-devanagari.scss @@ -0,0 +1,151 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../config'; +@use './src'; + +$font-family: 'IBM Plex Sans Devanagari'; +$name: 'IBM-Plex-Sans-Devanagari'; +$styles: (normal); +$formats: (woff2, woff); + +@mixin thin() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 100; + src: src.get( + $name: $name, + $weight: Thin, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin extralight() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 200; + src: src.get( + $name: $name, + $weight: ExtraLight, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin light() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 300; + src: src.get( + $name: $name, + $weight: Light, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin regular() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 400; + src: src.get( + $name: $name, + $weight: Regular, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin text() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 450; + src: src.get( + $name: $name, + $weight: Text, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin medium() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Medium, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin semibold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: SemiBold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin bold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Bold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin all() { + @include thin(); + @include extralight(); + @include light(); + @include regular(); + @include text(); + @include medium(); + @include semibold(); + @include bold(); +} + +@mixin default() { + @include light(); + @include regular(); + @include semibold(); +} diff --git a/packages/styles/scss/fonts/_sans-hebrew.scss b/packages/styles/scss/fonts/_sans-hebrew.scss new file mode 100644 index 000000000000..0c6f8d8d0807 --- /dev/null +++ b/packages/styles/scss/fonts/_sans-hebrew.scss @@ -0,0 +1,151 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../config'; +@use './src'; + +$font-family: 'IBM Plex Sans Hebrew'; +$name: 'IBM-Plex-Sans-Hebrew'; +$styles: (normal); +$formats: (woff2, woff); + +@mixin thin() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 100; + src: src.get( + $name: $name, + $weight: Thin, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin extralight() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 200; + src: src.get( + $name: $name, + $weight: ExtraLight, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin light() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 300; + src: src.get( + $name: $name, + $weight: Light, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin regular() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 400; + src: src.get( + $name: $name, + $weight: Regular, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin text() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 450; + src: src.get( + $name: $name, + $weight: Text, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin medium() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Medium, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin semibold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: SemiBold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin bold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Bold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin all() { + @include thin(); + @include extralight(); + @include light(); + @include regular(); + @include text(); + @include medium(); + @include semibold(); + @include bold(); +} + +@mixin default() { + @include light(); + @include regular(); + @include semibold(); +} diff --git a/packages/styles/scss/fonts/_sans-thai-looped.scss b/packages/styles/scss/fonts/_sans-thai-looped.scss new file mode 100644 index 000000000000..21cec613e960 --- /dev/null +++ b/packages/styles/scss/fonts/_sans-thai-looped.scss @@ -0,0 +1,151 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../config'; +@use './src'; + +$font-family: 'IBM Plex Sans Thai Looped'; +$name: 'IBM-Plex-Sans-Thai-Looped'; +$styles: (normal); +$formats: (woff2, woff); + +@mixin thin() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 100; + src: src.get( + $name: $name, + $weight: Thin, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin extralight() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 200; + src: src.get( + $name: $name, + $weight: ExtraLight, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin light() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 300; + src: src.get( + $name: $name, + $weight: Light, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin regular() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 400; + src: src.get( + $name: $name, + $weight: Regular, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin text() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 450; + src: src.get( + $name: $name, + $weight: Text, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin medium() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Medium, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin semibold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: SemiBold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin bold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Bold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin all() { + @include thin(); + @include extralight(); + @include light(); + @include regular(); + @include text(); + @include medium(); + @include semibold(); + @include bold(); +} + +@mixin default() { + @include light(); + @include regular(); + @include semibold(); +} diff --git a/packages/styles/scss/fonts/_sans-thai.scss b/packages/styles/scss/fonts/_sans-thai.scss new file mode 100644 index 000000000000..c639469eeb3e --- /dev/null +++ b/packages/styles/scss/fonts/_sans-thai.scss @@ -0,0 +1,151 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../config'; +@use './src'; + +$font-family: 'IBM Plex Sans Thai'; +$name: 'IBM-Plex-Sans-Thai'; +$styles: (normal); +$formats: (woff2, woff); + +@mixin thin() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 100; + src: src.get( + $name: $name, + $weight: Thin, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin extralight() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 200; + src: src.get( + $name: $name, + $weight: ExtraLight, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin light() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 300; + src: src.get( + $name: $name, + $weight: Light, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin regular() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 400; + src: src.get( + $name: $name, + $weight: Regular, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin text() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 450; + src: src.get( + $name: $name, + $weight: Text, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin medium() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Medium, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin semibold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: SemiBold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin bold() { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: normal; + font-weight: 500; + src: src.get( + $name: $name, + $weight: Bold, + $style: $styles, + $formats: $formats + ); + } +} + +@mixin all() { + @include thin(); + @include extralight(); + @include light(); + @include regular(); + @include text(); + @include medium(); + @include semibold(); + @include bold(); +} + +@mixin default() { + @include light(); + @include regular(); + @include semibold(); +} diff --git a/packages/styles/scss/fonts/_sans.scss b/packages/styles/scss/fonts/_sans.scss new file mode 100644 index 000000000000..f1a6fdce4855 --- /dev/null +++ b/packages/styles/scss/fonts/_sans.scss @@ -0,0 +1,153 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../config'; +@use './src'; +@use './unicode'; + +$font-family: 'IBM Plex Sans'; +$name: 'IBM-Plex-Sans'; +$styles: (normal, italic); +$unicode-ranges: (Cyrillic, Pi, Latin3, Latin2, Latin1); +$formats: (woff2, woff); + +@mixin thin($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 100; + src: src.get($name, Thin, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin extralight($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 200; + src: src.get($name, ExtraLight, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin light($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 300; + src: src.get($name, Light, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin regular($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 400; + src: src.get($name, Regular, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin text($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 450; + src: src.get($name, Text, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin medium($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 500; + src: src.get($name, Medium, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin semibold($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 600; + src: src.get($name, SemiBold, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin bold($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 700; + src: src.get($name, Bold, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin all($styles: $styles, $unicode-ranges: $unicode-ranges) { + @include thin($styles, $unicode-ranges); + @include extralight($styles, $unicode-ranges); + @include light($styles, $unicode-ranges); + @include regular($styles, $unicode-ranges); + @include text($styles, $unicode-ranges); + @include medium($styles, $unicode-ranges); + @include semibold($styles, $unicode-ranges); + @include bold($styles, $unicode-ranges); +} + +@mixin default() { + @include light(); + @include regular(); + @include semibold(); +} diff --git a/packages/styles/scss/fonts/_serif.scss b/packages/styles/scss/fonts/_serif.scss new file mode 100644 index 000000000000..60a423547f4a --- /dev/null +++ b/packages/styles/scss/fonts/_serif.scss @@ -0,0 +1,153 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../config'; +@use './src'; +@use './unicode'; + +$font-family: 'IBM Plex Serif'; +$name: 'IBM-Plex-Serif'; +$styles: (normal, italic); +$unicode-ranges: (Cyrillic, Pi, Latin3, Latin2, Latin1); +$formats: (woff2, woff); + +@mixin thin($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 100; + src: src.get($name, Thin, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin extralight($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 200; + src: src.get($name, ExtraLight, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin light($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 300; + src: src.get($name, Light, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin regular($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 400; + src: src.get($name, Regular, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin text($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 450; + src: src.get($name, Text, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin medium($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 500; + src: src.get($name, Medium, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin semibold($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 600; + src: src.get($name, SemiBold, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin bold($styles: $styles, $unicode-ranges: $unicode-ranges) { + @each $style in $styles { + @each $unicode-range in $unicode-ranges { + @font-face { + font-display: config.$font-display; + font-family: $font-family; + font-style: $style; + font-weight: 700; + src: src.get($name, Bold, $style, $unicode-range, $formats); + unicode-range: unicode.get-range($unicode-range); + } + } + } +} + +@mixin all($styles: $styles, $unicode-ranges: $unicode-ranges) { + @include thin($styles, $unicode-ranges); + @include extralight($styles, $unicode-ranges); + @include light($styles, $unicode-ranges); + @include regular($styles, $unicode-ranges); + @include text($styles, $unicode-ranges); + @include medium($styles, $unicode-ranges); + @include semibold($styles, $unicode-ranges); + @include bold($styles, $unicode-ranges); +} + +@mixin default() { + @include light(); + @include regular(); + @include semibold(); +} diff --git a/packages/styles/scss/fonts/_src.scss b/packages/styles/scss/fonts/_src.scss new file mode 100644 index 000000000000..f4b0ecb52892 --- /dev/null +++ b/packages/styles/scss/fonts/_src.scss @@ -0,0 +1,102 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use '../config'; +@use 'sass:list'; +@use 'sass:map'; +@use 'sass:meta'; + +$-filenames: ( + IBM-Plex-Mono: 'IBMPlexMono', + IBM-Plex-Sans-Arabic: 'IBMPlexSansArabic', + IBM-Plex-Sans-Devanagari: 'IBMPlexSansDevanagari', + IBM-Plex-Sans-Hebrew: 'IBMPlexSansHebrew', + IBM-Plex-Sans-Thai-Looped: 'IBMPlexSansThaiLooped', + IBM-Plex-Sans-Thai: 'IBMPlexSansThai', + IBM-Plex-Sans: 'IBMPlexSans', + IBM-Plex-Serif: 'IBMPlexSerif', +); + +@function -get-base-filename($name) { + @return map.get($-filenames, $name); +} + +/// The default resolver for locating a font file in the `@ibm/plex` package. +/// This function will return a path that will work in bundling tools like +/// webpack but will not work without a tool that understands paths that are +/// prefixed with `~` +/// +/// @param {String} $name +/// @param {String} $weight +/// @param {String} $style +/// @param {String} $unicode-range +/// @param {List} $formats +/// @returns List +@function -default-resolver($name, $weight, $style, $unicode-range, $formats) { + $filename: -get-base-filename($name); + + // Special case for weight = Regular (400) + @if $weight == Regular { + @if $style == italic { + $filename: '#{$filename}-Italic'; + } @else { + $filename: '#{$filename}-Regular'; + } + } @else { + // Otherwise add weight + optional style (italic) + $filename: '#{$filename}-#{$weight}'; + @if $style == italic { + $filename: '#{$filename}Italic'; + } + } + + $filenames: (); + + @each $format in $formats { + $url: $filename; + + @if $unicode-range { + $url: '#{config.$font-path}/#{$name}/fonts/split/#{$format}/#{$filename}-#{$unicode-range}'; + } @else { + $url: '#{config.$font-path}/#{$name}/fonts/complete/#{$format}/#{$filename}'; + } + + // Add extension + $url: '#{$url}.#{$format}'; + $filenames: list.append( + $filenames, + url('#{$url}') format('#{$format}'), + $separator: comma + ); + } + + @return $filenames; +} + +/// The resolver used for locating the filepaths in `url() format()` values in +/// @font-face blocks +$resolver: meta.get-function('-default-resolver') !default; + +/// Retrieve the list of `url() format()` values used in the `src` property in +/// an `@font-face` block + +/// @param {String} $name +/// @param {String} $weight +/// @param {String} $style +/// @param {String} $unicode-range +/// @param {List} $formats +/// @returns List +@function get($name, $weight, $style, $unicode-range: null, $formats) { + @return meta.call( + $resolver, + $name: $name, + $weight: $weight, + $style: $style, + $unicode-range: $unicode-range, + $formats: $formats + ); +} diff --git a/packages/styles/scss/fonts/unicode/_index.scss b/packages/styles/scss/fonts/unicode/_index.scss new file mode 100644 index 000000000000..300a68f1c25f --- /dev/null +++ b/packages/styles/scss/fonts/unicode/_index.scss @@ -0,0 +1,124 @@ +// +// Copyright IBM Corp. 2018, 2018 +// +// This source code is licensed under the Apache-2.0 license found in the +// LICENSE file in the root directory of this source tree. +// + +@use 'sass:map'; + +/// All available unicode ranges where the keys are unicode range names and the +/// value is the list of unicode ranges that are applicable +/// @type {List} +$ranges: ( + Cyrillic: ( + 'U+0400-045F', + 'U+0472-0473', + 'U+0490-049D', + 'U+04A0-04A5', + 'U+04AA-04AB', + 'U+04AE-04B3', + 'U+04B6-04BB', + 'U+04C0-04C2', + 'U+04CF-04D9', + 'U+04DC-04DF', + 'U+04E2-04E9', + 'U+04EE-04F5', + 'U+04F8-04F9', + ), + Greek: ( + 'U+0384-038A', + 'U+038C', + 'U+038E-03A1', + 'U+03A3-03CE', + ), + Latin1: ( + 'U+0000', + 'U+000D', + 'U+0020-007E', + 'U+00A0-00A3', + 'U+00A4-00FF', + 'U+0131', + 'U+0152-0153', + 'U+02C6', + 'U+02DA', + 'U+02DC', + 'U+2013-2014', + 'U+2018-201A', + 'U+201C-201E', + 'U+2020-2022', + 'U+2026', + 'U+2030', + 'U+2039-203A', + 'U+2044', + 'U+2074', + 'U+20AC', + 'U+2122', + 'U+2212', + 'U+FB01-FB02', + ), + Latin2: ( + 'U+0100-024F', + 'U+0259', + 'U+1E00-1EFF', + 'U+20A0-20AB', + 'U+20AD-20CF', + 'U+2C60-2C7F', + 'U+A720-A7FF', + 'U+FB01-FB02', + ), + Latin3: ( + 'U+0102-0103', + 'U+1EA0-1EF9', + 'U+20AB', + ), + Pi: ( + 'U+0E3F', + 'U+2032-2033', + 'U+2070', + 'U+2075-2079', + 'U+2080-2081', + 'U+2083', + 'U+2085-2089', + 'U+2113', + 'U+2116', + 'U+2126', + 'U+212E', + 'U+2150-2151', + 'U+2153-215E', + 'U+2190-2199', + 'U+21A9-21AA', + 'U+21B0-21B3', + 'U+21B6-21B7', + 'U+21BA-21BB', + 'U+21C4', + 'U+21C6', + 'U+2202', + 'U+2206', + 'U+220F', + 'U+2211', + 'U+221A', + 'U+221E', + 'U+222B', + 'U+2248', + 'U+2260', + 'U+2264-2265', + 'U+25CA', + 'U+2713', + 'U+274C', + 'U+2B0E-2B11', + 'U+EBE1-EBE7', + 'U+ECE0', + 'U+EFCC', + ), +); + +/// Retrieve the unicode range for a given unicode range name +/// @param {String} $name +/// @returns {List} +@function get-range($name) { + @if map.has-key($ranges, $name) { + @return map.get($ranges, $name); + } + @error 'Unable to find range with the name: #{$name}'; +} diff --git a/packages/type/scss/modules/_font-family.scss b/packages/type/scss/modules/_font-family.scss index 12f90dfa81bd..828d31ba308e 100644 --- a/packages/type/scss/modules/_font-family.scss +++ b/packages/type/scss/modules/_font-family.scss @@ -43,6 +43,10 @@ $font-families: ( unquote( "'IBM Plex Sans KR', system-ui, -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', sans-serif" ), + 'sans-thai-looped': + unquote( + "'IBM Plex Sans Thai Looped', system-ui, -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', sans-serif" + ), 'sans-thai': unquote( "'IBM Plex Sans Thai', system-ui, -apple-system, BlinkMacSystemFont, '.SFNSText-Regular', sans-serif"