DEV Community

Lucas Bennett
Lucas Bennett

Posted on

Getting Started with Basic Components in svar-core for Svelte

svar-core (also known as SVAR UI) is a powerful UI component library that provides feature-rich, advanced widgets for Svelte applications. It offers a comprehensive set of components including buttons, popups, modals, grids, and more, all designed to work seamlessly with Svelte's reactive system. This guide walks through setting up svar-core and building your first interactive components using Button and Popup. This article is part 19 of a series on using svar-core with Svelte.

Prerequisites

Before you begin, make sure you have:

  • Node.js version 16 or higher installed
  • npm or yarn package manager
  • A basic understanding of Svelte (components, reactivity, events)
  • A Svelte project set up (using SvelteKit, Vite, or any Svelte setup)

For this tutorial, we'll work with a simple Svelte component structure. The key concepts you'll learn are:

  • Importing components: How to bring svar-core components into your Svelte files
  • Skin wrapper: Using the Willow skin component to style your entire application
  • Event handling: Connecting button clicks and popup interactions
  • Conditional rendering: Showing and hiding popups based on state

Installation

Install the svar-core package using npm or yarn:

npm install @svar-ui/svelte-core
Enter fullscreen mode Exit fullscreen mode

Or with yarn:

yarn add @svar-ui/svelte-core
Enter fullscreen mode Exit fullscreen mode

After installation, your package.json should include the dependency:

