Initial commit
This commit is contained in:
25
src/components/app-home/app-home.css
Normal file
25
src/components/app-home/app-home.css
Normal file
@@ -0,0 +1,25 @@
|
||||
.app-home {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
background: #5851ff;
|
||||
color: white;
|
||||
margin: 8px;
|
||||
border: none;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
padding: 16px 20px;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1), 0 3px 6px rgba(0, 0, 0, 0.08);
|
||||
outline: 0;
|
||||
letter-spacing: 0.04em;
|
||||
transition: all 0.15s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(1px);
|
||||
}
|
||||
19
src/components/app-home/app-home.e2e.ts
Normal file
19
src/components/app-home/app-home.e2e.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
describe('app-home', () => {
|
||||
it('renders', async () => {
|
||||
const page = await newE2EPage();
|
||||
await page.setContent('<app-home></app-home>');
|
||||
|
||||
const element = await page.find('app-home');
|
||||
expect(element).toHaveClass('hydrated');
|
||||
});
|
||||
|
||||
it('contains a "Profile Page" button', async () => {
|
||||
const page = await newE2EPage();
|
||||
await page.setContent('<app-home></app-home>');
|
||||
|
||||
const element = await page.find('app-home >>> button');
|
||||
expect(element.textContent).toEqual('Profile page');
|
||||
});
|
||||
});
|
||||
23
src/components/app-home/app-home.tsx
Normal file
23
src/components/app-home/app-home.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Component, h } from '@stencil/core';
|
||||
|
||||
@Component({
|
||||
tag: 'app-home',
|
||||
styleUrl: 'app-home.css',
|
||||
shadow: true,
|
||||
})
|
||||
export class AppHome {
|
||||
render() {
|
||||
return (
|
||||
<div class="app-home">
|
||||
<p>
|
||||
Welcome to the Stencil App Starter. You can use this starter to build entire apps all with web components using Stencil! Check out our docs on{' '}
|
||||
<a href="https://stenciljs.com">stenciljs.com</a> to get started.
|
||||
</p>
|
||||
|
||||
<stencil-route-link url="/profile/stencil">
|
||||
<button>Profile page</button>
|
||||
</stencil-route-link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
3
src/components/app-profile/app-profile.css
Normal file
3
src/components/app-profile/app-profile.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.app-profile {
|
||||
padding: 10px;
|
||||
}
|
||||
27
src/components/app-profile/app-profile.e2e.ts
Normal file
27
src/components/app-profile/app-profile.e2e.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
describe('app-profile', () => {
|
||||
it('renders', async () => {
|
||||
const page = await newE2EPage();
|
||||
await page.setContent('<app-profile></app-profile>');
|
||||
|
||||
const element = await page.find('app-profile');
|
||||
expect(element).toHaveClass('hydrated');
|
||||
});
|
||||
|
||||
it('displays the specified name', async () => {
|
||||
const page = await newE2EPage({ url: '/profile/joseph' });
|
||||
|
||||
const profileElement = await page.find('app-root >>> app-profile');
|
||||
const element = profileElement.shadowRoot.querySelector('div');
|
||||
expect(element.textContent).toContain('Hello! My name is Joseph.');
|
||||
});
|
||||
|
||||
// it('includes a div with the class "app-profile"', async () => {
|
||||
// const page = await newE2EPage({ url: '/profile/joseph' });
|
||||
|
||||
// I would like to use a selector like this above, but it does not seem to work
|
||||
// const element = await page.find('app-root >>> app-profile >>> div');
|
||||
// expect(element).toHaveClass('app-profile');
|
||||
// });
|
||||
});
|
||||
46
src/components/app-profile/app-profile.spec.ts
Normal file
46
src/components/app-profile/app-profile.spec.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { AppProfile } from './app-profile';
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
|
||||
describe('app-profile', () => {
|
||||
describe('normalization', () => {
|
||||
it('returns a blank string if the name is undefined', async () => {
|
||||
const { rootInstance } = await newSpecPage({
|
||||
components: [AppProfile],
|
||||
html: '<app-profile></app-profile>',
|
||||
});
|
||||
expect(rootInstance.normalize(undefined)).toEqual('');
|
||||
});
|
||||
|
||||
it('returns a blank string if the name is null', async () => {
|
||||
const { rootInstance } = await newSpecPage({
|
||||
components: [AppProfile],
|
||||
html: '<app-profile></app-profile>',
|
||||
});
|
||||
expect(rootInstance.normalize(null)).toEqual('');
|
||||
});
|
||||
|
||||
it('capitalizes the first letter', async () => {
|
||||
const { rootInstance } = await newSpecPage({
|
||||
components: [AppProfile],
|
||||
html: '<app-profile></app-profile>',
|
||||
});
|
||||
expect(rootInstance.normalize('quincy')).toEqual('Quincy');
|
||||
});
|
||||
|
||||
it('lower-cases the following letters', async () => {
|
||||
const { rootInstance } = await newSpecPage({
|
||||
components: [AppProfile],
|
||||
html: '<app-profile></app-profile>',
|
||||
});
|
||||
expect(rootInstance.normalize('JOSEPH')).toEqual('Joseph');
|
||||
});
|
||||
|
||||
it('handles single letter names', async () => {
|
||||
const { rootInstance } = await newSpecPage({
|
||||
components: [AppProfile],
|
||||
html: '<app-profile></app-profile>',
|
||||
});
|
||||
expect(rootInstance.normalize('q')).toEqual('Q');
|
||||
});
|
||||
});
|
||||
});
|
||||
28
src/components/app-profile/app-profile.tsx
Normal file
28
src/components/app-profile/app-profile.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Component, Prop, h } from '@stencil/core';
|
||||
import { MatchResults } from '@stencil/router';
|
||||
|
||||
@Component({
|
||||
tag: 'app-profile',
|
||||
styleUrl: 'app-profile.css',
|
||||
shadow: true,
|
||||
})
|
||||
export class AppProfile {
|
||||
@Prop() match: MatchResults;
|
||||
|
||||
normalize(name: string): string {
|
||||
if (name) {
|
||||
return name.substr(0, 1).toUpperCase() + name.substr(1).toLowerCase();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.match && this.match.params.name) {
|
||||
return (
|
||||
<div class="app-profile">
|
||||
<p>Hello! My name is {this.normalize(this.match.params.name)}. My name was passed in through a route param!</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
src/components/app-root/app-root.css
Normal file
15
src/components/app-root/app-root.css
Normal file
@@ -0,0 +1,15 @@
|
||||
header {
|
||||
background: #5851ff;
|
||||
color: white;
|
||||
height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.4rem;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
padding: 0 12px;
|
||||
}
|
||||
17
src/components/app-root/app-root.e2e.ts
Normal file
17
src/components/app-root/app-root.e2e.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
describe('app-root', () => {
|
||||
it('renders', async () => {
|
||||
const page = await newE2EPage({ url: '/' });
|
||||
|
||||
const element = await page.find('app-root');
|
||||
expect(element).toHaveClass('hydrated');
|
||||
});
|
||||
|
||||
it('renders the title', async () => {
|
||||
const page = await newE2EPage({ url: '/' });
|
||||
|
||||
const element = await page.find('app-root >>> h1');
|
||||
expect(element.textContent).toEqual('Stencil App Starter');
|
||||
});
|
||||
});
|
||||
27
src/components/app-root/app-root.tsx
Normal file
27
src/components/app-root/app-root.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Component, h } from '@stencil/core';
|
||||
|
||||
@Component({
|
||||
tag: 'app-root',
|
||||
styleUrl: 'app-root.css',
|
||||
shadow: true,
|
||||
})
|
||||
export class AppRoot {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<header>
|
||||
<h1>Stencil App Starter</h1>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<stencil-router>
|
||||
<stencil-route-switch scrollTopOffset={0}>
|
||||
<stencil-route url="/" component="app-home" exact={true} />
|
||||
<stencil-route url="/profile/:name" component="app-profile" />
|
||||
</stencil-route-switch>
|
||||
</stencil-router>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user