Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
5550bff
feat: Vuetify3 support
mariobuikhuizen Oct 31, 2023
bc27561
build: sort components and properties in the generated code
mariobuikhuizen Nov 1, 2023
7853dfa
build: use latest node LTS version
mariobuikhuizen Nov 1, 2023
9cb02ae
feat: keep same module structure for generated python code
mariobuikhuizen Nov 1, 2023
f9645ad
chore: bump version 1.8.10 -> 3.0.0.dev0
mariobuikhuizen Nov 1, 2023
04c984c
chore: require ipyvue>=3.0.0.dev0
maartenbreddels Nov 1, 2023
6766f4f
chore: update reacton component
maartenbreddels Nov 1, 2023
314c860
chore: format code with new line width
maartenbreddels Nov 1, 2023
a853e05
fix: typo pm->npm
maartenbreddels Nov 1, 2023
0027704
temp: install solara from branch
maartenbreddels Nov 1, 2023
867c436
docs: make example notebooks work
mariobuikhuizen Nov 1, 2023
c22036d
temp: install ipyvue from branch
maartenbreddels Nov 1, 2023
418ce22
fix: no need for special nodeps view
maartenbreddels Nov 2, 2023
2a7c4ef
feat: reintroduce vueRender so we can keep the templates the same
mariobuikhuizen Nov 8, 2023
035628d
chore: use new prepend-icon prop of vuetify3 in ui-tests
mariobuikhuizen Nov 9, 2023
7c5439e
build: use correct cli param in ui-tests
mariobuikhuizen Nov 9, 2023
7de8ecf
build: accept the small change in rendering for ui-tests
mariobuikhuizen Nov 9, 2023
a620e5a
build: accept visual change in ui-test
mariobuikhuizen Nov 13, 2023
6e181e5
feat: add theme support
mariobuikhuizen Nov 15, 2023
2b46ede
chore: remove commented-out code, update js model versions
mariobuikhuizen Nov 17, 2023
662a9d3
chore: release v3.0.0.alpha1
mariobuikhuizen Nov 17, 2023
f5bac3a
build: use correct version in pypackage.toml and add dry-run
mariobuikhuizen Nov 20, 2023
e35eddd
fix: relax ipyvue version constraint a bit
mariobuikhuizen Nov 28, 2023
cf651f0
chore: bump ipyvue version
mariobuikhuizen Nov 28, 2023
dccdd10
chore: release v3.0.0.alpha2
mariobuikhuizen Nov 28, 2023
27fc095
chore: add build all script
iisakkirotko Feb 24, 2025
3377ce2
feat: scope vuetify styles with :where
iisakkirotko Feb 24, 2025
4ae4ab7
feat: export Vue and Vuetify
iisakkirotko Feb 24, 2025
3822d48
chore: bump external actions
iisakkirotko Feb 24, 2025
6167abf
chore: use jupyter-vue version 3
iisakkirotko Feb 24, 2025
042e4b0
chore: move test runners to ubuntu-22.04
iisakkirotko Feb 25, 2025
49f8a4a
chore: update officially supported Python versions to 3.6-3.13
iisakkirotko Feb 27, 2025
08a5dbc
fix: revert css extraction (#332)
iisakkirotko Feb 27, 2025
898b604
fix: ensure correct styles are excluded from scoping
iisakkirotko Feb 27, 2025
10fe7eb
chore: release v3.0.0.alpha3
mariobuikhuizen Feb 28, 2025
ad5f8bc
fix: get the right vue export for nodeps for solara
mariobuikhuizen Mar 5, 2026
a390f47
publish dev release to github releases
mariobuikhuizen Mar 5, 2026
25682d0
fix github release download
mariobuikhuizen Mar 5, 2026
6aea0f7
use object store instead of github releases
mariobuikhuizen Mar 9, 2026
c66f8d2
expose vutify namespace to templates
mariobuikhuizen Apr 21, 2026
5ac3ec4
fix dependecy issue with solara-test
mariobuikhuizen Apr 21, 2026
1f916a5
Don't create a new theme for each view
mariobuikhuizen Apr 23, 2026
ed3f353
chore: update package-lock after rebase
mariobuikhuizen May 8, 2026
6b2b517
chore: update docs
mariobuikhuizen May 13, 2026
64e613b
fix: make datatable available for solara
mariobuikhuizen May 14, 2026
a0751e2
ci: actually publish dev build on PR push
mariobuikhuizen May 14, 2026
41bd235
refactor: Override Vue component factory for Vuetify views
mariobuikhuizen May 18, 2026
d966521
feat: add support for custom theme colors
mariobuikhuizen May 29, 2026
697f0de
fix: export all lab components
mariobuikhuizen Jun 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ values =

[bumpversion:file:docs/conf.py]

[bumpversion:file:pyproject.toml]
[bumpversion:file:js/src/VuetifyWidget.js]
92 changes: 53 additions & 39 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ on:
pull_request:
workflow_dispatch:

env:
PKG_URL: https://nbg1.your-objectstorage.com/ipyvue3-packages/packages

permissions:
contents: read

jobs:
lint:
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
Expand All @@ -20,23 +26,20 @@ jobs:
- uses: pre-commit/action@v3.0.1

build:
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.10"
# https://github.com/webpack/webpack/issues/14532
- uses: actions/setup-node@v4
with:
node-version: 16
- name: install build
run: python -m pip install build

node-version: 18.x
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install "reacton[generate]" ipyvue
pip install "reacton[generate]" ipyvue "jupyterlab<4" build

- name: build wheel
run: python -m build

Expand All @@ -45,7 +48,6 @@ jobs:
cp ipyvuetify/components.py ipyvuetify/components-previous.py
python -m ipyvuetify.components
diff ipyvuetify/components.py ipyvuetify/components-previous.py

- name: Package js
run: (cd js && npm pack)
- name: Upload build artifacts
Expand All @@ -56,6 +58,27 @@ jobs:
./dist
./js/*.tgz

- name: Publish dev artifacts to object storage
if: >
github.event_name == 'pull_request' &&
github.event.pull_request.head.ref == 'vuetify3' &&
github.event.pull_request.head.repo.full_name == github.repository
env:
AWS_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
AWS_REGION: nbg1
AWS_ENDPOINT_URL_S3: https://nbg1.your-objectstorage.com
S3_BUCKET: ipyvue3-packages
run: |
python -m pip install --upgrade awscli

aws s3 cp dist/ "s3://${S3_BUCKET}/packages/ipyvuetify/" \
--recursive \
--exclude "*" \
--include "*.whl" \
--endpoint-url "$AWS_ENDPOINT_URL_S3" \
--region "$AWS_REGION"

- name: Upload components
uses: actions/upload-artifact@v4
with:
Expand All @@ -65,11 +88,11 @@ jobs:

test:
needs: [lint, build]
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
Expand All @@ -79,13 +102,14 @@ jobs:
with:
name: ipyvuetify-dist-${{ github.run_number }}
- name: Install ipyvuetify
run: python -m pip install "$(find dist -name *.whl)"
run: |
python -m pip install jupyter_core jupyter-packaging "jupyterlab<4" "$(find dist -name '*.whl')"
- name: test import
run: (mkdir test-install; cd test-install; python -c "from ipyvuetify import Btn")

ui-test:
needs: [lint, build]
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
Expand All @@ -95,11 +119,16 @@ jobs:
with:
name: ipyvuetify-dist-${{ github.run_number }}
- name: Install ipyvuetify
run: python -m pip install "$(find dist -name *.whl)[test]"
run: |
python -m pip install jupyter_core jupyter-packaging "jupyterlab<4" "$(find dist -name '*.whl')"
python -m pip install pytest "pytest-playwright<0.6"
python -m pip install "solara-ui[all] @ ${PKG_URL}/solara/solara_ui-1.57.3-py3-none-any.whl"
python -m pip install "starlette<1" "solara-server[starlette,dev] @ ${PKG_URL}/solara-server/solara_server-1.57.3-py3-none-any.whl"
python -m pip install "pytest-ipywidgets[all] @ ${PKG_URL}/pytest-ipywidgets/pytest_ipywidgets-1.57.3-py3-none-any.whl"
- name: Install chromium
run: playwright install chromium
- name: Run ui-tests
run: pytest tests/ui/ --video=retain-on-failure --solara-update-snapshots-ci -s
run: pytest tests/ui/ --video=retain-on-failure -s
- name: Upload Test artifacts
if: always()
uses: actions/upload-artifact@v4
Expand All @@ -108,9 +137,8 @@ jobs:
path: test-results

release-dry-run:
needs: [test, ui-test]
if: github.event.pull_request.head.repo.full_name == 'widgetti/ipyvuetify'
runs-on: ubuntu-24.04
needs: [test]
runs-on: ubuntu-22.04
steps:
- uses: actions/download-artifact@v4
with:
Expand All @@ -119,38 +147,24 @@ jobs:
- name: Install node
uses: actions/setup-node@v4
with:
node-version: 14
node-version: "18.x"
registry-url: "https://registry.npmjs.org"

- name: Install Python
uses: actions/setup-python@v5
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install twine

- name: Publish the Python package
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
run: twine upload --skip-existing --repository testpypi dist/*

# No --dry-run available for twine
# - name: Publish the Python package
- name: Publish the NPM package
run: |
cd js
echo $PRE_RELEASE
if [[ $PRE_RELEASE == "true" ]]; then export TAG="next"; else export TAG="latest"; fi
npm publish --dry-run --tag ${TAG} --access public *.tgz
npm publish --dry-run --tag ${TAG} --access public *.tgz
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
PRE_RELEASE: ${{ github.event.release.prerelease }}

release:
if: startsWith(github.event.ref, 'refs/tags/v')
needs: [test, ui-test]
runs-on: ubuntu-24.04
needs: [release-dry-run]
runs-on: ubuntu-22.04
steps:
- uses: actions/download-artifact@v4
with:
Expand All @@ -159,7 +173,7 @@ jobs:
- name: Install node
uses: actions/setup-node@v4
with:
node-version: 14
node-version: "18.x"
registry-url: "https://registry.npmjs.org"

- name: Install Python
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ dist/
build/

# generated code
generate_source/build
generate_source/vuetify
ipyvuetify/generated
js/src/generated
Expand Down
10 changes: 8 additions & 2 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ version: 2

# build with latest available ubuntu version
build:
os: ubuntu-20.04
os: ubuntu-22.04
tools:
python: "3.10"
nodejs: "16"
nodejs: "20"
jobs:
pre_install:
- cd js && npm ci --ignore-scripts
- cd js && npm run build:docs
- mkdir -p prefix/share/jupyter/nbextensions/jupyter-vuetify
- touch prefix/share/jupyter/nbextensions/jupyter-vuetify/index.js

# Build documentation in the docs/ directory with Sphinx
sphinx:
Expand Down
15 changes: 15 additions & 0 deletions docs/_static/jupyter-vuetify-embed-amd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const localVuetify = new URL("_static/jupyter-vuetify/index", document.baseURI)
.href;

require.config({
paths: {
"jupyter-vue":
"https://cdn.jsdelivr.net/npm/jupyter-vue@3.0.0-alpha.5/dist/index",
"jupyter-vuetify": localVuetify,
},
});

const script = document.createElement("script");
script.src =
"https://cdn.jsdelivr.net/npm/@jupyter-widgets/html-manager@^1.0.1/dist/embed-amd.js";
document.head.appendChild(script);
55 changes: 27 additions & 28 deletions docs/advanced_usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ Advanced Usage

Slots are used to add content at a certain location in a widget. You can find out what slots a widget supports by using
the Vuetify documentation. If you want to know what slots :code:`Select` has, search for :code:`v-select` on the
`Vuetify API explorer <https://v2.vuetifyjs.com/components/api-explorer/>`_ or for this example use the `direct link
<https://v2.vuetifyjs.com/en/components/selects/#api>`_. On the left-hand side of the list of attributes you will find a tab
'slots'.
`Vuetify API explorer <https://vuetifyjs.com/en/api/>`_ or for this example use the `direct link
<https://vuetifyjs.com/en/api/v-select/>`_. In the component API you will find the slots it supports.

An example for using the slot 'no-data', which changes what the Select widget shows when it has no items:

Expand Down Expand Up @@ -43,16 +42,16 @@ ipyvuetify:
v.ListItemTitle(children=['My custom no data message'])])]
}])

Scoped slots are used if the parent widget needs to share its scope with the content. In the example below the events
of the parent widget are used in the slot content.
Scoped slots are used if the parent widget needs to share its scope with the content. In the example below the activator
props of the parent widget are used in the slot content.

Vuetify:

.. code-block:: html

<v-tooltip>
<template v-slot:activator="tooltip">
<v-btn v-on="tooltip.on" color="primary">
<v-btn v-bind="tooltip.props" color="primary">
button with tooltip
</v-btn>
</template>
Expand All @@ -64,10 +63,10 @@ ipyvuetify:
.. jupyter-execute::

v.Container(children=[
v.Tooltip(bottom=True, v_slots=[{
v.Tooltip(location='bottom', v_slots=[{
'name': 'activator',
'variable': 'tooltip',
'children': v.Btn(v_on='tooltip.on', color='primary', children=[
'children': v.Btn(v_on='tooltip.props', color='primary', children=[
'button with tooltip'
]),
}], children=['Insert tooltip text here'])
Expand All @@ -78,8 +77,8 @@ In the Vuetify examples you will actually see:
.. code-block:: html

...
<template v-slot:activator="{ on }">
<v-btn v-on="on">
<template v-slot:activator="{ props }">
<v-btn v-bind="props">
...

Instead of the functionally equivalent (like used in the example above):
Expand All @@ -88,11 +87,11 @@ Instead of the functionally equivalent (like used in the example above):

...
<template v-slot:activator="tooltip">
<v-btn v-on="tooltip.on">
<v-btn v-bind="tooltip.props">
...

The :code:`{ on }` is JavaScript syntax for destructuring an object. It takes the 'on' attribute from an object and
exposes it as the 'on' variable.
The :code:`{ props }` is JavaScript syntax for destructuring an object. It takes the 'props' attribute from an object and
exposes it as the 'props' variable.

.. note::

Expand All @@ -102,7 +101,7 @@ Responsive Layout
-----------------

When making dashboards with Voilà you can change the layout depending on the user's screen size. This is done with a `grid
system <https://v2.vuetifyjs.com/en/components/grids/>`_. For example on a laptop (breakpoint md) you could fit two
system <https://vuetifyjs.com/en/components/grids/>`_. For example on a laptop (breakpoint md) you could fit two
elements next to each other while on a smartphone (defined with 'cols' as default) you would want one element to take up
the full width:

Expand All @@ -111,7 +110,7 @@ the full width:

v.Row(children=[
v.Col(cols=12, md=6, children=[
v.Card(outlined=True, style_='height: 400px', children=[f'Element {i}'])
v.Card(variant='outlined', style_='height: 400px', children=[f'Element {i}'])
]) for i in range (1,3)
])

Expand All @@ -125,20 +124,20 @@ On a phone as:
.. image:: images/responsive-mobile.png
:width: 263

In the `display section <https://v2.vuetifyjs.com/en/styles/display/>`_ you will find CSS helper classes to do more
In the `display section <https://vuetifyjs.com/en/styles/display/>`_ you will find CSS helper classes to do more
customizations based on screen size.

Event modifiers
---------------

In Vue `event modifiers <https://vuejs.org/v2/guide/events.html#Event-Modifiers>`_ can be used to change event behavior.
In Vue `event modifiers <https://vuejs.org/guide/essentials/event-handling.html#event-modifiers>`_ can be used to change event behavior.

For example when you have two nested elements and want a different click handler for the inner and outer element, the
``stop`` event modifier can be used by appending ``.stop`` to the event name:

.. jupyter-execute::

icon = v.Icon(right=True, children=['mdi-account-lock'])
icon = v.Icon(end=True, children=['mdi-account-lock'])
btn = v.Btn(color='primary', children=[
'button',
icon
Expand All @@ -153,12 +152,12 @@ For example when you have two nested elements and want a different click handler

# Note: the event handlers won't work in this page because there is no active kernel.

.sync
-----
v-model arguments
-----------------

When you see ``.sync`` appended to an attribute in Vuetify syntax, it means the attribute has a `two-way binding
<https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier>`_ (like ``v-model``). This is shorthand in Vue
that automatically listens to an event named ``update:<attributeNameInCamelCase>``.
When you see a ``v-model`` argument such as ``v-model:rail`` in Vuetify syntax, it means the attribute has a `two-way binding
<https://vuejs.org/guide/components/v-model.html#v-model-arguments>`_ (like the default ``v-model``). Vue
automatically listens to an event named ``update:<attributeNameInCamelCase>``.

We can achieve the same manually in ipyvuetify by setting an event handler
``<widget>.on_event('update:<attributeNameInCamelCase>', <function>)``
Expand All @@ -167,15 +166,15 @@ Vuetify:

.. code-block:: none

<v-navigation-drawer :mini-variant.sync="someProperty" ...
<v-navigation-drawer v-model:rail="someProperty" ...

ipyvuetify:

.. code-block:: none

drawer = v.NavigationDrawer(mini_variant=True, ...)
drawer = v.NavigationDrawer(rail=True, ...)

def update_mini(widget, event, data):
drawer.mini_variant = data
def update_rail(widget, event, data):
drawer.rail = data

drawer.on_event('update:miniVariant', update_mini)
drawer.on_event('update:rail', update_rail)
Loading
Loading