@descope-ui/descope-avatar 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.
@@ -0,0 +1,54 @@
1
+ import { test, expect } from '@playwright/test';
2
+ import { getStoryUrl, loopConfig, loopPresets } from 'e2e-utils';
3
+
4
+ const img =
5
+ 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSzmudcbKkbOue75DaM9HDDrt0W39SJLBH-3HPK3s-K1w&s';
6
+
7
+ const componentAttributes = {
8
+ size: ['xs', 'sm', 'md', 'lg'],
9
+ editable: ['true', 'false'],
10
+ img: [img],
11
+ };
12
+
13
+ const presets = {
14
+ 'direction rtl': {
15
+ direction: 'rtl',
16
+ editable: 'true',
17
+ },
18
+ 'no image': {
19
+ img: '',
20
+ 'display-name': 'John Doe',
21
+ },
22
+ 'no image and name': {
23
+ img: '',
24
+ 'display-name': '',
25
+ },
26
+ };
27
+
28
+ const storyName = 'descope-avatar';
29
+ const componentName = 'descope-avatar';
30
+
31
+ test.describe('theme', () => {
32
+ loopConfig(componentAttributes, (attr, value) => {
33
+ test.describe(`${attr}: ${value}`, () => {
34
+ test.beforeEach(async ({ page }) => {
35
+ await page.goto(getStoryUrl(storyName, { text: 'Text 123', [attr]: value }), { waitUntil: 'load' });
36
+ });
37
+ test('style', async ({ page }) => {
38
+ const componentParent = page.locator(componentName);
39
+
40
+ expect(await componentParent.screenshot()).toMatchSnapshot();
41
+ });
42
+ });
43
+ });
44
+
45
+ loopPresets(presets, (preset, name) => {
46
+ test(name, async ({ page }) => {
47
+ await page.goto(getStoryUrl(storyName, preset));
48
+ await page.waitForSelector(componentName);
49
+ const component = page.locator(componentName);
50
+ expect(
51
+ await component.screenshot({ animations: 'disabled', timeout: 3000, caret: 'hide' })
52
+ ).toMatchSnapshot();
53
+ });
54
+ });});
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@descope-ui/descope-avatar",
3
+ "version": "0.0.1",
4
+ "exports": {
5
+ ".": {
6
+ "import": "./src/component/index.js"
7
+ },
8
+ "./theme": {
9
+ "import": "./src/theme.js"
10
+ },
11
+ "./class": {
12
+ "import": "./src/component/AvatarClass.js"
13
+ }
14
+ },
15
+ "devDependencies": {
16
+ "@playwright/test": "1.38.1",
17
+ "e2e-utils": "0.0.1"
18
+ },
19
+ "dependencies": {
20
+ "@descope-ui/common": "0.0.1",
21
+ "@descope-ui/theme-globals": "0.0.1",
22
+ "@vaadin/avatar": "24.3.4",
23
+ "@vaadin/icon": "24.3.4",
24
+ "@vaadin/icons": "24.3.4"
25
+ },
26
+ "publishConfig": {
27
+ "link-workspace-packages": false
28
+ },
29
+ "scripts": {
30
+ "test": "echo 'No tests defined' && exit 0",
31
+ "test:e2e": "echo 'No e2e tests defined' && exit 0"
32
+ }
33
+ }
package/project.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "@descope-ui/descope-avatar",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "packages/web-components/components/descope-avatar/src",
5
+ "projectType": "library",
6
+ "tags": []
7
+ }
@@ -0,0 +1,123 @@
1
+ import {
2
+ createStyleMixin,
3
+ draggableMixin,
4
+ componentNameValidationMixin,
5
+ } from '@descope-ui/common/components-mixins';
6
+ import { createBaseClass } from '@descope-ui/common/base-classes';
7
+ import { compose } from '@descope-ui/common/utils';
8
+ import {
9
+ forwardAttrs,
10
+ getComponentName,
11
+ observeAttributes,
12
+ } from '@descope-ui/common/components-helpers';
13
+
14
+ export const componentName = getComponentName('avatar');
15
+ class RawAvatar extends createBaseClass({
16
+ componentName,
17
+ baseSelector: ':host > .wrapper',
18
+ }) {
19
+ constructor() {
20
+ super();
21
+
22
+ this.attachShadow({ mode: 'open' }).innerHTML = `
23
+ <style>
24
+ :host {
25
+ display: inline-flex;
26
+ }
27
+
28
+ .editableBadge {
29
+ border: 1px solid;
30
+ border-radius: 100%;
31
+ height: fit-content;
32
+ width: 25%;
33
+ height: 25%;
34
+ display: flex;
35
+ justify-content: center;
36
+ align-items: center;
37
+ padding: 5%;
38
+ box-sizing: border-box;
39
+ position: absolute;
40
+ bottom: 0;
41
+ inset-inline-end: 0;
42
+ }
43
+
44
+ vaadin-icon {
45
+ color: currentcolor;
46
+ }
47
+
48
+ vaadin-avatar {
49
+ width: 100%;
50
+ height: 100%;
51
+ margin: 0;
52
+ border: none
53
+ }
54
+
55
+ .wrapper {
56
+ display: inline-flex;
57
+ position: relative;
58
+ width: 100%;
59
+ height: 100%;
60
+ }
61
+ </style>
62
+
63
+
64
+ <div class="wrapper">
65
+ <vaadin-avatar></vaadin-avatar>
66
+ <div class="editableBadge">
67
+ <vaadin-icon icon="vaadin:pencil"></vaadin-icon>
68
+ </div>
69
+ </div>
70
+ `;
71
+
72
+ this.avatarComponent = this.shadowRoot.querySelector('vaadin-avatar');
73
+
74
+ forwardAttrs(this, this.avatarComponent, {
75
+ includeAttrs: ['display-name', 'img', 'abbr'],
76
+ mapAttrs: { 'display-name': 'name' },
77
+ });
78
+
79
+ const editableIcon = this.shadowRoot.querySelector('.editableBadge');
80
+
81
+ observeAttributes(
82
+ this,
83
+ () => {
84
+ editableIcon.style.display = this.isEditable ? '' : 'none';
85
+ },
86
+ { includeAttrs: ['editable'] },
87
+ );
88
+ }
89
+
90
+ get isEditable() {
91
+ return this.getAttribute('editable') === 'true';
92
+ }
93
+ }
94
+
95
+ const { host, editableBadge, avatar } = {
96
+ host: { selector: () => ':host' },
97
+ editableBadge: { selector: '> .editableBadge' },
98
+ avatar: { selector: 'vaadin-avatar' },
99
+ };
100
+
101
+ export const AvatarClass = compose(
102
+ createStyleMixin({
103
+ mappings: {
104
+ hostWidth: [
105
+ { ...host, property: 'width' },
106
+ { ...host, property: 'min-width' },
107
+ ],
108
+ hostHeight: { ...host, property: 'height' },
109
+ cursor: [avatar, host],
110
+ hostDirection: { ...host, property: 'direction' },
111
+ avatarTextColor: { ...avatar, property: 'color' },
112
+ avatarBackgroundColor: { ...avatar, property: 'background-color' },
113
+ editableIconColor: { ...editableBadge, property: 'color' },
114
+ editableBorderColor: { ...editableBadge, property: 'border-color' },
115
+ editableBackgroundColor: {
116
+ ...editableBadge,
117
+ property: 'background-color',
118
+ },
119
+ },
120
+ }),
121
+ draggableMixin,
122
+ componentNameValidationMixin,
123
+ )(RawAvatar);
@@ -0,0 +1,8 @@
1
+ import { componentName, AvatarClass } from './AvatarClass';
2
+ import '@vaadin/avatar';
3
+ import '@vaadin/icon';
4
+ import '@vaadin/icons';
5
+
6
+ customElements.define(componentName, AvatarClass);
7
+
8
+ export { AvatarClass };
package/src/theme.js ADDED
@@ -0,0 +1,44 @@
1
+ import globals from '@descope-ui/theme-globals';
2
+ import { AvatarClass } from './component/AvatarClass';
3
+ import { getThemeRefs } from '@descope-ui/common/theme-helpers';
4
+
5
+ const globalRefs = getThemeRefs(globals);
6
+ const compVars = AvatarClass.cssVarList;
7
+
8
+ const avatar = {
9
+ [compVars.hostDirection]: globalRefs.direction,
10
+ [compVars.editableIconColor]: globalRefs.colors.surface.dark,
11
+ [compVars.editableBorderColor]: globalRefs.colors.surface.dark,
12
+ [compVars.editableBackgroundColor]: globalRefs.colors.surface.main,
13
+ [compVars.avatarTextColor]: globalRefs.colors.surface.main,
14
+ [compVars.avatarBackgroundColor]: globalRefs.colors.surface.dark,
15
+
16
+ _editable: {
17
+ [compVars.cursor]: 'pointer',
18
+ },
19
+
20
+ size: {
21
+ xs: {
22
+ [compVars.hostWidth]: '30px',
23
+ [compVars.hostHeight]: '30px',
24
+ },
25
+ sm: {
26
+ [compVars.hostWidth]: '40px',
27
+ [compVars.hostHeight]: '40px',
28
+ },
29
+ md: {
30
+ [compVars.hostWidth]: '60px',
31
+ [compVars.hostHeight]: '60px',
32
+ },
33
+ lg: {
34
+ [compVars.hostWidth]: '98px',
35
+ [compVars.hostHeight]: '98px',
36
+ },
37
+ },
38
+ };
39
+
40
+ export default avatar;
41
+
42
+ export const vars = {
43
+ ...compVars,
44
+ };
Binary file
@@ -0,0 +1,32 @@
1
+ import { componentName } from '../src/component/AvatarClass';
2
+ import { directionControl, sizeControl } from '@descope-ui/common/sb-controls';
3
+ import img from './avatar.jpeg'
4
+
5
+ const Template = ({ 'display-name': displayName, img, size, editable, direction }) => `
6
+ <descope-avatar
7
+ display-name="${displayName || ''}"
8
+ img="${img}"
9
+ size="${size}"
10
+ editable="${editable || ''}"
11
+ st-host-direction="${direction ?? ''}">
12
+ ></descope-avatar
13
+ `;
14
+
15
+ export default {
16
+ component: componentName,
17
+ title: 'descope-avatar',
18
+ argTypes: {
19
+ ...sizeControl,
20
+ ...directionControl,
21
+ },
22
+ };
23
+
24
+ export const Default = Template.bind({});
25
+
26
+ Default.args = {
27
+ img: img,
28
+ 'display-name': 'John Doe',
29
+ size: 'sm',
30
+ editable: false,
31
+ direction: ''
32
+ };