Skip to content

Commit

Permalink
refactor: use component extensions for theming (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
Peppe authored Mar 9, 2021
1 parent 32c1676 commit 68ffc34
Show file tree
Hide file tree
Showing 28 changed files with 271 additions and 96 deletions.
42 changes: 42 additions & 0 deletions src/vaadin-message-avatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @license
* Copyright (c) 2021 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { AvatarElement } from '@vaadin/vaadin-avatar/src/vaadin-avatar.js';
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';

registerStyles(
'vaadin-message-avatar',
css`
:host {
--vaadin-avatar-outline-width: 0px; /* stylelint-disable-line length-zero-no-unit */
flex-shrink: 0;
}
`,
{ moduleId: 'vaadin-message-avatar-styles' }
);

/**
* The avatar element for message.
*
* ### Styling
*
* See [`<vaadin-avatar>` documentation](https://github.com/vaadin/vaadin-avatar/blob/master/src/vaadin-avatar.js)
* for `<vaadin-message-avatar>` parts and available slots
*
* See [ThemableMixin – how to apply styles for shadow parts](https://github.com/vaadin/vaadin-themable-mixin#readme)
*
* @extends AvatarElement
*/
class MessageAvatarElement extends AvatarElement {
static get is() {
return 'vaadin-message-avatar';
}

static get version() {
return '2.0.0-alpha1';
}
}

customElements.define(MessageAvatarElement.is, MessageAvatarElement);
42 changes: 42 additions & 0 deletions src/vaadin-message-input-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @license
* Copyright (c) 2021 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { ButtonElement } from '@vaadin/vaadin-button/src/vaadin-button.js';
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';

registerStyles(
'vaadin-message-input-button',
css`
:host {
flex-shrink: 0;
margin: 0;
}
`,
{ moduleId: 'vaadin-message-input-button-styles' }
);

/**
* The button element for a message input.
*
* ### Styling
*
* See [`<vaadin-button>` documentation](https://github.com/vaadin/vaadin-button/blob/master/src/vaadin-button.js)
* for `<vaadin-message-input-button>` parts and available slots
*
* See [ThemableMixin – how to apply styles for shadow parts](https://github.com/vaadin/vaadin-themable-mixin#readme)
*
* @extends ButtonElement
*/
class MessageInputButtonElement extends ButtonElement {
static get is() {
return 'vaadin-message-input-button';
}

static get version() {
return '2.0.0-alpha1';
}
}

customElements.define(MessageInputButtonElement.is, MessageInputButtonElement);
68 changes: 68 additions & 0 deletions src/vaadin-message-input-text-area.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* @license
* Copyright (c) 2021 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { TextAreaElement } from '@vaadin/vaadin-text-field/src/vaadin-text-area.js';
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';

registerStyles(
'vaadin-message-input-text-area',
css`
:host {
align-self: stretch;
flex-grow: 1;
padding: 0;
}
`,
{ moduleId: 'vaadin-message-input-text-area-styles' }
);

/**
* The text area element for a message input.
*
* ### Styling
*
* See [`<vaadin-text-area>` documentation](https://github.com/vaadin/vaadin-text-field/blob/master/src/vaadin-text-area.js)
* for `<vaadin-message-input-text-area>` parts and available slots
*
* See [ThemableMixin – how to apply styles for shadow parts](https://github.com/vaadin/vaadin-themable-mixin#readme)
*
* @extends TextAreaElement
*/
class MessageInputTextAreaElement extends TextAreaElement {
static get is() {
return 'vaadin-message-input-text-area';
}

static get version() {
return '2.0.0-alpha1';
}

ready() {
super.ready();

const textarea = this.inputElement;
textarea.removeAttribute('aria-labelledby');

// Set initial height to one row
textarea.setAttribute('rows', 1);
textarea.style.minHeight = '0';

// Add enter handling for text area.
textarea.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
e.stopPropagation();
this.dispatchEvent(new CustomEvent('enter'));
}
});
}

_setAriaLabel(message) {
// Set aria-label to provide an accessible name for the labelless input
this.inputElement.setAttribute('aria-label', message);
}
}

