Skip to content

Commit

Permalink
feat(description): expand it with crafted sw items (#9)
Browse files Browse the repository at this point in the history
* feat(description): expand description with items crafted
* fix(description): add link URL to SSO
* feat(description): add security in mind
* feat(description): add HTTP REST APIs
* feat(description): static collapsible list
* perf: inline .sr-only to avoid layout flash / shift
* feat(description): add collapsible animations
* feat(description): light theme link colors
* feat(description): do not collapse non-collapsible lists
* feat(description): expanded when no JS
* refactor: explicit noscript visibility/display utils
* feat(description): move title into profile
* feat: switch to Helvetica as it's more universal
  • Loading branch information
davidlj95 authored Sep 28, 2023
1 parent 658c6d7 commit 2612f9e
Show file tree
Hide file tree
Showing 26 changed files with 805 additions and 170 deletions.
2 changes: 2 additions & 0 deletions src/app/about/_about-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
@use "profile-picture/profile-picture-theme";
@use "contact-social-icons/contact-social-icons-theme";
@use "contact-traditional-icons/contact-traditional-icons-theme";
@use "description/description-theme";

@mixin color($theme) {
app-about {
@include profile-picture-theme.color($theme);
@include contact-traditional-icons-theme.color($theme);
@include contact-social-icons-theme.color($theme);
@include description-theme.color($theme);
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/app/about/about.component.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<section class="about">
<section>
<div class="profile">
<app-profile-picture></app-profile-picture>
<h1>
<span aria-hidden="true">
<span>{{ realName }}</span>
<span class="visible-header" aria-hidden="true">
<span class="real-name">{{ realName }}</span>
<code>@{{ nickname }}</code>
</span>
<!-- Duplicated for accessibility
Expand All @@ -13,10 +13,11 @@ <h1>
{{ realName }} @{{ nickname }}
</span>
</h1>
<h2>{{ title }}</h2>
<div class="contacts">
<app-contact-traditional-icons></app-contact-traditional-icons>
<app-contact-social-icons></app-contact-social-icons>
</div>
</div>
<app-description></app-description>
<app-description [line]="rootLine"></app-description>
</section>
55 changes: 26 additions & 29 deletions src/app/about/about.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,52 +4,49 @@
@use "breakpoints";

:host {
position: absolute;
width: 100%;
min-height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;

section {
position: absolute;
width: 100%;
min-height: 100%;
display: flex;
flex-direction: row;
justify-content: center;

@include breakpoints.xs {
flex-direction: column;
align-items: center;
}

> * {
padding: paddings.$m;
}
flex-direction: column;
gap: margins.$l;
padding: paddings.$m paddings.$l;

.profile {
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
gap: margins.$m;
gap: margins.$s;

@include breakpoints.xs {
flex-direction: row;
align-items: center;
h1 > span.visible-header {
display: flex;
flex-direction: column;

.real-name {
font-size: 1.75rem;
font-weight: bold;
}
code {
font-size: 1.5rem;
}
}

h1 > span {
h2 {
font-size: 1.5rem;
display: flex;
flex-direction: column;
}

.contacts {
display: flex;
gap: margins.$m;
flex-wrap: wrap;
flex-direction: column;

@include breakpoints.xs {
flex-basis: 100%;
justify-content: center;
flex-direction: row;
}
flex-direction: row;
margin-top: margins.$s;
}
}
}
Expand Down
16 changes: 11 additions & 5 deletions src/app/about/about.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ describe('AboutComponent', () => {
let component: AboutComponent;
let fixture: ComponentFixture<AboutComponent>;
const fakeMetadata: Metadata = ({
nickname: 'bar',
realName: 'Foo',
} as Pick<Metadata, 'nickname' | 'realName'>) as Metadata;
nickname: 'Fake nickname',
realName: 'Fake real name',
title: 'Fake title',
} as Pick<Metadata, 'nickname' | 'realName' | 'title'>) as Metadata;

beforeEach(() => {
TestBed.configureTestingModule({
Expand All @@ -43,16 +44,21 @@ describe('AboutComponent', () => {
expect(component).toBeTruthy();
});

it('should display real name in header', () => {
it('should display real name in primary header', () => {
const h1 = fixture.debugElement.query(By.css('h1'));
expect(h1.nativeElement.textContent).toContain(fakeMetadata.realName);
})

it('should display nickname preceded by \'@\' in header', () => {
it('should display nickname preceded by \'@\' in primary header', () => {
const h1 = fixture.debugElement.query(By.css('h1'));
expect(h1.nativeElement.textContent).toContain(`@${fakeMetadata.nickname}`);
})

it('should display title in secondary header', () => {
const h2 = fixture.debugElement.query(By.css('h2'));
expect(h2.nativeElement.textContent).toEqual(fakeMetadata.title);
})

ensureHasComponents(() => fixture,
ProfilePictureComponent,
ContactTraditionalIconsComponent,
Expand Down
11 changes: 8 additions & 3 deletions src/app/about/about.component.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { Component, Inject } from '@angular/core';
import { METADATA } from '../common/injection-tokens';
import { Metadata } from '../metadata';
import { DescriptionLine, Metadata } from '../metadata';

@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.scss'],
})
export class AboutComponent {
public realName = this.metadata.realName;
public nickname = this.metadata.nickname;
public readonly realName = this.metadata.realName
public readonly nickname = this.metadata.nickname
public readonly title = this.metadata.title
public readonly rootLine = new DescriptionLine(
undefined,
this.metadata.descriptionLines
)

constructor(
@Inject(METADATA) private metadata: Metadata,
Expand Down
13 changes: 13 additions & 0 deletions src/app/about/description/_description-theme.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@use "sass:color";
@use "sass:map";

@mixin color($theme) {
$text-palette: map.get($theme, text);
$primary: map.get($text-palette, primary);

app-description {
a {
text-decoration-color: color.adjust($primary, $alpha: -0.75);
}
}
}
30 changes: 23 additions & 7 deletions src/app/about/description/description.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
<h2 *ngFor="let descriptionLine of descriptionLines">
<span aria-hidden="true">
<span class="material-symbols-outlined">{{ descriptionLine.symbol }}</span>
<span [innerHTML]="descriptionLine.text"></span>
</span>
<span class="sr-only" [innerHtml]="descriptionLine.text"></span>
</h2>
<ng-container *ngIf="!isCollapsible; else collapsibleTemplate">
<div class="data" *ngIf="line.data">
<ng-container [ngTemplateOutlet]="dataTemplate"></ng-container>
</div>
</ng-container>
<ng-template #collapsibleTemplate>
<button class="data" type="button" [attr.aria-expanded]="isExpanded" [attr.aria-controls]="sluggedId"
(click)="isExpanded ? this.collapse() : this.expand()"
>
<span class="caret displayNoneIfNoScript" aria-hidden="true">{{ isExpanded ? config.expandedIcon : config.collapsedIcon }}</span>
<ng-container [ngTemplateOutlet]="dataTemplate"></ng-container>
</button>
</ng-template>
<ng-template #dataTemplate>
<span class="symbol material-symbols-outlined" aria-hidden="true" *ngIf="line.data">{{ line.data.symbol }}</span>
<span class="content" [innerHtml]="sanitizer.bypassSecurityTrustHtml(line.data?.html ?? '')"></span>
</ng-template>
<ul *ngIf="line.children.length" [attr.id]="sluggedId" [@expanded]="isCollapsible ? isExpanded : true">
<li *ngFor="let line of line.children">
<app-description [line]="line" [depth]="depth+1">
</app-description>
</li>
</ul>
73 changes: 63 additions & 10 deletions src/app/about/description/description.component.scss
Original file line number Diff line number Diff line change
@@ -1,21 +1,74 @@
@use "margins";
@use "paddings";

:host {
display: flex;
flex-direction: column;
justify-content: center;
gap: margins.$s;
&.hidden {
visibility: hidden;
}

h2 > span {
font-size: 1.1rem;
text-align: left;
width: fit-content;
ul {
display: flex;
flex-direction: column;
gap: margins.$m;
}

// Indentation for nested lists
ul ul {
margin-left: margins.$l;
}

ul ul > li:first-child {
margin-top: margins.$m;
}

.data {
display: flex;
flex-direction: row;
align-items: center;
word-break: break-word;
font-size: 1.5rem;
gap: margins.$s;
text-align: left;

> span {
font-size: 1em;
// If we move it outside this selector, conflicts with root <a> styles
::ng-deep a {
text-decoration-line: underline;
text-decoration-thickness: 1px;
}
}

.material-symbols-outlined {
font-size: 1em;
font-variation-settings: 'FILL' 1,
'wght' 700,
'GRAD' 200,
'opsz' 24
}

button {
cursor: pointer;
background-color: transparent;
border: none;
color: inherit;
font-family: inherit;
}

.caret {
font-size: .5em;
width: .75em;
}

// Content-specific customizations
::ng-deep a.craft {
text-decoration-line: underline;
text-decoration-color: currentColor;
}

.data[aria-expanded="false"] + ul {
overflow: hidden;
}

.data[aria-expanded] + ul .data {
font-size: 1.25rem;
}
}
Loading

0 comments on commit 2612f9e

Please sign in to comment.