From c1e28224aa2e1450031669d9a7e359b63e04687d Mon Sep 17 00:00:00 2001 From: Volpeon Date: Wed, 22 Jul 2026 19:40:59 +0200 Subject: Init --- src/styles/objects/_deflist.scss | 25 ++++ src/styles/objects/_message.scss | 216 +++++++++++++++++++++++++++++++ src/styles/objects/_message.vars.scss | 39 ++++++ src/styles/objects/_placeholder-box.scss | 12 ++ src/styles/objects/_toc.scss | 27 ++++ 5 files changed, 319 insertions(+) create mode 100644 src/styles/objects/_deflist.scss create mode 100644 src/styles/objects/_message.scss create mode 100644 src/styles/objects/_message.vars.scss create mode 100644 src/styles/objects/_placeholder-box.scss create mode 100644 src/styles/objects/_toc.scss (limited to 'src/styles/objects') diff --git a/src/styles/objects/_deflist.scss b/src/styles/objects/_deflist.scss new file mode 100644 index 0000000..63ba1b9 --- /dev/null +++ b/src/styles/objects/_deflist.scss @@ -0,0 +1,25 @@ +@use "sass:list"; + +@use "pkg:iro-sass/bem"; +@use "pkg:iro-sass/props"; +@use "pkg:iro-design" as iro; + +@mixin styles { + @include bem.object("deflist") { + display: grid; + grid-template-columns: auto 1fr; + gap: props.get(iro.$core--size--50) props.get(iro.$core--size--400); + padding: 0; + margin-block: props.get(iro.$s-implicit--paragraph--margin-bs) 0; + margin-inline: 0; + + dt { + font-weight: bold; + color: props.get(iro.$core--theme, --heading); + } + + dd { + margin: 0; + } + } +} diff --git a/src/styles/objects/_message.scss b/src/styles/objects/_message.scss new file mode 100644 index 0000000..a7c9996 --- /dev/null +++ b/src/styles/objects/_message.scss @@ -0,0 +1,216 @@ +@use "sass:meta"; + +@use "pkg:iro-design" as iro; +@use "pkg:iro-sass/bem"; +@use "pkg:iro-sass/props"; + +@forward "message.vars"; +@use "message.vars" as vars; + +@mixin styles { + @include iro.props--materialize-at-root(meta.module-variables("vars")); + + @include bem.object("message") { + display: grid; + position: relative; + grid-template-rows: auto 1fr auto; + grid-template-columns: + auto calc(props.get(vars.$avatar-size) + props.get(vars.$spacing-x)) + minmax(0, 1fr); + grid-template-areas: + "line-from avatar main" + "line-from line-to main" + "line-from replies replies"; + + & + & { + padding-block-start: props.get(vars.$spacing-outer); + } + + @include bem.elem("line-from") { + grid-area: line-from; + position: relative; + inline-size: calc(props.get(vars.$avatar-size) + props.get(vars.$spacing-x)); + + &::before, + &::after { + content: ""; + display: block; + position: absolute; + inset-block-start: 0; + inset-inline-start: props.get(vars.$line-offset); + } + + &::before { + inline-size: props.get(vars.$line-width); + block-size: calc(100% + props.get(vars.$spacing-outer)); + background-color: props.get(vars.$colors, --line); + } + + &::after { + inline-size: calc( + props.get(vars.$avatar-size) - props.get(vars.$line-offset) + props.get(vars.$spacing-x) + ); + block-size: calc(0.5 * (props.get(vars.$avatar-size) - props.get(vars.$line-width))); + border-block-end: props.get(vars.$line-width) solid props.get(vars.$colors, --line); + border-inline-start: props.get(vars.$line-width) solid props.get(vars.$colors, --line); + border-radius: 0 0 0 props.get(vars.$line-curve); + } + + @include bem.modifier("last") { + &::before { + block-size: 0; + } + } + + @include bem.sibling-elem("avatar") { + &::before { + inset-block-start: 50%; + inset-block-end: auto; + inset-inline-start: 0; + inline-size: 50%; + block-size: props.get(vars.$line-width); + transform: translateY(-50%); + } + } + } + + @include bem.elem("line-to") { + grid-area: line-to; + display: block; + inline-size: props.get(vars.$line-width); + margin-inline-start: props.get(vars.$line-offset); + background-color: props.get(vars.$colors, --line); + } + + @include bem.elem("avatar") { + position: relative; + grid-area: avatar; + inline-size: props.get(vars.$avatar-size); + block-size: props.get(vars.$avatar-size); + margin-inline-end: props.get(vars.$spacing-x); + + &::before, + &::after { + content: ""; + display: block; + position: absolute; + z-index: -1; + inset-inline-start: props.get(vars.$line-offset); + inline-size: props.get(vars.$line-width); + block-size: 50%; + background-color: props.get(vars.$colors, --line); + } + + &::before { + inset-block-start: 0; + } + + &::after { + inset-block-end: 0; + } + + @include bem.modifier("last") { + &::after { + display: none; + } + } + } + + @include bem.elem("avatar-dot") { + grid-area: avatar; + position: absolute; + inset-block-start: 50%; + inset-inline-start: 50%; + inline-size: props.get(vars.$dot-radius); + block-size: props.get(vars.$dot-radius); + transform: translate(-50%, -50%); + border: props.get(vars.$dot-width) solid props.get(vars.$colors, --dot, --border); + border-radius: 1em; + background-color: props.get(vars.$colors, --dot, --bg); + } + + @include bem.elem("meta") { + white-space: nowrap; + color: props.get(vars.$colors, --meta); + } + + @include bem.elem("main") { + position: relative; + grid-area: main; + } + + @include bem.elem("replies") { + grid-area: replies; + + &::before { + content: ""; + grid-area: line; + display: block; + inline-size: props.get(vars.$line-width); + block-size: props.get(vars.$spacing-inner); + margin-inline-start: props.get(vars.$line-offset); + background-color: props.get(vars.$colors, --line); + } + } + + @include bem.elem("header") { + line-height: 1.4; + + @include bem.next-elem("body") { + padding-block-start: props.get(vars.$spacing-y); + } + } + + @include bem.elem("body") { + word-wrap: break-word; + + &::before { + content: ""; + display: block; + margin-block: -100em 100em; + } + } + + @include bem.elem("attachments") { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(props.get(vars.$attachment-width), 1fr)); + grid-auto-rows: auto; + gap: props.get(vars.$spacing-x); + margin-block-start: props.get(vars.$spacing-attachments); + } + + @include bem.elem("attachment") { + aspect-ratio: 3 / 2; + background-color: props.get(vars.$colors, --attachment, --bg); + } + + @include bem.modifier("expanded") { + grid-template-rows: auto 1fr auto; + grid-template-columns: calc(props.get(vars.$avatar-size) + props.get(vars.$spacing-x)) minmax( + 0, + 1fr + ); + grid-template-areas: + "avatar header" + "body body" + "attachments attachments"; + + @include bem.elem("header") { + grid-area: header; + align-self: center; + } + + @include bem.elem("main") { + display: contents; + } + + @include bem.elem("body") { + grid-area: body; + } + + @include bem.elem("attachments") { + grid-area: attachments; + } + } + } +} diff --git a/src/styles/objects/_message.vars.scss b/src/styles/objects/_message.vars.scss new file mode 100644 index 0000000..f394894 --- /dev/null +++ b/src/styles/objects/_message.vars.scss @@ -0,0 +1,39 @@ +@use "pkg:iro-design/core.vars" as core; +@use "pkg:iro-design/objects/avatar.vars" as avatar; +@use "pkg:iro-sass/props"; + +$avatar-size: props.def(--o-message--avatar-size, props.get(avatar.$size)); + +$dot-radius: props.def(--o-message--dot-radius, 6px); +$dot-width: props.def(--o-message--dot-width, 4px); + +$spacing-x: props.def(--o-message--spacing-x, props.get(core.$size--200)); +$spacing-y: props.def(--o-message--spacing-y, props.get(core.$size--150)); +$spacing-inner: props.def(--o-message--spacing-inner, props.get(core.$size--500)); +$spacing-outer: props.def(--o-message--spacing-outer, props.get(core.$size--700)); +$spacing-attachments: props.def(--o-message--spacing-attachments, props.get(core.$size--200)); + +$line-width: props.def(--o-message--line-width, props.get(core.$border-width--medium)); +$line-offset: props.def( + --o-message--line-offset, + calc(0.5 * props.get($avatar-size) - props.get($line-width)) +); +$line-curve: props.def(--o-message--line-curve, props.get(core.$size--250)); + +$attachment-width: props.def(--o-message--attachment-width, props.get(core.$size--2000)); + +$colors: props.def( + --o-message, + ( + --meta: props.get(core.$theme, --text-mute-more), + --line: props.get(core.$theme, --border), + --dot: ( + --border: props.get(core.$theme, --text-mute-more), + --bg: props.get(core.$theme, --bg-base), + ), + --attachment: ( + --bg: props.get(core.$theme, --border-mute), + ), + ), + "color" +); diff --git a/src/styles/objects/_placeholder-box.scss b/src/styles/objects/_placeholder-box.scss new file mode 100644 index 0000000..9be3dc8 --- /dev/null +++ b/src/styles/objects/_placeholder-box.scss @@ -0,0 +1,12 @@ +@use "pkg:iro-sass/bem"; +@use "pkg:iro-sass/props"; +@use "pkg:iro-design" as iro; + +@mixin styles { + @include bem.object("placeholder-box") { + padding: props.get(iro.$core--size--250) props.get(iro.$core--size--300); + border: props.get(iro.$core--border-width--thin) dashed + props.get(iro.$core--theme, --border, --mute); + border-radius: props.get(iro.$core--rounding); + } +} diff --git a/src/styles/objects/_toc.scss b/src/styles/objects/_toc.scss new file mode 100644 index 0000000..aefb0c5 --- /dev/null +++ b/src/styles/objects/_toc.scss @@ -0,0 +1,27 @@ +@use "sass:list"; + +@use "pkg:iro-sass/bem"; +@use "pkg:iro-sass/props"; +@use "pkg:iro-design" as iro; + +@mixin styles { + @include bem.object("toc") { + @include bem.elem("item") { + @include bem.next-twin-elem { + margin-block-start: props.get(iro.$core--size--50); + } + + @include bem.is("active") { + @include bem.elem("item-link") { + font-weight: bold; + text-decoration-line: none; + color: props.get(iro.$core--theme, --heading); + + &:hover { + text-decoration-line: underline; + } + } + } + } + } +} -- cgit v1.3.1