#reading astro.props values across components.

2 messages · Page 1 of 1 (latest)

river bloom
#

(i only started learning js this autumn, also new to astro)

i have a component, that uses astro.props and i would like to use script to manipulate the css and toggle visibility of an element based on the presence of data in the prop.

it's using data from a content collection schema and the relevant .md files, which is then mapped, and when the schema object is empty/null (as it's optional), the space and styling reserved for the final object is still visible.

for example:

---
const { age } = Astro.props;

---

<div class="cat-box-2">
    <div class="age-tag" id="minimum-age-tag">{age}</div>
</div>

<style> 
.age-tag {
    border: 3px double var(--new-pink);
    color: var(--text-white);
}
</ style> 

if the frontmatter was left null, the border on the would-be parent element still shows.

My plan was to:
add/remove a .hidden class onto each copy of the component depending if the prop has a value or is null
or
since the {age} value will be different on each copy of the component ( map() ), how could I change the specific CSS border: property depending on the value of {age}.
(value is 'string' btw)

but how do I access the values of each component on load?
it should technically all be server side because the values are determined on build, there's no need for client side manipulation (no buttons or such)

my original attempt was a simple function running if/else, but i stumbled at how to access the values that would be dynamically passed into the {age} prop. then i read about inline script here: https://docs.astro.build/en/guides/client-side-scripts/#_top
and i think i need to find other tutorials or written information, but not sure how to look for it.

if it don't make much sense, do let me know ~

Docs

How to add client-side interactivity to Astro components using native browser JavaScript APIs.

plush quiver
#

If this is build-time rendered, and if I understood correctly, you have a few options:

If age is either a string or null/undefined, you can conditionnally render the div:

<div class="cat-box-2">
    {age && <div class="age-tag" id="minimum-age-tag">{age}</div>}
</div>

This will render the minimum-age-tag div only if age is defined.

If you want to customize the border based on the given age, you could also apply different CSS classes. For example:

<div class="cat-box-2">
    <div class:list={["age-tag", {minor: Number(age) < 18, major: Number(age) >= 18}]} id="minimum-age-tag">{age}</div>
</div>

And adjust your CSS based on the classes.

If you prefer a data-attribute,

---
const isMinor = Number(age) < 18;
---
<div class="cat-box-2">
    <div class="age-tag" data-age={isMinor ? "minor" : "major"} id="minimum-age-tag">{age}</div>
</div>

And adjust your CSS based on the data-age value.

So, if this is build-time rendered (static mode), you don't need a client side script because this is only executed in the browser, not at build time.

Docs

Learn how to style components in Astro with scoped styles, external CSS, and tooling like Sass and PostCSS.