{
  "dependencies": {
    "@svar-ui/svelte-core": "^1.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Project Setup

To use svar-core components properly, you need to wrap your application with a skin component. The library provides several skins, and we'll use the Willow skin for this tutorial. This ensures consistent styling across all components.

In your main application file (typically App.svelte or your root component), import and use the Willow wrapper:

<!-- App.svelte -->
<script>
  import { Willow } from "@svar-ui/svelte-core";
</script>

<Willow>
  <!-- Your entire application goes here -->
</Willow>
Enter fullscreen mode Exit fullscreen mode

The <Willow> component applies the default theme to all svar-core components within it. You can place your entire application content inside this wrapper.

First Example / Basic Usage

Let's create a simple example with a Button component:

<!-- src/components/SimpleButton.svelte -->
<script>
  import { Button, Willow } from "@svar-ui/svelte-core";

  function handleClick() {
    alert("Button clicked!");
  }
</script>

<Willow>
  <div style="padding: 20px;">
    <Button onclick={handleClick}>Click Me</Button>
  </div>
</Willow>
Enter fullscreen mode Exit fullscreen mode

This example demonstrates:

  • Import: We import Button and Willow from @svar-ui/svelte-core
  • Event handler: The handleClick function runs when the button is clicked
  • onclick prop: We pass the function to the button's onclick property
  • Skin wrapper: The Willow component ensures proper styling

When you click the button, you'll see an alert dialog. The button is styled with svar-core's default theme.

Understanding the Basics

How svar-core Integrates with Svelte

svar-core components are built specifically for Svelte and follow Svelte's reactive patterns:

  1. Props: Components accept props just like regular Svelte components
  2. Events: Use onclick, oncancel, etc. to handle user interactions
  3. Reactivity: Components react to state changes automatically
  4. Styling: The skin system provides consistent theming

Button Component Properties

The Button component supports several useful properties:

<script>
  import { Button, Willow } from "@svar-ui/svelte-core";

  let isDisabled = false;

  function toggleDisabled() {
    isDisabled = !isDisabled;
  }
</script>

<Willow>
  <div style="padding: 20px; display: flex; gap: 10px; flex-direction: column;">
    <!-- Basic button -->
    <Button>Default Button</Button>

    <!-- Primary button -->
    <Button type="primary">Primary Button</Button>

    <!-- Disabled button -->
    <Button disabled={isDisabled}>Toggle Disabled</Button>

    <!-- Button with custom click handler -->
    <Button onclick={toggleDisabled}>
      {isDisabled ? "Enable" : "Disable"} Button Above
    </Button>
  </div>
</Willow>
Enter fullscreen mode Exit fullscreen mode

Key properties:

  • type: Sets button style ("primary", "danger", etc.)
  • disabled: Boolean to disable/enable the button
  • onclick: Function to handle click events
  • css: Custom CSS class for additional styling

Popup Component Basics

The Popup component creates overlay dialogs. Here's a simple example:

<script>
  import { Button, Popup, Willow } from "@svar-ui/svelte-core";

  let showPopup = false;

  function openPopup() {
    showPopup = true;
  }

  function closePopup() {
    showPopup = false;
  }
</script>

<Willow>
  <div style="padding: 20px;">
    <Button onclick={openPopup}>Show Popup</Button>
  </div>

  {#if showPopup}
    <Popup onclick={closePopup} oncancel={closePopup}>
      <div style="padding: 20px; background: white; border-radius: 8px;">
        <h3>Hello from Popup!</h3>
        <p>This is a simple popup dialog.</p>
        <Button onclick={closePopup}>Close</Button>
      </div>
    </Popup>
  {/if}
</Willow>
Enter fullscreen mode Exit fullscreen mode

The Popup component:

  • Conditional rendering: Use {#if} to show/hide based on state
  • oncancel: Triggered when clicking outside the popup or pressing Escape
  • onclick: Can be used for custom close logic
  • Content: Any Svelte content can be placed inside the popup

Practical Example / Building Something Real

Let's build a complete contact form with validation feedback using Button and Popup:

<!-- src/components/ContactForm.svelte -->
<script>
  import { Button, Popup, Willow, Text } from "@svar-ui/svelte-core";

  let showSuccessPopup = false;
  let showErrorPopup = false;
  let name = "";
  let email = "";
  let message = "";
  let isSubmitting = false;

  function validateForm() {
    if (!name.trim() || !email.trim() || !message.trim()) {
      return false;
    }
    // Simple email validation
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  }

  async function handleSubmit() {
    if (!validateForm()) {
      showErrorPopup = true;
      return;
    }

    isSubmitting = true;

    // Simulate API call
    setTimeout(() => {
      isSubmitting = false;
      showSuccessPopup = true;
      // Reset form
      name = "";
      email = "";
      message = "";
    }, 1000);
  }

  function closeSuccessPopup() {
    showSuccessPopup = false;
  }

  function closeErrorPopup() {
    showErrorPopup = false;
  }
</script>

<Willow>
  <div style="max-width: 500px; margin: 40px auto; padding: 20px;">
    <h2>Contact Us</h2>

    <form on:submit|preventDefault={handleSubmit} style="display: flex; flex-direction: column; gap: 15px;">
      <div>
        <label for="name" style="display: block; margin-bottom: 5px;">Name:</label>
        <input
          id="name"
          type="text"
          bind:value={name}
          placeholder="Your name"
          style="width: 100%; padding: 8px; box-sizing: border-box;"
        />
      </div>

      <div>
        <label for="email" style="display: block; margin-bottom: 5px;">Email:</label>
        <input
          id="email"
          type="email"
          bind:value={email}
          placeholder="your.email@example.com"
          style="width: 100%; padding: 8px; box-sizing: border-box;"
        />
      </div>

      <div>
        <label for="message" style="display: block; margin-bottom: 5px;">Message:</label>
        <textarea
          id="message"
          bind:value={message}
          placeholder="Your message"
          rows="5"
          style="width: 100%; padding: 8px; box-sizing: border-box;"
        ></textarea>
      </div>

      <Button type="primary" onclick={handleSubmit} disabled={isSubmitting}>
        {isSubmitting ? "Submitting..." : "Send Message"}
      </Button>
    </form>
  </div>

  <!-- Success Popup -->
  {#if showSuccessPopup}
    <Popup onclick={closeSuccessPopup} oncancel={closeSuccessPopup}>
      <div style="padding: 30px; background: white; border-radius: 8px; max-width: 400px; text-align: center;">
        <h3 style="color: #4caf50; margin-top: 0;">Success!</h3>
        <p>Your message has been sent successfully.</p>
        <Button type="primary" onclick={closeSuccessPopup}>OK</Button>
      </div>
    </Popup>
  {/if}

  <!-- Error Popup -->
  {#if showErrorPopup}
    <Popup onclick={closeErrorPopup} oncancel={closeErrorPopup}>
      <div style="padding: 30px; background: white; border-radius: 8px; max-width: 400px; text-align: center;">
        <h3 style="color: #f44336; margin-top: 0;">Error</h3>
        <p>Please fill in all fields with valid information.</p>
        <Button type="primary" onclick={closeErrorPopup}>OK</Button>
      </div>
    </Popup>
  {/if}
</Willow>
Enter fullscreen mode Exit fullscreen mode

This example demonstrates:

  • Form handling: Collecting user input with Svelte's bind:value
  • Validation: Checking form data before submission
  • Loading state: Disabling button during submission
  • Multiple popups: Managing different popup states
  • User feedback: Success and error messages
  • Real-world pattern: A complete, usable contact form

Common Issues / Troubleshooting

Issue 1: Components Not Styled Correctly

Problem: Buttons and other components appear unstyled or broken.

Solution: Make sure you've wrapped your application with the <Willow> component (or another skin). All svar-core components must be inside a skin wrapper to receive proper styling.

<!-- ❌ Wrong -->
<Button>Click Me</Button>

<!-- ✅ Correct -->
<Willow>
  <Button>Click Me</Button>
</Willow>
Enter fullscreen mode Exit fullscreen mode

Issue 2: Popup Not Closing

Problem: Popup doesn't close when clicking outside or pressing Escape.

Solution: Ensure you've provided the oncancel handler and are updating the state variable that controls visibility:

<!-- ❌ Wrong - no oncancel handler -->
<Popup>
  <div>Content</div>
</Popup>

<!-- ✅ Correct -->
<Popup oncancel={() => showPopup = false}>
  <div>Content</div>
</Popup>
Enter fullscreen mode Exit fullscreen mode

Issue 3: Button Click Not Working

Problem: Click handler function doesn't execute.

Solution: Use the onclick prop (not on:click). svar-core uses props for event handling:

<!-- ❌ Wrong - Svelte native syntax -->
<Button on:click={handleClick}>Click Me</Button>

<!-- ✅ Correct - svar-core prop syntax -->
<Button onclick={handleClick}>Click Me</Button>
Enter fullscreen mode Exit fullscreen mode

Issue 4: Import Errors

Problem: Module not found or import errors.

Solution: Verify the package is installed and you're using the correct import path:

<!-- ✅ Correct import -->
import { Button, Popup, Willow } from "@svar-ui/svelte-core";
Enter fullscreen mode Exit fullscreen mode

Make sure the package name is exactly @svar-ui/svelte-core (not svar-core).

Next Steps

Now that you've learned the basics of svar-core, here are some directions to continue learning:

  1. Explore More Components: Try out other components like Modal, Text, Textarea, and Checkbox
  2. Advanced Popup Features: Learn about positioning popups relative to elements using the at and parent properties
  3. Custom Styling: Explore the css property for applying custom styles to components
  4. Data Grid: Check out @svar-ui/svelte-grid for building data tables
  5. Form Components: Explore form-related components for building complex forms
  6. Official Documentation: Visit the svar-core documentation for complete API reference

Continue with other articles in this series to learn about advanced features, data grids, filters, and more complex use cases.

Summary

You've learned how to set up svar-core in a Svelte project, use the Button and Popup components, and build a complete contact form with validation. You should now be able to integrate svar-core components into your Svelte applications, handle user interactions, and create interactive dialogs and forms.

Top comments (0)