customElements.define(MessageInputTextAreaElement.is, MessageInputTextAreaElement);
56 changes: 13 additions & 43 deletions src/vaadin-message-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { ElementMixin } from '@vaadin/vaadin-element-mixin/vaadin-element-mixin.js';
import '@vaadin/vaadin-button/src/vaadin-button.js';
import '@vaadin/vaadin-text-field/src/vaadin-text-area.js';
import './vaadin-message-input-text-area.js';
import './vaadin-message-input-button.js';
/**
* `<vaadin-message-input>` is a Web Component for sending messages.
* It consists of a text area that grows on along with the content, and a send button to send message.
Expand Down Expand Up @@ -86,18 +86,16 @@ class MessageInputElement extends ElementMixin(ThemableMixin(PolymerElement)) {
overflow: hidden;
flex-shrink: 0;
}
vaadin-text-area {
align-self: stretch;
flex-grow: 1;
padding: 0;
}
vaadin-button {
flex-shrink: 0;
margin: 0;
}
</style>
<vaadin-text-area disabled="[[disabled]]" value="{{value}}" placeholder="[[i18n.message]]"></vaadin-text-area>
<vaadin-button disabled="[[disabled]]" theme="primary contained" on-click="__submit">[[i18n.send]]</vaadin-button>
<vaadin-message-input-text-area
disabled="[[disabled]]"
value="{{value}}"
placeholder="[[i18n.message]]"
on-enter="__submit"
></vaadin-message-input-text-area>
<vaadin-message-input-button disabled="[[disabled]]" theme="primary contained" on-click="__submit"
>[[i18n.send]]</vaadin-message-input-button
>
`;
}

Expand All @@ -109,26 +107,6 @@ class MessageInputElement extends ElementMixin(ThemableMixin(PolymerElement)) {
return '2.0.0-alpha1';
}

ready() {
super.ready();

const textarea = this.__inputElement;
textarea.removeAttribute('aria-labelledby');

// Set initial height to one row
textarea.setAttribute('rows', 1);
textarea.style.minHeight = '0';

// Add enter handling for text area.
textarea.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
e.stopPropagation();
this.__submit();
}
});
}

/**
* Submits the current value as an custom event named 'submit'.
* It also clears the text input and refocuses it for sending another message.
Expand All @@ -140,19 +118,11 @@ class MessageInputElement extends ElementMixin(ThemableMixin(PolymerElement)) {
this.dispatchEvent(new CustomEvent('submit', { detail: { value: this.value } }));
this.value = '';
}
this.shadowRoot.querySelector('vaadin-text-area').focus();
this.shadowRoot.querySelector('vaadin-message-input-text-area').focus();
}

__i18nChanged(i18n) {
// Set aria-label to provide an accessible name for the labelless input
this.__inputElement.setAttribute('aria-label', i18n.message);
}

/**
* Gets the native `<textarea>` inside the `<vaadin-text-area>`.
*/
get __inputElement() {
return this.shadowRoot.querySelector('vaadin-text-area').inputElement;
this.shadowRoot.querySelector('vaadin-message-input-text-area')._setAriaLabel(i18n.message);
}
}

