@lukso/web-components 1.2.2 → 1.3.0

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 (59) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +4 -0
  3. package/dist/components/index.d.ts +5 -0
  4. package/dist/components/index.js +1596 -527
  5. package/dist/components/index.umd.cjs +159 -40
  6. package/dist/components/lukso-button/index.d.ts +1 -0
  7. package/dist/components/lukso-button/index.js +131 -127
  8. package/dist/components/lukso-button/index.umd.cjs +16 -16
  9. package/dist/components/lukso-card/index.d.ts +19 -0
  10. package/dist/components/lukso-card/index.js +1541 -0
  11. package/dist/components/lukso-card/index.umd.cjs +144 -0
  12. package/dist/components/lukso-navbar/index.js +2 -2
  13. package/dist/components/lukso-navbar/index.umd.cjs +2 -2
  14. package/dist/components/lukso-profile/index.d.ts +25 -0
  15. package/dist/components/lukso-profile/index.js +1423 -0
  16. package/dist/components/lukso-profile/index.umd.cjs +90 -0
  17. package/dist/components/lukso-sanitize/index.d.ts +12 -0
  18. package/dist/components/lukso-sanitize/index.js +1626 -0
  19. package/dist/components/lukso-sanitize/index.umd.cjs +61 -0
  20. package/dist/components/lukso-tag/index.d.ts +20 -0
  21. package/dist/components/lukso-tag/index.js +1209 -0
  22. package/dist/components/lukso-tag/index.umd.cjs +67 -0
  23. package/dist/components/lukso-test/index.js +46 -46
  24. package/dist/components/lukso-test/index.umd.cjs +22 -22
  25. package/dist/components/lukso-username/index.d.ts +34 -0
  26. package/dist/components/lukso-username/index.js +1255 -0
  27. package/dist/components/lukso-username/index.umd.cjs +75 -0
  28. package/dist/components/lukso-wizard/index.js +2 -2
  29. package/dist/components/lukso-wizard/index.umd.cjs +2 -2
  30. package/dist/index.js +1596 -527
  31. package/dist/index.umd.cjs +159 -40
  32. package/dist/sass/typography.scss +4 -4
  33. package/dist/shared/tailwind-element/index.js +146 -146
  34. package/dist/shared/tailwind-element/index.umd.cjs +1 -1
  35. package/dist/shared/tailwind-element.js +146 -146
  36. package/dist/shared/tailwind-element.umd.cjs +1 -1
  37. package/dist/shared/utils/sliceAddress.d.ts +9 -0
  38. package/dist/styles/main.css +4 -4
  39. package/package.json +30 -2
  40. package/src/components/index.ts +5 -0
  41. package/src/components/lukso-button/index.ts +4 -0
  42. package/src/components/lukso-button/lukso-button.stories.ts +64 -5
  43. package/src/components/lukso-card/index.ts +118 -0
  44. package/src/components/lukso-card/lukso-card.stories.ts +135 -0
  45. package/src/components/lukso-navbar/index.ts +1 -1
  46. package/src/components/lukso-navbar/lukso-navbar.stories.ts +13 -4
  47. package/src/components/lukso-profile/index.ts +100 -0
  48. package/src/components/lukso-profile/lukso-profile.stories.ts +87 -0
  49. package/src/components/lukso-sanitize/index.ts +28 -0
  50. package/src/components/lukso-sanitize/lukso-sanitize.stories.ts +26 -0
  51. package/src/components/lukso-tag/index.ts +68 -0
  52. package/src/components/lukso-tag/lukso-tag.stories.ts +107 -0
  53. package/src/components/lukso-username/index.ts +104 -0
  54. package/src/components/lukso-username/lukso-username.stories.ts +94 -0
  55. package/src/components/lukso-wizard/index.ts +1 -1
  56. package/src/components/lukso-wizard/lukso-wizard.stories.ts +6 -2
  57. package/src/shared/styles/typography.scss +4 -4
  58. package/src/shared/utils/__tests__/sliceAddress.spec.ts +15 -0
  59. package/src/shared/utils/sliceAddress.ts +30 -0
