Further experiments with the meal planning page

This commit is contained in:
Z. Charles Dziura 2025-06-09 17:37:02 -04:00
parent 4e62506d13
commit 2c5e751e75
12 changed files with 141 additions and 14 deletions

View file

@ -0,0 +1,7 @@
<ng-content select="header"></ng-content>
<div class="content">
<ng-content></ng-content>
</div>
<ng-content select="footer"></ng-content>

View file

@ -0,0 +1,18 @@
:host {
background-color: var(--color-primary-container);
border: 1px solid var(--color-outline);
border-radius: 0.2em;
color: var(--color-on-primary-container);
display: inline-grid;
font-size: 2.0em;
grid-template-areas:
"head"
"body"
"foot";
grid-template-rows: min-content auto min-content;
padding: 1.2em;
}
header {
font-size: 1.6em;
}

View file

@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { Card } from './card';
describe('Card', () => {
let component: Card;
let fixture: ComponentFixture<Card>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [Card],
}).compileComponents();
fixture = TestBed.createComponent(Card);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,8 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-card',
templateUrl: './card.html',
styleUrl: './card.scss',
})
export class Card {}

View file

@ -1,3 +1,15 @@
<header>
{{ name }}
</header>
<app-card>
<header>
<h2>{{ name }}</h2>
</header>
@if (foods!!.length > 0) {
} @else {
No foods planned. Click the button below to add some!
}
<footer>
<button>Add Food</button>
</footer>
</app-card>

View file

@ -1,8 +1,3 @@
:host {
display: grid;
grid-template-areas:
"head"
"body"
"foot";
grid-template-rows: min-content auto min-content;
padding: 0.8em;
}

View file

@ -1,9 +1,10 @@
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { MealType } from 'models/meal.model';
import { IFood, MealType } from 'models/meal.model';
import { Card } from 'components/card/card';
@Component({
selector: 'app-meal',
imports: [],
imports: [Card],
templateUrl: './meal.html',
styleUrl: './meal.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
@ -11,6 +12,7 @@ import { MealType } from 'models/meal.model';
export class Meal {
@Input() type: MealType | undefined;
@Input('name') _name?: string;
@Input() foods: Array<IFood> | undefined;
get name(): string {
const name = this._name ?? (this.type as string);

View file

@ -1,6 +1,6 @@
<header>Header!</header>
<section class="meal-plan">
@for (meal of meals(); track meal.id) {
<app-meal [type]="meal.type" [name]="meal.name"></app-meal>
<app-meal [type]="meal.type" [name]="meal.name" [foods]="meal.foods"></app-meal>
}
</section>

View file

@ -13,4 +13,5 @@ header {
.meal-plan {
grid-area: "body";
padding-left: 1.8em;
}

View file

@ -1,20 +1,30 @@
@import url('./styles/reset.scss');
@import url('./styles/fonts.scss');
:root {
--astronaut-blue: oklch(0.3303 0.078667 242.1936);
--kashmir-blue: oklch(0.5311 0.0868 244.85);
--periwinkle: oklch(0.9124 0.0439 250.42);
--midnight-blue: oklch(0.3958 0.0893 242.11);
--bossanova: oklch(0.3442 0.0916 323.14);
--trendy-pink: oklch(0.5466 0.0925 325.35);
--zuccini: oklch(0.3235 0.077159 156.9102);
--amazon: oklch(0.5235 0.0882 155.85);
--buccaneer: oklch(0.3435 0.0869 23.74);
--copper-rust: oklch(0.5452 0.0967 23.21);
--zircon: oklch(0.9823 0.008252 271.3302);
--athens-gray: oklch(0.9312 0.0084 271.32);
--gray: oklch(0.5696 0.0117 248.03);
--cadet-blue: oklch(0.8279 0.0112 256.7);
--color-primary: var(--astronaut-blue);
--color-on-primary: white;
--color-primary-container: var(--kashmir-blue);
--color-primary-container: var(--periwinkle);
--color-on-primary-container: var(--midnight-blue);
--color-secondary: var(--bossanova);
--color-on-secondary: white;
@ -29,9 +39,24 @@
--color-surface: var(--zircon);
--color-surface-container: var(--athens-gray);
--color-outline: var(--gray);
--color-outline-variant: var(--cadet-blue);
}
body {
font-family: 'Quicksand', sans-serif;
font-size: 62.5%;
font-weight: 400;
margin: 0;
}
h1, h3, h5 {
font-family: 'Limelight', serif;
font-weight: 400;
}
h2, h4, h6 {
font-family: 'Quicksand', sans-serif;
font-weight: 500;
}

View file

@ -0,0 +1,36 @@
/* latin-ext */
@font-face {
font-family: 'Limelight';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/limelight/v20/XLYkIZL7aopJVbZJHDuoNOlHnnY.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Limelight';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/limelight/v20/XLYkIZL7aopJVbZJHDuoOulH.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
font-family: 'Quicksand';
font-style: normal;
font-weight: 300 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/quicksand/v36/6xKtdSZaM9iE8KbpRA_hJVQNcOM.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Quicksand';
font-style: normal;
font-weight: 300 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/quicksand/v36/6xKtdSZaM9iE8KbpRA_hK1QN.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

View file

@ -15,6 +15,7 @@
"target": "ES2022",
"module": "preserve",
"paths": {
"components/*": ["./src/app/components/*"],
"models/*": ["./src/app/models/*"]
},
},