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

Storybook 8 #39

Merged
merged 13 commits into from
Aug 30, 2024
6 changes: 5 additions & 1 deletion .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ const safeConfigOverrides = configOverrides || {};

const config = {
stories: [
'../../../../src/**/*.stories.@(js|jsx|ts|tsx)',
'../../../../(src|components)/**/*.stories.@(js|jsx|ts|tsx)',
],
staticDirs: [
'../../../../assets/images',
'../../../../assets/icons',
],
addons: [
'../../../@storybook/addon-a11y',
Expand Down
3 changes: 1 addition & 2 deletions .storybook/manager.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { addons } from '@storybook/addons';

import { addons } from '@storybook/manager-api';
import emulsifyTheme from './emulsifyTheme';

import('../../../../config/emulsify-core/storybook/theme')
Expand Down
6 changes: 2 additions & 4 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { useEffect } from '@storybook/client-api';
import { useEffect } from '@storybook/preview-api';
import Twig from 'twig';
import { setupTwig } from './setupTwig';

// GLOBAL CSS
import('../../../../dist/storybook/storybook.css');
// Custom theme preview config if it exists.
// Project config to import stylesheets.
import('../../../../config/emulsify-core/storybook/preview');

// If in a Drupal project, it's recommended to import a symlinked version of drupal.js.
Expand Down
1 change: 0 additions & 1 deletion config/eslintrc.config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"extends": [
"airbnb-base",
"eslint:recommended",
"plugin:import/recommended",
"plugin:security/recommended-legacy",
Expand Down
9 changes: 6 additions & 3 deletions config/webpack/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const _MiniCssExtractPlugin = require('mini-css-extract-plugin');
const _SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
const CopyPlugin = require('copy-webpack-plugin');
const glob = require('glob');
const fs = require('fs-extra');

// Get directories for file contexts.
const projectDir = path.resolve(__dirname, '../../../../..');
Expand Down Expand Up @@ -57,9 +58,11 @@ function getPatterns(filesMatcher) {
}

// Copy twig files from src directory.
const CopyTwigPlugin = new CopyPlugin({
patterns: getPatterns(componentFilesPattern),
});
const CopyTwigPlugin = fs.existsSync(path.resolve(projectDir, 'src'))
? new CopyPlugin({
patterns: getPatterns(componentFilesPattern),
})
: '';

// Export plugin configuration.
module.exports = {
Expand Down
46 changes: 29 additions & 17 deletions config/webpack/resolves.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,58 @@
const path = require('path');
const glob = require('glob');
const fs = require('fs-extra');

// Emulsify project configuration.
const emulsifyConfig = require('../../../../../project.emulsify.json');

// Get directories for file contexts.
const projectDir = path.resolve(__dirname, '../../../../..');
const projectName = emulsifyConfig.project.name;
const srcDir = path.resolve(projectDir, 'src');
const srcDir = fs.existsSync(path.resolve(projectDir, 'src'))
? path.resolve(projectDir, 'src')
: path.resolve(projectDir, 'components');

// Glob pattern for twig aliases.
const aliasPattern = path.resolve(srcDir, '**/!(_*).twig');

// Get all directories from a specified directory.
function getDirectories(source) {
const dirs = fs
.readdirSync(source, { withFileTypes: true }) // Read contents of the directory
.filter((dirent) => dirent.isDirectory()) // Filter only directories
.map((dirent) => dirent.name);
return dirs;
}

// Clean up directory names for namespacing purposes.
function cleanDirectoryName(dir) {
if (/^\d{2}/.test(dir)) {
return dir.slice(3);
}
return dir;
}

// Prepare list of twig files to copy to "compiled" directories.
function getAliases(aliasMatcher) {
// Create default aliases
let aliases = {};
// Add SDC compatible aliases.
glob.sync(aliasMatcher).forEach((file) => {
const filePath = file.split('src/')[1];
const filePath = file.split(`${srcDir}/`)[1];
const fileName = path.basename(filePath);

if (emulsifyConfig.project.platform === 'drupal') {
aliases[`${projectName}:${fileName.replace('.twig', '')}`] = file;
}
});

if (emulsifyConfig.project.platform === 'drupal') {
// Add typical @namespace (path to directory) aliases for twig partials.
const dirs = getDirectories(srcDir);
dirs.forEach((dir) => {
const name = cleanDirectoryName(dir);
Object.assign(aliases, {
'@tokens': `${projectDir}/src/tokens`,
'@foundation': `${projectDir}/src/foundation`,
'@components': `${projectDir}/src/components`,
'@layout': `${projectDir}/src/layout`,
[`@${name}`]: `${projectDir}/${path.basename(srcDir)}/${dir}`,
});
} else {
aliases = {
'@tokens': `${projectDir}/src/tokens`,
'@foundation': `${projectDir}/src/foundation`,
'@components': `${projectDir}/src/components`,
'@layout': `${projectDir}/src/layout`,
};
}

});
return aliases;
}

Expand Down
75 changes: 50 additions & 25 deletions config/webpack/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,49 @@ const plugins = require('./plugins');
const resolves = require('./resolves');
const optimizers = require('./optimizers');
const emulsifyConfig = require('../../../../../project.emulsify.json');
const fs = require('fs-extra');

// Get directories for file contexts.
const webpackDir = path.resolve(__dirname);
const projectDir = path.resolve(__dirname, '../../../../..');
const srcDir = fs.existsSync(path.resolve(projectDir, 'src'))
? path.resolve(projectDir, 'src')
: path.resolve(projectDir, 'components');

// Glob pattern for scss files that ignore file names prefixed with underscore.
const BaseScssPattern = path.resolve(
projectDir,
'src/{tokens,foundation,layout}/**/!(_*|cl-*|sb-*).scss',
);
const ComponentScssPattern = path.resolve(
projectDir,
'src/components/**/!(_*|cl-*|sb-*).scss',
);
const ComponentLibraryScssPattern = path.resolve(
projectDir,
'src/util/**/!(_).scss',
);
const BaseScssPattern = fs.existsSync(path.resolve(projectDir, 'src'))
? path.resolve(srcDir, '!(components|util)/**/!(_*|cl-*|sb-*).scss')
: '';
const ComponentScssPattern = fs.existsSync(path.resolve(projectDir, 'src'))
? path.resolve(srcDir, 'components/**/!(_*|cl-*|sb-*).scss')
: path.resolve(srcDir, '**/!(_*|cl-*|sb-*).scss');
const ComponentLibraryScssPattern = path.resolve(srcDir, 'util/**/!(_).scss');

// Glob pattern for JS files.
const jsPattern = path.resolve(
projectDir,
'src/components/**/!(*.stories|*.component|*.min|*.test).js',
);
const jsPattern = fs.existsSync(path.resolve(projectDir, 'src'))
? path.resolve(
srcDir,
'components/**/!(*.stories|*.component|*.min|*.test).js',
)
: path.resolve(srcDir, '**/!(*.stories|*.component|*.min|*.test).js');

// Glob pattern for svgSprite config.
const spritePattern = path.resolve(webpackDir, 'svgSprite.js');

// Helper function to replace the last instance of / in a path.
function replaceLastSlash(str, replacement) {
// Find the last occurrence of '/'
const lastSlashIndex = str.lastIndexOf('/');
// If there is no '/' in the string, return the original string
if (lastSlashIndex === -1) {
return str;
}
// Replace the last '/' with the specified replacement
return (
str.slice(0, lastSlashIndex) + replacement + str.slice(lastSlashIndex + 1)
);
}

// Prepare list of scss and js file for "entry".
function getEntries(
BaseScssMatcher,
Expand All @@ -43,24 +58,30 @@ function getEntries(
) {
const entries = {};

// Token/Foundation/Layout SCSS entries.
// Non-component or global SCSS entries.
glob.sync(BaseScssMatcher).forEach((file) => {
const filePath = file.split(/(tokens\/|foundation\/|layout\/)/)[2];
const filePath = file.split(`${srcDir}/`)[1];
const filePathDist = filePath.split('/')[1]
? filePath.split('/')[1]
: filePath.split('/')[0];
const newfilePath = `dist/global/${filePathDist.replace('.scss', '')}`;
const newfilePath = fs.existsSync(path.resolve(projectDir, 'src'))
? `dist/global/${filePathDist.replace('.scss', '')}`
: `dist/css/${filePathDist.replace('.scss', '')}`;
entries[newfilePath] = file;
});

// Component SCSS entries.
glob.sync(ComponentScssMatcher).forEach((file) => {
const filePath = file.split('components/')[1];
const filePathDist = filePath.replace('/', '/css/');
const filePathDist = replaceLastSlash(filePath, '/css/');
const distStructure = fs.existsSync(path.resolve(projectDir, 'src'))
? 'components'
: 'css';
const newfilePath =
emulsifyConfig.project.platform === 'drupal'
emulsifyConfig.project.platform === 'drupal' &&
fs.existsSync(path.resolve(projectDir, 'src'))
? `components/${filePathDist.replace('.scss', '')}`
: `dist/components/${filePathDist.replace('.scss', '')}`;
: `dist/${distStructure}/${filePathDist.replace('.scss', '')}`;
entries[newfilePath] = file;
});

Expand All @@ -75,11 +96,15 @@ function getEntries(
glob.sync(jsMatcher).forEach((file) => {
if (!file.includes('dist/')) {
const filePath = file.split('components/')[1];
const filePathDist = filePath.replace('/', '/js/');
const filePathDist = replaceLastSlash(filePath, '/js/');
const distStructure = fs.existsSync(path.resolve(projectDir, 'src'))
? 'components'
: 'js';
const newfilePath =
emulsifyConfig.project.platform === 'drupal'
emulsifyConfig.project.platform === 'drupal' &&
fs.existsSync(path.resolve(projectDir, 'src'))
? `components/${filePathDist.replace('.js', '')}`
: `dist/components/${filePathDist.replace('.js', '')}`;
: `dist/${distStructure}/${filePathDist.replace('.js', '')}`;
entries[newfilePath] = file;
}
});
Expand Down
Loading
Loading