@@ -0,0 +1,135 @@
1
+ import { html } from 'lit-html'
2
+ import './index'
3
+
4
+ export default {
5
+ title: 'Design System/Components/Card',
6
+ component: 'lukso-card',
7
+ argTypes: {
8
+ variant: {
9
+ control: { type: 'select' },
10
+ options: ['basic', 'with-header', 'profile'],
11
+ },
12
+ content: { control: { type: 'text' } },
13
+ header: {
14
+ control: { type: 'text' },
15
+ if: { arg: 'variant', eq: 'with-header' },
16
+ },
17
+ backgroundUrl: {
18
+ control: { type: 'text' },
19
+ if: { arg: 'variant', eq: 'profile' },
20
+ },
21
+ profileUrl: {
22
+ control: { type: 'text' },
23
+ if: { arg: 'variant', eq: 'profile' },
24
+ },
25
+ profileAddress: {
26
+ control: { type: 'text' },
27
+ if: { arg: 'variant', eq: 'profile' },
28
+ },
29
+ },
30
+ args: {
31
+ variant: 'basic',
32
+ content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
33
+ header: 'Dolor sit amet',
34
+ backgroundUrl: 'images/sample-background.jpg',
35
+ profileUrl: 'images/sample-avatar.png',
36
+ profileAddress: '0x9671Db683406EE0817B1f5cB6A3b3BD111477457',
37
+ },
38
+ parameters: {
39
+ controls: {
40
+ exclude: [
41
+ 'defaultStyles',
42
+ 'background-url',
43
+ 'profile-url',
44
+ 'profile-address',
45
+ ],
46
+ },
47
+ },
48
+ }
49
+
50
+ const DefaultTemplate = ({ variant, content, header }) =>
51
+ html`
52
+ <lukso-card variant=${variant}>
53
+ <div slot="header" class="p-6">${header}</div>
54
+ <div slot="content" class="p-6">${content}</div>
55
+ </lukso-card>
56
+ `
57
+
58
+ const CustomHeaderTemplate = ({ variant, content, header }) =>
59
+ html`
60
+ <lukso-card variant=${variant}>
61
+ <div slot="header" class="p-6 relative overflow-hidden min-h-[200px]">
62
+ <div
63
+ class="w-[876px] h-[200px] -left-[257px] top-[72px] bg-neutral-95 rounded-[50%] absolute"
64
+ ></div>
65
+ ${header}
66
+ </div>
67
+ <div slot="content" class="p-6">${content}</div>
68
+ </lukso-card>
69
+ `
70
+
71
+ const ProfileTemplate = ({
72
+ variant,
73
+ content,
74
+ backgroundUrl,
75
+ profileUrl,
76
+ profileAddress,
77
+ }) =>
78
+ html`
79
+ <lukso-card
80
+ variant=${variant}
81
+ background-url=${backgroundUrl}
82
+ profile-url=${profileUrl}
83
+ profile-address=${profileAddress}
84
+ >
85
+ <div slot="content" class="p-6">${content}</div>
86
+ </lukso-card>
87
+ `
88
+
89
+ export const DefaultCard = DefaultTemplate.bind({})
90
+ DefaultCard.parameters = {
91
+ design: {
92
+ type: 'figma',
93
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=1332%3A18025&t=AGmdbG8fXRENuU3o-4',
94
+ },
95
+ }
96
+
97
+ export const CardWithHeader = DefaultTemplate.bind({})
98
+ CardWithHeader.args = {
99
+ variant: 'with-header',
100
+ }
101
+ CardWithHeader.parameters = {
102
+ design: {
103
+ type: 'figma',
104
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=1332%3A18028&t=AGmdbG8fXRENuU3o-4',
105
+ },
106
+ }
107
+
108
+ export const CardWithCustomHeader = CustomHeaderTemplate.bind({})
109
+ CardWithCustomHeader.args = {
110
+ variant: 'with-header',
111
+ }
112
+ CardWithCustomHeader.parameters = {
113
+ design: {
114
+ type: 'figma',
115
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=1332%3A18026&t=AGmdbG8fXRENuU3o-4',
116
+ },
117
+ }
118
+
119
+ export const ProfileCard = ProfileTemplate.bind({})
120
+ ProfileCard.args = {
121
+ variant: 'profile',
122
+ parameters: {
123
+ design: {
124
+ type: 'figma',
125
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=1096%3A14641&t=AGmdbG8fXRENuU3o-4',
126
+ },
127
+ },
128
+ }
129
+
130
+ ProfileCard.parameters = {
131
+ design: {
132
+ type: 'figma',
133
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=1332%3A18027&t=AGmdbG8fXRENuU3o-4',
134
+ },
135
+ }
@@ -19,7 +19,7 @@ export class LuksoNavbar extends TailwindElement {
19
19
 
20
20
  private centerStyles = `justify-center`
21
21
 
22
- private stickyStyles = `sticky top-0 z-10`
22
+ private stickyStyles = `sticky top-0 z-[1000]`
23
23
 
24
24
  _onBrandClick() {
25
25
  const event = new CustomEvent('click-brand', {
@@ -2,7 +2,7 @@ import { html } from 'lit-html'
2
2
  import './index'
3
3
 
4
4
  export default {
5
- title: 'Design System/Atoms/Navbar',
5
+ title: 'Design System/Components/Navbar',
6
6
  component: 'lukso-navbar',
7
7
  argTypes: {
8
8
  title: {
@@ -31,14 +31,23 @@ PROFILES`,
31
31
  'is-sticky',
32
32
  ],
33
33
  },
34
+ design: {
35
+ type: 'figma',
36
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=1097%3A14669&t=AGmdbG8fXRENuU3o-4',
37
+ },
34
38
  },
35
39
  }
36
40
 
37
41
  const Template = ({ title, isCenter, isSticky }) =>
38
42
  html`<lukso-navbar
39
43
  title=${title}
40
- ?is-center="${isCenter}"
41
- ?is-sticky="${isSticky}"
44
+ ?is-center=${isCenter}
45
+ ?is-sticky=${isSticky}
42
46
  ></lukso-navbar>`
43
47
 
44
- export const Navbar = Template.bind({})
48
+ export const DefaultNavbar = Template.bind({})
49
+
50
+ export const CenterNavbar = Template.bind({})
51
+ CenterNavbar.args = {
52
+ isCenter: true,
53
+ }
@@ -0,0 +1,100 @@
1
+ import { html } from 'lit'
2
+ import { customElement, property } from 'lit/decorators.js'
3
+ import { styleMap } from 'lit/directives/style-map.js'
4
+ import makeBlockie from 'ethereum-blockies-base64'
5
+
6
+ import { TailwindElement } from '@/shared/tailwind-element'
7
+
8
+ export type ProfileSize = 'x-small' | 'small' | 'medium' | 'large' | 'x-large'
9
+ type SizeDef = { identiconSize?: number; profileImageSize: number }
10
+
11
+ @customElement('lukso-profile')
12
+ export class LuksoProfile extends TailwindElement {
13
+ @property({ type: String, attribute: 'profile-url' })
14
+ profileUrl = ''
15
+
16
+ @property({ type: String, attribute: 'profile-address' })
17
+ profileAddress = ''
18
+
19
+ @property({ type: Boolean, attribute: 'has-identicon' })
20
+ hasIdenticon = false
21
+
22
+ @property({ type: String })
23
+ size: ProfileSize = 'large'
24
+
25
+ sizes: Record<ProfileSize, SizeDef> = {
26
+ 'x-small': {
27
+ identiconSize: undefined,
28
+ profileImageSize: 24,
29
+ },
30
+ small: {
31
+ identiconSize: 16,
32
+ profileImageSize: 40,
33
+ },
34
+ medium: {
35
+ identiconSize: 20,
36
+ profileImageSize: 56,
37
+ },
38
+ large: {
39
+ identiconSize: 24,
40
+ profileImageSize: 80,
41
+ },
42
+ 'x-large': {
43
+ identiconSize: 28,
44
+ profileImageSize: 96,
45
+ },
46
+ }
47
+
48
+ private profileImageSize = () => this.sizes[this.size].profileImageSize
49
+ private identiconSize = () => this.sizes[this.size].identiconSize
50
+ private defaultProfileUrl = 'assets/images/profile-default.png'
51
+
52
+ private identicon = () => {
53
+ return this.hasIdenticon && this.profileAddress && this.identiconSize()
54
+ ? makeBlockie(this.profileAddress)
55
+ : ''
56
+ }
57
+
58
+ render() {
59
+ return html`
60
+ <div
61
+ data-testid="profile"
62
+ style=${styleMap({
63
+ backgroundImage: `url(${this.defaultProfileUrl})`,
64
+ width: `${this.profileImageSize()}px`,
65
+ height: `${this.profileImageSize()}px`,
66
+ })}
67
+ class="rounded-full bg-[50%] bg-no-repeat bg-cover bg-neutral-90
68
+ outline outline-2 outline-neutral-100"
69
+ >
70
+ <div
71
+ style=${styleMap({
72
+ backgroundImage: `url(${this.profileUrl})`,
73
+ width: `${this.profileImageSize()}px`,
74
+ height: `${this.profileImageSize()}px`,
75
+ })}
76
+ class="rounded-full bg-[50%] bg-no-repeat bg-cover relative
77
+ "
78
+ >
79
+ ${this.identicon()
80
+ ? html`<img
81
+ src=${this.identicon()}
82
+ class="absolute shadow-shadow-1xl rounded-full
83
+ outline outline-2 outline-neutral-100 right-0 bottom-0"
84
+ style=${styleMap({
85
+ width: `${this.identiconSize()}px`,
86
+ height: `${this.identiconSize()}px`,
87
+ })}
88
+ />`
89
+ : ''}
90
+ </div>
91
+ </div>
92
+ `
93
+ }
94
+ }
95
+
96
+ declare global {
97
+ interface HTMLElementTagNameMap {
98
+ 'lukso-profile': LuksoProfile
99
+ }
100
+ }
@@ -0,0 +1,87 @@
1
+ import { html } from 'lit-html'
2
+ import './index'
3
+
4
+ export default {
5
+ title: 'Design System/Components/Profile',
6
+ component: 'lukso-profile',
7
+ argTypes: {
8
+ profileUrl: {
9
+ control: { type: 'text' },
10
+ },
11
+ size: {
12
+ control: {
13
+ type: 'select',
14
+ },
15
+ options: ['x-small', 'small', 'medium', 'large', 'x-large'],
16
+ },
17
+ profileAddress: {
18
+ control: { type: 'text' },
19
+ },
20
+ hasIdenticon: {
21
+ control: { type: 'boolean' },
22
+ },
23
+ },
24
+ args: {
25
+ profileUrl: 'images/sample-avatar.png',
26
+ size: 'x-large',
27
+ profileAddress: '0x9671Db683406EE0817B1f5cB6A3b3BD111477457',
28
+ hasIdenticon: true,
29
+ },
30
+ parameters: {
31
+ controls: {
32
+ exclude: [
33
+ 'sizes',
34
+ 'profile-url',
35
+ 'profileImageSize',
36
+ 'identiconSize',
37
+ 'identicon',
38
+ 'profile-address',
39
+ 'has-identicon',
40
+ 'defaultProfileUrl',
41
+ ],
42
+ },
43
+ design: {
44
+ type: 'figma',
45
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=378%3A3395&t=AGmdbG8fXRENuU3o-4',
46
+ },
47
+ },
48
+ }
49
+
50
+ const Template = ({ profileUrl, size, profileAddress, hasIdenticon }) =>
51
+ html`<lukso-profile
52
+ profile-url=${profileUrl}
53
+ size=${size}
54
+ profile-address=${profileAddress}
55
+ ?has-identicon=${hasIdenticon}
56
+ ></lukso-profile>`
57
+
58
+ export const XLarge = Template.bind({})
59
+ XLarge.args = {
60
+ size: 'x-large',
61
+ }
62
+
63
+ export const Large = Template.bind({})
64
+ Large.args = {
65
+ size: 'large',
66
+ }
67
+
68
+ export const Medium = Template.bind({})
69
+ Medium.args = {
70
+ size: 'medium',
71
+ }
72
+
73
+ export const Small = Template.bind({})
74
+ Small.args = {
75
+ size: 'small',
76
+ }
77
+
78
+ export const XSmall = Template.bind({})
79
+ XSmall.args = {
80
+ size: 'x-small',
81
+ }
82
+
83
+ export const Unknown = Template.bind({})
84
+ Unknown.args = {
85
+ profileUrl: '',
86
+ hasIdenticon: false,
87
+ }
@@ -0,0 +1,28 @@
1
+ import { html } from 'lit'
2
+ import { customElement, property } from 'lit/decorators.js'
3
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js'
4
+ import DOMPurify from 'dompurify'
5
+
6
+ import { TailwindElement } from '@/shared/tailwind-element'
7
+
8
+ @customElement('lukso-sanitize')
9
+ export class LuksoSanitize extends TailwindElement {
10
+ @property({ type: String, attribute: 'html-content' })
11
+ htmlContent = ''
12
+
13
+ sanitize = () => {
14
+ return DOMPurify.sanitize(this.htmlContent)
15
+ }
16
+
17
+ render() {
18
+ // in order to show HTML we need to use unsafeHTML directive.
19
+ // This is safe since we already sanitized content
20
+ return html`${unsafeHTML(this.sanitize())}`
21
+ }
22
+ }
23
+
24
+ declare global {
25
+ interface HTMLElementTagNameMap {
26
+ 'lukso-sanitize': LuksoSanitize
27
+ }
28
+ }
@@ -0,0 +1,26 @@
1
+ import { html } from 'lit-html'
2
+ import './index'
3
+
4
+ export default {
5
+ title: 'Design System/Components/Sanitize',
6
+ component: 'lukso-sanitize',
7
+ argTypes: {
8
+ htmlContent: {
9
+ control: { type: 'text' },
10
+ },
11
+ },
12
+ args: {
13
+ htmlContent:
14
+ 'This is sample text containing html tags like <b>bold</b> or <a class="text-sky-64" href="/">link</a>.',
15
+ },
16
+ parameters: {
17
+ controls: {
18
+ exclude: ['sanitize', 'html-content'],
19
+ },
20
+ },
21
+ }
22
+
23
+ const Template = ({ htmlContent }) =>
24
+ html`<lukso-sanitize html-content=${htmlContent}></lukso-sanitize>`
25
+
26
+ export const Sanitize = Template.bind({})
@@ -0,0 +1,68 @@
1
+ import { html } from 'lit'
2
+ import { customElement, property } from 'lit/decorators.js'
3
+ import { styleMap } from 'lit/directives/style-map.js'
4
+
5
+ import { TailwindElement } from '@/shared/tailwind-element'
6
+ import { customClassMap } from '@/shared/directives'
7
+
8
+ export type TagSizes = 'small' | 'large'
9
+
10
+ @customElement('lukso-tag')
11
+ export class LuksoTag extends TailwindElement {
12
+ @property({ type: String })
13
+ size: TagSizes = 'small'
14
+
15
+ @property({ type: Boolean, attribute: 'is-rounded' })
16
+ isRounded = false
17
+
18
+ @property({ type: String, attribute: 'background-color' })
19
+ backgroundColor = ''
20
+
21
+ @property({ type: String, attribute: 'text-color' })
22
+ textColor = ''
23
+
24
+ private defaultStyles = `rounded-lg inline-flex items-center justify-center border border-neutral-20 text-neutral-20`
25
+ private smallStyles = `paragraph-12-medium h-[28px]`
26
+ private largeStyles = `paragraph-14-medium h-[34px]`
27
+ private roundedStyles = `rounded-[56px]`
28
+
29
+ private padding = () => {
30
+ if (this.size === 'small' && this.isRounded) {
31
+ return 'px-3'
32
+ }
33
+
34
+ if (this.size === 'large') {
35
+ return 'px-4'
36
+ }
37
+
38
+ return 'px-2'
39
+ }
40
+
41
+ render() {
42
+ return html`
43
+ <div
44
+ data-testid="tag"
45
+ class=${customClassMap({
46
+ [this.defaultStyles]: true,
47
+ [this.padding()]: true,
48
+ [this.roundedStyles]: this.isRounded,
49
+ [this.smallStyles]: this.size === 'small',
50
+ [this.largeStyles]: this.size === 'large',
51
+ })}
52
+ style=${styleMap({
53
+ backgroundColor: this.backgroundColor,
54
+ borderColor: this.backgroundColor,
55
+ color: this.textColor,
56
+ })}
57
+ >
58
+ <slot></slot>
59
+ </div>
60
+ `
61
+ }
62
+ }
63
+
64
+ declare global {
65
+ interface HTMLElementTagNameMap {
66
+ 'lukso-tag': LuksoTag
67
+ }
68
+ }
@@ -0,0 +1,107 @@
1
+ import { html } from 'lit-html'
2
+ import './index'
3
+
4
+ export default {
5
+ title: 'Design System/Components/Tag',
6
+ component: 'lukso-tag',
7
+ argTypes: {
8
+ content: {
9
+ control: { type: 'text' },
10
+ },
11
+ isRounded: {
12
+ control: {
13
+ type: 'boolean',
14
+ },
15
+ },
16
+ size: {
17
+ control: {
18
+ type: 'select',
19
+ },
20
+ options: ['small', 'large'],
21
+ },
22
+ backgroundColor: {
23
+ control: {
24
+ type: 'color',
25
+ },
26
+ },
27
+ textColor: {
28
+ control: {
29
+ type: 'color',
30
+ },
31
+ },
32
+ },
33
+ args: {
34
+ size: 'small',
35
+ isRounded: false,
36
+ content: 'Small Tag',
37
+ backgroundColor: '',
38
+ textColor: '',
39
+ },
40
+ parameters: {
41
+ controls: {
42
+ exclude: [
43
+ 'defaultStyles',
44
+ 'smallStyles',
45
+ 'largeStyles',
46
+ 'roundedStyles',
47
+ 'is-rounded',
48
+ 'background-color',
49
+ 'text-color',
50
+ 'padding',
51
+ ],
52
+ },
53
+ },
54
+ }
55
+
56
+ const Template = ({ content, size, isRounded, backgroundColor, textColor }) =>
57
+ html`<lukso-tag
58
+ size=${size}
59
+ ?is-rounded=${isRounded}
60
+ background-color=${backgroundColor}
61
+ text-color=${textColor}
62
+ >${content}</lukso-tag
63
+ >`
64
+
65
+ export const DefaultTag = Template.bind({})
66
+ DefaultTag.parameters = {
67
+ design: {
68
+ type: 'figma',
69
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=375%3A3234&t=AGmdbG8fXRENuU3o-4',
70
+ },
71
+ }
72
+
73
+ export const LargeTag = Template.bind({})
74
+ LargeTag.args = {
75
+ size: 'large',
76
+ content: 'Large Tag',
77
+ }
78
+ LargeTag.parameters = {
79
+ design: {
80
+ type: 'figma',
81
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=375%3A3234&t=AGmdbG8fXRENuU3o-4',
82
+ },
83
+ }
84
+
85
+ export const RoundedTag = Template.bind({})
86
+ RoundedTag.args = {
87
+ isRounded: true,
88
+ }
89
+ RoundedTag.parameters = {
90
+ design: {
91
+ type: 'figma',
92
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=1083%3A13483&t=AGmdbG8fXRENuU3o-4',
93
+ },
94
+ }
95
+
96
+ export const CustomColorTag = Template.bind({})
97
+ CustomColorTag.args = {
98
+ content: 'Custom Color Tag',
99
+ backgroundColor: '#E96464',
100
+ textColor: '#FFFFFF',
101
+ }
102
+ CustomColorTag.parameters = {
103
+ design: {
104
+ type: 'figma',
105
+ url: 'https://www.figma.com/file/NFCh20xAq3Jg2g8A0DNC9I/UI-Library?node-id=375%3A3241&t=AGmdbG8fXRENuU3o-4',
106
+ },
107
+ }
@@ -0,0 +1,104 @@
1
+ import { html } from 'lit'
2
+ import { customElement, property } from 'lit/decorators.js'
3
+ import { sliceAddress } from '@/shared/utils/sliceAddress'
4
+
5
+ import { TailwindElement } from '@/shared/tailwind-element'
6
+ import { customClassMap } from '@/shared/directives/custom-class-map'
7
+ import { styleMap } from 'lit-html/directives/style-map.js'
8
+
9
+ export type UsernameSize = 'small' | 'large'
10
+
11
+ @customElement('lukso-username')
12
+ export class LuksoUsername extends TailwindElement {
13
+ @property({ type: String })
14
+ name = ''
15
+
16
+ @property({ type: String })
17
+ address = ''
18
+
19
+ @property({ type: Number, attribute: 'max-width' })
20
+ maxWidth = 200
21
+
22
+ @property({ type: 'string' })
23
+ size: UsernameSize = 'large'
24
+
25
+ @property({ type: Number, attribute: 'slice-by' })
26
+ sliceBy = 8
27
+
28
+ @property({ type: String, attribute: 'address-color' })
29
+ addressColor = 'neutral-20'
30
+
31
+ /** Width of the first 4 bytes of the address */
32
+ private bytesWidth = 52
33
+
34
+ /**
35
+ * Template for 4byte address
36
+ * e.g: #1234
37
+ */
38
+ private addressBytesTemplate() {
39
+ return html`<div class="inline-block text-neutral-60">
40
+ #${this.address.slice(2, 6)}
41
+ </div>`
42
+ }
43
+
44
+ /**
45
+ * Template for name
46
+ * e.g: @John
47
+ */
48
+ private nameTemplate() {
49
+ return html`<div
50
+ class="inline-block whitespace-nowrap overflow-hidden text-ellipsis text-transparent
51
+ bg-clip-text bg-gradient-to-r from-gradient-1-start to-gradient-1-end"
52
+ style=${styleMap({
53
+ maxWidth: `${this.maxWidth - this.bytesWidth}px`,
54
+ })}
55
+ >
56
+ @${this.name}
57
+ </div>`
58
+ }
59
+
60
+ /**
61
+ * Template for address
62
+ * e.g: 0x123...789
63
+ */
64
+ private addressTemplate() {
65
+ return html`<div
66
+ class="inline-block ${customClassMap({
67
+ ['text-' + this.addressColor]: this.addressColor !== 'neutral-20',
68
+ })}"
69
+ >
70
+ ${sliceAddress(this.address, this.sliceBy, this.sliceBy)}
71
+ </div>`
72
+ }
73
+
74
+ render() {
75
+ const template = (() => {
76
+ if (this.name && this.address) {
77
+ return html`${this.nameTemplate()}${this.addressBytesTemplate()}`
78
+ }
79
+
80
+ if (this.name) {
81
+ return this.nameTemplate()
82
+ }
83
+
84
+ if (this.address) {
85
+ return this.addressTemplate()
86
+ }
87
+ })()
88
+
89
+ return html`<div
90
+ class="inline-flex ${customClassMap({
91
+ 'monospaced-12-bold': this.size === 'small',
92
+ 'monospaced-16-bold': this.size === 'large',
93
+ })}"
94
+ >
95
+ ${template}
96
+ </div>`
97
+ }
98
+ }
99
+
100
+ declare global {
101
+ interface HTMLElementTagNameMap {
102
+ 'lukso-username': LuksoUsername
103
+ }
104
+ }