@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.
Files changed (235) hide show
  1. package/.eslintrc.js +16 -0
  2. package/CONTRIBUTING.md +5 -0
  3. package/README.md +39 -0
  4. package/SCRIPTS.md +15 -0
  5. package/TESTING.md +38 -0
  6. package/config/api-extractor.json +33 -0
  7. package/config/custom-elements-manifest.config.js +28 -0
  8. package/config/esbuild/configs/browser.js +21 -0
  9. package/config/esbuild/configs/e2e.js +10 -0
  10. package/config/esbuild/esbuild-e2e.config.js +22 -0
  11. package/config/esbuild/esbuild.config.js +9 -0
  12. package/config/playwright/playwright.config.ts +107 -0
  13. package/config/playwright/public/index.css +43 -0
  14. package/config/playwright/public/index.html +26 -0
  15. package/config/playwright/setup/Components.page.ts +163 -0
  16. package/config/playwright/setup/constants.ts +27 -0
  17. package/config/playwright/setup/index.ts +42 -0
  18. package/config/playwright/setup/steps/accessibility.ts +9 -0
  19. package/config/playwright/setup/types.ts +5 -0
  20. package/config/playwright/setup/utils/accessibility.ts +70 -0
  21. package/config/playwright/setup/utils/visual-regression.ts +35 -0
  22. package/config/plop/actions/AddComponent.ts +21 -0
  23. package/config/plop/actions/AddToComponentExports.ts +16 -0
  24. package/config/plop/actions/AddToComponentImports.ts +16 -0
  25. package/config/plop/constants/index.ts +31 -0
  26. package/config/plop/esbuild.config.plop.js +4 -0
  27. package/config/plop/generators/component/index.ts +25 -0
  28. package/config/plop/plopfile.ts +6 -0
  29. package/config/plop/prompts/index.ts +8 -0
  30. package/config/plop/templates/add/component/index.ts.hbs +12 -0
  31. package/config/plop/templates/add/component/{{componentName}}.component.ts.hbs +22 -0
  32. package/config/plop/templates/add/component/{{componentName}}.constants.ts.hbs +5 -0
  33. package/config/plop/templates/add/component/{{componentName}}.e2e-test.ts.hbs +67 -0
  34. package/config/plop/templates/add/component/{{componentName}}.fixtures.ts.hbs +13 -0
  35. package/config/plop/templates/add/component/{{componentName}}.stories.ts.hbs +18 -0
  36. package/config/plop/templates/add/component/{{componentName}}.styles.ts.hbs +8 -0
  37. package/config/plop/tsconfig.plop.json +11 -0
  38. package/config/storybook/MomentumStorybookTheme.js +41 -0
  39. package/config/storybook/main.js +21 -0
  40. package/config/storybook/manager.js +17 -0
  41. package/config/storybook/preview.js +63 -0
  42. package/config/storybook/provider/iconProvider.js +8 -0
  43. package/config/storybook/provider/themeProvider.js +31 -0
  44. package/config/storybook/public/background-graphic.png +0 -0
  45. package/config/storybook/public/fonts/Inter.var.woff2 +0 -0
  46. package/config/storybook/public/momentum-logo.png +0 -0
  47. package/config/storybook/themes/index.js +14 -0
  48. package/config/storybook/themes/themes.css +15 -0
  49. package/data/custom-elements.json +677 -0
  50. package/dist/browser/index.js +366 -0
  51. package/dist/browser/index.js.map +7 -0
  52. package/dist/components/avatar/avatar.component.d.ts +28 -0
  53. package/dist/components/avatar/avatar.component.js +79 -0
  54. package/dist/components/avatar/avatar.constants.d.ts +7 -0
  55. package/dist/components/avatar/avatar.constants.js +14 -0
  56. package/dist/components/avatar/avatar.styles.d.ts +2 -0
  57. package/dist/components/avatar/avatar.styles.js +20 -0
  58. package/dist/components/avatar/avatar.types.d.ts +1 -0
  59. package/dist/components/avatar/avatar.types.js +2 -0
  60. package/dist/components/avatar/index.d.ts +7 -0
  61. package/dist/components/avatar/index.js +7 -0
  62. package/dist/components/badge/badge.component.d.ts +51 -0
  63. package/dist/components/badge/badge.component.js +114 -0
  64. package/dist/components/badge/badge.constants.d.ts +8 -0
  65. package/dist/components/badge/badge.constants.js +15 -0
  66. package/dist/components/badge/badge.styles.d.ts +2 -0
  67. package/dist/components/badge/badge.styles.js +26 -0
  68. package/dist/components/badge/badge.types.d.ts +1 -0
  69. package/dist/components/badge/badge.types.js +2 -0
  70. package/dist/components/badge/index.d.ts +7 -0
  71. package/dist/components/badge/index.js +7 -0
  72. package/dist/components/icon/icon.component.d.ts +63 -0
  73. package/dist/components/icon/icon.component.js +158 -0
  74. package/dist/components/icon/icon.constants.d.ts +6 -0
  75. package/dist/components/icon/icon.constants.js +12 -0
  76. package/dist/components/icon/icon.styles.d.ts +2 -0
  77. package/dist/components/icon/icon.styles.js +15 -0
  78. package/dist/components/icon/icon.utils.d.ts +2 -0
  79. package/dist/components/icon/icon.utils.js +13 -0
  80. package/dist/components/icon/index.d.ts +7 -0
  81. package/dist/components/icon/index.js +7 -0
  82. package/dist/components/iconprovider/iconprovider.component.d.ts +34 -0
  83. package/dist/components/iconprovider/iconprovider.component.js +71 -0
  84. package/dist/components/iconprovider/iconprovider.constants.d.ts +7 -0
  85. package/dist/components/iconprovider/iconprovider.constants.js +14 -0
  86. package/dist/components/iconprovider/iconprovider.context.d.ts +9 -0
  87. package/dist/components/iconprovider/iconprovider.context.js +9 -0
  88. package/dist/components/iconprovider/index.d.ts +7 -0
  89. package/dist/components/iconprovider/index.js +7 -0
  90. package/dist/components/text/fonts.styles.d.ts +1 -0
  91. package/dist/components/text/fonts.styles.js +100 -0
  92. package/dist/components/text/index.d.ts +7 -0
  93. package/dist/components/text/index.js +7 -0
  94. package/dist/components/text/text.component.d.ts +29 -0
  95. package/dist/components/text/text.component.js +41 -0
  96. package/dist/components/text/text.constants.d.ts +9 -0
  97. package/dist/components/text/text.constants.js +28 -0
  98. package/dist/components/text/text.styles.d.ts +2 -0
  99. package/dist/components/text/text.styles.js +17 -0
  100. package/dist/components/text/text.types.d.ts +1 -0
  101. package/dist/components/text/text.types.js +2 -0
  102. package/dist/components/text/text.utils.d.ts +20 -0
  103. package/dist/components/text/text.utils.js +50 -0
  104. package/dist/components/themeprovider/index.d.ts +7 -0
  105. package/dist/components/themeprovider/index.js +7 -0
  106. package/dist/components/themeprovider/themeprovider.component.d.ts +48 -0
  107. package/dist/components/themeprovider/themeprovider.component.js +86 -0
  108. package/dist/components/themeprovider/themeprovider.constants.d.ts +10 -0
  109. package/dist/components/themeprovider/themeprovider.constants.js +31 -0
  110. package/dist/components/themeprovider/themeprovider.context.d.ts +9 -0
  111. package/dist/components/themeprovider/themeprovider.context.js +13 -0
  112. package/dist/components/themeprovider/themeprovider.styles.d.ts +2 -0
  113. package/dist/components/themeprovider/themeprovider.styles.js +13 -0
  114. package/dist/components/themeprovider/themeprovider.types.d.ts +5 -0
  115. package/dist/components/themeprovider/themeprovider.types.js +2 -0
  116. package/dist/components/themeprovider/themeprovider.utils.d.ts +9 -0
  117. package/dist/components/themeprovider/themeprovider.utils.js +10 -0
  118. package/dist/index.d.ts +8 -0
  119. package/dist/index.js +19 -0
  120. package/dist/models/component/component.component.d.ts +38 -0
  121. package/dist/models/component/component.component.js +45 -0
  122. package/dist/models/component/component.types.d.ts +15 -0
  123. package/dist/models/component/component.types.js +2 -0
  124. package/dist/models/component/index.d.ts +3 -0
  125. package/dist/models/component/index.js +5 -0
  126. package/dist/models/index.d.ts +4 -0
  127. package/dist/models/index.js +8 -0
  128. package/dist/models/provider/index.d.ts +2 -0
  129. package/dist/models/provider/index.js +5 -0
  130. package/dist/models/provider/provider.component.d.ts +70 -0
  131. package/dist/models/provider/provider.component.js +56 -0
  132. package/dist/models/provider/provider.styles.d.ts +2 -0
  133. package/dist/models/provider/provider.styles.js +14 -0
  134. package/dist/utils/provider/index.d.ts +13 -0
  135. package/dist/utils/provider/index.js +14 -0
  136. package/dist/utils/styles/index.d.ts +2 -0
  137. package/dist/utils/styles/index.js +14 -0
  138. package/dist/utils/tag-name/constants.d.ts +7 -0
  139. package/dist/utils/tag-name/constants.js +10 -0
  140. package/dist/utils/tag-name/index.d.ts +4 -0
  141. package/dist/utils/tag-name/index.js +10 -0
  142. package/dist/utils/types.d.ts +1 -0
  143. package/dist/utils/types.js +2 -0
  144. package/jest.config.js +3 -0
  145. package/package.json +78 -0
  146. package/scripts/copyFonts.js +31 -0
  147. package/scripts/copyIcons.js +31 -0
  148. package/scripts/copyTokens.js +24 -0
  149. package/src/components/avatar/__screenshots__/mdc-avatar.png +0 -0
  150. package/src/components/avatar/avatar.component.ts +74 -0
  151. package/src/components/avatar/avatar.constants.ts +12 -0
  152. package/src/components/avatar/avatar.e2e-test.ts +70 -0
  153. package/src/components/avatar/avatar.stories.ts +25 -0
  154. package/src/components/avatar/avatar.styles.ts +20 -0
  155. package/src/components/avatar/avatar.types.ts +1 -0
  156. package/src/components/avatar/index.ts +12 -0
  157. package/src/components/badge/__screenshots__/mdc-badge.png +0 -0
  158. package/src/components/badge/badge.component.ts +121 -0
  159. package/src/components/badge/badge.constants.ts +13 -0
  160. package/src/components/badge/badge.e2e-test.ts +68 -0
  161. package/src/components/badge/badge.stories.ts +33 -0
  162. package/src/components/badge/badge.styles.ts +26 -0
  163. package/src/components/badge/badge.types.ts +1 -0
  164. package/src/components/badge/index.ts +12 -0
  165. package/src/components/icon/__screenshots__/mdc-icon-default.png +0 -0
  166. package/src/components/icon/__screenshots__/mdc-icon-scale.png +0 -0
  167. package/src/components/icon/icon.component.ts +155 -0
  168. package/src/components/icon/icon.constants.ts +10 -0
  169. package/src/components/icon/icon.e2e-test.ts +101 -0
  170. package/src/components/icon/icon.stories.ts +34 -0
  171. package/src/components/icon/icon.styles.ts +15 -0
  172. package/src/components/icon/icon.utils.ts +13 -0
  173. package/src/components/icon/index.ts +12 -0
  174. package/src/components/iconprovider/__screenshots__/mdc-iconprovider.png +0 -0
  175. package/src/components/iconprovider/iconprovider.component.ts +76 -0
  176. package/src/components/iconprovider/iconprovider.constants.ts +12 -0
  177. package/src/components/iconprovider/iconprovider.context.ts +16 -0
  178. package/src/components/iconprovider/iconprovider.e2e-test.ts +65 -0
  179. package/src/components/iconprovider/iconprovider.stories.ts +27 -0
  180. package/src/components/iconprovider/iconprovider.stories.utils.ts +27 -0
  181. package/src/components/iconprovider/index.ts +12 -0
  182. package/src/components/text/__screenshots__/mdc-text-body-large.png +0 -0
  183. package/src/components/text/__screenshots__/mdc-text-body-regular.png +0 -0
  184. package/src/components/text/__screenshots__/mdc-text-body-small.png +0 -0
  185. package/src/components/text/__screenshots__/mdc-text-heading-1.png +0 -0
  186. package/src/components/text/__screenshots__/mdc-text-heading-2.png +0 -0
  187. package/src/components/text/__screenshots__/mdc-text-heading-3.png +0 -0
  188. package/src/components/text/__screenshots__/mdc-text-heading-4.png +0 -0
  189. package/src/components/text/__screenshots__/mdc-text-heading-5.png +0 -0
  190. package/src/components/text/__screenshots__/mdc-text-heading-6.png +0 -0
  191. package/src/components/text/__screenshots__/mdc-text-heading-7.png +0 -0
  192. package/src/components/text/__screenshots__/mdc-text-image-title.png +0 -0
  193. package/src/components/text/__screenshots__/mdc-text-label.png +0 -0
  194. package/src/components/text/fonts.styles.ts +99 -0
  195. package/src/components/text/index.ts +12 -0
  196. package/src/components/text/text.component.ts +51 -0
  197. package/src/components/text/text.constants.ts +27 -0
  198. package/src/components/text/text.e2e-test.ts +76 -0
  199. package/src/components/text/text.stories.ts +29 -0
  200. package/src/components/text/text.styles.ts +17 -0
  201. package/src/components/text/text.types.ts +13 -0
  202. package/src/components/text/text.utils.ts +51 -0
  203. package/src/components/themeprovider/__screenshots__/mdc-themeprovider-darkWebex.png +0 -0
  204. package/src/components/themeprovider/__screenshots__/mdc-themeprovider-lightWebex.png +0 -0
  205. package/src/components/themeprovider/index.ts +12 -0
  206. package/src/components/themeprovider/themeprovider.component.ts +91 -0
  207. package/src/components/themeprovider/themeprovider.constants.ts +32 -0
  208. package/src/components/themeprovider/themeprovider.context.ts +18 -0
  209. package/src/components/themeprovider/themeprovider.e2e-test.ts +89 -0
  210. package/src/components/themeprovider/themeprovider.stories.styles.css +22 -0
  211. package/src/components/themeprovider/themeprovider.stories.ts +38 -0
  212. package/src/components/themeprovider/themeprovider.stories.utils.ts +23 -0
  213. package/src/components/themeprovider/themeprovider.styles.ts +13 -0
  214. package/src/components/themeprovider/themeprovider.types.ts +7 -0
  215. package/src/components/themeprovider/themeprovider.utils.ts +16 -0
  216. package/src/index.ts +22 -0
  217. package/src/models/component/component.component.ts +46 -0
  218. package/src/models/component/component.types.ts +16 -0
  219. package/src/models/component/index.ts +7 -0
  220. package/src/models/index.ts +11 -0
  221. package/src/models/provider/index.ts +3 -0
  222. package/src/models/provider/provider.component.ts +87 -0
  223. package/src/models/provider/provider.styles.ts +14 -0
  224. package/src/stories/colors.mdx +32 -0
  225. package/src/stories/icons.mdx +13 -0
  226. package/src/stories/typography.mdx +20 -0
  227. package/src/utils/mixins/DisabledMixin.ts +19 -0
  228. package/src/utils/mixins/TabIndexMixin.ts +19 -0
  229. package/src/utils/provider/index.ts +21 -0
  230. package/src/utils/styles/index.ts +13 -0
  231. package/src/utils/tag-name/constants.ts +10 -0
  232. package/src/utils/tag-name/index.ts +15 -0
  233. package/src/utils/types.ts +1 -0
  234. package/tsconfig.json +45 -0
  235. package/tsconfig.module.json +47 -0
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@momentum-design/components",
3
+ "packageManager": "yarn@3.2.4",
4
+ "engines": {
5
+ "node": ">=20.0.0",
6
+ "npm": ">=8.0.0",
7
+ "yarn": ">=3.0.0"
8
+ },
9
+ "main": "./dist/module/index.js",
10
+ "types": "./dist/types/index.d.ts",
11
+ "exports": {
12
+ ".": "./dist/module/",
13
+ "./module": "./dist/module",
14
+ "./browser": "./dist/browser"
15
+ },
16
+ "scripts": {
17
+ "analyze": "yarn analyze:prebuild && yarn analyze:postbuild",
18
+ "analyze:postbuild": "echo \"script 'analyze:postbuild' has not been implemented\"",
19
+ "analyze:prebuild": "echo \"script 'analyze:prebuild' has not been implemented\"",
20
+ "dev": "concurrently --names 'manifest,storybook' -c 'blue.bold,magenta.bold' 'yarn:dev:generate-manifest' 'yarn:dev:storybook'",
21
+ "dev:generate-manifest": "custom-elements-manifest analyze --config config/custom-elements-manifest.config.js",
22
+ "dev:storybook:setup": "concurrently --names 'copy:icons,copy:fonts' -c 'cyan.bold,blue.bold' 'yarn copy:icons storybook' 'yarn copy:fonts storybook'",
23
+ "dev:storybook": "yarn dev:storybook:setup && storybook dev -p 6006 -c config/storybook",
24
+ "build:browser:e2e": "node config/esbuild/esbuild-e2e.config.js",
25
+ "build:browser": "node config/esbuild/esbuild.config.js",
26
+ "build:module": "tsc --project \"./tsconfig.module.json\"",
27
+ "build": "yarn build:module && yarn build:browser",
28
+ "clean": "yarn clean:dist",
29
+ "clean:dist": "rimraf ./dist",
30
+ "copy:tokens": "node scripts/copyTokens.js",
31
+ "copy:icons": "node scripts/copyIcons.js",
32
+ "copy:fonts": "node scripts/copyFonts.js",
33
+ "docs": "echo \"script 'docs' has not been implemented\"",
34
+ "publish": "yarn publish:npmjs",
35
+ "publish:npmjs": "yarn npm publish --access=public",
36
+ "test": "yarn test:prebuild && yarn test:postbuild",
37
+ "test:postbuild": "yarn test:e2e",
38
+ "test:prebuild": "echo \"script 'test:prebuild' has not been implemented\"",
39
+ "test:e2e:report": "yarn playwright show-report",
40
+ "test:e2e:setup": "concurrently --names 'copy:tokens,copy:icons,copy:fonts' -c 'magenta.bold,cyan.bold,blue.bold' 'yarn copy:tokens' 'yarn copy:icons playwright' 'yarn copy:fonts playwright' && yarn build:browser:e2e",
41
+ "test:e2e": "playwright test --config './config/playwright/playwright.config.ts'",
42
+ "test:e2e:ui": "yarn test:e2e --ui",
43
+ "build-storybook": "storybook build -c config/storybook",
44
+ "clean:plop": "rimraf ./config/plop/dist",
45
+ "build:plop": "yarn clean:plop && node ./config/plop/esbuild.config.plop.js",
46
+ "generate:component": "yarn build:plop && plop --plopfile config/plop/dist/plopfile.mjs"
47
+ },
48
+ "dependencies": {
49
+ "@lit-labs/context": "^0.5.1",
50
+ "@momentum-design/icons": "^0.0.0",
51
+ "@momentum-design/tokens": "^0.0.0",
52
+ "lit": "^3.1.4"
53
+ },
54
+ "devDependencies": {
55
+ "@axe-core/playwright": "^4.9.1",
56
+ "@custom-elements-manifest/analyzer": "^0.10.3",
57
+ "@playwright/test": "^1.45.3",
58
+ "@storybook/addon-a11y": "^8.2.5",
59
+ "@storybook/addon-controls": "^8.2.5",
60
+ "@storybook/addon-essentials": "^8.2.5",
61
+ "@storybook/addon-links": "^8.2.5",
62
+ "@storybook/blocks": "^8.2.5",
63
+ "@storybook/manager-api": "^8.2.5",
64
+ "@storybook/theming": "^8.2.5",
65
+ "@storybook/web-components": "^8.2.5",
66
+ "@storybook/web-components-vite": "^8.2.5",
67
+ "chalk": "^4.1.2",
68
+ "concurrently": "^8.2.2",
69
+ "esbuild": "^0.23.0",
70
+ "eslint-plugin-lit": "^1.14.0",
71
+ "fs-extra": "^11.2.0",
72
+ "plop": "^4.0.1",
73
+ "rimraf": "^6.0.1",
74
+ "storybook": "^8.2.5",
75
+ "typescript": "^4.8.4"
76
+ },
77
+ "version": "0.0.1"
78
+ }
@@ -0,0 +1,31 @@
1
+
2
+ const fse = require('fs-extra');
3
+ const path = require('path');
4
+ const chalk = require('chalk');
5
+
6
+ const fontsFolder = path.dirname(require.resolve('@momentum-design/fonts/dist/inter/Inter.var.woff2'));
7
+ const root = process.cwd();
8
+ const playwrightPublicDist = path.join(root, 'config', 'playwright', 'public', 'dist', 'fonts');
9
+ const storybookPublicDist = path.join(root, 'config', 'storybook', 'public', 'fonts');
10
+
11
+ const copyFolderToDest = (srcDir, destDir) => {
12
+ try {
13
+ fse.copySync(srcDir, destDir, { overwrite: true })
14
+ } catch (err) {
15
+ console.error(err)
16
+ }
17
+ }
18
+
19
+ if (process.argv[2] === 'playwright') {
20
+ copyFolderToDest(fontsFolder, playwrightPublicDist);
21
+ console.log(chalk.gray('Fonts have been copied successfully to Playwright public!'));
22
+ return;
23
+ }
24
+
25
+ if (process.argv[2] === 'storybook') {
26
+ copyFolderToDest(fontsFolder, storybookPublicDist);
27
+ console.log(chalk.gray('Fonts have been copied successfully to Storybook public!'));
28
+ return;
29
+ }
30
+
31
+ console.log(chalk.red('No type has been provided. Use "playwright" or "storybook" as a argument!'));
@@ -0,0 +1,31 @@
1
+
2
+ const fse = require('fs-extra');
3
+ const path = require('path');
4
+ const chalk = require('chalk');
5
+
6
+ const iconsFolder = path.dirname(require.resolve('@momentum-design/icons/dist/manifest.json'));
7
+ const root = process.cwd();
8
+ const playwrightPublicDist = path.join(root, 'config', 'playwright', 'public', 'dist', 'icons');
9
+ const storybookPublicDist = path.join(root, 'config', 'storybook', 'public', 'icons');
10
+
11
+ const copyFolderToDest = (srcDir, destDir) => {
12
+ try {
13
+ fse.copySync(srcDir, destDir, { overwrite: true })
14
+ } catch (err) {
15
+ console.error(err)
16
+ }
17
+ }
18
+
19
+ if (process.argv[2] === 'playwright') {
20
+ copyFolderToDest(iconsFolder, playwrightPublicDist);
21
+ console.log(chalk.gray('Icons have been copied successfully to Playwright public!'));
22
+ return;
23
+ }
24
+
25
+ if (process.argv[2] === 'storybook') {
26
+ copyFolderToDest(iconsFolder, storybookPublicDist);
27
+ console.log(chalk.gray('Icons have been copied successfully to Storybook public!'));
28
+ return;
29
+ }
30
+
31
+ console.log(chalk.red('No type has been provided. Use "playwright" or "storybook" as a argument!'));
@@ -0,0 +1,24 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const chalk = require('chalk');
4
+
5
+ const complete = require.resolve('@momentum-design/tokens/dist/css/core/complete.css');
6
+ const dark = require.resolve('@momentum-design/tokens/dist/css/theme/webex/dark-stable.css');
7
+ const light = require.resolve('@momentum-design/tokens/dist/css/theme/webex/light-stable.css');
8
+
9
+ const root = process.cwd();
10
+ const playwrightPublicDist = path.join(root, 'config', 'playwright', 'public', 'dist');
11
+
12
+
13
+ const copyToFolder = (src, destFolder) => {
14
+ const dest = path.join(destFolder, path.basename(src));
15
+ fs.copyFile(src, dest, (err) => {
16
+ if (err) throw err;
17
+ });
18
+ }
19
+
20
+ copyToFolder(complete, playwrightPublicDist);
21
+ copyToFolder(dark, playwrightPublicDist);
22
+ copyToFolder(light, playwrightPublicDist);
23
+
24
+ console.log(chalk.gray('Tokens have been copied successfully!'));
@@ -0,0 +1,74 @@
1
+ import { html } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import { ifDefined } from 'lit/directives/if-defined.js';
4
+ import styles from './avatar.styles';
5
+ import { Component } from '../../models';
6
+ import { AvatarType } from './avatar.types';
7
+ import { DEFAULTS, LENGTH_UNIT } from './avatar.constants';
8
+
9
+ /**
10
+ * @slot - This is a default/unnamed slot
11
+ *
12
+ * @summary This is MyElement
13
+ *
14
+ * @tag mdc-avatar
15
+ * @tagname mdc-avatar
16
+ */
17
+ class Avatar extends Component {
18
+ @property({ type: String, reflect: true })
19
+ type?: AvatarType = DEFAULTS.TYPE;
20
+
21
+ @property({ type: String })
22
+ alt?: string;
23
+
24
+ @property({ type: String })
25
+ src?: string;
26
+
27
+ /**
28
+ * Scale of the avatar
29
+ */
30
+ @property({ type: Number })
31
+ scale?: number = DEFAULTS.SCALE;
32
+
33
+ /**
34
+ * Updates the size by setting the width and height
35
+ */
36
+ private updateSize() {
37
+ if (this.scale) {
38
+ const value = `${this.scale}${LENGTH_UNIT}`;
39
+ this.style.width = value;
40
+ this.style.height = value;
41
+ }
42
+ }
43
+
44
+ override updated(changedProperties: Map<string, any>) {
45
+ super.updated(changedProperties);
46
+
47
+ if (changedProperties.has('scale')) {
48
+ this.updateSize();
49
+ }
50
+ }
51
+
52
+ photoTemplate() {
53
+ return html`
54
+ <img
55
+ src="${ifDefined(this.src)}"
56
+ alt="${ifDefined(this.alt)}"
57
+ />
58
+ `;
59
+ }
60
+
61
+ public override render() {
62
+ let content;
63
+ if (this.type === 'photo') {
64
+ content = this.photoTemplate();
65
+ } else {
66
+ content = html``;
67
+ }
68
+ return html`${content}`;
69
+ }
70
+
71
+ public static override styles = styles;
72
+ }
73
+
74
+ export default Avatar;
@@ -0,0 +1,12 @@
1
+ import utils from '../../utils/tag-name';
2
+
3
+ const TAG_NAME = utils.constructTagName('avatar');
4
+
5
+ const LENGTH_UNIT = 'rem';
6
+
7
+ const DEFAULTS = {
8
+ TYPE: 'photo' as const,
9
+ SCALE: 1.5,
10
+ };
11
+
12
+ export { TAG_NAME, DEFAULTS, LENGTH_UNIT };
@@ -0,0 +1,70 @@
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
+ <mdc-avatar alt="test"/>
8
+ `,
9
+ });
10
+ });
11
+
12
+ // TODO: fix e2e test
13
+ test.fixme('mdc-avatar', async ({ componentsPage }) => {
14
+ const avatar = componentsPage.page.locator('mdc-avatar');
15
+
16
+ // initial check for the avatar be visible on the screen:
17
+ await avatar.waitFor();
18
+
19
+ /**
20
+ * ACCESSIBILITY
21
+ */
22
+ await test.step('accessibility', async () => {
23
+ await steps.automaticA11yCheckStep(componentsPage);
24
+ });
25
+
26
+ /**
27
+ * VISUAL REGRESSION
28
+ */
29
+
30
+ // TODO: fix visual regression test on CI
31
+ // await test.step('visual-regression', async () => {
32
+ // await test.step('matches screenshot of element', async () => {
33
+ // await componentsPage.visualRegression.takeScreenshot('mdc-avatar', { element: avatar });
34
+ // });
35
+ // });
36
+
37
+ /**
38
+ * ATTRIBUTES
39
+ */
40
+ await test.step('attributes', async () => {
41
+ await test.step('attribute X should be present on component by default', async () => {
42
+ // TODO: add test here
43
+ });
44
+ });
45
+
46
+ /**
47
+ * INTERACTIONS
48
+ */
49
+ await test.step('interactions', async () => {
50
+ await test.step('mouse/pointer', async () => {
51
+ await test.step('component should fire callback x when clicking on it', async () => {
52
+ // TODO: add test here
53
+ });
54
+ });
55
+
56
+ await test.step('focus', async () => {
57
+ await test.step('component should be focusable with tab', async () => {
58
+ // TODO: add test here
59
+ });
60
+
61
+ // add additional tests here, like tabbing through several parts of the component
62
+ });
63
+
64
+ await test.step('keyboard', async () => {
65
+ await test.step('component should fire callback x when pressing y', async () => {
66
+ // TODO: add test here
67
+ });
68
+ });
69
+ });
70
+ });
@@ -0,0 +1,25 @@
1
+ import type { Meta, StoryObj, Args } from '@storybook/web-components';
2
+ import '.';
3
+ import { html } from 'lit';
4
+ import { DEFAULTS } from './avatar.constants';
5
+
6
+ const render = (args: Args) => html`
7
+ <mdc-avatar src="${args.src}" scale="${args.scale}" type="${args.type}"></mdc-avatar>
8
+ `;
9
+
10
+ const meta: Meta = {
11
+ component: 'mdc-avatar',
12
+ render,
13
+ argTypes: {},
14
+ };
15
+
16
+ export default meta;
17
+
18
+ export const Primary: StoryObj = {
19
+ args: {
20
+ // eslint-disable-next-line max-len
21
+ src: 'https://images.unsplash.com/photo-1583195764036-6dc248ac07d9?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=2855&q=80',
22
+ scale: DEFAULTS.SCALE,
23
+ type: DEFAULTS.TYPE,
24
+ },
25
+ };
@@ -0,0 +1,20 @@
1
+ import { css } from 'lit';
2
+
3
+ const styles = css`
4
+ :host {
5
+ display: flex;
6
+ justify-content: center;
7
+ align-items: center;
8
+ border-radius: 100vh;
9
+ position: relative;
10
+ width: fit-content;
11
+ }
12
+ img {
13
+ border-radius: 100vh;
14
+ height: inherit;
15
+ width: inherit;
16
+ object-fit: cover;
17
+ }
18
+ `;
19
+
20
+ export default styles;
@@ -0,0 +1 @@
1
+ export type AvatarType = 'photo' | 'text' | 'icon' | 'multiuser'
@@ -0,0 +1,12 @@
1
+ import Avatar from './avatar.component';
2
+ import { TAG_NAME } from './avatar.constants';
3
+
4
+ Avatar.register(TAG_NAME);
5
+
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ ['mdc-avatar']: Avatar
9
+ }
10
+ }
11
+
12
+ export default Avatar;
@@ -0,0 +1,121 @@
1
+ import { html } from 'lit';
2
+ import { property } from 'lit/decorators.js';
3
+ import { StyleInfo, styleMap } from 'lit/directives/style-map.js';
4
+ import { Component } from '../../models';
5
+ import { DEFAULTS, WARNING_ICON_NAME } from './badge.constants';
6
+ import styles from './badge.styles';
7
+ import type { BadgeType } from './badge.types';
8
+
9
+ /**
10
+ * @slot - This is a default/unnamed slot
11
+ *
12
+ * @summary This is MyElement
13
+ *
14
+ * @tag mdc-badge
15
+ * @tagname mdc-badge
16
+ */
17
+ class Badge extends Component {
18
+ /**
19
+ * Type of the badge
20
+ * Can be `regular`, `icon`, `text` or `warning`
21
+ *
22
+ * Default: `regular`
23
+ */
24
+ @property({ type: String, reflect: true })
25
+ type?: BadgeType = DEFAULTS.TYPE;
26
+
27
+ /**
28
+ * Scale of the badge (works in combination with length unit)
29
+ *
30
+ * Default: `1`
31
+ */
32
+ @property({ type: Number })
33
+ scale?: number = DEFAULTS.SCALE;
34
+
35
+ /**
36
+ * Length unit attribute for scale
37
+ *
38
+ * Default: `rem`
39
+ */
40
+ @property({ type: String, attribute: 'length-unit' })
41
+ lengthUnit?: string = DEFAULTS.LENGTH_UNIT;
42
+
43
+ /**
44
+ * If `type` is set to `icon`, attribute `iconName` can
45
+ * be used to choose which icon should be shown
46
+ *
47
+ * If no `iconName` is provided, no icon will be rendered.
48
+ */
49
+ @property({ type: String, attribute: 'icon-name' })
50
+ iconName?: string;
51
+
52
+ /**
53
+ * If `type` is set to `text`, attribute `text` can
54
+ * be used to pass in any text to be displayed in the badge.
55
+ */
56
+ @property({ type: String })
57
+ text?: string;
58
+
59
+ private updateSize() {
60
+ // if (this.scale && this.lengthUnit) {
61
+ // const value = `${this.scale}${this.lengthUnit}`;
62
+ // this.style.height = value;
63
+ // if (this.type !== 'text') {
64
+ // this.style.width = value;
65
+ // }
66
+ // }
67
+ }
68
+
69
+ override updated(changedProperties: Map<string, any>) {
70
+ super.updated(changedProperties);
71
+ if (changedProperties.has('scale') || changedProperties.has('lengthUnit')) {
72
+ this.updateSize();
73
+ }
74
+ }
75
+
76
+ iconTemplate() {
77
+ return html`<div class="mdc-badge-icon-container">
78
+ <mdc-icon name="${this.iconName}" scale="100" length-unit="%"></mdc-icon>
79
+ </div>`;
80
+ }
81
+
82
+ textTemplate() {
83
+ return html`${this.text}`;
84
+ }
85
+
86
+ warningTemplate() {
87
+ return html` <mdc-icon name="${WARNING_ICON_NAME}" class="mdc-badge-warning"></mdc-icon> `;
88
+ }
89
+
90
+ public override render() {
91
+ let content;
92
+ const size = `${this.scale}${this.lengthUnit}`;
93
+ let sizeStyles: StyleInfo = { width: size, height: size };
94
+
95
+ switch (this.type) {
96
+ case 'regular':
97
+ content = html``;
98
+ break;
99
+ case 'icon':
100
+ content = this.iconTemplate();
101
+ break;
102
+ case 'text':
103
+ content = this.textTemplate();
104
+ // make width flexible when text -> only set the height:
105
+ sizeStyles = { height: sizeStyles.height };
106
+ break;
107
+ case 'warning':
108
+ content = this.warningTemplate();
109
+ break;
110
+ default:
111
+ content = html``;
112
+ break;
113
+ }
114
+
115
+ return html`<div class="mdc-badge-container" style=${styleMap(sizeStyles)}>${content}</div>`;
116
+ }
117
+
118
+ public static override styles = styles;
119
+ }
120
+
121
+ export default Badge;
@@ -0,0 +1,13 @@
1
+ import utils from '../../utils/tag-name';
2
+
3
+ const TAG_NAME = utils.constructTagName('badge');
4
+
5
+ const WARNING_ICON_NAME = 'warning-badge-filled';
6
+
7
+ const DEFAULTS = {
8
+ TYPE: 'regular' as const,
9
+ SCALE: 1,
10
+ LENGTH_UNIT: 'rem',
11
+ };
12
+
13
+ export { TAG_NAME, DEFAULTS, WARNING_ICON_NAME };
@@ -0,0 +1,68 @@
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
+ <mdc-badge />
8
+ `,
9
+ });
10
+ });
11
+
12
+ test('mdc-badge', async ({ componentsPage }) => {
13
+ const badge = componentsPage.page.locator('mdc-badge');
14
+
15
+ // initial check for the badge be visible on the screen:
16
+ await badge.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
+ // TODO: fix visual regression test on CI
29
+ // await test.step('visual-regression', async () => {
30
+ // await test.step('matches screenshot of element', async () => {
31
+ // await componentsPage.visualRegression.takeScreenshot('mdc-badge', { element: badge });
32
+ // });
33
+ // });
34
+
35
+ /**
36
+ * ATTRIBUTES
37
+ */
38
+ await test.step('attributes', async () => {
39
+ await test.step('attribute X should be present on component by default', async () => {
40
+ // TODO: add test here
41
+ });
42
+ });
43
+
44
+ /**
45
+ * INTERACTIONS
46
+ */
47
+ await test.step('interactions', async () => {
48
+ await test.step('mouse/pointer', async () => {
49
+ await test.step('component should fire callback x when clicking on it', async () => {
50
+ // TODO: add test here
51
+ });
52
+ });
53
+
54
+ await test.step('focus', async () => {
55
+ await test.step('component should be focusable with tab', async () => {
56
+ // TODO: add test here
57
+ });
58
+
59
+ // add additional tests here, like tabbing through several parts of the component
60
+ });
61
+
62
+ await test.step('keyboard', async () => {
63
+ await test.step('component should fire callback x when pressing y', async () => {
64
+ // TODO: add test here
65
+ });
66
+ });
67
+ });
68
+ });
@@ -0,0 +1,33 @@
1
+ import type { Meta, StoryObj, Args } from '@storybook/web-components';
2
+ import '.';
3
+ import { html } from 'lit';
4
+ import { DEFAULTS } from './badge.constants';
5
+
6
+ const render = (args: Args) => html`
7
+ <mdc-badge
8
+ type="${args.type}"
9
+ icon-name="${args.iconName}"
10
+ scale="${args.scale}"
11
+ length-unit="${args.lengthUnit}"
12
+ text="${args.text}"
13
+ ></mdc-badge>
14
+ `;
15
+
16
+ const meta: Meta = {
17
+ tags: ['autodocs'],
18
+ component: 'mdc-badge',
19
+ render,
20
+ argTypes: {},
21
+ };
22
+
23
+ export default meta;
24
+
25
+ export const Primary: StoryObj = {
26
+ args: {
27
+ type: DEFAULTS.TYPE,
28
+ iconName: 'accessibility-regular',
29
+ scale: 1,
30
+ lengthUnit: 'rem',
31
+ text: '99+',
32
+ },
33
+ };
@@ -0,0 +1,26 @@
1
+ import { css } from 'lit';
2
+ import { hostFitContentStyles } from '../../utils/styles';
3
+
4
+ const styles = [
5
+ hostFitContentStyles,
6
+ css`
7
+ :host {
8
+ --mdc-badge-icon-background-color: var(--mds-color-theme-background-accent-normal);
9
+ }
10
+
11
+ .mdc-badge-container {
12
+ display: flex;
13
+ justify-content: center;
14
+ align-items: center;
15
+ border-radius: 9999px;
16
+ background-color: var(--mdc-badge-icon-background-color);
17
+ }
18
+
19
+ .mdc-badge-icon-container {
20
+ height: 80%;
21
+ width: 80%;
22
+ }
23
+ `,
24
+ ];
25
+
26
+ export default styles;
@@ -0,0 +1 @@
1
+ export type BadgeType = 'regular' | 'text' | 'icon' | 'warning';
@@ -0,0 +1,12 @@
1
+ import Badge from './badge.component';
2
+ import { TAG_NAME } from './badge.constants';
3
+
4
+ Badge.register(TAG_NAME);
5
+
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ ['mdc-badge']: Badge
9
+ }
10
+ }
11
+
12
+ export default Badge;