Search code examples
sveltesveltekitsvelte-3svelte-component

Pass component as a prop in Svelte (typescript)


I have a Button component that uses the types from ButtonTypes.ts

<script lang="ts">
   import type { ButtonTypes } from './file_path' # importing button type
   export let buttonProps:ButtonTypes 
</script>

<button type="{buttonProps.type}" class="{buttonProps.customClasses}">Click</button>

In the Slider component (that uses types from sliderTypes.ts), I am using the above Button component

<script lang="ts">
    import Buttons from './file_path';
    import sliderTypes from './ file_path';
    export let sliderProps:sliderTypes          # types from sliderTypes
    export let button_props;                    # exporting button_props so that slider can be called in other files and pass props values to customize the buttons for each instance of the slider called
</script>

<div>
  <img src="{sliderProps.image}" alt="sliderProps.alt"/>
  <h1>{sliderProps.heading}</h1>
  <Button buttonProps = {...button_props}/> # This throws an error- properties are missing from type ButtonTypes
</div>

Finally, I want both Slider and Button components to be used in App.svelte(root file). I have tried the following in the App.svelte. But it does not work

<script lang="ts">
   import Slider from "./file_path";
</script>

<Slider 
   sliderProps = {{
     src="www.image_link.com",
     alt="picture_name"
}} 
  button_props = {{
   type="submit",
   class="customclass"
}}
/>

The slider component with SliderProps is rendered but the *button is not rendered.

What can be done?


Solution

  • This is wrong:

    <Button buttonProps={...button_props} />
    

    If a named property is assigned, there should not be a spread:

    <Button buttonProps={button_props} />
    

    Spreading is for assigning many individual properties where the keys on the spread object correspond to the properties. E.g.

    <script>
      // ...
      const stuff = { a: 1, b: 2 }; // Name of object does not matter
    </script>
    
    <Button {...stuff} />
    
    <!-- Button -->
    <script>
      export let a;
      export let b;
    </script>