Hi, when I use a custom button component as the slot content of a code component, the icon color is wrong. Using the same component as the slot content of a regular component works fine. Im not overwriting any classes from within the code component. I would be happy to share the project id for further debugging.
Hi Matthias! Does it work when you use plain Plasmic components? If so would you mind sharing the code component? Feel free to DM me
Yes it does work in plain Plasmic components. The code component is here:
import React, { forwardRef } from "react"
import { cloneElement } from "react"
import { registerComponent } from "@plasmicapp/host"
import { HTMLElementRefOf } from "@plasmicapp/react-web"
import { useButton } from "@react-aria/button"
import { FocusScope } from "@react-aria/focus"
import {
useOverlay,
usePreventScroll,
useModal,
OverlayContainer,
OverlayProps,
} from "@react-aria/overlays"
import { useOverlayTriggerState } from "@react-stately/overlays"
import { AriaDialogProps } from "@react-types/dialog"
import { AnimatePresence, m } from "framer-motion"
import styles from "./SideMenu.module.css"
type ModalDialogProps = OverlayProps &
AriaDialogProps & {
children: React.ReactElement
// className: string
CloseButton: React.ReactElement
positionRight: boolean
}
function ModalDialog_(props: ModalDialogProps, refForPlasmic: HTMLElementRefOf<"div">) {
let { children, positionRight } = props
// Handle interacting outside the dialog and pressing
// the Escape key to close the modal.
let ref = React.useRef<HTMLDivElement>(null)
let { overlayProps, underlayProps } = useOverlay(props, ref)
// Prevent scrolling while the modal is open, and hide content
// outside the modal from screen readers.
usePreventScroll()
let { modalProps } = useModal()
return (
<OverlayContainer>
<m.div
{...(underlayProps as any)}
className={styles.fillFixed}
animate={{ background: "rgba(0, 0, 0, 0.09)" }}
exit={{ background: "rgba(0, 0, 0, 0)" }}
>
<FocusScope contain restoreFocus autoFocus>
<m.div
style={{ x: positionRight ? "100%" : "-100%" }}
animate={{ x: 0, opacity: 1 }}
exit={{ x: positionRight ? "100%" : "-100%", opacity: 0 }}
transition={{ ease: "easeInOut" }}
// ref={mergeRefs([refForPlasmic as React.RefObject<HTMLDivElement>, ref])}
ref={ref}
// className={[props.className, styles.slideover]}
className={styles.slideover}
{...(overlayProps as any)}
{...modalProps}
>
{props.CloseButton}
{children}
</m.div>
</FocusScope>
</m.div>
</OverlayContainer>
)
}
const ModalDialog = React.forwardRef(ModalDialog_)
type SideMenuProps = {
children: React.ReactNode
openButton: React.ReactElement<any>
closeButton: React.ReactElement<any>
className: string
show: boolean
positionRight: boolean
}
function SideMenu_(
{
children = <div />,
openButton = <button />,
closeButton = <button />,
show,
className,
positionRight,
}: SideMenuProps,
ref: HTMLElementRefOf<"div">
) {
let state = useOverlayTriggerState({})
let openButtonRef = React.useRef<HTMLButtonElement>(null)
let closeButtonRef = React.useRef<HTMLButtonElement>(null)
let { buttonProps: openButtonProps } = useButton(
{
onPress: () => state.open(),
},
openButtonRef
)
let { buttonProps: closeButtonProps } = useButton(
{
onPress: () => state.close(),
},
closeButtonRef
)
const OpenButton = cloneElement(openButton, { ...openButtonProps, ref: openButtonRef })
const CloseButton = cloneElement(closeButton, { ...closeButtonProps, ref: closeButtonRef })
return (
<div ref={ref} className={className}>
{OpenButton}
<AnimatePresence>
{(state.isOpen || show) && (
<ModalDialog
// className={className}
isOpen
onClose={state.close}
isDismissable
// ref={ref}
CloseButton={CloseButton}
positionRight={positionRight}
>
{children as React.ReactElement}
</ModalDialog>
)}
</AnimatePresence>
</div>
)
}
const SideMenu = React.forwardRef(SideMenu_)
export default SideMenu
registerComponent(SideMenu, {
name: "SideMenu",
props: {
show: "boolean",
positionRight: "boolean",
children: { type: "slot" },
openButton: "slot",
closeButton: "slot",
},
isDefaultExport: true,
importPath: "./app/core/components/headless/SideMenu",
})
ohh I see, the button is getting the default color of the base variant, instead of the color from green10
variant (from type
variant group).
That’s because openButton
element contains type: "green10"
in its props, but it gets overwritten by buttonProps
from react-aria, which sets type: "button"
(which is not a valid variant, so it ends up getting the color from the base variant)
renaming the variant group to something else like color
fixes it