{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "import panel as pn\n",
    "import holoviews as hv\n",
    "import numpy as np\n",
    "import holoviews.plotting.bokeh\n",
    "\n",
    "pn.extension(loading_spinner='dots', loading_color='#00aa41', sizing_mode=\"stretch_width\")\n",
    "hv.extension('bokeh')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Every pane, widget and layout provides the **`loading` parameter**. When set to `True` a spinner will overlay the panel and indicate that the panel is currently loading. When you set `loading` to false the spinner is removed. \n",
    "\n",
    "Using the `pn.extension` or by setting the equivalent parameters on `pn.config` we can select between different visual styles and colors for the loading indicator.\n",
    "\n",
    "```python\n",
    "pn.extension(loading_spinner='dots', loading_color='#00aa41')\n",
    "```\n",
    "\n",
    "We can enable the loading indicator for reactive functions annotated with `depends` or `bind` globally using:\n",
    "\n",
    "```python\n",
    "pn.param.ParamMethod.loading_indicator = True\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively we can enable it for a specific function by passing the `loading_indicator=True` argument into `pn.panel` which returns a `ParamMethod`/`ParamFunction` object with the parameter set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "button = pn.widgets.Button(name=\"UPDATE\", button_type=\"primary\")\n",
    "\n",
    "def random_plot(event):\n",
    "    if event: time.sleep(2)\n",
    "    return hv.Points(np.random.rand(100, 2)).opts(\n",
    "        width=400, height=400, size=8, color=\"green\")\n",
    "\n",
    "component = pn.Column(button, pn.panel(pn.bind(random_plot, button), loading_indicator=True))\n",
    "component"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## App\n",
    "\n",
    "Lets wrap it into nice template that can be served via `panel serve download_upload_csv.ipynb`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "description = \"\"\"\n",
    "Every pane, widget and layout provides the **`loading` parameter**. When set to `True` a spinner will overlay the panel and indicate that the panel is currently loading. When you set `loading` to false the spinner is removed. \n",
    "\n",
    "Using the `pn.extension` or by setting the equivalent parameters on `pn.config` we can select between different visual styles and colors for the loading indicator.\n",
    "\n",
    "```python\n",
    "pn.extension(loading_spinner='dots', loading_color='#00aa41')\n",
    "```\n",
    "\n",
    "We can enable the loading indicator for reactive functions annotated with `depends` or `bind` globally using:\n",
    "\n",
    "```python\n",
    "pn.param.ParamMethod.loading_indicator = True\n",
    "```\n",
    "\"\"\"\n",
    "pn.template.FastListTemplate(\n",
    "    site=\"Panel\", title=\"Loading Indicator\", \n",
    "    main=[ description, component]).servable();"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
