Skip to content

Commit

Permalink
feat(pixels): add inital package
Browse files Browse the repository at this point in the history
  • Loading branch information
toxsick committed Apr 12, 2024
1 parent e75a0dd commit ad580ee
Show file tree
Hide file tree
Showing 54 changed files with 10,898 additions and 1,198 deletions.
17 changes: 17 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
# see: https://pnpm.io/next/npmrc#auto-install-peers
auto-install-peers=true

# storybook-config
public-hoist-pattern[]=@testing-library/*
public-hoist-pattern[]=*storybook*
public-hoist-pattern[]=jsdom
public-hoist-pattern[]=nyc
public-hoist-pattern[]=playwright

# tailwind-config
public-hoist-pattern[]=tailwindcss

# vite-config
public-hoist-pattern[]=@vitejs/plugin-react
public-hoist-pattern[]=rollup-plugin-visualizer
public-hoist-pattern[]=vite
public-hoist-pattern[]=vite-plugin-dts
public-hoist-pattern[]=vite-tsconfig-paths

# @fuf-stack/project-cli-tools
public-hoist-pattern[]=@commitlint*
public-hoist-pattern[]=@lerna-lite*
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ install:
pnpm install --ignore-scripts;
pnpm husky install;
pnpm build;

storybook:
@$(MAKE) install;
pnpm --filter storybook-config storybook;
6 changes: 5 additions & 1 deletion lint-staged.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
module.exports = {
// pixels
'packages/pixels/**/*.{js,ts,tsx}': ['eslint', 'vitest related --run'],
// uniform
'packages/uniform/**/*.{ts}': ['eslint', 'vitest related --run'],
'packages/uniform/**/*.{js,ts,tsx}': ['eslint', 'vitest related --run'],
// veto
'packages/veto/**/*.{js,ts,tsx}': ['eslint', 'vitest related --run'],
// config packages
'packages/config/**/*.{js,ts}': ['eslint'],
// other filetypes
Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
{
"private": true,
"scripts": {
"build": "pnpm --filter=\"@fuf-stack/*\" build",
"build": "pnpm turbo build",
"commit": "lint-staged && git-cz",
"dev": "lerna run --parallel dev",
"fix": "eslint --debug --fix --ext .js --ignore-path .gitignore packages || true && prettier --write \"packages/**/*\"",
"lint": "eslint --debug --ignore-path .gitignore ./packages",
"test": "NODE_OPTIONS=\"--max-old-space-size=4096\" FORCE_COLOR=1 vitest --coverage $VITEST_EXTRA_OPTS"
"test": "NODE_OPTIONS=\"--max-old-space-size=4096\" FORCE_COLOR=1 vitest --coverage $VITEST_EXTRA_OPTS",
"test:storybook": "pnpm exec playwright install chromium && test-storybook --coverage --config-dir packages/config/storybook-config/.storybook --maxWorkers=4 && nyc report --reporter=lcov -t coverage/storybook --report-dir coverage/storybook",
"turbo": "FORCE_COLOR=1 turbo --cache-dir ./.turbo-cache --color --no-daemon"
},
"devDependencies": {
"@types/node": "20.12.5",
"@fuf-stack/eslint-config-fuf": "0.8.0",
"@fuf-stack/eslint-config-fuf": "0.8.3",
"@fuf-stack/project-cli-tools": "0.4.1",
"@fuf-stack/vitest-config": "0.1.0",
"@fuf-stack/vitest-config": "0.1.1",
"ts-node": "10.9.2",
"typescript": "5.4.4"
},
Expand Down
11 changes: 11 additions & 0 deletions packages/config/storybook-config/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import sharedConfig, { StorybookConfig } from '../main';

const config: StorybookConfig = {
...sharedConfig,
stories: [
'../../../pixels/src/**/*.stories.@(ts|tsx)',
'../../../uniform/**/*.stories.@(ts|tsx)',
],
};

export default config;
3 changes: 3 additions & 0 deletions packages/config/storybook-config/.storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<script>
window.global = window;
</script>
10 changes: 10 additions & 0 deletions packages/config/storybook-config/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import sharedPreview, { Preview } from '../preview';

// load tailwind css
import 'tailwind-config/tailwind.css';

const preview: Preview = {
...sharedPreview,
};

export default preview;
3 changes: 3 additions & 0 deletions packages/config/storybook-config/.storybook/test-runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import config from '../test-runner';

export default config;
45 changes: 45 additions & 0 deletions packages/config/storybook-config/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { StorybookConfig } from '@storybook/react-vite';

import path from 'path';

const config: StorybookConfig = {
// this has to be defined where shared config is used
stories: [],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'@storybook/addon-links',
'@storybook/addon-a11y',
'@storybook/addon-interactions',
{
name: '@storybook/addon-coverage',
options: {
istanbul: {
// coverage paths should be from project root
cwd: path.resolve(__dirname, '../../'),
// exclude files from coverage report
exclude: ['**/__generated__/*', '**/*.cy.*', '**/*.stories.*'],
},
},
},
'storybook-dark-mode',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
core: {
// disable telemetry
// see: https://storybook.js.org/docs/react/configure/telemetry#how-to-opt-out
disableTelemetry: true,
},
// enable autodocs for all stories
// see: https://storybook.js.org/docs/react/writing-docs/autodocs
docs: {
autodocs: true,
},
};

export default config;

export type { StorybookConfig };
36 changes: 36 additions & 0 deletions packages/config/storybook-config/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "storybook-config",
"description": "uniforms shared storybook config",
"version": "0.0.1",
"private": true,
"main": "index.js",
"scripts": {
"storybook": "storybook dev -p 6006",
"storybook:build": "rm -rf ./dist && storybook build --quiet",
"test": "test-storybook"
},
"devDependencies": {
"@storybook/addon-a11y": "8.0.6",
"@storybook/addon-actions": "8.0.6",
"@storybook/addon-coverage": "1.0.1",
"@storybook/addon-essentials": "8.0.6",
"@storybook/addon-interactions": "8.0.6",
"@storybook/addon-links": "8.0.6",
"@storybook/addon-storyshots": "7.6.17",
"@storybook/blocks": "8.0.6",
"@storybook/node-logger": "8.0.6",
"@storybook/react": "8.0.6",
"@storybook/react-vite": "8.0.6",
"@storybook/test": "8.0.6",
"@storybook/test-runner": "0.17.0",
"axe-playwright": "2.0.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"storybook": "8.0.6",
"storybook-dark-mode": "4.0.1",
"tailwind-config": "workspace:*",
"vite-config": "workspace:*",
"jsdom": "24.0.0",
"@testing-library/react": "14.3.0"
}
}
5 changes: 5 additions & 0 deletions packages/config/storybook-config/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* eslint-disable import/no-extraneous-dependencies */

