@momentum-design/components 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- package/.eslintrc.js +16 -0
- package/CONTRIBUTING.md +5 -0
- package/README.md +39 -0
- package/SCRIPTS.md +15 -0
- package/TESTING.md +38 -0
- package/config/api-extractor.json +33 -0
- package/config/custom-elements-manifest.config.js +28 -0
- package/config/esbuild/configs/browser.js +21 -0
- package/config/esbuild/configs/e2e.js +10 -0
- package/config/esbuild/esbuild-e2e.config.js +22 -0
- package/config/esbuild/esbuild.config.js +9 -0
- package/config/playwright/playwright.config.ts +107 -0
- package/config/playwright/public/index.css +43 -0
- package/config/playwright/public/index.html +26 -0
- package/config/playwright/setup/Components.page.ts +163 -0
- package/config/playwright/setup/constants.ts +27 -0
- package/config/playwright/setup/index.ts +42 -0
- package/config/playwright/setup/steps/accessibility.ts +9 -0
- package/config/playwright/setup/types.ts +5 -0
- package/config/playwright/setup/utils/accessibility.ts +70 -0
- package/config/playwright/setup/utils/visual-regression.ts +35 -0
- package/config/plop/actions/AddComponent.ts +21 -0
- package/config/plop/actions/AddToComponentExports.ts +16 -0
- package/config/plop/actions/AddToComponentImports.ts +16 -0
- package/config/plop/constants/index.ts +31 -0
- package/config/plop/esbuild.config.plop.js +4 -0
- package/config/plop/generators/component/index.ts +25 -0
- package/config/plop/plopfile.ts +6 -0
- package/config/plop/prompts/index.ts +8 -0
- package/config/plop/templates/add/component/index.ts.hbs +12 -0
- package/config/plop/templates/add/component/{{componentName}}.component.ts.hbs +22 -0
- package/config/plop/templates/add/component/{{componentName}}.constants.ts.hbs +5 -0
- package/config/plop/templates/add/component/{{componentName}}.e2e-test.ts.hbs +67 -0
- package/config/plop/templates/add/component/{{componentName}}.fixtures.ts.hbs +13 -0
- package/config/plop/templates/add/component/{{componentName}}.stories.ts.hbs +18 -0
- package/config/plop/templates/add/component/{{componentName}}.styles.ts.hbs +8 -0
- package/config/plop/tsconfig.plop.json +11 -0
- package/config/storybook/MomentumStorybookTheme.js +41 -0
- package/config/storybook/main.js +21 -0
- package/config/storybook/manager.js +17 -0
- package/config/storybook/preview.js +63 -0
- package/config/storybook/provider/iconProvider.js +8 -0
- package/config/storybook/provider/themeProvider.js +31 -0
- package/config/storybook/public/background-graphic.png +0 -0
- package/config/storybook/public/fonts/Inter.var.woff2 +0 -0
- package/config/storybook/public/momentum-logo.png +0 -0
- package/config/storybook/themes/index.js +14 -0
- package/config/storybook/themes/themes.css +15 -0
- package/data/custom-elements.json +677 -0
- package/dist/browser/index.js +366 -0
- package/dist/browser/index.js.map +7 -0
- package/dist/components/avatar/avatar.component.d.ts +28 -0
- package/dist/components/avatar/avatar.component.js +79 -0
- package/dist/components/avatar/avatar.constants.d.ts +7 -0
- package/dist/components/avatar/avatar.constants.js +14 -0
- package/dist/components/avatar/avatar.styles.d.ts +2 -0
- package/dist/components/avatar/avatar.styles.js +20 -0
- package/dist/components/avatar/avatar.types.d.ts +1 -0
- package/dist/components/avatar/avatar.types.js +2 -0
- package/dist/components/avatar/index.d.ts +7 -0
- package/dist/components/avatar/index.js +7 -0
- package/dist/components/badge/badge.component.d.ts +51 -0
- package/dist/components/badge/badge.component.js +114 -0
- package/dist/components/badge/badge.constants.d.ts +8 -0
- package/dist/components/badge/badge.constants.js +15 -0
- package/dist/components/badge/badge.styles.d.ts +2 -0
- package/dist/components/badge/badge.styles.js +26 -0
- package/dist/components/badge/badge.types.d.ts +1 -0
- package/dist/components/badge/badge.types.js +2 -0
- package/dist/components/badge/index.d.ts +7 -0
- package/dist/components/badge/index.js +7 -0
- package/dist/components/icon/icon.component.d.ts +63 -0
- package/dist/components/icon/icon.component.js +158 -0
- package/dist/components/icon/icon.constants.d.ts +6 -0
- package/dist/components/icon/icon.constants.js +12 -0
- package/dist/components/icon/icon.styles.d.ts +2 -0
- package/dist/components/icon/icon.styles.js +15 -0
- package/dist/components/icon/icon.utils.d.ts +2 -0
- package/dist/components/icon/icon.utils.js +13 -0
- package/dist/components/icon/index.d.ts +7 -0
- package/dist/components/icon/index.js +7 -0
- package/dist/components/iconprovider/iconprovider.component.d.ts +34 -0
- package/dist/components/iconprovider/iconprovider.component.js +71 -0
- package/dist/components/iconprovider/iconprovider.constants.d.ts +7 -0
- package/dist/components/iconprovider/iconprovider.constants.js +14 -0
- package/dist/components/iconprovider/iconprovider.context.d.ts +9 -0
- package/dist/components/iconprovider/iconprovider.context.js +9 -0
- package/dist/components/iconprovider/index.d.ts +7 -0
- package/dist/components/iconprovider/index.js +7 -0
- package/dist/components/text/fonts.styles.d.ts +1 -0
- package/dist/components/text/fonts.styles.js +100 -0
- package/dist/components/text/index.d.ts +7 -0
- package/dist/components/text/index.js +7 -0
- package/dist/components/text/text.component.d.ts +29 -0
- package/dist/components/text/text.component.js +41 -0
- package/dist/components/text/text.constants.d.ts +9 -0
- package/dist/components/text/text.constants.js +28 -0
- package/dist/components/text/text.styles.d.ts +2 -0
- package/dist/components/text/text.styles.js +17 -0
- package/dist/components/text/text.types.d.ts +1 -0
- package/dist/components/text/text.types.js +2 -0
- package/dist/components/text/text.utils.d.ts +20 -0
- package/dist/components/text/text.utils.js +50 -0
- package/dist/components/themeprovider/index.d.ts +7 -0
- package/dist/components/themeprovider/index.js +7 -0
- package/dist/components/themeprovider/themeprovider.component.d.ts +48 -0
- package/dist/components/themeprovider/themeprovider.component.js +86 -0
- package/dist/components/themeprovider/themeprovider.constants.d.ts +10 -0
- package/dist/components/themeprovider/themeprovider.constants.js +31 -0
- package/dist/components/themeprovider/themeprovider.context.d.ts +9 -0
- package/dist/components/themeprovider/themeprovider.context.js +13 -0
- package/dist/components/themeprovider/themeprovider.styles.d.ts +2 -0
- package/dist/components/themeprovider/themeprovider.styles.js +13 -0
- package/dist/components/themeprovider/themeprovider.types.d.ts +5 -0
- package/dist/components/themeprovider/themeprovider.types.js +2 -0
- package/dist/components/themeprovider/themeprovider.utils.d.ts +9 -0
- package/dist/components/themeprovider/themeprovider.utils.js +10 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +19 -0
- package/dist/models/component/component.component.d.ts +38 -0
- package/dist/models/component/component.component.js +45 -0
- package/dist/models/component/component.types.d.ts +15 -0
- package/dist/models/component/component.types.js +2 -0
- package/dist/models/component/index.d.ts +3 -0
- package/dist/models/component/index.js +5 -0
- package/dist/models/index.d.ts +4 -0
- package/dist/models/index.js +8 -0
- package/dist/models/provider/index.d.ts +2 -0
- package/dist/models/provider/index.js +5 -0
- package/dist/models/provider/provider.component.d.ts +70 -0
- package/dist/models/provider/provider.component.js +56 -0
- package/dist/models/provider/provider.styles.d.ts +2 -0
- package/dist/models/provider/provider.styles.js +14 -0
- package/dist/utils/provider/index.d.ts +13 -0
- package/dist/utils/provider/index.js +14 -0
- package/dist/utils/styles/index.d.ts +2 -0
- package/dist/utils/styles/index.js +14 -0
- package/dist/utils/tag-name/constants.d.ts +7 -0
- package/dist/utils/tag-name/constants.js +10 -0
- package/dist/utils/tag-name/index.d.ts +4 -0
- package/dist/utils/tag-name/index.js +10 -0
- package/dist/utils/types.d.ts +1 -0
- package/dist/utils/types.js +2 -0
- package/jest.config.js +3 -0
- package/package.json +78 -0
- package/scripts/copyFonts.js +31 -0
- package/scripts/copyIcons.js +31 -0
- package/scripts/copyTokens.js +24 -0
- package/src/components/avatar/__screenshots__/mdc-avatar.png +0 -0
- package/src/components/avatar/avatar.component.ts +74 -0
- package/src/components/avatar/avatar.constants.ts +12 -0
- package/src/components/avatar/avatar.e2e-test.ts +70 -0
- package/src/components/avatar/avatar.stories.ts +25 -0
- package/src/components/avatar/avatar.styles.ts +20 -0
- package/src/components/avatar/avatar.types.ts +1 -0
- package/src/components/avatar/index.ts +12 -0
- package/src/components/badge/__screenshots__/mdc-badge.png +0 -0
- package/src/components/badge/badge.component.ts +121 -0
- package/src/components/badge/badge.constants.ts +13 -0
- package/src/components/badge/badge.e2e-test.ts +68 -0
- package/src/components/badge/badge.stories.ts +33 -0
- package/src/components/badge/badge.styles.ts +26 -0
- package/src/components/badge/badge.types.ts +1 -0
- package/src/components/badge/index.ts +12 -0
- package/src/components/icon/__screenshots__/mdc-icon-default.png +0 -0
- package/src/components/icon/__screenshots__/mdc-icon-scale.png +0 -0
- package/src/components/icon/icon.component.ts +155 -0
- package/src/components/icon/icon.constants.ts +10 -0
- package/src/components/icon/icon.e2e-test.ts +101 -0
- package/src/components/icon/icon.stories.ts +34 -0
- package/src/components/icon/icon.styles.ts +15 -0
- package/src/components/icon/icon.utils.ts +13 -0
- package/src/components/icon/index.ts +12 -0
- package/src/components/iconprovider/__screenshots__/mdc-iconprovider.png +0 -0
- package/src/components/iconprovider/iconprovider.component.ts +76 -0
- package/src/components/iconprovider/iconprovider.constants.ts +12 -0
- package/src/components/iconprovider/iconprovider.context.ts +16 -0
- package/src/components/iconprovider/iconprovider.e2e-test.ts +65 -0
- package/src/components/iconprovider/iconprovider.stories.ts +27 -0
- package/src/components/iconprovider/iconprovider.stories.utils.ts +27 -0
- package/src/components/iconprovider/index.ts +12 -0
- package/src/components/text/__screenshots__/mdc-text-body-large.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-body-regular.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-body-small.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-heading-1.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-heading-2.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-heading-3.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-heading-4.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-heading-5.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-heading-6.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-heading-7.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-image-title.png +0 -0
- package/src/components/text/__screenshots__/mdc-text-label.png +0 -0
- package/src/components/text/fonts.styles.ts +99 -0
- package/src/components/text/index.ts +12 -0
- package/src/components/text/text.component.ts +51 -0
- package/src/components/text/text.constants.ts +27 -0
- package/src/components/text/text.e2e-test.ts +76 -0
- package/src/components/text/text.stories.ts +29 -0
- package/src/components/text/text.styles.ts +17 -0
- package/src/components/text/text.types.ts +13 -0
- package/src/components/text/text.utils.ts +51 -0
- package/src/components/themeprovider/__screenshots__/mdc-themeprovider-darkWebex.png +0 -0
- package/src/components/themeprovider/__screenshots__/mdc-themeprovider-lightWebex.png +0 -0
- package/src/components/themeprovider/index.ts +12 -0
- package/src/components/themeprovider/themeprovider.component.ts +91 -0
- package/src/components/themeprovider/themeprovider.constants.ts +32 -0
- package/src/components/themeprovider/themeprovider.context.ts +18 -0
- package/src/components/themeprovider/themeprovider.e2e-test.ts +89 -0
- package/src/components/themeprovider/themeprovider.stories.styles.css +22 -0
- package/src/components/themeprovider/themeprovider.stories.ts +38 -0
- package/src/components/themeprovider/themeprovider.stories.utils.ts +23 -0
- package/src/components/themeprovider/themeprovider.styles.ts +13 -0
- package/src/components/themeprovider/themeprovider.types.ts +7 -0
- package/src/components/themeprovider/themeprovider.utils.ts +16 -0
- package/src/index.ts +22 -0
- package/src/models/component/component.component.ts +46 -0
- package/src/models/component/component.types.ts +16 -0
- package/src/models/component/index.ts +7 -0
- package/src/models/index.ts +11 -0
- package/src/models/provider/index.ts +3 -0
- package/src/models/provider/provider.component.ts +87 -0
- package/src/models/provider/provider.styles.ts +14 -0
- package/src/stories/colors.mdx +32 -0
- package/src/stories/icons.mdx +13 -0
- package/src/stories/typography.mdx +20 -0
- package/src/utils/mixins/DisabledMixin.ts +19 -0
- package/src/utils/mixins/TabIndexMixin.ts +19 -0
- package/src/utils/provider/index.ts +21 -0
- package/src/utils/styles/index.ts +13 -0
- package/src/utils/tag-name/constants.ts +10 -0
- package/src/utils/tag-name/index.ts +15 -0
- package/src/utils/types.ts +1 -0
- package/tsconfig.json +45 -0
- package/tsconfig.module.json +47 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
/* eslint-disable no-restricted-syntax */
|
2
|
+
/* eslint-disable no-await-in-loop */
|
3
|
+
import { Locator, Page, expect, TestInfo } from '@playwright/test';
|
4
|
+
import AxeBuilder from '@axe-core/playwright';
|
5
|
+
import CONSTANTS from '../constants';
|
6
|
+
|
7
|
+
interface Accessibility {
|
8
|
+
page: Page;
|
9
|
+
testInfo: TestInfo;
|
10
|
+
}
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Contains common `accessibility` utils, which are useful when doing accessibility tests
|
14
|
+
*/
|
15
|
+
class Accessibility {
|
16
|
+
constructor(page: Page, testInfo: TestInfo) {
|
17
|
+
this.page = page;
|
18
|
+
this.testInfo = testInfo;
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Attaches the provided scan results as JSON
|
23
|
+
* to the test report
|
24
|
+
* @param accessibilityScanResults
|
25
|
+
*/
|
26
|
+
async attachA11yResults(accessibilityScanResults: any) {
|
27
|
+
await this.testInfo.attach('accessibility-scan-results', {
|
28
|
+
body: JSON.stringify(accessibilityScanResults, null, 2),
|
29
|
+
contentType: 'application/json',
|
30
|
+
});
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Checks for Accessibility violations by scanning the whole
|
35
|
+
* page with axe-core, using the specific accessibility WCAG tags to check
|
36
|
+
* and disabled rules. The results will be attached as a JSON file
|
37
|
+
* to the test report afterwards.
|
38
|
+
*
|
39
|
+
* This function will fail if there are any accessibility violations.
|
40
|
+
*/
|
41
|
+
async checkForA11yViolations() {
|
42
|
+
const accessibilityScanResults = await new AxeBuilder({ page: this.page })
|
43
|
+
.withTags(CONSTANTS.ACCESSIBILITY.WCAG_TAGS_TO_CHECK)
|
44
|
+
.disableRules(CONSTANTS.ACCESSIBILITY.RULES_TO_DISABLE)
|
45
|
+
.analyze();
|
46
|
+
|
47
|
+
await this.attachA11yResults(accessibilityScanResults);
|
48
|
+
|
49
|
+
expect(accessibilityScanResults.violations).toEqual([]);
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* pressAndCheckFocus utility function - it will press the provided `keyToPress` as often
|
54
|
+
* as the provided `elementsToBeFocused` are and checks afterwards, if the provided element of the
|
55
|
+
* `elementsToBeFocused` has been focused.
|
56
|
+
*
|
57
|
+
* If only 1 keyPress needs to be done, just simply provide the `elementsToBeFocused` array with
|
58
|
+
* 1 element, which should receive focus.
|
59
|
+
* @param keyToPress key which should be pressed
|
60
|
+
* @param elementsToBeFocused array of elements, which have to be focused after pressing a key
|
61
|
+
*/
|
62
|
+
async pressAndCheckFocus(keyToPress: string, elementsToBeFocused: Array<Locator>) {
|
63
|
+
for (const elementToBeFocused of elementsToBeFocused) {
|
64
|
+
await this.page.keyboard.press(keyToPress);
|
65
|
+
await expect(elementToBeFocused).toBeFocused();
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
export default Accessibility;
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import { Page, expect } from '@playwright/test';
|
2
|
+
import type { ScreenShotOptions } from '../types';
|
3
|
+
import CONSTANTS from '../constants';
|
4
|
+
|
5
|
+
interface VisualRegression {
|
6
|
+
page: Page;
|
7
|
+
}
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Contains common `visual-regression` utils, which are useful when doing visual-regression tests
|
11
|
+
*/
|
12
|
+
class VisualRegression {
|
13
|
+
constructor(page: Page) {
|
14
|
+
this.page = page;
|
15
|
+
}
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Takes a screenshot of the whole page, with the passed in options
|
19
|
+
*
|
20
|
+
* @param name - name of the screenshot, file extension will be appended automatically!
|
21
|
+
* @param options - description
|
22
|
+
* @param options.element - element to take screenshot from
|
23
|
+
*/
|
24
|
+
async takeScreenshot(name: string, options?: ScreenShotOptions): Promise<void> {
|
25
|
+
const elementToTakeScreenShotFrom = options?.element || this.page;
|
26
|
+
|
27
|
+
expect(await elementToTakeScreenShotFrom.screenshot(options)).toMatchSnapshot({
|
28
|
+
name: `${name}.${CONSTANTS.VISUAL_REGRESSION.FILE_EXTENSION}`,
|
29
|
+
threshold: CONSTANTS.VISUAL_REGRESSION.THRESHOLD,
|
30
|
+
maxDiffPixelRatio: CONSTANTS.VISUAL_REGRESSION.MAX_DIFF_PIXELS_RATIO,
|
31
|
+
});
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
export default VisualRegression;
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { join } from 'path';
|
2
|
+
import { ActionType } from 'plop';
|
3
|
+
import { folders, ACTION, TYPE, componentName, componentNamePrefix, componentNameSeparator } from '../constants';
|
4
|
+
|
5
|
+
const base = `${join(`${folders.templates}`, `${ACTION.ADD}`, `${TYPE.COMPONENT}`)}`;
|
6
|
+
|
7
|
+
export const AddComponent: ActionType = {
|
8
|
+
type: 'addMany',
|
9
|
+
base,
|
10
|
+
templateFiles: `${join(`${base}`, '**')}`,
|
11
|
+
destination: `${join(`${folders.components}`, `{{${componentName}}}`)}`,
|
12
|
+
data: {
|
13
|
+
componentName,
|
14
|
+
prefix: componentNamePrefix,
|
15
|
+
separator: componentNameSeparator,
|
16
|
+
},
|
17
|
+
globOptions: {
|
18
|
+
// allow hidden files to be copied as well:
|
19
|
+
dot: false,
|
20
|
+
},
|
21
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/* eslint-disable max-len */
|
2
|
+
import { join } from 'path';
|
3
|
+
import { ActionType } from 'plop';
|
4
|
+
import { folders, componentName, componentNamePrefix } from '../constants';
|
5
|
+
|
6
|
+
export const AddToComponentExports: ActionType = {
|
7
|
+
type: 'modify',
|
8
|
+
path: `${join(`${folders.src}`, 'index.ts')}`,
|
9
|
+
pattern: /(};)/g,
|
10
|
+
data: {
|
11
|
+
componentName,
|
12
|
+
prefix: componentNamePrefix,
|
13
|
+
},
|
14
|
+
template:
|
15
|
+
` {{sentenceCase prefix}}{{sentenceCase ${componentName}}},\n$1`,
|
16
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/* eslint-disable max-len */
|
2
|
+
import { join } from 'path';
|
3
|
+
import { ActionType } from 'plop';
|
4
|
+
import { folders, componentName, componentNamePrefix } from '../constants';
|
5
|
+
|
6
|
+
export const AddToComponentImports: ActionType = {
|
7
|
+
type: 'modify',
|
8
|
+
path: `${join(`${folders.src}`, 'index.ts')}`,
|
9
|
+
pattern: /(\nexport)/g,
|
10
|
+
data: {
|
11
|
+
componentName,
|
12
|
+
prefix: componentNamePrefix,
|
13
|
+
},
|
14
|
+
template:
|
15
|
+
`import {{sentenceCase prefix}}{{sentenceCase ${componentName}}} from './components/{{${componentName}}}';\n$1`,
|
16
|
+
};
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { join } from 'path';
|
2
|
+
import CONSTANTS from '../../../src/utils/tag-name/constants';
|
3
|
+
|
4
|
+
export enum PROMPT_TYPE {
|
5
|
+
INPUT = 'input',
|
6
|
+
}
|
7
|
+
|
8
|
+
export enum GENERATOR_NAME {
|
9
|
+
COMPONENT_GENERATOR = 'component'
|
10
|
+
}
|
11
|
+
|
12
|
+
export enum ACTION {
|
13
|
+
ADD = 'add',
|
14
|
+
}
|
15
|
+
|
16
|
+
export enum TYPE {
|
17
|
+
COMPONENT = 'component',
|
18
|
+
}
|
19
|
+
|
20
|
+
export const componentName: string = 'componentName';
|
21
|
+
export const componentNamePrefix: string = CONSTANTS.NAMESPACE.PREFIX;
|
22
|
+
export const componentNameSeparator: string = CONSTANTS.NAMESPACE.SEPARATOR;
|
23
|
+
|
24
|
+
export const root: string = process.cwd();
|
25
|
+
export const plop: string = `${join(root, 'config', 'plop')}`;
|
26
|
+
|
27
|
+
export const folders = {
|
28
|
+
src: `${join(root, 'src')}`,
|
29
|
+
components: `${join(root, 'src', 'components')}`,
|
30
|
+
templates: `${join(plop, 'templates')}`,
|
31
|
+
};
|
@@ -0,0 +1,25 @@
|
|
1
|
+
/* eslint-disable quotes */
|
2
|
+
import { PlopGeneratorConfig } from 'plop';
|
3
|
+
|
4
|
+
import { GENERATOR_NAME, componentName, PROMPT_TYPE } from '../../constants';
|
5
|
+
import { AddComponent } from '../../actions/AddComponent';
|
6
|
+
import { prompt } from '../../prompts';
|
7
|
+
import { AddToComponentImports } from '../../actions/AddToComponentImports';
|
8
|
+
import { AddToComponentExports } from '../../actions/AddToComponentExports';
|
9
|
+
|
10
|
+
const componentNameMessage = `Choose the name of the component.
|
11
|
+
Requirements
|
12
|
+
- lowercase
|
13
|
+
- without prefix e.g. "button"
|
14
|
+
- no additional "hyphens", like "theme-provider"
|
15
|
+
`;
|
16
|
+
const generator: Partial<PlopGeneratorConfig> = {
|
17
|
+
description: 'Scaffold a new package',
|
18
|
+
prompts: [prompt(`${componentName}`, componentNameMessage, PROMPT_TYPE.INPUT)],
|
19
|
+
actions: [AddComponent, AddToComponentImports, AddToComponentExports],
|
20
|
+
};
|
21
|
+
|
22
|
+
export const ComponentGenerator = {
|
23
|
+
name: GENERATOR_NAME.COMPONENT_GENERATOR,
|
24
|
+
generator,
|
25
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import {{sentenceCase componentName}} from './{{componentName}}.component';
|
2
|
+
import { TAG_NAME } from './{{componentName}}.constants';
|
3
|
+
|
4
|
+
{{sentenceCase componentName}}.register(TAG_NAME);
|
5
|
+
|
6
|
+
declare global {
|
7
|
+
interface HTMLElementTagNameMap {
|
8
|
+
['{{prefix}}{{separator}}{{componentName}}']: {{sentenceCase componentName}}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
export default {{sentenceCase componentName}};
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { html } from 'lit';
|
2
|
+
import { property } from 'lit/decorators.js';
|
3
|
+
import styles from './{{componentName}}.styles';
|
4
|
+
import { Component } from '../../models';
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @slot - This is a default/unnamed slot
|
8
|
+
*
|
9
|
+
* @summary This is MyElement
|
10
|
+
*
|
11
|
+
* @tag {{prefix}}-{{componentName}}
|
12
|
+
* @tagname {{prefix}}-{{componentName}}
|
13
|
+
*/
|
14
|
+
class {{sentenceCase prefix}}{{sentenceCase componentName}} extends Component {
|
15
|
+
public override render() {
|
16
|
+
return html`<p>This is a dummy component!</p><slot></slot>`;
|
17
|
+
}
|
18
|
+
|
19
|
+
public static override styles = styles;
|
20
|
+
}
|
21
|
+
|
22
|
+
export default {{sentenceCase componentName}};
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import { test } from '../../../config/playwright/setup';
|
2
|
+
import steps from '../../../config/playwright/setup/steps/accessibility';
|
3
|
+
|
4
|
+
test.beforeEach(async ({ componentsPage }) => {
|
5
|
+
await componentsPage.mount({
|
6
|
+
html: `
|
7
|
+
<{{prefix}}{{separator}}{{componentName}} />
|
8
|
+
`,
|
9
|
+
});
|
10
|
+
});
|
11
|
+
|
12
|
+
test('{{prefix}}{{separator}}{{componentName}}', async ({ componentsPage }) => {
|
13
|
+
const {{componentName}} = componentsPage.page.locator('{{prefix}}-{{componentName}}');
|
14
|
+
|
15
|
+
// initial check for the {{componentName}} be visible on the screen:
|
16
|
+
await {{componentName}}.waitFor();
|
17
|
+
|
18
|
+
/**
|
19
|
+
* ACCESSIBILITY
|
20
|
+
*/
|
21
|
+
await test.step('accessibility', async () => {
|
22
|
+
await steps.automaticA11yCheckStep(componentsPage);
|
23
|
+
});
|
24
|
+
|
25
|
+
/**
|
26
|
+
* VISUAL REGRESSION
|
27
|
+
*/
|
28
|
+
await test.step('visual-regression', async () => {
|
29
|
+
await test.step('matches screenshot of element', async () => {
|
30
|
+
await componentsPage.visualRegression.takeScreenshot('{{prefix}}{{separator}}{{componentName}}', { element: {{componentName}} });
|
31
|
+
});
|
32
|
+
});
|
33
|
+
|
34
|
+
/**
|
35
|
+
* ATTRIBUTES
|
36
|
+
*/
|
37
|
+
await test.step('attributes', async () => {
|
38
|
+
await test.step('attribute X should be present on component by default', async () => {
|
39
|
+
// TODO: add test here
|
40
|
+
});
|
41
|
+
});
|
42
|
+
|
43
|
+
/**
|
44
|
+
* INTERACTIONS
|
45
|
+
*/
|
46
|
+
await test.step('interactions', async () => {
|
47
|
+
await test.step('mouse/pointer', async () => {
|
48
|
+
await test.step('component should fire callback x when clicking on it', async () => {
|
49
|
+
// TODO: add test here
|
50
|
+
});
|
51
|
+
});
|
52
|
+
|
53
|
+
await test.step('focus', async () => {
|
54
|
+
await test.step('component should be focusable with tab', async () => {
|
55
|
+
// TODO: add test here
|
56
|
+
});
|
57
|
+
|
58
|
+
// add additional tests here, like tabbing through several parts of the component
|
59
|
+
});
|
60
|
+
|
61
|
+
await test.step('keyboard', async () => {
|
62
|
+
await test.step('component should fire callback x when pressing y', async () => {
|
63
|
+
// TODO: add test here
|
64
|
+
});
|
65
|
+
});
|
66
|
+
});
|
67
|
+
});
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import type { Meta, StoryObj, Args } from '@storybook/web-components';
|
2
|
+
import '.';
|
3
|
+
import fixtures from './{{componentName}}.fixtures';
|
4
|
+
|
5
|
+
const render = (args: Args) => fixtures.base(args);
|
6
|
+
|
7
|
+
const meta: Meta = {
|
8
|
+
tags: ['autodocs'],
|
9
|
+
component: '{{prefix}}{{separator}}{{componentName}}',
|
10
|
+
render,
|
11
|
+
argTypes: {},
|
12
|
+
};
|
13
|
+
|
14
|
+
export default meta;
|
15
|
+
|
16
|
+
export const Primary: StoryObj = {
|
17
|
+
args: {},
|
18
|
+
};
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { create } from '@storybook/theming/create';
|
2
|
+
|
3
|
+
export default create({
|
4
|
+
base: 'dark',
|
5
|
+
|
6
|
+
// Typography for Manager
|
7
|
+
// (can't use Inter here without a lot of workarounds):
|
8
|
+
fontBase: 'Helvetica Neue, sans-serif',
|
9
|
+
fontCode: 'monospace',
|
10
|
+
|
11
|
+
brandTitle: 'Momentum Design',
|
12
|
+
brandUrl: 'https://momentum.design',
|
13
|
+
brandImage: '/momentum-logo.png',
|
14
|
+
brandTarget: '_self',
|
15
|
+
|
16
|
+
colorPrimary: '#64b4fa',
|
17
|
+
colorSecondary: '#64b4fa',
|
18
|
+
|
19
|
+
// UI
|
20
|
+
appBg: '#1a1a1a',
|
21
|
+
appContentBg: '#262626',
|
22
|
+
appBorderColor: '#ffffff4d',
|
23
|
+
|
24
|
+
// Text colors
|
25
|
+
textColor: '#FFFFF2',
|
26
|
+
textInverseColor: '#000002',
|
27
|
+
|
28
|
+
// Toolbar default and active colors
|
29
|
+
barTextColor: '#FFFFF2',
|
30
|
+
barSelectedColor: '#64b4fa',
|
31
|
+
barBg: '#262626',
|
32
|
+
|
33
|
+
// Form colors
|
34
|
+
inputBg: '#FFFFFF',
|
35
|
+
inputBorder: '#ffffffb3',
|
36
|
+
inputTextColor: '#000002',
|
37
|
+
|
38
|
+
// Buttons:
|
39
|
+
buttonBg: '#FFFFFF',
|
40
|
+
buttonBorder: '#ffffffb3',
|
41
|
+
});
|
@@ -0,0 +1,21 @@
|
|
1
|
+
const config = {
|
2
|
+
stories: ['../../src/**/*.stories.@(js|jsx|ts|tsx)', '../../src/stories/**/*.mdx'],
|
3
|
+
addons: [
|
4
|
+
'@storybook/addon-controls',
|
5
|
+
'@storybook/addon-links',
|
6
|
+
'@storybook/addon-essentials',
|
7
|
+
'@storybook/addon-a11y',
|
8
|
+
],
|
9
|
+
framework: {
|
10
|
+
name: '@storybook/web-components-vite',
|
11
|
+
options: {},
|
12
|
+
},
|
13
|
+
core: {
|
14
|
+
disableTelemetry: true, // 👈 Disables telemetry
|
15
|
+
},
|
16
|
+
docs: {
|
17
|
+
autodocs: 'tag',
|
18
|
+
},
|
19
|
+
staticDirs: ['./public'],
|
20
|
+
};
|
21
|
+
export default config;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import { addons } from '@storybook/manager-api';
|
2
|
+
import momentum from './MomentumStorybookTheme';
|
3
|
+
|
4
|
+
addons.setConfig({
|
5
|
+
bottomPanelHeight: '500',
|
6
|
+
panelPosition: 'bottom',
|
7
|
+
sidebar: {
|
8
|
+
showRoots: true,
|
9
|
+
},
|
10
|
+
toolbar: {
|
11
|
+
zoom: { hidden: false },
|
12
|
+
eject: { hidden: false },
|
13
|
+
copy: { hidden: false },
|
14
|
+
fullscreen: { hidden: false },
|
15
|
+
},
|
16
|
+
theme: momentum,
|
17
|
+
});
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import '../../src/components/themeprovider';
|
2
|
+
import '@momentum-design/tokens/dist/css/core/complete.css';
|
3
|
+
import '@momentum-design/tokens/dist/css/theme/webex/dark-stable.css';
|
4
|
+
import '@momentum-design/tokens/dist/css/theme/webex/light-stable.css';
|
5
|
+
import '@momentum-design/fonts/dist/css/fonts.css';
|
6
|
+
|
7
|
+
import { setCustomElementsManifest } from '@storybook/web-components';
|
8
|
+
import customElements from '../../data/custom-elements.json';
|
9
|
+
import { themes } from './themes';
|
10
|
+
import { withThemeProvider } from './provider/themeProvider';
|
11
|
+
import { withIconProvider } from './provider/iconProvider';
|
12
|
+
|
13
|
+
setCustomElementsManifest(customElements);
|
14
|
+
|
15
|
+
const preview = {
|
16
|
+
parameters: {
|
17
|
+
a11y: {
|
18
|
+
options: {
|
19
|
+
runOnly: {
|
20
|
+
type: 'tag',
|
21
|
+
values: ['best-practice', 'wcag2a', 'wcag2aa', 'wcag21aa', 'wcag22aa'],
|
22
|
+
},
|
23
|
+
},
|
24
|
+
},
|
25
|
+
backgrounds: {
|
26
|
+
disable: true,
|
27
|
+
grid: {
|
28
|
+
disable: true,
|
29
|
+
},
|
30
|
+
},
|
31
|
+
actions: { argTypesRegex: '^on[A-Z].*' },
|
32
|
+
controls: {
|
33
|
+
controls: { expanded: true },
|
34
|
+
matchers: {
|
35
|
+
color: /(background|color)$/i,
|
36
|
+
date: /Date$/,
|
37
|
+
},
|
38
|
+
},
|
39
|
+
options: {
|
40
|
+
storySort: {
|
41
|
+
order: ['System', 'Components'],
|
42
|
+
},
|
43
|
+
},
|
44
|
+
},
|
45
|
+
decorators: [withThemeProvider, withIconProvider],
|
46
|
+
globalTypes: {
|
47
|
+
theme: {
|
48
|
+
description: 'Global theme for components',
|
49
|
+
defaultValue: themes[0].displayName,
|
50
|
+
toolbar: {
|
51
|
+
// The label to show for this toolbar item
|
52
|
+
title: 'Theme',
|
53
|
+
icon: 'globe',
|
54
|
+
// Array of plain string values or MenuItem shape (see below)
|
55
|
+
items: themes.map((theme) => theme.displayName),
|
56
|
+
// Change title based on selected value
|
57
|
+
dynamicTitle: true,
|
58
|
+
},
|
59
|
+
},
|
60
|
+
},
|
61
|
+
};
|
62
|
+
|
63
|
+
export default preview;
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { html } from 'lit';
|
2
|
+
import { themes } from '../themes';
|
3
|
+
import '../themes/themes.css';
|
4
|
+
|
5
|
+
const clearStyles = (element) => {
|
6
|
+
// eslint-disable-next-line no-restricted-syntax
|
7
|
+
for (const theme of themes) {
|
8
|
+
element.classList.remove(theme.className);
|
9
|
+
}
|
10
|
+
};
|
11
|
+
|
12
|
+
const applyStyle = (element, className) => {
|
13
|
+
element.classList.add(className);
|
14
|
+
};
|
15
|
+
|
16
|
+
export const withThemeProvider = (story, context) => {
|
17
|
+
const currentTheme = context.globals.theme;
|
18
|
+
const themeObject = themes.find((theme) => theme.displayName === currentTheme);
|
19
|
+
|
20
|
+
const body = document.querySelector('body.sb-show-main');
|
21
|
+
clearStyles(body);
|
22
|
+
applyStyle(body, themeObject.className);
|
23
|
+
|
24
|
+
return html`<mdc-themeprovider
|
25
|
+
id="theme-provider"
|
26
|
+
theme="${themeObject.name}"
|
27
|
+
themes="mds-theme-stable-darkWebex mds-theme-stable-lightWebex"
|
28
|
+
>
|
29
|
+
${story()}
|
30
|
+
</mdc-themeprovider>`;
|
31
|
+
};
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,14 @@
|
|
1
|
+
export const themes = [
|
2
|
+
{
|
3
|
+
name: 'mds-theme-stable-darkWebex',
|
4
|
+
displayName: 'darkWebex',
|
5
|
+
backgroundColor: '#000000',
|
6
|
+
className: 'dark',
|
7
|
+
},
|
8
|
+
{
|
9
|
+
name: 'mds-theme-stable-lightWebex',
|
10
|
+
displayName: 'lightWebex',
|
11
|
+
backgroundColor: '#ffffff',
|
12
|
+
className: 'light',
|
13
|
+
},
|
14
|
+
];
|
@@ -0,0 +1,15 @@
|
|
1
|
+
.dark {
|
2
|
+
background-color: #000000;
|
3
|
+
height: 100vh;
|
4
|
+
background-image: url('/background-graphic.png');
|
5
|
+
background-repeat: no-repeat;
|
6
|
+
background-position: top right;
|
7
|
+
}
|
8
|
+
|
9
|
+
.light {
|
10
|
+
background-color: #ffffff;
|
11
|
+
height: 100vh;
|
12
|
+
background-image: url('/background-graphic.png');
|
13
|
+
background-repeat: no-repeat;
|
14
|
+
background-position: top right;
|
15
|
+
}
|