Casual UI for Svelte

website·Indexed 31 days ago

https://svelte.casual-ui.site/

A simple, easy-to-use UI component library for Svelte 3+ featuring dark mode support. The library includes a wide range of components such as buttons, forms, dialogs, carousels, and data presentation tools, along with global CSS utilities for flex, grid, and sizing.

Tokens
19K
Snippets
133
Records
151
Agent score
51%

What's inside Casual UI

  1. Overview of Casual UI - Svelte

    Casual UI is a lightweight, type-friendly UI component library designed for Svelte developers using Svelte 3 or newer. Key features include full TypeScript support for component APIs, a small bundle size due to minimal third-party dependencies, and native support for dark mode UI styles across all components.
  2. Implement a closeable CTag

    To make a tag dismissible, set the closeable prop to true. This adds a close icon to the tag. When the icon is clicked, the component emits a close event which can be handled using on:close.
    <script lang="ts">
      function handleClose() {
        console.log('Tag closed');
      }
    </script>
    
    <CTag 
      label="Closeable Tag" 
      closeable 
      on:close={handleClose} 
    />
  3. Manually control CDropdown visibility

    To control the dropdown visibility via external logic or a different trigger, set the manual prop to true and use bind:show to link the visibility state to a boolean variable.
    <script lang="ts">
      let show = false
    </script>
    
    <CButton label="Click to show dropdown" on:click={() => (show = !show)} />
    
    <CDropdown manual bind:show>
      <div>Click the left button to show dropdown</div>
      <div slot="drop-content" class="p-4">Here's some drop content</div>
    </CDropdown>
  4. Implement sticky columns in CTable

    Set the sticky property in the column configuration to either 'left' or 'right' to keep that column visible while scrolling horizontally. It is recommended to provide a width when using sticky columns.
    const columns = [
      {
        title: 'Name',
        field: 'name',
        width: '100px',
        sticky: 'left',
      },
      {
        title: 'Description',
        field: 'description',
        width: '200px',
        sticky: 'right',
      },
    ]
  5. Implement form validation with CForm

    To enable validation, you must provide the value and rules props to <CForm>, and the field prop to the corresponding <CFormItem>.

    The rules object maps field names to an array of validator functions. A validator function receives the current value and returns:

    • A string: The error message to be displayed at the bottom of the form item.
    • false: Indicates no error.
    • Promise<string | false>: Used for asynchronous validation.
    type Validator = (val: any) => string | false | Promise<string | false>
    interface Rules {
      [key: string]: Array<Validator>
    }
  6. Implement asynchronous validation in CForm

    To perform asynchronous validation (e.g., checking a value against an API), define the rule function to return a Promise<string | false>. The CForm component will await the promise before determining if the field is valid.
    const rules = {
      name: [
        (v: string) =>
          new Promise<string | false>(resolve => {
            // Simulate API call
            setTimeout(() => {
              resolve(v ? false : 'Please enter name');
            }, 2000);
          }),
      ],
    };
  7. Install CNotification in the application root

    The <CNotification /> component must be placed exactly once in the entire application root to enable notification rendering. For SvelteKit projects, it is recommended to place it in the top-level layout file.
    <!-- /src/routes/+layout.svelte -->
    <CNotification /> 
    <slot />
  8. Select months or years with CDatePicker

    By changing the unit prop to 'month' or 'year', the CDatePicker switches from a day-picker to a month or year selector. You should also update the format prop to match the selected unit (e.g., MM/YYYY for months or YYYY for years).
    <!-- Month Picker -->
    <CDatePicker
      bind:value={month}
      bind:formattedValue={formattedMonth}
      format="MM/YYYY"
      unit="month"
      placeholder="Select month"
    />
    
    <!-- Year Picker -->
    <CDatePicker
      bind:value={year}
      bind:formattedValue={yearFormatted}
      format="YYYY"
      unit="year"
      placeholder="Select year"
    />
  9. Manage CButton loading and disabled states

    Use the disabled prop to prevent user interaction and the loading prop to indicate a background process. Note that the click event will not trigger when the button is in a loading or disabled state.
    <CButton label="Disabled" disabled />
    <CButton label="Loading..." loading />
  10. Create a complex list using CList and CInfoItem

    To create a list with rich content (icons, subtitles, and active states), use CList with the item slot. Pass CInfoItem into the slot to handle the layout of each row. Use the clickable prop on CList to enable interactions and activeFn to determine which item is currently active.
    <script>
      const items = [
        { title: 'Notification', subtitle: 'Some notification description', icon: 'no' },
        { title: 'Personal', subtitle: 'Some personal description', icon: 'per' },
      ]
    
      let activeItem = ''
      const handleItemClick = e => {
        activeItem = e.detail.title
      }
    </script>
    
    <CList 
      {items} 
      clickable 
      activeFn={item => activeItem === item.title} 
      on:item-click={handleItemClick}
    >
      <CInfoItem
        slot="item"
        let:active
        let:itemObj
        title={itemObj.title}
        subtitle={itemObj.subtitle}
      >
        <div slot="icon" class={itemObj.icon}></div>
        <div slot="append" class:checked-icon={active}></div>
      </CInfoItem>
    </CList>
  11. Implement custom Carousel controls

    Replace the default navigation arrows by using the control-prev and control-next slots. This allows you to insert custom buttons or elements to trigger slide changes.
    <CCarousel bind:activeIndex infinity>
      <CCarouselSlider>...</CCarouselSlider>
      
      <CButton slot="control-prev" icon flat>Prev</CButton>
      <CButton slot="control-next" icon flat>Next</CButton>
    </CCarousel>