Hi, is possible to achieve something like this in ...
# javascript
m
Hi, is possible to achieve something like this in ReactJs, emotion css and kotlin wrappers? val LayoutListItem = div.styled { selected: Boolean -> display = Display.flex alignItems = AlignItems.center justifyContent = JustifyContent.spaceBetween padding(vertical = 8.px, horizontal = 24.px) backgroundColor = if (selected) SharedStyles.darkColor else Color(“white”) borderRadius = 6.px fontSize = 1.rem color = SharedStyles.darkColor boxShadow = SharedStyles.shadows.small }
👌 1
a
@turansky ^^
t
It’s possible with custom props (
HTMLAttributes
+
selected
) but probably it’s not best solution in your case
Copy code
external interface LayoutListItemProps : HTMLAttributes {
    var selected: Boolean
}

val LayoutListItem = div.styled<LayoutListItemProps> { props ->
  display = Display.flex
  alignItems = AlignItems.center
  justifyContent = JustifyContent.spaceBetween
  padding(vertical = 8.px, horizontal = 24.px)
  backgroundColor = if (props.selected) SharedStyles.darkColor else Color("white")
  borderRadius = 6.px
  fontSize = 1.rem
  color = SharedStyles.darkColor
  boxShadow = SharedStyles.shadows.small
}
JFYI - for paddings you can use
Padding
factory function
Copy code
padding = Padding(8.px, 24.px)
m
Thank you. Really helpful. Found missing <HTMLDivElement>:
Copy code
external interface LayoutListItemProps : HTMLAttributes<HTMLDivElement> {
    var selected: Boolean
}
val LayoutListItem2 = div.styled<LayoutListItemProps> { props ->
    display = Display.flex
    alignItems = AlignItems.center
    justifyContent = JustifyContent.spaceBetween
    padding = Padding(1.px, 32.px)
    backgroundColor = if (props.selected) SharedStyles.darkColor else Color("white")
    borderRadius = 6.px
    fontSize = 1.rem
    color = SharedStyles.darkColor
    boxShadow = SharedStyles.shadows.small
}
Meanwhile I found this workaround:
Copy code
val LayoutSideBar = FC<LayoutSideBarProps> { props ->
    val viewModel by reactKoin.inject<SideBarViewModel>()

    val (items, setItems) = useState<List<LayoutItem>>(emptyList())
    val scope = useMemo { CoroutineScope(Dispatchers.Default) }
    var editingId by useState<Uuid?>(null)
    var editingName by useState("")
    var selectedId by useState<String?>(null)

    useEffectRaw({
        val job = scope.launch {
            viewModel.layouts.collectLatest { latestList ->
                setItems(latestList.map { layout -> LayoutItem(layout.id!!, layout.name) })
                editingId = null
            }
        }

        return@useEffectRaw {
            job.cancel()
            scope.cancel()
        }
    }, arrayOf(viewModel.layouts))

    val LayoutListItem = div.styled {
        display = Display.flex
        alignItems = AlignItems.center
        justifyContent = JustifyContent.spaceBetween
        padding = Padding(8.px, 24.px)
        backgroundColor = if (it.id == selectedId) SharedStyles.lightColor else Color("white")
        borderRadius = 6.px
        fontSize = 1.rem
        color = SharedStyles.darkColor
        boxShadow = SharedStyles.shadows.small
    }
Is something else preffered? (but probably it’s not best solution in your case)
t
Styled component is fine
m
Ok. thank you very much. Coming from Android world and not too much docs in kotlinWrappers
t
And you should’t create components inside components
👍 1
Default
useEffect
already do all cancellations on cleanup
You can do like this:
Copy code
useEffect(viewModel.layouts) {
    viewModel.layouts.collectLatest { latestList ->
        setItems(latestList.map { layout -> LayoutItem(layout.id!!, layout.name) })
                editingId = null
        }
    }
}
❤️ 1