Expand Down
11 changes: 3 additions & 8 deletions src/vaadin-message.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { ElementMixin } from '@vaadin/vaadin-element-mixin/vaadin-element-mixin.js';
import '@vaadin/vaadin-avatar/src/vaadin-avatar.js';
import './vaadin-message-avatar.js';
/**
* `<vaadin-message>` is a Web Component for showing a single message with an author, message and time.
*
Expand Down Expand Up @@ -111,11 +111,6 @@ class MessageElement extends ElementMixin(ThemableMixin(PolymerElement)) {
display: none !important;
}
vaadin-avatar {
--vaadin-avatar-outline-width: 0px;
flex-shrink: 0;
}
[part='content'] {
display: flex;
flex-direction: column;
Expand All @@ -137,15 +132,15 @@ class MessageElement extends ElementMixin(ThemableMixin(PolymerElement)) {
white-space: pre-wrap;
}
</style>
<vaadin-avatar
<vaadin-message-avatar
part="avatar"
name="[[userName]]"
abbr="[[userAbbr]]"
img="[[userImg]]"
color-index="[[userColorIndex]]"
tabindex="-1"
aria-hidden="true"
></vaadin-avatar>
></vaadin-message-avatar>
<div part="content">
<div part="header">
<span part="name">[[userName]]</span>
Expand Down
4 changes: 2 additions & 2 deletions test/message-input.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ describe('message-input', () => {

beforeEach(() => {
messageInput = fixtureSync('<vaadin-message-input></vaadin-message-input>');
textArea = messageInput.shadowRoot.querySelector('vaadin-text-area');
button = messageInput.shadowRoot.querySelector('vaadin-button');
textArea = messageInput.shadowRoot.querySelector('vaadin-message-input-text-area');
button = messageInput.shadowRoot.querySelector('vaadin-message-input-button');
});

it('should have a valid version number', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/message.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('message', () => {
root.style.setProperty('--vaadin-user-color-2', 'blue');

message = fixtureSync('<vaadin-message>Hello</vaadin-message>');
avatar = message.shadowRoot.querySelector('vaadin-avatar');
avatar = message.shadowRoot.querySelector('vaadin-message-avatar');
name = message.shadowRoot.querySelector('[part="name"]');
content = message.shadowRoot.querySelector('[part="content"]');
time = message.shadowRoot.querySelector('[part="time"]');
Expand Down
Binary file modified test/visual/screens/vaadin-message/material-message-list-ltr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions theme/lumo/vaadin-message-avatar-styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
import '@vaadin/vaadin-avatar/theme/lumo/vaadin-avatar-styles.js';

registerStyles(
'vaadin-message-avatar',
css`
:host {
margin-right: calc(var(--lumo-space-m) - var(--vaadin-avatar-outline-width));
margin-top: calc(var(--lumo-space-s) - var(--vaadin-avatar-outline-width));
}
:host([dir='rtl']) {
margin-left: calc(var(--lumo-space-m) - var(--vaadin-avatar-outline-width));
margin-right: calc(var(--vaadin-avatar-outline-width) * -1);
}
`,
{ moduleId: 'lumo-message-avatar' }
);
2 changes: 2 additions & 0 deletions theme/lumo/vaadin-message-avatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './vaadin-message-avatar-styles.js';
import '../../src/vaadin-message-avatar.js';
4 changes: 4 additions & 0 deletions theme/lumo/vaadin-message-input-button-styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
import '@vaadin/vaadin-button/theme/lumo/vaadin-button-styles.js';

registerStyles('vaadin-message-input-button', css``, { moduleId: 'lumo-message-input-button' });
2 changes: 2 additions & 0 deletions theme/lumo/vaadin-message-input-button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './vaadin-message-input-button-styles.js';
import '../../src/vaadin-message-input-button.js';
11 changes: 1 addition & 10 deletions theme/lumo/vaadin-message-input-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,15 @@ import '@vaadin/vaadin-lumo-styles/color.js';
import '@vaadin/vaadin-lumo-styles/sizing.js';
import '@vaadin/vaadin-lumo-styles/spacing.js';
import '@vaadin/vaadin-lumo-styles/style.js';
import './vaadin-message-input-text-area-styles.js';
import '@vaadin/vaadin-button/theme/lumo/vaadin-button-styles.js';
import '@vaadin/vaadin-text-field/theme/lumo/vaadin-text-area-styles.js';
import '@vaadin/vaadin-text-field/theme/lumo/vaadin-text-field-styles.js';

registerStyles(
'vaadin-message-input',
css`
:host {
padding: var(--lumo-space-s) var(--lumo-space-m);
}
vaadin-text-area {
margin: 0 var(--lumo-space-s) 0 0;
}
:host([dir='rtl']) vaadin-text-area {
margin: 0 0 0 var(--lumo-space-s);
}
`,
{ moduleId: 'lumo-message-input' }
);
17 changes: 17 additions & 0 deletions theme/lumo/vaadin-message-input-text-area-styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { registerStyles, css } from '@vaadin/vaadin-themable-mixin/register-styles.js';
import '@vaadin/vaadin-text-field/theme/lumo/vaadin-text-area-styles.js';
import '@vaadin/vaadin-text-field/theme/lumo/vaadin-text-field-styles.js';

registerStyles(
'vaadin-message-input-text-area',
css`
:host {
margin: 0 var(--lumo-space-s) 0 0;
}
:host([dir='rtl']) {
margin: 0 0 0 var(--lumo-space-s);
}
`,
{ moduleId: 'lumo-message-input-text-area' }
);
2 changes: 2 additions & 0 deletions theme/lumo/vaadin-message-input-text-area.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './vaadin-message-input-text-area-styles.js';
import '../../src/vaadin-message-input-text-area.js';
2 changes: 2 additions & 0 deletions theme/lumo/vaadin-message-input.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
import './vaadin-message-input-styles.js';
import './vaadin-message-input-text-area.js';
import './vaadin-message-input-button.js';
import '../../src/vaadin-message-input.js';
Loading

0 comments on commit 68ffc34

Please sign in to comment.