Knob

Circular input controls

Preview

50

Props Editor

✅ JSON is valid - Click "Preview Update" to see changes

Source Code

defmodule FeenixUiWeb.Components.KnobComponent do
  use Phoenix.Component

  def render(assigns) do
    assigns = assign_new(assigns, :value, fn -> 50 end)
    assigns = assign_new(assigns, :min, fn -> 0 end)
    assigns = assign_new(assigns, :max, fn -> 100 end)
    assigns = assign_new(assigns, :step, fn -> 1 end)

    percentage = ((assigns.value - assigns.min) / (assigns.max - assigns.min)) * 100
    assigns = assign(assigns, :percentage, percentage)

    ~H"""
    <div class="flex flex-col items-center">
      <div class="relative w-24 h-24">
        <svg class="w-24 h-24 transform -rotate-90" viewBox="0 0 100 100">
          <circle
            cx="50"
            cy="50"
            r="40"
            stroke="currentColor"
            stroke-width="8"
            fill="transparent"
            class="text-gray-200"
          />
          <circle
            cx="50"
            cy="50"
            r="40"
            stroke="currentColor"
            stroke-width="8"
            fill="transparent"
            stroke-dasharray="251.2"
            stroke-dashoffset={251.2 - (251.2 * @percentage / 100)}
            class="text-primary-600 transition-all duration-300"
          />
        </svg>
        <div class="absolute inset-0 flex items-center justify-center">
          <span class="text-lg font-semibold text-gray-900"><%= @value %></span>
        </div>
      </div>
      <div class="mt-4 flex items-center space-x-2">
        <button class="w-8 h-8 rounded-full bg-gray-200 hover:bg-gray-300 flex items-center justify-center">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 12H4"></path>
          </svg>
        </button>
        <button class="w-8 h-8 rounded-full bg-gray-200 hover:bg-gray-300 flex items-center justify-center">
          <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path>
          </svg>
        </button>
      </div>
    </div>
    """
  end
end