Mishka Chelekom Documentation

repository·master·Indexed 20 days ago

https://github.com/mishka-group/mishka_chelekom

A UI kit library for Phoenix and Phoenix LiveView that uses a mix generator to inject customizable component source code directly into projects. It features a development harness with an interactive showcase, a live-edit loop for component development, and a video generation pipeline for creating component demos using JSON specs.

Tokens
167.1K
Snippets
499
Records
745
Agent score
67%

What's inside Mishka Chelekom

  1. Overview of Mishka Chelekom

    master

    Mishka Chelekom is a UI kit library for Phoenix and Phoenix LiveView projects. Instead of acting as a traditional dependency with hidden logic, it uses a mix generator to inject fully customizable component source code directly into your project.

    Key characteristics:

    • Local Generation: Components are generated locally in your project, giving you full control over the source code.
    • No Production Overhead: The library is intended for use in the development environment only; it does not add weight to your production build.
    • Customizable via CLI: You can generate components with specific variants (e.g., specific colors or shadow styles) using CLI commands to avoid code clutter.
    • Powered by Igniter: The library uses Igniter to facilitate seamless updates to previously generated code.
  2. Overview of available Component Categories

    master

    The Chelekom Design System includes a wide range of components categorized by their functional role in the UI:

    • Navigation: Navbar, Sidebar, Menu, Mega Menu, Breadcrumb, Pagination, Tabs, Speed Dial, Footer.
    • Feedback: Alert, Toast, Banner, Progress, Spinner, Skeleton, Rating, Stepper.
    • Media: Image, Video, Gallery, Carousel, Avatar, Device Mockup.
    • Overlay: Modal, Drawer, Dropdown, Popover, Tooltip, Overlay.
    • General UI: Button, Badge, Card, Accordion, Collapse, List, Table, Timeline, Divider, Indicator, Typography, Icon.
    • Form: Input Field, Text Field, Textarea, Checkbox, Radio, Toggle, Select, Combobox, Date/Time Picker, File Upload, Range Slider.
  3. Explore components in the interactive showcase

    master

    The development harness provides an interactive showcase for all components:

    • /showcase: A list of components grouped by category.
    • /showcase/:component: An interactive prop explorer for a specific component. It includes:
      • Controls derived from the component's catalog args.
      • A live preview.
      • A copy-pasteable HEEx snippet for easy integration.
  4. Reuse and restyle components with the Kit

    master

    The Kit (MishkaChelekom.Kit) is an opt-in Spark DSL that allows you to reuse and restyle generated components without modifying their original files. It creates thin wrappers that delegate to the real component.

    Key features:

    • Styling: Use customize to define colors, variants, or sizes. Use the ! suffix (e.g., bg-brand-500!) to ensure Tailwind classes are applied verbatim.
    • Headless Customization: For components like dialogs, use part to style specific sub-elements using the [&_[data-part=...]] selector pattern.
    • Vendoring: Because the Kit is a live macro, you must vendor it into your application for production. Use the CLI to copy the engine to your lib/ directory.

    For a full DSL reference, see usage-rules/docs/kit.md.

    defmodule MyAppWeb.Kit do
      use MishkaChelekom.Kit
    
      customize :button do
        color :brand, "bg-brand-500! text-white!"
        default color: :brand
      end
    
      customize :confirm_dialog do
        from :dialog
        part :popup, "[&_[data-part=popup]]:rounded-2xl"
      end
    end
  5. How the headless toggle manages state and accessibility

    master

    The headless toggle manages its state through a combination of ARIA attributes and data attributes, synchronized by the Toggle JS engine.

    State Attributes

    The engine toggles the following mutually exclusive attributes on the root <button>:

    • data-on: Present when the button is pressed.
    • data-off: Present when the button is not pressed.
    • aria-pressed: Mirrors the state ("true" or "false") to satisfy WAI-ARIA requirements.

    Accessibility & Interaction

    • Keyboard: Supports Enter and Space to toggle state. Space calls preventDefault() to ensure standard button behavior.
    • Mouse: Toggles on click.
    • Disabled State: If the data-disabled attribute is present on the root, all activations are ignored.
    • Pattern: Implements the WAI-ARIA APG Button (Toggle) pattern.
  6. How the Sidebar minimize/expand state works

    master

    The sidebar uses a minimized state to toggle between a full-width view and an icon-only view.

    Behavior when minimized:

    1. The sidebar width is reduced (typically to a fixed width like 4rem).
    2. Elements with the .sidebar-text class are hidden (display: none).
    3. The .minimize-icon rotates (typically 180 degrees).
    4. The state is persistent (the hook remembers the minimized state).
  7. Use the Alert component for static and dynamic messages

    master

    The Alert component provides three main types of UI elements for Phoenix LiveView:

    1. flash/1: Flash notices that feature auto-dismiss on click.
    2. flash_group/1: A container that displays a group of flash messages with predefined content. It also automatically handles LiveView disconnection/reconnection by showing client/server error flashes.
    3. alert/1: Static alert messages used for persistent notifications.

    All three components accept an inner_block slot for custom content.

    <.alert kind={:info} title="Information">
      This is an informational message.
    </.alert>
  8. Common Drawer Patterns: Mobile Nav, Shopping Cart, and Filters

    master

    The Drawer component is commonly used for:

    1. Mobile Navigation: A large drawer positioned on the left containing navigation links.
    2. Shopping Cart: A right positioned drawer showing cart items and a checkout button.
    3. Filter Panel: A right positioned drawer containing forms for filtering content.
    <%!-- Mobile Navigation Pattern --%>
    <.button phx-click={show_drawer("mobile-nav")} class="md:hidden">
      <.icon name="hero-bars-3" />
    </.button>
    
    <.drawer id="mobile-nav" position="left" size="large">
      <:header>
        <div class="flex items-center gap-2">
          <img src="/logo.svg" class="h-8" />
          <span class="font-bold">MyApp</span>
        </div>
      </:header>
      <nav class="space-y-1">
        <a :for={item <- @nav_items} href={item.path} class="block p-3 hover:bg-gray-100 rounded">
          {item.label}
        </a>
      </nav>
    </.drawer>
    
    <%!-- Shopping Cart Pattern --%>
    <.drawer id="cart-drawer" position="right" size="large">
      <:header>Shopping Cart ({@cart_count})</:header>
      <div class="space-y-4">
        <div :for={item <- @cart_items} class="flex gap-4 border-b pb-4">
          <img src={item.image} class="w-16 h-16 object-cover rounded" />
          <div class="flex-1">
            <p class="font-medium">{item.name}</p>
            <p class="text-gray-500">${item.price}</p>
          </div>
        </div>
      </div>
      <div class="mt-auto pt-4 border-t">
        <div class="flex justify-between mb-4">
          <span>Total:</span>
          <span class="font-bold">${@cart_total}</span>
        </div>
        <.button full_width color="primary">Checkout</.button>
      </div>
    </.drawer>
    
    <%!-- Filter Panel Pattern --%>
    <.drawer id="filters" position="right">
      <:header>Filters</:header>
      <.form for={@filter_form} phx-change="filter">
        <div class="space-y-4">
          <div>
            <label class="font-medium">Category</label>
            <.group_checkbox field={@filter_form[:categories]}>
              <:checkbox :for={cat <- @categories} value={cat.id} label={cat.name} />
            </.group_checkbox>
          </div>
          <div>
            <label class="font-medium">Price Range</label>
            <.range_field field={@filter_form[:price]} min={0} max={1000} />
          </div>
        </div>
        <.button type="submit" class="mt-4">Apply Filters</.button>
      </.form>
    </.drawer>
  9. Configure ScrollArea element structure and CSS classes

    master

    The ScrollArea hook operates on a specific DOM hierarchy. If you are building a custom implementation or debugging, ensure the following structure and classes are present:

    Required DOM Structure

    <div id="scroll-1" phx-hook="ScrollArea" class="scroll-area-wrapper">
      <!-- Scrollable viewport -->
      <div class="scroll-viewport">
        <div class="scroll-content">
          <!-- Your content here -->
        </div>
      </div>
    
      <!-- Vertical scrollbar -->
      <div class="scrollbar-y">
        <div class="thumb-y"></div>
      </div>
    
      <!-- Horizontal scrollbar -->
      <div class="scrollbar-x">
        <div class="thumb-x"></div>
      </div>
    </div>

    CSS Class Reference

    • .scroll-area-wrapper: The main container.
    • .scroll-viewport: The scrollable area (native scrollbars are hidden here via scrollbar-width: none and ::-webkit-scrollbar { display: none }).
    • .scroll-content: The inner wrapper for your content.
    • .scrollbar-y / .scrollbar-x: The tracks for vertical and horizontal scrollbars.
    • .thumb-y / .thumb-x: The draggable thumb elements for vertical and horizontal scrollbars.
  10. Use the Table Content component

    master

    The table_content component is used for structured content displays like tables of contents or nested sidebars. It relies on the icon component as a necessary dependency.

    Components

    • table_content/1: The main content container.
    • content_item/1: An individual item within the list.
    • content_wrapper/1: A wrapper used inside a content_item to hold nested sub-items.
    <.table_content title="Contents">
      <.content_item icon="hero-hashtag" active>Current Section</.content_item>
      <.content_item icon="hero-hashtag">
        <.link href="#getting-started">Getting Started</.link>
      </.content_item>
    </.table_content>
  11. Anatomy and ARIA of the Popover

    master

    The Popover component relies on specific data-part attributes to allow the JavaScript engine to identify and control the trigger and the popup.

    Component Parts

    PartElementdata-part hookNotes
    trigger<button>data-part="trigger"Toggles the popup on click
    popup`<div

    |data-part="popup"|role="dialog"`, anchored content |

    Accessibility (ARIA & Keyboard)

    • Trigger: Automatically manages aria-expanded ("true"/"false") and aria-controls (linked to the popup's ID).
    • Popup: Uses role="dialog".
    • Dismissal:
      • Pressing Escape closes the popup and returns focus to the trigger.
      • Clicking outside the popup closes it.
    • Focus Management: When opened, focus automatically moves to the first focusable element inside the popup (e.g., [data-part="item"], [role="menuitem"], [role="option"], a, or button).