@momentum-design/components 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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;