const postcssConfig = require('tailwind-config/postcss.config');

module.exports = postcssConfig;
93 changes: 93 additions & 0 deletions packages/config/storybook-config/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* eslint-disable import/no-extraneous-dependencies */

import type { Decorator, Preview } from '@storybook/react';

import { useEffect } from 'react';

import { UPDATE_GLOBALS } from '@storybook/core-events';
import { addons } from '@storybook/preview-api';
import { DARK_MODE_EVENT_NAME, useDarkMode } from 'storybook-dark-mode';

// see: https://github.com/hipstersmoothie/storybook-dark-mode/issues/168
const DarkModeHtmlAttributeDecorator: Decorator = (Story) => {
const isDarkMode = useDarkMode();
useEffect(() => {
document.documentElement.dataset.theme = isDarkMode ? 'dark' : 'light';
}, [isDarkMode]);
return <Story />;
};

// see: https://github.com/storybookjs/test-runner/issues/74#issuecomment-1165389157
const DisableTestRunnerDecorator: Decorator = (Story, { parameters }) => {
if (
parameters.testRunner?.disable === true &&
navigator.userAgent.includes('StorybookTestRunner')
) {
return <>Disabled for Test Runner</>;
}
return <Story />;
};

const preview: Preview = {
decorators: [DarkModeHtmlAttributeDecorator, DisableTestRunnerDecorator],
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
// show also description and default in controls panel
controls: { expanded: true },
backgrounds: {
default: 'lightgray',
values: [
{
name: 'lightgray',
value: '#f5f7fa',
},
{
name: 'white',
value: '#ffffff',
},
{
name: 'dark',
value: '#333333',
},
],
},
// configure dark mode
// see: https://storybook.js.org/addons/storybook-dark-mode
darkMode: {
// Set the initial theme to light
current: 'light',
stylePreview: true,
darkClass: 'dark',
lightClass: 'ignore-sb-light',
},
layout: 'centered',
},
};

