Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(devenv): re-introduce theme switcher #3073

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Binary file removed .yarn/offline-mirror/carbon-components-9.91.1.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/carbon-components-9.91.3.tgz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed .yarn/offline-mirror/gulp-autoprefixer-6.1.0.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/gulp-concat-2.6.1.tgz
Binary file not shown.
Binary file added .yarn/offline-mirror/gulp-postcss-8.0.0.tgz
Binary file not shown.
Expand Up @@ -13,7 +13,7 @@
position: relative;
padding: 2rem 2rem 2.5rem;
margin: 1.5rem 0 0;
background-color: $ui-02;
background-color: $ui-background;
color: $text-01;
border: solid $ui-03 1px;

Expand Down
59 changes: 56 additions & 3 deletions packages/components/demo/js/components/RootPage.js
@@ -1,12 +1,31 @@
import PropTypes from 'prop-types';
import React, { Component, Fragment } from 'react';
import { ToggleSmall } from 'carbon-components-react';
import { Dropdown, DropdownItem, ToggleSmall } from 'carbon-components-react';
import eventMatches from '../../../src/globals/js/misc/event-matches';
import on from '../../../src/globals/js/misc/on';
import CodePage from './CodePage/CodePage';
import SideNav from './SideNav';
import PageHeader from './PageHeader/PageHeader';

const themeSwitcherItems = [
{
id: 'white',
text: 'White',
},
{
id: 'g10',
text: 'Gray 10',
},
{
id: 'g90',
text: 'Gray 90',
},
{
id: 'g100',
text: 'Gray 100',
},
];

const checkStatus = response => {
if (response.status >= 200 && response.status < 400) {
return response;
Expand Down Expand Up @@ -172,7 +191,9 @@ class RootPage extends Component {
});
}

state = {};
state = {
currentTheme: themeSwitcherItems[0].id,
};

