reagent

Ovi Stoica 2023-06-27T18:08:35.104459Z

I’m trying to have this effect, where if you have asChild the button will use the child element and apply all its styles to the child as opposed to using :button

// The final HTML will just be <a .. /> instead of `<button />`
export function ButtonAsChild() {
  return (
    <Button asChild>
      <a href="/login">Login</Link>
    </Button>
  )
}
Here’s the react implementation doing the exact thing
import { Slot } from "@radix-ui/react-slot"

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  ({ className, variant, size, asChild = false, ...props }, ref) => {
    const Comp = asChild ? Slot : "button"
    return (
      <Comp
        className={cn(buttonVariants({ variant, size, className }))}
        ref={ref}
        {...props}
      />
    )
  }
)
here’s my cljs equivalent (it does not render correctly):
(defn props-children
  []
  (let [this (r/current-component)
        props (r/props this)
        children (r/children this)]
    {:props props
     :children children}))

(defn render-children
  [children]
  (for [child children]
    child))

(def slot (r/adapt-react-class Slot)) ;; same as in JS example

(defn button
  [& _]
  (let [{:keys [props children]} (props-children)
        {:keys [as-child class]} props
        comp (if as-child slot :button)
        rest (dissoc props :class :variant :size :as-child)
        classes (u/get-classes
                 button-variants
                 (select-keys props [:variant :size]))
        component-props (merge {:class (u/tw class classes)} rest)]
    [comp component-props
     (render-children children)]))

;; Not rendering
[button {:as-child true}
     [:a {:href "login"} "Login"]]
I’m pretty sure it’s related to the Slot component and how that interracts with reagent but I can’t really put my finger on it. Any ideas?