Skip to content

Commit

Permalink
chore: Expose styles build as a standalone feature (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
just-boris authored Mar 15, 2024
1 parent 89daeee commit 2a31329
Show file tree
Hide file tree
Showing 15 changed files with 107 additions and 7 deletions.
4 changes: 4 additions & 0 deletions scripts/generate-package
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const packages = [
manifest: {
name: '@cloudscape-design/theming-build',
main: './build/index.js',
exports: {
'.': './build/index.js',
'./internal': './build/internal.js'
},
files: ['shared', 'build'],
},
packageRoot: path.join(root, './lib/node'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.container {
background: #fff;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@use './commons';

.root {
inset: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.root {
/* used in test-utils */
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.root {
/* used in test-utils */
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@use 'awsui:tokens' as tokens;

.root {
background: tokens.$color-background;
}
9 changes: 9 additions & 0 deletions src/build/__tests__/__fixtures__/scss-only/simple/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
$root-color: red;

.root {
/* used in tests */
}

.red-text {
color: $root-color;
}
2 changes: 1 addition & 1 deletion src/build/__tests__/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { preset as _presetWithSecondaryTheme } from './__fixtures__/template/int
export const preset = _preset as ThemePreset;
export const presetWithSecondaryTheme = _presetWithSecondaryTheme as ThemePreset;
export const outputDir = join(__dirname, 'out');
export const scssDir = join(__dirname, '__fixtures__', 'scss');
export const scssDir = join(__dirname, '__fixtures__', 'scss-advanced');
export const templateDir = join(__dirname, '__fixtures__', 'template');
export const designTokensTemplateDir = join(__dirname, '__fixtures__', 'template-tokens');

Expand Down
66 changes: 66 additions & 0 deletions src/build/__tests__/styles.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { expect, test } from 'vitest';
import { buildStyles, InlineStylesheet } from '../internal';
import { join } from 'node:path';
import { readFileSync, readdirSync } from 'node:fs';

const fixturesRoot = join(__dirname, '__fixtures__', 'scss-only');
const outputRoot = join(__dirname, 'out', 'scss-only');

async function buildWithFixtures(suiteName: string, inlines?: InlineStylesheet[]) {
const outDir = join(outputRoot, suiteName);
await buildStyles(join(fixturesRoot, suiteName), join(outputRoot, suiteName), inlines);
return outDir;
}

test('simple styles build', async () => {
const outDir = await buildWithFixtures('simple');
expect(readdirSync(outDir)).toEqual(['styles.css.js', 'styles.scoped.css', 'styles.selectors.js']);
const { default: styles } = await import(join(outDir, 'styles.css.js'));
expect(styles).toMatchInlineSnapshot(`
{
"red-text": "awsui_red-text_4px4j_e9pfl_5",
"root": "awsui_root_4px4j_e9pfl_1",
}
`);
});

test('bundles all imports for styles.scss entry point', async () => {
const outDir = await buildWithFixtures('dependencies');
expect(readdirSync(outDir)).toEqual(['styles.css.js', 'styles.scoped.css', 'styles.selectors.js']);
const { default: styles } = await import(join(outDir, 'styles.css.js'));
// includes class names from both files in the fixture
expect(styles).toMatchInlineSnapshot(`
{
"container": "awsui_container_4px4j_1gm47_1",
"root": "awsui_root_4px4j_1gm47_5",
}
`);
});

test('supports virtual stylesheets', async () => {
const outDir = await buildWithFixtures('inlines', [{ url: 'awsui:tokens', contents: '$color-background: #abcabc' }]);
expect(readdirSync(outDir)).toEqual(['styles.css.js', 'styles.scoped.css', 'styles.selectors.js']);
const cssContent = readFileSync(join(outDir, 'styles.scoped.css'), 'utf8');
expect(cssContent).toContain('#abcabc');
});

test('throws an error if a virtual stylesheet is not defined', async () => {
// rejects with an error containing message 'Can\'t find stylesheet to import'
await expect(() => buildWithFixtures('inlines')).rejects.toThrowError(/awsui:tokens/);
});

test('mirrors directory structure of the sources', async () => {
const outDir = await buildWithFixtures('dir-structure');
expect(readdirSync(outDir)).toEqual(['styles.css.js', 'styles.scoped.css', 'styles.selectors.js', 'sub-component']);
expect(readdirSync(join(outDir, 'sub-component'))).toEqual([
'styles.css.js',
'styles.scoped.css',
'styles.selectors.js',
]);
const { default: rootStyles } = await import(join(outDir, 'styles.css.js'));
const { default: subComponentStyles } = await import(join(outDir, 'sub-component', 'styles.css.js'));
// ensure the same class name has different scoped name in different files
expect(rootStyles.root).not.toEqual(subComponentStyles.root);
});
10 changes: 6 additions & 4 deletions src/build/internal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { createStyles } from './tasks/style';
import { buildStyles, InlineStylesheet } from './tasks/style';
import { createPresetFiles } from './tasks/preset';
import { createInternalTokenFiles } from './tasks/internal-tokens';
import { createPublicTokenFiles } from './tasks/public-tokens';
Expand All @@ -9,6 +9,8 @@ import { getInlineStylesheets } from './inline-stylesheets';
import { calculatePropertiesMap } from './properties';
import findNeededTokens from './needed-tokens';

export { buildStyles, InlineStylesheet };

export type Tasks = 'preset' | 'design-tokens';

export interface BuildThemedComponentsInternalParams {
Expand Down Expand Up @@ -78,10 +80,10 @@ export async function buildThemedComponentsInternal(params: BuildThemedComponent
const defaults = reduce(resolution, primary, defaultsReducer());

const propertiesMap = calculatePropertiesMap([primary, ...secondary], variablesMap);
const styleTask = createStyles(
getInlineStylesheets(primary, secondary, defaults, variablesMap, propertiesMap, neededTokens),
const styleTask = buildStyles(
scssDir,
componentsOutputDir,
scssDir
getInlineStylesheets(primary, secondary, defaults, variablesMap, propertiesMap, neededTokens)
);
const internalTokensTask = createInternalTokenFiles(primary, defaults, propertiesMap, exposed, componentsOutputDir);

Expand Down
4 changes: 2 additions & 2 deletions src/build/tasks/style.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import sass from 'sass';
import * as sass from 'sass';
import glob from 'glob';
import { postCSSForEach, postCSSAfterAll, scopedFileExt } from './postcss';
import path from 'path';
Expand All @@ -12,7 +12,7 @@ export interface InlineStylesheet {
contents: string;
}

export async function createStyles(inlines: InlineStylesheet[], outputDir: string, sassDir: string) {
export async function buildStyles(sassDir: string, outputDir: string, inlines: InlineStylesheet[] = []) {
const files = await promisify(glob)('**/styles.scss', { cwd: sassDir });
const compiler = createCompiler(inlines, outputDir, sassDir);

Expand Down

0 comments on commit 2a31329

Please sign in to comment.