From 3666466c99d23ea3cc1d876b54b9b28970dcf1f0 Mon Sep 17 00:00:00 2001 From: "Franco N. Colaizzi" Date: Tue, 21 Jul 2026 18:58:05 -0400 Subject: [PATCH 01/14] new layout --- .config/mise/config.toml | 2 +- configs/@pwrs-cem/.config/mise/config.toml | 2 +- configs/eslint/.config/mise/config.toml | 2 +- configs/prettier/.config/mise/config.toml | 2 +- configs/typedoc/.config/mise/config.toml | 2 +- configs/typescript/.config/mise/config.toml | 2 +- packages/.config/mise/config.toml | 2 +- packages/components/.config/mise/config.toml | 2 +- .../src/bento-layout/bento-layout.styles.ts | 26 ++- .../src/bento-layout/bento-layout.ts | 67 ++++--- .../connections/connections-card.styles.ts | 69 +++++++ .../src/card/connections/connections-card.ts | 116 ++++++++++++ .../src/card/profile/profile-card.styles.ts | 57 +----- .../src/card/profile/profile-card.ts | 89 +--------- .../professional-connection.styles.ts | 2 +- packages/components/src/index.ts | 25 +-- packages/components/src/vite-env.d.ts | 7 + packages/data/.config/mise/config.toml | 2 +- packages/data/src/bento-layout/index.ts | 44 +++-- packages/data/src/vite-env.d.ts | 7 + .../design-tokens/.config/mise/config.toml | 2 +- packages/design-tokens/src/vite-env.d.ts | 7 + packages/services/.config/mise/config.toml | 2 +- packages/services/src/vite-env.d.ts | 7 + packages/types/.config/mise/config.toml | 2 +- packages/types/src/vite-env.d.ts | 7 + pnpm-lock.yaml | 168 ++++++++++-------- pnpm-workspace.yaml | 6 +- sites/docs/.config/mise/config.toml | 2 +- sites/portfolio/.config/mise/config.toml | 2 +- 30 files changed, 439 insertions(+), 293 deletions(-) create mode 100644 packages/components/src/card/connections/connections-card.styles.ts create mode 100644 packages/components/src/card/connections/connections-card.ts create mode 100644 packages/components/src/vite-env.d.ts create mode 100644 packages/data/src/vite-env.d.ts create mode 100644 packages/design-tokens/src/vite-env.d.ts create mode 100644 packages/services/src/vite-env.d.ts create mode 100644 packages/types/src/vite-env.d.ts diff --git a/.config/mise/config.toml b/.config/mise/config.toml index 615cf686..19109a53 100644 --- a/.config/mise/config.toml +++ b/.config/mise/config.toml @@ -26,7 +26,7 @@ monorepo_root = true "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" [deps] pnpm = { diff --git a/configs/@pwrs-cem/.config/mise/config.toml b/configs/@pwrs-cem/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/configs/@pwrs-cem/.config/mise/config.toml +++ b/configs/@pwrs-cem/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/configs/eslint/.config/mise/config.toml b/configs/eslint/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/configs/eslint/.config/mise/config.toml +++ b/configs/eslint/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/configs/prettier/.config/mise/config.toml b/configs/prettier/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/configs/prettier/.config/mise/config.toml +++ b/configs/prettier/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/configs/typedoc/.config/mise/config.toml b/configs/typedoc/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/configs/typedoc/.config/mise/config.toml +++ b/configs/typedoc/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/configs/typescript/.config/mise/config.toml b/configs/typescript/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/configs/typescript/.config/mise/config.toml +++ b/configs/typescript/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/packages/.config/mise/config.toml b/packages/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/packages/.config/mise/config.toml +++ b/packages/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/packages/components/.config/mise/config.toml b/packages/components/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/packages/components/.config/mise/config.toml +++ b/packages/components/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/packages/components/src/bento-layout/bento-layout.styles.ts b/packages/components/src/bento-layout/bento-layout.styles.ts index 6bdb3758..be8ed669 100644 --- a/packages/components/src/bento-layout/bento-layout.styles.ts +++ b/packages/components/src/bento-layout/bento-layout.styles.ts @@ -23,6 +23,7 @@ export const BentoLayoutStyles = css` inline-size: 100%; padding-block-end: var(--spaces-padding-xl); container-name: bento-layout; + container-type: inline-size; } main { @@ -37,7 +38,6 @@ export const BentoLayoutStyles = css` border: var(--sizes-thickness-hairline) solid var(--md-sys-color-on-primary-container); border-radius: var(--md-sys-shape-corner-large); color: var(--md-sys-color-on-primary-container); - grid-area: span 1 / span var(--bento-layout-column-count); inline-size: 100%; margin-inline: auto; padding-block: var(--spaces-padding-l); @@ -66,6 +66,10 @@ export const BentoLayoutStyles = css` grid-auto-flow: dense; grid-template-columns: repeat(var(--bento-layout-column-count), 1fr); } + + header { + grid-area: header; + } } @container style(--breakpoint-label: tablet) { @@ -77,6 +81,14 @@ export const BentoLayoutStyles = css` align-items: unset; gap: var(--spaces-gap-m); padding: var(--spaces-padding-s); + grid-template-areas: + "header header header header header header" + "profile profile connections connections connections connections" + "profile profile experience experience experience experience" + "code code code blog blog blog" + "skills skills skills skills education education" + "settings settings settings settings settings settings" + ; } } @@ -87,6 +99,14 @@ export const BentoLayoutStyles = css` main { gap: var(--spaces-gap-l); + grid-template-areas: + "header header header header header header header header header header header header" + "profile profile profile profile connections connections connections connections connections connections connections connections" + "profile profile profile profile experience experience experience experience experience experience experience experience" + "code code code code code code blog blog blog blog blog blog" + "skills skills skills skills skills skills skills skills education education education education" + "settings settings settings settings settings settings settings settings settings settings settings settings" + ; margin: var(--spaces-none) auto; padding: var(--spaces-padding-m); place-items: stretch stretch; @@ -150,5 +170,9 @@ export const TransitionStyles = css` > *:nth-child(9) { animation-delay: var(--motions-delay-xxxl); } + + > *:nth-child(10) { + animation-delay: var(--motions-delay-xxxl); + } } `; diff --git a/packages/components/src/bento-layout/bento-layout.ts b/packages/components/src/bento-layout/bento-layout.ts index 5a33c131..0e43840c 100644 --- a/packages/components/src/bento-layout/bento-layout.ts +++ b/packages/components/src/bento-layout/bento-layout.ts @@ -2,7 +2,7 @@ import { BentoLayoutStyles, TransitionStyles } from "@/lib/bento-layout/bento-la import { UIAwareElement } from "@/lib/mixins/ui-aware-element/ui-aware-element"; import { TextStyles } from "@/lib/styles"; import { BentoBoxConfigsArray, titles } from "@fnc314/packages.data"; -import { type ABentoBoxConfig, BENTO_BOX_TYPES, BreakpointLabels, type GridPosition } from "@fnc314/packages.types"; +import { type ABentoBoxConfig, BENTO_BOX_TYPES, BreakpointLabels } from "@fnc314/packages.types"; import { type TemplateResult, html, nothing } from "lit"; import { customElement, state } from "lit/decorators.js"; import { styleMap } from "lit/directives/style-map.js"; @@ -25,95 +25,92 @@ export class BentoLayout extends UIAwareElement { private _bentoBoxConfigs: ABentoBoxConfig[] = BentoBoxConfigsArray(this.breakpoint); private renderBentoBox(config: ABentoBoxConfig): TemplateResult { - const position: GridPosition = config.placement[this.breakpoint]; - - let gridStyles = {}; - if (position.breakpoint !== BreakpointLabels.mobile) { - const rowOffset = `${position?.offsets?.row ? `${position?.offsets?.row} / ` : ""}`; - const colOffset = `${position?.offsets?.col ? `${position?.offsets?.col} / ` : ""}`; - gridStyles = { - gridColumn: `${colOffset} span ${position.span.colSpan}`, - gridRow: `${rowOffset} span ${position.span.rowSpan}`, - }; + let cardStyles = { }; + if (this.breakpoint !== BreakpointLabels.mobile) { + cardStyles = { gridArea: config.type }; } - let cardContent: TemplateResult; + cardStyles = { + ...cardStyles, + blockSize: "100%" + }; + switch (config.type) { case BENTO_BOX_TYPES.profile: - cardContent = html` + return html` `; - break; + case BENTO_BOX_TYPES.connections: + return html` + + + `; case BENTO_BOX_TYPES.education: - cardContent = html` + return html` `; - break; case BENTO_BOX_TYPES.experience: - cardContent = html` + return html` `; - break; case BENTO_BOX_TYPES.blog: - cardContent = html` + return html` `; - break; case BENTO_BOX_TYPES.code: - cardContent = html` + return html` `; - break; case BENTO_BOX_TYPES.skills: - cardContent = html` + return html` `; - break; case BENTO_BOX_TYPES.settings: - cardContent = html` + return html` `; - break; default: return html`${nothing}`; } - - return cardContent; } override render() { diff --git a/packages/components/src/card/connections/connections-card.styles.ts b/packages/components/src/card/connections/connections-card.styles.ts new file mode 100644 index 00000000..5482d9c2 --- /dev/null +++ b/packages/components/src/card/connections/connections-card.styles.ts @@ -0,0 +1,69 @@ +import { type CSSResult, css } from "lit"; + +export const DL_DIV_COLUMN_COUNT: number = 6; + +export const ConnectionsCardStyles: CSSResult = css` + :host { + display: block; + block-size: 100%; + + --dl-div-column-count: ${DL_DIV_COLUMN_COUNT}; + + --connections-card-filled-icon-button-container-shape: var(--bento-layout-card-shape); + --connections-card-filled-icon-button-scale: 2.25; + --connections-card-filled-icon-button-container-color: var(--bento-layout-card-background); + --connections-card-filled-icon-button-container-size: calc( + var(--connections-card-filled-icon-button-scale) * var(--md-icon-size) + ); + --connections-card-filled-icon-button-container-shape: var(--bento-layout-card-shape); + --connections-card-filled-icon-button-icon-color: var(--bento-layout-card-color); + --connections-card-filled-icon-button-icon-scale: 0.75; + --connections-card-filled-icon-button-icon-size: calc( + var(--connections-card-filled-icon-button-icon-scale) * var(--connections-card-filled-icon-button-container-size) + ); + + --md-filled-icon-button-container-color: var(--connections-card-filled-icon-button-container-color); + --md-filled-icon-button-container-height: var(--connections-card-filled-icon-button-container-size); + --md-filled-icon-button-container-width: var(--connections-card-filled-icon-button-container-size); + --md-filled-icon-button-container-shape: var(--connections-card-filled-icon-button-container-shape); + --md-filled-icon-button-icon-color: var(--connections-card-filled-icon-button-icon-color); + --md-filled-icon-button-icon-size: var(--connections-card-filled-icon-button-icon-size); + --md-filled-icon-button-focus-icon-color: var(--connections-card-filled-icon-button-icon-color); + --md-filled-icon-button-hover-icon-color: var(--connections-card-filled-icon-button-icon-color); + } + + dl { + display: flex; + flex-direction: row; + gap: var(--spaces-gap-s); + flex-wrap: wrap; + justify-content: space-around; + + div { + display: grid; + grid-template-rows: min-content auto; + grid-template-columns: repeat(var(--dl-div-column-count), 1fr); + row-gap: var(--spaces-gap-s); + column-gap: var(--spaces-gap-xs); + place-items: center; + border-radius: var(--connections-card-filled-icon-button-container-shape); + border: solid var(--sizes-thickness-xxs) var(--connections-card-filled-icon-button-icon-color); + background-color: var(--md-sys-color-surface-container-highest); + padding-block: var(--spaces-padding-s); + flex: 1 0 min-content; + + dt { + grid-row: 1 / 2; + grid-column: span var(--dl-div-column-count); + color: var(--connections-card-filled-icon-button-icon-color); + } + + dd { + grid-row: 2 / 3; + margin: unset; + border: solid var(--sizes-thickness-xxs) var(--connections-card-filled-icon-button-icon-color); + border-radius: var(--connections-card-filled-icon-button-container-shape); + } + } + } +`; \ No newline at end of file diff --git a/packages/components/src/card/connections/connections-card.ts b/packages/components/src/card/connections/connections-card.ts new file mode 100644 index 00000000..f9a6a913 --- /dev/null +++ b/packages/components/src/card/connections/connections-card.ts @@ -0,0 +1,116 @@ +import { ConnectionsCardStyles, DL_DIV_COLUMN_COUNT } from "@/lib/card/connections/connections-card.styles"; +import { UIAwareElement } from "@/lib/mixins/ui-aware-element/ui-aware-element"; +import { TextStyles } from "@/lib/styles"; +import { Connections } from "@fnc314/packages.data"; +import { type ArtifactConnectionData, type ArtifactConnectionType, BENTO_BOX_TYPES, type ConnectionInstance, type ProfessionalConnectionJsonData } from "@fnc314/packages.types"; +import { type TemplateResult, html } from "lit"; +import { customElement, property } from "lit/decorators.js"; + +@customElement("connections-card") +export class ConnectionsCard extends UIAwareElement { + + static override styles = [ + TextStyles, + ConnectionsCardStyles + ] + + @property({ type: Boolean }) + expanded = true; + + @property({ type: Boolean }) + enableHover = false; + + @property({ type: Boolean }) + enableFocus = false; + + private contactsDefinitionList(): TemplateResult { + const directConnectionsCount = Object.entries(Connections.direct).length; + const directConnectionsColSpan = Math.floor(DL_DIV_COLUMN_COUNT / directConnectionsCount); + const contact = html` +
+
Contact
+ ${ + Object.entries(Connections.direct).map( + ([_, instance]: [string, ConnectionInstance]) => + html` +
+ + +
+ ` + ) + } +
+ `; + + const socialConnectionsCount = Object.entries(Connections.social).length; + const socialConnectionsColSpan = Math.floor(DL_DIV_COLUMN_COUNT / socialConnectionsCount); + const network = html` +
+
Network
+ ${Object.entries(Connections.social).map( + ([type, data]: [string, ProfessionalConnectionJsonData]) => html` +
+ + +
+ `, + )} +
+ `; + + const resumeConnectionsCount = Object.entries(Connections.resume).length; + const resumeConnectionsColSpan = Math.floor(DL_DIV_COLUMN_COUNT / resumeConnectionsCount); + const resume = html` +
+
Resume
+ ${Object.entries(Connections.resume).map( + ([name, data]: [string, ArtifactConnectionData]) => html` +
+ + +
+ `, + )} +
+ `; + + return html` +
+ ${contact} + ${network} + ${resume} +
+ `; + } + + override render() { + return html` + +
+ ${this.contactsDefinitionList()} +
+
+ `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "connections-card": ConnectionsCard + } +} \ No newline at end of file diff --git a/packages/components/src/card/profile/profile-card.styles.ts b/packages/components/src/card/profile/profile-card.styles.ts index a7f5faba..80db2f05 100644 --- a/packages/components/src/card/profile/profile-card.styles.ts +++ b/packages/components/src/card/profile/profile-card.styles.ts @@ -8,27 +8,6 @@ export const ProfileCardStyles: CSSResult = css` --profile-card-image-block-size: auto; --profile-card-image-block-size-max: 500px; --profile-card-image-inline-size-max: 100%; - - --profile-card-filled-icon-button-scale: 2.25; - --profile-card-filled-icon-button-container-color: var(--bento-layout-card-background); - --profile-card-filled-icon-button-container-size: calc( - var(--profile-card-filled-icon-button-scale) * var(--md-icon-size) - ); - --profile-card-filled-icon-button-container-shape: var(--bento-layout-card-shape); - --profile-card-filled-icon-button-icon-color: var(--bento-layout-card-color); - --profile-card-filled-icon-button-icon-scale: 0.75; - --profile-card-filled-icon-button-icon-size: calc( - var(--profile-card-filled-icon-button-icon-scale) * var(--profile-card-filled-icon-button-container-size) - ); - - --md-filled-icon-button-container-color: var(--profile-card-filled-icon-button-container-color); - --md-filled-icon-button-container-height: var(--profile-card-filled-icon-button-container-size); - --md-filled-icon-button-container-width: var(--profile-card-filled-icon-button-container-size); - --md-filled-icon-button-container-shape: var(--profile-card-filled-icon-button-container-shape); - --md-filled-icon-button-icon-color: var(--profile-card-filled-icon-button-icon-color); - --md-filled-icon-button-icon-size: var(--profile-card-filled-icon-button-icon-size); - --md-filled-icon-button-focus-icon-color: var(--profile-card-filled-icon-button-icon-color); - --md-filled-icon-button-hover-icon-color: var(--profile-card-filled-icon-button-icon-color); } article { @@ -45,7 +24,7 @@ export const ProfileCardStyles: CSSResult = css` img { border: var(--sizes-thickness-xxs) solid var(--md-sys-color-primary-fixed); - border-radius: var(--md-sys-shape-corner-medium); + border-radius: var(--bento-layout-card-shape); block-size: var(--profile-card-image-block-size); max-inline-size: var(--profile-card-image-inline-size-max); object-fit: cover; @@ -54,7 +33,7 @@ export const ProfileCardStyles: CSSResult = css` figcaption { background-color: var(--md-sys-color-primary-fixed); - border-radius: var(--md-sys-shape-corner-medium); + border-radius: var(--bento-layout-card-shape); border: var(--md-sys-color-on-primary-fixed) solid var(--sizes-thickness-hairline); color: var(--md-sys-color-on-primary-fixed); font-size: var(--md-sys-typescale-body-small-size); @@ -92,36 +71,12 @@ export const ProfileCardStyles: CSSResult = css` } } - dl { - display: flex; - flex-direction: column; - gap: var(--spaces-gap-l); - - div { - display: grid; - grid-template-rows: min-content auto; - grid-template-columns: repeat(9, 1fr); - gap: var(--spaces-gap-s); - place-items: center; - border-radius: var(--profile-card-filled-icon-button-container-shape); - border: solid var(--sizes-thickness-xxs) var(--profile-card-filled-icon-button-icon-color); - background-color: var(--md-sys-color-surface-container-highest); - padding-block: var(--spaces-padding-s); - - dt { - grid-row: 1 / 2; - grid-column: 4 / span 3; - color: var(--profile-card-filled-icon-button-icon-color); - } - - dd { - grid-row: 2 / 3; - margin: unset; - border: solid var(--sizes-thickness-xxs) var(--profile-card-filled-icon-button-icon-color); - border-radius: var(--profile-card-filled-icon-button-container-shape); + article { + section { + ul { + padding-inline-start: unset; } } - } } `; diff --git a/packages/components/src/card/profile/profile-card.ts b/packages/components/src/card/profile/profile-card.ts index dfe5d673..be35b5a8 100644 --- a/packages/components/src/card/profile/profile-card.ts +++ b/packages/components/src/card/profile/profile-card.ts @@ -1,18 +1,14 @@ import { ProfileCardStyles } from "@/lib/card/profile/profile-card.styles"; import { UIAwareElement } from "@/lib/mixins/ui-aware-element/ui-aware-element"; import { TextStyles } from "@/lib/styles"; -import { Biographies, Connections, Photos } from "@fnc314/packages.data"; +import { Biographies, Photos } from "@fnc314/packages.data"; import { configsService } from "@fnc314/packages.services"; import { APP_CONFIGS_CHANGE_EVENT_NAME, - type ArtifactConnectionData, - type ArtifactConnectionType, BENTO_BOX_TYPES, - type BioExtended, - type ConnectionInstance, - type ProfessionalConnectionJsonData, + type BioExtended } from "@fnc314/packages.types"; -import { type TemplateResult, html, unsafeCSS } from "lit"; +import { type TemplateResult, html } from "lit"; import { customElement, property } from "lit/decorators.js"; import { unsafeHTML } from "lit/directives/unsafe-html.js"; @@ -94,13 +90,13 @@ export class ProfileCard extends UIAwareElement { `); return html` -
+

About Me

-

${this.aboutMe.opener}

+

${this.aboutMe.opener}

-
+
${summary}
@@ -113,74 +109,6 @@ export class ProfileCard extends UIAwareElement { `; } - private contactsDefinitionList(): TemplateResult { - const directConnectionsCount = Object.entries(Connections.direct).length; - const directConnectionsColSpan = Math.floor(9 / directConnectionsCount); - const contact = html` -
-
Contact
- ${ - Object.entries(Connections.direct).map( - ([_, instance]: [string, ConnectionInstance], index: number) => - html` -
- - -
- ` - ) - } -
- `; - - const socialConnectionsCount = Object.entries(Connections.social).length; - const socialConnectionsColSpan = Math.floor(9 / socialConnectionsCount); - const network = html` -
-
Network
- ${Object.entries(Connections.social).map( - ([type, data]: [string, ProfessionalConnectionJsonData], index: number) => html` -
- - -
- `, - )} -
- `; - - const resumeConnectionsCount = Object.entries(Connections.resume).length; - const resumeConnectionsColSpan = Math.floor(9 / resumeConnectionsCount); - const resume = html` -
-
Resume
- ${Object.entries(Connections.resume).map( - ([name, data]: [string, ArtifactConnectionData], index: number) => html` -
- - -
- `, - )} -
- `; - - return html` -
- ${contact} - ${network} - ${resume} -
- `; - } - private imageSection(): TemplateResult { const srcSet = ` ${this.photoData.srcSet.mobile} 750w, @@ -207,8 +135,6 @@ export class ProfileCard extends UIAwareElement {
${this.photoData.figcaption}
- - ${unsafeHTML(Biographies.bio.long)}
`; } @@ -216,7 +142,6 @@ export class ProfileCard extends UIAwareElement { override render() { return html`
${this.imageSection()} - ${this.contactsDefinitionList()} + ${this.renderAboutMe()}
`; diff --git a/packages/components/src/connection/professional/professional-connection.styles.ts b/packages/components/src/connection/professional/professional-connection.styles.ts index 62edf09b..f1e01bb7 100644 --- a/packages/components/src/connection/professional/professional-connection.styles.ts +++ b/packages/components/src/connection/professional/professional-connection.styles.ts @@ -10,7 +10,7 @@ export const ProfessionalConnectionStyles: CSSResult = css` } span { - background-color: var(--md-filled-icon-button-icon-color); + background-color: var(--connections-card-filled-icon-button-icon-color); mask: var(--professional-connection-mask) no-repeat center / contain; } `; diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index a76f13d5..6edbc41f 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -6,6 +6,7 @@ export { BlogCard } from "@/lib/card/blog/blog-card"; export { BlogCardStyles } from "@/lib/card/blog/blog-card.styles"; export { CodeCard } from "@/lib/card/code/code-card"; export { CodeCardStyles } from "@/lib/card/code/code-card.styles"; +export { ConnectionsCard } from "@/lib/card/connections/connections-card"; export { EducationCard } from "@/lib/card/education/education-card"; export { EducationCardStyles } from "@/lib/card/education/education-card.styles"; export { ExperienceCard } from "@/lib/card/experience/experience-card"; @@ -39,20 +40,20 @@ export { VersionTag } from "@/lib/version-tag/version-tag"; export { WordCloud } from "@/lib/word/cloud/word-cloud"; export { WordCloudStyles } from "@/lib/word/cloud/word-cloud.styles"; export { - WordCloudAppearances, - WordCloudGroupings, - WordCloudSortings, - makeWordCloudWord, + WordCloudAppearances, + WordCloudGroupings, + WordCloudSortings, + makeWordCloudWord } from "@/lib/word/cloud/word-cloud.types"; export type { - RenderableWordCloudWord, - WeightQuartile, - Weights, - WordCloudAppearance, - WordCloudGrouping, - WordCloudSorting, - WordCloudWord, - WordCloudWordCategory, + RenderableWordCloudWord, + WeightQuartile, + Weights, + WordCloudAppearance, + WordCloudGrouping, + WordCloudSorting, + WordCloudWord, + WordCloudWordCategory } from "@/lib/word/cloud/word-cloud.types"; export { WordTag } from "@/lib/word/tag/word-tag"; export { WordTagStyles } from "@/lib/word/tag/word-tag.styles"; diff --git a/packages/components/src/vite-env.d.ts b/packages/components/src/vite-env.d.ts new file mode 100644 index 00000000..6fdf08c1 --- /dev/null +++ b/packages/components/src/vite-env.d.ts @@ -0,0 +1,7 @@ +declare module "vite-env" { + declare const __FNC314_FNC314_GITHUB_IO_VERSION__: string; +} +declare module '*.css' { + const content: CSSStyleSheet; + export default content; +} \ No newline at end of file diff --git a/packages/data/.config/mise/config.toml b/packages/data/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/packages/data/.config/mise/config.toml +++ b/packages/data/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/packages/data/src/bento-layout/index.ts b/packages/data/src/bento-layout/index.ts index 4fbae8cb..2473b9ca 100644 --- a/packages/data/src/bento-layout/index.ts +++ b/packages/data/src/bento-layout/index.ts @@ -17,29 +17,29 @@ export const titles: string = [ export const BENTO_BOX_CONFIG: BentoBoxConfigs = { profile: { placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 4, rowSpan: 1 }, order: 1 }, - tablet: { breakpoint: "tablet", span: { colSpan: 2, rowSpan: 1 }, order: 1 }, + desktop: { breakpoint: "desktop", span: { colSpan: 4, rowSpan: 2 }, order: 1 }, + tablet: { breakpoint: "tablet", offsets: { row: 1 }, span: { colSpan: 2, rowSpan: 1 }, order: 1 }, mobile: { breakpoint: "mobile", order: 1 }, }, isExpanded: () => true, }, - experience: { + connections: { placement: { desktop: { breakpoint: "desktop", span: { colSpan: 8, rowSpan: 1 }, order: 2 }, tablet: { breakpoint: "tablet", span: { colSpan: 4, rowSpan: 1 }, order: 2 }, mobile: { breakpoint: "mobile", order: 2 }, }, - isExpanded: (breakpoint: BreakpointLabel) => breakpoint !== BreakpointLabels.mobile, + isExpanded: () => true, }, - code: { + experience: { placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 6, rowSpan: 1 }, order: 3 }, - tablet: { breakpoint: "tablet", span: { colSpan: 3, rowSpan: 1 }, order: 3 }, + desktop: { breakpoint: "desktop", span: { colSpan: 8, rowSpan: 1 }, order: 3 }, + tablet: { breakpoint: "tablet", span: { colSpan: 4, rowSpan: 1 }, order: 3 }, mobile: { breakpoint: "mobile", order: 3 }, }, isExpanded: (breakpoint: BreakpointLabel) => breakpoint !== BreakpointLabels.mobile, }, - blog: { + code: { placement: { desktop: { breakpoint: "desktop", span: { colSpan: 6, rowSpan: 1 }, order: 4 }, tablet: { breakpoint: "tablet", span: { colSpan: 3, rowSpan: 1 }, order: 4 }, @@ -47,30 +47,38 @@ export const BENTO_BOX_CONFIG: BentoBoxConfigs = { }, isExpanded: (breakpoint: BreakpointLabel) => breakpoint !== BreakpointLabels.mobile, }, - skills: { + blog: { placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 7, rowSpan: 2 }, order: 5 }, - tablet: { breakpoint: "tablet", span: { colSpan: 4, rowSpan: 1 }, order: 5 }, + desktop: { breakpoint: "desktop", span: { colSpan: 6, rowSpan: 1 }, order: 5 }, + tablet: { breakpoint: "tablet", span: { colSpan: 3, rowSpan: 1 }, order: 5 }, mobile: { breakpoint: "mobile", order: 5 }, }, - isExpanded: () => false, + isExpanded: (breakpoint: BreakpointLabel) => breakpoint !== BreakpointLabels.mobile, }, - education: { + skills: { placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 5, rowSpan: 1 }, order: 6 }, - tablet: { breakpoint: "tablet", span: { colSpan: 2, rowSpan: 1 }, order: 6 }, + desktop: { breakpoint: "desktop", span: { colSpan: 7, rowSpan: 2 }, order: 6 }, + tablet: { breakpoint: "tablet", span: { colSpan: 4, rowSpan: 1 }, order: 6 }, mobile: { breakpoint: "mobile", order: 6 }, }, isExpanded: () => false, }, - settings: { + education: { placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 12, rowSpan: 1 }, order: 7 }, - tablet: { breakpoint: "tablet", span: { colSpan: 6, rowSpan: 1 }, order: 7 }, + desktop: { breakpoint: "desktop", span: { colSpan: 5, rowSpan: 1 }, order: 7 }, + tablet: { breakpoint: "tablet", span: { colSpan: 2, rowSpan: 1 }, order: 7 }, mobile: { breakpoint: "mobile", order: 7 }, }, isExpanded: () => false, }, + settings: { + placement: { + desktop: { breakpoint: "desktop", span: { colSpan: 12, rowSpan: 1 }, order: 8 }, + tablet: { breakpoint: "tablet", span: { colSpan: 6, rowSpan: 1 }, order: 8 }, + mobile: { breakpoint: "mobile", order: 8 }, + }, + isExpanded: () => false, + } }; /** diff --git a/packages/data/src/vite-env.d.ts b/packages/data/src/vite-env.d.ts new file mode 100644 index 00000000..6fdf08c1 --- /dev/null +++ b/packages/data/src/vite-env.d.ts @@ -0,0 +1,7 @@ +declare module "vite-env" { + declare const __FNC314_FNC314_GITHUB_IO_VERSION__: string; +} +declare module '*.css' { + const content: CSSStyleSheet; + export default content; +} \ No newline at end of file diff --git a/packages/design-tokens/.config/mise/config.toml b/packages/design-tokens/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/packages/design-tokens/.config/mise/config.toml +++ b/packages/design-tokens/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/packages/design-tokens/src/vite-env.d.ts b/packages/design-tokens/src/vite-env.d.ts new file mode 100644 index 00000000..6fdf08c1 --- /dev/null +++ b/packages/design-tokens/src/vite-env.d.ts @@ -0,0 +1,7 @@ +declare module "vite-env" { + declare const __FNC314_FNC314_GITHUB_IO_VERSION__: string; +} +declare module '*.css' { + const content: CSSStyleSheet; + export default content; +} \ No newline at end of file diff --git a/packages/services/.config/mise/config.toml b/packages/services/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/packages/services/.config/mise/config.toml +++ b/packages/services/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/packages/services/src/vite-env.d.ts b/packages/services/src/vite-env.d.ts new file mode 100644 index 00000000..6fdf08c1 --- /dev/null +++ b/packages/services/src/vite-env.d.ts @@ -0,0 +1,7 @@ +declare module "vite-env" { + declare const __FNC314_FNC314_GITHUB_IO_VERSION__: string; +} +declare module '*.css' { + const content: CSSStyleSheet; + export default content; +} \ No newline at end of file diff --git a/packages/types/.config/mise/config.toml b/packages/types/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/packages/types/.config/mise/config.toml +++ b/packages/types/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/packages/types/src/vite-env.d.ts b/packages/types/src/vite-env.d.ts new file mode 100644 index 00000000..6fdf08c1 --- /dev/null +++ b/packages/types/src/vite-env.d.ts @@ -0,0 +1,7 @@ +declare module "vite-env" { + declare const __FNC314_FNC314_GITHUB_IO_VERSION__: string; +} +declare module '*.css' { + const content: CSSStyleSheet; + export default content; +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8931f35..14208fd3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -318,11 +318,11 @@ catalogs: specifier: 1.2.2 version: 1.2.2 '@typescript-eslint/eslint-plugin': - specifier: 8.64.0 - version: 8.64.0 + specifier: 8.65.0 + version: 8.65.0 '@typescript-eslint/parser': - specifier: 8.64.0 - version: 8.64.0 + specifier: 8.65.0 + version: 8.65.0 '@typescript/typescript6': specifier: 6.0.2 version: 6.0.2 @@ -549,8 +549,8 @@ catalogs: specifier: 7.0.2 version: 7.0.2 typescript-eslint: - specifier: 8.64.0 - version: 8.64.0 + specifier: 8.65.0 + version: 8.65.0 unplugin-dts: specifier: 1.0.3 version: 1.0.3 @@ -722,10 +722,10 @@ importers: version: 1.2.2 '@typescript-eslint/eslint-plugin': specifier: catalog:devDependencies - version: 8.64.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.64.0)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + version: 8.65.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.65.0)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) '@typescript-eslint/parser': specifier: catalog:devDependencies - version: 8.64.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + version: 8.65.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) '@typescript/typescript6': specifier: catalog:devDependencies version: 6.0.2 @@ -947,7 +947,7 @@ importers: version: 7.0.2 typescript-eslint: specifier: catalog:devDependencies - version: 8.64.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + version: 8.65.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) unplugin-dts: specifier: catalog:devDependencies version: 1.0.3(esbuild@0.28.1)(rolldown@1.2.0)(rollup@4.62.0)(supports-color@10.2.2)(typescript@7.0.2)(vite@8.1.5) @@ -1003,10 +1003,10 @@ importers: devDependencies: '@typescript-eslint/eslint-plugin': specifier: catalog:devDependencies - version: 8.64.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.64.0)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + version: 8.65.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.65.0)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) '@typescript-eslint/parser': specifier: catalog:devDependencies - version: 8.64.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + version: 8.65.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) eslint: specifier: catalog:devDependencies version: 10.7.0(@types/eslint@9.6.1)(jiti@2.7.0)(supports-color@10.2.2) @@ -1015,7 +1015,7 @@ importers: version: 0.14.0(eslint@10.7.0) eslint-plugin-import: specifier: catalog:devDependencies - version: 2.32.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.64.0)(eslint@10.7.0)(supports-color@10.2.2) + version: 2.32.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.65.0)(eslint@10.7.0)(supports-color@10.2.2) firebase-functions-test: specifier: catalog:functionsDevDependencies version: 3.5.0(firebase-admin@14.0.0)(firebase-functions@7.2.5)(jest@30.4.2) @@ -4546,16 +4546,16 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.64.0': - resolution: {integrity: sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==} + '@typescript-eslint/eslint-plugin@8.65.0': + resolution: {integrity: sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.64.0 + '@typescript-eslint/parser': ^8.65.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.64.0': - resolution: {integrity: sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==} + '@typescript-eslint/parser@8.65.0': + resolution: {integrity: sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -4567,8 +4567,8 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.64.0': - resolution: {integrity: sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==} + '@typescript-eslint/project-service@8.65.0': + resolution: {integrity: sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -4577,8 +4577,8 @@ packages: resolution: {integrity: sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.64.0': - resolution: {integrity: sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==} + '@typescript-eslint/scope-manager@8.65.0': + resolution: {integrity: sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/tsconfig-utils@8.56.1': @@ -4593,8 +4593,14 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.64.0': - resolution: {integrity: sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==} + '@typescript-eslint/tsconfig-utils@8.65.0': + resolution: {integrity: sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.65.0': + resolution: {integrity: sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -4608,14 +4614,18 @@ packages: resolution: {integrity: sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.65.0': + resolution: {integrity: sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.56.1': resolution: {integrity: sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/typescript-estree@8.64.0': - resolution: {integrity: sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==} + '@typescript-eslint/typescript-estree@8.65.0': + resolution: {integrity: sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' @@ -4627,8 +4637,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.64.0': - resolution: {integrity: sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==} + '@typescript-eslint/utils@8.65.0': + resolution: {integrity: sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -4638,8 +4648,8 @@ packages: resolution: {integrity: sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.64.0': - resolution: {integrity: sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==} + '@typescript-eslint/visitor-keys@8.65.0': + resolution: {integrity: sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript/typescript-aix-ppc64@7.0.2': @@ -9941,8 +9951,8 @@ packages: peerDependencies: typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x - typescript-eslint@8.64.0: - resolution: {integrity: sha512-0qg+pDNMnqYzqH9AnNK+39tejHvsShUOUUoRUgtnTGE7QuMZhiFDnozq8nHJVq+Wae6NMLKNWLg5WmkcC/ndyQ==} + typescript-eslint@8.65.0: + resolution: {integrity: sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -14355,15 +14365,15 @@ snapshots: '@types/node': 26.1.1 optional: true - '@typescript-eslint/eslint-plugin@8.64.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.64.0)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2)': + '@typescript-eslint/eslint-plugin@8.65.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.65.0)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2)': dependencies: '@eslint-community/regexpp': 4.12.2 '@types/natural-compare': 1.4.3 - '@typescript-eslint/parser': 8.64.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) - '@typescript-eslint/scope-manager': 8.64.0 - '@typescript-eslint/type-utils': 8.64.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) - '@typescript-eslint/utils': 8.64.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) - '@typescript-eslint/visitor-keys': 8.64.0 + '@typescript-eslint/parser': 8.65.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/type-utils': 8.65.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/utils': 8.65.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/visitor-keys': 8.65.0 eslint: 10.7.0(@types/eslint@9.6.1)(jiti@2.7.0)(supports-color@10.2.2) ignore: 7.0.5 natural-compare: 1.4.0 @@ -14373,12 +14383,12 @@ snapshots: - '@types/eslint' - supports-color - '@typescript-eslint/parser@8.64.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2)': + '@typescript-eslint/parser@8.65.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2)': dependencies: - '@typescript-eslint/scope-manager': 8.64.0 - '@typescript-eslint/types': 8.64.0 - '@typescript-eslint/typescript-estree': 8.64.0(supports-color@10.2.2)(typescript@7.0.2) - '@typescript-eslint/visitor-keys': 8.64.0 + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/visitor-keys': 8.65.0 debug: 4.4.3(supports-color@10.2.2) eslint: 10.7.0(@types/eslint@9.6.1)(jiti@2.7.0)(supports-color@10.2.2) typescript: 7.0.2 @@ -14394,10 +14404,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.64.0(supports-color@10.2.2)(typescript@7.0.2)': + '@typescript-eslint/project-service@8.65.0(supports-color@10.2.2)(typescript@7.0.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.64.0(typescript@7.0.2) - '@typescript-eslint/types': 8.64.0 + '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@7.0.2) + '@typescript-eslint/types': 8.65.0 debug: 4.4.3(supports-color@10.2.2) typescript: 7.0.2 transitivePeerDependencies: @@ -14408,10 +14418,10 @@ snapshots: '@typescript-eslint/types': 8.56.1 '@typescript-eslint/visitor-keys': 8.56.1 - '@typescript-eslint/scope-manager@8.64.0': + '@typescript-eslint/scope-manager@8.65.0': dependencies: - '@typescript-eslint/types': 8.64.0 - '@typescript-eslint/visitor-keys': 8.64.0 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/visitor-keys': 8.65.0 '@typescript-eslint/tsconfig-utils@8.56.1(typescript@7.0.2)': dependencies: @@ -14421,11 +14431,15 @@ snapshots: dependencies: typescript: 7.0.2 - '@typescript-eslint/type-utils@8.64.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2)': + '@typescript-eslint/tsconfig-utils@8.65.0(typescript@7.0.2)': dependencies: - '@typescript-eslint/types': 8.64.0 - '@typescript-eslint/typescript-estree': 8.64.0(supports-color@10.2.2)(typescript@7.0.2) - '@typescript-eslint/utils': 8.64.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + typescript: 7.0.2 + + '@typescript-eslint/type-utils@8.65.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2)': + dependencies: + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/utils': 8.65.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) debug: 4.4.3(supports-color@10.2.2) eslint: 10.7.0(@types/eslint@9.6.1)(jiti@2.7.0)(supports-color@10.2.2) ts-api-utils: 2.5.0(typescript@7.0.2) @@ -14438,6 +14452,8 @@ snapshots: '@typescript-eslint/types@8.64.0': {} + '@typescript-eslint/types@8.65.0': {} + '@typescript-eslint/typescript-estree@8.56.1(supports-color@10.2.2)(typescript@7.0.2)': dependencies: '@typescript-eslint/project-service': 8.56.1(supports-color@10.2.2)(typescript@7.0.2) @@ -14453,12 +14469,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.64.0(supports-color@10.2.2)(typescript@7.0.2)': + '@typescript-eslint/typescript-estree@8.65.0(supports-color@10.2.2)(typescript@7.0.2)': dependencies: - '@typescript-eslint/project-service': 8.64.0(supports-color@10.2.2)(typescript@7.0.2) - '@typescript-eslint/tsconfig-utils': 8.64.0(typescript@7.0.2) - '@typescript-eslint/types': 8.64.0 - '@typescript-eslint/visitor-keys': 8.64.0 + '@typescript-eslint/project-service': 8.65.0(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@7.0.2) + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/visitor-keys': 8.65.0 debug: 4.4.3(supports-color@10.2.2) minimatch: 10.2.5 semver: 7.8.4 @@ -14480,12 +14496,12 @@ snapshots: - '@types/eslint' - supports-color - '@typescript-eslint/utils@8.64.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2)': + '@typescript-eslint/utils@8.65.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2)': dependencies: '@eslint-community/eslint-utils': 4.9.1(@types/eslint@9.6.1)(eslint@10.7.0) - '@typescript-eslint/scope-manager': 8.64.0 - '@typescript-eslint/types': 8.64.0 - '@typescript-eslint/typescript-estree': 8.64.0(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/scope-manager': 8.65.0 + '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/typescript-estree': 8.65.0(supports-color@10.2.2)(typescript@7.0.2) eslint: 10.7.0(@types/eslint@9.6.1)(jiti@2.7.0)(supports-color@10.2.2) typescript: 7.0.2 transitivePeerDependencies: @@ -14497,9 +14513,9 @@ snapshots: '@typescript-eslint/types': 8.56.1 eslint-visitor-keys: 5.0.1 - '@typescript-eslint/visitor-keys@8.64.0': + '@typescript-eslint/visitor-keys@8.65.0': dependencies: - '@typescript-eslint/types': 8.64.0 + '@typescript-eslint/types': 8.65.0 eslint-visitor-keys: 5.0.1 '@typescript/typescript-aix-ppc64@7.0.2': @@ -16565,18 +16581,18 @@ snapshots: esquery: 1.7.0 jsonc-eslint-parser: 3.1.0 - eslint-module-utils@2.13.0(@typescript-eslint/parser@8.64.0)(eslint-import-resolver-node@0.3.10)(eslint@10.7.0)(supports-color@10.2.2): + eslint-module-utils@2.13.0(@typescript-eslint/parser@8.65.0)(eslint-import-resolver-node@0.3.10)(eslint@10.7.0)(supports-color@10.2.2): dependencies: '@types/debug': 4.1.13 debug: 3.2.7(supports-color@10.2.2) optionalDependencies: - '@typescript-eslint/parser': 8.64.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/parser': 8.65.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) eslint: 10.7.0(@types/eslint@9.6.1)(jiti@2.7.0)(supports-color@10.2.2) eslint-import-resolver-node: 0.3.10(supports-color@10.2.2) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.64.0)(eslint@10.7.0)(supports-color@10.2.2): + eslint-plugin-import@2.32.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.65.0)(eslint@10.7.0)(supports-color@10.2.2): dependencies: '@rtsao/scc': 1.1.0 '@types/eslint': 9.6.1 @@ -16588,7 +16604,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.7.0(@types/eslint@9.6.1)(jiti@2.7.0)(supports-color@10.2.2) eslint-import-resolver-node: 0.3.10(supports-color@10.2.2) - eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.64.0)(eslint-import-resolver-node@0.3.10)(eslint@10.7.0)(supports-color@10.2.2) + eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.65.0)(eslint-import-resolver-node@0.3.10)(eslint@10.7.0)(supports-color@10.2.2) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -16600,7 +16616,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.64.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/parser': 8.65.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -21209,12 +21225,12 @@ snapshots: typescript: 7.0.2 yaml: 2.9.0 - typescript-eslint@8.64.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2): + typescript-eslint@8.65.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.64.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.64.0)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) - '@typescript-eslint/parser': 8.64.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) - '@typescript-eslint/typescript-estree': 8.64.0(supports-color@10.2.2)(typescript@7.0.2) - '@typescript-eslint/utils': 8.64.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/eslint-plugin': 8.65.0(@types/eslint@9.6.1)(@typescript-eslint/parser@8.65.0)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/parser': 8.65.0(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/typescript-estree': 8.65.0(supports-color@10.2.2)(typescript@7.0.2) + '@typescript-eslint/utils': 8.65.0(@types/eslint@9.6.1)(eslint@10.7.0)(supports-color@10.2.2)(typescript@7.0.2) eslint: 10.7.0(@types/eslint@9.6.1)(jiti@2.7.0)(supports-color@10.2.2) typescript: 7.0.2 transitivePeerDependencies: @@ -22088,8 +22104,8 @@ time: '@types/fs-extra@11.0.4': '2023-11-07T20:15:59.748Z' '@types/node@26.1.1': '2026-07-08T06:47:46.733Z' '@types/wordcloud@1.2.2': '2023-11-07T19:21:56.870Z' - '@typescript-eslint/eslint-plugin@8.64.0': '2026-07-13T17:39:22.423Z' - '@typescript-eslint/parser@8.64.0': '2026-07-13T17:39:00.545Z' + '@typescript-eslint/eslint-plugin@8.65.0': '2026-07-20T17:39:25.625Z' + '@typescript-eslint/parser@8.65.0': '2026-07-20T17:39:03.395Z' '@typescript/typescript6@6.0.2': '2026-07-06T18:06:47.459Z' '@vite-pwa/assets-generator@1.0.2': '2025-10-14T13:40:10.449Z' '@vitejs/devtools@0.4.1': '2026-07-14T04:11:17.577Z' @@ -22174,7 +22190,7 @@ time: typedoc-plugin-skillit@2.0.1: '2026-07-03T04:50:22.123Z' typedoc-plugin-version-header@1.0.0: '2024-10-05T02:15:15.718Z' typedoc@0.28.20: '2026-07-05T22:54:07.305Z' - typescript-eslint@8.64.0: '2026-07-13T17:39:29.371Z' + typescript-eslint@8.65.0: '2026-07-20T17:39:32.402Z' typescript@7.0.2: '2026-07-08T15:55:18.431Z' unplugin-dts@1.0.3: '2026-06-24T08:15:01.703Z' unplugin-info@1.3.2: '2026-03-30T11:56:02.951Z' diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 7c89fd28..4ce1dad3 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -48,8 +48,8 @@ catalogs: "@types/fs-extra": 11.0.4 "@types/node": 26.1.1 "@types/wordcloud": 1.2.2 - "@typescript-eslint/eslint-plugin": 8.64.0 - "@typescript-eslint/parser": 8.64.0 + "@typescript-eslint/eslint-plugin": 8.65.0 + "@typescript-eslint/parser": 8.65.0 "@typescript/typescript6": 6.0.2 "@vite-pwa/assets-generator": 1.0.2 "@vitejs/devtools": 0.4.1 @@ -128,7 +128,7 @@ catalogs: typedoc-plugin-skillit: 2.0.1 typedoc-plugin-version-header: 1.0.0 typescript: 7.0.2 - typescript-eslint: 8.64.0 + typescript-eslint: 8.65.0 unplugin-dts: 1.0.3 unplugin-info: 1.3.2 vite: 8.1.5 diff --git a/sites/docs/.config/mise/config.toml b/sites/docs/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/sites/docs/.config/mise/config.toml +++ b/sites/docs/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" diff --git a/sites/portfolio/.config/mise/config.toml b/sites/portfolio/.config/mise/config.toml index 9185b650..81943bbf 100644 --- a/sites/portfolio/.config/mise/config.toml +++ b/sites/portfolio/.config/mise/config.toml @@ -5,5 +5,5 @@ "npm:vite" = "8.1.5" pnpm = "11.15.1" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" npm = "12.0.0" From e75c8a312a0d134b53528abf090027bfa1a04ccb Mon Sep 17 00:00:00 2001 From: "Franco N. Colaizzi" Date: Wed, 22 Jul 2026 00:31:49 -0400 Subject: [PATCH 02/14] cleans up a lot of impls --- .vscode/settings.json | 7 +- .../functions/node/.config/mise/config.toml | 2 +- .../src/bento-layout/bento-layout.ts | 26 +++--- .../components/src/card/blog/blog-card.ts | 2 +- .../components/src/card/code/code-card.ts | 2 +- .../connections/connections-card.styles.ts | 58 +++++++------ .../src/card/connections/connections-card.ts | 8 ++ .../src/card/experience/experience-card.ts | 2 +- .../src/card/profile/profile-card.ts | 6 +- .../src/card/settings/settings-card.ts | 2 +- packages/data/src/bento-layout/index.ts | 86 +++---------------- .../assets/css/_material-overrides.css | 2 +- .../design-tokens/assets/css/_variables.css | 2 +- .../design-tokens/assets/css/icon-svg.css | 2 +- packages/types/src/bento-layout/index.ts | 60 +++---------- packages/types/src/bio/index.ts | 8 +- 16 files changed, 97 insertions(+), 178 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 93ab0cd8..c235205b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -24,7 +24,7 @@ "editor.wordBasedSuggestions": "off" }, "[toml]": { - "editor.defaultFormatter": "tamasfe.even-better-toml", + "editor.defaultFormatter": "tombi-toml.tombi", "editor.detectIndentation": true }, "[typescript]": { @@ -750,5 +750,8 @@ "**/zlogout" ], "zshellcheck.run": "onSave", - "zshellcheck.useWorkspaceRootAsCwd": true + "zshellcheck.useWorkspaceRootAsCwd": true, + "[postcss]": { + "editor.defaultFormatter": "stylelint.vscode-stylelint" + } } \ No newline at end of file diff --git a/firebase/functions/node/.config/mise/config.toml b/firebase/functions/node/.config/mise/config.toml index 59485b54..d00ef928 100644 --- a/firebase/functions/node/.config/mise/config.toml +++ b/firebase/functions/node/.config/mise/config.toml @@ -2,7 +2,7 @@ firebase = "15.24.0" node = "26.5.0" tombi = "1.1.5" - usage = "3.5.5" + usage = "3.5.6" pnpm = "11.15.1" "npm:vite" = "8.1.5" "npm:corepack" = "0.35.0" diff --git a/packages/components/src/bento-layout/bento-layout.ts b/packages/components/src/bento-layout/bento-layout.ts index 0e43840c..14e22dab 100644 --- a/packages/components/src/bento-layout/bento-layout.ts +++ b/packages/components/src/bento-layout/bento-layout.ts @@ -1,10 +1,10 @@ import { BentoLayoutStyles, TransitionStyles } from "@/lib/bento-layout/bento-layout.styles"; import { UIAwareElement } from "@/lib/mixins/ui-aware-element/ui-aware-element"; import { TextStyles } from "@/lib/styles"; -import { BentoBoxConfigsArray, titles } from "@fnc314/packages.data"; -import { type ABentoBoxConfig, BENTO_BOX_TYPES, BreakpointLabels } from "@fnc314/packages.types"; +import { BENTO_BOX_CONFIG, titles } from "@fnc314/packages.data"; +import { BENTO_BOX_TYPES, type BentoBoxConfig, type BentoBoxType, BreakpointLabels } from "@fnc314/packages.types"; import { type TemplateResult, html, nothing } from "lit"; -import { customElement, state } from "lit/decorators.js"; +import { customElement } from "lit/decorators.js"; import { styleMap } from "lit/directives/style-map.js"; import { unsafeHTML } from "lit/directives/unsafe-html.js"; import { author } from "~build/package"; @@ -21,13 +21,10 @@ export class BentoLayout extends UIAwareElement { /** {@link @lit/reactive-element!css} */ static override styles = [TextStyles, BentoLayoutStyles, TransitionStyles]; - @state() - private _bentoBoxConfigs: ABentoBoxConfig[] = BentoBoxConfigsArray(this.breakpoint); - - private renderBentoBox(config: ABentoBoxConfig): TemplateResult { + private renderBentoBox(configName: BentoBoxType, config: BentoBoxConfig): TemplateResult { let cardStyles = { }; if (this.breakpoint !== BreakpointLabels.mobile) { - cardStyles = { gridArea: config.type }; + cardStyles = { gridArea: configName }; } cardStyles = { @@ -35,7 +32,7 @@ export class BentoLayout extends UIAwareElement { blockSize: "100%" }; - switch (config.type) { + switch (configName) { case BENTO_BOX_TYPES.profile: return html` `; - const boxes = this._bentoBoxConfigs.map((boxConfig) => this.renderBentoBox(boxConfig)); + const boxes = Object + .entries(BENTO_BOX_CONFIG) + .sort( + (configA: [string, BentoBoxConfig], configB: [string, BentoBoxConfig]) => + configA[1].order - configB[1].order + ) + .map( + ([configName, boxConfig]: [string, BentoBoxConfig]) => + this.renderBentoBox(configName as BentoBoxType, boxConfig) + ); return html`
${header} diff --git a/packages/components/src/card/blog/blog-card.ts b/packages/components/src/card/blog/blog-card.ts index 40204be1..5a32a5b8 100644 --- a/packages/components/src/card/blog/blog-card.ts +++ b/packages/components/src/card/blog/blog-card.ts @@ -29,7 +29,7 @@ export class BlogCard extends UIAwareElement { override connectedCallback() { super.connectedCallback(); - this.id = "blog"; + this.id = BENTO_BOX_TYPES.blog; } override render() { diff --git a/packages/components/src/card/code/code-card.ts b/packages/components/src/card/code/code-card.ts index a034cfd8..e7ef5324 100644 --- a/packages/components/src/card/code/code-card.ts +++ b/packages/components/src/card/code/code-card.ts @@ -29,7 +29,7 @@ export class CodeCard extends UIAwareElement { override connectedCallback() { super.connectedCallback(); - this.id = "code"; + this.id = BENTO_BOX_TYPES.code; } override render() { diff --git a/packages/components/src/card/connections/connections-card.styles.ts b/packages/components/src/card/connections/connections-card.styles.ts index 5482d9c2..e30807a5 100644 --- a/packages/components/src/card/connections/connections-card.styles.ts +++ b/packages/components/src/card/connections/connections-card.styles.ts @@ -32,37 +32,39 @@ export const ConnectionsCardStyles: CSSResult = css` --md-filled-icon-button-hover-icon-color: var(--connections-card-filled-icon-button-icon-color); } - dl { - display: flex; - flex-direction: row; - gap: var(--spaces-gap-s); - flex-wrap: wrap; - justify-content: space-around; + article { + dl { + display: flex; + flex-direction: row; + gap: var(--spaces-gap-s); + flex-wrap: wrap; + justify-content: space-around; - div { - display: grid; - grid-template-rows: min-content auto; - grid-template-columns: repeat(var(--dl-div-column-count), 1fr); - row-gap: var(--spaces-gap-s); - column-gap: var(--spaces-gap-xs); - place-items: center; - border-radius: var(--connections-card-filled-icon-button-container-shape); - border: solid var(--sizes-thickness-xxs) var(--connections-card-filled-icon-button-icon-color); - background-color: var(--md-sys-color-surface-container-highest); - padding-block: var(--spaces-padding-s); - flex: 1 0 min-content; + div { + display: grid; + grid-template-rows: min-content auto; + grid-template-columns: repeat(var(--dl-div-column-count), 1fr); + row-gap: var(--spaces-gap-s); + column-gap: var(--spaces-gap-xs); + place-items: center; + border-radius: var(--connections-card-filled-icon-button-container-shape); + border: solid var(--sizes-thickness-xxs) var(--connections-card-filled-icon-button-icon-color); + background-color: var(--md-sys-color-surface-container-highest); + padding-block: var(--spaces-padding-s); + flex: 1 0 min-content; - dt { - grid-row: 1 / 2; - grid-column: span var(--dl-div-column-count); - color: var(--connections-card-filled-icon-button-icon-color); - } + dt { + grid-row: 1 / 2; + grid-column: span var(--dl-div-column-count); + color: var(--connections-card-filled-icon-button-icon-color); + } - dd { - grid-row: 2 / 3; - margin: unset; - border: solid var(--sizes-thickness-xxs) var(--connections-card-filled-icon-button-icon-color); - border-radius: var(--connections-card-filled-icon-button-container-shape); + dd { + grid-row: 2 / 3; + margin: unset; + border: solid var(--sizes-thickness-xxs) var(--connections-card-filled-icon-button-icon-color); + border-radius: var(--connections-card-filled-icon-button-container-shape); + } } } } diff --git a/packages/components/src/card/connections/connections-card.ts b/packages/components/src/card/connections/connections-card.ts index f9a6a913..a96e3dcc 100644 --- a/packages/components/src/card/connections/connections-card.ts +++ b/packages/components/src/card/connections/connections-card.ts @@ -6,6 +6,14 @@ import { type ArtifactConnectionData, type ArtifactConnectionType, BENTO_BOX_TYP import { type TemplateResult, html } from "lit"; import { customElement, property } from "lit/decorators.js"; +/** + * @summary The collection of connection components wrapped in a `dl` + * + * @export + * @class ConnectionsCard + * @typedef {ConnectionsCard} + * @extends {UIAwareElement} + */ @customElement("connections-card") export class ConnectionsCard extends UIAwareElement { diff --git a/packages/components/src/card/experience/experience-card.ts b/packages/components/src/card/experience/experience-card.ts index 9f1602e7..2c565449 100644 --- a/packages/components/src/card/experience/experience-card.ts +++ b/packages/components/src/card/experience/experience-card.ts @@ -29,7 +29,7 @@ export class ExperienceCard extends UIAwareElement { override connectedCallback() { super.connectedCallback(); - this.id = "experience"; + this.id = BENTO_BOX_TYPES.experience; } override render() { diff --git a/packages/components/src/card/profile/profile-card.ts b/packages/components/src/card/profile/profile-card.ts index be35b5a8..8080e7a9 100644 --- a/packages/components/src/card/profile/profile-card.ts +++ b/packages/components/src/card/profile/profile-card.ts @@ -26,10 +26,10 @@ export class ProfileCard extends UIAwareElement { photoData = Photos[configsService.loadConfigs().colorScheme.theme]; @property({ type: Object }) - aboutMe: BioExtended = Biographies.bio.extended; + aboutMe: BioExtended = Biographies.extended; @property({ type: Boolean }) - expanded = false; + expanded = true; @property({ type: Boolean }) enableHover = false; @@ -39,7 +39,7 @@ export class ProfileCard extends UIAwareElement { override connectedCallback() { super.connectedCallback(); - this.id = "bio"; + this.id = BENTO_BOX_TYPES.profile; configsService.addEventListener(APP_CONFIGS_CHANGE_EVENT_NAME, this._onConfigChange); } diff --git a/packages/components/src/card/settings/settings-card.ts b/packages/components/src/card/settings/settings-card.ts index c6f4b1e2..2d38ba75 100644 --- a/packages/components/src/card/settings/settings-card.ts +++ b/packages/components/src/card/settings/settings-card.ts @@ -51,7 +51,7 @@ export class SettingsCard extends UIAwareElement { override connectedCallback() { super.connectedCallback(); - this.id = "settings"; + this.id = BENTO_BOX_TYPES.settings; configsService.addEventListener(APP_CONFIGS_CHANGE_EVENT_NAME, this.onAppConfigsChange); } diff --git a/packages/data/src/bento-layout/index.ts b/packages/data/src/bento-layout/index.ts index 2473b9ca..9ddbebe0 100644 --- a/packages/data/src/bento-layout/index.ts +++ b/packages/data/src/bento-layout/index.ts @@ -1,9 +1,7 @@ import { - type ABentoBoxConfig, type BentoBoxConfigs, - type BentoBoxType, type BreakpointLabel, - BreakpointLabels, + BreakpointLabels } from "@fnc314/packages.types"; /** Titles to grab attention, joined with `|` but in HTML Entity Code (`|`) */ @@ -16,99 +14,35 @@ export const titles: string = [ /** The final rendered {@link BentoBoxConfigs} */ export const BENTO_BOX_CONFIG: BentoBoxConfigs = { profile: { - placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 4, rowSpan: 2 }, order: 1 }, - tablet: { breakpoint: "tablet", offsets: { row: 1 }, span: { colSpan: 2, rowSpan: 1 }, order: 1 }, - mobile: { breakpoint: "mobile", order: 1 }, - }, isExpanded: () => true, + order: 1, }, connections: { - placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 8, rowSpan: 1 }, order: 2 }, - tablet: { breakpoint: "tablet", span: { colSpan: 4, rowSpan: 1 }, order: 2 }, - mobile: { breakpoint: "mobile", order: 2 }, - }, isExpanded: () => true, + order: 2, }, experience: { - placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 8, rowSpan: 1 }, order: 3 }, - tablet: { breakpoint: "tablet", span: { colSpan: 4, rowSpan: 1 }, order: 3 }, - mobile: { breakpoint: "mobile", order: 3 }, - }, isExpanded: (breakpoint: BreakpointLabel) => breakpoint !== BreakpointLabels.mobile, + order: 3, }, code: { - placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 6, rowSpan: 1 }, order: 4 }, - tablet: { breakpoint: "tablet", span: { colSpan: 3, rowSpan: 1 }, order: 4 }, - mobile: { breakpoint: "mobile", order: 4 }, - }, isExpanded: (breakpoint: BreakpointLabel) => breakpoint !== BreakpointLabels.mobile, + order: 4, }, blog: { - placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 6, rowSpan: 1 }, order: 5 }, - tablet: { breakpoint: "tablet", span: { colSpan: 3, rowSpan: 1 }, order: 5 }, - mobile: { breakpoint: "mobile", order: 5 }, - }, isExpanded: (breakpoint: BreakpointLabel) => breakpoint !== BreakpointLabels.mobile, + order: 5, }, skills: { - placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 7, rowSpan: 2 }, order: 6 }, - tablet: { breakpoint: "tablet", span: { colSpan: 4, rowSpan: 1 }, order: 6 }, - mobile: { breakpoint: "mobile", order: 6 }, - }, isExpanded: () => false, + order: 6, }, education: { - placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 5, rowSpan: 1 }, order: 7 }, - tablet: { breakpoint: "tablet", span: { colSpan: 2, rowSpan: 1 }, order: 7 }, - mobile: { breakpoint: "mobile", order: 7 }, - }, isExpanded: () => false, + order: 7, }, settings: { - placement: { - desktop: { breakpoint: "desktop", span: { colSpan: 12, rowSpan: 1 }, order: 8 }, - tablet: { breakpoint: "tablet", span: { colSpan: 6, rowSpan: 1 }, order: 8 }, - mobile: { breakpoint: "mobile", order: 8 }, - }, isExpanded: () => false, + order: 8, } -}; - -/** - * Determines the logical DOM order for bento box types based on grid placement. - * Reading order follows Top-to-Bottom, then Start-to-End (Leading-to-Trailing). - * - * @param breakpoint - The current active breakpoint. - * @returns An array of {@link BentoBoxType} in the appropriate order for the DOM. - */ -export function getBentoDOMOrder(breakpoint: BreakpointLabel): BentoBoxType[] { - // Use desktop as the sequence authority if we are on a non-grid breakpoint (mobile) - const sortBreakpoint = breakpoint === "mobile" ? "desktop" : breakpoint; - const types = Object.keys(BENTO_BOX_CONFIG) as BentoBoxType[]; - - return types.sort((a, b) => { - const posA = BENTO_BOX_CONFIG[a].placement[sortBreakpoint]; - const posB = BENTO_BOX_CONFIG[b].placement[sortBreakpoint]; - - if ("order" in posA && "order" in posB) { - return posA.order - posB.order; - } - return 0; - }); -} - -/** - * Produces an array of {@link ABentoBoxConfig} instances sorted for proper DOM order. - */ -export const BentoBoxConfigsArray = (breakpoint: BreakpointLabel = "desktop"): ABentoBoxConfig[] => - getBentoDOMOrder(breakpoint).map((type) => ({ - type, - ...BENTO_BOX_CONFIG[type], - })); +}; \ No newline at end of file diff --git a/packages/design-tokens/assets/css/_material-overrides.css b/packages/design-tokens/assets/css/_material-overrides.css index 38e2f1b8..649f04f0 100644 --- a/packages/design-tokens/assets/css/_material-overrides.css +++ b/packages/design-tokens/assets/css/_material-overrides.css @@ -1,6 +1,6 @@ /** * Do not edit directly, this file was auto-generated. - * Generated on Tue, 21 Jul 2026 04:46:55 GMT + * Generated on Wed, 22 Jul 2026 04:27:34 GMT */ :root { diff --git a/packages/design-tokens/assets/css/_variables.css b/packages/design-tokens/assets/css/_variables.css index e9c73c88..db1e59ae 100644 --- a/packages/design-tokens/assets/css/_variables.css +++ b/packages/design-tokens/assets/css/_variables.css @@ -1,6 +1,6 @@ /** * Do not edit directly, this file was auto-generated. - * Generated on Tue, 21 Jul 2026 04:46:55 GMT + * Generated on Wed, 22 Jul 2026 04:27:34 GMT */ :root { diff --git a/packages/design-tokens/assets/css/icon-svg.css b/packages/design-tokens/assets/css/icon-svg.css index 7b74d5d1..ad0b2bad 100644 --- a/packages/design-tokens/assets/css/icon-svg.css +++ b/packages/design-tokens/assets/css/icon-svg.css @@ -1,6 +1,6 @@ /** * Do not edit directly, this file was auto-generated. - * Generated on Tue, 21 Jul 2026 04:46:55 GMT + * Generated on Wed, 22 Jul 2026 04:27:34 GMT */ :root { diff --git a/packages/types/src/bento-layout/index.ts b/packages/types/src/bento-layout/index.ts index 08eb061a..b973cc39 100644 --- a/packages/types/src/bento-layout/index.ts +++ b/packages/types/src/bento-layout/index.ts @@ -1,49 +1,12 @@ import { type BreakpointLabel } from "@/lib/design-tokens"; /** - * Defines the column and row span for dense auto-flow grid - * - * @typedef GridSpan - */ -export interface GridSpan { - colSpan: number; - rowSpan: number; -} - -/** - * The span and order for a given breakpoint - * - * @typedef GridPosition - */ -export type GridPosition = - | { - /** The breakpoint for this position */ - breakpoint: Exclude; - /** The grid span */ - span: GridSpan; - /** The logical order in the DOM */ - order: number; - /** Offsets */ - offsets?: { - row?: number | 0; - col?: number | 0; - }; - } - | { - /** The breakpoint for this position */ - breakpoint: Extract; - /** The logical order in the DOM */ - order: number; - }; - -/** - * The finite `bento-box` instances + * @summary The finite `bento-box` instances * * @typedef {BentoBoxType} */ -export type BentoBoxType = "profile" | "experience" | "code" | "blog" | "settings" | "education" | "skills"; +export type BentoBoxType = keyof typeof BENTO_BOX_TYPES; -// "now-playing" /** A {@link Record} of {@link BentoBoxType} definitions */ export const BENTO_BOX_TYPES = { profile: "profile" as const, @@ -53,19 +16,24 @@ export const BENTO_BOX_TYPES = { settings: "settings" as const, education: "education" as const, skills: "skills" as const, - // "now-playing": "now-playing" as const, + connections: "connections" as const, } as const; /** - * Defines the {@link BentoBoxType} coupled with a {@link GridPosition} used - * to place a particular `bento-box`. + * @summary Defines the {@link BentoBoxType} coupled with a {@link GridPosition} + * used to place a particular `bento-box`. * * @interface BentoBoxConfig */ -export interface ABentoBoxConfig { - type: BentoBoxType; - placement: Record; +export interface BentoBoxConfig { isExpanded: (breakpoint: BreakpointLabel) => boolean; + order: number; } -export type BentoBoxConfigs = Record>; +/** + * @summary The complete configuration for `bento-layout` + * + * @export + * @typedef {BentoBoxConfigs} + */ +export type BentoBoxConfigs = Record; diff --git a/packages/types/src/bio/index.ts b/packages/types/src/bio/index.ts index 596d81f4..e580905e 100644 --- a/packages/types/src/bio/index.ts +++ b/packages/types/src/bio/index.ts @@ -1,9 +1,7 @@ export interface Bio { - bio: { - short: string; - long: string; - extended: BioExtended; - }; + short: string; + long: string; + extended: BioExtended; }; export interface BioExtended { From bab1a78a4203143c0802b27519da0cb0f1082213 Mon Sep 17 00:00:00 2001 From: "Franco N. Colaizzi" Date: Wed, 22 Jul 2026 05:35:26 -0400 Subject: [PATCH 03/14] popover refinements --- .../src/bento-layout/bento-layout.styles.ts | 1 + .../src/card/bento/bento-card.styles.ts | 6 +- .../components/src/card/blog/blog-card.ts | 2 +- .../components/src/card/code/code-card.ts | 10 +- .../src/card/experience/experience-card.ts | 9 +- .../src/card/settings/settings-card.styles.ts | 6 +- .../src/card/settings/settings-card.ts | 6 +- packages/components/src/index.ts | 21 +--- .../components/src/version-tag/version-tag.ts | 27 ++-- .../src/word/popover/word-popover.styles.ts | 39 ++++++ .../src/word/popover/word-popover.ts | 66 ++++++++++ .../src/word/tag/word-tag.styles.ts | 9 +- packages/components/src/word/tag/word-tag.ts | 117 +++++++++++++----- .../components/src/word/tag/word-tag.types.ts | 32 +++-- packages/data/src/code/index.ts | 34 +++++ packages/types/src/code/index.ts | 17 ++- sites/portfolio/index.css | 3 +- 17 files changed, 314 insertions(+), 91 deletions(-) create mode 100644 packages/components/src/word/popover/word-popover.styles.ts create mode 100644 packages/components/src/word/popover/word-popover.ts diff --git a/packages/components/src/bento-layout/bento-layout.styles.ts b/packages/components/src/bento-layout/bento-layout.styles.ts index be8ed669..4d770803 100644 --- a/packages/components/src/bento-layout/bento-layout.styles.ts +++ b/packages/components/src/bento-layout/bento-layout.styles.ts @@ -16,6 +16,7 @@ export const BentoLayoutStyles = css` --bento-layout-card-background: var(--md-sys-color-surface-container-lowest); --bento-layout-card-color: var(--md-sys-color-on-surface); --bento-layout-card-shape: var(--md-sys-shape-corner-medium); + --bento-layout-card-border-color: var(--md-sys-color-primary); background-color: var(--globals-color-background); color: var(--md-sys-color-on-surface); diff --git a/packages/components/src/card/bento/bento-card.styles.ts b/packages/components/src/card/bento/bento-card.styles.ts index 2e47158f..7a370072 100644 --- a/packages/components/src/card/bento/bento-card.styles.ts +++ b/packages/components/src/card/bento/bento-card.styles.ts @@ -20,7 +20,7 @@ export const BentoCardStyles = css` display: block; inline-size: 100%; - --md-focus-ring-shape: var(--md-sys-shape-corner-small); + --md-focus-ring-shape: var(--bento-layout-card-shape); } article { @@ -28,6 +28,8 @@ export const BentoCardStyles = css` flex-direction: column; justify-content: center; align-items: stretch; + border-radius: var(--bento-layout-card-shape); + border: solid var(--sizes-thickness-hairline) var(--bento-layout-card-border-color); &:has(details[open]) { } @@ -45,8 +47,8 @@ export const BentoCardStyles = css` color: var(--bento-layout-card-color); display: flex; flex-direction: column; - padding: var(--spaces-padding-s); + will-change: transform, box-shadow, border-color, background-color; transition: transform var(--motions-duration-short) var(--motions-easing-emphasized), box-shadow var(--motions-duration-short) var(--motions-easing-base), diff --git a/packages/components/src/card/blog/blog-card.ts b/packages/components/src/card/blog/blog-card.ts index 5a32a5b8..47b1a404 100644 --- a/packages/components/src/card/blog/blog-card.ts +++ b/packages/components/src/card/blog/blog-card.ts @@ -44,7 +44,7 @@ export class BlogCard extends UIAwareElement { .bentoTag=${BENTO_BOX_TYPES.blog} >
- ${Blogs.map((entry: BlogEntryJson) => html` `)} + ${Blogs.map((blogEntry: BlogEntryJson) => html``)}
`; diff --git a/packages/components/src/card/code/code-card.ts b/packages/components/src/card/code/code-card.ts index e7ef5324..21429d84 100644 --- a/packages/components/src/card/code/code-card.ts +++ b/packages/components/src/card/code/code-card.ts @@ -9,7 +9,7 @@ import { html } from "lit"; import { customElement, property } from "lit/decorators.js"; /** - * @summary CodeCard - A card component displaying code projects. + * @summary A card component displaying code projects. * * @element code-card */ @@ -43,7 +43,13 @@ export class CodeCard extends UIAwareElement { .bentoCardTitle=${"Code"} .bentoTag=${BENTO_BOX_TYPES.code} > -
${Projects.map((p) => html` `)}
+
+ ${ + Projects.map((codeRepo) => html` + + `) + } +
`; } diff --git a/packages/components/src/card/experience/experience-card.ts b/packages/components/src/card/experience/experience-card.ts index 2c565449..a3061c9e 100644 --- a/packages/components/src/card/experience/experience-card.ts +++ b/packages/components/src/card/experience/experience-card.ts @@ -9,7 +9,7 @@ import { html } from "lit"; import { customElement, property } from "lit/decorators.js"; /** - * @summary WorkCard - A card component displaying work experience. + * @summary A card component displaying work experience. * * @element experience-card */ @@ -43,8 +43,8 @@ export class ExperienceCard extends UIAwareElement { .bentoCardTitle=${"Experience"} .bentoTag=${BENTO_BOX_TYPES.experience} > - ${Experiences.map( - (exp) => html` + ${ + Experiences.map((exp) => html` `, - )} + ) + } `; } diff --git a/packages/components/src/card/settings/settings-card.styles.ts b/packages/components/src/card/settings/settings-card.styles.ts index 8da8f26b..b5027901 100644 --- a/packages/components/src/card/settings/settings-card.styles.ts +++ b/packages/components/src/card/settings/settings-card.styles.ts @@ -6,7 +6,7 @@ export const SettingsCardStyles: CSSResult = css` display: block; } - .settings-content { + article { display: flex; flex: 1; flex-direction: column; @@ -57,13 +57,13 @@ export const SettingsCardStyles: CSSResult = css` } } - version-tag { + footer { padding-block-start: var(--spaces-padding-m); } } @media screen and (width >= 1201px) { - .settings-content { + article { form { flex-direction: row; justify-content: space-evenly; diff --git a/packages/components/src/card/settings/settings-card.ts b/packages/components/src/card/settings/settings-card.ts index 2d38ba75..d73dffa8 100644 --- a/packages/components/src/card/settings/settings-card.ts +++ b/packages/components/src/card/settings/settings-card.ts @@ -178,7 +178,7 @@ export class SettingsCard extends UIAwareElement { .bentoCardTitle=${"Settings"} .bentoTag=${BENTO_BOX_TYPES.settings} > -
+
- +
+ +
`; diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 6edbc41f..d2728108 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -7,6 +7,7 @@ export { BlogCardStyles } from "@/lib/card/blog/blog-card.styles"; export { CodeCard } from "@/lib/card/code/code-card"; export { CodeCardStyles } from "@/lib/card/code/code-card.styles"; export { ConnectionsCard } from "@/lib/card/connections/connections-card"; +export { ConnectionsCardStyles, DL_DIV_COLUMN_COUNT } from "@/lib/card/connections/connections-card.styles"; export { EducationCard } from "@/lib/card/education/education-card"; export { EducationCardStyles } from "@/lib/card/education/education-card.styles"; export { ExperienceCard } from "@/lib/card/experience/experience-card"; @@ -39,22 +40,10 @@ export { UIModeToggleStyles } from "@/lib/ui-mode-toggle/ui-mode-toggle.styles"; export { VersionTag } from "@/lib/version-tag/version-tag"; export { WordCloud } from "@/lib/word/cloud/word-cloud"; export { WordCloudStyles } from "@/lib/word/cloud/word-cloud.styles"; -export { - WordCloudAppearances, - WordCloudGroupings, - WordCloudSortings, - makeWordCloudWord -} from "@/lib/word/cloud/word-cloud.types"; -export type { - RenderableWordCloudWord, - WeightQuartile, - Weights, - WordCloudAppearance, - WordCloudGrouping, - WordCloudSorting, - WordCloudWord, - WordCloudWordCategory -} from "@/lib/word/cloud/word-cloud.types"; +export { WordCloudAppearances, WordCloudGroupings, WordCloudSortings, makeWordCloudWord } from "@/lib/word/cloud/word-cloud.types"; +export type { RenderableWordCloudWord, WeightQuartile, Weights, WordCloudAppearance, WordCloudGrouping, WordCloudSorting, WordCloudWord, WordCloudWordCategory } from "@/lib/word/cloud/word-cloud.types"; +export { WordPopover } from "@/lib/word/popover/word-popover"; +export { WordPopoverStyles } from "@/lib/word/popover/word-popover.styles"; export { WordTag } from "@/lib/word/tag/word-tag"; export { WordTagStyles } from "@/lib/word/tag/word-tag.styles"; export { WordTagVariantAttributeConverter } from "@/lib/word/tag/word-tag.types"; diff --git a/packages/components/src/version-tag/version-tag.ts b/packages/components/src/version-tag/version-tag.ts index ba3c94e9..89b1c8f1 100644 --- a/packages/components/src/version-tag/version-tag.ts +++ b/packages/components/src/version-tag/version-tag.ts @@ -16,7 +16,7 @@ export class VersionTag extends UIAwareElement { text-align: center; } - div { + aside { align-items: center; display: flex; flex-direction: row; @@ -37,22 +37,25 @@ export class VersionTag extends UIAwareElement { * @private * @type {string} */ - private formattedDate: string = new Intl.DateTimeFormat(navigator.languages, { - hour: "2-digit", - minute: "2-digit", - second: "2-digit", - month: "2-digit", - day: "2-digit", - year: "numeric", - hour12: false, - }).format(time); + private formattedDate: string = new Intl.DateTimeFormat( + navigator.languages, + { + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + month: "2-digit", + day: "2-digit", + year: "numeric", + hour12: false, + } + ).format(time); override render() { return html` -
+
+ `; } } diff --git a/packages/components/src/word/popover/word-popover.styles.ts b/packages/components/src/word/popover/word-popover.styles.ts new file mode 100644 index 00000000..052d4d05 --- /dev/null +++ b/packages/components/src/word/popover/word-popover.styles.ts @@ -0,0 +1,39 @@ +import { type CSSResult, css } from "lit"; + +export const WordPopoverStyles: CSSResult = css` + :host { + + } + + article { + display: flex; + flex-direction: column; + block-size: 75%; + inline-size: 75%; + overflow-y: auto; + overscroll-behavior: contain; + background-color: var(--md-sys-color-surface); + color: var(--md-sys-color-on-surface); + + header { + h3 { + + } + } + + section { + + } + + footer { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + a { + + } + } + } +`; \ No newline at end of file diff --git a/packages/components/src/word/popover/word-popover.ts b/packages/components/src/word/popover/word-popover.ts new file mode 100644 index 00000000..1c828fce --- /dev/null +++ b/packages/components/src/word/popover/word-popover.ts @@ -0,0 +1,66 @@ +import { UIAwareElement } from "@/lib/mixins/ui-aware-element/ui-aware-element"; +import { TextStyles } from "@/lib/styles"; +import { WordPopoverStyles } from "@/lib/word/popover/word-popover.styles"; +import { type TemplateResult, html } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; + +/** + * @summary A `popover` `HTML` element displayed instead of launching clicks + * on {@link WordTag}s + * + * @export + * @class WordPopover + * @typedef {WordPopover} + * @extends {UIAwareElement} + */ +@customElement("word-popover") +export class WordPopover extends UIAwareElement { + static override styles = [ + TextStyles, + WordPopoverStyles + ] + + @property({ type: String }) + word = ""; + + @property({ type: String }) + popoverId: string = this.word; + + @property({ type: Object }) + footerURL: { text: string, url: string } = { text: this.word, url: "" } + + override render(): TemplateResult { + return html` + + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "word-popover": WordPopover; + } +} \ No newline at end of file diff --git a/packages/components/src/word/tag/word-tag.styles.ts b/packages/components/src/word/tag/word-tag.styles.ts index bead487f..87fc3878 100644 --- a/packages/components/src/word/tag/word-tag.styles.ts +++ b/packages/components/src/word/tag/word-tag.styles.ts @@ -29,6 +29,9 @@ export const WordTagStyles: CSSResult = css` /** @ignore */ --internal-word-tag-gap: var(--word-tag-gap, var(--spaces-gap-xs)); + /** @ignore */ + --internal-word-tag-backdrop-blur: var(--word-tag-backdrop-blur, 0.25rem); + display: contents; @media (prefers-reduced-motion: reduce) { @@ -36,7 +39,11 @@ export const WordTagStyles: CSSResult = css` } } - .word-tag-variant-wrapper { + ::backdrop { + backdrop-filter: blur(var(--internal-word-tag-backdrop-blur)); + } + + button, div { align-items: center; background-color: var(--internal-word-tag-background-color); border-color: var(--internal-word-tag-color); diff --git a/packages/components/src/word/tag/word-tag.ts b/packages/components/src/word/tag/word-tag.ts index ca04558f..9e45a87a 100644 --- a/packages/components/src/word/tag/word-tag.ts +++ b/packages/components/src/word/tag/word-tag.ts @@ -2,12 +2,15 @@ import { UIAwareElement } from "@/lib/mixins/ui-aware-element/ui-aware-element"; import { TextStyles } from "@/lib/styles"; import { WordTagStyles } from "@/lib/word/tag/word-tag.styles"; import { - type WordTagHeaviness, - type WordTagVariant, - WordTagVariantAttributeConverter, + type WordTagHeaviness, + type WordTagVariant, + WordTagVariantAttributeConverter, + WordTagVariants, } from "@/lib/word/tag/word-tag.types"; -import { type CSSResult, type TemplateResult, css, html, nothing } from "lit"; +import { type CSSResult, type TemplateResult, css, html, nothing, unsafeCSS } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { map } from "lit/directives/map.js"; +import { when } from "lit/directives/when.js"; /** * @summary Displays a word in a simple padded box in which the text color and border are synchronised @@ -19,6 +22,8 @@ import { customElement, property } from "lit/decorators.js"; * @property [variant="text-only"] - The version of the layout to render * @property [hrefUrl=""] - A URL which, when provided, wraps this {@link WordTag} in a * {@link HTMLAnchorElement} + * @property [urlObject={text=this.word,url=this.hrefUrl}] - An object configuring a `url` + * and link text * * @cssprop [--word-tag-color="--md-sys-color-on-primary-container"] - The text and border color * @cssprop [--word-tag-background-color="--md-sys-color-primary-container"] - The background color @@ -29,7 +34,8 @@ import { customElement, property } from "lit/decorators.js"; * @cssprop [--word-tag-border-radius="--md-sys-shape-corner-small"] - The corner radius (for all corners) * @cssprop [--word-tag-gap="--spaces-gap-xs"] - The `gap` between `word` and any `slot`-ed icon * - * @slot icon - The optional space available for, and positioned by, the {@link variant} property + * @slot [icon] - The optional space available for, and positioned by, the {@link variant} property + * @slot [popover] - The `popover` content * * @class WordTag * @extends {UIAwareElement} @@ -48,6 +54,12 @@ export class WordTag extends UIAwareElement { @property({ type: String }) hrefUrl = ""; + @property({ type: Object }) + urlObject: { text: string, url: string } = { text: this.word, url: this.hrefUrl } + + @property({ attribute: false }) + popoverContent: string | string[] = ""; + /** {@link WordTagVariantAttributeConverter} */ @property({ attribute: "variant", @@ -59,35 +71,43 @@ export class WordTag extends UIAwareElement { variant: WordTagVariant = "text-only"; private layoutForVariant(variant: WordTagVariant): TemplateResult { - const fontStyles: CSSResult = css` - font-weight: ${this.heaviness === "normal" ? css`var(--md-ref-typeface-weight-regular)` : css`var(--md-ref-typeface-weight-bold)`}; - `; + const fontWeight = this.heaviness === "normal" ? css`var(--md-ref-typeface-weight-regular)` : css`var(--md-ref-typeface-weight-bold)`; + const fontStyles: CSSResult = unsafeCSS(` + font-weight: ${fontWeight}; + `); - const borderStyles: CSSResult = css` - border-width: ${this.heaviness === "normal" ? css`var(--sizes-thickness-hairline)` : css`var(--sizes-thickness-s)`}; - `; + const borderWidth = this.heaviness === "normal" ? css`var(--sizes-thickness-hairline)` : css`var(--sizes-thickness-s)`; + const borderStyles: CSSResult = unsafeCSS(` + border-width: ${borderWidth}; + `); - const defaultWordTag = html` ${this.word} `; + const defaultWordTag = html` + ${this.word} + `; let contents: TemplateResult | undefined = undefined; switch (variant) { - case "text-icon": + case WordTagVariants["text-icon"]: contents = html` ${defaultWordTag} `; break; - case "icon-text": + case WordTagVariants["icon-text"]: contents = html` ${defaultWordTag} `; break; - case "icon-only": - contents = html` `; + case WordTagVariants["icon-only"]: + contents = html` + + `; break; - case "text-only": - contents = html` ${defaultWordTag} `; + case WordTagVariants["text-only"]: + contents = html` + ${defaultWordTag} + `; break; default: break; @@ -95,26 +115,57 @@ export class WordTag extends UIAwareElement { return contents ? html` -
- ${contents} -
+ ${ + when( + this.hrefUrl, + () => html` + + `, + () => html` +
+ ${contents} +
+ ` + ) + } ` : html`${nothing}`; } override render() { - return this.hrefUrl === "" - ? this.layoutForVariant(this.variant) - : html`${this.layoutForVariant(this.variant)}`; + const tag = this.layoutForVariant(this.variant); + + const popoverContent = when( + Array.isArray(this.popoverContent), + () => html` +
    + ${map(this.popoverContent, (content: string) => html`
  • ${content}
  • `)} +
+ `, + () => html` +

${this.popoverContent}

+ ` + ); + return html` + + + + ${popoverContent} + + + ${tag} + `; } } diff --git a/packages/components/src/word/tag/word-tag.types.ts b/packages/components/src/word/tag/word-tag.types.ts index 067868cd..b7b363b6 100644 --- a/packages/components/src/word/tag/word-tag.types.ts +++ b/packages/components/src/word/tag/word-tag.types.ts @@ -9,13 +9,25 @@ import { type ComplexAttributeConverter } from "lit"; */ export type WordTagHeaviness = "normal" | "heavy"; +/** + * @summary A `const` declaration from which {@link WordTagVariant} is defined + * + * @type {{ readonly "text-only": "text-only"; readonly "icon-text": "icon-text"; readonly "text-icon": "text-icon"; readonly "icon-only": "icon-only"; }} + */ +export const WordTagVariants = { + "text-only": "text-only" as const, + "icon-text": "icon-text" as const, + "text-icon": "text-icon" as const, + "icon-only": "icon-only" as const, +} as const; + /** * The variations of {@link WordTag} representing the possible combinations * of `text only`, `icon only`, `icon then text`, and `text then icon` * * @typedef {WordTagVariant} */ -export type WordTagVariant = "text-only" | "icon-text" | "text-icon" | "icon-only"; +export type WordTagVariant = keyof typeof WordTagVariants; /** * Implements {@link ComplexAttributeConverter} for {@link WordTagVariant} properties @@ -24,16 +36,16 @@ export const WordTagVariantAttributeConverter: ComplexAttributeConverter `${value}`, fromAttribute: (value: string) => { switch (value) { - case "icon-text": - return "icon-text"; - case "text-icon": - return "text-icon"; - case "text-only": - return "text-only"; - case "icon-only": - return "icon-only"; + case WordTagVariants["icon-text"]: + return WordTagVariants["icon-text"]; + case WordTagVariants["text-icon"]: + return WordTagVariants["text-icon"]; + case WordTagVariants["text-only"]: + return WordTagVariants["text-only"]; + case WordTagVariants["icon-only"]: + return WordTagVariants["icon-only"]; default: - return "text-only"; + return WordTagVariants["text-only"]; } }, }; diff --git a/packages/data/src/code/index.ts b/packages/data/src/code/index.ts index e656f2a3..6b5f2417 100644 --- a/packages/data/src/code/index.ts +++ b/packages/data/src/code/index.ts @@ -11,6 +11,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-gradle-dark-icon-svg", light: "--icons-logos-tech-gradle-light-icon-svg", }, + popoverContent: "JVM Build Tool for Java, Kotlin, Android, and more" }, { name: "Kotlin", @@ -19,6 +20,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-kotlin-dark-icon-svg", light: "--icons-logos-tech-kotlin-light-icon-svg", }, + popoverContent: "JetBrains' modern JVM languange" }, ], url: "https://github.com/fnc314/project-collections-gradle-settings-plugin", @@ -36,6 +38,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-bash-dark-icon-svg", light: "--icons-logos-tech-bash-light-icon-svg", }, + popoverContent: "Shell scripting" }, { name: "Oh-My-Zsh", @@ -44,6 +47,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-zsh-dark-icon-svg", light: "--icons-logos-tech-zsh-light-icon-svg", }, + popoverContent: "Shell scripting" }, ], url: "https://github.com/fnc314/mac-os-env-scripts", @@ -61,6 +65,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-android-dark-icon-svg", light: "--icons-logos-tech-android-light-icon-svg", }, + popoverContent: "World's most used, open-source operating system", }, { name: "Gradle", @@ -69,6 +74,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-gradle-dark-icon-svg", light: "--icons-logos-tech-gradle-light-icon-svg", }, + popoverContent: "JVM Build Tool for Java, Kotlin, Android, and more", }, { name: "Kotlin", @@ -77,6 +83,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-kotlin-dark-icon-svg", light: "--icons-logos-tech-kotlin-light-icon-svg", }, + popoverContent: "JetBrains' modern JVM languange", }, ], url: "https://github.com/fnc314/fnc314-kmp", @@ -94,6 +101,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-mise-dark-icon-svg", light: "--icons-logos-tech-mise-light-icon-svg", }, + popoverContent: "Development Environment Tool Manager", }, { name: "PNPM", @@ -102,6 +110,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-pnpm-dark-icon-svg", light: "--icons-logos-tech-pnpm-light-icon-svg", }, + popoverContent: "Alternative `Node` package manager", }, { name: "Vite", @@ -110,6 +119,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-vite-dark-icon-svg", light: "--icons-logos-tech-vite-light-icon-svg", }, + popoverContent: "Modern JavaScript toolchain based on Rust", }, { name: "Lit", @@ -118,6 +128,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-lit-dark-icon-svg", light: "--icons-logos-tech-lit-light-icon-svg", }, + popoverContent: "JavaScript library for building Web Components", }, { name: "TypeScript", @@ -126,6 +137,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-typescript-dark-icon-svg", light: "--icons-logos-tech-typescript-light-icon-svg", }, + popoverContent: "Microsoft's modern JavaScript superset language", }, { name: "Style Dictionary", @@ -134,6 +146,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-style-dictionary-dark-icon-svg", light: "--icons-logos-tech-style-dictionary-light-icon-svg", }, + popoverContent: "NPM Package for generating design tokens from `json` files", }, { name: "Material Components", @@ -143,6 +156,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-material-design-dark-icon-svg", light: "--icons-logos-tech-material-design-light-icon-svg", }, + popoverContent: "Web Components library adhering to Material Design principles", }, { name: "Node", @@ -151,6 +165,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-node-dark-icon-svg", light: "--icons-logos-tech-node-light-icon-svg", }, + popoverContent: "JavaScript Runtime" }, { name: "Material Theme Builder", @@ -159,6 +174,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-material-design-dark-icon-svg", light: "--icons-logos-tech-material-design-light-icon-svg", }, + popoverContent: "Online tool to generate Material Theme colors from provided images", }, { name: "HTML/CSS/JS", @@ -167,6 +183,11 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-web-html-dark-icon-svg", light: "--icons-logos-tech-web-html-light-icon-svg", }, + popoverContent: [ + "HTML5", + "CSS", + "JavaScript", + ] }, { name: "Prettier", @@ -175,6 +196,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-prettier-dark-icon-svg", light: "--icons-logos-tech-prettier-light-icon-svg", }, + popoverContent: "Formatting library for Node", }, { name: "ESLint", @@ -183,6 +205,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-eslint-dark-icon-svg", light: "--icons-logos-tech-eslint-light-icon-svg", }, + popoverContent: "Linting library for Node", }, { name: "Typescript-ESLint", @@ -191,6 +214,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-typescript-eslint-dark-icon-svg", light: "--icons-logos-tech-typescript-eslint-light-icon-svg", }, + popoverContent: "TypeScript Linting library for Node", }, { name: "StyleLint", @@ -199,6 +223,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-stylelint-dark-icon-svg", light: "--icons-logos-tech-stylelint-light-icon-svg", }, + popoverContent: "Formatting library for Node", }, { name: "PostCSS", @@ -207,6 +232,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-postcss-dark-icon-svg", light: "--icons-logos-tech-postcss-light-icon-svg", }, + popoverContent: "CSS processing library for Node", }, ], url: "https://github.com/fnc314/fnc314.github.io", @@ -223,6 +249,11 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-web-html-dark-icon-svg", light: "--icons-logos-tech-web-html-light-icon-svg", }, + popoverContent: [ + "HTML5", + "CSS", + "JavaScript", + ] }, { name: "Material Theme Builder", @@ -231,6 +262,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-material-design-dark-icon-svg", light: "--icons-logos-tech-material-design-light-icon-svg", }, + popoverContent: "Online tool to generate Material Theme colors from provided images", }, ], url: "https://github.com/fnc314/material-theme-viewer", @@ -248,6 +280,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-python-dark-icon-svg", light: "--icons-logos-tech-python-light-icon-svg", }, + popoverContent: "Popular scripting language", }, { name: "Ruby", @@ -256,6 +289,7 @@ export const Projects: CodeRepoData[] = [ dark: "--icons-logos-tech-ruby-dark-icon-svg", light: "--icons-logos-tech-ruby-light-icon-svg", }, + popoverContent: "Formerly popular scripting language", }, ], url: "https://github.com/fnc314/project_euler", diff --git a/packages/types/src/code/index.ts b/packages/types/src/code/index.ts index 9b94fab7..7dae6f57 100644 --- a/packages/types/src/code/index.ts +++ b/packages/types/src/code/index.ts @@ -15,7 +15,7 @@ export const WORD_TAG_SIZES = { } as const; /** We give {@link @fnc314/packages.components!WordTag} various treatments within this component */ -export type WordTagSize = (typeof WORD_TAG_SIZES)[keyof typeof WORD_TAG_SIZES]; +export type WordTagSize = keyof typeof WORD_TAG_SIZES; /** * Represents a single project entry loaded from `code.json`. @@ -43,7 +43,7 @@ export interface CodeRepoData { /** * Represents a single technology entry used by a project. */ -export interface CodeRepoTech { +export interface CodeRepoTech extends CodeRepoPopover { /** A generated `CSS Variable` from `@fnc314/packages.types` */ designToken: string | DesignTokenIcon; @@ -52,4 +52,15 @@ export interface CodeRepoTech { /** URL with more information about the technology. */ url: string; -} +}; + +/** + * @summary The content used to drive the `popover`s in the `` + * + * @export + * @interface CodeRepoPopover + * @typedef {CodeRepoPopover} + */ +export interface CodeRepoPopover { + popoverContent: string | string[]; +}; diff --git a/sites/portfolio/index.css b/sites/portfolio/index.css index 695506ca..698b3f40 100644 --- a/sites/portfolio/index.css +++ b/sites/portfolio/index.css @@ -77,8 +77,7 @@ stroke var(--color-transition-duration) var(--color-transition-timing), fill var(--color-transition-duration) var(--color-transition-timing), border-color var(--color-transition-duration) var(--color-transition-timing), - background-color var(--color-transition-duration) - var(--color-transition-timing), + background-color var(--color-transition-duration) var(--color-transition-timing), color var(--color-transition-duration) var(--color-transition-timing); } From 084ce13a7f04af2e5999e48479c6d9fb59b9e357 Mon Sep 17 00:00:00 2001 From: "Franco N. Colaizzi" Date: Wed, 22 Jul 2026 06:40:47 -0400 Subject: [PATCH 04/14] popover treatment on tech icons in code --- .../components/src/code/repo/code-repo.ts | 38 ++++++--- .../ui-aware-element/ui-aware-element.ts | 22 +++-- .../src/word/popover/word-popover.styles.ts | 21 ++++- .../src/word/popover/word-popover.ts | 2 +- packages/components/src/word/tag/word-tag.ts | 81 ++++++++----------- .../assets/css/_material-overrides.css | 2 +- .../design-tokens/assets/css/_variables.css | 2 +- .../design-tokens/assets/css/icon-svg.css | 4 +- .../icons/logos/tech/web/html/html-dark.svg | 9 +++ .../web/{html.svg => html/html-default.svg} | 0 .../icons/logos/tech/web/html/html-light.svg | 9 +++ .../tokens/icons/logos/tech/web/web.json | 6 +- packages/types/src/code/index.ts | 2 +- 13 files changed, 121 insertions(+), 77 deletions(-) create mode 100644 packages/design-tokens/assets/icons/logos/tech/web/html/html-dark.svg rename packages/design-tokens/assets/icons/logos/tech/web/{html.svg => html/html-default.svg} (100%) create mode 100644 packages/design-tokens/assets/icons/logos/tech/web/html/html-light.svg diff --git a/packages/components/src/code/repo/code-repo.ts b/packages/components/src/code/repo/code-repo.ts index 02d2b730..917a4c03 100644 --- a/packages/components/src/code/repo/code-repo.ts +++ b/packages/components/src/code/repo/code-repo.ts @@ -5,6 +5,8 @@ import { readCSSProperty } from "@fnc314/packages.design-tokens"; import { BreakpointLabels, type CodeRepoData, type CodeRepoTech } from "@fnc314/packages.types"; import { type TemplateResult, html, nothing, unsafeCSS } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { map } from "lit/directives/map.js"; +import { when } from "lit/directives/when.js"; /** * An instance of a given `GitHub` repository project documented through @@ -27,18 +29,9 @@ export class CodeRepo extends UIAwareElement { private createWordTagLI(tech: CodeRepoTech): TemplateResult { const techWord = tech.name.replaceAll(" ", "-").toLowerCase(); - const imgSrc = - typeof tech.designToken === "string" - ? readCSSProperty(tech.designToken) - : readCSSProperty(this.darkMode ? tech.designToken.dark : tech.designToken.light); + const imgSrc = readCSSProperty(this.whichDesignToken(tech.designToken)); - const tagId: string = `${ - typeof tech.designToken === "string" - ? tech.designToken - : this.darkMode - ? tech.designToken.dark - : tech.designToken.light - }-${techWord}-word-tag`; + const tagId: string = `${this.whichDesignToken(tech.designToken)}-${techWord}-word-tag`; const imgTag = imgSrc ? html` @@ -61,6 +54,18 @@ export class CodeRepo extends UIAwareElement { ? "icon-text" : "icon-only"; + const popoverContent = when( + Array.isArray(tech.popoverContent), + () => html` +
    + ${map(tech.popoverContent, (content: string) => html`
  • ${content}
  • `)} +
+ `, + () => html` +

${tech.popoverContent}

+ ` + ); + return html`
  • ${imgTag} + ${tech.name} + ${popoverContent}
  • `; @@ -82,7 +97,6 @@ export class CodeRepo extends UIAwareElement { const tokenSvg = readCSSProperty(token); - const borderStyle = unsafeCSS(` --dynamic-border-background-image: url('${tokenSvg}'); `); diff --git a/packages/components/src/mixins/ui-aware-element/ui-aware-element.ts b/packages/components/src/mixins/ui-aware-element/ui-aware-element.ts index 9c6617b6..03f1a8a2 100644 --- a/packages/components/src/mixins/ui-aware-element/ui-aware-element.ts +++ b/packages/components/src/mixins/ui-aware-element/ui-aware-element.ts @@ -1,11 +1,12 @@ import { readCSSProperty } from "@fnc314/packages.design-tokens"; import { configsService } from "@fnc314/packages.services"; import { - type AppConfigsChange, - type BreakpointLabel, - CONFIG_COLOR_SCHEME_NAMES, - CSS_VARIABLE_BREAKPOINT_LABEL, - CSS_VARIABLE_TOUCH_SCREEN, + type AppConfigsChange, + type BreakpointLabel, + CONFIG_COLOR_SCHEME_NAMES, + CSS_VARIABLE_BREAKPOINT_LABEL, + CSS_VARIABLE_TOUCH_SCREEN, + type DesignTokenIcon, } from "@fnc314/packages.types"; import { type CSSResult, LitElement } from "lit"; import { state } from "lit/decorators.js"; @@ -66,4 +67,15 @@ export abstract class UIAwareElement extends LitElement { window.removeEventListener("resize", this.onBreakpointChange); configsService.removeEventListener("app-configs.change", this.onAppConfigChange); } + + /** + * Determines which field of the `designToken` should be rendered based on `darkMode` + * + * @protected + * @param designToken - A {@link DesignTokenIcon} to read + * @returns {string} - The actual token + */ + protected whichDesignToken(designToken: DesignTokenIcon): string { + return this.darkMode ? designToken.dark : designToken.light; + } } diff --git a/packages/components/src/word/popover/word-popover.styles.ts b/packages/components/src/word/popover/word-popover.styles.ts index 052d4d05..1cddd4cc 100644 --- a/packages/components/src/word/popover/word-popover.styles.ts +++ b/packages/components/src/word/popover/word-popover.styles.ts @@ -2,7 +2,7 @@ import { type CSSResult, css } from "lit"; export const WordPopoverStyles: CSSResult = css` :host { - + --md-icon-size: calc(2 * var(--md-icon-size)); } article { @@ -14,15 +14,30 @@ export const WordPopoverStyles: CSSResult = css` overscroll-behavior: contain; background-color: var(--md-sys-color-surface); color: var(--md-sys-color-on-surface); + border: solid var(--sizes-thickness-hairline) var(--md-sys-color-on-surface-variant); + border-radius: var(--bento-layout-card-shape); + justify-content: space-around; header { - h3 { + display: grid; + grid-template-areas: + ". icon ." + "header header header"; + place-items: center; + + & ::slotted(*) { + grid-area: icon; + aspect-ratio: 1; + max-inline-size: 33%; + } + h3 { + grid-area: header; } } section { - + padding-inline: var(--spaces-padding-m); } footer { diff --git a/packages/components/src/word/popover/word-popover.ts b/packages/components/src/word/popover/word-popover.ts index 1c828fce..90260baf 100644 --- a/packages/components/src/word/popover/word-popover.ts +++ b/packages/components/src/word/popover/word-popover.ts @@ -40,7 +40,7 @@ export class WordPopover extends UIAwareElement {
    - +