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?