From cd44b02a8b3650e86bddd7f250a6bcd41918bfb6 Mon Sep 17 00:00:00 2001 From: Frederic Heem Date: Mon, 28 Oct 2024 20:35:32 -0300 Subject: [PATCH] lblog preview card --- examples/blog-preview-card/.gitignore | 24 +++++++ examples/blog-preview-card/.npmrc | 2 + examples/blog-preview-card/README.md | 23 ++++++ examples/blog-preview-card/index.html | 17 +++++ examples/blog-preview-card/package.json | 20 ++++++ .../public/assets/images/favicon-32x32.png | Bin 0 -> 1063 bytes .../assets/images/illustration-article.svg | 1 + .../public/assets/images/image-avatar.webp | Bin 0 -> 2394 bytes .../blog-preview-card/src/blogPreviewCard.ts | 67 ++++++++++++++++++ examples/blog-preview-card/src/main.ts | 20 ++++++ examples/blog-preview-card/src/style.css | 24 +++++++ examples/blog-preview-card/src/vite-env.d.ts | 1 + examples/blog-preview-card/tsconfig.json | 23 ++++++ examples/blog-preview-card/vite.config.js | 9 +++ 14 files changed, 231 insertions(+) create mode 100644 examples/blog-preview-card/.gitignore create mode 100644 examples/blog-preview-card/.npmrc create mode 100644 examples/blog-preview-card/README.md create mode 100644 examples/blog-preview-card/index.html create mode 100644 examples/blog-preview-card/package.json create mode 100644 examples/blog-preview-card/public/assets/images/favicon-32x32.png create mode 100644 examples/blog-preview-card/public/assets/images/illustration-article.svg create mode 100644 examples/blog-preview-card/public/assets/images/image-avatar.webp create mode 100644 examples/blog-preview-card/src/blogPreviewCard.ts create mode 100644 examples/blog-preview-card/src/main.ts create mode 100644 examples/blog-preview-card/src/style.css create mode 100644 examples/blog-preview-card/src/vite-env.d.ts create mode 100644 examples/blog-preview-card/tsconfig.json create mode 100644 examples/blog-preview-card/vite.config.js diff --git a/examples/blog-preview-card/.gitignore b/examples/blog-preview-card/.gitignore new file mode 100644 index 00000000..a547bf36 --- /dev/null +++ b/examples/blog-preview-card/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/examples/blog-preview-card/.npmrc b/examples/blog-preview-card/.npmrc new file mode 100644 index 00000000..6b5f38e8 --- /dev/null +++ b/examples/blog-preview-card/.npmrc @@ -0,0 +1,2 @@ +save-exact = true +package-lock = false diff --git a/examples/blog-preview-card/README.md b/examples/blog-preview-card/README.md new file mode 100644 index 00000000..1006b3f1 --- /dev/null +++ b/examples/blog-preview-card/README.md @@ -0,0 +1,23 @@ +# Frontend Mentor Blog Preview Card + +Here is the implementation in [Bau.js](https://github.com/grucloud/bau) of the [Frontend Mentor Blog Preview Card code challenge](https://www.frontendmentor.io/challenges/blog-preview-card-ckPaj01IcS) + +## Workflow + +Install the dependencies: + +```sh +npm install +``` + +Start a development server: + +```sh +npm run dev +``` + +Build a production version: + +```sh +npm run build +``` diff --git a/examples/blog-preview-card/index.html b/examples/blog-preview-card/index.html new file mode 100644 index 00000000..cf6a300f --- /dev/null +++ b/examples/blog-preview-card/index.html @@ -0,0 +1,17 @@ + + + + + + + Blog Preview Card | FrontendMentor + + +
+ + + diff --git a/examples/blog-preview-card/package.json b/examples/blog-preview-card/package.json new file mode 100644 index 00000000..eb1d289d --- /dev/null +++ b/examples/blog-preview-card/package.json @@ -0,0 +1,20 @@ +{ + "name": "frontendmentor-blog-preview-card", + "private": true, + "version": "0.85.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "devDependencies": { + "typescript": "^5.0.2", + "vite": "^5.2.11" + }, + "dependencies": { + "@grucloud/bau": "^0.85.0", + "@grucloud/bau-css": "^0.85.0", + "@grucloud/bau-ui": "^0.85.0" + } +} diff --git a/examples/blog-preview-card/public/assets/images/favicon-32x32.png b/examples/blog-preview-card/public/assets/images/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..1e2df7f089f46dd930239e418bf13e8e4c1cca0f GIT binary patch literal 1063 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+081EY0-Plzi}!G9Wnr(eF` z|M+F+!xzhMK3;zF(cgdn_B?v|`rD7+fB)V2@MY=EN9|{BEWPpQ{f}RtfBl|!^+Ea3 z%d2iZe)i@2x9`6{eg66V&!4ULpSPU4KJ)Uu^RM22`~BzO$wz&&PyPA(@7<4I`yRjQ zJAZr1#XB#){D-o5+r^Vjdc3)fsquh@R{^yA;Z|8C!Zw`1zDvzMNK{QUFr z^G~yvU&yK5nOnE3q5ts2d8Z#d`S9=G|MwriU%2{m%ii0owp@Sy>dXGuA$NemCsPvS z7YvLEt(>(tKmBDkpML+hROc(RL;oBPGFiO5x8~1ErS?rgb&N^g?k~Ih+L^ zk;M!Q+`=Ht$S`Y;1W=H@#M9T6{SlWiKeL>x)y)*39#2mf#}JFtt&`J}n+ycniko-@ z3;26vOWyCzeS7I$?C$UX{_kIKV}WAF+24(KRQ;Wbm=(hXgpO=b(eBb|byZ~P5M3dt zyDB-nDx`Zw9LoWN-GrY`kHxRfy}Q3KfBxRdclJCv_%N_mL-x0j+x*I+s%JIY&vgg3Y zTes?8j%DMbh5PocynFBNZJq}$w`Q+tKfe6=^y}tkkv_Zb+uQBmSHB|O-+X(*4%OrO zQF%8%OSj*z`t$7X`oHyz%ReTa40^8r7Z}c}C9V-ADTyViR>?)FK#IZ0z|cb1&_LJF zGQ`l-%D~vl*g)IB$jZQAv*1E06b-rgDVb@NxHTN|kz5AU01WSllAy$Lg@U5|w9K4T zg_6pGRE5lfl4J&kiaC!z@o*G|X=t4CKYhmYX%GXmGPhnbx3IFX_hb=fVFi~4lfx;@ u%9}$JPT#n4;>ejJGDp}?H+U@Y(qnifE?Dx($#g2v3I \ No newline at end of file diff --git a/examples/blog-preview-card/public/assets/images/image-avatar.webp b/examples/blog-preview-card/public/assets/images/image-avatar.webp new file mode 100644 index 0000000000000000000000000000000000000000..eb276a74e701e706fc97d21279eca4be8f7f6156 GIT binary patch literal 2394 zcmaKtc|6qH8^@1j8e8gO%8(4NBxJ8ijeS=%lS-6AV@Wm4HE0>TkYzHK$sUS?u?<;r zMOmwhp)8Fuw#ru7Bc{1u^+)%Q`};lT^*rDAd7jVfoacPMuk-raTA7>M3IcG(%ot~f z)3Fx<0BAsN0DvI?RwgF64jyO_>){-Xbk zkZPs>m-e;le=7ceQqa|ngoh+^knizRkf) zJ=z-?U`F*8prcY_P)J@CfeCpW1*H{cFOUvpa(0IWy5z{|bi)JdS1|H>0rzV4R&7n7 zwBVMWr$*MfxL5p88>+xjcun*QgHYFP%X1^D?{KPahuzcWhZCZn?{29NW`+kQF8^gh z*+?Hd`w9NWDtBqd5%=}gm#Q|*W&fbY*{~-R169FC?+r&|jtsXTxAp{(P2lLwje}Cf#tUrXk)*H%L2U&XOwYX??sPsr;{DT-{ekCs z2hxfj-u|#&TC&fKKBa%_a^yAo`hqGBkgI?^Qzjgav^uFfX zoeEFWnp9{mrnE$|zwC{KcctRfo#WDRo~e={5_MQ)F&}jMP#rMn_DO*(9%Vyd1oSm` zM4QOV$sy8hbWnW!IU@L=xMnhZ{7@xNgi_;gaRuwGpd{)zHe)J@=9*N#k3U}x zS6kfRcG0b-o|80{u}*o`kOg1L6IJd?$o@MK`btP_&kN61 zOekVdt2Q;iQ2$LuK>g#V_btXFm(PFpWu%y&>dVM~HfiuR6O)Xg_7-JdULG`M7%9>6 zWNHPQw2@wc$zSTpv@@1{3mLQJ1e1-Hpz62W1e*qC)ZZ6Fevlg3^!)llzGR+KMDe4g zkRG?QL!4mwUT)U*KW{jTJbbaA>8E(Wj1;+6ae z0h(Bz=Yo_-c?PA9z_%|lO6c*o292pPp4mgD6y*y2iVF_UXZ3S6aRV( zVW(Jsv$5XPih1Ra9rMBmxEh}`!r}0$*wUIQ)!=LVD=KoZjCbm+PlN6zX%EB>wIx(B zHf9m&nI^F*++5*d_?Bnqa)u{>9-7(Et~JN$X_uZ?qH||B@flr~8OW3}0{z-#A_M|rk%wB2} zJ#U}SJVJUVu)Vb+6pW6o8m`?oHkfOvQ*3y^*voQhk-f`)1$I2@;6|L3EEfnf%FVPr zSO2Wd?h1h!5>-r@IRU@C9Aw$VadDW6w)kZ8>WG%-sG|Kbvaz!g=lgUYB_@us%`q1f zOm&7I=#w*iJmQqiYqKb5XG}i!4R-IO(241pQ7l};0zRoeF7(lWnH^MFl5;p^6}`ng zxXYtkREzy)-LLBk0V6biRFdqSS-qd87#W?gcIirq%@2o6onigD!hyVGzaw(beWf%q z&Qmy7R&{7o(PDx=@ccm zq_u+v)1t_JgRDGg+59RaH~Rc>ARMm2Njq4HY;o2zKg(zC6P)zc(^|Xlbd; z<7n!<$SvXM8PQX@)_iXE&1x=fn-m@os-Aw})6$8+XfAhWZNAQZ0 zS_&l0uBQ*BZs6M@hHVd{l2dIbU>o{zNzN$+e;JT!eXDC6hbL2E+>JOp*-W!a<6CEA ztAh-;IW;2^_b76+s=?eWm($Y(5ACvTm+*64m!9_3t+7fSvyNYl;HtIoZjCjSJrnY0 Jo&V2Y^*=yP0Wtsp literal 0 HcmV?d00001 diff --git a/examples/blog-preview-card/src/blogPreviewCard.ts b/examples/blog-preview-card/src/blogPreviewCard.ts new file mode 100644 index 00000000..cd49e339 --- /dev/null +++ b/examples/blog-preview-card/src/blogPreviewCard.ts @@ -0,0 +1,67 @@ +import { type Context } from "@grucloud/bau-ui/context"; + +export default function (context: Context) { + const { bau, css } = context; + const { h1, h3, div, p, article, img, figure, figcaption, span } = bau.tags; + + const className = css` + border: 1px solid var(--Black); + max-width: 400px; + margin: auto; + display: flex; + flex-direction: column; + gap: 0.6rem; + border-radius: 0.6rem; + background-color: var(--White); + padding: 1rem; + box-shadow: 10px 10px; + img { + border-radius: 0.6rem; + } + .badge { + background-color: var(--Yellow); + padding: 0.4rem; + border-radius: 0.3rem; + font-size: smaller; + font-weight: bolder; + } + .published-time { + font-size: 0.8rem; + font-weight: 500; + color: var(--Grey); + } + figure { + display: inline-flex; + align-items: center; + gap: 1rem; + img { + width: 36px; + } + h3 { + font-size: 1rem; + font-weight: bold; + } + } + `; + + return function myComponent() { + return article( + { class: className }, + img({ src: "./assets/images/illustration-article.svg" }), + div(span({ class: "badge" }, "Learning")), + div({ class: "published-time" }, "Published 21 Dec 2023"), + h1("HTML & CSS foundations"), + p( + "These languages are the backbone of every website, defining structure, content, and presentation." + ), + figure( + img({ + class: "profile-picture", + src: "./assets/images/image-avatar.webp", + alt: "Greg Hooper", + }), + figcaption(h3("Greg Hooper")) + ) + ); + }; +} diff --git a/examples/blog-preview-card/src/main.ts b/examples/blog-preview-card/src/main.ts new file mode 100644 index 00000000..47a2f86b --- /dev/null +++ b/examples/blog-preview-card/src/main.ts @@ -0,0 +1,20 @@ +import { createContext, type Context } from "@grucloud/bau-ui/context"; +import blogPreviewCard from "./blogPreviewCard"; + +import "./style.css"; + +const context = createContext(); + +const app = (context: Context) => { + const { bau } = context; + const { main } = bau.tags; + + const BlogPreviewCard = blogPreviewCard(context); + + return function () { + return main(BlogPreviewCard()); + }; +}; + +const App = app(context); +document.getElementById("app")?.replaceChildren(App()); diff --git a/examples/blog-preview-card/src/style.css b/examples/blog-preview-card/src/style.css new file mode 100644 index 00000000..a6c0f069 --- /dev/null +++ b/examples/blog-preview-card/src/style.css @@ -0,0 +1,24 @@ +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400..700&display=swap"); + +* { + margin: 0; + box-sizing: border-box; +} + +:root { + --Yellow: hsl(47, 88%, 63%); + --White: hsl(0, 0%, 100%); + --Grey: hsl(0, 0%, 50%); + --Black: hsl(0, 0%, 7%); +} + +body { + font-family: "Inter", sans-serif; + min-height: 100vh; + display: grid; + place-items: center; + background-color: var(--Yellow); + + @media (max-width: 600px) { + } +} diff --git a/examples/blog-preview-card/src/vite-env.d.ts b/examples/blog-preview-card/src/vite-env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/examples/blog-preview-card/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/examples/blog-preview-card/tsconfig.json b/examples/blog-preview-card/tsconfig.json new file mode 100644 index 00000000..75abdef2 --- /dev/null +++ b/examples/blog-preview-card/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"] +} diff --git a/examples/blog-preview-card/vite.config.js b/examples/blog-preview-card/vite.config.js new file mode 100644 index 00000000..41713bec --- /dev/null +++ b/examples/blog-preview-card/vite.config.js @@ -0,0 +1,9 @@ +import { defineConfig } from "vite"; + +export default defineConfig(({ command, mode, ssrBuild }) => { + return { + server: { + open: true, + }, + }; +});