diff --git a/src/modules/recipe/apiSpread/__tests__/apiSpread.test.js b/src/modules/recipe/apiSpread/__tests__/apiSpread.test.js new file mode 100644 index 00000000..c09c09c5 --- /dev/null +++ b/src/modules/recipe/apiSpread/__tests__/apiSpread.test.js @@ -0,0 +1,78 @@ +import { createElement } from 'lwc'; +import ApiSpread from 'recipe/apiSpread'; + +describe('recipe-api-spread', () => { + afterEach(() => { + // The jsdom instance is shared across test cases in a single file so reset the DOM + while (document.body.firstChild) { + document.body.removeChild(document.body.firstChild); + } + }); + + // Helper function to wait until the microtask queue is empty. + async function flushPromises() { + return Promise.resolve(); + } + + // Helper function to set values in the ui-input elements + function setInputElementValues(element, firstName, lastName) { + element.shadowRoot.querySelectorAll('ui-input').forEach((input) => { + if (firstName && input.name === 'firstName') { + input.value = firstName; + input.dispatchEvent(new CustomEvent('change')); + } else if (lastName && input.name === 'lastName') { + input.value = lastName; + input.dispatchEvent(new CustomEvent('change')); + } + }); + } + + it('renders recipe-child component with default values', () => { + // Create component + const element = createElement('recipe-api-spread', { + is: ApiSpread + }); + document.body.appendChild(element); + + // Query child component + const childEl = element.shadowRoot.querySelector('recipe-child'); + expect(childEl).not.toBeNull(); + + // Validation for default values passed down to child component + expect(childEl.firstName).toBe('Amy'); + expect(childEl.lastName).toBe('Taylor'); + }); + + it('changes the value of the recipe-child component based on user input', async () => { + // Create component + const element = createElement('recipe-api-spread', { + is: ApiSpread + }); + document.body.appendChild(element); + + // Set values in the ui-input elements + setInputElementValues(element, 'Jennifer', 'Wu'); + + // Query child component + const childEl = element.shadowRoot.querySelector('recipe-child'); + expect(childEl).not.toBeNull(); + + // Wait for any asynchronous DOM updates + await flushPromises(); + + // Validation for values of lwc spread properties passed down to child component + expect(childEl.firstName).toBe('Jennifer'); + expect(childEl.lastName).toBe('Wu'); + }); + + it('is accessible', async () => { + // Create component + const element = createElement('recipe-api-spread', { + is: ApiSpread + }); + document.body.appendChild(element); + + // Check accessibility + await expect(element).toBeAccessible(); + }); +}); diff --git a/src/modules/recipe/apiSpread/apiSpread.css b/src/modules/recipe/apiSpread/apiSpread.css new file mode 100644 index 00000000..1f1beb1d --- /dev/null +++ b/src/modules/recipe/apiSpread/apiSpread.css @@ -0,0 +1,18 @@ +recipe-child { + position: relative; + border: solid 1px #ecebea; + border-radius: 4px; + display: block; + padding: 14px 8px 8px 8px; + margin-top: 16px; +} + +recipe-child:before { + content: 'recipe-child'; + color: #dddbda; + position: absolute; + top: -16px; + left: 4px; + background-color: #ffffff; + padding: 0 4px; +} diff --git a/src/modules/recipe/apiSpread/apiSpread.html b/src/modules/recipe/apiSpread/apiSpread.html new file mode 100644 index 00000000..e11f7daf --- /dev/null +++ b/src/modules/recipe/apiSpread/apiSpread.html @@ -0,0 +1,25 @@ + diff --git a/src/modules/recipe/apiSpread/apiSpread.js b/src/modules/recipe/apiSpread/apiSpread.js new file mode 100644 index 00000000..999c4f80 --- /dev/null +++ b/src/modules/recipe/apiSpread/apiSpread.js @@ -0,0 +1,16 @@ +import { LightningElement, track } from 'lwc'; + +export default class ApiSpread extends LightningElement { + @track props = { + firstName: 'Amy', + lastName: 'Taylor' + }; + + handleFirstNameChange(event) { + this.props.firstName = event.target.value; + } + + handleLastNameChange(event) { + this.props.lastName = event.target.value; + } +} diff --git a/src/modules/recipe/child/child.html b/src/modules/recipe/child/child.html new file mode 100644 index 00000000..c35b8c96 --- /dev/null +++ b/src/modules/recipe/child/child.html @@ -0,0 +1 @@ + diff --git a/src/modules/recipe/child/child.js b/src/modules/recipe/child/child.js new file mode 100644 index 00000000..98a9c918 --- /dev/null +++ b/src/modules/recipe/child/child.js @@ -0,0 +1,10 @@ +import { LightningElement, api } from 'lwc'; + +export default class Child extends LightningElement { + @api firstName; + @api lastName; + + get fullName() { + return `${this.firstName} ${this.lastName}`; + } +} diff --git a/src/modules/ui/app/app.html b/src/modules/ui/app/app.html index 99a90812..6675d224 100644 --- a/src/modules/ui/app/app.html +++ b/src/modules/ui/app/app.html @@ -33,6 +33,7 @@ +