#How can I pass the parent size prop to my child button components ?

48 messages · Page 1 of 1 (latest)

austere tusk
#

index.astro

<ButtonGroup size="xl">
  <Button pill color="purple">Profile</Button>
  <Button pill color="purple">Settings</Button>
  <Button pill color="purple">Messages</Button>
</ButtonGroup>

ButtonGroup.astro

---
import type { HTMLAttributes } from "astro/types";

import { twMerge } from "tailwind-merge";

import type { SizeType } from "../types";

export interface Props extends HTMLAttributes<"div"> {
  size?: SizeType;
  divClass?: string;
}

const {
  size = "xs",
  divClass = "inline-flex rounded-lg shadow-sm",
  ...attrs
} = Astro.props;
---

<div {...attrs} class={twMerge(divClass, attrs.class)} role="group">
  <slot />
</div>

Button.astro

---
import type { HTMLAttributes } from "astro/types";

import { twMerge } from "tailwind-merge";

import type { ButtonType, SizeType } from "../types";

type ButtonColor = keyof typeof colorClasses;

export interface Props extends HTMLAttributes<"button" & "a"> {
  group?: SizeType | undefined;
  pill?: boolean;
  outline?: boolean;
  size?: "xs" | "sm" | "md" | "lg" | "xl";
  href?: string | undefined;
  type?: ButtonType;
  color?: ButtonColor;
  shadow?: boolean;
}

const {
  group = undefined,
  pill = false,
  outline = false,
  size = group ? "sm" : "md",
  href = undefined,
  type = "button",
  color = group ? (outline ? "dark" : "alternative") : "primary",
  shadow = false,
  ...attrs
} = Astro.props;

....
---

<Element
  type={href ? undefined : type}
  {href}
  class={buttonClass}
  role={href ? "link" : "button"}
  {...attrs}
>
  <slot />
</Element>
dense thistle
#

I don't know if that's possible with Astro. This example made me think to react context but if we want to stick astro files, I don't know if it's possible

austere tusk
#

like this :

#
<ButtonGroup>
  {(size: any) =>
    <Button group={size} pill color="purple">Profile</Button>
    <Button group={size} pill color="purple">Settings</Button>
    <Button group={size} pill color="purple">Messages</Button>
  }
</ButtonGroup>
#

ugly 😄

#

I need component context... :/

dense thistle
#

It could be something like I think:

<ButtonGroup size="xl">
  {(props) =>
    <Button {...props} pill color="purple">Profile</Button>
    <Button {...props} pill color="purple">Settings</Button>
    <Button {...props} pill color="purple">Messages</Button>
  }
</ButtonGroup>
#

Honestly I have never tried doing this so I don't think I can help more, I'll ask in dev to see if they have ideas

austere tusk
#

Ok thx ! 🙂

dense thistle
#

According to #framework message this doesn't seem possible in a context way, but if I have another answers I'll keep you posted

austere tusk
#

ok, maybe a local component store with nanostores ?

#

with component id hashmap

dense thistle
#

See #framework message

#

nanostores seems the way to go

austere tusk
#

ok do you have any example for a local component store ? I tried it before but my store was global :/

livid kelp
#

it would be possible to allow context pattern popular in react ecosystem

#

i could look into it later

#

but your case is dead simple

austere tusk
#

Yes I know, in Svelte too, setContext/getContext

#

but I don't want to use frontend libs

livid kelp
#

so the parent is button group right

austere tusk
#

yes

livid kelp
#

...role="group" style="--size: xl">

#

and from any element within it,

element.getComputedStyles().getProperty("--size")
livid kelp
#

no, a client side script

austere tusk
#

that's an astro ui lib for ssg

livid kelp
livid kelp
austere tusk
#

that will not work on ssg perspectives

#

no ?

livid kelp
#

it will

#

ssg does not mean no client side javascript

austere tusk
#

yes

livid kelp
#

it means no server side javascript

austere tusk
#

but pages are generated before and components too

#

the markup

livid kelp
#

yes exactly

#

the pages including the client side javascript they need

austere tusk
#

ok I will try this

#

hacky way

livid kelp
#

it is a very valid way imo

austere tusk
#

ok

#

thx

livid kelp
#

i should disclaim i haven't read the entire conversation, im just sharing the equivalent of react's context for vanilla javascript

#

whether or not that's the right tool for the job in the first place is upto you

austere tusk
#

Yeah I saw 🙂