{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "pn.extension()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``ButtonIcon`` widget allows triggering events when the button is clicked. In addition to a value parameter, which will button from `False` to `True` while the click event is being processed an additional ``clicks`` parameter that can be watched to subscribe to click events.\n",
    "\n",
    "This widget displays a default `icon` initially. Upon being clicked, an `active_icon` appears for a specified `toggle_duration`.\n",
    "\n",
    "For instance, the `ButtonIcon` can be effectively utilized to implement a feature akin to ChatGPT's copy-to-clipboard button.\n",
    "\n",
    "Discover more on using widgets to add interactivity to your applications in the [how-to guides on interactivity](../../how_to/interactivity/index.md). Alternatively, learn [how to set up callbacks and (JS-)links between parameters](../../how_to/links/index.md) or [how to use them as part of declarative UIs with Param](../../how_to/param/index.md).\n",
    "\n",
    "#### Parameters:\n",
    "\n",
    "For details on other options for customizing the component see the [layout](../../how_to/layout/index.md) and [styling](../../how_to/styling/index.md) how-to guides.\n",
    "\n",
    "##### Core\n",
    "\n",
    "* **`active_icon`** (str): The name of the icon to display when toggled from [tabler-icons.io](https://tabler-icons.io)/\n",
    "* **`clicks`** (integer): The number of times the icon was clicked.\n",
    "* **`icon`** (str): The name of the icon to display from [tabler-icons.io](https://tabler-icons.io)/ or an SVG.\n",
    "* **`toggle_duration`** (integer): The number of milliseconds the active_icon should be shown for and how long the button should be disabled for.\n",
    "* **`value`** (boolean): Toggles from False to True while the event is being processed.\n",
    "\n",
    "##### Display\n",
    "\n",
    "* **``description``** (str | Bokeh Tooltip | pn.widgets.TooltipIcon): A description which is shown when the widget is hovered.\n",
    "* **`disabled`** (boolean): Whether the widget is editable\n",
    "* **`name`** (str): The title of the widget\n",
    "* **`size`** (str): Optional explicit size as a CSS font-size value, e.g. '1em' or '20px'. \n",
    "\n",
    "___"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "button = pn.widgets.ButtonIcon(icon=\"heart\", size=\"4em\", description=\"favorite\")\n",
    "button"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also replace the `description` with `name` to have it shown on the side."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "button = pn.widgets.ButtonIcon(icon=\"heart\", size=\"4em\", name=\"favorite\")\n",
    "button"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The ``clicks`` parameter will report the number of times the button has been pressed:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "button.clicks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can `bind` to the `Button` to trigger actions when the `Button` is clicked."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "indicator = pn.indicators.LoadingSpinner(value=False, size=25)\n",
    "\n",
    "def update_indicator(event):\n",
    "    if not event:\n",
    "        return\n",
    "    indicator.value = not indicator.value\n",
    "\n",
    "pn.bind(update_indicator, button, watch=True)\n",
    "\n",
    "pn.Column(button, indicator)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also `bind` to the `clicks` parameter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def handle_click(clicks):\n",
    "    return f'You have clicked me {clicks} times'\n",
    "\n",
    "pn.Column(\n",
    "    button,\n",
    "    pn.bind(handle_click, button.param.clicks),\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively you can use the ``on_click`` method to trigger a function when the button is clicked:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "text = pn.widgets.TextInput(value='Ready')\n",
    "\n",
    "def b(event):\n",
    "    text.value = 'Clicked {0} times'.format(button.clicks)\n",
    "    \n",
    "button.on_click(b)\n",
    "pn.Row(button, text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By default, when `value` is `True`, the `active_icon` (`heart-filled`) is the filled version of the `icon` (`heart`).\n",
    "\n",
    "If you'd like this to be changed, manually set the `active_icon`.\n",
    "\n",
    "The icon will automatically adapt to the specified `width`/`height` but you may also provide an explicit `size`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.widgets.ButtonIcon(icon=\"clipboard\", active_icon=\"check\", size=\"4em\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `toggle_duration`, in milliseconds, will determine how long the `active_icon` should be shown for and how long the button should be `disabled` for."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.widgets.ButtonIcon(icon=\"clipboard\", active_icon=\"check\", toggle_duration=2500, size=\"4em\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also use SVGs for icons."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "SVG = \"\"\"\n",
    "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"icon icon-tabler icon-tabler-ad-off\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M9 5h10a2 2 0 0 1 2 2v10m-2 2h-14a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2\" /><path d=\"M7 15v-4a2 2 0 0 1 2 -2m2 2v4\" /><path d=\"M7 13h4\" /><path d=\"M17 9v4\" /><path d=\"M16.115 12.131c.33 .149 .595 .412 .747 .74\" /><path d=\"M3 3l18 18\" /></svg>\n",
    "\"\"\"\n",
    "ACTIVE_SVG = \"\"\"\n",
    "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"icon icon-tabler icon-tabler-ad-filled\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" stroke-width=\"2\" stroke=\"currentColor\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M19 4h-14a3 3 0 0 0 -3 3v10a3 3 0 0 0 3 3h14a3 3 0 0 0 3 -3v-10a3 3 0 0 0 -3 -3zm-10 4a3 3 0 0 1 2.995 2.824l.005 .176v4a1 1 0 0 1 -1.993 .117l-.007 -.117v-1h-2v1a1 1 0 0 1 -1.993 .117l-.007 -.117v-4a3 3 0 0 1 3 -3zm0 2a1 1 0 0 0 -.993 .883l-.007 .117v1h2v-1a1 1 0 0 0 -1 -1zm8 -2a1 1 0 0 1 .993 .883l.007 .117v6a1 1 0 0 1 -.883 .993l-.117 .007h-1.5a2.5 2.5 0 1 1 .326 -4.979l.174 .029v-2.05a1 1 0 0 1 .883 -.993l.117 -.007zm-1.41 5.008l-.09 -.008a.5 .5 0 0 0 -.09 .992l.09 .008h.5v-.5l-.008 -.09a.5 .5 0 0 0 -.318 -.379l-.084 -.023z\" stroke-width=\"0\" fill=\"currentColor\" /></svg>\n",
    "\"\"\"\n",
    "\n",
    "pn.widgets.ButtonIcon(icon=SVG, active_icon=ACTIVE_SVG, size='4em')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Controls\n",
    "\n",
    "The `ButtonIcon` widget exposes a number of options which can be changed from both Python and Javascript. Try out the effect of these parameters interactively:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "pn.Row(button.controls(jslink=True), button)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