// change background when dark mode is toggled
// see: https://www.bekk.christmas/post/2021/3/storybook-background-change-on-prop-change
const channel = addons.getChannel();

let previousIsDarkMode = false;

const darkModeToggleListener = (isDarkMode) => {
if (previousIsDarkMode !== isDarkMode) {
console.log('dark mode changed, setting background...', {
isDarkMode,
});
previousIsDarkMode = isDarkMode;
channel.emit(UPDATE_GLOBALS, {
globals: {
backgrounds: isDarkMode
? { name: 'dark', value: '#333333' }
: { name: 'lightgray', value: '#f5f7fa' },
},
});
}
};

channel.addListener(DARK_MODE_EVENT_NAME, darkModeToggleListener);

export default preview;

export type { Preview };
49 changes: 49 additions & 0 deletions packages/config/storybook-config/story-snapshots.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* eslint-disable import/no-extraneous-dependencies */

// see: https://storybook.js.org/docs/writing-tests/snapshot-testing#execute-tests-on-multiple-stories

import type { Meta, StoryFn } from '@storybook/react';

import { expect, test } from 'vitest';

import { composeStories } from '@storybook/react';
import { render } from '@testing-library/react';

type StoryFile = {
default: Meta;
[name: string]: StoryFn | Meta;
};

const compose = (
entry: StoryFile,
): ReturnType<typeof composeStories<StoryFile>> => {
try {
return composeStories(entry);
} catch (e) {
throw new Error(
`There was an issue composing stories for the module: ${JSON.stringify(entry)}, ${e}`,
);
}
};

export default (storyFile: StoryFile) => {
const stories = Object.entries(compose(storyFile)).map(([name, story]) => ({
name,
story,
}));

if (stories.length <= 0) {
throw new Error(
`No stories found for this module: ${storyFile.default.title}. Make sure there is at least one valid story for this module.`,
);
}

stories.forEach(({ name, story }) => {
test(name, async () => {
const mounted = render(story());
// Ensures a consistent snapshot by waiting for the component to render by adding a delay of 1 ms before taking the snapshot.
await new Promise((resolve) => setTimeout(resolve, 1));
expect(mounted.container).toMatchSnapshot();
});
});
};
7 changes: 7 additions & 0 deletions packages/config/storybook-config/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */

const sharedConfig = require('tailwind-config/tailwind.config');

module.exports = {
presets: [sharedConfig],
};
26 changes: 26 additions & 0 deletions packages/config/storybook-config/test-runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-disable import/no-extraneous-dependencies */

import type { TestRunnerConfig } from '@storybook/test-runner';

import { checkA11y, injectAxe } from 'axe-playwright';

/*
* See https://storybook.js.org/docs/writing-tests/test-runner#test-hook-api
* to learn more about the test-runner hooks API.
*/
const config: TestRunnerConfig = {
async preVisit(_page) {
// setup axe-playwright
// see: https://storybook.js.org/docs/writing-tests/accessibility-testing#automate-accessibility-tests-with-test-runner
await injectAxe(page);
},
async postVisit(_page) {
// test accessibility
await checkA11y(page, '#storybook-root', {
verbose: false,
detailedReport: false,
});
},
};

export default config;
4 changes: 4 additions & 0 deletions packages/config/storybook-config/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "../../../tsconfig.base.json",
"references": [{ "path": "../../pixels" }]
}
5 changes: 5 additions & 0 deletions packages/config/storybook-config/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* eslint-disable import/no-extraneous-dependencies */

import viteConfig from 'vite-config/vite.config';

export default viteConfig;
12 changes: 12 additions & 0 deletions packages/config/tailwind-config/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "tailwind-config",
"description": "uniforms shared tailwind config",
"version": "0.0.1",
"private": true,
"main": "index.js",
"devDependencies": {
"@nextui-org/theme": "2.1.18",
"autoprefixer": "10.4.19",
"tailwindcss": "3.4.3"
}
}
6 changes: 6 additions & 0 deletions packages/config/tailwind-config/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
Loading

0 comments on commit ad580ee

Please sign in to comment.