static getDerivedStateFromProps({ componentItems, isComponentsX }, state) {
const {
Expand Down Expand Up @@ -412,6 +433,22 @@ class RootPage extends Component {
}
}

/**
* Handles selection change in theme switcher dropdown.
* @param {object} evt
* @param {object} evt.value The id of the selected dropdown item.
*/
_handleChangeThemeSwitcherDropdown = ({ value }) => {
this.setState({ currentTheme: value }, () => {
themeSwitcherItems.forEach(item => {
document.documentElement.classList.toggle(
`demo--theme--${item.id}`,
item.id === value
);
});
});
};

/**
* Switches the selected component.
* @param {string} selectedNavItemId The ID of the newly selected component.
Expand All @@ -437,7 +474,12 @@ class RootPage extends Component {

render() {
const { portSassBuild, useStaticFullRenderPage } = this.props;
const { componentItems, isComponentsX, selectedNavItemId } = this.state;
const {
componentItems,
isComponentsX,
selectedNavItemId,
currentTheme,
} = this.state;
const metadata = this.getCurrentComponentItem();
const { name, label } = metadata || {};
return !metadata ? null : (
Expand Down Expand Up @@ -468,6 +510,17 @@ class RootPage extends Component {
onChange={this._switchExperimental}
/>
</main>
<div className="demo--theme-switcher--dropdown">
<Dropdown
items={themeSwitcherItems}
itemToString={item => (item ? item.text : '')}
value={currentTheme}
onChange={this._handleChangeThemeSwitcherDropdown}>
{themeSwitcherItems.map(({ id, text }) => (
<DropdownItem itemText={text} value={id} />
))}
</Dropdown>
</div>
</Fragment>
);
}
Expand Down
37 changes: 37 additions & 0 deletions packages/components/demo/scss/_theme.scss
@@ -0,0 +1,37 @@
@import '../../src/globals/scss/vendor/@carbon/elements/scss/themes/theme-maps';

/// @param {Map} $theme-map [$carbon--theme] The theme map to base the result on.
/// @return {Map} A Carbon theme map whose valus are CSS custom properties.
@function carbon-get-theme-map-with-custom-properties(
$theme-map: $carbon--theme
) {
$theme-map--with-custom-properties: ();
@each $key in map-keys($theme-map) {
$theme-map--with-custom-properties: map-merge(
$theme-map--with-custom-properties,
(
$key: var(--#{$key}),
)
);
}
@return $theme-map--with-custom-properties;
}

/// Emits CSS custom properties from a Carbon theme map.
/// @param {Map} $theme-map [$carbon--theme] The theme map to emit CSS custom properties from.
/// @example @include carbon--theme--custom-properties($carbon--theme--white);
@mixin carbon--theme--custom-properties($theme-map: $carbon--theme) {
@each $key, $value in $theme-map {
--#{$key}: #{$value};
}
}

/// The key/value map of Carbon themes, named by theme name.
/// @type Map
$carbon--theme--list: (
'white': $carbon--theme--white,
'g10': $carbon--theme--g10,
'g90': $carbon--theme--g90,
'g100': $carbon--theme--g100,
'custom-properties': carbon-get-theme-map-with-custom-properties(),
);
45 changes: 44 additions & 1 deletion packages/components/demo/scss/demo.scss
Expand Up @@ -21,6 +21,16 @@
// )
// );

@import './_theme.scss';

/// The theme name to use in the dev env.
/// @type String
$demo--carbon--theme-name: 'white' !default;

/// The Carbon theme to use, chosen with `$demo--carbon--theme-name`.
/// @type Map
$carbon--theme: map-get($carbon--theme--list, $demo--carbon--theme-name);

@import '../../src/globals/scss/styles';

$deprecations--entry: true;
Expand Down Expand Up @@ -71,10 +81,36 @@ REASON: #{$reason}';
box-sizing: border-box;
padding-top: 1em;
transition: 0.2s;
background-color: $ui-02;
background-color: $ui-background;
padding-left: 0;
}

:root {
@include carbon--theme--custom-properties($carbon--theme--white);
}

.demo--container,
:root.demo--theme--white .demo--container,
.component-example__live,
:root.demo--theme--white .component-example__live {
@include carbon--theme--custom-properties($carbon--theme--white);
}

:root.demo--theme--g10 .demo--container,
:root.demo--theme--g10 .component-example__live {
@include carbon--theme--custom-properties($carbon--theme--g10);
}

:root.demo--theme--g90 .demo--container,
:root.demo--theme--g90 .component-example__live {
@include carbon--theme--custom-properties($carbon--theme--g90);
}

:root.demo--theme--g100 .demo--container,
:root.demo--theme--g100 .component-example__live {
@include carbon--theme--custom-properties($carbon--theme--g100);
}

.demo--container.demo--container--list-box > .demo--container__panel,
.demo--container.demo--container--multi-select > .demo--container__panel,
.component-example__live--rendered.list-box > div,
Expand All @@ -94,6 +130,13 @@ REASON: #{$reason}';
display: none; // Temporarily hide theme switcher
}

.demo--theme-switcher--dropdown {
position: absolute;
top: rem(32px);
right: rem(32px);
display: if($demo--carbon--theme-name == 'custom-properties', block, none);
}

.bx--tile-container {
width: 100%;

Expand Down
83 changes: 61 additions & 22 deletions packages/components/gulpfile.js
Expand Up @@ -7,7 +7,9 @@ const http = require('http');

// Styles
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const deduper = require('postcss-discard-duplicates');

// Javascript deps
const babel = require('gulp-babel');
Expand All @@ -24,13 +26,16 @@ const gulp = require('gulp');
const rename = require('gulp-rename');
const sourcemaps = require('gulp-sourcemaps');
const header = require('gulp-header');
const concat = require('gulp-concat');
const jsdoc = require('gulp-jsdoc3');
const log = require('fancy-log');
const through = require('through2');
const merge = require('merge2');

// Rollup
const { rollup } = require('rollup');
const commonjs = require('rollup-plugin-commonjs');
const { terser: rollupTerser } = require('rollup-plugin-terser');
const rollupConfigDev = require('./tools/rollup.config.dev');
const rollupConfigProd = require('./tools/rollup.config');

Expand Down Expand Up @@ -71,6 +76,10 @@ const cloptions = commander
'-b, --use-breaking-changes',
'Build with breaking changes turned on (For dev build only)'
)
.option(
'--use-custom-properties',
'Build CSS with custom properties (For dev build only)'
)
.option(
'-e, --use-experimental-features',
'Build with experimental features turned on (For dev build only)'
Expand Down Expand Up @@ -130,7 +139,7 @@ gulp.task('clean', () =>
* JavaScript Tasks
*/

const { useBreakingChanges } = cloptions;
const { useBreakingChanges, useCustomProperties } = cloptions;
let { useExperimentalFeatures } = cloptions;

gulp.task('scripts:dev:feature-flags', () => {
Expand Down Expand Up @@ -161,12 +170,20 @@ gulp.task('scripts:dev:feature-flags', () => {

const buildDemoJS = () => {
if (cloptions.rollup) {
return rollup(rollupConfigDev)
return rollup({
...rollupConfigDev,
plugins: [
...rollupConfigDev.plugins,
process.env.NODE_ENV !== 'production' ? {} : rollupTerser(),
],
})
.then(bundle =>
bundle.write({
format: 'iife',
name: 'CarbonComponents',
file: 'demo/demo.js',
file: `demo/demo${
process.env.NODE_ENV !== 'production' ? '' : '.min'
}.js`,
sourcemap: 'inline',
})
)
Expand Down Expand Up @@ -324,9 +341,11 @@ const buildStyles = prod => {
}).on('error', sass.logError)
)
.pipe(
autoprefixer({
browsers: ['> 1%', 'last 2 versions'],
})
postcss([
autoprefixer({
browsers: ['> 1%', 'last 2 versions'],
}),
])
)
.pipe(
rename(filePath => {
Expand Down Expand Up @@ -363,26 +382,46 @@ gulp.task('sass:dev', () => {
flags['components-x'] = useExperimentalFeatures;
flags.grid = useExperimentalFeatures;
}
return gulp
.src('demo/scss/demo.scss')
.pipe(sourcemaps.init())
.pipe(
header(`
const createStream = (theme = 'white') =>
gulp
.src('demo/scss/demo.scss')
.pipe(sourcemaps.init())
.pipe(
header(`
$demo--carbon--theme-name: ${theme};
$feature-flags: (${Object.keys(flags)
.reduce((a, flag) => [...a, `${flag}: ${!!flags[flag]}`], [])
.join(', ')});
`)
)
.pipe(
sass({
includePaths: ['node_modules'],
outputStyle: 'expanded',
}).on('error', sass.logError)
)
)
.pipe(
sass({
includePaths: ['node_modules'],
outputStyle: 'expanded',
}).on('error', sass.logError)
);
if (useCustomProperties) {
return merge(createStream(), createStream('custom-properties'))
.pipe(concat('demo.css'))
.pipe(
postcss([
deduper(),
autoprefixer({
browsers: ['> 1%', 'last 2 versions'],
}),
])
)
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('demo'))
.pipe(browserSync.stream({ match: '**/*.css' }));
}
return createStream()
.pipe(
autoprefixer({
browsers: ['> 1%', 'last 2 versions'],
})
postcss([
autoprefixer({
browsers: ['> 1%', 'last 2 versions'],
}),
])
)
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('demo'))
Expand Down