Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Uncontrolled collapsible not working #310

Closed
ParasSolanki opened this issue Jan 30, 2024 · 3 comments · Fixed by #241
Closed

[Bug]: Uncontrolled collapsible not working #310

ParasSolanki opened this issue Jan 30, 2024 · 3 comments · Fixed by #241
Labels
bug Something isn't working

Comments

@ParasSolanki
Copy link
Contributor

ParasSolanki commented Jan 30, 2024

Environment

Developement/Production OS: Windows 10 Pro 10.0.19045
Node version: 18.14.0
Package manager: pnpm@8.12.1
Radix Vue version: 1.3.2
Shadcn Vue version: 0.8.7
Vue version: 3.4.0
Nuxt version: 3.0.0
Nuxt mode: universal
Nuxt target: server
CSS framework: tailwindcss@3.4.0
Client OS: Windows 10 Pro 10.0.19045
Browser: Chrome 120.0.6099.130

Link to minimal reproduction

https://stackblitz.com/edit/w2uuxx-s8mgnp?file=src%2FApp.vue,package.json

Steps to reproduce

  1. Start a new Vue 3, Typescript project with Vite and create-vue pnpm create vue@latest.
  2. Install tailwindcss and its peer dependencies.
  3. After that Run the shadcn-vue init command to setup shadcn-vue in project pnpm dlx shadcn-vue@latest init.
  4. Install Collapsible and Button component from shadcn-vue.
  5. Start the local dev server pnpm run dev.
  6. Create two Collapsible one with ref (Controlled) and Second (Uncontrolled).

Describe the bug

I was checking the docs on mobile the other day and found out that on mobile "On this Page" TOC was not working. So, i decided to check what is the issue?

on-this-page-shadcn-vue.webm

In the docs we are using TableOfContent.vue component and it will show TOC for the page and there we have this On This Page Collapsible which will toggle the TOC section.

The code had no issue because we can use Collapsible both Controlled and Uncontrolled way. Here, In the docs we are using as Uncontrolled and it should work. Then i checked in our Collapsible Component Docs and there it was working but not for the "On this page" TOC.

Controlled collapsible is working but Uncontrolled collapsible not working. Also i am not sure whether this is bug from radix-vue side from our collapsible component side.

uncontrolled-collapsible-not-working.webm

Expected behavior

Collapsible should work if its controlled or uncontrolled.

Conext & Screenshots (if applicable)

No response

@ParasSolanki ParasSolanki added the bug Something isn't working label Jan 30, 2024
@sadeghbarati
Copy link
Collaborator

sadeghbarati commented Jan 30, 2024

export interface CollapsibleRootProps extends PrimitiveProps {
    /** The open state of the collapsible when it is initially rendered. <br> Use when you do not need to control its open state. */
    defaultOpen?: boolean;
    /** The controlled open state of the collapsible. Can be binded with `v-model`. */
    open?: boolean;
    /** When `true`, prevents the user from interacting with the collapsible. */
    disabled?: boolean;
}

Boolean casting curse

@ParasSolanki This is because Vue will transform undefined boolean prop to false instead of keeping it as undefined 😭

With this issue, we kinda make the Component Controlled even though we don't want too

I HOPE the Vue team fixes it soon


You have two options to fix it

1. useForwardPropsEmits and useForwardProps

<script setup lang="ts">
import { CollapsibleRoot, useForwardPropsEmits } from 'radix-vue'
import type { CollapsibleRootEmits, CollapsibleRootProps } from 'radix-vue'

const props = defineProps<CollapsibleRootProps>()
const emits = defineEmits<CollapsibleRootEmits>()

const forwarded = useForwardPropsEmits(props, emits)
</script>

<template>
  <CollapsibleRoot v-slot="{ open }" v-bind="forwarded">
    <slot :open="open" />
  </CollapsibleRoot>
</template>

2. withDeafults

<script setup lang="ts">
import { CollapsibleRoot, useEmitAsProps } from 'radix-vue'
import type { CollapsibleRootEmits, CollapsibleRootProps } from 'radix-vue'

const props = withDefaults(defineProps<CollapsibleRootProps>(), {
  defaultOpen: undefined,
  disabled: undefined,
  open: undefined,
})

const emits = defineEmits<CollapsibleRootEmits>()
</script>

<template>
  <CollapsibleRoot v-slot="{ open }" v-bind="{ ...props, ...useEmitAsProps(emits) }">
    <slot :open="open" />
  </CollapsibleRoot>
</template>

@sadeghbarati
Copy link
Collaborator

vuejs/core#8576 (comment)

@ParasSolanki
Copy link
Contributor Author

Oh interesting!
I thought maybe issue will be from our side but looks like for now we have to use Collapsible in Controlled way or add default propa values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants