Skip to content

Commit

Permalink
experiment: add LitElement based version of message-input (#8258)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan authored Dec 3, 2024
1 parent 781a58e commit ea37190
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 13 deletions.
3 changes: 2 additions & 1 deletion packages/message-input/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"@vaadin/text-area": "24.6.0-beta1",
"@vaadin/vaadin-lumo-styles": "24.6.0-beta1",
"@vaadin/vaadin-material-styles": "24.6.0-beta1",
"@vaadin/vaadin-themable-mixin": "24.6.0-beta1"
"@vaadin/vaadin-themable-mixin": "24.6.0-beta1",
"lit": "^3.0.0"
},
"devDependencies": {
"@vaadin/chai-plugins": "24.6.0-beta1",
Expand Down
1 change: 1 addition & 0 deletions packages/message-input/src/vaadin-lit-message-input.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './vaadin-message-input.js';
69 changes: 69 additions & 0 deletions packages/message-input/src/vaadin-lit-message-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* @license
* Copyright (c) 2021 - 2024 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import '@vaadin/button/src/vaadin-lit-button.js';
import '@vaadin/text-area/src/vaadin-lit-text-area.js';
import { css, html, LitElement } from 'lit';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { MessageInputMixin } from './vaadin-message-input-mixin.js';

/**
* LitElement based version of `<vaadin-message-input>` web component.
*
* ## Disclaimer
*
* This component is an experiment and not yet a part of Vaadin platform.
* There is no ETA regarding specific Vaadin version where it'll land.
* Feel free to try this code in your apps as per Apache 2.0 license.
*/
class MessageInput extends MessageInputMixin(ElementMixin(ThemableMixin(PolylitMixin(LitElement)))) {
static get is() {
return 'vaadin-message-input';
}

static get styles() {
return css`
:host {
align-items: flex-start;
box-sizing: border-box;
display: flex;
max-height: 50vh;
overflow: hidden;
flex-shrink: 0;
}
:host([hidden]) {
display: none !important;
}
::slotted([slot='button']) {
flex-shrink: 0;
}
::slotted([slot='textarea']) {
align-self: stretch;
flex-grow: 1;
}
`;
}

/** @protected */
render() {
return html`
<slot name="textarea"></slot>
<slot name="button"></slot>
<slot name="tooltip"></slot>
`;
}
}

defineCustomElement(MessageInput);

export { MessageInput };
22 changes: 15 additions & 7 deletions packages/message-input/src/vaadin-message-input-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const MessageInputMixin = (superClass) =>
value: {
type: String,
value: '',
sync: true,
},

/**
Expand All @@ -45,6 +46,7 @@ export const MessageInputMixin = (superClass) =>
*/
i18n: {
type: Object,
sync: true,
value: () => ({
send: 'Send',
message: 'Message',
Expand All @@ -59,16 +61,19 @@ export const MessageInputMixin = (superClass) =>
type: Boolean,
value: false,
reflectToAttribute: true,
sync: true,
},

/** @private */
_button: {
type: Object,
sync: true,
},

/** @private */
_textArea: {
type: Object,
sync: true,
},
};
}
Expand Down Expand Up @@ -111,8 +116,16 @@ export const MessageInputMixin = (superClass) =>
}
});

// With Lit version, input element renders asynchronously and it will
// override the `rows` attribute set to `1` in the `minRows` observer.
// Workaround: perform update twice to run the observer synchronously.
// TODO: needs https://github.com/vaadin/web-components/pull/8168
if (textarea.performUpdate) {
textarea.performUpdate();
textarea.performUpdate();
}

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

// Set initial height to one row
input.setAttribute('rows', 1);
Expand Down Expand Up @@ -149,12 +162,7 @@ export const MessageInputMixin = (superClass) =>

const message = i18n.message;
textArea.placeholder = message;

if (message) {
textArea.inputElement.setAttribute('aria-label', message);
} else {
textArea.inputElement.removeAttribute('aria-label');
}
textArea.accessibleName = message;
}
}

Expand Down
2 changes: 2 additions & 0 deletions packages/message-input/test/message-input-lit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '../src/vaadin-lit-message-input.js';
import './message-input.common.js';
2 changes: 2 additions & 0 deletions packages/message-input/test/message-input-polymer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import '../src/vaadin-message-input.js';
import './message-input.common.js';
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { expect } from '@vaadin/chai-plugins';
import { enterKeyDown, fixtureSync } from '@vaadin/testing-helpers';
import { enterKeyDown, fixtureSync, nextFrame, nextRender } from '@vaadin/testing-helpers';
import sinon from 'sinon';
import '../vaadin-message-input.js';

describe('message-input', () => {
let messageInput, textArea, button;

beforeEach(() => {
beforeEach(async () => {
messageInput = fixtureSync('<vaadin-message-input></vaadin-message-input>');
await nextRender();
textArea = messageInput.querySelector('vaadin-text-area');
button = messageInput.querySelector('vaadin-button');
});
Expand Down Expand Up @@ -102,13 +102,15 @@ describe('message-input', () => {
expect(textArea.placeholder).to.be.equal('Viesti');
});

it('should translate aria-label', () => {
it('should translate aria-label', async () => {
messageInput.i18n = { ...messageInput.i18n, message: 'Viesti' };
await nextFrame();
expect(textArea.inputElement.getAttribute('aria-label')).to.be.equal('Viesti');
});

it('should remove aria-label attribute when translation not defined', () => {
it('should remove aria-label attribute when translation not defined', async () => {
messageInput.i18n = {};
await nextFrame();
expect(textArea.inputElement.hasAttribute('aria-label')).to.equal(false);
});
});
Expand Down
4 changes: 4 additions & 0 deletions packages/message-input/theme/lumo/vaadin-lit-message-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import '@vaadin/button/theme/lumo/vaadin-lit-button.js';
import '@vaadin/text-area/theme/lumo/vaadin-lit-text-area.js';
import './vaadin-message-input-styles.js';
import '../../src/vaadin-lit-message-input.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import '@vaadin/button/theme/material/vaadin-lit-button.js';
import '@vaadin/text-area/theme/material/vaadin-lit-text-area.js';
import './vaadin-message-input-styles.js';
import '../../src/vaadin-lit-message-input.js';
1 change: 1 addition & 0 deletions packages/message-input/vaadin-lit-message-input.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src/vaadin-message-input.js';
2 changes: 2 additions & 0 deletions packages/message-input/vaadin-lit-message-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './theme/lumo/vaadin-lit-message-input.js';
export * from './src/vaadin-lit-message-input.js';

0 comments on commit ea37190

Please sign in to comment.