diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index d3829dd..2ea191e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -15,7 +15,7 @@ jobs: - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install JupyterLab - run: python -m pip install jupyterlab + run: python -m pip install 'jupyterlab >=3.1,<4' - name: Lint TypeScript run: | jlpm diff --git a/examples/icons.ipynb b/examples/icons.ipynb index d8ca5f0..ec6291c 100644 --- a/examples/icons.ipynb +++ b/examples/icons.ipynb @@ -149,10 +149,59 @@ "app = JupyterFrontEnd()\n", "panel = Panel([icon_controls])\n", "panel.title.icon = icon\n", + "panel.title.closable = False\n", "dlink((background, \"value\"), (panel.title, \"label\"))\n", "app.shell.add(panel, \"main\", {\"mode\": \"split-right\"})" ] }, + { + "cell_type": "markdown", + "id": "1df9a22e-90d6-440a-9921-3519e0e4da53", + "metadata": {}, + "source": [ + "### More Title Options\n", + "\n", + "Titles can also include a number of other options." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ebb3698f-7752-4584-89f1-7d552264a04e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from ipywidgets import Text, Checkbox, IntText\n", + "import json\n", + "\n", + "def noop(value):\n", + " return value\n", + "\n", + "def as_json(value):\n", + " try:\n", + " return json.loads(value)\n", + " except:\n", + " return {}\n", + "\n", + "\n", + "title_controls = []\n", + "for field_name in [\"label\", \"caption\", \"icon_class\", \"class_name\", \"dataset\"]:\n", + " link_fn = noop\n", + " placeholder = \"\"\n", + " if field_name == \"dataset\":\n", + " placeholder = \"{}\" \n", + " link_fn = as_json\n", + " field = Text(description=field_name, placeholder=placeholder)\n", + " dlink((field, \"value\"), (panel.title, field_name), link_fn)\n", + " title_controls.append(field)\n", + "closable = Checkbox(description=\"closable?\")\n", + "dlink((closable, \"value\"), (panel.title, \"closable\"))\n", + "title_controls += [closable]\n", + "panel.children = [icon_controls, *title_controls]" + ] + }, { "cell_type": "markdown", "id": "f3018262-e383-4b8e-b0cb-b8cefd936d98", diff --git a/ipylab/widgets.py b/ipylab/widgets.py index 2a22929..f499647 100644 --- a/ipylab/widgets.py +++ b/ipylab/widgets.py @@ -2,7 +2,7 @@ # Distributed under the terms of the Modified BSD License. from ipywidgets import VBox, Widget, register, widget_serialization -from traitlets import Bool, Instance, Unicode +from traitlets import Bool, Dict, Instance, Unicode from ._frontend import module_name, module_version from .icon import Icon @@ -15,7 +15,12 @@ class Title(Widget): label = Unicode().tag(sync=True) icon_class = Unicode().tag(sync=True) + caption = Unicode().tag(sync=True) + class_name = Unicode().tag(sync=True) closable = Bool(True).tag(sync=True) + dataset = Dict().tag(sync=True) + icon_label = Unicode().tag(sync=True) + icon = Instance(Icon, allow_none=True).tag(sync=True, **widget_serialization) diff --git a/src/widgets/shell.ts b/src/widgets/shell.ts index d144257..3051e20 100644 --- a/src/widgets/shell.ts +++ b/src/widgets/shell.ts @@ -83,11 +83,16 @@ export class ShellModel extends WidgetModel { ); const updateTitle = async (): Promise => { - const icon = await unpack_models(title.get('icon'), this.widget_manager); + luminoWidget.title.caption = title.get('caption'); + luminoWidget.title.className = title.get('class_name'); + luminoWidget.title.closable = title.get('closable'); luminoWidget.title.label = title.get('label'); - luminoWidget.title.iconClass = icon ? null : title.get('icon_class'); + luminoWidget.title.dataset = title.get('dataset'); + luminoWidget.title.iconLabel = title.get('icon_label'); + + const icon = await unpack_models(title.get('icon'), this.widget_manager); luminoWidget.title.icon = icon ? icon.labIcon : null; - luminoWidget.title.closable = title.get('closable'); + luminoWidget.title.iconClass = icon ? null : title.get('icon_class'); }; title.on('change', updateTitle);