@momentum-design/components 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|