diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 88331fcb..3f1816d4 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -21,4 +21,4 @@ values =
[bumpversion:file:docs/conf.py]
-[bumpversion:file:pyproject.toml]
+[bumpversion:file:js/src/VuetifyWidget.js]
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ff9f1479..ac3be57f 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -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
@@ -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
@@ -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
@@ -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:
@@ -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
@@ -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
@@ -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
@@ -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:
@@ -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:
@@ -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
diff --git a/.gitignore b/.gitignore
index 1722c7d6..09450290 100755
--- a/.gitignore
+++ b/.gitignore
@@ -10,7 +10,6 @@ dist/
build/
# generated code
-generate_source/build
generate_source/vuetify
ipyvuetify/generated
js/src/generated
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index a661804e..cfb65d72 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -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:
diff --git a/docs/_static/jupyter-vuetify-embed-amd.js b/docs/_static/jupyter-vuetify-embed-amd.js
new file mode 100644
index 00000000..483fa471
--- /dev/null
+++ b/docs/_static/jupyter-vuetify-embed-amd.js
@@ -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);
diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst
index 6b6681ec..5a4d0ede 100644
--- a/docs/advanced_usage.rst
+++ b/docs/advanced_usage.rst
@@ -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 `_ or for this example use the `direct link
-`_. On the left-hand side of the list of attributes you will find a tab
-'slots'.
+`Vuetify API explorer `_ or for this example use the `direct link
+`_. 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:
@@ -43,8 +42,8 @@ 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:
@@ -52,7 +51,7 @@ Vuetify:
-
+
button with tooltip
@@ -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'])
@@ -78,8 +77,8 @@ In the Vuetify examples you will actually see:
.. code-block:: html
...
-
-
+
+
...
Instead of the functionally equivalent (like used in the example above):
@@ -88,11 +87,11 @@ Instead of the functionally equivalent (like used in the example above):
...
-
+
...
-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::
@@ -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 `_. For example on a laptop (breakpoint md) you could fit two
+system `_. 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:
@@ -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)
])
@@ -125,20 +124,20 @@ On a phone as:
.. image:: images/responsive-mobile.png
:width: 263
-In the `display section `_ you will find CSS helper classes to do more
+In the `display section `_ you will find CSS helper classes to do more
customizations based on screen size.
Event modifiers
---------------
-In Vue `event modifiers `_ can be used to change event behavior.
+In Vue `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
@@ -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
-`_ (like ``v-model``). This is shorthand in Vue
-that automatically listens to an event named ``update:``.
+When you see a ``v-model`` argument such as ``v-model:rail`` in Vuetify syntax, it means the attribute has a `two-way binding
+`_ (like the default ``v-model``). Vue
+automatically listens to an event named ``update:``.
We can achieve the same manually in ipyvuetify by setting an event handler
``.on_event('update:', )``
@@ -167,15 +166,15 @@ Vuetify:
.. code-block:: none
- {{ index }}