diff --git a/.gitignore b/.gitignore
index 1722c7d6..d0d8d593 100755
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ js/lib
# Sphinx documentation
docs/_build/
+docs/autoapi/
# Jupyter Notebook
.ipynb_checkpoints
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0207538a..3fc189f0 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,27 +1,32 @@
+default_install_hook_types: [pre-commit, commit-msg]
+
repos:
- repo: "https://github.com/psf/black"
rev: "22.3.0"
hooks:
- id: black
- stages: [commit]
+ stages: [pre-commit]
+
- repo: "https://github.com/commitizen-tools/commitizen"
rev: "v2.18.0"
hooks:
- id: commitizen
stages: [commit-msg]
+
- repo: "https://github.com/kynan/nbstripout"
rev: "0.5.0"
hooks:
- id: nbstripout
- stages: [commit]
+ stages: [pre-commit]
+
- repo: "https://github.com/pre-commit/mirrors-prettier"
rev: "v2.7.1"
hooks:
- id: prettier
- stages: [commit]
+ stages: [pre-commit]
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.0.213"
hooks:
- id: ruff
- stages: [commit]
+ stages: [pre-commit]
diff --git a/docs/_extension/aknowledgement.py b/docs/_extension/aknowledgement.py
new file mode 100644
index 00000000..162f89bf
--- /dev/null
+++ b/docs/_extension/aknowledgement.py
@@ -0,0 +1,103 @@
+"""A directive to generate an alert admonition."""
+from __future__ import annotations
+
+from typing import ClassVar
+
+from docutils import nodes
+from docutils.nodes import Node
+from sphinx import addnodes
+from sphinx.application import Sphinx
+from sphinx.util import logging
+from sphinx.util.docutils import SphinxDirective
+from sphinx.util.typing import OptionSpec
+from sphinx.writers.html5 import HTML5Translator
+
+logger = logging.getLogger(__name__)
+
+
+class alert_node(nodes.Admonition, nodes.Element):
+ pass
+
+
+def visit_aknowledgement_node(self: HTML5Translator, node: alert_node) -> None:
+ self.visit_admonition(node)
+
+
+def depart_aknowledgement_node(self: HTML5Translator, node: alert_node) -> None:
+ self.depart_admonition(node)
+
+
+class AknowledgementDirective(SphinxDirective):
+ """Directive to reference the original source of the documentation."""
+
+ has_content = True
+ required_arguments = 0
+ optional_arguments = 0
+ final_argument_whitespace = True
+ option_spec: ClassVar[OptionSpec] = {}
+
+ def run(self) -> list[Node]:
+ node = addnodes.versionmodified()
+ node.document = self.state.document
+ self.set_source_info(node)
+ node["type"] = "versionchanged"
+ node["version"] = ""
+ text = "Aknowledgement"
+ messages = []
+ if self.content:
+ node += self.parse_content_to_nodes()
+ classes = ["versionmodified", "changed"]
+ if len(node) > 0 and isinstance(node[0], nodes.paragraph):
+ # the contents start with a paragraph
+ if node[0].rawsource:
+ # make the first paragraph translatable
+ content = nodes.inline(node[0].rawsource, translatable=True)
+ content.source = node[0].source
+ content.line = node[0].line
+ content += node[0].children
+ node[0].replace_self(nodes.paragraph("", "", content, translatable=False))
+ para = node[0]
+ para.insert(0, nodes.inline("", "%s: " % text, classes=classes))
+ elif len(node) > 0:
+ # the contents do not starts with a paragraph
+ para = nodes.paragraph(
+ "",
+ "",
+ nodes.inline("", "%s: " % text, classes=classes),
+ translatable=False,
+ )
+ node.insert(0, para)
+ else:
+ # the contents are empty
+ para = nodes.paragraph(
+ "",
+ "",
+ nodes.inline("", "%s." % text, classes=classes),
+ translatable=False,
+ )
+ node.append(para)
+
+ domain = self.env.domains.changeset_domain
+ domain.note_changeset(node)
+
+ ret: list[Node] = [node]
+ ret += messages
+ return ret
+
+
+def setup(app: Sphinx) -> dict[str, object]:
+ """Add custom configuration to sphinx app.
+
+ Args:
+ app: the Sphinx application
+
+ Returns:
+ the 2 parallel parameters set to ``True``.
+ """
+ app.add_directive("aknowledgement", AknowledgementDirective)
+ app.add_node(alert_node, html=(visit_aknowledgement_node, depart_aknowledgement_node))
+
+ return {
+ "parallel_read_safe": True,
+ "parallel_write_safe": True,
+ }
diff --git a/docs/_extension/api_admonition.py b/docs/_extension/api_admonition.py
new file mode 100644
index 00000000..7e096053
--- /dev/null
+++ b/docs/_extension/api_admonition.py
@@ -0,0 +1,73 @@
+"""A directive to generate an API admonition."""
+from __future__ import annotations
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from docutils.parsers.rst.directives.admonitions import BaseAdmonition
+from sphinx.application import Sphinx
+from sphinx.util import logging
+from sphinx.util.docutils import SphinxDirective
+from sphinx.writers.html5 import HTML5Translator
+
+logger = logging.getLogger(__name__)
+
+
+class api_node(nodes.Admonition, nodes.Element):
+ pass
+
+
+def visit_api_node(self: HTML5Translator, node: api_node) -> None:
+ self.visit_admonition(node)
+
+
+def depart_api_node(self: HTML5Translator, node: api_node) -> None:
+ self.depart_admonition(node)
+
+
+class APIAdmonitionDirective(BaseAdmonition, SphinxDirective):
+ """An API entry, displayed (if configured) in the form of an admonition."""
+
+ node_class = api_node
+ has_content = True
+ required_arguments = 0
+ optional_arguments = 0
+ final_argument_whitespace = False
+ option_spec = {
+ "class": directives.class_option,
+ "name": directives.unchanged,
+ }
+
+ def run(self) -> list[nodes.Node]:
+ if not self.options.get("class"):
+ self.options["class"] = ["admonition-api"]
+
+ (api,) = super().run()
+ if isinstance(api, nodes.system_message):
+ return [api]
+ elif isinstance(api, api_node):
+ api.insert(0, nodes.title(text="See API"))
+ api["docname"] = self.env.docname
+ self.add_name(api)
+ self.set_source_info(api)
+ self.state.document.note_explicit_target(api)
+ return [api]
+ else:
+ raise RuntimeError # never reached here
+
+
+def setup(app: Sphinx) -> dict[str, object]:
+ """Add custom configuration to sphinx app.
+
+ Args:
+ app: the Sphinx application
+
+ Returns:
+ the 2 parallel parameters set to ``True``.
+ """
+ app.add_directive("api", APIAdmonitionDirective)
+ app.add_node(api_node, html=(visit_api_node, depart_api_node))
+
+ return {
+ "parallel_read_safe": True,
+ "parallel_write_safe": True,
+ }
diff --git a/docs/_static/banner.html b/docs/_static/banner.html
new file mode 100644
index 00000000..ddb197ec
--- /dev/null
+++ b/docs/_static/banner.html
@@ -0,0 +1,6 @@
+
diff --git a/docs/_static/custom.css b/docs/_static/custom.css
index 8744437f..5bbc1543 100644
--- a/docs/_static/custom.css
+++ b/docs/_static/custom.css
@@ -38,3 +38,65 @@ html[data-theme="light"] {
html[data-theme="dark"] {
--pst-color-primary: #1697f6;
}
+
+/*******************************************************************************
+* Create a custom api admonition
+*/
+div.admonition.admonition-api > .admonition-title::after {
+ content: "\f121"; /* the fa-code icon */
+}
+
+/*******************************************************************************
+* Customize the font used by the title to make it look like the original lib
+*/
+.title.logo__title {
+ font-family: "Exo", sans-serif;
+ font-optical-sizing: auto;
+ font-weight: 700;
+ font-style: normal;
+}
+
+/*******************************************************************************
+* custom article footer rendering
+*/
+footer.bd-footer-article {
+ background-color: transparent;
+ border-top: 1px solid var(--pst-color-border);
+ margin-top: 2em;
+}
+
+.bd-footer-article .footer-article-items {
+ flex-direction: row;
+}
+
+.bd-footer-article .footer-article-items .footer-article-item {
+ flex-grow: 1;
+}
+
+.bd-footer-article .last-updated {
+ color: var(--pst-color-text-muted);
+ text-align: right;
+}
+
+/*******************************************************************************
+* add dollar sign in console code-block
+*/
+div.highlight-console pre span.go::before {
+ content: "$";
+ margin-right: 10px;
+ margin-left: 5px;
+}
+
+/*******************************************************************************
+* custom loader animation
+*/
+@keyframes spin {
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+.custom-loader {
+ display: flex;
+ animation: spin 1s linear infinite;
+}
diff --git a/docs/_static/logo.png b/docs/_static/logo.png
new file mode 100644
index 00000000..717b3d4c
Binary files /dev/null and b/docs/_static/logo.png differ
diff --git a/docs/_templates/python/class.rst b/docs/_templates/python/class.rst
new file mode 100644
index 00000000..77963fbc
--- /dev/null
+++ b/docs/_templates/python/class.rst
@@ -0,0 +1,106 @@
+{% if obj.display %}
+ {% if is_own_page %}
+:html_theme.sidebar_secondary.remove:
+
+{{ obj.id.split(".")[-1] }}
+{{ "=" * obj.id.split(".")[-1] | length }}
+
+ {% endif %}
+ {% set visible_children = obj.children|selectattr("display")|list %}
+ {% set own_page_children = visible_children|selectattr("type", "in", own_page_types)|list %}
+ {% if is_own_page and own_page_children %}
+.. toctree::
+ :hidden:
+
+ {% for child in own_page_children %}
+ {{ child.include_path }}
+ {% endfor %}
+
+ {% endif %}
+.. py:{{ obj.type }}:: {% if is_own_page %}{{ obj.id }}{% else %}{{ obj.short_name }}{% endif %}{% if obj.args %}({{ obj.args }}){% endif %}
+
+ {% for (args, return_annotation) in obj.overloads %}
+ {{ " " * (obj.type | length) }} {{ obj.short_name }}{% if args %}({{ args }}){% endif %}
+
+ {% endfor %}
+ {% if obj.bases %}
+ {% if "show-inheritance" in autoapi_options %}
+
+ Bases: {% for base in obj.bases %}{{ base|link_objs }}{% if not loop.last %}, {% endif %}{% endfor %}
+ {% endif %}
+
+
+ {% if "show-inheritance-diagram" in autoapi_options and obj.bases != ["object"] %}
+ .. autoapi-inheritance-diagram:: {{ obj.obj["full_name"] }}
+ :parts: 1
+ {% if "private-members" in autoapi_options %}
+ :private-bases:
+ {% endif %}
+
+ {% endif %}
+ {% endif %}
+ {% if obj.docstring %}
+
+ {{ obj.docstring|indent(3) }}
+ {% endif %}
+ {% for obj_item in visible_children %}
+ {% if obj_item.type not in own_page_types %}
+
+ {{ obj_item.render()|indent(3) }}
+ {% endif %}
+ {% endfor %}
+ {% if is_own_page and own_page_children %}
+ {% set visible_attributes = own_page_children|selectattr("type", "in", ("attribute", "property"))|list %}
+ {% if visible_attributes %}
+Attributes
+----------
+
+.. autoapisummary::
+
+ {% for attribute in visible_attributes %}
+ {{ attribute.id }}
+ {% endfor %}
+
+
+ {% endif %}
+ {% set visible_exceptions = own_page_children|selectattr("type", "equalto", "exception")|list %}
+ {% if visible_exceptions %}
+Exceptions
+----------
+
+.. autoapisummary::
+
+ {% for exception in visible_exceptions %}
+ {{ exception.id }}
+ {% endfor %}
+
+
+ {% endif %}
+ {% set visible_classes = own_page_children|selectattr("type", "equalto", "class")|list %}
+ {% if visible_classes %}
+Classes
+-------
+
+.. autoapisummary::
+
+ {% for klass in visible_classes %}
+ {{ klass.id }}
+ {% endfor %}
+
+
+ {% endif %}
+ {% set visible_methods = own_page_children|selectattr("type", "equalto", "method")|list %}
+ {% if visible_methods %}
+Methods
+-------
+
+.. autoapisummary::
+
+ {% for method in visible_methods %}
+ {{ method.id }}
+ {% endfor %}
+
+
+ {% endif %}
+ {% endif %}
+{% endif %}
\ No newline at end of file
diff --git a/docs/advanced_usage.rst b/docs/advanced_usage.rst
deleted file mode 100644
index 890fcfa2..00000000
--- a/docs/advanced_usage.rst
+++ /dev/null
@@ -1,181 +0,0 @@
-Advanced Usage
-==============
-
-(Scoped) Slots
---------------
-
-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 list of attributes you will find a tab
-'slots'.
-
-An example for using the slot 'no-data', which changes what the Select widget shows when it has no items:
-
-Vuetify:
-
-.. code-block:: html
-
-
-
-
-
- My custom no data message
-
-
-
-
-
-ipyvuetify:
-
-.. jupyter-execute::
- :hide-output:
- :hide-code:
-
- import ipyvuetify as v
-
-.. jupyter-execute::
-
- v.Select(v_slots=[{
- 'name': 'no-data',
- 'children': [
- v.ListItem(children=[
- 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.
-
-Vuetify:
-
-.. code-block:: html
-
-
-
-
- button with tooltip
-
-
- Insert tooltip text here
-
-
-ipyvuetify:
-
-.. jupyter-execute::
-
- v.Container(children=[
- v.Tooltip(bottom=True, v_slots=[{
- 'name': 'activator',
- 'variable': 'tooltip',
- 'children': v.Btn(v_on='tooltip.on', color='primary', children=[
- 'button with tooltip'
- ]),
- }], children=['Insert tooltip text here'])
- ])
-
-In the Vuetify examples you will actually see:
-
-.. code-block:: html
-
- ...
-
-
- ...
-
-Instead of the functionally equivalent (like used in the example above):
-
-.. code-block:: html
-
- ...
-
-
- ...
-
-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.
-
-.. note::
-
- The 'default' slot can be ignored, this is where the content defined in the :code:`children` attribute goes.
-
-Responsive Layout
------------------
-
-When making dashbords with Voilà you can change the layout depending on the users screen size. This is done with a `grid
-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:
-
-.. jupyter-execute::
- :hide-output:
-
- v.Row(children=[
- v.Col(cols=12, md=6, children=[
- v.Card(outlined=True, style_='height: 400px', children=[f'Element {i}'])
- ]) for i in range (1,3)
- ])
-
-Which displays on a laptop as:
-
-.. image:: images/responsive-laptop.png
- :width: 680
-
-On a phone as:
-
-.. image:: images/responsive-mobile.png
- :width: 263
-
-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.
-
-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'])
- btn = v.Btn(color='primary', children=[
- 'button',
- icon
- ])
-
- icon.on_event('click.stop', lambda *args: print('icon clicked'))
- btn.on_event('click', lambda *args: print('btn clicked'))
-
- v.Container(children=[
- btn
- ])
-
- # Note: the event handlers won't work in this page because there is no active kernel.
-
-.sync
------
-
-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:``.
-
-We can achieve the same manually in ipyvuetify by setting an event handler
-``.on_event('update:', )``
-
-Vuetify:
-
-.. code-block:: none
-
- `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Alert ` component is used to convey important information to the user
+through the use of contextual types, icons, and colors. These default types come in 4 variations:
+``success``, ``info``, ``warning``, and ``error``. Default icons are assigned which help represent
+different actions each type portrays. Many parts of an alert such as ``border``, ``icon``, and ``color``
+can also be customized to fit almost any situation.
+
+.. api::
+
+ :py:class:`ipyvuetify.Alert`
+
+Usage
+-----
+
+Alerts in their simplest form are flat sheets of paper that display a message.
+
+.. jupyter-execute:: Alert/usage.py
+ :raises:
+
+Border
+------
+
+The ``border`` prop adds a simple border to one of the 4 sides of the alert. This can be combined with
+props like ``color``, ``dark``, and ``type`` to provide unique accents to the alert.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/border.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/border.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/border.vue
+
+Colored Border
+--------------
+
+The ``colored-border`` prop removes the alert background in order to accent the ``border`` prop.
+If a ``type`` is set, it will use the type's default color. If no color or type is set, the color
+will default to the inverted color of the applied theme (black for light and white/gray for dark).
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/colored_border.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/colored_border.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/colored_border.vue
+
+Dense
+-----
+
+The ``dense`` prop decreases the height of the alert to create a simple and compact style.
+When combined with the ``border`` prop, the border thickness will be decreased to stay consistent
+with the style.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/dense.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/dense.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/dense.vue
+
+Dismissible
+-----------
+
+The ``dismissible`` prop adds a close button to the end of the alert component. Clicking this
+button will set its value to false and effectively hide the alert. You can restore the alert by
+binding ``v_model`` and setting it to true. The close icon automatically has an ``aria-label``
+applied that can be changed by modifying the ``close_label`` prop or changing close value in your
+locale.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/dismissible.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/dismissible.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/dismissible.vue
+
+Icon
+----
+
+The ``icon`` prop allows you to add an icon to the beginning of the alert component. If a ``type`` is
+provided, this will override the default type icon. Additionally, setting the ``icon`` prop to false
+will remove the icon altogether.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/icon.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/icon.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/icon.vue
+
+Outlined
+--------
+
+The ``outlined`` prop inverts the style of an alert, inheriting the currently applied color, applying
+it to the text and border, and making its background transparent.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/outlined.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/outlined.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/outlined.vue
+
+Prominent
+---------
+
+The ``prominent`` prop provides a more pronounced alert by increasing the height and applying a halo
+to the icon. When applying both ``prominent`` and ``dense`` together, the alert will take on the
+appearance of a normal alert but with the prominent icon effects.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/prominent.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/prominent.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/prominent.vue
+
+Text
+----
+
+The ``text`` prop is a simple alert variant that applies a reduced opacity background of the provided
+color. Similar to other styled props, ``text`` can be combined with other props like ``dense``,
+``prominent``, ``outlined``, and ``shaped`` to create a unique and customized component.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/text.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/text.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/text.vue
+
+Transition
+----------
+
+The ``transition`` prop allows you to apply a transition to the alert which is viewable when the
+component hides and shows.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/transition.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/transition.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/transition.vue
+
+Type
+----
+
+The ``type`` prop provides 4 default :py:class:`Alert ` styles: success, info, warning, and error. Each of
+these styles provides a default icon and color. The default colors can be configured globally by
+customizing Vuetify's theme.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/type.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/type.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/type.vue
+
+Twitter Example
+---------------
+
+By combining ``color``, ``dismissible``, ``border``, ``elevation``, ``icon``, and ``colored_border``
+props, you can create stylish custom alerts such as this Twitter notification.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Alert/twitter_example.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Alert/twitter_example.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Alert/twitter_example.vue
+
+Accessibility
+-------------
+
+By default, :py:class:`Alert ` components are assigned the WAI-ARIA role of alert
+which denotes that the alert "is a live region with important and usually time-sensitive information."
+When using the ``dismissible`` prop, the close icon will receive a corresponding ``aria-label``.
+This value can be modified by changing either the ``close-label`` prop or globally through customizing
+the Internationalization's default value for the close property.
diff --git a/docs/component/Alert/border.py b/docs/component/Alert/border.py
new file mode 100644
index 00000000..c7a35db5
--- /dev/null
+++ b/docs/component/Alert/border.py
@@ -0,0 +1,30 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Alert(
+ border="top",
+ color="red lighten-2",
+ dark=True,
+ children=["I'm an alert with a top border and red color"],
+ ),
+ v.Alert(
+ border="right",
+ color="blue-grey",
+ dark=True,
+ children=["I'm an alert with a right border and blue-grey color"],
+ ),
+ v.Alert(
+ border="bottom",
+ color="pink darken-1",
+ dark=True,
+ children=["I'm an alert with a bottom border and pink color"],
+ ),
+ v.Alert(
+ border="left",
+ color="indigo",
+ dark=True,
+ children=["I'm an alert with a border left type info"],
+ ),
+ ]
+)
diff --git a/docs/component/Alert/border.vue b/docs/component/Alert/border.vue
new file mode 100644
index 00000000..a35b5db0
--- /dev/null
+++ b/docs/component/Alert/border.vue
@@ -0,0 +1,16 @@
+
+
+
+ I'm an alert with a top border and red color
+
+
+ I'm an alert with a right border and blue-grey color
+
+
+ I'm an alert with a bottom border and pink color
+
+
+ I'm an alert with a border left type info
+
+
+
diff --git a/docs/component/Alert/colored_border.py b/docs/component/Alert/colored_border.py
new file mode 100644
index 00000000..e9c329c7
--- /dev/null
+++ b/docs/component/Alert/colored_border.py
@@ -0,0 +1,52 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Alert(
+ border="left",
+ colored_border=True,
+ color="deep-purple accent-4",
+ elevation=2,
+ children=[
+ "Aliquam eu nunc. Fusce commodo aliquam arcu. In consectetuer turpis ut velit. "
+ "Nulla facilisi.. Morbi mollis tellus ac sapien. Fusce vel dui. Praesent ut ligula "
+ "non mi varius sagittis. Vivamus consectetuer hendrerit lacus. Suspendisse enim "
+ "turpis, dictum sed, iaculis a, condimentum nec, nisi."
+ ],
+ ),
+ v.Alert(
+ border="top",
+ colored_border=True,
+ type="info",
+ elevation=2,
+ children=[
+ "Vestibulum ullamcorper mauris at ligula. Nam pretium turpis et arcu. Ut varius "
+ "tincidunt libero. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere "
+ "imperdiet, leo. Morbi nec metus."
+ ],
+ ),
+ v.Alert(
+ border="bottom",
+ colored_border=True,
+ type="warning",
+ elevation=2,
+ children=[
+ "Sed in libero ut nibh placerat accumsan. Phasellus leo dolor, tempus non, auctor "
+ "et, hendrerit quis, nisi. Phasellus leo dolor, tempus non, auctor et, hendrerit "
+ "quis, nisi. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc, "
+ "quis gravida magna mi a libero. Donec elit libero, sodales nec, volutpat a, "
+ "suscipit non, turpis."
+ ],
+ ),
+ v.Alert(
+ border="right",
+ colored_border=True,
+ type="error",
+ elevation=2,
+ children=[
+ "Fusce commodo aliquam arcu. Pellentesque posuere. Phasellus tempus. Donec "
+ "posuere vulputate arcu."
+ ],
+ ),
+ ]
+)
diff --git a/docs/component/Alert/colored_border.vue b/docs/component/Alert/colored_border.vue
new file mode 100644
index 00000000..26ce5bae
--- /dev/null
+++ b/docs/component/Alert/colored_border.vue
@@ -0,0 +1,21 @@
+
+
+
+ Aliquam eu nunc. Fusce commodo aliquam arcu...
+
+
+ Vestibulum ullamcorper mauris at ligula...
+
+
+ Sed in libero ut nibh placerat accumsan...
+
+
+ Fusce commodo aliquam arcu...
+
+
+
diff --git a/docs/component/Alert/dense.py b/docs/component/Alert/dense.py
new file mode 100644
index 00000000..7819f2e1
--- /dev/null
+++ b/docs/component/Alert/dense.py
@@ -0,0 +1,25 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Alert(dense=True, type="info", children=["I'm a dense alert with a type of info"]),
+ v.Alert(
+ dense=True,
+ text=True,
+ type="success",
+ children=["I'm a dense alert with the text prop and a type of success"],
+ ),
+ v.Alert(
+ dense=True,
+ border="left",
+ type="warning",
+ children=["I'm a dense alert with the border prop and a type of warning"],
+ ),
+ v.Alert(
+ dense=True,
+ outlined=True,
+ type="error",
+ children=["I'm a dense alert with the outlined prop and a type of error"],
+ ),
+ ]
+)
diff --git a/docs/component/Alert/dense.vue b/docs/component/Alert/dense.vue
new file mode 100644
index 00000000..ccf0edf7
--- /dev/null
+++ b/docs/component/Alert/dense.vue
@@ -0,0 +1,14 @@
+
+
+ I'm a dense alert with a type of info
+
+ I'm a dense alert with the text prop and a type of success
+
+
+ I'm a dense alert with the border prop and a type of warning
+
+
+ I'm a dense alert with the outlined prop and a type of error
+
+
+
diff --git a/docs/component/Alert/dismissible.py b/docs/component/Alert/dismissible.py
new file mode 100644
index 00000000..276805fe
--- /dev/null
+++ b/docs/component/Alert/dismissible.py
@@ -0,0 +1,20 @@
+import ipyvuetify as v
+
+alert = v.Alert(
+ v_model=True,
+ border="left",
+ close_text="Close Alert",
+ color="deep-purple accent-4",
+ dark=True,
+ dismissible=True,
+ children=[
+ "Aenean imperdiet. Quisque id odio. Cras dapibus. Pellentesque ut neque. Cras "
+ "dapibus. Vivamus consectetuer hendrerit lacus. Sed mollis, eros et ultrices "
+ "tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. Sed "
+ "mollis, eros et ultrices tempus, mauris ipsum aliquam libero, non adipiscing "
+ "dolor urna a orci. Curabitur blandit mollis lacus. Curabitur ligula sapien, "
+ "tincidunt non, euismod vitae, posuere imperdiet, leo."
+ ],
+)
+
+v.Container(children=[alert])
diff --git a/docs/component/Alert/dismissible.vue b/docs/component/Alert/dismissible.vue
new file mode 100644
index 00000000..b46a5b11
--- /dev/null
+++ b/docs/component/Alert/dismissible.vue
@@ -0,0 +1,14 @@
+
+
+
+ Aenean imperdiet. Quisque id odio...
+
+
+
diff --git a/docs/component/Alert/icon.py b/docs/component/Alert/icon.py
new file mode 100644
index 00000000..ae353d9c
--- /dev/null
+++ b/docs/component/Alert/icon.py
@@ -0,0 +1,40 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Alert(
+ color="#2A3B4D",
+ dark=True,
+ icon="mdi-firework",
+ dense=True,
+ children=[
+ "Suspendisse enim turpis, dictum sed, iaculis a, condimentum nec, nisi. "
+ "Vivamus quis mi. Quisque ut nisi. Maecenas malesuada."
+ ],
+ ),
+ v.Alert(
+ color="#C51162",
+ dark=True,
+ icon="mdi-material-design",
+ border="right",
+ children=[
+ "Phasellus blandit leo ut odio. Morbi mattis ullamcorper velit. Donec orci "
+ "lectus, aliquam ut, faucibus non, euismod id, nulla. In ut quam vitae odio "
+ "lacinia tincidunt."
+ ],
+ ),
+ v.Alert(
+ color="primary",
+ dark=True,
+ icon="mdi-vuetify",
+ border="left",
+ prominent=True,
+ children=[
+ "Praesent congue erat at massa. Nullam vel sem. Aliquam lorem ante, dapibus "
+ "in, viverra quis, feugiat a, tellus. Proin viverra, ligula sit amet ultrices "
+ "semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. "
+ "Curabitur at lacus ac velit ornare lobortis."
+ ],
+ ),
+ ]
+)
diff --git a/docs/component/Alert/icon.vue b/docs/component/Alert/icon.vue
new file mode 100644
index 00000000..24e0414a
--- /dev/null
+++ b/docs/component/Alert/icon.vue
@@ -0,0 +1,10 @@
+
+
+
+ Suspendisse enim turpis...
+
+
+ Phasellus blandit leo ut odio...
+
+
+
diff --git a/docs/component/Alert/outlined.py b/docs/component/Alert/outlined.py
new file mode 100644
index 00000000..c1e9fa44
--- /dev/null
+++ b/docs/component/Alert/outlined.py
@@ -0,0 +1,42 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Alert(
+ outlined=True,
+ color="purple",
+ children=[
+ v.Html(tag="h5", class_="mt-1", children=["Lorem Ipsum"]),
+ (
+ "Maecenas ullamcorper, dui et placerat feugiat, eros pede varius nisi, "
+ "condimentum viverra felis nunc et lorem. Duis vel nibh at velit scelerisque "
+ "suscipit. Praesent blandit laoreet nibh. Aenean posuere, tortor sed cursus "
+ "feugiat, nunc augue blandit nunc, eu sollicitudin urna dolor sagittis lacus. "
+ "Etiam sollicitudin, ipsum eu pulvinar rutrum, tellus ipsum laoreet sapien, "
+ "quis venenatis ante odio sit amet eros."
+ ),
+ ],
+ ),
+ v.Alert(
+ outlined=True,
+ type="success",
+ text=True,
+ children=[
+ "Praesent venenatis metus at tortor pulvinar varius. Aenean commodo ligula eget "
+ "dolor. Praesent ac massa at ligula laoreet iaculis. Vestibulum ullamcorper mauris "
+ "at ligula."
+ ],
+ ),
+ v.Alert(
+ outlined=True,
+ type="warning",
+ prominent=True,
+ border="left",
+ children=[
+ "Duis arcu tortor, suscipit eget, imperdiet nec, imperdiet iaculis, ipsum. "
+ "Suspendisse non nisl sit amet velit hendrerit rutrum. Nullam vel sem. "
+ "Pellentesque dapibus hendrerit tortor."
+ ],
+ ),
+ ]
+)
diff --git a/docs/component/Alert/outlined.vue b/docs/component/Alert/outlined.vue
new file mode 100644
index 00000000..9463ee5a
--- /dev/null
+++ b/docs/component/Alert/outlined.vue
@@ -0,0 +1,11 @@
+
+
+
+ Lorem Ipsum
+ Maecenas ullamcorper...
+
+
+ Praesent venenatis metus...
+
+
+
diff --git a/docs/component/Alert/prominent.py b/docs/component/Alert/prominent.py
new file mode 100644
index 00000000..485945f7
--- /dev/null
+++ b/docs/component/Alert/prominent.py
@@ -0,0 +1,40 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Alert(
+ prominent=True,
+ type="error",
+ children=[
+ v.Row(
+ align="center",
+ children=[
+ v.Col(
+ class_="grow",
+ children=[
+ "Nunc nonummy metus. Nunc interdum lacus sit amet orci. Nullam dictum felis "
+ "eu pede mollis pretium. Cras id dui."
+ ],
+ ),
+ v.Col(class_="shrink", children=[v.Btn(children=["Take action"])]),
+ ],
+ )
+ ],
+ ),
+ v.Alert(
+ color="blue-grey",
+ dark=True,
+ dense=True,
+ icon="mdi-school",
+ prominent=True,
+ children=["Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui."],
+ ),
+ v.Alert(
+ icon="mdi-shield-lock-outline",
+ prominent=True,
+ text=True,
+ type="info",
+ children=["Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem."],
+ ),
+ ]
+)
diff --git a/docs/component/Alert/prominent.vue b/docs/component/Alert/prominent.vue
new file mode 100644
index 00000000..134f7478
--- /dev/null
+++ b/docs/component/Alert/prominent.vue
@@ -0,0 +1,12 @@
+
+
+
+
+ Nunc nonummy metus...
+
+ Take action
+
+
+
+
+
diff --git a/docs/component/Alert/text.py b/docs/component/Alert/text.py
new file mode 100644
index 00000000..a32f6f9e
--- /dev/null
+++ b/docs/component/Alert/text.py
@@ -0,0 +1,74 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Alert(
+ text=True,
+ color="info",
+ children=[
+ v.Html(tag="h5", class_="mt-1", children=["Lorem Ipsum"]),
+ v.Html(
+ tag="div",
+ children=[
+ "Maecenas nec odio et ante tincidunt tempus. Sed mollis, eros et ultrices "
+ "tempus, mauris ipsum aliquam libero, non adipiscing dolor urna a orci. "
+ "Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique "
+ "sapien, a accumsan nisi mauris ac eros. Curabitur turpis."
+ ],
+ ),
+ v.Divider(class_="my-4 info", style_="opacity: 0.22"),
+ v.Row(
+ align="center",
+ no_gutters=True,
+ children=[
+ v.Col(
+ class_="grow",
+ children=[
+ "Proin magna. Vivamus in erat ut urna cursus vestibulum. Etiam "
+ "imperdiet imperdiet orci."
+ ],
+ ),
+ v.Spacer(),
+ v.Col(
+ class_="shrink",
+ children=[v.Btn(color="info", outlined=True, children=["Okay"])],
+ ),
+ ],
+ ),
+ ],
+ ),
+ v.Alert(
+ text=True,
+ outlined=True,
+ color="deep-orange",
+ icon="mdi-fire",
+ children=[
+ "Nullam tincidunt adipiscing enim. In consectetuer turpis ut velit. "
+ "Maecenas egestas arcu quis ligula mattis placerat. Praesent metus tellus, "
+ "elementum eu, semper a, adipiscing nec, purus."
+ ],
+ ),
+ v.Alert(
+ text=True,
+ dense=True,
+ color="teal",
+ icon="mdi-clock-fast",
+ border="left",
+ children=[
+ "Vestibulum ullamcorper mauris at ligula. Nulla porta dolor. Vestibulum facilisis, "
+ "purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna "
+ "in dolor. Curabitur at lacus ac velit ornare lobortis."
+ ],
+ ),
+ v.Alert(
+ text=True,
+ prominent=True,
+ type="error",
+ icon="mdi-cloud-alert",
+ children=[
+ "Praesent blandit laoreet nibh. Praesent nonummy mi in odio. Phasellus tempus. "
+ "Mauris turpis nunc, blandit et, volutpat molestie, porta ut, ligula. Duis leo."
+ ],
+ ),
+ ]
+)
diff --git a/docs/component/Alert/text.vue b/docs/component/Alert/text.vue
new file mode 100644
index 00000000..e3067e50
--- /dev/null
+++ b/docs/component/Alert/text.vue
@@ -0,0 +1,27 @@
+
+
+
+ Lorem Ipsum
+ Maecenas nec odio et ante tincidunt tempus...
+
+
+
+
+ Proin magna...
+
+
+ Okay
+
+
+
+
+ Nullam tincidunt adipiscing enim...
+
+
+ Vestibulum ullamcorper mauris at ligula...
+
+
+ Praesent blandit laoreet nibh...
+
+
+
diff --git a/docs/component/Alert/transition.py b/docs/component/Alert/transition.py
new file mode 100644
index 00000000..762f7f03
--- /dev/null
+++ b/docs/component/Alert/transition.py
@@ -0,0 +1,22 @@
+import ipyvuetify as v
+
+alert = v.Alert(
+ value=True,
+ color="pink",
+ dark=True,
+ border="top",
+ icon="mdi-home",
+ transition="scale-transition",
+ children=[
+ "Phasellus tempus. Fusce ac felis sit amet ligula pharetra condimentum. In dui magna, "
+ "posuere eget, vestibulum et, tempor auctor, justo. Pellentesque posuere. Curabitur "
+ "ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Phasellus nec "
+ "sem in justo pellentesque facilisis. Phasellus magna. Cras risus ipsum, faucibus ut, "
+ "ullamcorper id, varius ac, leo. In hac habitasse platea dictumst. Praesent turpis."
+ ],
+)
+
+btn = v.Btn(color="primary", children=["Toggle"])
+btn.on_event("click", lambda w, e, d: setattr(alert, "value", not alert.value))
+
+v.Container(children=[btn, alert])
diff --git a/docs/component/Alert/transition.vue b/docs/component/Alert/transition.vue
new file mode 100644
index 00000000..75707fa0
--- /dev/null
+++ b/docs/component/Alert/transition.vue
@@ -0,0 +1,15 @@
+
+
+ Toggle
+
+ Phasellus tempus...
+
+
+
diff --git a/docs/component/Alert/twitter_example.py b/docs/component/Alert/twitter_example.py
new file mode 100644
index 00000000..6a41f3db
--- /dev/null
+++ b/docs/component/Alert/twitter_example.py
@@ -0,0 +1,14 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Alert(
+ color="#26c6da",
+ border="left",
+ elevation=2,
+ colored_border=True,
+ icon="mdi-twitter",
+ children=["You've got 5 new updates on your timeline!"],
+ ),
+ ]
+)
diff --git a/docs/component/Alert/twitter_example.vue b/docs/component/Alert/twitter_example.vue
new file mode 100644
index 00000000..0e093ba4
--- /dev/null
+++ b/docs/component/Alert/twitter_example.vue
@@ -0,0 +1,13 @@
+
+
+
+ You've got 5 new updates on your timeline!
+
+
+
diff --git a/docs/component/Alert/type.py b/docs/component/Alert/type.py
new file mode 100644
index 00000000..bfc1725b
--- /dev/null
+++ b/docs/component/Alert/type.py
@@ -0,0 +1,10 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Alert(type="success", children=["I'm a success alert."]),
+ v.Alert(type="info", children=["I'm an info alert."]),
+ v.Alert(type="warning", children=["I'm a warning alert."]),
+ v.Alert(type="error", children=["I'm an error alert."]),
+ ]
+)
diff --git a/docs/component/Alert/type.vue b/docs/component/Alert/type.vue
new file mode 100644
index 00000000..1991bf30
--- /dev/null
+++ b/docs/component/Alert/type.vue
@@ -0,0 +1,8 @@
+
+
+ I'm a success alert.
+ I'm an info alert.
+ I'm a warning alert.
+ I'm an error alert.
+
+
diff --git a/docs/component/Alert/usage.py b/docs/component/Alert/usage.py
new file mode 100644
index 00000000..f5dd6ff6
--- /dev/null
+++ b/docs/component/Alert/usage.py
@@ -0,0 +1,8 @@
+import ipyvuetify as v
+
+alert = v.Alert(
+ children=["I'm an Alert Usage Example"],
+ type="success",
+)
+
+v.Container(children=[alert])
diff --git a/docs/component/App.rst b/docs/component/App.rst
new file mode 100644
index 00000000..60fb5d2a
--- /dev/null
+++ b/docs/component/App.rst
@@ -0,0 +1,115 @@
+App
+===
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+In Vuetify, the :py:class:`App ` component and the ``app`` prop on components like
+:py:class:`NavigationDrawer `, :py:class:`AppBar `,
+:py:class:`Footer ` and more, help bootstrap your application with the proper sizing
+around :py:class:`Main ` component. This allows you to create truly unique interfaces
+without the hassle of managing your layout sizing. The :py:class:`App ` component is
+**REQUIRED** for all applications. This is the mount point for many of Vuetify's components and
+functionality and ensures that it propagates the default application variant (dark/light) to children
+components and also ensures proper cross-browser support for certain click events in browsers like
+Safari. :py:class:`App ` should only be rendered within your application **ONCE**.
+
+.. api::
+
+ :py:class:`ipyvuetify.App`
+
+Default application markup
+---------------------------
+
+This is an example of the default application markup for Vuetify. You can place
+your layout elements anywhere, as long as you apply the ``app`` property.
+
+.. tab-set::
+
+ .. tab-item:: :fab:`python` Python
+
+ .. code-block:: python
+
+ import ipyvuetify as v
+
+ v.App(
+ children=[
+ v.NavigationDrawer(
+ app=True,
+ children=[v.Html(tag='div', children=['Navigation content'])]
+ ),
+ v.AppBar(
+ app=True,
+ children=[v.Html(tag='div', children=['App bar content'])]
+ ),
+ v.Container(
+ fluid=True,
+ children=[v.Html(tag='div', children=['Main content area'])]
+ )
+ v.Footer(
+ app=True,
+ children=[v.Html(tag='div', children=['Footer content'])]
+ ),
+ ]
+ )
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. code-block:: vue
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+.. note::
+
+ Applying the ``app`` prop automatically applies ``position: fixed`` to the layout element. If
+ your application calls for an absolute element, you can overwrite this functionality by using the
+ ``absolute`` prop.
+
+Application components
+----------------------
+
+Below is a list of all the components that support the ``app`` prop and can be used as layout
+elements in your application. These can be mixed and matched and only **one** of each particular
+component should exist at any time. You can, however, swap them out and the layout will accommodate.
+
+Each of these application components have a designated location and priority that it affects within the layout system:
+
+- :py:class:`AppBar `: Is always placed at the top of an application with a lower
+ priority than :py:class:`SystemBar `.
+- :py:class:`BottomNavigation `: Is always placed at the bottom of an
+ application with a higher priority than :py:class:`Footer `.
+- :py:class:`Footer `: Is always placed at the bottom of an application with a
+ lower priority than :py:class:`BottomNavigation `.
+- :py:class:`NavigationDrawer `: Can be placed on the left or right
+ side of an application and can be configured to sit next to or below :py:class:`AppBar `.
+- :py:class:`SystemBar `: Is always placed at the top of an application with
+ higher priority than :py:class:`AppBar `.
+
+.. todo::
+
+ Missing image from the original page: https://v2.vuetifyjs.com/en/components/application/#application-components
diff --git a/docs/component/AppBar.rst b/docs/component/AppBar.rst
new file mode 100644
index 00000000..caae9eb2
--- /dev/null
+++ b/docs/component/AppBar.rst
@@ -0,0 +1,278 @@
+AppBar
+======
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify App Bar documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`AppBar ` component is pivotal to any graphical user interface (GUI),
+as it generally is the primary source of site navigation. The app-bar component works great in conjunction
+with a :py:class:`NavigationDrawer ` for providing site navigation in
+your application.
+
+.. api::
+
+ :py:class:`ipyvuetify.AppBar`
+ :py:class:`ipyvuetify.AppBarNavIcon`
+
+Usage
+-----
+
+The :py:class:`AppBar ` component is used for application-wide actions and information.
+
+.. jupyter-execute:: AppBar/usage.py
+ :raises:
+
+AppBarNavIcon
+-------------
+
+A styled icon button component created specifically for use with :py:class:`Toolbar `
+and :py:class:`AppBar `. Typically seen on the left side of a toolbar as a hamburger
+menu, it is often used to control the state of a navigation drawer. The default slot can be used to
+customize the icon and function of this component. This is a **functional** component.
+
+Dense
+-----
+
+You can make app-bar dense. A dense app bar has lower height than regular one.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: AppBar/dense.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: AppBar/dense.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: AppBar/dense.vue
+
+Elevate on Scroll
+-----------------
+
+When using the ``elevate_on_scroll`` prop, the :py:class:`AppBar ` will rest at an
+elevation of 0dp until the user begins to scroll down. Once scrolling, the bar raises to 4dp.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: AppBar/elevate_on_scroll.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: AppBar/elevate_on_scroll.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: AppBar/elevate_on_scroll.vue
+
+Prominent
+---------
+
+An :py:class:`AppBar ` with the ``prominent`` prop can opt to have its height shrunk
+as the user scrolls down. This provides a smooth transition to taking up less visual space when the
+user is scrolling through content.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: AppBar/prominent.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: AppBar/prominent.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: AppBar/prominent.vue
+
+Collapse
+--------
+
+With the ``collapse`` and ``collapse_on_scroll`` props you can easily control the state of toolbar
+that the user interacts with.
+
+.. tab-set::
+
+ .. tab-item:: Rendered
+
+ .. jupyter-execute:: AppBar/collapse.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: Python
+
+ .. literalinclude:: AppBar/collapse.py
+
+ .. tab-item:: Vue template
+
+ .. literalinclude:: AppBar/collapse.vue
+
+Hiding on scroll
+----------------
+
+:py:class:`AppBar ` can be hidden on scroll. Use the ``hide_on_scroll``
+property for this.
+
+.. tab-set::
+
+ .. tab-item:: Rendered
+
+ .. jupyter-execute:: AppBar/hiding_on_scroll.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: Python
+
+ .. literalinclude:: AppBar/hiding_on_scroll.py
+
+ .. tab-item:: Vue template
+
+ .. literalinclude:: AppBar/hiding_on_scroll.vue
+
+Images
+------
+
+:py:class:`AppBar ` can contain background images. You can set source via the
+``src`` prop. If you need to customize the :py:class:`Img ` properties, the app-bar
+provides you with an ``img`` slot.
+
+.. tab-set::
+
+ .. tab-item:: Rendered
+
+ .. jupyter-execute:: AppBar/images.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: Python
+
+ .. literalinclude:: AppBar/images.py
+
+ .. tab-item:: Vue template
+
+ .. literalinclude:: AppBar/images.vue
+
+Fade image on scroll
+--------------------
+
+The background image of a :py:class:`AppBar ` can fade on scroll. Use the
+``fade_img_on_scroll`` property for this.
+
+.. tab-set::
+
+ .. tab-item:: Rendered
+
+ .. jupyter-execute:: AppBar/fade_image_on_scroll.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: Python
+
+ .. literalinclude:: AppBar/fade_image_on_scroll.py
+
+ .. tab-item:: Vue template
+
+ .. literalinclude:: AppBar/fade_image_on_scroll.vue
+
+Inverted scrolling
+------------------
+
+When using the ``inverted_scroll`` property, the bar will hide until the user scrolls past the
+designated threshold. Once past the threshold, the :py:class:`AppBar ` will
+continue to display until the users scrolls up past the threshold. If no ``scroll_threshold`` value
+is supplied a default value of 0 will be used.
+
+.. tab-set::
+
+ .. tab-item:: Rendered
+
+ .. jupyter-execute:: AppBar/inverted_scrolling.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: Python
+
+ .. literalinclude:: AppBar/inverted_scrolling.py
+
+ .. tab-item:: Vue template
+
+ .. literalinclude:: AppBar/inverted_scrolling.vue
+
+Scroll threshold
+----------------
+
+:py:class:`AppBar ` can have scroll threshold. It will start reacting to scroll
+only after defined via ``scroll_threshold`` property amount of pixels.
+
+.. tab-set::
+
+ .. tab-item:: Rendered
+
+ .. jupyter-execute:: AppBar/scroll_threshold.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: Python
+
+ .. literalinclude:: AppBar/scroll_threshold.py
+
+ .. tab-item:: Vue template
+
+ .. literalinclude:: AppBar/scroll_threshold.vue
+
+Menu
+----
+
+You can easily extend the functionality of app bar by adding :py:class:`Menu `
+there. Click on last icon to see it in action.
+
+.. tab-set::
+
+ .. tab-item:: Rendered
+
+ .. jupyter-execute:: AppBar/menu.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: Python
+
+ .. literalinclude:: AppBar/menu.py
+
+ .. tab-item:: Vue template
+
+ .. literalinclude:: AppBar/menu.vue
+
+Toggle navigation drawers
+--------------------------
+
+Using the functional component :py:class:`AppBarNavIcon ` you can toggle the
+state of other components such as a :py:class:`NavigationDrawer `.
+
+.. tab-set::
+
+ .. tab-item:: Rendered
+
+ .. jupyter-execute:: AppBar/toggle_navigation_drawers.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: Python
+
+ .. literalinclude:: AppBar/toggle_navigation_drawers.py
+
+ .. tab-item:: Vue template
+
+ .. literalinclude:: AppBar/toggle_navigation_drawers.vue
+
diff --git a/docs/component/AppBar/collapse.py b/docs/component/AppBar/collapse.py
new file mode 100644
index 00000000..e116ed36
--- /dev/null
+++ b/docs/component/AppBar/collapse.py
@@ -0,0 +1,23 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="overflow-hidden",
+ children=[
+ v.AppBar(
+ absolute=True,
+ color="deep-purple accent-4",
+ dark=True,
+ collapse_on_scroll=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Collapsing Bar"]),
+ v.Spacer(),
+ ],
+ ),
+ v.Sheet(
+ class_="overflow-y-auto",
+ max_height=400,
+ children=[v.Container(style_="height: 1000px;")],
+ ),
+ ],
+)
diff --git a/docs/component/AppBar/collapse.vue b/docs/component/AppBar/collapse.vue
new file mode 100644
index 00000000..530ebe2a
--- /dev/null
+++ b/docs/component/AppBar/collapse.vue
@@ -0,0 +1,22 @@
+
+
+
+
+ Collapsing Bar
+
+
+
+
+
+
+
diff --git a/docs/component/AppBar/dense.py b/docs/component/AppBar/dense.py
new file mode 100644
index 00000000..c6596b1a
--- /dev/null
+++ b/docs/component/AppBar/dense.py
@@ -0,0 +1,15 @@
+import ipyvuetify as v
+
+v.AppBar(
+ color="deep-purple accent-4",
+ dense=True,
+ dark=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Page title"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-dots-vertical"])]),
+ ],
+)
diff --git a/docs/component/AppBar/dense.vue b/docs/component/AppBar/dense.vue
new file mode 100644
index 00000000..098a69bb
--- /dev/null
+++ b/docs/component/AppBar/dense.vue
@@ -0,0 +1,16 @@
+
+
+
+ Page title
+
+
+ mdi-heart
+
+
+ mdi-magnify
+
+
+ mdi-dots-vertical
+
+
+
diff --git a/docs/component/AppBar/elevate_on_scroll.py b/docs/component/AppBar/elevate_on_scroll.py
new file mode 100644
index 00000000..9691e6aa
--- /dev/null
+++ b/docs/component/AppBar/elevate_on_scroll.py
@@ -0,0 +1,25 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="overflow-hidden",
+ children=[
+ v.AppBar(
+ absolute=True,
+ color="white",
+ elevate_on_scroll=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Title"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-dots-vertical"])]),
+ ],
+ ),
+ v.Sheet(
+ class_="overflow-y-auto",
+ max_height=400,
+ children=[v.Container(style_="height: 1000px;")],
+ ),
+ ],
+)
diff --git a/docs/component/AppBar/elevate_on_scroll.vue b/docs/component/AppBar/elevate_on_scroll.vue
new file mode 100644
index 00000000..54dc5990
--- /dev/null
+++ b/docs/component/AppBar/elevate_on_scroll.vue
@@ -0,0 +1,24 @@
+
+
+
+
+ Title
+
+
+ mdi-magnify
+
+
+
+
+
+
+
diff --git a/docs/component/AppBar/fade_image_on_scroll.py b/docs/component/AppBar/fade_image_on_scroll.py
new file mode 100644
index 00000000..24d1479d
--- /dev/null
+++ b/docs/component/AppBar/fade_image_on_scroll.py
@@ -0,0 +1,29 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="overflow-hidden",
+ children=[
+ v.AppBar(
+ absolute=True,
+ color="#6A76AB",
+ dark=True,
+ shrink_on_scroll=True,
+ prominent=True,
+ src="https://picsum.photos/1920/1080?random",
+ fade_img_on_scroll=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Title"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-dots-vertical"])]),
+ ],
+ ),
+ v.Sheet(
+ class_="overflow-y-auto",
+ max_height=400,
+ children=[v.Container(style_="height: 1000px;")],
+ ),
+ ],
+)
diff --git a/docs/component/AppBar/fade_image_on_scroll.vue b/docs/component/AppBar/fade_image_on_scroll.vue
new file mode 100644
index 00000000..43953382
--- /dev/null
+++ b/docs/component/AppBar/fade_image_on_scroll.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+ Title
+
+
+ mdi-magnify
+
+
+ mdi-heart
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
diff --git a/docs/component/AppBar/hiding_on_scroll.py b/docs/component/AppBar/hiding_on_scroll.py
new file mode 100644
index 00000000..b3bdaf51
--- /dev/null
+++ b/docs/component/AppBar/hiding_on_scroll.py
@@ -0,0 +1,27 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="overflow-hidden",
+ children=[
+ v.AppBar(
+ absolute=True,
+ color="teal lighten-3",
+ dark=True,
+ hide_on_scroll=True,
+ prominent=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Title"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-dots-vertical"])]),
+ ],
+ ),
+ v.Sheet(
+ class_="overflow-y-auto",
+ max_height=400,
+ children=[v.Container(style_="height: 1000px;")],
+ ),
+ ],
+)
diff --git a/docs/component/AppBar/hiding_on_scroll.vue b/docs/component/AppBar/hiding_on_scroll.vue
new file mode 100644
index 00000000..fae66bd7
--- /dev/null
+++ b/docs/component/AppBar/hiding_on_scroll.vue
@@ -0,0 +1,32 @@
+
+
+
+
+ Title
+
+
+ mdi-magnify
+
+
+ mdi-heart
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
diff --git a/docs/component/AppBar/images.py b/docs/component/AppBar/images.py
new file mode 100644
index 00000000..515c512e
--- /dev/null
+++ b/docs/component/AppBar/images.py
@@ -0,0 +1,27 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="overflow-hidden",
+ children=[
+ v.AppBar(
+ absolute=True,
+ color="#fcb69f",
+ dark=True,
+ shrink_on_scroll=True,
+ src="https://picsum.photos/1920/1080?random",
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Title"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-dots-vertical"])]),
+ ],
+ ),
+ v.Sheet(
+ class_="overflow-y-auto",
+ max_height=400,
+ children=[v.Container(style_="height: 1000px;")],
+ ),
+ ],
+)
diff --git a/docs/component/AppBar/images.vue b/docs/component/AppBar/images.vue
new file mode 100644
index 00000000..1f8dac89
--- /dev/null
+++ b/docs/component/AppBar/images.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+ Title
+
+
+ mdi-magnify
+
+
+ mdi-heart
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
diff --git a/docs/component/AppBar/inverted_scrolling.py b/docs/component/AppBar/inverted_scrolling.py
new file mode 100644
index 00000000..6d3caef6
--- /dev/null
+++ b/docs/component/AppBar/inverted_scrolling.py
@@ -0,0 +1,26 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="overflow-hidden",
+ children=[
+ v.AppBar(
+ absolute=True,
+ color="primary",
+ dark=True,
+ inverted_scroll=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Title"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-dots-vertical"])]),
+ ],
+ ),
+ v.Sheet(
+ class_="overflow-y-auto",
+ max_height=400,
+ children=[v.Container(style_="height: 1500px;")],
+ ),
+ ],
+)
diff --git a/docs/component/AppBar/inverted_scrolling.vue b/docs/component/AppBar/inverted_scrolling.vue
new file mode 100644
index 00000000..7eef5730
--- /dev/null
+++ b/docs/component/AppBar/inverted_scrolling.vue
@@ -0,0 +1,31 @@
+
+
+
+
+ Title
+
+
+ mdi-magnify
+
+
+ mdi-heart
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
diff --git a/docs/component/AppBar/menu.py b/docs/component/AppBar/menu.py
new file mode 100644
index 00000000..871ba59f
--- /dev/null
+++ b/docs/component/AppBar/menu.py
@@ -0,0 +1,55 @@
+import ipyvuetify as v
+
+menu = v.Menu(
+ bottom=True,
+ left=True,
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "menuProps",
+ "children": v.Btn(
+ icon=True,
+ color="yellow",
+ v_on="menuProps.on",
+ children=[v.Icon(children=["mdi-dots-vertical"])],
+ ),
+ }
+ ],
+ children=[
+ v.List(
+ children=[
+ v.ListItem(children=[v.ListItemTitle(children=["Click Me 1"])]),
+ v.ListItem(children=[v.ListItemTitle(children=["Click Me 2"])]),
+ v.ListItem(children=[v.ListItemTitle(children=["Click Me 3"])]),
+ ]
+ )
+ ],
+)
+
+v.Card(
+ class_="overflow-hidden",
+ children=[
+ v.AppBar(
+ absolute=True,
+ color="#6A76AB",
+ dark=True,
+ shrink_on_scroll=True,
+ prominent=True,
+ src="https://picsum.photos/1920/1080?random",
+ fade_img_on_scroll=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Title"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ menu,
+ ],
+ ),
+ v.Sheet(
+ class_="overflow-y-auto",
+ max_height=400,
+ children=[v.Container(style_="height: 1000px;")],
+ ),
+ ],
+)
diff --git a/docs/component/AppBar/menu.vue b/docs/component/AppBar/menu.vue
new file mode 100644
index 00000000..1f64cfed
--- /dev/null
+++ b/docs/component/AppBar/menu.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+ Title
+
+
+ mdi-magnify
+
+
+ mdi-heart
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+ Click Me 1
+
+
+ Click Me 2
+
+
+ Click Me 3
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/AppBar/prominent.py b/docs/component/AppBar/prominent.py
new file mode 100644
index 00000000..d4c42d38
--- /dev/null
+++ b/docs/component/AppBar/prominent.py
@@ -0,0 +1,27 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="overflow-hidden",
+ children=[
+ v.AppBar(
+ absolute=True,
+ color="indigo darken-2",
+ dark=True,
+ shrink_on_scroll=True,
+ prominent=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Title"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-dots-vertical"])]),
+ ],
+ ),
+ v.Sheet(
+ class_="overflow-y-auto",
+ max_height=400,
+ children=[v.Container(style_="height: 1000px;")],
+ ),
+ ],
+)
diff --git a/docs/component/AppBar/prominent.vue b/docs/component/AppBar/prominent.vue
new file mode 100644
index 00000000..03e4919c
--- /dev/null
+++ b/docs/component/AppBar/prominent.vue
@@ -0,0 +1,25 @@
+
+
+
+
+ Title
+
+
+ mdi-magnify
+
+
+ mdi-heart
+
+
+
+
+
+
+
diff --git a/docs/component/AppBar/scroll_threshold.py b/docs/component/AppBar/scroll_threshold.py
new file mode 100644
index 00000000..3cfbe3c0
--- /dev/null
+++ b/docs/component/AppBar/scroll_threshold.py
@@ -0,0 +1,30 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="overflow-hidden",
+ children=[
+ v.AppBar(
+ absolute=True,
+ color="#43a047",
+ dark=True,
+ shrink_on_scroll=True,
+ prominent=True,
+ src="https://picsum.photos/1920/1080?random",
+ fade_img_on_scroll=True,
+ scroll_threshold=500,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Title"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-dots-vertical"])]),
+ ],
+ ),
+ v.Sheet(
+ class_="overflow-y-auto",
+ max_height=400,
+ children=[v.Container(style_="height: 1500px;")],
+ ),
+ ],
+)
diff --git a/docs/component/AppBar/scroll_threshold.vue b/docs/component/AppBar/scroll_threshold.vue
new file mode 100644
index 00000000..bc412884
--- /dev/null
+++ b/docs/component/AppBar/scroll_threshold.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+ Title
+
+
+ mdi-magnify
+
+
+ mdi-heart
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+
diff --git a/docs/component/AppBar/toggle_navigation_drawers.py b/docs/component/AppBar/toggle_navigation_drawers.py
new file mode 100644
index 00000000..3e748238
--- /dev/null
+++ b/docs/component/AppBar/toggle_navigation_drawers.py
@@ -0,0 +1,55 @@
+import ipyvuetify as v
+
+drawer = v.NavigationDrawer(
+ v_model=False,
+ absolute=True,
+ temporary=True,
+ children=[
+ v.List(
+ nav=True,
+ dense=True,
+ children=[
+ v.ListItemGroup(
+ children=[
+ v.ListItem(
+ children=[
+ v.ListItemIcon(children=[v.Icon(children=["mdi-home"])]),
+ v.ListItemTitle(children=["Home"]),
+ ]
+ ),
+ v.ListItem(
+ children=[
+ v.ListItemIcon(children=[v.Icon(children=["mdi-account"])]),
+ v.ListItemTitle(children=["Account"]),
+ ]
+ ),
+ ]
+ )
+ ],
+ )
+ ],
+)
+
+
+def toggle_drawer(widget, event, data):
+ drawer.v_model = not drawer.v_model
+
+
+nav_icon = v.AppBarNavIcon()
+nav_icon.on_event("click", toggle_drawer)
+
+v.Card(
+ class_="mx-auto overflow-hidden",
+ max_height=400,
+ children=[
+ v.AppBar(
+ color="deep-purple",
+ dark=True,
+ children=[
+ nav_icon,
+ v.ToolbarTitle(children=["Title"]),
+ ],
+ ),
+ drawer,
+ ],
+)
diff --git a/docs/component/AppBar/toggle_navigation_drawers.vue b/docs/component/AppBar/toggle_navigation_drawers.vue
new file mode 100644
index 00000000..0c401019
--- /dev/null
+++ b/docs/component/AppBar/toggle_navigation_drawers.vue
@@ -0,0 +1,31 @@
+
+
+
+
+ Title
+
+
+
+
+
+
+
+ mdi-home
+
+ Home
+
+
+
+
+ mdi-account
+
+ Account
+
+
+
+
+
+
diff --git a/docs/component/AppBar/usage.py b/docs/component/AppBar/usage.py
new file mode 100644
index 00000000..75d1f8e8
--- /dev/null
+++ b/docs/component/AppBar/usage.py
@@ -0,0 +1,17 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.AppBar(
+ color="primary",
+ dark=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["My Application"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-heart"])]),
+ ],
+ )
+ ]
+)
diff --git a/docs/component/Autocomplete.rst b/docs/component/Autocomplete.rst
new file mode 100644
index 00000000..2309b113
--- /dev/null
+++ b/docs/component/Autocomplete.rst
@@ -0,0 +1,134 @@
+Autocomplete
+============
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Autocomplete ` component offers simple and flexible type-ahead
+functionality. This is useful when searching large sets of data or even dynamically requesting information
+from an API. The autocomplete component extends :py:class:`Select ` and adds the
+ability to filter items.
+
+.. api::
+
+ :py:class:`ipyvuetify.Autocomplete`
+
+Usage
+-----
+
+The autocomplete component extends :py:class:`Select ` and adds the ability to filter items.
+
+.. jupyter-execute:: Autocomplete/usage.py
+ :raises:
+
+Dense
+-----
+
+You can use ``dense`` prop to reduce autocomplete height and lower max height of list items.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Autocomplete/dense.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Autocomplete/dense.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Autocomplete/dense.vue
+
+No-Filter
+---------
+
+The ``no-filter`` prop can be used to prevent filtering of the items. Useful when
+you want to display all options regardless of the search input.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Autocomplete/no_filter.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Autocomplete/no_filter.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Autocomplete/no_filter.vue
+
+Slots
+-----
+
+With the power of slots, you can customize the visual output of the select. In this example we add a profile picture for both the chips and list items.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Autocomplete/slots.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Autocomplete/slots.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Autocomplete/slots.vue
+
+Asynchronous items
+------------------
+
+Sometimes you need to load data externally based upon a search query. Use the ``search_input`` prop
+with the ``.sync`` modifier when using the ``autocomplete`` prop. We also make use of the new
+``cache_items`` prop. This will keep a unique list of all items that have been passed to the ``items``
+prop and is REQUIRED when using asynchronous items and the multiple prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Autocomplete/asynchronous_items.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Autocomplete/asynchronous_items.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Autocomplete/asynchronous_items.vue
+
+State selector
+--------------
+
+Using a combination of :py:class:`Autocomplete ` slots and transitions, you
+can create a stylish toggleable autocomplete field such as this state selector.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Autocomplete/state_selector.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Autocomplete/state_selector.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Autocomplete/state_selector.vue
+
diff --git a/docs/component/Autocomplete/asynchronous_items.py b/docs/component/Autocomplete/asynchronous_items.py
new file mode 100644
index 00000000..f60e4b20
--- /dev/null
+++ b/docs/component/Autocomplete/asynchronous_items.py
@@ -0,0 +1,35 @@
+import ipyvuetify as v
+
+states = [
+ "Alabama",
+ "Alaska",
+ "American Samoa",
+ "Arizona",
+ "Arkansas",
+ "California",
+ "Colorado",
+ "Connecticut",
+ "Delaware",
+ "District of Columbia",
+ "Florida",
+ "Georgia",
+]
+
+v.Toolbar(
+ dark=True,
+ color="teal",
+ children=[
+ v.ToolbarTitle(children=["State selection"]),
+ v.Autocomplete(
+ items=states,
+ cache_items=True,
+ class_="mx-4",
+ flat=True,
+ hide_no_data=True,
+ hide_details=True,
+ label="What state are you from?",
+ solo_inverted=True,
+ ),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-dots-vertical"])]),
+ ],
+)
diff --git a/docs/component/Autocomplete/asynchronous_items.vue b/docs/component/Autocomplete/asynchronous_items.vue
new file mode 100644
index 00000000..6e361736
--- /dev/null
+++ b/docs/component/Autocomplete/asynchronous_items.vue
@@ -0,0 +1,21 @@
+
+
+ State selection
+
+
+ mdi-dots-vertical
+
+
+
diff --git a/docs/component/Autocomplete/dense.py b/docs/component/Autocomplete/dense.py
new file mode 100644
index 00000000..dc9dc505
--- /dev/null
+++ b/docs/component/Autocomplete/dense.py
@@ -0,0 +1,57 @@
+import ipyvuetify as v
+
+v.Card(
+ children=[
+ v.Container(
+ fluid=True,
+ children=[
+ v.Row(
+ align="center",
+ children=[
+ v.Col(
+ cols=12,
+ children=[
+ v.Autocomplete(
+ v_model=["foo", "bar"],
+ items=["foo", "bar", "fizz", "buzz"],
+ outlined=True,
+ dense=True,
+ chips=True,
+ small_chips=True,
+ label="Outlined",
+ multiple=True,
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ children=[
+ v.Autocomplete(
+ v_model=["foo", "bar"],
+ items=["foo", "bar", "fizz", "buzz"],
+ dense=True,
+ chips=True,
+ small_chips=True,
+ label="Solo",
+ multiple=True,
+ solo=True,
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ children=[
+ v.Autocomplete(
+ items=["foo", "bar", "fizz", "buzz"],
+ dense=True,
+ filled=True,
+ label="Filled",
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+ )
+ ]
+)
diff --git a/docs/component/Autocomplete/dense.vue b/docs/component/Autocomplete/dense.vue
new file mode 100644
index 00000000..10d6e6d2
--- /dev/null
+++ b/docs/component/Autocomplete/dense.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Autocomplete/no_filter.py b/docs/component/Autocomplete/no_filter.py
new file mode 100644
index 00000000..36730ce3
--- /dev/null
+++ b/docs/component/Autocomplete/no_filter.py
@@ -0,0 +1,48 @@
+import ipyvuetify as v
+
+states = [
+ {"name": "Florida", "abbr": "FL", "id": 1},
+ {"name": "Georgia", "abbr": "GA", "id": 2},
+ {"name": "Nebraska", "abbr": "NE", "id": 3},
+ {"name": "California", "abbr": "CA", "id": 4},
+ {"name": "New York", "abbr": "NY", "id": 5},
+]
+
+v.Card(
+ class_="overflow-hidden",
+ color="purple lighten-1",
+ dark=True,
+ children=[
+ v.Toolbar(
+ flat=True,
+ color="purple",
+ children=[
+ v.Icon(children=["mdi-account"]),
+ v.ToolbarTitle(class_="font-weight-light", children=["User Profile"]),
+ v.Spacer(),
+ ],
+ ),
+ v.CardText(
+ children=[
+ v.TextField(
+ color="white",
+ label="Name",
+ ),
+ v.Autocomplete(
+ items=states,
+ item_text="name",
+ color="white",
+ label="State",
+ no_filter=True,
+ ),
+ ]
+ ),
+ v.Divider(),
+ v.CardActions(
+ children=[
+ v.Spacer(),
+ v.Btn(color="success", children=["Save"]),
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Autocomplete/no_filter.vue b/docs/component/Autocomplete/no_filter.vue
new file mode 100644
index 00000000..e36f99d4
--- /dev/null
+++ b/docs/component/Autocomplete/no_filter.vue
@@ -0,0 +1,26 @@
+
+
+
+ mdi-account
+
+ User Profile
+
+
+
+
+
+
+
+
+
+
+ Save
+
+
+
diff --git a/docs/component/Autocomplete/slots.py b/docs/component/Autocomplete/slots.py
new file mode 100644
index 00000000..3940294a
--- /dev/null
+++ b/docs/component/Autocomplete/slots.py
@@ -0,0 +1,137 @@
+import ipyvuetify as v
+
+people = [
+ {"name": "Sandra Adams", "avatar": "https://cdn.vuetifyjs.com/images/lists/1.jpg"},
+ {"name": "Britta Holt", "avatar": "https://cdn.vuetifyjs.com/images/lists/2.jpg"},
+]
+
+v.Card(
+ color="blue-grey darken-1",
+ dark=True,
+ children=[
+ v.Img(
+ height=200,
+ src="https://cdn.vuetifyjs.com/images/cards/dark-beach.jpg",
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ class_="text-right",
+ cols=12,
+ children=[
+ v.Menu(
+ bottom=True,
+ left=True,
+ transition="slide-y-transition",
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "menuProps",
+ "children": v.Btn(
+ icon=True,
+ v_on="menuProps.on",
+ children=[v.Icon(children=["mdi-dots-vertical"])],
+ ),
+ }
+ ],
+ children=[
+ v.List(
+ children=[
+ v.ListItem(
+ children=[
+ v.ListItemAction(
+ children=[v.Icon(children=["mdi-cogs"])]
+ ),
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(children=["Update"])
+ ]
+ ),
+ ]
+ ),
+ ]
+ )
+ ],
+ )
+ ],
+ ),
+ v.Row(
+ class_="ma-auto",
+ align="center",
+ justify="center",
+ children=[
+ v.Col(
+ class_="text-center",
+ children=[
+ v.Html(
+ tag="h3",
+ class_="mb-1 text-white",
+ children=["Midnight Crew"],
+ ),
+ v.Html(
+ tag="span",
+ class_="mt-1 grey--text text--lighten-1",
+ children=["The summer breeze"],
+ ),
+ ],
+ )
+ ],
+ ),
+ ]
+ )
+ ],
+ ),
+ v.Form(
+ children=[
+ v.Container(
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ cols=12,
+ md=6,
+ children=[
+ v.TextField(
+ v_model="Midnight Crew",
+ filled=True,
+ color="blue-grey lighten-2",
+ label="Name",
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ md=6,
+ children=[
+ v.TextField(
+ v_model="The summer breeze",
+ filled=True,
+ color="blue-grey lighten-2",
+ label="Title",
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ children=[
+ v.Autocomplete(
+ v_model=["Sandra Adams", "Britta Holt"],
+ items=people,
+ filled=True,
+ chips=True,
+ color="blue-grey lighten-2",
+ label="Select",
+ item_text="name",
+ item_value="name",
+ multiple=True,
+ )
+ ],
+ ),
+ ]
+ )
+ ]
+ )
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Autocomplete/slots.vue b/docs/component/Autocomplete/slots.vue
new file mode 100644
index 00000000..d2758841
--- /dev/null
+++ b/docs/component/Autocomplete/slots.vue
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ data.item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Autocomplete/state_selector.py b/docs/component/Autocomplete/state_selector.py
new file mode 100644
index 00000000..db4a28cd
--- /dev/null
+++ b/docs/component/Autocomplete/state_selector.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+states = ["Alabama", "Alaska", "Arizona", "Arkansas", "California"]
+
+v.Card(
+ children=[
+ v.CardTitle(
+ class_="text-h5 font-weight-regular blue-grey white--text", children=["Profile"]
+ ),
+ v.CardText(
+ children=[
+ v.Subheader(class_="pa-0", children=["Where do you live?"]),
+ v.Autocomplete(
+ items=states,
+ readonly=True,
+ label="State — Readonly",
+ persistent_hint=True,
+ hint="Click the icon to edit",
+ prepend_icon="mdi-city",
+ ),
+ ]
+ ),
+ ]
+)
diff --git a/docs/component/Autocomplete/state_selector.vue b/docs/component/Autocomplete/state_selector.vue
new file mode 100644
index 00000000..8b4a8ddf
--- /dev/null
+++ b/docs/component/Autocomplete/state_selector.vue
@@ -0,0 +1,32 @@
+
+
+
+ Profile
+
+
+ Where do you live?
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Autocomplete/usage.py b/docs/component/Autocomplete/usage.py
new file mode 100644
index 00000000..60b0a03b
--- /dev/null
+++ b/docs/component/Autocomplete/usage.py
@@ -0,0 +1,11 @@
+import ipyvuetify as v
+
+autocomplete = v.Autocomplete(
+ items=["Alabama", "Alaska", "Arizona", "Arkansas", "California"],
+ label="States",
+ dense=False,
+ filled=False,
+ clearable=True,
+)
+
+v.Container(children=[autocomplete])
diff --git a/docs/component/Avatar.rst b/docs/component/Avatar.rst
new file mode 100644
index 00000000..cc59656b
--- /dev/null
+++ b/docs/component/Avatar.rst
@@ -0,0 +1,134 @@
+Avatar
+======
+
+.. aknowledgement::
+ This documentation has been adapted from the official Vuetify 2 documentation available at
+ https://v2.vuetifyjs.com/en/components/avatars/.
+
+The :py:class:`Avatar ` component is typically used to display circular user
+profile pictures. This component will allow you to dynamically size and add a border radius of
+responsive images, icons, and text. A ``tile`` variation is available for displaying an avatar
+without border radius.
+
+.. api::
+
+ :py:class:`ipyvuetify.Avatar`
+
+Usage
+-----
+
+Avatars in their simplest form display content within a circular container.
+
+.. jupyter-execute:: Avatar/usage.py
+ :raises:
+ :hide-code:
+
+Size
+----
+
+The ``size`` prop allows you to define the height and width of :py:class:`Avatar `.
+This prop scales both evenly with an aspect ratio of 1. ``height`` and ``width`` props will override
+this prop.
+
+.. tab-set::
+
+ .. tab-item:: Rendered
+
+ .. jupyter-execute:: Avatar/size.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Avatar/size.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Avatar/size.vue
+
+Tile
+----
+
+The ``tile`` prop removes the border radius from :py:class:`Avatar ` leaving you
+with a simple square avatar.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Avatar/tile.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Avatar/tile.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Avatar/tile.vue
+
+Using images
+------------
+
+The :py:class:`Avatar ` default chikdren will accept the :py:class:`Icon `
+component, an image, or text. Mix and match these with other props to create something unique.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Avatar/using_images.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Avatar/using_images.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Avatar/using_images.vue
+
+Advanced usage
+--------------
+
+Combining an avatar with other components allows you to build beautiful user interfaces right out of the box.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Avatar/advanced_usage.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Avatar/advanced_usage.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Avatar/advanced_usage.vue
+
+Profile Card
+------------
+
+Using the ``tile`` prop, we can create a sleek hard-lined profile card.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Avatar/profile_card.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Avatar/profile_card.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Avatar/profile_card.vue
+
diff --git a/docs/component/Avatar/advanced_usage.py b/docs/component/Avatar/advanced_usage.py
new file mode 100644
index 00000000..2be134e3
--- /dev/null
+++ b/docs/component/Avatar/advanced_usage.py
@@ -0,0 +1,116 @@
+import ipyvuetify as v
+
+messages = [
+ {
+ "avatar": "https://avatars0.githubusercontent.com/u/9064066?v=4&s=460",
+ "name": "John Leider",
+ "title": "Welcome to Vuetify!",
+ "excerpt": "Thank you for joining our community...",
+ "new": None,
+ "total": None,
+ "color": None,
+ "icon": None,
+ },
+ {
+ "color": "red",
+ "icon": "mdi-account-multiple",
+ "name": "Social",
+ "new": 1,
+ "total": 3,
+ "title": "Twitter",
+ "excerpt": None,
+ "avatar": None,
+ },
+ {
+ "color": "teal",
+ "icon": "mdi-tag",
+ "name": "Promos",
+ "new": 2,
+ "total": 4,
+ "title": "Shop your way",
+ "excerpt": "New deals available, Join Today",
+ "avatar": None,
+ },
+]
+
+lorem = (
+ "Lorem ipsum dolor sit amet, at aliquam vivendum vel, everti delicatissimi cu eos. Dico "
+ "iuvaret debitis mel an, et cum zril menandri."
+)
+
+panels = []
+for i, message in enumerate(messages):
+ avatar_content = []
+ if message["avatar"]:
+ avatar_content.append(v.Img(alt="Avatar", src=message["avatar"]))
+ else:
+ avatar_content.append(v.Icon(color=message["color"], children=[message["icon"]]))
+
+ header_cols = [
+ v.Col(cols=4, sm=2, md=1, children=[v.Avatar(size=36, children=avatar_content)]),
+ v.Col(
+ class_="hidden-xs-only",
+ sm=5,
+ md=3,
+ children=[
+ v.Html(tag="strong", children=[message["name"]]),
+ v.Html(
+ tag="span",
+ class_="grey--text",
+ children=[f" ({message['total']})" if "total" in message else ""],
+ ),
+ ],
+ ),
+ v.Col(
+ class_="text-no-wrap",
+ cols=5,
+ sm=3,
+ children=[
+ v.Chip(
+ color=f"{message['color']} lighten-4",
+ class_="ml-0 mr-2 black--text",
+ label=True,
+ small=True,
+ children=[f"{message['new'] if 'new' in message else ''} new"],
+ ),
+ v.Html(tag="strong", children=[message["title"]]),
+ ],
+ ),
+ ]
+
+ if message["excerpt"]:
+ header_cols.append(
+ v.Col(
+ class_="grey--text text-truncate hidden-sm-and-down",
+ children=[f"— {message['excerpt']}"],
+ )
+ )
+
+ panels.append(
+ v.ExpansionPanel(
+ hide_actions=True,
+ children=[
+ v.ExpansionPanelHeader(
+ children=[
+ v.Row(
+ align="center", class_="spacer", no_gutters=True, children=header_cols
+ )
+ ]
+ ),
+ v.ExpansionPanelContent(children=[v.Divider(), v.CardText(children=[lorem])]),
+ ],
+ )
+ )
+
+v.Container(
+ fluid=True,
+ children=[
+ v.Row(
+ justify="center",
+ children=[
+ v.Subheader(children=["Today"]),
+ v.ExpansionPanels(popout=True, children=panels),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Avatar/advanced_usage.vue b/docs/component/Avatar/advanced_usage.vue
new file mode 100644
index 00000000..df1fa147
--- /dev/null
+++ b/docs/component/Avatar/advanced_usage.vue
@@ -0,0 +1,100 @@
+
+
+
+ Today
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ({{ message.total }})
+
+
+
+
+
+ {{ message.new }} new
+
+
+
+
+
+ -
+ {{ message.excerpt }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Avatar/profile_card.py b/docs/component/Avatar/profile_card.py
new file mode 100644
index 00000000..8fa0cdd9
--- /dev/null
+++ b/docs/component/Avatar/profile_card.py
@@ -0,0 +1,58 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="mx-auto",
+ max_width=434,
+ tile=True,
+ children=[
+ v.Img(
+ height="100%",
+ src="https://cdn.vuetifyjs.com/images/cards/server-room.jpg",
+ children=[
+ v.Row(
+ align="end",
+ class_="fill-height",
+ children=[
+ v.Col(
+ align_self="start",
+ class_="pa-0",
+ cols=12,
+ children=[
+ v.Avatar(
+ class_="profile",
+ color="grey",
+ size=164,
+ tile=True,
+ children=[
+ v.Img(
+ src="https://cdn.vuetifyjs.com/images/profiles/marcus.jpg"
+ )
+ ],
+ )
+ ],
+ ),
+ v.Col(
+ class_="py-0",
+ children=[
+ v.ListItem(
+ color="rgba(0, 0, 0, .4)",
+ dark=True,
+ children=[
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(
+ class_="text-h6", children=["Marcus Obrien"]
+ ),
+ v.ListItemSubtitle(children=["Network Engineer"]),
+ ]
+ )
+ ],
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Avatar/profile_card.vue b/docs/component/Avatar/profile_card.vue
new file mode 100644
index 00000000..f5b130fc
--- /dev/null
+++ b/docs/component/Avatar/profile_card.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Marcus Obrien
+
+ Network Engineer
+
+
+
+
+
+
+
diff --git a/docs/component/Avatar/size.py b/docs/component/Avatar/size.py
new file mode 100644
index 00000000..1d38a29c
--- /dev/null
+++ b/docs/component/Avatar/size.py
@@ -0,0 +1,22 @@
+import ipyvuetify as v
+
+v.Row(
+ justify="space-around",
+ children=[
+ v.Avatar(
+ color="indigo",
+ size=36,
+ children=[v.Html(tag="span", class_="text-white", children=["36"])],
+ ),
+ v.Avatar(
+ color="teal",
+ size=48,
+ children=[v.Html(tag="span", class_="text-white", children=["48"])],
+ ),
+ v.Avatar(
+ color="orange",
+ size=62,
+ children=[v.Html(tag="span", class_="text-white", children=["62"])],
+ ),
+ ],
+)
diff --git a/docs/component/Avatar/size.vue b/docs/component/Avatar/size.vue
new file mode 100644
index 00000000..47c4a43b
--- /dev/null
+++ b/docs/component/Avatar/size.vue
@@ -0,0 +1,15 @@
+
+
+
+ 36
+
+
+
+ 48
+
+
+
+ 62
+
+
+
diff --git a/docs/component/Avatar/tile.py b/docs/component/Avatar/tile.py
new file mode 100644
index 00000000..f880849f
--- /dev/null
+++ b/docs/component/Avatar/tile.py
@@ -0,0 +1,3 @@
+import ipyvuetify as v
+
+v.Avatar(tile=True, color="blue", children=[v.Icon(dark=True, children=["mdi-alarm"])])
diff --git a/docs/component/Avatar/tile.vue b/docs/component/Avatar/tile.vue
new file mode 100644
index 00000000..26597e04
--- /dev/null
+++ b/docs/component/Avatar/tile.vue
@@ -0,0 +1,7 @@
+
+
+
+ mdi-alarm
+
+
+
diff --git a/docs/component/Avatar/usage.py b/docs/component/Avatar/usage.py
new file mode 100644
index 00000000..619ca149
--- /dev/null
+++ b/docs/component/Avatar/usage.py
@@ -0,0 +1,8 @@
+import ipyvuetify as v
+
+avatar = v.Avatar(
+ color="primary",
+ size=56,
+ children=["VJ"],
+)
+v.Container(children=[avatar])
diff --git a/docs/component/Avatar/using_images.py b/docs/component/Avatar/using_images.py
new file mode 100644
index 00000000..442ec163
--- /dev/null
+++ b/docs/component/Avatar/using_images.py
@@ -0,0 +1,20 @@
+import ipyvuetify as v
+
+v.Row(
+ justify="space-around",
+ children=[
+ v.Avatar(color="indigo", children=[v.Icon(dark=True, children=["mdi-account-circle"])]),
+ v.Avatar(
+ children=[
+ v.Img(
+ src="https://avatars.githubusercontent.com/u/12596392??v=4&s=460",
+ alt="John",
+ )
+ ]
+ ),
+ v.Avatar(
+ color="red",
+ children=[v.Html(tag="span", class_="white--text text-h5", children=["CJ"])],
+ ),
+ ],
+)
diff --git a/docs/component/Avatar/using_images.vue b/docs/component/Avatar/using_images.vue
new file mode 100644
index 00000000..270d445a
--- /dev/null
+++ b/docs/component/Avatar/using_images.vue
@@ -0,0 +1,18 @@
+
+
+
+ mdi-account-circle
+
+
+
+
+
+
+
+ CJ
+
+
+
diff --git a/docs/component/Badge.rst b/docs/component/Badge.rst
new file mode 100644
index 00000000..5ca6d264
--- /dev/null
+++ b/docs/component/Badge.rst
@@ -0,0 +1,107 @@
+Badge
+=====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Badge ` component superscripts or subscripts an avatar-like icon or
+text onto content to highlight information to a user or to just draw attention to a specific element.
+Content within the badge usually contains numbers or icons.
+
+.. api::
+
+ :py:class:`ipyvuetify.Badge`
+
+Usage
+-----
+
+Badges in their simplest form display to the upper right of the content that it wraps and requires the badge slot.
+
+.. jupyter-execute:: Badge/usage.py
+ :raises:
+
+Customization options
+---------------------
+
+The :py:class:`Badge ` component is flexible and can be used in a variety of use-cases over numerous elements. Options to tweak the location are also available through the ``offset_x`` and ``offset_y`` props.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Badge/customization_options.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Badge/customization_options.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Badge/customization_options.vue
+
+Dynamic notifications
+---------------------
+
+You can incorporate badges with dynamic content to make things such as a notification system.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Badge/dynamic_notifications.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Badge/dynamic_notifications.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Badge/dynamic_notifications.vue
+
+Show on hover
+-------------
+
+You can do many things with visibility control, for example, show badge on hover.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Badge/show_on_hover.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Badge/show_on_hover.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Badge/show_on_hover.vue
+
+Tabs
+----
+
+Badges help convey information to the user in a variety of ways.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Badge/tabs.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Badge/tabs.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Badge/tabs.vue
+
diff --git a/docs/component/Badge/customization_options.py b/docs/component/Badge/customization_options.py
new file mode 100644
index 00000000..1a60232f
--- /dev/null
+++ b/docs/component/Badge/customization_options.py
@@ -0,0 +1,49 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="d-inline-flex justify-center",
+ children=[
+ v.Badge(
+ bordered=True,
+ color="error",
+ icon="mdi-lock",
+ overlap=True,
+ children=[
+ v.Btn(
+ class_="white--text", color="error", depressed=True, children=["Lock Account"]
+ )
+ ],
+ ),
+ v.Html(tag="div", class_="mx-3"),
+ v.Badge(
+ bordered=True,
+ bottom=True,
+ color="deep-purple accent-4",
+ dot=True,
+ offset_x=10,
+ offset_y=10,
+ children=[
+ v.Avatar(
+ size=40, children=[v.Img(src="https://cdn.vuetifyjs.com/images/lists/2.jpg")]
+ )
+ ],
+ ),
+ v.Html(tag="div", class_="mx-3"),
+ v.Badge(
+ avatar=True,
+ bordered=True,
+ overlap=True,
+ v_slots=[
+ {
+ "name": "badge",
+ "children": v.Avatar(
+ children=[v.Img(src="https://cdn.vuetifyjs.com/images/logos/v.png")]
+ ),
+ }
+ ],
+ children=[
+ v.Avatar(size=40, children=[v.Img(src="https://cdn.vuetifyjs.com/images/john.png")])
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Badge/customization_options.vue b/docs/component/Badge/customization_options.vue
new file mode 100644
index 00000000..046b7328
--- /dev/null
+++ b/docs/component/Badge/customization_options.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
+ Lock Account
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Badge/dynamic_notifications.py b/docs/component/Badge/dynamic_notifications.py
new file mode 100644
index 00000000..f6513298
--- /dev/null
+++ b/docs/component/Badge/dynamic_notifications.py
@@ -0,0 +1,37 @@
+import ipyvuetify as v
+
+messages = 0
+
+
+def update_messages(*args):
+ global messages
+ messages += 1
+ badge.content = messages
+ badge.value = messages > 0
+
+
+def clear_messages(*args):
+ global messages
+ messages = 0
+ badge.content = 0
+ badge.value = False
+
+
+btn_send = v.Btn(class_="mx-1", color="primary", children=["Send Message"])
+btn_send.on_event("click", update_messages)
+
+btn_clear = v.Btn(class_="mx-1", color="error", children=["Clear Notifications"])
+btn_clear.on_event("click", clear_messages)
+
+badge = v.Badge(
+ content=5,
+ value=True,
+ color="green",
+ overlap=True,
+ children=[v.Icon(large=True, children=["mdi-vuetify"])],
+)
+
+v.Container(
+ class_="d-inline-flex",
+ children=[v.Html(tag="div", children=[btn_send, btn_clear]), v.Spacer(), badge],
+)
diff --git a/docs/component/Badge/dynamic_notifications.vue b/docs/component/Badge/dynamic_notifications.vue
new file mode 100644
index 00000000..22bc14f9
--- /dev/null
+++ b/docs/component/Badge/dynamic_notifications.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+ Send Message
+
+
+
+ Clear Notifications
+
+
+
+
+ mdi-vuetify
+
+
+
+
+
+
diff --git a/docs/component/Badge/show_on_hover.py b/docs/component/Badge/show_on_hover.py
new file mode 100644
index 00000000..5b8ea419
--- /dev/null
+++ b/docs/component/Badge/show_on_hover.py
@@ -0,0 +1,18 @@
+import ipyvuetify as v
+
+icon = v.Icon(color="grey lighten-1", large=True, children=["mdi-account"])
+
+badge = v.Badge(
+ value=True,
+ color="deep-purple accent-4",
+ content="9999+",
+ left=True,
+ transition="slide-x-transition",
+ children=[icon],
+)
+
+# Simulate hover with mouse events
+icon.on_event("mouseenter", lambda *args: badge.set("value", True))
+icon.on_event("mouseleave", lambda *args: badge.set("value", False))
+
+v.Container(class_="d-inline-flex justify-center pb-1 pt-5", children=[badge])
diff --git a/docs/component/Badge/show_on_hover.vue b/docs/component/Badge/show_on_hover.vue
new file mode 100644
index 00000000..18a2c5dd
--- /dev/null
+++ b/docs/component/Badge/show_on_hover.vue
@@ -0,0 +1,23 @@
+
+
+
+
+ mdi-account
+
+
+
+
+
+
diff --git a/docs/component/Badge/tabs.py b/docs/component/Badge/tabs.py
new file mode 100644
index 00000000..4abf529c
--- /dev/null
+++ b/docs/component/Badge/tabs.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+v.Toolbar(
+ children=[
+ v.Tabs(
+ dark=True,
+ background_color="primary",
+ grow=True,
+ children=[
+ v.Tab(children=[v.Badge(color="pink", dot=True, children=["Item One"])]),
+ v.Tab(children=[v.Badge(color="green", content="6", children=["Item Two"])]),
+ v.Tab(
+ children=[
+ v.Badge(
+ color="deep-purple accent-4",
+ icon="mdi-language-python",
+ children=["Item Three"],
+ )
+ ]
+ ),
+ ],
+ )
+ ]
+)
diff --git a/docs/component/Badge/tabs.vue b/docs/component/Badge/tabs.vue
new file mode 100644
index 00000000..dfd43648
--- /dev/null
+++ b/docs/component/Badge/tabs.vue
@@ -0,0 +1,19 @@
+
+
+
+
+ Item One
+
+
+
+ Item Two
+
+
+
+
+ Item Three
+
+
+
+
+
diff --git a/docs/component/Badge/usage.py b/docs/component/Badge/usage.py
new file mode 100644
index 00000000..ec802959
--- /dev/null
+++ b/docs/component/Badge/usage.py
@@ -0,0 +1,7 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="text-center mt-2",
+ style_="width: 100%",
+ children=[v.Badge(content="6", children=[v.Icon(large=True, children=["mdi-vuetify"])])],
+)
diff --git a/docs/component/Banner.rst b/docs/component/Banner.rst
new file mode 100644
index 00000000..48f39f79
--- /dev/null
+++ b/docs/component/Banner.rst
@@ -0,0 +1,131 @@
+Banner
+======
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Banner ` component is used as middle-interruptive message to user
+with 1-2 actions. It comes in 2 variations single-line and multi-line (implicit). These can have icons
+which you can use with your message and actions.
+
+.. api::
+
+ :py:class:`ipyvuetify.Banner`
+
+Usage
+-----
+
+Banners can have 1-2 lines of text, actions and icon.
+
+.. jupyter-execute:: Banner/usage.py
+ :raises:
+
+Single line
+-----------
+
+Single-line :py:class:`Banner ` is used for small amount of information and is
+recommended for desktop only implementations. You can optionally enable the ``sticky`` prop to ensure
+the content is pinned to the screen (note: does not work in IE11).
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Banner/single_line.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Banner/single_line.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Banner/single_line.vue
+
+Icon click event
+----------------
+
+:py:class:`Banner ` emits ``click:icon`` event on icon click, even with custom icon slot.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Banner/icon_click_event.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Banner/icon_click_event.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Banner/icon_click_event.vue
+
+Actions slot
+------------
+
+The ``actions`` slot has ``dismiss`` function in its scope, you can use it to easily dismiss banner.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Banner/actions_slot.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Banner/actions_slot.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Banner/actions_slot.vue
+
+Icon slot
+---------
+
+The icon slot allows you to explicitly control the content and functionality within it.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Banner/icon_slot.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Banner/icon_slot.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Banner/icon_slot.vue
+
+Two line
+--------
+
+Two-line :py:class:`Banner ` can store larger amount of data, use it for big messages.
+This is recommended for mobile implementations.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Banner/two_line.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Banner/two_line.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Banner/two_line.vue
+
diff --git a/docs/component/Banner/actions_slot.py b/docs/component/Banner/actions_slot.py
new file mode 100644
index 00000000..39e1fa80
--- /dev/null
+++ b/docs/component/Banner/actions_slot.py
@@ -0,0 +1,33 @@
+import ipyvuetify as v
+
+checkbox = v.Checkbox(v_model=True, label="Visible")
+
+
+def on_dismiss(*args):
+ banner.v_model = False
+ checkbox.v_model = False
+
+
+def on_checkbox_change(widget, event, data):
+ banner.v_model = data
+
+
+checkbox.on_event("change", on_checkbox_change)
+
+banner = v.Banner(
+ v_model=True,
+ single_line=True,
+ transition="slide-y-transition",
+ v_slots=[
+ {
+ "name": "actions",
+ "children": [
+ v.Btn(text=True, color="primary", children=["Dismiss"], on_click=on_dismiss),
+ v.Btn(text=True, color="primary", children=["Retry"]),
+ ],
+ }
+ ],
+ children=["No Internet connection"],
+)
+
+v.Container(children=[checkbox, banner])
diff --git a/docs/component/Banner/actions_slot.vue b/docs/component/Banner/actions_slot.vue
new file mode 100644
index 00000000..56044656
--- /dev/null
+++ b/docs/component/Banner/actions_slot.vue
@@ -0,0 +1,20 @@
+
+
+
+
+ No Internet connection
+
+ Dismiss
+ Retry
+
+
+
+
+
+
diff --git a/docs/component/Banner/icon_click_event.py b/docs/component/Banner/icon_click_event.py
new file mode 100644
index 00000000..bb551add
--- /dev/null
+++ b/docs/component/Banner/icon_click_event.py
@@ -0,0 +1,27 @@
+import ipyvuetify as v
+
+
+def on_icon_click(widget, event, data):
+ print("Icon clicked!")
+
+
+banner = v.Banner(
+ single_line=True,
+ v_slots=[
+ {
+ "name": "icon",
+ "children": v.Icon(
+ color="warning", size=36, children=["mdi-wifi-strength-alert-outline"]
+ ),
+ },
+ {
+ "name": "actions",
+ "children": v.Btn(color="primary", text=True, children=["Connection Settings"]),
+ },
+ ],
+ children=["Unable to verify your Internet connection"],
+)
+
+banner.on_event("click:icon", on_icon_click)
+
+v.Container(children=[banner])
diff --git a/docs/component/Banner/icon_click_event.vue b/docs/component/Banner/icon_click_event.vue
new file mode 100644
index 00000000..2a6a8cc7
--- /dev/null
+++ b/docs/component/Banner/icon_click_event.vue
@@ -0,0 +1,21 @@
+
+
+
+ mdi-wifi-strength-alert-outline
+
+ Unable to verify your Internet connection
+
+ Connection Settings
+
+
+
+
+
diff --git a/docs/component/Banner/icon_slot.py b/docs/component/Banner/icon_slot.py
new file mode 100644
index 00000000..4a461b7b
--- /dev/null
+++ b/docs/component/Banner/icon_slot.py
@@ -0,0 +1,27 @@
+import ipyvuetify as v
+
+v.Banner(
+ two_line=True,
+ v_slots=[
+ {
+ "name": "icon",
+ "children": v.Avatar(
+ color="deep-purple accent-4",
+ size=40,
+ children=[v.Icon(icon="mdi-lock", color="white", children=["mdi-lock"])],
+ ),
+ },
+ {
+ "name": "actions",
+ "children": [
+ v.Btn(text=True, color="deep-purple accent-4", children=["Action"]),
+ v.Btn(text=True, color="deep-purple accent-4", children=["Action"]),
+ ],
+ },
+ ],
+ children=[
+ "Three line text string example with two actions. One to two lines is preferable. "
+ "Three lines should be considered the maximum string length on desktop in order to "
+ "keep messages short and actionable."
+ ],
+)
diff --git a/docs/component/Banner/icon_slot.vue b/docs/component/Banner/icon_slot.vue
new file mode 100644
index 00000000..6e7a3d02
--- /dev/null
+++ b/docs/component/Banner/icon_slot.vue
@@ -0,0 +1,16 @@
+
+
+
+ mdi-lock
+
+
+ Three line text string example with two actions. One to two lines is
+ preferable. Three lines should be considered the maximum string length on
+ desktop in order to keep messages short and actionable.
+
+
+ Action
+ Action
+
+
+
diff --git a/docs/component/Banner/single_line.py b/docs/component/Banner/single_line.py
new file mode 100644
index 00000000..5558b955
--- /dev/null
+++ b/docs/component/Banner/single_line.py
@@ -0,0 +1,40 @@
+import ipyvuetify as v
+
+switch = v.Switch(v_model=False, label="Sticky Banner", hide_details=True)
+
+banner = v.Banner(
+ single_line=True,
+ sticky=False,
+ v_slots=[
+ {
+ "name": "actions",
+ "children": v.Btn(text=True, color="deep-purple accent-4", children=["Get Online"]),
+ }
+ ],
+ children=["We can't save your edits while you are in offline mode."],
+)
+
+
+def update_sticky(widget, event, data):
+ banner.sticky = data
+
+
+switch.on_event("change", update_sticky)
+
+v.Card(
+ children=[
+ v.SystemBar(),
+ v.Toolbar(
+ flat=True,
+ children=[
+ v.ToolbarTitle(children=["My Document"]),
+ v.Spacer(),
+ v.Html(tag="div", children=[switch]),
+ ],
+ ),
+ banner,
+ v.CardText(
+ class_="grey lighten-4", children=[v.Sheet(max_width=800, height=500, class_="mx-auto")]
+ ),
+ ]
+)
diff --git a/docs/component/Banner/single_line.vue b/docs/component/Banner/single_line.vue
new file mode 100644
index 00000000..eba4ae90
--- /dev/null
+++ b/docs/component/Banner/single_line.vue
@@ -0,0 +1,33 @@
+
+
+
+
+ My Document
+
+
+
+
+
+
+ We can't save your edits while you are in offline mode.
+
+ Get Online
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Banner/two_line.py b/docs/component/Banner/two_line.py
new file mode 100644
index 00000000..7692ddfd
--- /dev/null
+++ b/docs/component/Banner/two_line.py
@@ -0,0 +1,17 @@
+import ipyvuetify as v
+
+v.Banner(
+ v_slots=[
+ {
+ "name": "actions",
+ "children": [
+ v.Btn(text=True, color="primary", children=["Dismiss"]),
+ v.Btn(text=True, color="primary", children=["Retry"]),
+ ],
+ }
+ ],
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus nec sem "
+ "id malesuada. Curabitur lacinia sem et turpis euismod, eget elementum ex pretium."
+ ],
+)
diff --git a/docs/component/Banner/two_line.vue b/docs/component/Banner/two_line.vue
new file mode 100644
index 00000000..e4c9be96
--- /dev/null
+++ b/docs/component/Banner/two_line.vue
@@ -0,0 +1,11 @@
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus nec
+ sem id malesuada. Curabitur lacinia sem et turpis euismod, eget elementum ex
+ pretium.
+
+ Dismiss
+ Retry
+
+
+
diff --git a/docs/component/Banner/usage.py b/docs/component/Banner/usage.py
new file mode 100644
index 00000000..350b651a
--- /dev/null
+++ b/docs/component/Banner/usage.py
@@ -0,0 +1,5 @@
+import ipyvuetify as v
+
+v.Container(
+ style_="width: 100%", children=[v.Banner(children=["A banner for use on desktop / mobile"])]
+)
diff --git a/docs/component/BottomNavigation.rst b/docs/component/BottomNavigation.rst
new file mode 100644
index 00000000..fa8f73d9
--- /dev/null
+++ b/docs/component/BottomNavigation.rst
@@ -0,0 +1,184 @@
+BottomNavigation
+================
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`BottomNavigation ` component is an alternative to the sidebar.
+It is primarily used for mobile applications and comes in three variants, icons and text, and shift.
+
+.. api::
+
+ :py:class:`ipyvuetify.BottomNavigation`
+
+Usage
+-----
+
+While :py:class:`BottomNavigation ` is meant to be used with vue-router,
+you can also programmatically control the active state of the buttons by using the ``v_model`` property.
+A button is given a default value of its index with ``v-bottom-navigation``.
+
+.. jupyter-execute:: BottomNavigation/usage.py
+ :raises:
+
+Color
+-----
+
+The ``color`` prop applies a color to the background of the bottom navigation. We recommend using the
+``light`` and ``dark`` props to properly contrast text color.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomNavigation/color.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomNavigation/color.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomNavigation/color.vue
+
+Grow
+----
+
+Using the ``grow`` property forces :py:class:`Btn ` components to fill all available
+space. Buttons have a maximum width of 168px per the Bottom Navigation Material Design specification.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomNavigation/grow.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomNavigation/grow.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomNavigation/grow.vue
+
+Hide on scroll
+--------------
+
+The :py:class:`BottomNavigation ` component hides when scrolling up when
+using the ``hide_on_scroll`` property. This is similar to the scrolling techniques that are supported
+in :py:class:`AppBar `. In the following example, scroll up and down to see this
+behavior.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomNavigation/hide_on_scroll.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomNavigation/hide_on_scroll.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomNavigation/hide_on_scroll.vue
+
+Horizontal
+----------
+
+Adjust the style of buttons and icons by using the ``horizontal`` prop. This positions button text
+inline with the provided :py:class:`Icon `.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomNavigation/horizontal.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomNavigation/horizontal.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomNavigation/horizontal.vue
+
+Scroll threshold
+----------------
+
+Modify the ``scroll_threshold`` property to increase the distance a user must scroll before the
+:py:class:`BottomNavigation ` is hidden.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomNavigation/scroll_threshold.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomNavigation/scroll_threshold.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomNavigation/scroll_threshold.vue
+
+Shift
+-----
+
+The ``shift`` prop hides button text when not active. This provides an alternative visual style to
+the :py:class:`BottomNavigation ` component.
+
+.. note::
+ For this to work, :py:class:`Btn ` text is required to be wrapped in a
+ :py:class:`Html ` `span` tag.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomNavigation/shift.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomNavigation/shift.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomNavigation/shift.vue
+
+Toggle
+------
+
+The display state of :py:class:`BottomNavigation ` can be toggled using
+the ``input_value`` prop. You can also control the currently active button using ``v_model``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomNavigation/toggle.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomNavigation/toggle.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomNavigation/toggle.vue
+
diff --git a/docs/component/BottomNavigation/color.py b/docs/component/BottomNavigation/color.py
new file mode 100644
index 00000000..dc429ba0
--- /dev/null
+++ b/docs/component/BottomNavigation/color.py
@@ -0,0 +1,17 @@
+import ipyvuetify as v
+
+v.BottomNavigation(
+ value=1,
+ color="primary",
+ children=[
+ v.Btn(
+ children=[v.Html(tag="span", children=["Recents"]), v.Icon(children=["mdi-history"])]
+ ),
+ v.Btn(
+ children=[v.Html(tag="span", children=["Favorites"]), v.Icon(children=["mdi-heart"])]
+ ),
+ v.Btn(
+ children=[v.Html(tag="span", children=["Nearby"]), v.Icon(children=["mdi-map-marker"])]
+ ),
+ ],
+)
diff --git a/docs/component/BottomNavigation/color.vue b/docs/component/BottomNavigation/color.vue
new file mode 100644
index 00000000..7b20ed46
--- /dev/null
+++ b/docs/component/BottomNavigation/color.vue
@@ -0,0 +1,22 @@
+
+
+
+ Recents
+ mdi-history
+
+
+ Favorites
+ mdi-heart
+
+
+ Nearby
+ mdi-map-marker
+
+
+
+
+
diff --git a/docs/component/BottomNavigation/grow.py b/docs/component/BottomNavigation/grow.py
new file mode 100644
index 00000000..58a58e61
--- /dev/null
+++ b/docs/component/BottomNavigation/grow.py
@@ -0,0 +1,18 @@
+import ipyvuetify as v
+
+v.BottomNavigation(
+ value=1,
+ color="teal",
+ grow=True,
+ children=[
+ v.Btn(
+ children=[v.Html(tag="span", children=["Recents"]), v.Icon(children=["mdi-history"])]
+ ),
+ v.Btn(
+ children=[v.Html(tag="span", children=["Favorites"]), v.Icon(children=["mdi-heart"])]
+ ),
+ v.Btn(
+ children=[v.Html(tag="span", children=["Nearby"]), v.Icon(children=["mdi-map-marker"])]
+ ),
+ ],
+)
diff --git a/docs/component/BottomNavigation/grow.vue b/docs/component/BottomNavigation/grow.vue
new file mode 100644
index 00000000..8a4b0a85
--- /dev/null
+++ b/docs/component/BottomNavigation/grow.vue
@@ -0,0 +1,22 @@
+
+
+
+ Recents
+ mdi-history
+
+
+ Favorites
+ mdi-heart
+
+
+ Nearby
+ mdi-map-marker
+
+
+
+
+
diff --git a/docs/component/BottomNavigation/hide_on_scroll.py b/docs/component/BottomNavigation/hide_on_scroll.py
new file mode 100644
index 00000000..f9655614
--- /dev/null
+++ b/docs/component/BottomNavigation/hide_on_scroll.py
@@ -0,0 +1,48 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="overflow-hidden my-2 mx-auto",
+ border=True,
+ height=200,
+ width=500,
+ children=[
+ v.Responsive(
+ id="hide-on-scroll-example",
+ class_="overflow-y-auto",
+ max_height=600,
+ children=[v.Responsive(height=1500)],
+ ),
+ v.BottomNavigation(
+ absolute=True,
+ hide_on_scroll=True,
+ horizontal=True,
+ scroll_target="#hide-on-scroll-example",
+ children=[
+ v.Btn(
+ color="deep-purple accent-4",
+ text=True,
+ children=[
+ v.Html(tag="span", children=["Recents"]),
+ v.Icon(children=["mdi-history"]),
+ ],
+ ),
+ v.Btn(
+ color="deep-purple accent-4",
+ text=True,
+ children=[
+ v.Html(tag="span", children=["Favorites"]),
+ v.Icon(children=["mdi-heart"]),
+ ],
+ ),
+ v.Btn(
+ color="deep-purple accent-4",
+ text=True,
+ children=[
+ v.Html(tag="span", children=["Nearby"]),
+ v.Icon(children=["mdi-map-marker"]),
+ ],
+ ),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/BottomNavigation/hide_on_scroll.vue b/docs/component/BottomNavigation/hide_on_scroll.vue
new file mode 100644
index 00000000..af401066
--- /dev/null
+++ b/docs/component/BottomNavigation/hide_on_scroll.vue
@@ -0,0 +1,31 @@
+
+
+
+
+ Recents
+ mdi-history
+
+
+ Favorites
+ mdi-heart
+
+
+ Nearby
+ mdi-map-marker
+
+
+
+
+
+
+
+
diff --git a/docs/component/BottomNavigation/horizontal.py b/docs/component/BottomNavigation/horizontal.py
new file mode 100644
index 00000000..f5aa2ea0
--- /dev/null
+++ b/docs/component/BottomNavigation/horizontal.py
@@ -0,0 +1,18 @@
+import ipyvuetify as v
+
+v.BottomNavigation(
+ value=1,
+ color="primary",
+ horizontal=True,
+ children=[
+ v.Btn(
+ children=[v.Html(tag="span", children=["Recents"]), v.Icon(children=["mdi-history"])]
+ ),
+ v.Btn(
+ children=[v.Html(tag="span", children=["Favorites"]), v.Icon(children=["mdi-heart"])]
+ ),
+ v.Btn(
+ children=[v.Html(tag="span", children=["Nearby"]), v.Icon(children=["mdi-map-marker"])]
+ ),
+ ],
+)
diff --git a/docs/component/BottomNavigation/horizontal.vue b/docs/component/BottomNavigation/horizontal.vue
new file mode 100644
index 00000000..5a381d88
--- /dev/null
+++ b/docs/component/BottomNavigation/horizontal.vue
@@ -0,0 +1,22 @@
+
+
+
+ Recents
+ mdi-history
+
+
+ Favorites
+ mdi-heart
+
+
+ Nearby
+ mdi-map-marker
+
+
+
+
+
diff --git a/docs/component/BottomNavigation/scroll_threshold.py b/docs/component/BottomNavigation/scroll_threshold.py
new file mode 100644
index 00000000..df79160f
--- /dev/null
+++ b/docs/component/BottomNavigation/scroll_threshold.py
@@ -0,0 +1,43 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="mx-auto overflow-hidden my-2",
+ height=200,
+ width=500,
+ children=[
+ v.BottomNavigation(
+ absolute=True,
+ color="white",
+ hide_on_scroll=True,
+ horizontal=True,
+ scroll_target="#scroll-threshold-example",
+ scroll_threshold=500,
+ children=[
+ v.Btn(
+ children=[
+ v.Html(tag="span", children=["Recents"]),
+ v.Icon(children=["mdi-history"]),
+ ]
+ ),
+ v.Btn(
+ children=[
+ v.Html(tag="span", children=["Favorites"]),
+ v.Icon(children=["mdi-heart"]),
+ ]
+ ),
+ v.Btn(
+ children=[
+ v.Html(tag="span", children=["Nearby"]),
+ v.Icon(children=["mdi-map-marker"]),
+ ]
+ ),
+ ],
+ ),
+ v.Sheet(
+ id="scroll-threshold-example",
+ class_="overflow-y-auto pb-16",
+ max_height=600,
+ children=[v.Responsive(height=1500)],
+ ),
+ ],
+)
diff --git a/docs/component/BottomNavigation/scroll_threshold.vue b/docs/component/BottomNavigation/scroll_threshold.vue
new file mode 100644
index 00000000..74aa2f9a
--- /dev/null
+++ b/docs/component/BottomNavigation/scroll_threshold.vue
@@ -0,0 +1,32 @@
+
+
+
+
+ Recents
+ mdi-history
+
+
+ Favorites
+ mdi-heart
+
+
+ Nearby
+ mdi-map-marker
+
+
+
+
+
+
+
diff --git a/docs/component/BottomNavigation/shift.py b/docs/component/BottomNavigation/shift.py
new file mode 100644
index 00000000..81e1884d
--- /dev/null
+++ b/docs/component/BottomNavigation/shift.py
@@ -0,0 +1,33 @@
+import ipyvuetify as v
+
+colors = ["blue-grey", "teal", "brown", "indigo"]
+
+bottom_nav = v.BottomNavigation(
+ v_model=1,
+ background_color=colors[1],
+ dark=True,
+ shift=True,
+ children=[
+ v.Btn(
+ children=[
+ v.Html(tag="span", children=["Video"]),
+ v.Icon(children=["mdi-television-play"]),
+ ]
+ ),
+ v.Btn(
+ children=[v.Html(tag="span", children=["Music"]), v.Icon(children=["mdi-music-note"])]
+ ),
+ v.Btn(children=[v.Html(tag="span", children=["Book"]), v.Icon(children=["mdi-book"])]),
+ v.Btn(children=[v.Html(tag="span", children=["Image"]), v.Icon(children=["mdi-image"])]),
+ ],
+)
+
+
+def update_color(widget, event, data):
+ if data < len(colors):
+ bottom_nav.background_color = colors[data]
+
+
+bottom_nav.on_event("change", update_color)
+
+v.Container(children=[bottom_nav])
diff --git a/docs/component/BottomNavigation/shift.vue b/docs/component/BottomNavigation/shift.vue
new file mode 100644
index 00000000..c8fade31
--- /dev/null
+++ b/docs/component/BottomNavigation/shift.vue
@@ -0,0 +1,42 @@
+
+
+
+ Video
+ mdi-television-play
+
+
+ Music
+ mdi-music-note
+
+
+ Book
+ mdi-book
+
+
+ Image
+ mdi-image
+
+
+
+
+
diff --git a/docs/component/BottomNavigation/toggle.py b/docs/component/BottomNavigation/toggle.py
new file mode 100644
index 00000000..36ea42b1
--- /dev/null
+++ b/docs/component/BottomNavigation/toggle.py
@@ -0,0 +1,40 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+toggle_btn = v.Btn(
+ color="deep-purple",
+ outlined=True,
+ children=["Toggle Navigation"],
+ v_model=True,
+)
+
+bottom_nav = v.BottomNavigation(
+ v_model=True,
+ input_value=True,
+ color="indigo",
+ children=[
+ v.Btn(
+ children=[v.Html(tag="span", children=["Recents"]), v.Icon(children=["mdi-history"])]
+ ),
+ v.Btn(
+ children=[v.Html(tag="span", children=["Favorites"]), v.Icon(children=["mdi-heart"])]
+ ),
+ v.Btn(
+ children=[v.Html(tag="span", children=["Nearby"]), v.Icon(children=["mdi-map-marker"])]
+ ),
+ ],
+)
+
+
+def toggle_navigation(widget, event, data):
+ bottom_nav.v_model = not widget.v_model
+
+
+toggle_btn.on_event("click", toggle_navigation)
+jslink((toggle_btn, "v_model"), (bottom_nav, "v_model"))
+
+v.Container(
+ class_="overflow-hidden",
+ children=[v.Html(tag="div", class_="text-center mb-8", children=[toggle_btn]), bottom_nav],
+)
diff --git a/docs/component/BottomNavigation/toggle.vue b/docs/component/BottomNavigation/toggle.vue
new file mode 100644
index 00000000..acd0bb46
--- /dev/null
+++ b/docs/component/BottomNavigation/toggle.vue
@@ -0,0 +1,35 @@
+
+
+
+
+ Toggle Navigation
+
+
+
+
+
+ Recents
+ mdi-history
+
+
+ Favorites
+ mdi-heart
+
+
+ Nearby
+ mdi-map-marker
+
+
+
+
+
+
diff --git a/docs/component/BottomNavigation/usage.py b/docs/component/BottomNavigation/usage.py
new file mode 100644
index 00000000..7aafad46
--- /dev/null
+++ b/docs/component/BottomNavigation/usage.py
@@ -0,0 +1,21 @@
+import ipyvuetify as v
+
+bottom_nav = v.BottomNavigation(
+ v_model="recent",
+ children=[
+ v.Btn(
+ value="recent",
+ children=[v.Html(tag="span", children=["Recent"]), v.Icon(children=["mdi-history"])],
+ ),
+ v.Btn(
+ value="favorites",
+ children=[v.Html(tag="span", children=["Favorites"]), v.Icon(children=["mdi-heart"])],
+ ),
+ v.Btn(
+ value="nearby",
+ children=[v.Html(tag="span", children=["Nearby"]), v.Icon(children=["mdi-map-marker"])],
+ ),
+ ],
+)
+
+v.Container(children=[bottom_nav])
diff --git a/docs/component/BottomSheet.rst b/docs/component/BottomSheet.rst
new file mode 100644
index 00000000..844180df
--- /dev/null
+++ b/docs/component/BottomSheet.rst
@@ -0,0 +1,126 @@
+BottomSheet
+===========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The bottom sheet is a modified :py:class:`Dialog ` that slides from the bottom of the screen, similar to a :py:class:`BottomNavigation `. Whereas a bottom navigation component is for buttons and specific application level actions, a bottom sheet can contain anything.
+
+.. api::
+
+ :py:class:`ipyvuetify.BottomSheet`
+
+Usage
+-----
+
+Here we display an example list of actions that could be present in an application.
+
+.. jupyter-execute:: BottomSheet/usage.py
+ :raises:
+
+Inset
+-----
+
+Bottom sheets can be inset, reducing their maximum width on desktop to 70%. This can be further reduced manually using the ``width`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomSheet/inset.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomSheet/inset.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomSheet/inset.vue
+
+Model
+-----
+
+Bottom sheets can be controlled using ``v_model``. You can use it to close them or if you can't use ``activator`` slot.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomSheet/model.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomSheet/model.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomSheet/model.vue
+
+Persistent
+----------
+
+Persistent bottom sheets can't be closed by clicking outside them.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomSheet/persistent.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomSheet/persistent.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomSheet/persistent.vue
+
+Music Player
+------------
+
+Using a inset bottom sheet, you can make practical components such as this simple music player.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomSheet/music_player.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomSheet/music_player.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomSheet/music_player.vue
+
+Open In List
+------------
+
+By combining a functional list into a bottom sheet, you can create a simple 'open in' component.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BottomSheet/open_in_list.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BottomSheet/open_in_list.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BottomSheet/open_in_list.vue
+
diff --git a/docs/component/BottomSheet/inset.py b/docs/component/BottomSheet/inset.py
new file mode 100644
index 00000000..85d97bd6
--- /dev/null
+++ b/docs/component/BottomSheet/inset.py
@@ -0,0 +1,33 @@
+import ipyvuetify as v
+
+close_btn = v.Btn(class_="mt-6", text=True, color="error", children=["close"])
+
+bottom_sheet = v.BottomSheet(
+ v_model=False,
+ inset=True,
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "x",
+ "children": v.Btn(color="orange", dark=True, children=["Open Inset"]),
+ }
+ ],
+ children=[
+ v.Sheet(
+ class_="text-center",
+ height="200px",
+ children=[
+ close_btn,
+ v.Html(
+ tag="div",
+ class_="my-3",
+ children=["This is a bottom sheet using the inset prop"],
+ ),
+ ],
+ )
+ ],
+)
+
+close_btn.on_event("click", lambda *args: setattr(bottom_sheet, "v_model", False))
+
+v.Container(class_="text-center", children=[bottom_sheet])
diff --git a/docs/component/BottomSheet/inset.vue b/docs/component/BottomSheet/inset.vue
new file mode 100644
index 00000000..3afa29aa
--- /dev/null
+++ b/docs/component/BottomSheet/inset.vue
@@ -0,0 +1,23 @@
+
+
+
+
+ Open Inset
+
+
+
+ close
+
+ This is a bottom sheet using the inset prop
+
+
+
+
+
+
diff --git a/docs/component/BottomSheet/model.py b/docs/component/BottomSheet/model.py
new file mode 100644
index 00000000..4be808e8
--- /dev/null
+++ b/docs/component/BottomSheet/model.py
@@ -0,0 +1,35 @@
+import ipyvuetify as v
+
+open_btn = v.Btn(color="blue", dark=True, children=["Open v-model"])
+
+close_btn = v.Btn(class_="mt-6", text=True, color="red", children=["close"])
+
+bottom_sheet = v.BottomSheet(
+ v_model=False,
+ children=[
+ v.Sheet(
+ class_="text-center",
+ height="200px",
+ children=[
+ close_btn,
+ v.Html(
+ tag="div",
+ class_="py-3",
+ children=[
+ "This is a bottom sheet using the controlled by v-model instead of activator"
+ ],
+ ),
+ ],
+ )
+ ],
+)
+
+
+def toggle_sheet(*args):
+ bottom_sheet.v_model = not bottom_sheet.v_model
+
+
+open_btn.on_event("click", toggle_sheet)
+close_btn.on_event("click", toggle_sheet)
+
+v.Container(class_="text-center", children=[open_btn, bottom_sheet])
diff --git a/docs/component/BottomSheet/model.vue b/docs/component/BottomSheet/model.vue
new file mode 100644
index 00000000..fd227dae
--- /dev/null
+++ b/docs/component/BottomSheet/model.vue
@@ -0,0 +1,24 @@
+
+
+
Open v-model
+
+
+
+ close
+
+
+ This is a bottom sheet using the controlled by v-model instead of
+ activator
+
+
+
+
+
+
+
diff --git a/docs/component/BottomSheet/music_player.py b/docs/component/BottomSheet/music_player.py
new file mode 100644
index 00000000..2afd930a
--- /dev/null
+++ b/docs/component/BottomSheet/music_player.py
@@ -0,0 +1,69 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="text-center",
+ children=[
+ v.BottomSheet(
+ inset=True,
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "x",
+ "children": v.Btn(color="red", dark=True, children=["Open Player"]),
+ }
+ ],
+ children=[
+ v.Card(
+ tile=True,
+ children=[
+ v.ProgressLinear(value=50, class_="my-0", height=3),
+ v.List(
+ children=[
+ v.ListItem(
+ children=[
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(children=["The Walker"]),
+ v.ListItemSubtitle(
+ children=["Fitz & The Trantrums"]
+ ),
+ ]
+ ),
+ v.Spacer(),
+ v.ListItemIcon(
+ children=[
+ v.Btn(
+ icon=True,
+ children=[v.Icon(children=["mdi-rewind"])],
+ )
+ ]
+ ),
+ v.ListItemIcon(
+ children=[
+ v.Btn(
+ icon=True,
+ children=[v.Icon(children=["mdi-pause"])],
+ )
+ ]
+ ),
+ v.ListItemIcon(
+ class_="ml-0",
+ children=[
+ v.Btn(
+ icon=True,
+ children=[
+ v.Icon(children=["mdi-fast-forward"])
+ ],
+ )
+ ],
+ ),
+ ]
+ )
+ ]
+ ),
+ ],
+ )
+ ],
+ )
+ ],
+)
diff --git a/docs/component/BottomSheet/music_player.vue b/docs/component/BottomSheet/music_player.vue
new file mode 100644
index 00000000..78b82067
--- /dev/null
+++ b/docs/component/BottomSheet/music_player.vue
@@ -0,0 +1,47 @@
+
+
+
+
+ Open Player
+
+
+
+
+
+
+
+ The Walker
+ Fitz and The Trantrums
+
+
+
+
+
+
+ mdi-rewind
+
+
+
+
+
+ mdi-pause
+
+
+
+
+
+ mdi-fast-forward
+
+
+
+
+
+
+
+
diff --git a/docs/component/BottomSheet/open_in_list.py b/docs/component/BottomSheet/open_in_list.py
new file mode 100644
index 00000000..bc0be54c
--- /dev/null
+++ b/docs/component/BottomSheet/open_in_list.py
@@ -0,0 +1,49 @@
+import ipyvuetify as v
+
+tiles = [
+ {"img": "keep.png", "title": "Keep"},
+ {"img": "inbox.png", "title": "Inbox"},
+ {"img": "hangouts.png", "title": "Hangouts"},
+ {"img": "messenger.png", "title": "Messenger"},
+ {"img": "google.png", "title": "Google+"},
+]
+
+bottom_sheet = v.BottomSheet(
+ v_model=False,
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "x",
+ "children": v.Btn(color="purple", dark=True, children=["Open In"]),
+ }
+ ],
+ children=[v.List(children=[v.Subheader(children=["Open in"])])],
+)
+
+list_items = []
+for tile in tiles:
+ item = v.ListItem(
+ children=[
+ v.ListItemAvatar(
+ children=[
+ v.Avatar(
+ size=32,
+ tile=True,
+ children=[
+ v.Img(
+ src=f"https://cdn.vuetifyjs.com/images/bottom-sheets/{tile['img']}",
+ alt=tile["title"],
+ )
+ ],
+ )
+ ]
+ ),
+ v.ListItemTitle(children=[tile["title"]]),
+ ]
+ )
+
+ item.on_event("click", lambda *args: setattr(bottom_sheet, "v_model", False))
+ list_items.append(item)
+
+bottom_sheet.children[0].children.extend(list_items)
+v.Container(class_="text-center", children=[bottom_sheet])
diff --git a/docs/component/BottomSheet/open_in_list.vue b/docs/component/BottomSheet/open_in_list.vue
new file mode 100644
index 00000000..aacdf720
--- /dev/null
+++ b/docs/component/BottomSheet/open_in_list.vue
@@ -0,0 +1,42 @@
+
+
+
+
+ Open In
+
+
+ Open in
+
+
+
+
+
+
+ {{ tile.title }}
+
+
+
+
+
+
+
diff --git a/docs/component/BottomSheet/persistent.py b/docs/component/BottomSheet/persistent.py
new file mode 100644
index 00000000..739ace50
--- /dev/null
+++ b/docs/component/BottomSheet/persistent.py
@@ -0,0 +1,33 @@
+import ipyvuetify as v
+
+close_btn = v.Btn(class_="mt-6", text=True, color="error", children=["close"])
+
+bottom_sheet = v.BottomSheet(
+ v_model=False,
+ persistent=True,
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "x",
+ "children": v.Btn(color="green", dark=True, children=["Open Persistent"]),
+ }
+ ],
+ children=[
+ v.Sheet(
+ class_="text-center",
+ height="200px",
+ children=[
+ close_btn,
+ v.Html(
+ tag="div",
+ class_="py-3",
+ children=["This is a bottom sheet using the persistent prop"],
+ ),
+ ],
+ )
+ ],
+)
+
+close_btn.on_event("click", lambda *args: setattr(bottom_sheet, "v_model", False))
+
+v.Container(class_="text-center", children=[bottom_sheet])
diff --git a/docs/component/BottomSheet/persistent.vue b/docs/component/BottomSheet/persistent.vue
new file mode 100644
index 00000000..6ecd8810
--- /dev/null
+++ b/docs/component/BottomSheet/persistent.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+ Open Persistent
+
+
+
+
+ close
+
+ This is a bottom sheet using the persistent prop
+
+
+
+
+
+
diff --git a/docs/component/BottomSheet/usage.py b/docs/component/BottomSheet/usage.py
new file mode 100644
index 00000000..4b71ff1d
--- /dev/null
+++ b/docs/component/BottomSheet/usage.py
@@ -0,0 +1,22 @@
+import ipyvuetify as v
+
+close_btn = v.Btn(class_="my-6", depressed=True, color="error", children=["close"])
+
+bottom_sheet = v.BottomSheet(
+ v_model=False,
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "x",
+ "children": v.Btn(color="purple", dark=True, children=["Open Playground"]),
+ }
+ ],
+ children=[v.Sheet(class_="text-center", height="200px", children=[close_btn])],
+)
+
+close_btn.on_event("click", lambda *args: setattr(bottom_sheet, "v_model", False))
+
+v.Container(
+ class_="fill-height",
+ children=[v.Row(align="center", justify="center", children=[bottom_sheet])],
+)
diff --git a/docs/component/Breadcrumbs.rst b/docs/component/Breadcrumbs.rst
new file mode 100644
index 00000000..dac6be7f
--- /dev/null
+++ b/docs/component/Breadcrumbs.rst
@@ -0,0 +1,129 @@
+Breadcrumbs
+===========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Breadcrumbs ` component is a navigational helper for pages.
+It can accept a Material Icons icon or text characters as a divider. An array of objects can be passed
+to the ``items`` property of the component. Additionally, slots exists for more control of the breadcrumbs,
+either utilizing :py:class:`BreadcrumbsItem ` or other custom markup.
+
+.. api::
+
+ - :py:class:`ipyvuetify.Breadcrumbs`
+ - :py:class:`ipyvuetify.BreadcrumbsItem`
+ - :py:class:`ipyvuetify.BreadcrumbsDivider`
+
+.. note:: Caveat
+
+ By default v-breadcrumbs will disable all crumbs up to the current page in a nested paths.
+ You can prevent this behavior by using exact: true on each applicable breadcrumb in the
+ items array.
+
+Usage
+-----
+
+By default, breadcrumbs use a text divider. This can be any string.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Breadcrumbs/usage.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Breadcrumbs/usage.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Breadcrumbs/usage.vue
+
+Divider
+-------
+
+Breadcrumbs separator can be set using ``divider`` property.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Breadcrumbs/divider.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Breadcrumbs/divider.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Breadcrumbs/divider.vue
+
+Large
+-----
+
+Large breadcrumbs have larger font size.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Breadcrumbs/large.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Breadcrumbs/large.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Breadcrumbs/large.vue
+
+Icon Dividers
+-------------
+
+For the icon variant, breadcrumbs can use any icon in Material Design Icons.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Breadcrumbs/icon_dividers.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Breadcrumbs/icon_dividers.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Breadcrumbs/icon_dividers.vue
+
+Item
+----
+
+You can use the ``item`` slot to customize each breadcrumb.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Breadcrumbs/item.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Breadcrumbs/item.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Breadcrumbs/item.vue
+
diff --git a/docs/component/Breadcrumbs/divider.py b/docs/component/Breadcrumbs/divider.py
new file mode 100644
index 00000000..72606ba5
--- /dev/null
+++ b/docs/component/Breadcrumbs/divider.py
@@ -0,0 +1,14 @@
+import ipyvuetify as v
+
+items = [
+ {"text": "Dashboard", "disabled": False, "href": "breadcrumbs_dashboard"},
+ {"text": "Link 1", "disabled": False, "href": "breadcrumbs_link_1"},
+ {"text": "Link 2", "disabled": True, "href": "breadcrumbs_link_2"},
+]
+
+v.Container(
+ children=[
+ v.Breadcrumbs(items=items, divider="."),
+ v.Breadcrumbs(items=items, divider="-"),
+ ]
+)
diff --git a/docs/component/Breadcrumbs/divider.vue b/docs/component/Breadcrumbs/divider.vue
new file mode 100644
index 00000000..3e010ec4
--- /dev/null
+++ b/docs/component/Breadcrumbs/divider.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
+
diff --git a/docs/component/Breadcrumbs/icon_dividers.py b/docs/component/Breadcrumbs/icon_dividers.py
new file mode 100644
index 00000000..55f9319a
--- /dev/null
+++ b/docs/component/Breadcrumbs/icon_dividers.py
@@ -0,0 +1,11 @@
+import ipyvuetify as v
+
+items = [
+ {"text": "Dashboard", "disabled": False, "href": "breadcrumbs_dashboard"},
+ {"text": "Link 1", "disabled": False, "href": "breadcrumbs_link_1"},
+ {"text": "Link 2", "disabled": True, "href": "breadcrumbs_link_2"},
+]
+
+v.Breadcrumbs(
+ items=items, v_slots=[{"name": "divider", "children": v.Icon(children=["mdi-forward"])}]
+)
diff --git a/docs/component/Breadcrumbs/icon_dividers.vue b/docs/component/Breadcrumbs/icon_dividers.vue
new file mode 100644
index 00000000..12814e93
--- /dev/null
+++ b/docs/component/Breadcrumbs/icon_dividers.vue
@@ -0,0 +1,31 @@
+
+
+
+ mdi-forward
+
+
+
+
+
diff --git a/docs/component/Breadcrumbs/item.py b/docs/component/Breadcrumbs/item.py
new file mode 100644
index 00000000..83944142
--- /dev/null
+++ b/docs/component/Breadcrumbs/item.py
@@ -0,0 +1,21 @@
+import ipyvuetify as v
+
+items = [
+ {"text": "Dashboard", "disabled": False, "href": "breadcrumbs_dashboard"},
+ {"text": "Link 1", "disabled": False, "href": "breadcrumbs_link_1"},
+ {"text": "Link 2", "disabled": True, "href": "breadcrumbs_link_2"},
+]
+
+v.Breadcrumbs(
+ items=items,
+ v_slots=[
+ {
+ "name": "item",
+ "variable": "props",
+ "children": v.BreadcrumbsItem(
+ v_bind="props",
+ children=[v.Html(tag="span", children=["{{ props.item.text.toUpperCase() }}"])],
+ ),
+ }
+ ],
+)
diff --git a/docs/component/Breadcrumbs/item.vue b/docs/component/Breadcrumbs/item.vue
new file mode 100644
index 00000000..d6ee3fb3
--- /dev/null
+++ b/docs/component/Breadcrumbs/item.vue
@@ -0,0 +1,33 @@
+
+
+
+
+ {{ item.text.toUpperCase() }}
+
+
+
+
+
+
diff --git a/docs/component/Breadcrumbs/large.py b/docs/component/Breadcrumbs/large.py
new file mode 100644
index 00000000..059d6ac4
--- /dev/null
+++ b/docs/component/Breadcrumbs/large.py
@@ -0,0 +1,9 @@
+import ipyvuetify as v
+
+items = [
+ {"text": "Dashboard", "disabled": False, "href": "breadcrumbs_dashboard"},
+ {"text": "Link 1", "disabled": False, "href": "breadcrumbs_link_1"},
+ {"text": "Link 2", "disabled": True, "href": "breadcrumbs_link_2"},
+]
+
+v.Container(children=[v.Breadcrumbs(items=items), v.Breadcrumbs(items=items, large=True)])
diff --git a/docs/component/Breadcrumbs/large.vue b/docs/component/Breadcrumbs/large.vue
new file mode 100644
index 00000000..eb75ae05
--- /dev/null
+++ b/docs/component/Breadcrumbs/large.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
diff --git a/docs/component/Breadcrumbs/usage.py b/docs/component/Breadcrumbs/usage.py
new file mode 100644
index 00000000..ca1d8431
--- /dev/null
+++ b/docs/component/Breadcrumbs/usage.py
@@ -0,0 +1,9 @@
+import ipyvuetify as v
+
+items = [
+ {"text": "Dashboard", "disabled": False, "href": "breadcrumbs_dashboard"},
+ {"text": "Link 1", "disabled": False, "href": "breadcrumbs_link_1"},
+ {"text": "Link 2", "disabled": True, "href": "breadcrumbs_link_2"},
+]
+
+v.Breadcrumbs(items=items)
diff --git a/docs/component/Breadcrumbs/usage.vue b/docs/component/Breadcrumbs/usage.vue
new file mode 100644
index 00000000..8b9d65fc
--- /dev/null
+++ b/docs/component/Breadcrumbs/usage.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/docs/component/Btn.rst b/docs/component/Btn.rst
new file mode 100644
index 00000000..1a6b4a71
--- /dev/null
+++ b/docs/component/Btn.rst
@@ -0,0 +1,298 @@
+Btn
+===
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Btn documentation
+ `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Btn ` component replaces the standard html button with a material
+design theme and many configurable options. Any color helper class can be used to alter background
+or text color.
+
+.. api::
+
+ - :py:class:`ipyvuetify.Btn`
+ - :py:class:`ipyvuetify.BtnToggle`
+
+.. seealso::
+
+ :doc:`BtnToggle`
+
+Usage
+-----
+
+Buttons in their simplest form contain uppercase text, a slight elevation, hover effect, and a
+ripple effect on click.
+
+.. jupyter-execute:: Btn/usage.py
+ :raises:
+
+Block
+-----
+
+``block`` buttons extend the full available width.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/block.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/block.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/block.vue
+
+Depressed
+---------
+
+``depressed`` buttons maintain their background color but have no box shadow.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/depressed.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/depressed.py
+
+ .. tab-item:: :fab:`vuejs` Vue templates
+
+ .. literalinclude:: Btn/depressed.vue
+
+Floating / FAB
+--------------
+
+Floating action buttons (FAB) are circular and typically contain an icon. Use ``fab`` and size props.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/floating_fab.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/floating_fab.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/floating_fab.vue
+
+Icon
+----
+
+Buttons can be used as icon-only controls. This makes the button rounded and applies text styles.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/icon.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/icon.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/icon.vue
+
+Loaders
+-------
+
+Using the loading prop, you can notify a user that there is processing taking place. The default
+behavior is to use a :py:class:`ProgressBar ` component but this can be
+customized.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/loaders.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/loaders.py
+
+ .. tab-item:: :fab:`css3` css
+
+ .. code-block:: css
+
+ @keyframes spin {
+ to { transform: rotate(360deg); }
+ }
+
+ .custom-loader {
+ display: flex;
+ animation: spin 1s linear infinite;
+ }
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/loaders.vue
+
+Outlined
+--------
+
+``outlined`` buttons inherit their borders from the current color applied.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/outlined.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/outlined.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/outlined.vue
+
+Plain
+-----
+
+**plain** buttons have a lower baseline opacity that reacts to **hover** and **focus**.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/plain.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/plain.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/plain.vue
+
+Rounded
+-------
+
+``rounded`` buttons behave the same as regular buttons but have rounded edges.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/rounded.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/rounded.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/rounded.vue
+
+sizing
+------
+
+Buttons can be given different sizing options to fit a multitude of scenarios.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/sizing.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/sizing.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/sizing.vue
+
+Text
+----
+
+Text buttons have no box shadow and no background. Only on hover is the container for the button shown.
+When used with the color prop, the supplied color is applied to the button text instead of the background.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/text.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/text.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/text.vue
+
+Tile
+----
+
+**tile** buttons behave the same as regular buttons but have no border radius.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/tile.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/tile.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/tile.vue
+
+Raised
+------
+
+**raised** buttons have a box shadow that increases when clicked. This is the default style.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Btn/raised.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Btn/raised.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Btn/raised.vue
+
diff --git a/docs/component/Btn/block.py b/docs/component/Btn/block.py
new file mode 100644
index 00000000..b1757d99
--- /dev/null
+++ b/docs/component/Btn/block.py
@@ -0,0 +1,7 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Btn(block=True, class_="mb-2", children=["Block Button"]),
+ ]
+)
diff --git a/docs/component/Btn/block.vue b/docs/component/Btn/block.vue
new file mode 100644
index 00000000..1a46cf37
--- /dev/null
+++ b/docs/component/Btn/block.vue
@@ -0,0 +1,3 @@
+
+ Block Button
+
diff --git a/docs/component/Btn/depressed.py b/docs/component/Btn/depressed.py
new file mode 100644
index 00000000..dc89d05a
--- /dev/null
+++ b/docs/component/Btn/depressed.py
@@ -0,0 +1,10 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Btn(depressed=True, children=["Normal"], class_="mx-2"),
+ v.Btn(depressed=True, color="primary", children=["Primary"], class_="mx-2"),
+ v.Btn(depressed=True, color="error", children=["Error"], class_="mx-2"),
+ v.Btn(depressed=True, disabled=True, children=["Disabled"], class_="mx-2"),
+ ]
+)
diff --git a/docs/component/Btn/depressed.vue b/docs/component/Btn/depressed.vue
new file mode 100644
index 00000000..dc55161b
--- /dev/null
+++ b/docs/component/Btn/depressed.vue
@@ -0,0 +1,8 @@
+
+
+ Normal
+ Primary
+ Error
+ Disabled
+
+
diff --git a/docs/component/Btn/floating_fab.py b/docs/component/Btn/floating_fab.py
new file mode 100644
index 00000000..17a084ac
--- /dev/null
+++ b/docs/component/Btn/floating_fab.py
@@ -0,0 +1,45 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Btn(
+ fab=True,
+ dark=True,
+ small=True,
+ color="primary",
+ children=[v.Icon(dark=True, children=["mdi-minus"])],
+ class_="mx-2",
+ ),
+ v.Btn(
+ fab=True,
+ dark=True,
+ small=True,
+ color="pink",
+ children=[v.Icon(dark=True, children=["mdi-heart"])],
+ class_="mx-2",
+ ),
+ v.Btn(
+ fab=True,
+ dark=True,
+ color="indigo",
+ children=[v.Icon(dark=True, children=["mdi-plus"])],
+ class_="mx-2",
+ ),
+ v.Btn(
+ fab=True,
+ dark=True,
+ large=True,
+ color="cyan",
+ children=[v.Icon(dark=True, children=["mdi-pencil"])],
+ class_="mx-2",
+ ),
+ v.Btn(
+ fab=True,
+ dark=True,
+ large=True,
+ color="purple",
+ children=[v.Icon(dark=True, children=["mdi-android"])],
+ class_="mx-2",
+ ),
+ ]
+)
diff --git a/docs/component/Btn/floating_fab.vue b/docs/component/Btn/floating_fab.vue
new file mode 100644
index 00000000..b31ebd59
--- /dev/null
+++ b/docs/component/Btn/floating_fab.vue
@@ -0,0 +1,17 @@
+
+ mdi-minus
+ mdi-heart
+ mdi-plus
+ mdi-pencil
+ mdi-android
+
diff --git a/docs/component/Btn/icon.py b/docs/component/Btn/icon.py
new file mode 100644
index 00000000..4df1067f
--- /dev/null
+++ b/docs/component/Btn/icon.py
@@ -0,0 +1,116 @@
+import ipyvuetify as v
+
+v.Card(
+ flat=True,
+ children=[
+ v.CardText(
+ children=[
+ v.Container(
+ fluid=True,
+ class_="pa-0",
+ children=[
+ v.Row(
+ children=[
+ v.Col(cols=12, children=[v.Html(tag="p", children=["Normal"])]),
+ v.Col(
+ cols=12,
+ sm=3,
+ children=[
+ v.Btn(
+ icon=True,
+ color="pink",
+ children=[v.Icon(children=["mdi-heart"])],
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=3,
+ children=[
+ v.Btn(
+ icon=True,
+ color="indigo",
+ children=[v.Icon(children=["mdi-star"])],
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=3,
+ children=[
+ v.Btn(
+ icon=True,
+ color="green",
+ children=[v.Icon(children=["mdi-cached"])],
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=3,
+ children=[
+ v.Btn(
+ icon=True,
+ color="deep-orange",
+ children=[v.Icon(children=["mdi-thumb-up"])],
+ )
+ ],
+ ),
+ ]
+ ),
+ v.Row(
+ class_="mt-12",
+ children=[
+ v.Col(cols=12, children=[v.Html(tag="p", children=["Disabled"])]),
+ v.Col(
+ cols=12,
+ sm=3,
+ children=[
+ v.Btn(
+ icon=True,
+ disabled=True,
+ children=[v.Icon(children=["mdi-heart"])],
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=3,
+ children=[
+ v.Btn(
+ icon=True,
+ disabled=True,
+ children=[v.Icon(children=["mdi-star"])],
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=3,
+ children=[
+ v.Btn(
+ icon=True,
+ disabled=True,
+ children=[v.Icon(children=["mdi-cached"])],
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=3,
+ children=[
+ v.Btn(
+ icon=True,
+ disabled=True,
+ children=[v.Icon(children=["mdi-thumb-up"])],
+ )
+ ],
+ ),
+ ],
+ ),
+ ],
+ )
+ ]
+ )
+ ],
+)
diff --git a/docs/component/Btn/icon.vue b/docs/component/Btn/icon.vue
new file mode 100644
index 00000000..e3c4551c
--- /dev/null
+++ b/docs/component/Btn/icon.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+ Normal
+
+
+ mdi-heart
+
+
+ mdi-star
+
+
+ mdi-cached
+
+
+ mdi-thumb-up
+
+
+
+
+
+ Disabled
+
+
+ mdi-heart
+
+
+ mdi-star
+
+
+ mdi-cached
+
+
+ mdi-thumb-up
+
+
+
+
+
+
diff --git a/docs/component/Btn/loaders.py b/docs/component/Btn/loaders.py
new file mode 100644
index 00000000..701340d7
--- /dev/null
+++ b/docs/component/Btn/loaders.py
@@ -0,0 +1,38 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Btn(children=["Loading"], loading=True, color="primary", disabled=True, class_="mx-2"),
+ v.Btn(
+ children=["Loading..."],
+ loading=True,
+ color="success",
+ disabled=True,
+ class_="mx-2",
+ v_slots=[
+ {"name": "loader", "children": [v.Html(tag="span", children=["Uploading..."])]}
+ ],
+ ),
+ v.Btn(
+ children=["Loading Icon"],
+ loading=True,
+ color="info",
+ disabled=True,
+ class_="mx-2",
+ v_slots=[
+ {
+ "name": "loader",
+ "children": [
+ v.Html(
+ tag="span",
+ children=[
+ v.Icon(light=True, class_="custom-loader", children=["mdi-cached"])
+ ],
+ )
+ ],
+ }
+ ],
+ ),
+ v.Btn(fab=True, loading=True, disabled=True, class_="mx-2"),
+ ]
+)
diff --git a/docs/component/Btn/loaders.vue b/docs/component/Btn/loaders.vue
new file mode 100644
index 00000000..243376df
--- /dev/null
+++ b/docs/component/Btn/loaders.vue
@@ -0,0 +1,63 @@
+
+
+
+ Accept Terms
+
+
+
+ Upload
+ mdi-cloud-upload
+
+
+
+ Custom Loader
+
+ Loading...
+
+
+
+
+ Icon Loader
+
+
+ mdi-cached
+
+
+
+
+
+ mdi-cloud-upload
+
+
+
diff --git a/docs/component/Btn/outlined.py b/docs/component/Btn/outlined.py
new file mode 100644
index 00000000..f75d87c7
--- /dev/null
+++ b/docs/component/Btn/outlined.py
@@ -0,0 +1,22 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Btn(class_="ma-2", outlined=True, color="indigo", children=["Outlined Button"]),
+ v.Btn(
+ class_="ma-2",
+ outlined=True,
+ fab=True,
+ color="teal",
+ children=[v.Icon(children="mdi-format-list-bulleted-square")],
+ ),
+ v.Btn(
+ class_="ma-2",
+ outlined=True,
+ large=True,
+ fab=True,
+ color="indigo",
+ children=[v.Icon(children=["mdi-pencil"])],
+ ),
+ ]
+)
diff --git a/docs/component/Btn/outlined.vue b/docs/component/Btn/outlined.vue
new file mode 100644
index 00000000..efb018ce
--- /dev/null
+++ b/docs/component/Btn/outlined.vue
@@ -0,0 +1,11 @@
+
+
+ Outlined Button
+
+ mdi-format-list-bulleted-square
+
+
+ mdi-pencil
+
+
+
diff --git a/docs/component/Btn/plain.py b/docs/component/Btn/plain.py
new file mode 100644
index 00000000..294b4889
--- /dev/null
+++ b/docs/component/Btn/plain.py
@@ -0,0 +1,16 @@
+import ipyvuetify as v
+
+v.Sheet(
+ class_="px-7 pt-7 pb-4 mx-auto text-center d-inline-block",
+ color="blue-grey darken-3",
+ dark=True,
+ children=[
+ v.Html(
+ tag="div",
+ class_="grey--text text--lighten-1 text-body-2 mb-4",
+ children=["Are you sure you want to delete this album?"],
+ ),
+ v.Btn(class_="ma-1", color="grey", plain=True, children=["Cancel"]),
+ v.Btn(class_="ma-1", color="error", plain=True, children=["Delete"]),
+ ],
+)
diff --git a/docs/component/Btn/plain.vue b/docs/component/Btn/plain.vue
new file mode 100644
index 00000000..b1e706b1
--- /dev/null
+++ b/docs/component/Btn/plain.vue
@@ -0,0 +1,27 @@
+
+
+
+
+ Are you sure you want to delete this album?
+
+
+
+ Cancel
+
+
+
+ Delete
+
+
+
+
diff --git a/docs/component/Btn/raised.py b/docs/component/Btn/raised.py
new file mode 100644
index 00000000..a1d8c7a1
--- /dev/null
+++ b/docs/component/Btn/raised.py
@@ -0,0 +1,10 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Btn(raised=True, children=["Normal"], class_="mx-2"),
+ v.Btn(raised=True, color="primary", children=["Primary"], class_="mx-2"),
+ v.Btn(raised=True, color="error", children=["Error"], class_="mx-2"),
+ v.Btn(raised=True, disabled=True, children=["Disabled"], class_="mx-2"),
+ ]
+)
diff --git a/docs/component/Btn/raised.vue b/docs/component/Btn/raised.vue
new file mode 100644
index 00000000..89b9c818
--- /dev/null
+++ b/docs/component/Btn/raised.vue
@@ -0,0 +1,8 @@
+
+
+ Normal
+ Primary
+ Error
+ Disabled
+
+
diff --git a/docs/component/Btn/rounded.py b/docs/component/Btn/rounded.py
new file mode 100644
index 00000000..6261a891
--- /dev/null
+++ b/docs/component/Btn/rounded.py
@@ -0,0 +1,3 @@
+import ipyvuetify as v
+
+v.Btn(rounded=True, color="primary", dark=True, children=["Rounded Button"])
diff --git a/docs/component/Btn/rounded.vue b/docs/component/Btn/rounded.vue
new file mode 100644
index 00000000..2f3e9975
--- /dev/null
+++ b/docs/component/Btn/rounded.vue
@@ -0,0 +1,3 @@
+
+ Rounded Button
+
diff --git a/docs/component/Btn/sizing.py b/docs/component/Btn/sizing.py
new file mode 100644
index 00000000..4619f883
--- /dev/null
+++ b/docs/component/Btn/sizing.py
@@ -0,0 +1,158 @@
+import ipyvuetify as v
+
+v.Container(
+ fluid=True,
+ class_="pa-0",
+ children=[
+ v.Row(
+ align="center",
+ children=[
+ v.Col(
+ cols=12,
+ sm=6,
+ children=[
+ v.Html(
+ tag="div",
+ class_="text-center",
+ children=[
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ x_small=True,
+ color="secondary",
+ dark=True,
+ children=["Extra small Button"],
+ )
+ ],
+ ),
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ small=True,
+ color="primary",
+ dark=True,
+ children=["Small Button"],
+ )
+ ],
+ ),
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ color="warning", dark=True, children=["Normal Button"]
+ )
+ ],
+ ),
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ large=True,
+ color="error",
+ dark=True,
+ children=["Large Button"],
+ )
+ ],
+ ),
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ x_large=True,
+ color="success",
+ dark=True,
+ children=["Extra large Button"],
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=6,
+ children=[
+ v.Html(
+ tag="div",
+ class_="text-center",
+ children=[
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ fab=True,
+ x_small=True,
+ color="secondary",
+ dark=True,
+ children=[v.Icon(children=["mdi-television"])],
+ )
+ ],
+ ),
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ fab=True,
+ small=True,
+ color="primary",
+ dark=True,
+ children=[v.Icon(children=["mdi-pencil"])],
+ )
+ ],
+ ),
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ fab=True,
+ color="warning",
+ dark=True,
+ children=[v.Icon(children=["mdi-account-circle"])],
+ )
+ ],
+ ),
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ fab=True,
+ large=True,
+ color="error",
+ dark=True,
+ children=[v.Icon(children=["mdi-alarm"])],
+ )
+ ],
+ ),
+ v.Html(
+ tag="div",
+ class_="my-2",
+ children=[
+ v.Btn(
+ fab=True,
+ x_large=True,
+ color="success",
+ dark=True,
+ children=[v.Icon(children=["mdi-domain"])],
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Btn/sizing.vue b/docs/component/Btn/sizing.vue
new file mode 100644
index 00000000..e816b290
--- /dev/null
+++ b/docs/component/Btn/sizing.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+ Extra small Button
+
+
+ Small Button
+
+
+ Normal Button
+
+
+ Large Button
+
+
+ Extra large Button
+
+
+
+
+
+
+
+ mdi-television
+
+
+
+
+ mdi-pencil
+
+
+
+
+ mdi-account-circle
+
+
+
+
+ mdi-alarm
+
+
+
+
+ mdi-domain
+
+
+
+
+
+
+
diff --git a/docs/component/Btn/text.py b/docs/component/Btn/text.py
new file mode 100644
index 00000000..95b490ae
--- /dev/null
+++ b/docs/component/Btn/text.py
@@ -0,0 +1,10 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Btn(text=True, children=["Normal"]),
+ v.Btn(text=True, color="primary", children=["Primary"]),
+ v.Btn(text=True, color="error", children=["Error"]),
+ v.Btn(text=True, disabled=True, children=["Disabled"]),
+ ]
+)
diff --git a/docs/component/Btn/text.vue b/docs/component/Btn/text.vue
new file mode 100644
index 00000000..4023ce1c
--- /dev/null
+++ b/docs/component/Btn/text.vue
@@ -0,0 +1,8 @@
+
+
+ Normal
+ Primary
+ Error
+ Disabled
+
+
diff --git a/docs/component/Btn/tile.py b/docs/component/Btn/tile.py
new file mode 100644
index 00000000..c0ac02a2
--- /dev/null
+++ b/docs/component/Btn/tile.py
@@ -0,0 +1,10 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Btn(tile=True, children=["Normal"], class_="mx-2"),
+ v.Btn(tile=True, color="primary", children=["Primary"], class_="mx-2"),
+ v.Btn(tile=True, color="error", children=["Error"], class_="mx-2"),
+ v.Btn(tile=True, disabled=True, children=["Disabled"], class_="mx-2"),
+ ]
+)
diff --git a/docs/component/Btn/tile.vue b/docs/component/Btn/tile.vue
new file mode 100644
index 00000000..ffa57bf7
--- /dev/null
+++ b/docs/component/Btn/tile.vue
@@ -0,0 +1,8 @@
+
+
+ Normal
+ Primary
+ Error
+ Disabled
+
+
diff --git a/docs/component/Btn/usage.py b/docs/component/Btn/usage.py
new file mode 100644
index 00000000..bc0df128
--- /dev/null
+++ b/docs/component/Btn/usage.py
@@ -0,0 +1,3 @@
+import ipyvuetify as v
+
+v.Container(children=[v.Btn(children=["Click Me"])])
diff --git a/docs/component/BtnToggle.rst b/docs/component/BtnToggle.rst
new file mode 100644
index 00000000..8d4f1d72
--- /dev/null
+++ b/docs/component/BtnToggle.rst
@@ -0,0 +1,124 @@
+BtnToggle
+=========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`BtnToggle ` component is a simple wrapper for :py:class:`ItemGroup ` built specifically to work with :py:class:`Btn `.
+
+.. api::
+
+ - :py:class:`ipyvuetify.BtnToggle`
+ - :py:class:`ipyvuetify.Btn`
+
+.. seealso::
+
+ :doc:`Btn`
+
+Usage
+-----
+
+Toggle buttons allow you to create a styled group of buttons that can be selected or toggled under a single ``v_model``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BtnToggle/usage.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BtnToggle/usage.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BtnToggle/usage.vue
+
+Mandatory
+---------
+
+A :py:class:`BtnToggle ` with the ``mandatory`` prop will always have a value.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BtnToggle/mandatory.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BtnToggle/mandatory.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BtnToggle/mandatory.vue
+
+Multiple
+--------
+
+A :py:class:`BtnToggle ` with the ``multiple`` prop will allow a user to select
+multiple return values as an array.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BtnToggle/multiple.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BtnToggle/multiple.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BtnToggle/multiple.vue
+
+Rounded
+-------
+
+You can make :py:class:`BtnToggle ` rounded using the ``rounded`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BtnToggle/rounded.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BtnToggle/rounded.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BtnToggle/rounded.vue
+
+Toolbar
+-------
+
+Easily integrate customized button solutions with a v-toolbar.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: BtnToggle/toolbar.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: BtnToggle/toolbar.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: BtnToggle/toolbar.vue
+
diff --git a/docs/component/BtnToggle/mandatory.py b/docs/component/BtnToggle/mandatory.py
new file mode 100644
index 00000000..b823febf
--- /dev/null
+++ b/docs/component/BtnToggle/mandatory.py
@@ -0,0 +1,14 @@
+import ipyvuetify as v
+
+toggle_mandatory = v.BtnToggle(
+ v_model=0,
+ mandatory=True,
+ children=[
+ v.Btn(children=[v.Icon(children=["mdi-format-align-left"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-center"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-right"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-justify"])]),
+ ],
+)
+
+v.Container(children=[toggle_mandatory])
diff --git a/docs/component/BtnToggle/mandatory.vue b/docs/component/BtnToggle/mandatory.vue
new file mode 100644
index 00000000..81b493c3
--- /dev/null
+++ b/docs/component/BtnToggle/mandatory.vue
@@ -0,0 +1,16 @@
+
+
+ mdi-format-align-left
+ mdi-format-align-center
+ mdi-format-align-right
+ mdi-format-align-justify
+
+
+
+
diff --git a/docs/component/BtnToggle/multiple.py b/docs/component/BtnToggle/multiple.py
new file mode 100644
index 00000000..b64f6d8b
--- /dev/null
+++ b/docs/component/BtnToggle/multiple.py
@@ -0,0 +1,14 @@
+import ipyvuetify as v
+
+toggle_multiple = v.BtnToggle(
+ v_model=[0, 1, 2],
+ multiple=True,
+ children=[
+ v.Btn(children=[v.Icon(children=["mdi-format-align-left"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-center"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-right"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-justify"])]),
+ ],
+)
+
+v.Container(children=[toggle_multiple])
diff --git a/docs/component/BtnToggle/multiple.vue b/docs/component/BtnToggle/multiple.vue
new file mode 100644
index 00000000..8676ded7
--- /dev/null
+++ b/docs/component/BtnToggle/multiple.vue
@@ -0,0 +1,16 @@
+
+
+ mdi-format-align-left
+ mdi-format-align-center
+ mdi-format-align-right
+ mdi-format-align-justify
+
+
+
+
diff --git a/docs/component/BtnToggle/rounded.py b/docs/component/BtnToggle/rounded.py
new file mode 100644
index 00000000..d2bd1958
--- /dev/null
+++ b/docs/component/BtnToggle/rounded.py
@@ -0,0 +1,14 @@
+import ipyvuetify as v
+
+toggle_rounded = v.BtnToggle(
+ v_model=1,
+ rounded=True,
+ children=[
+ v.Btn(children=[v.Icon(children=["mdi-format-align-left"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-center"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-right"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-justify"])]),
+ ],
+)
+
+v.Container(children=[toggle_rounded])
diff --git a/docs/component/BtnToggle/rounded.vue b/docs/component/BtnToggle/rounded.vue
new file mode 100644
index 00000000..0e8fd688
--- /dev/null
+++ b/docs/component/BtnToggle/rounded.vue
@@ -0,0 +1,16 @@
+
+
+ mdi-format-align-left
+ mdi-format-align-center
+ mdi-format-align-right
+ mdi-format-align-justify
+
+
+
+
diff --git a/docs/component/BtnToggle/toolbar.py b/docs/component/BtnToggle/toolbar.py
new file mode 100644
index 00000000..3c7ea684
--- /dev/null
+++ b/docs/component/BtnToggle/toolbar.py
@@ -0,0 +1,71 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Toolbar(
+ dense=True,
+ children=[
+ v.OverflowBtn(
+ items=["10", "12", "14", "16", "18", "20", "22", "24", "26", "28", "30"],
+ editable=True,
+ label="Select size",
+ hide_details=True,
+ class_="pa-0",
+ overflow=True,
+ ),
+ v.Divider(vertical=True),
+ v.Spacer(),
+ v.BtnToggle(
+ v_model=[1, 3],
+ color="primary",
+ dense=True,
+ group=True,
+ multiple=True,
+ children=[
+ v.Btn(value=1, text=True, children=[v.Icon(children=["mdi-format-bold"])]),
+ v.Btn(
+ value=2, text=True, children=[v.Icon(children=["mdi-format-italic"])]
+ ),
+ v.Btn(
+ value=3, text=True, children=[v.Icon(children=["mdi-format-underline"])]
+ ),
+ v.Btn(
+ value=4,
+ text=True,
+ children=[v.Icon(children=["mdi-format-color-fill"])],
+ ),
+ ],
+ ),
+ v.Html(tag="div", class_="mx-4"),
+ v.BtnToggle(
+ v_model=2,
+ color="primary",
+ dense=True,
+ group=True,
+ children=[
+ v.Btn(
+ value=1,
+ text=True,
+ children=[v.Icon(children=["mdi-format-align-left"])],
+ ),
+ v.Btn(
+ value=2,
+ text=True,
+ children=[v.Icon(children=["mdi-format-align-center"])],
+ ),
+ v.Btn(
+ value=3,
+ text=True,
+ children=[v.Icon(children=["mdi-format-align-right"])],
+ ),
+ v.Btn(
+ value=4,
+ text=True,
+ children=[v.Icon(children=["mdi-format-align-justify"])],
+ ),
+ ],
+ ),
+ ],
+ )
+ ]
+)
diff --git a/docs/component/BtnToggle/toolbar.vue b/docs/component/BtnToggle/toolbar.vue
new file mode 100644
index 00000000..9ddbcb29
--- /dev/null
+++ b/docs/component/BtnToggle/toolbar.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-format-bold
+ mdi-format-italic
+ mdi-format-underline
+ mdi-format-color-fill
+
+
+
+
+
+ mdi-format-align-left
+ mdi-format-align-center
+ mdi-format-align-right
+ mdi-format-align-justify
+
+
+
+
diff --git a/docs/component/BtnToggle/usage.py b/docs/component/BtnToggle/usage.py
new file mode 100644
index 00000000..9c07736a
--- /dev/null
+++ b/docs/component/BtnToggle/usage.py
@@ -0,0 +1,154 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ cols=12,
+ sm=6,
+ class_="py-2",
+ children=[
+ v.Html(tag="p", children=["Exclusive"]),
+ v.BtnToggle(
+ children=[
+ v.Btn(children=[v.Icon(children=["mdi-format-align-left"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-center"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-right"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-justify"])]),
+ ]
+ ),
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=6,
+ class_="py-2",
+ children=[
+ v.Html(tag="p", children=["Multiple"]),
+ v.BtnToggle(
+ dense=True,
+ background_color="primary",
+ dark=True,
+ multiple=True,
+ children=[
+ v.Btn(children=[v.Icon(children=["mdi-format-bold"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-italic"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-underline"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-color-fill"])]),
+ ],
+ ),
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=6,
+ class_="py-2",
+ children=[
+ v.Html(tag="p", children=["No Options Selected"]),
+ v.BtnToggle(
+ children=[
+ v.Btn(children=[v.Icon(children=["mdi-format-align-left"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-center"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-right"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-justify"])]),
+ ]
+ ),
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=6,
+ class_="py-2",
+ children=[
+ v.Html(tag="p", children=["Mandatory"]),
+ v.BtnToggle(
+ shaped=True,
+ mandatory=True,
+ children=[
+ v.Btn(children=[v.Icon(children=["mdi-format-align-left"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-center"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-right"])]),
+ v.Btn(children=[v.Icon(children=["mdi-format-align-justify"])]),
+ ],
+ ),
+ ],
+ ),
+ v.Col(
+ cols=12,
+ class_="py-2",
+ children=[
+ v.Html(tag="p", children=["Text Options"]),
+ v.BtnToggle(
+ tile=True,
+ color="deep-purple accent-3",
+ group=True,
+ children=[
+ v.Btn(value="left", children=["Left"]),
+ v.Btn(value="center", children=["Center"]),
+ v.Btn(value="right", children=["Right"]),
+ v.Btn(value="justify", children=["Justify"]),
+ ],
+ ),
+ ],
+ ),
+ v.Col(
+ cols=12,
+ class_="py-2",
+ children=[
+ v.Html(tag="p", children=["Text & Icon Options"]),
+ v.BtnToggle(
+ borderless=True,
+ children=[
+ v.Btn(
+ value="left",
+ children=[
+ v.Html(
+ tag="span",
+ class_="hidden-sm-and-down",
+ children=["Left"],
+ ),
+ v.Icon(right=True, children=["mdi-format-align-left"]),
+ ],
+ ),
+ v.Btn(
+ value="center",
+ children=[
+ v.Html(
+ tag="span",
+ class_="hidden-sm-and-down",
+ children=["Center"],
+ ),
+ v.Icon(right=True, children=["mdi-format-align-center"]),
+ ],
+ ),
+ v.Btn(
+ value="right",
+ children=[
+ v.Html(
+ tag="span",
+ class_="hidden-sm-and-down",
+ children=["Right"],
+ ),
+ v.Icon(right=True, children=["mdi-format-align-right"]),
+ ],
+ ),
+ v.Btn(
+ value="justify",
+ children=[
+ v.Html(
+ tag="span",
+ class_="hidden-sm-and-down",
+ children=["Justify"],
+ ),
+ v.Icon(right=True, children=["mdi-format-align-justify"]),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ]
+ ),
+ ]
+)
diff --git a/docs/component/BtnToggle/usage.vue b/docs/component/BtnToggle/usage.vue
new file mode 100644
index 00000000..fe8ded23
--- /dev/null
+++ b/docs/component/BtnToggle/usage.vue
@@ -0,0 +1,81 @@
+
+
+
+ Exclusive
+
+ mdi-format-align-left
+ mdi-format-align-center
+ mdi-format-align-right
+ mdi-format-align-justify
+
+
+
+
+ Multiple
+
+ mdi-format-bold
+ mdi-format-italic
+ mdi-format-underline
+ mdi-format-color-fill
+
+
+
+
+ No Options Selected
+
+ mdi-format-align-left
+ mdi-format-align-center
+ mdi-format-align-right
+ mdi-format-align-justify
+
+
+
+
+ Mandatory
+
+ mdi-format-align-left
+ mdi-format-align-center
+ mdi-format-align-right
+ mdi-format-align-justify
+
+
+
+
+ Text Options
+
+ Left
+ Center
+ Right
+ Justify
+
+
+
+
+ Text & Icon Options
+
+ Leftmdi-format-align-left
+ Centermdi-format-align-center
+ Rightmdi-format-align-right
+ Justifymdi-format-align-justify
+
+
+
+
diff --git a/docs/component/Calendar.rst b/docs/component/Calendar.rst
new file mode 100644
index 00000000..9c702798
--- /dev/null
+++ b/docs/component/Calendar.rst
@@ -0,0 +1,82 @@
+Calendar
+========
+
+.. warning::
+ This page is AI-generated and requires human review. The content may contain errors or inaccuracies.
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Calendar ` component is used to display information in a daily, weekly, monthly, or category view. The daily view has slots for all day or timed elements, and the weekly and monthly view has a slot for each day. Optionally you can pass in an array of events and they will be rendered over the appropriate days and times.
+
+.. api::
+
+ :py:class:`ipyvuetify.Calendar`
+ :py:class:`ipyvuetify.CalendarDaily`
+ :py:class:`ipyvuetify.CalendarWeekly`
+ :py:class:`ipyvuetify.CalendarMonthly`
+
+Usage
+-----
+
+A calendar has a type and a value which determines what type of calendar is shown over what span of time. This shows the bare minimum configuration, an array of events with name, start and end properties.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Calendar/usage.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Calendar/usage.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Calendar/usage.vue
+
+Type Week
+---------
+
+This is an example of an event calendar with all-day and timed events with a type of ``week``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Calendar/type_week.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Calendar/type_week.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Calendar/type_week.vue
+
+Type Day
+--------
+
+This is an example of calendar with a type of ``day``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Calendar/type_day.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Calendar/type_day.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Calendar/type_day.vue
+
diff --git a/docs/component/Calendar/type_day.py b/docs/component/Calendar/type_day.py
new file mode 100644
index 00000000..5dab5687
--- /dev/null
+++ b/docs/component/Calendar/type_day.py
@@ -0,0 +1,9 @@
+import ipyvuetify as v
+
+events = [
+ {"name": "Morning Meeting", "start": "2025-11-28 09:00", "end": "2025-11-28 10:00"},
+ {"name": "Lunch Break", "start": "2025-11-28 12:00", "end": "2025-11-28 13:00"},
+ {"name": "Afternoon Session", "start": "2025-11-28 14:00", "end": "2025-11-28 16:00"},
+]
+
+v.Calendar(type="day", value="2025-11-28", events=events)
diff --git a/docs/component/Calendar/type_day.vue b/docs/component/Calendar/type_day.vue
new file mode 100644
index 00000000..bdb85ee0
--- /dev/null
+++ b/docs/component/Calendar/type_day.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
diff --git a/docs/component/Calendar/type_week.py b/docs/component/Calendar/type_week.py
new file mode 100644
index 00000000..c23301d5
--- /dev/null
+++ b/docs/component/Calendar/type_week.py
@@ -0,0 +1,9 @@
+import ipyvuetify as v
+
+events = [
+ {"name": "Weekly Meeting", "start": "2025-11-07 09:00", "end": "2025-11-07 10:00"},
+ {"name": "Lunch", "start": "2025-11-08 12:30", "end": "2025-11-08 13:30"},
+ {"name": "Thomas Birthday", "start": "2025-11-10", "color": "green"},
+]
+
+v.Calendar(type="week", value="2025-11-07", events=events)
diff --git a/docs/component/Calendar/type_week.vue b/docs/component/Calendar/type_week.vue
new file mode 100644
index 00000000..dbc7cccd
--- /dev/null
+++ b/docs/component/Calendar/type_week.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
diff --git a/docs/component/Calendar/usage.py b/docs/component/Calendar/usage.py
new file mode 100644
index 00000000..538f24de
--- /dev/null
+++ b/docs/component/Calendar/usage.py
@@ -0,0 +1,10 @@
+import ipyvuetify as v
+
+events = [
+ {"name": "Meeting", "start": "2025-11-01 09:00", "end": "2025-11-01 10:00"},
+ {"name": "Conference", "start": "2025-11-05 14:00", "end": "2025-11-05 17:00"},
+ {"name": "Birthday Party", "start": "2025-11-10", "color": "green"},
+ {"name": "PTO", "start": "2025-11-15", "end": "2025-11-17", "color": "blue"},
+]
+
+v.Calendar(type="month", value="2025-11-01", events=events)
diff --git a/docs/component/Calendar/usage.vue b/docs/component/Calendar/usage.vue
new file mode 100644
index 00000000..a3aadb34
--- /dev/null
+++ b/docs/component/Calendar/usage.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
diff --git a/docs/component/Card.rst b/docs/component/Card.rst
new file mode 100644
index 00000000..101545c3
--- /dev/null
+++ b/docs/component/Card.rst
@@ -0,0 +1,305 @@
+Card
+====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Card documentation
+ `__. All examples have been converted
+ to ipyvuetify syntax.
+
+The :py:class:`Card ` component is a versatile component that can
+be used for anything from a panel to a static image. The card component has numerous
+helper components to make markup as easy as possible. Components that have no listed
+options use Vue's functional component option for faster rendering and serve as markup
+sugar to make building easier.
+
+.. api::
+
+ - :py:class:`ipyvuetify.Card`
+ - :py:class:`ipyvuetify.CardTitle`
+ - :py:class:`ipyvuetify.CardSubtitle`
+ - :py:class:`ipyvuetify.CardText`
+ - :py:class:`ipyvuetify.CardActions`
+
+Usage
+-----
+
+A card has 4 basic components: :py:class:`CardTitle `,
+:py:class:`CardSubtitle `,
+:py:class:`CardText ` and
+:py:class:`CardActions `.
+
+.. jupyter-execute:: Card/usage.py
+ :raises:
+
+Functional Components
+---------------------
+
+``CardActions``
+^^^^^^^^^^^^^^^
+
+The container used for placing **actions** for a card, such as :py:class:`Btn `
+or :py:class:`Menu `. Also applies special margin to buttons so that
+they properly line up with other card content areas.
+
+``CardSubtitle``
+^^^^^^^^^^^^^^^^
+
+Provides a default **font-size** and **padding** for card subtitles. Font-size can be
+overwritten with `typography classes `__.
+
+``CardText``
+^^^^^^^^^^^^
+
+Primarily used for **text content** in a card. Applies padding for text, reduces its
+font-size to .875rem.
+
+``CardTitle``
+^^^^^^^^^^^^^
+
+Provides a default **font-size** and **padding** for card titles. Font-size can be
+overwritten with `typography classes `__.
+
+Loading
+-------
+
+Cards can be set to a loading state when processing a user action. This disables
+further actions and provides visual feedback with an indeterminate
+:py:class:`ProgressLinear `.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/loading.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/loading.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/loading.vue
+
+Outlined
+--------
+
+An ``outlined`` card has 0 elevation and contains a soft border.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/outlined.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/outlined.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/outlined.vue
+
+Card Reveal
+-----------
+
+Using :py:class:`ExpandTransition ` and a ``click``
+event you can have a card that reveals more information once the button is clicked,
+activating the hidden card to be revealed.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/card_reveal.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/card_reveal.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/card_reveal.vue
+
+Content Wrapping
+----------------
+
+The ``v-card`` component is useful for wrapping content.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/content_wrapping.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/content_wrapping.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/content_wrapping.vue
+
+Custom Actions
+--------------
+
+With a simple conditional, you can easily add supplementary text that is hidden until opened.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/custom_actions.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/custom_actions.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/custom_actions.vue
+
+Grids
+-----
+
+Using grids, you can create beautiful layouts.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/grids.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/grids.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/grids.vue
+
+Horizontal Cards
+----------------
+
+Using :py:class:`Col `, you can create customized horizontal cards.
+Use the ``contain`` property to shrink the :py:class:`Img ` to fit inside the container,
+instead of covering.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/horizontal_cards.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/horizontal_cards.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/horizontal_cards.vue
+
+Information Card
+----------------
+
+Cards are entry points to more detailed information. To keep things concise, ensure to limit the number of actions the user can take.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/information_card.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/information_card.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/information_card.vue
+
+Media with Text
+---------------
+
+Using the layout system, we can add custom text anywhere within the background.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/media_with_text.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/media_with_text.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/media_with_text.vue
+
+Twitter Card
+------------
+
+The :py:class:`Card ` component has multiple children components
+that help you build complex examples without having to worry about spacing. This
+example is comprised of the :py:class:`CardTitle `,
+:py:class:`CardText ` and
+:py:class:`CardActions ` components.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/twitter_card.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/twitter_card.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/twitter_card.vue
+
+Weather Card
+------------
+
+Using :py:class:`ListItem ` and a :py:class:`Slider `,
+we are able to create a unique weather card. The list components ensure that we have
+consistent spacing and functionality while the slider component allows us to provide
+a useful interface of selection to the user.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Card/weather_card.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Card/weather_card.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Card/weather_card.vue
+
diff --git a/docs/component/Card/card_reveal.py b/docs/component/Card/card_reveal.py
new file mode 100644
index 00000000..c0c26037
--- /dev/null
+++ b/docs/component/Card/card_reveal.py
@@ -0,0 +1,40 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width=344,
+ children=[
+ v.CardTitle(children=["Word of the Day"]),
+ v.CardSubtitle(children=["el·ee·mos·y·nar·y"]),
+ v.CardActions(children=[v.Btn(text=True, children=["Learn More"])]),
+ v.ExpandTransition(
+ children=[
+ v.Card(
+ class_="transition-fast-in-fast-out v-card--reveal",
+ style_="height: 100%;",
+ children=[
+ v.CardText(
+ class_="pb-0",
+ children=[
+ v.Html(
+ tag="p", class_="text-h4 text--primary", children=["adjective"]
+ ),
+ v.Html(
+ tag="p",
+ children=["relating to or dependent on charity; charitable."],
+ ),
+ v.Html(
+ tag="p", children=['"an eleemosynary educational institution."']
+ ),
+ ],
+ ),
+ v.CardActions(
+ class_="pt-0",
+ children=[v.Btn(text=True, color="teal accent-4", children=["Close"])],
+ ),
+ ],
+ )
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Card/card_reveal.vue b/docs/component/Card/card_reveal.vue
new file mode 100644
index 00000000..8af739db
--- /dev/null
+++ b/docs/component/Card/card_reveal.vue
@@ -0,0 +1,40 @@
+
+
+
+ Word of the Day
+ el·ee·mos·y·nar·y
+ adjective
+
+ relating to or dependent on charity; charitable.
+ "an eleemosynary educational institution."
+
+
+
+
+ Learn More
+
+
+
+
+
+
+ Origin
+
+ late 16th century (as a noun denoting a place where alms were
+ distributed): from medieval Latin eleemosynarius, from late Latin
+ eleemosyna ‘alms’, from Greek eleēmosunē ‘compassion’
+
+
+
+
+ Close
+
+
+
+
+
+
diff --git a/docs/component/Card/content_wrapping.py b/docs/component/Card/content_wrapping.py
new file mode 100644
index 00000000..b3e32ecf
--- /dev/null
+++ b/docs/component/Card/content_wrapping.py
@@ -0,0 +1,98 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Row(
+ justify="space-around",
+ children=[
+ v.Card(
+ width=400,
+ children=[
+ v.Img(
+ height="200px",
+ src="https://cdn.vuetifyjs.com/docs/images/cards/purple-flowers.jpg",
+ children=[
+ v.AppBar(
+ flat=True,
+ color="rgba(0, 0, 0, 0)",
+ children=[
+ v.AppBarNavIcon(color="white"),
+ v.ToolbarTitle(
+ class_="text-h6 white--text pl-0", children=["Messages"]
+ ),
+ v.Spacer(),
+ v.Btn(
+ color="white",
+ icon=True,
+ children=[v.Icon(children=["mdi-dots-vertical"])],
+ ),
+ ],
+ )
+ ],
+ ),
+ v.CardText(
+ children=[
+ v.Html(
+ tag="div",
+ class_="font-weight-bold ml-8 mb-2",
+ children=["Today"],
+ ),
+ v.Timeline(
+ align_top=True,
+ dense=True,
+ children=[
+ v.TimelineItem(
+ color=message["color"],
+ small=True,
+ children=[
+ v.Html(
+ tag="div",
+ children=[
+ v.Html(
+ tag="div",
+ class_="font-weight-normal",
+ children=[
+ v.Html(
+ tag="strong",
+ children=[message["from"]],
+ ),
+ f" @{message['time']}",
+ ],
+ ),
+ v.Html(
+ tag="div", children=[message["message"]]
+ ),
+ ],
+ )
+ ],
+ )
+ for message in [
+ {
+ "from": "You",
+ "message": "Sure, I'll see you later.",
+ "time": "10:42am",
+ "color": "deep-purple lighten-1",
+ },
+ {
+ "from": "John Doe",
+ "message": "Yeah, sure. Does 1:00pm work?",
+ "time": "10:37am",
+ "color": "green",
+ },
+ {
+ "from": "You",
+ "message": "Did you still want to grab lunch today?",
+ "time": "9:47am",
+ "color": "deep-purple lighten-1",
+ },
+ ]
+ ],
+ ),
+ ]
+ ),
+ ],
+ )
+ ],
+ )
+ ]
+)
diff --git a/docs/component/Card/content_wrapping.vue b/docs/component/Card/content_wrapping.vue
new file mode 100644
index 00000000..32b7b082
--- /dev/null
+++ b/docs/component/Card/content_wrapping.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+ Messages
+
+
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+ Today
+
+
+
+
+
+ {{ message.from }} @{{ message.time }}
+
+
{{ message.message }}
+
+
+
+
+
+
+
+
diff --git a/docs/component/Card/custom_actions.py b/docs/component/Card/custom_actions.py
new file mode 100644
index 00000000..8858f6d1
--- /dev/null
+++ b/docs/component/Card/custom_actions.py
@@ -0,0 +1,31 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width=344,
+ children=[
+ v.Img(src="https://cdn.vuetifyjs.com/images/cards/sunshine.jpg", height="200px"),
+ v.CardTitle(children=["Top western road trips"]),
+ v.CardSubtitle(children=["1,000 miles of wonder"]),
+ v.CardActions(
+ children=[
+ v.Btn(color="orange lighten-2", text=True, children=["Explore"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-chevron-down"])]),
+ ]
+ ),
+ v.ExpandTransition(
+ children=[
+ v.Divider(),
+ v.CardText(
+ children=[
+ "I'm a thing. But, like most politicians, he promised more than he could deliver. "
+ "You won't have time for sleeping, soldier, not with all the bed making you'll be doing. "
+ "Then we'll go with that data file! Hey, you add a one and two zeros to that or we walk! "
+ "You're going to do his laundry? I've got to find a way to escape."
+ ]
+ ),
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Card/custom_actions.vue b/docs/component/Card/custom_actions.vue
new file mode 100644
index 00000000..4fce48e9
--- /dev/null
+++ b/docs/component/Card/custom_actions.vue
@@ -0,0 +1,36 @@
+
+
+
+
+ Top western road trips
+
+ 1,000 miles of wonder
+
+
+ Explore
+
+
+
+
+ {{ show ? "mdi-chevron-up" : "mdi-chevron-down" }}
+
+
+
+
+
+
+
+
+ I'm a thing. But, like most politicians, he promised more than he
+ could deliver. You won't have time for sleeping, soldier, not with all
+ the bed making you'll be doing. Then we'll go with that data file!
+ Hey, you add a one and two zeros to that or we walk! You're going to
+ do his laundry? I've got to find a way to escape.
+
+
+
+
+
diff --git a/docs/component/Card/grids.py b/docs/component/Card/grids.py
new file mode 100644
index 00000000..241d3a5f
--- /dev/null
+++ b/docs/component/Card/grids.py
@@ -0,0 +1,92 @@
+import ipyvuetify as v
+
+data = [
+ {
+ "title": "Pre-fab homes",
+ "src": "https://cdn.vuetifyjs.com/images/cards/house.jpg",
+ "flex": 12,
+ },
+ {
+ "title": "Favorite road trips",
+ "src": "https://cdn.vuetifyjs.com/images/cards/road.jpg",
+ "flex": 6,
+ },
+ {
+ "title": "Best airlines",
+ "src": "https://cdn.vuetifyjs.com/images/cards/plane.jpg",
+ "flex": 6,
+ },
+]
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width=500,
+ children=[
+ v.SystemBar(
+ color="indigo darken-2",
+ dark=True,
+ children=[
+ v.Spacer(),
+ v.Icon(children=["mdi-window-minimize"]),
+ v.Icon(children=["mdi-window-maximize"]),
+ v.Icon(children=["mdi-close"]),
+ ],
+ ),
+ v.Toolbar(
+ color="indigo",
+ dark=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Discover"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ ],
+ ),
+ v.Container(
+ fluid=True,
+ children=[
+ v.Row(
+ dense=True,
+ children=[
+ v.Col(
+ cols=card["flex"],
+ children=[
+ v.Card(
+ children=[
+ v.Img(
+ src=card["src"],
+ class_="white--text align-end",
+ gradient="to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)",
+ height="200px",
+ children=[v.CardTitle(v_text=card["title"])],
+ ),
+ v.CardActions(
+ children=[
+ v.Spacer(),
+ v.Btn(
+ icon=True,
+ children=[v.Icon(children=["mdi-heart"])],
+ ),
+ v.Btn(
+ icon=True,
+ children=[v.Icon(children=["mdi-bookmark"])],
+ ),
+ v.Btn(
+ icon=True,
+ children=[
+ v.Icon(children=["mdi-share-variant"])
+ ],
+ ),
+ ]
+ ),
+ ]
+ )
+ ],
+ )
+ for card in data
+ ],
+ )
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Card/grids.vue b/docs/component/Card/grids.vue
new file mode 100644
index 00000000..e25959d1
--- /dev/null
+++ b/docs/component/Card/grids.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+ mdi-window-minimize
+
+ mdi-window-maximize
+
+ mdi-close
+
+
+
+
+
+ Discover
+
+
+
+
+ mdi-magnify
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-heart
+
+
+
+ mdi-bookmark
+
+
+
+ mdi-share-variant
+
+
+
+
+
+
+
+
diff --git a/docs/component/Card/horizontal_cards.py b/docs/component/Card/horizontal_cards.py
new file mode 100644
index 00000000..5ceec86d
--- /dev/null
+++ b/docs/component/Card/horizontal_cards.py
@@ -0,0 +1,165 @@
+import ipyvuetify as v
+
+items = [
+ {
+ "color": "#1F7087",
+ "src": "https://cdn.vuetifyjs.com/images/cards/foster.jpg",
+ "title": "Supermodel",
+ "artist": "Foster the People",
+ },
+ {
+ "color": "#952175",
+ "src": "https://cdn.vuetifyjs.com/images/cards/halcyon.png",
+ "title": "Halcyon Days",
+ "artist": "Ellie Goulding",
+ },
+]
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width=400,
+ children=[
+ v.SystemBar(
+ color="pink darken-2",
+ dark=True,
+ children=[
+ v.Spacer(),
+ v.Icon(children=["mdi-window-minimize"]),
+ v.Icon(children=["mdi-window-maximize"]),
+ v.Icon(children=["mdi-close"]),
+ ],
+ ),
+ v.AppBar(
+ dark=True,
+ color="pink",
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["My Music"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ ],
+ ),
+ v.Container(
+ children=[
+ v.Row(
+ dense=True,
+ children=[
+ v.Col(
+ cols=12,
+ children=[
+ v.Card(
+ color="#385F73",
+ dark=True,
+ children=[
+ v.CardTitle(
+ class_="text-h5", children=["Unlimited music now"]
+ ),
+ v.CardSubtitle(
+ children=[
+ "Listen to your favorite artists and albums whenever and wherever, "
+ "online and offline."
+ ]
+ ),
+ v.CardActions(
+ children=[v.Btn(text=True, children=["Listen Now"])]
+ ),
+ ],
+ )
+ ],
+ ),
+ *[
+ v.Col(
+ cols=12,
+ children=[
+ v.Card(
+ color=item["color"],
+ dark=True,
+ children=[
+ v.Html(
+ tag="div",
+ class_="d-flex flex-no-wrap justify-space-between",
+ children=[
+ v.Html(
+ tag="div",
+ children=[
+ v.CardTitle(
+ class_="text-h5",
+ children=[item["title"]],
+ ),
+ v.CardSubtitle(
+ children=[item["artist"]]
+ ),
+ v.CardActions(
+ children=[
+ v.Btn(
+ class_="ml-2 mt-3"
+ if item["artist"]
+ == "Ellie Goulding"
+ else "ml-2 mt-5",
+ fab=True
+ if item["artist"]
+ == "Ellie Goulding"
+ else False,
+ icon=True
+ if item["artist"]
+ == "Ellie Goulding"
+ else False,
+ height="40px"
+ if item["artist"]
+ == "Ellie Goulding"
+ else None,
+ right=True
+ if item["artist"]
+ == "Ellie Goulding"
+ else False,
+ width="40px"
+ if item["artist"]
+ == "Ellie Goulding"
+ else None,
+ outlined=False
+ if item["artist"]
+ == "Ellie Goulding"
+ else True,
+ rounded=False
+ if item["artist"]
+ == "Ellie Goulding"
+ else True,
+ small=False
+ if item["artist"]
+ == "Ellie Goulding"
+ else True,
+ children=[
+ v.Icon(
+ children=[
+ "mdi-play"
+ ]
+ )
+ if item["artist"]
+ == "Ellie Goulding"
+ else "START RADIO"
+ ],
+ )
+ ]
+ ),
+ ],
+ ),
+ v.Avatar(
+ class_="ma-3",
+ size="125",
+ tile=True,
+ children=[v.Img(src=item["src"])],
+ ),
+ ],
+ )
+ ],
+ )
+ ],
+ )
+ for item in items
+ ],
+ ],
+ )
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Card/horizontal_cards.vue b/docs/component/Card/horizontal_cards.vue
new file mode 100644
index 00000000..162109e5
--- /dev/null
+++ b/docs/component/Card/horizontal_cards.vue
@@ -0,0 +1,78 @@
+
+
+
+
+ mdi-window-minimize
+ mdi-window-maximize
+ mdi-close
+
+
+
+
+
+ My Music
+
+
+
+
+ mdi-magnify
+
+
+
+
+
+
+
+ Unlimited music now
+
+
+ Listen to your favorite artists and albums whenever and wherever,
+ online and offline.
+
+
+
+ Listen Now
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ mdi-play
+
+
+
+ START RADIO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Card/information_card.py b/docs/component/Card/information_card.py
new file mode 100644
index 00000000..c54aea0c
--- /dev/null
+++ b/docs/component/Card/information_card.py
@@ -0,0 +1,23 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="mx-auto my-2",
+ min_width=500,
+ children=[
+ v.CardText(
+ children=[
+ v.Html(tag="div", children=["Word of the Day"]),
+ v.Html(tag="h3", class_="text--primary my-2", children=["be•nev•o•lent"]),
+ v.Html(tag="p", children=["adjective"]),
+ v.Html(
+ tag="div",
+ class_="text--primary",
+ children=["well meaning and kindly.", v.Html(tag="br"), '"a benevolent smile"'],
+ ),
+ ]
+ ),
+ v.CardActions(
+ children=[v.Btn(text=True, color="deep-purple accent-4", children=["Learn More"])]
+ ),
+ ],
+)
diff --git a/docs/component/Card/information_card.vue b/docs/component/Card/information_card.vue
new file mode 100644
index 00000000..ab556f2e
--- /dev/null
+++ b/docs/component/Card/information_card.vue
@@ -0,0 +1,16 @@
+
+
+
+ Word of the Day
+ be•nev•o•lent
+ adjective
+
+ well meaning and kindly.
+ "a benevolent smile"
+
+
+
+ Learn More
+
+
+
diff --git a/docs/component/Card/loading.py b/docs/component/Card/loading.py
new file mode 100644
index 00000000..a1007689
--- /dev/null
+++ b/docs/component/Card/loading.py
@@ -0,0 +1,62 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width=374,
+ loading=True,
+ children=[
+ v.Img(height="250", src="https://cdn.vuetifyjs.com/images/cards/cooking.png"),
+ v.CardTitle(children=["Cafe Badilico"]),
+ v.CardText(
+ children=[
+ v.Container(
+ class_="pa-0 flex",
+ children=[
+ v.Rating(
+ value=4.5,
+ color="amber",
+ dense=True,
+ half_increments=True,
+ readonly=True,
+ size=14,
+ class_="d-inline-flex",
+ ),
+ v.Html(
+ tag="div",
+ class_="grey--text mb-2 d-inline-flex",
+ children=["4.5 (413)"],
+ ),
+ ],
+ ),
+ v.Html(tag="div", children=["$ • Italian, Cafe"], class_="my-2 text-subtitle-1"),
+ v.Html(
+ tag="div",
+ children=[
+ "Small plates, salads & sandwiches - an intimate setting with 12 indoor seats plus patio seating."
+ ],
+ ),
+ ]
+ ),
+ v.Divider(class_="mx-4"),
+ v.CardTitle(children=["Tonight's availability"]),
+ v.CardText(
+ children=[
+ v.ChipGroup(
+ v_model="selection",
+ active_class="deep-purple accent-4 white--text",
+ children=[
+ v.Chip(children=["5:30PM"], active=True),
+ v.Chip(children=["7:30PM"]),
+ v.Chip(children=["8:00PM"]),
+ v.Chip(children=["9:00PM"]),
+ ],
+ ),
+ ]
+ ),
+ v.CardActions(
+ children=[
+ v.Btn(color="deep-purple lighten-2", text=True, children=["Reserve"]),
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Card/loading.vue b/docs/component/Card/loading.vue
new file mode 100644
index 00000000..f4b8bdb1
--- /dev/null
+++ b/docs/component/Card/loading.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+ Cafe Badilico
+
+
+
+
+
+ 4.5 (413)
+
+
+ $ • Italian, Cafe
+
+
+ Small plates, salads & sandwiches - an intimate setting with 12 indoor
+ seats plus patio seating.
+
+
+
+
+
+ Tonight's availability
+
+
+
+ 5:30PM
+ 7:30PM
+ 8:00PM
+ 9:00PM
+
+
+
+
+
+ Reserve
+
+
+
+
diff --git a/docs/component/Card/media_with_text.py b/docs/component/Card/media_with_text.py
new file mode 100644
index 00000000..43cabd2a
--- /dev/null
+++ b/docs/component/Card/media_with_text.py
@@ -0,0 +1,28 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width=400,
+ children=[
+ v.Img(
+ src="https://cdn.vuetifyjs.com/images/cards/docks.jpg",
+ height="200px",
+ class_="white--text align-end",
+ children=[v.CardTitle(children=["Top 10 Australian beaches"])],
+ ),
+ v.CardSubtitle(class_="pb-0", children=["Number 10"]),
+ v.CardText(
+ class_="text--primary",
+ children=[
+ v.Html(tag="div", children=["Whitehaven Beach"]),
+ v.Html(tag="div", children=["Whitsunday Island, Whitsunday Islands"]),
+ ],
+ ),
+ v.CardActions(
+ children=[
+ v.Btn(color="orange", text=True, children=["Share"]),
+ v.Btn(color="orange", text=True, children=["Explore"]),
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Card/media_with_text.vue b/docs/component/Card/media_with_text.vue
new file mode 100644
index 00000000..242b534c
--- /dev/null
+++ b/docs/component/Card/media_with_text.vue
@@ -0,0 +1,25 @@
+
+
+
+ Top 10 Australian beaches
+
+
+ Number 10
+
+
+ Whitehaven Beach
+
+ Whitsunday Island, Whitsunday Islands
+
+
+
+ Share
+
+ Explore
+
+
+
diff --git a/docs/component/Card/outlined.py b/docs/component/Card/outlined.py
new file mode 100644
index 00000000..ad28489d
--- /dev/null
+++ b/docs/component/Card/outlined.py
@@ -0,0 +1,31 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width=344,
+ outlined=True,
+ children=[
+ v.ListItem(
+ three_line=True,
+ children=[
+ v.ListItemContent(
+ children=[
+ v.Html(tag="div", class_="text-overline mb-4", children=["OVERLINE"]),
+ v.ListItemTitle(class_="text-h5 mb-1", children=["Headline 5"]),
+ v.ListItemSubtitle(
+ children=["Greyhound divisely hello coldly fonwderfully"]
+ ),
+ ]
+ ),
+ v.ListItemAvatar(
+ tile=True,
+ size=80,
+ color="grey",
+ ),
+ ],
+ ),
+ v.CardActions(
+ children=[v.Btn(outlined=True, rounded=True, text=True, children=["Button"])]
+ ),
+ ],
+)
diff --git a/docs/component/Card/outlined.vue b/docs/component/Card/outlined.vue
new file mode 100644
index 00000000..aceb26da
--- /dev/null
+++ b/docs/component/Card/outlined.vue
@@ -0,0 +1,19 @@
+
+
+
+
+ OVERLINE
+ Headline 5
+ Greyhound divisely hello coldly fonwderfully
+
+
+
+
+
+
+ Button
+
+
+
diff --git a/docs/component/Card/twitter_card.py b/docs/component/Card/twitter_card.py
new file mode 100644
index 00000000..2b3ecaeb
--- /dev/null
+++ b/docs/component/Card/twitter_card.py
@@ -0,0 +1,52 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="mx-auto my-2",
+ color="#26c6da",
+ dark=True,
+ max_width=400,
+ children=[
+ v.CardTitle(
+ children=[
+ v.Icon(large=True, left=True, children=["mdi-twitter"]),
+ v.Html(tag="span", class_="text-h6 font-weight-light", children=["Twitter"]),
+ ]
+ ),
+ v.CardText(
+ class_="text-h5 font-weight-bold",
+ children=[
+ '"Turns out semicolon-less style is easier and safer in TS because most gotcha edge cases are type invalid as well."'
+ ],
+ ),
+ v.CardActions(
+ children=[
+ v.ListItem(
+ class_="flex-grow",
+ children=[
+ v.ListItemAvatar(
+ color="grey darken-3",
+ children=[
+ v.Img(
+ class_="elevation-6",
+ alt="",
+ src="https://avataaars.io/?avatarStyle=Transparent&topType=ShortHairShortCurly&accessoriesType=Prescription02&hairColor=Black&facialHairType=Blank&clotheType=Hoodie&clotheColor=White&eyeType=Default&eyebrowType=DefaultNatural&mouthType=Default&skinColor=Light",
+ )
+ ],
+ ),
+ v.ListItemContent(children=[v.ListItemTitle(children=["Evan You"])]),
+ v.Container(
+ class_="flex",
+ children=[
+ v.Icon(class_="mr-1", children=["mdi-heart"]),
+ v.Html(tag="span", class_="subheading mr-2", children=["256"]),
+ v.Html(tag="span", class_="mr-1", children=["·"]),
+ v.Icon(class_="mr-1", children=["mdi-share-variant"]),
+ v.Html(tag="span", class_="subheading", children=["45"]),
+ ],
+ ),
+ ],
+ )
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Card/twitter_card.vue b/docs/component/Card/twitter_card.vue
new file mode 100644
index 00000000..0c4880b7
--- /dev/null
+++ b/docs/component/Card/twitter_card.vue
@@ -0,0 +1,37 @@
+
+
+
+ mdi-twitter
+ Twitter
+
+
+
+ "Turns out semicolon-less style is easier and safer in TS because most
+ gotcha edge cases are type invalid as well."
+
+
+
+
+
+
+
+
+
+ Evan You
+
+
+
+ mdi-heart
+ 256
+ ·
+ mdi-share-variant
+ 45
+
+
+
+
+
diff --git a/docs/component/Card/usage.py b/docs/component/Card/usage.py
new file mode 100644
index 00000000..e22d6791
--- /dev/null
+++ b/docs/component/Card/usage.py
@@ -0,0 +1,19 @@
+import ipyvuetify as v
+
+v.Card(
+ children=[
+ v.CardTitle(children=["Card title"]),
+ v.CardSubtitle(children=["Subtitle text"]),
+ v.CardText(
+ children=[
+ "Greyhound divisively hello coldly wonderfully marginally far upon excluding."
+ ]
+ ),
+ v.CardActions(
+ children=[
+ v.Btn(text=True, color="primary", children=["Action 1"]),
+ v.Btn(text=True, color="primary", children=["Action 2"]),
+ ]
+ ),
+ ]
+)
diff --git a/docs/component/Card/weather_card.py b/docs/component/Card/weather_card.py
new file mode 100644
index 00000000..f0030322
--- /dev/null
+++ b/docs/component/Card/weather_card.py
@@ -0,0 +1,86 @@
+import ipyvuetify as v
+
+labels = ["SU", "MO", "TU", "WED", "TH", "FR", "SA"]
+forecast = [
+ {"day": "'Tuesday", "icon": "mdi-white-balance-sunny", "temp": "24\xB0/12\xB0"},
+ {"day": "Wednesday", "icon": "mdi-white-balance-sunny", "temp": "22\xB0/14\xB0"},
+ {"day": "Thursday", "icon": "mdi-cloud", "temp": "25\xB0/15\xB0"},
+]
+
+v.Card(
+ class_="mx-auto my-2",
+ min_width=500,
+ children=[
+ v.ListItem(
+ two_line=True,
+ children=[
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(
+ children=[
+ v.Html(
+ tag="h3", class_="text--primary", children=["San Francisco"]
+ ),
+ ]
+ ),
+ v.ListItemSubtitle(children=["Mon, 12:30 PM, Mostly sunny"]),
+ ]
+ )
+ ],
+ ),
+ v.CardText(
+ children=[
+ v.Row(
+ align="center",
+ children=[
+ v.Col(
+ cols=6,
+ children=[
+ v.Html(tag="h1", children=["23°C"], class_="text--primary"),
+ ],
+ ),
+ v.Col(
+ cols=6,
+ children=[
+ v.Img(
+ src="https://cdn.vuetifyjs.com/images/cards/sun.png",
+ alt="Sunny image",
+ width="92",
+ )
+ ],
+ ),
+ ],
+ )
+ ]
+ ),
+ v.ListItem(
+ children=[
+ v.ListItemIcon(children=[v.Icon(children=["mdi-send"])]),
+ v.ListItemSubtitle(children=["23 km/h"]),
+ ]
+ ),
+ v.ListItem(
+ children=[
+ v.ListItemIcon(children=[v.Icon(children=["mdi-cloud-download"])]),
+ v.ListItemSubtitle(children=["48%"]),
+ ]
+ ),
+ v.Slider(v_model=0, max=6, tick_labels=labels, class_="mx-4", ticks=True),
+ v.List(
+ class_="transparent",
+ children=[
+ v.ListItem(
+ key=i,
+ children=[
+ v.ListItemTitle(children=[day["day"]]),
+ v.ListItemIcon(children=[v.Icon(children=[day["icon"]])]),
+ v.ListItemSubtitle(class_="text-right", children=[day["temp"]]),
+ ],
+ )
+ for i, day in enumerate(forecast)
+ ],
+ ),
+ v.Divider(),
+ v.CardActions(children=[v.Btn(text=True, children=["Full Report"])]),
+ ],
+)
diff --git a/docs/component/Card/weather_card.vue b/docs/component/Card/weather_card.vue
new file mode 100644
index 00000000..ea628ae6
--- /dev/null
+++ b/docs/component/Card/weather_card.vue
@@ -0,0 +1,65 @@
+
+
+
+
+ San Francisco
+ Mon, 12:30 PM, Mostly sunny
+
+
+
+
+
+ 23°C
+
+
+
+
+
+
+
+
+ mdi-send
+
+ 23 km/h
+
+
+
+
+ mdi-cloud-download
+
+ 48%
+
+
+
+
+
+
+ {{ item.day }}
+
+
+ {{ item.icon }}
+
+
+
+ {{ item.temp }}
+
+
+
+
+
+
+
+ Full Report
+
+
+
diff --git a/docs/component/Carousel.rst b/docs/component/Carousel.rst
new file mode 100644
index 00000000..33512113
--- /dev/null
+++ b/docs/component/Carousel.rst
@@ -0,0 +1,196 @@
+Carousel
+========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Carousel ` component is used to display large numbers of visual content on a rotating timer. It expands upon v-window by providing additional features targeted at displaying images.
+
+.. api::
+
+ - :py:class:`ipyvuetify.Carousel`
+ - :py:class:`ipyvuetify.CarouselItem`
+ - :py:class:`ipyvuetify.CarouselReverseTransition`
+ - :py:class:`ipyvuetify.CarouselTransition`
+
+Usage
+-----
+
+The Carousel component expands upon the window component by providing additional features targeted at displaying images.
+
+.. jupyter-execute:: Carousel/usage.py
+ :raises:
+
+Custom delimiters
+-----------------
+
+Use any available icon as your carousel's slide delimiter.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Carousel/custom_delimiters.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Carousel/custom_delimiters.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: Carousel/custom_delimiters.vue
+
+Custom transition
+-----------------
+
+The :py:class:`CarouselItem ` component can have its
+transition/reverse-transition changed.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Carousel/custom_transition.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Carousel/custom_transition.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: Carousel/custom_transition.vue
+
+Cycle
+-----
+
+With the ``cycle`` prop you can have your slides automatically transition to the next available every 6 seconds (default).
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Carousel/cycle.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Carousel/cycle.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: Carousel/cycle.vue
+
+Hide controls
+-------------
+
+You can hide the carousel navigation controls with ``show_arrows=False``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Carousel/hide_controls.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Carousel/hide_controls.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: Carousel/hide_controls.vue
+
+Customized arrows
+-----------------
+
+Arrows can be customized by using the ``prev`` and ``next`` slots to replace the
+default navigation controls.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Carousel/customized_arrows.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Carousel/customized_arrows.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: Carousel/customized_arrows.vue
+
+Hide delimiters
+---------------
+
+You can hide the bottom controls with ``hide-delimiters`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Carousel/hide_delimiters.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Carousel/hide_delimiters.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: Carousel/hide_delimiters.vue
+
+Progress
+--------
+
+You can show a linear progress bar with the ``progress`` prop. It will indicate
+how far into the cycle the carousel currently is.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Carousel/progress.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Carousel/progress.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: Carousel/progress.vue
+
+Model
+-----
+
+You can control the carousel with ``v_model``. This example demonstrates manual
+control with buttons. This example will start the carousel on the 3rd slide.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Carousel/model.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Carousel/model.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: Carousel/model.vue
+
diff --git a/docs/component/Carousel/custom_delimiters.py b/docs/component/Carousel/custom_delimiters.py
new file mode 100644
index 00000000..241a8061
--- /dev/null
+++ b/docs/component/Carousel/custom_delimiters.py
@@ -0,0 +1,31 @@
+import ipyvuetify as v
+
+colors = ["primary", "secondary", "error", "success", "warning"]
+
+v.Carousel(
+ continuous=False,
+ cycle=False,
+ show_arrows=False,
+ hide_delimiter_background=True,
+ delimiter_icon="mdi-minus",
+ children=[
+ v.CarouselItem(
+ children=[
+ v.Sheet(
+ color=color,
+ height="100%",
+ tile=True,
+ children=[
+ v.Row(
+ class_="fill-height",
+ align="center",
+ justify="center",
+ children=[v.Html(tag="h1", children=[f"Slide {i + 1}"])],
+ )
+ ],
+ )
+ ]
+ )
+ for i, color in enumerate(colors)
+ ],
+)
diff --git a/docs/component/Carousel/custom_delimiters.vue b/docs/component/Carousel/custom_delimiters.vue
new file mode 100644
index 00000000..4daf13b3
--- /dev/null
+++ b/docs/component/Carousel/custom_delimiters.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+ {{ slide }} Slide
+
+
+
+
+
diff --git a/docs/component/Carousel/custom_transition.py b/docs/component/Carousel/custom_transition.py
new file mode 100644
index 00000000..b59ca736
--- /dev/null
+++ b/docs/component/Carousel/custom_transition.py
@@ -0,0 +1,19 @@
+import ipyvuetify as v
+
+items = [
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/sky.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/bird.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/planet.jpg"},
+]
+
+v.Carousel(
+ children=[
+ v.CarouselItem(
+ reverse_transition="fade-transition",
+ transition="fade-transition",
+ children=[v.Img(src=item["src"])],
+ )
+ for item in items
+ ]
+)
diff --git a/docs/component/Carousel/custom_transition.vue b/docs/component/Carousel/custom_transition.vue
new file mode 100644
index 00000000..2d050ff7
--- /dev/null
+++ b/docs/component/Carousel/custom_transition.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/docs/component/Carousel/customized_arrows.py b/docs/component/Carousel/customized_arrows.py
new file mode 100644
index 00000000..633f7a3d
--- /dev/null
+++ b/docs/component/Carousel/customized_arrows.py
@@ -0,0 +1,46 @@
+import ipyvuetify as v
+
+colors = ["primary", "secondary", "error", "success", "warning"]
+
+v.Carousel(
+ height="400px",
+ hide_delimiter_background=True,
+ show_arrows_on_hover=True,
+ children=[
+ v.CarouselItem(
+ children=[
+ v.Sheet(
+ color=color,
+ height="100%",
+ children=[
+ v.Row(
+ class_="fill-height",
+ align="center",
+ justify="center",
+ children=[v.Html(tag="h2", children=[f"{i + 1} Slide"])],
+ )
+ ],
+ )
+ ]
+ )
+ for i, color in enumerate(colors)
+ ],
+ v_slots=[
+ {
+ "name": "prev",
+ "variable": "var",
+ "children": [
+ v.Btn(
+ color="success", children=["Previous slide"], v_bind="var.attrs", v_on="var.on"
+ )
+ ],
+ },
+ {
+ "name": "next",
+ "variable": "var",
+ "children": [
+ v.Btn(color="info", children=["Next slide"], v_bind="var.attrs", v_on="var.on")
+ ],
+ },
+ ],
+)
diff --git a/docs/component/Carousel/customized_arrows.vue b/docs/component/Carousel/customized_arrows.vue
new file mode 100644
index 00000000..ad804ff8
--- /dev/null
+++ b/docs/component/Carousel/customized_arrows.vue
@@ -0,0 +1,17 @@
+
+
+
+ Previous slide
+
+
+ Next slide
+
+
+
+
+ {{ slide }} Slide
+
+
+
+
+
diff --git a/docs/component/Carousel/cycle.py b/docs/component/Carousel/cycle.py
new file mode 100644
index 00000000..5d4d59d9
--- /dev/null
+++ b/docs/component/Carousel/cycle.py
@@ -0,0 +1,30 @@
+import ipyvuetify as v
+
+colors = ["primary", "secondary", "error", "success", "warning"]
+
+v.Carousel(
+ continuous=False,
+ cycle=True,
+ hide_delimiter_background=True,
+ show_arrows_on_hover=True,
+ children=[
+ v.CarouselItem(
+ children=[
+ v.Sheet(
+ color=color,
+ height="100%",
+ tile=True,
+ children=[
+ v.Row(
+ class_="fill-height",
+ align="center",
+ justify="center",
+ children=[v.Html(tag="h1", children=[f"Slide {i + 1}"])],
+ )
+ ],
+ )
+ ]
+ )
+ for i, color in enumerate(colors)
+ ],
+)
diff --git a/docs/component/Carousel/cycle.vue b/docs/component/Carousel/cycle.vue
new file mode 100644
index 00000000..bf0a9781
--- /dev/null
+++ b/docs/component/Carousel/cycle.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+ {{ slide }} Slide
+
+
+
+
+
diff --git a/docs/component/Carousel/hide_controls.py b/docs/component/Carousel/hide_controls.py
new file mode 100644
index 00000000..6dc5120c
--- /dev/null
+++ b/docs/component/Carousel/hide_controls.py
@@ -0,0 +1,15 @@
+import ipyvuetify as v
+
+items = [
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/sky.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/bird.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/planet.jpg"},
+]
+
+v.Carousel(
+ continuous=False,
+ cycle=True,
+ show_arrows=False,
+ children=[v.CarouselItem(children=[v.Img(src=item["src"])]) for item in items],
+)
diff --git a/docs/component/Carousel/hide_controls.vue b/docs/component/Carousel/hide_controls.vue
new file mode 100644
index 00000000..e1eb808a
--- /dev/null
+++ b/docs/component/Carousel/hide_controls.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/docs/component/Carousel/hide_delimiters.py b/docs/component/Carousel/hide_delimiters.py
new file mode 100644
index 00000000..0574311d
--- /dev/null
+++ b/docs/component/Carousel/hide_delimiters.py
@@ -0,0 +1,13 @@
+import ipyvuetify as v
+
+items = [
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/sky.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/bird.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/planet.jpg"},
+]
+
+v.Carousel(
+ hide_delimiters=True,
+ children=[v.CarouselItem(children=[v.Img(src=item["src"])]) for item in items],
+)
diff --git a/docs/component/Carousel/hide_delimiters.vue b/docs/component/Carousel/hide_delimiters.vue
new file mode 100644
index 00000000..b129adfc
--- /dev/null
+++ b/docs/component/Carousel/hide_delimiters.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/docs/component/Carousel/model.py b/docs/component/Carousel/model.py
new file mode 100644
index 00000000..deeb35af
--- /dev/null
+++ b/docs/component/Carousel/model.py
@@ -0,0 +1,27 @@
+import ipyvuetify as v
+
+colors = ["primary", "secondary", "error", "success", "warning"]
+
+v.Carousel(
+ v_model=2,
+ children=[
+ v.CarouselItem(
+ children=[
+ v.Sheet(
+ color=color,
+ height="100%",
+ tile=True,
+ children=[
+ v.Row(
+ class_="fill-height",
+ align="center",
+ justify="center",
+ children=[v.Html(tag="h1", children=[f"Slide {i + 1}"])],
+ )
+ ],
+ )
+ ]
+ )
+ for i, color in enumerate(colors)
+ ],
+)
diff --git a/docs/component/Carousel/model.vue b/docs/component/Carousel/model.vue
new file mode 100644
index 00000000..0ebf5181
--- /dev/null
+++ b/docs/component/Carousel/model.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
+ {{ slide }} Slide
+
+
+
+
+
diff --git a/docs/component/Carousel/progress.py b/docs/component/Carousel/progress.py
new file mode 100644
index 00000000..20348a3c
--- /dev/null
+++ b/docs/component/Carousel/progress.py
@@ -0,0 +1,14 @@
+import ipyvuetify as v
+
+items = [
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/squirrel.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/sky.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/bird.jpg"},
+ {"src": "https://cdn.vuetifyjs.com/images/carousel/planet.jpg"},
+]
+
+v.Carousel(
+ hide_delimiters=True,
+ progress=True,
+ children=[v.CarouselItem(children=[v.Img(src=item["src"])]) for item in items],
+)
diff --git a/docs/component/Carousel/progress.vue b/docs/component/Carousel/progress.vue
new file mode 100644
index 00000000..cf04bdcf
--- /dev/null
+++ b/docs/component/Carousel/progress.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/docs/component/Carousel/usage.py b/docs/component/Carousel/usage.py
new file mode 100644
index 00000000..d86add4b
--- /dev/null
+++ b/docs/component/Carousel/usage.py
@@ -0,0 +1,27 @@
+import ipyvuetify as v
+
+colors = ["primary", "secondary", "error", "success", "warning"]
+
+v.Carousel(
+ v_model="model",
+ children=[
+ v.CarouselItem(
+ children=[
+ v.Sheet(
+ color=color,
+ height="100%",
+ tile=True,
+ children=[
+ v.Row(
+ class_="fill-height",
+ align="center",
+ justify="center",
+ children=[v.Html(tag="h1", children=[f"Slide {i + 1}"])],
+ )
+ ],
+ )
+ ]
+ )
+ for i, color in enumerate(colors)
+ ],
+)
diff --git a/docs/component/Checkbox.rst b/docs/component/Checkbox.rst
new file mode 100644
index 00000000..706c1f7c
--- /dev/null
+++ b/docs/component/Checkbox.rst
@@ -0,0 +1,157 @@
+Checkbox
+========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Checkbox ` component provides users the ability
+to choose between two distinct values. These are very similar to a switch and can
+be used in complex forms and checklists. A simpler version,
+:py:class:`SimpleCheckbox ` is used primarily as a
+lightweight alternative in data-table components to select rows or display inline
+boolean data.
+
+Usage
+-----
+
+A :py:class:`Checkbox ` in its simplest form provides a toggle
+between 2 values.
+
+.. jupyter-execute:: Checkbox/usage.py
+ :raises:
+
+.. api::
+
+ - :py:class:`ipyvuetify.Checkbox`
+ - :py:class:`ipyvuetify.SimpleCheckbox`
+
+Colors
+------
+
+Checkboxes can be colored by using any of the builtin colors and contextual names
+using the ``color`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Checkbox/colors.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Checkbox/colors.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Checkbox/colors.vue
+
+Model as Array
+--------------
+
+Multiple :py:class:`Checkbox `'s can share the same ``v_model`` by using an array.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Checkbox/model_as_array.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Checkbox/model_as_array.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Checkbox/model_as_array.vue
+
+Model as boolean
+----------------
+
+A single :py:class:`Checkbox ` will have a boolean value as its value.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Checkbox/model_as_boolean.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Checkbox/model_as_boolean.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Checkbox/model_as_boolean.vue
+
+States
+------
+
+:py:class:`Checkbox ` can have different states such as default,
+disabled, and indeterminate.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Checkbox/states.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Checkbox/states.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Checkbox/states.vue
+
+Label slot
+----------
+
+Checkbox labels can be defined in ``label`` slot - that will allow to use HTML content.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Checkbox/label_slot.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Checkbox/label_slot.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Checkbox/label_slot.vue
+
+Inline text field
+-----------------
+
+You can place :py:class:`Checkbox ` in line with other components
+such as :py:class:`TextField `.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Checkbox/inline_text_field.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Checkbox/inline_text_field.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Checkbox/inline_text_field.vue
+
diff --git a/docs/component/Checkbox/colors.py b/docs/component/Checkbox/colors.py
new file mode 100644
index 00000000..70a32700
--- /dev/null
+++ b/docs/component/Checkbox/colors.py
@@ -0,0 +1,129 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ v_model="red",
+ label="red",
+ color="red",
+ value="red",
+ hide_details=True,
+ ),
+ v.Checkbox(
+ v_model="red darken-3",
+ label="red darken-3",
+ color="red darken-3",
+ value="red darken-3",
+ hide_details=True,
+ ),
+ ],
+ ),
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ v_model="indigo",
+ label="indigo",
+ color="indigo",
+ value="indigo",
+ hide_details=True,
+ ),
+ v.Checkbox(
+ v_model="indigo darken-3",
+ label="indigo darken-3",
+ color="indigo darken-3",
+ value="indigo darken-3",
+ hide_details=True,
+ ),
+ ],
+ ),
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ v_model="orange",
+ label="orange",
+ color="orange",
+ value="orange",
+ hide_details=True,
+ ),
+ v.Checkbox(
+ v_model="orange darken-3",
+ label="orange darken-3",
+ color="orange darken-3",
+ value="orange darken-3",
+ hide_details=True,
+ ),
+ ],
+ ),
+ ]
+ ),
+ v.Row(
+ class_="mt-12",
+ children=[
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ v_model="primary",
+ label="primary",
+ color="primary",
+ value="primary",
+ hide_details=True,
+ ),
+ v.Checkbox(
+ v_model="secondary",
+ label="secondary",
+ color="secondary",
+ value="secondary",
+ hide_details=True,
+ ),
+ ],
+ ),
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ v_model="success",
+ label="success",
+ color="success",
+ value="success",
+ hide_details=True,
+ ),
+ v.Checkbox(
+ v_model="info",
+ label="info",
+ color="info",
+ value="info",
+ hide_details=True,
+ ),
+ ],
+ ),
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ v_model="warning",
+ label="warning",
+ color="warning",
+ value="warning",
+ hide_details=True,
+ ),
+ v.Checkbox(
+ v_model="error",
+ label="error",
+ color="error",
+ value="error",
+ hide_details=True,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ]
+)
diff --git a/docs/component/Checkbox/colors.vue b/docs/component/Checkbox/colors.vue
new file mode 100644
index 00000000..c8efe61f
--- /dev/null
+++ b/docs/component/Checkbox/colors.vue
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Checkbox/inline_text_field.py b/docs/component/Checkbox/inline_text_field.py
new file mode 100644
index 00000000..5f71a50d
--- /dev/null
+++ b/docs/component/Checkbox/inline_text_field.py
@@ -0,0 +1,52 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+container = v.Container(
+ children=[
+ v.Card(
+ children=[
+ v.CardText(
+ children=[
+ v.Html(
+ tag="div",
+ class_="flex align-center",
+ children=[
+ v.Checkbox(
+ v_model=False,
+ hide_details=True,
+ class_="shrink mr-2 mt-0 d-inline-flex",
+ ),
+ v.TextField(label="Include files", class_="d-inline-flex"),
+ ],
+ ),
+ v.Html(
+ tag="div",
+ class_="flex align-center",
+ children=[
+ (
+ checkbox := v.Checkbox(
+ v_model=True,
+ hide_details=True,
+ class_="shrink mr-2 mt-0 d-inline-flex",
+ )
+ ),
+ (
+ text_field := v.TextField(
+ label="I only work if you uncheck the box",
+ disabled=True,
+ class_="d-inline-flex",
+ )
+ ),
+ ],
+ ),
+ ]
+ ),
+ ]
+ ),
+ ]
+)
+
+jslink((checkbox, "v_model"), (text_field, "disabled"))
+
+container
diff --git a/docs/component/Checkbox/inline_text_field.vue b/docs/component/Checkbox/inline_text_field.vue
new file mode 100644
index 00000000..2fc616e9
--- /dev/null
+++ b/docs/component/Checkbox/inline_text_field.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Checkbox/label_slot.py b/docs/component/Checkbox/label_slot.py
new file mode 100644
index 00000000..fd1e8315
--- /dev/null
+++ b/docs/component/Checkbox/label_slot.py
@@ -0,0 +1,40 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Checkbox(
+ v_model=False,
+ v_slots=[
+ {
+ "name": "label",
+ "variable": "label",
+ "children": v.Html(
+ tag="div",
+ children=[
+ "I agree that ",
+ v.Tooltip(
+ bottom=True,
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "activator",
+ "children": v.Html(
+ tag="a",
+ v_on="activator.on",
+ attributes={
+ "href": "https://vuetifyjs.com",
+ "target": "_blank",
+ },
+ children=["Vuetify"],
+ ),
+ }
+ ],
+ ),
+ " is awesome",
+ ],
+ ),
+ }
+ ],
+ )
+ ]
+)
diff --git a/docs/component/Checkbox/label_slot.vue b/docs/component/Checkbox/label_slot.vue
new file mode 100644
index 00000000..f049bbb6
--- /dev/null
+++ b/docs/component/Checkbox/label_slot.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+ I agree that
+
+
+
+ Vuetify
+
+
+ Opens in new window
+
+ is awesome
+
+
+
+
+
diff --git a/docs/component/Checkbox/model_as_array.py b/docs/component/Checkbox/model_as_array.py
new file mode 100644
index 00000000..8e1cbdc2
--- /dev/null
+++ b/docs/component/Checkbox/model_as_array.py
@@ -0,0 +1,8 @@
+import ipyvuetify as v
+
+selected = ["John"]
+
+checkbox1 = v.Checkbox(v_model=selected, label="John", value="John")
+checkbox2 = v.Checkbox(v_model=selected, label="Jacob", value="Jacob")
+
+v.Container(children=[checkbox1, checkbox2])
diff --git a/docs/component/Checkbox/model_as_array.vue b/docs/component/Checkbox/model_as_array.vue
new file mode 100644
index 00000000..f2ea06f4
--- /dev/null
+++ b/docs/component/Checkbox/model_as_array.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/docs/component/Checkbox/model_as_boolean.py b/docs/component/Checkbox/model_as_boolean.py
new file mode 100644
index 00000000..b1b97d63
--- /dev/null
+++ b/docs/component/Checkbox/model_as_boolean.py
@@ -0,0 +1,8 @@
+import ipyvuetify as v
+
+checkbox1 = v.Checkbox(v_model=True, label="Checkbox 1")
+checkbox2 = v.Checkbox(v_model=False, label="Checkbox 2")
+checkbox1.label = "Checked" if checkbox1.v_model else "Unchecked"
+checkbox2.label = "Checked" if checkbox2.v_model else "Unchecked"
+
+v.Container(children=[checkbox1, checkbox2])
diff --git a/docs/component/Checkbox/model_as_boolean.vue b/docs/component/Checkbox/model_as_boolean.vue
new file mode 100644
index 00000000..f2ea06f4
--- /dev/null
+++ b/docs/component/Checkbox/model_as_boolean.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
diff --git a/docs/component/Checkbox/states.py b/docs/component/Checkbox/states.py
new file mode 100644
index 00000000..9da23148
--- /dev/null
+++ b/docs/component/Checkbox/states.py
@@ -0,0 +1,74 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Row(
+ class_="light--text",
+ children=[
+ v.Col(cols=4, children=["on"]),
+ v.Col(cols=4, children=["off"]),
+ v.Col(cols=4, children=["indeterminate"]),
+ ],
+ ),
+ v.Row(
+ children=[
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ input_value=True,
+ value=True,
+ ),
+ ],
+ ),
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ value=False,
+ ),
+ ],
+ ),
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ value=True,
+ indeterminate=True,
+ ),
+ ],
+ ),
+ ]
+ ),
+ v.Row(
+ class_="light--text",
+ children=[
+ v.Col(cols=4, children=["on disabled"]),
+ v.Col(cols=4, children=["off disabled"]),
+ ],
+ ),
+ v.Row(
+ children=[
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ input_value=True,
+ value=True,
+ disabled=True,
+ ),
+ ],
+ ),
+ v.Col(
+ cols=4,
+ children=[
+ v.Checkbox(
+ value=False,
+ disabled=True,
+ ),
+ ],
+ ),
+ ]
+ ),
+ ]
+)
diff --git a/docs/component/Checkbox/states.vue b/docs/component/Checkbox/states.vue
new file mode 100644
index 00000000..0011f4fb
--- /dev/null
+++ b/docs/component/Checkbox/states.vue
@@ -0,0 +1,32 @@
+
+
+
+ on
+ off
+ indeterminate
+
+
+
+
+
+
+
+
+
+
+
+
+
+ on disabled
+ off disabled
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Checkbox/usage.py b/docs/component/Checkbox/usage.py
new file mode 100644
index 00000000..fff8fdd4
--- /dev/null
+++ b/docs/component/Checkbox/usage.py
@@ -0,0 +1,3 @@
+import ipyvuetify as v
+
+v.Container(children=[v.Checkbox(v_model=True, label="Checkbox 1")])
diff --git a/docs/component/Chip.rst b/docs/component/Chip.rst
new file mode 100644
index 00000000..6bb2e484
--- /dev/null
+++ b/docs/component/Chip.rst
@@ -0,0 +1,216 @@
+Chip
+====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Chip ` component is used to convey small pieces of information.
+Using the ``close`` property, the chip becomes interactive, allowing user interaction.
+This component is used by the :py:class:`ChipGroup ` for advanced selection options.
+
+Usage
+-----
+
+Chips come in the following variations: closeable, colored, outlined, and sized.
+The default slot allows you to customize the content inside the chip.
+
+.. jupyter-execute:: Chip/usage.py
+ :raises:
+
+.. api::
+
+ - :py:class:`ipyvuetify.Chip`
+ - :py:class:`ipyvuetify.ChipGroup`
+
+Closeable
+---------
+
+Closeable chips can be controlled with a ``v_model``. You can also listen to the
+``click:close`` event to perform actions when the chip is closed.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Chip/closeable.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Chip/closeable.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Chip/closeable.vue
+
+Colored
+-------
+
+Any color from the Material Design palette can be used to change a chip's color.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Chip/colored.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Chip/colored.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Chip/colored.vue
+
+Draggable
+---------
+
+``draggable`` :py:class:`Chip ` component can be dragged by mouse.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Chip/draggable.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Chip/draggable.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Chip/draggable.vue
+
+Filter
+------
+
+:py:class:`Chip ` component has ``filter`` option which shows an
+additional icon to you if chip is active. It can be customized using ``filter-icon``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Chip/filter.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Chip/filter.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Chip/filter.vue
+
+Label
+-----
+
+Label chips use the :py:class:`Card ` border-radius.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Chip/label.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Chip/label.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Chip/label.vue
+
+No ripple
+---------
+
+:py:class:`Chip ` can be rendered without ripple if ``ripple`` prop is set to ``false``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Chip/no_ripple.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Chip/no_ripple.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Chip/no_ripple.vue
+
+Outlined
+--------
+
+Outlined chips inherit their border color from the current text color.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Chip/outlined.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Chip/outlined.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Chip/outlined.vue
+
+Sizes
+-----
+
+:py:class:`Chip ` component can have various sizes from ``x-small`` to ``x-large``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Chip/sizes.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Chip/sizes.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Chip/sizes.vue
+
+Icon
+----
+
+Chips can use text or any icon available in the Material Icons font library.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Chip/icon.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Chip/icon.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Chip/icon.vue
+
diff --git a/docs/component/Chip/closeable.py b/docs/component/Chip/closeable.py
new file mode 100644
index 00000000..ace58933
--- /dev/null
+++ b/docs/component/Chip/closeable.py
@@ -0,0 +1,32 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Chip(class_="ma-2", close_=True, v_model=True, children=["Closable"]),
+ v.Chip(
+ class_="ma-2",
+ close_=True,
+ color="red",
+ text_color="white",
+ v_model=True,
+ children=["Remove"],
+ ),
+ v.Chip(
+ class_="ma-2",
+ close_=True,
+ color="green",
+ outlined=True,
+ v_model=True,
+ children=["Success"],
+ ),
+ v.Chip(
+ class_="ma-2",
+ close_=True,
+ color="orange",
+ label=True,
+ outlined=True,
+ v_model=True,
+ children=["Complete"],
+ ),
+ ]
+)
diff --git a/docs/component/Chip/closeable.vue b/docs/component/Chip/closeable.vue
new file mode 100644
index 00000000..cb21cbf3
--- /dev/null
+++ b/docs/component/Chip/closeable.vue
@@ -0,0 +1,51 @@
+
+
+
+ Reset Chips
+
+
+
+ Closable
+
+
+
+ Remove
+
+
+
+ Success
+
+
+
+ Complete
+
+
+
diff --git a/docs/component/Chip/colored.py b/docs/component/Chip/colored.py
new file mode 100644
index 00000000..d68f2e07
--- /dev/null
+++ b/docs/component/Chip/colored.py
@@ -0,0 +1,10 @@
+import ipyvuetify as v
+
+colors = ["primary", "secondary", "success", "info", "warning", "error"]
+
+v.Container(
+ children=[
+ v.Chip(class_="ma-2", color=color, text_color="white", children=[color.capitalize()])
+ for color in colors
+ ]
+)
diff --git a/docs/component/Chip/colored.vue b/docs/component/Chip/colored.vue
new file mode 100644
index 00000000..4abe2385
--- /dev/null
+++ b/docs/component/Chip/colored.vue
@@ -0,0 +1,9 @@
+
+
+ Default
+ Primary
+ Secondary
+ Red Chip
+ Green Chip
+
+
diff --git a/docs/component/Chip/draggable.py b/docs/component/Chip/draggable.py
new file mode 100644
index 00000000..0cfa714a
--- /dev/null
+++ b/docs/component/Chip/draggable.py
@@ -0,0 +1,7 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Chip(class_="ma-2", draggable=True, children=["Default"]),
+ ]
+)
diff --git a/docs/component/Chip/draggable.vue b/docs/component/Chip/draggable.vue
new file mode 100644
index 00000000..2ea31f15
--- /dev/null
+++ b/docs/component/Chip/draggable.vue
@@ -0,0 +1,5 @@
+
+
+ Default
+
+
diff --git a/docs/component/Chip/filter.py b/docs/component/Chip/filter.py
new file mode 100644
index 00000000..4322432b
--- /dev/null
+++ b/docs/component/Chip/filter.py
@@ -0,0 +1,19 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+chip1 = v.Chip(class_="ma-2", input_value=True, filter=True, children=["I'm v-chip"])
+chip2 = v.Chip(
+ class_="ma-2", input_value=True, filter=True, filter_icon="mdi-plus", children=["I'm v-chip"]
+)
+chip3 = v.Chip(
+ class_="ma-2", input_value=True, filter=True, filter_icon="mdi-minus", children=["I'm v-chip"]
+)
+
+switch = v.Switch(v_model=True, label="Active")
+
+jslink((switch, "v_model"), (chip1, "input_value"))
+jslink((switch, "v_model"), (chip2, "input_value"))
+jslink((switch, "v_model"), (chip3, "input_value"))
+
+v.Container(children=[chip1, chip2, chip3, switch])
diff --git a/docs/component/Chip/filter.vue b/docs/component/Chip/filter.vue
new file mode 100644
index 00000000..84e9c8df
--- /dev/null
+++ b/docs/component/Chip/filter.vue
@@ -0,0 +1,15 @@
+
+
+ I'm v-chip
+
+
+ I'm v-chip
+
+
+
+ I'm v-chip
+
+
+
+
+
diff --git a/docs/component/Chip/icon.py b/docs/component/Chip/icon.py
new file mode 100644
index 00000000..02b738fe
--- /dev/null
+++ b/docs/component/Chip/icon.py
@@ -0,0 +1,53 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Chip(
+ class_="ma-2",
+ color="indigo",
+ text_color="white",
+ children=[
+ v.Avatar(left=True, children=[v.Icon(children=["mdi-account-circle"])]),
+ "Mike",
+ ],
+ ),
+ v.Chip(
+ class_="ma-2",
+ color="orange",
+ text_color="white",
+ children=["Premium", v.Icon(right=True, children=["mdi-star"])],
+ ),
+ v.Chip(
+ class_="ma-2",
+ color="primary",
+ text_color="white",
+ children=["1 Year", v.Icon(right=True, children=["mdi-cake-variant"])],
+ ),
+ v.Chip(
+ class_="ma-2",
+ color="green",
+ text_color="white",
+ children=[v.Avatar(left=True, class_="green darken-4", children=["1"]), "Years"],
+ ),
+ v.Chip(
+ class_="ma-2",
+ close_=True,
+ color="teal",
+ text_color="white",
+ children=[
+ v.Avatar(left=True, children=[v.Icon(children=["mdi-checkbox-marked-circle"])]),
+ "Confirmed",
+ ],
+ ),
+ v.Chip(
+ class_="ma-2",
+ close_=True,
+ color="teal",
+ text_color="white",
+ children=[
+ v.Avatar(left=True, children=[v.Icon(children=["mdi-checkbox-marked-circle"])]),
+ "Confirmed",
+ ],
+ ),
+ ]
+)
diff --git a/docs/component/Chip/icon.vue b/docs/component/Chip/icon.vue
new file mode 100644
index 00000000..5616c6d7
--- /dev/null
+++ b/docs/component/Chip/icon.vue
@@ -0,0 +1,52 @@
+
+
+
+
+ mdi-account-circle
+
+ Mike
+
+
+
+ Premium
+ mdi-star
+
+
+
+ 1 Year
+ mdi-cake-variant
+
+
+
+ 1
+ Years
+
+
+
+
+ mdi-checkbox-marked-circle
+
+ Confirmed
+
+
+
+
+ mdi-checkbox-marked-circle
+
+ Confirmed
+
+
+
diff --git a/docs/component/Chip/label.py b/docs/component/Chip/label.py
new file mode 100644
index 00000000..ea1baec6
--- /dev/null
+++ b/docs/component/Chip/label.py
@@ -0,0 +1,28 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Chip(class_="ma-2", label=True, children=["Label"]),
+ v.Chip(
+ class_="ma-2",
+ color="pink",
+ label=True,
+ text_color="white",
+ children=[v.Icon(left=True, children=["mdi-label"]), "Tags"],
+ ),
+ v.Chip(
+ class_="ma-2",
+ color="primary",
+ label=True,
+ children=[v.Icon(left=True, children=["mdi-account-circle-outline"]), "John Leider"],
+ ),
+ v.Chip(
+ class_="ma-2",
+ close_=True,
+ color="cyan",
+ label=True,
+ text_color="white",
+ children=[v.Icon(left=True, children=["mdi-twitter"]), "New Tweets"],
+ ),
+ ]
+)
diff --git a/docs/component/Chip/label.vue b/docs/component/Chip/label.vue
new file mode 100644
index 00000000..10d1ba29
--- /dev/null
+++ b/docs/component/Chip/label.vue
@@ -0,0 +1,20 @@
+
+
+ Label
+
+
+ mdi-label
+ Tags
+
+
+
+ mdi-account-circle-outline
+ John Leider
+
+
+
+ mdi-twitter
+ New Tweets
+
+
+
diff --git a/docs/component/Chip/no_ripple.py b/docs/component/Chip/no_ripple.py
new file mode 100644
index 00000000..4b3231b8
--- /dev/null
+++ b/docs/component/Chip/no_ripple.py
@@ -0,0 +1,7 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Chip(class_="ma-2", ripple=False, children=["No Ripple"]),
+ ]
+)
diff --git a/docs/component/Chip/no_ripple.vue b/docs/component/Chip/no_ripple.vue
new file mode 100644
index 00000000..6b31657d
--- /dev/null
+++ b/docs/component/Chip/no_ripple.vue
@@ -0,0 +1,5 @@
+
+
+ No Ripple
+
+
diff --git a/docs/component/Chip/outlined.py b/docs/component/Chip/outlined.py
new file mode 100644
index 00000000..815fab64
--- /dev/null
+++ b/docs/component/Chip/outlined.py
@@ -0,0 +1,32 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Chip(
+ class_="ma-2",
+ color="success",
+ outlined=True,
+ children=[v.Icon(left=True, children=["mdi-server-plus"]), "Server Status"],
+ ),
+ v.Chip(
+ class_="ma-2",
+ color="primary",
+ outlined=True,
+ pill=True,
+ children=["User Account", v.Icon(right=True, children=["mdi-account-outline"])],
+ ),
+ v.Chip(
+ class_="ma-2",
+ color="deep-purple accent-4",
+ outlined=True,
+ children=[v.Icon(left=True, children=["mdi-wrench"]), "Update Settings"],
+ ),
+ v.Chip(
+ class_="ma-2",
+ close_=True,
+ color="indigo darken-3",
+ outlined=True,
+ children=[v.Icon(left=True, children=["mdi-fire"]), "New Posts Available"],
+ ),
+ ]
+)
diff --git a/docs/component/Chip/outlined.vue b/docs/component/Chip/outlined.vue
new file mode 100644
index 00000000..1733d04c
--- /dev/null
+++ b/docs/component/Chip/outlined.vue
@@ -0,0 +1,23 @@
+
+
+
+ mdi-server-plus
+ Server Status
+
+
+
+ User Account
+ mdi-account-outline
+
+
+
+ mdi-wrench
+ Update Settings
+
+
+
+ mdi-fire
+ New Posts Available
+
+
+
diff --git a/docs/component/Chip/sizes.py b/docs/component/Chip/sizes.py
new file mode 100644
index 00000000..3af9466d
--- /dev/null
+++ b/docs/component/Chip/sizes.py
@@ -0,0 +1,10 @@
+import ipyvuetify as v
+
+sizes = ["x-small", "small", "default", "large", "x-large"]
+
+kwargs = [
+ {"class_": "ma-2", size.replace("-", "_"): True, "children": [(f"{size} chip").capitalize()]}
+ for size in sizes
+]
+
+v.Container(children=[v.Chip(**kw) for kw in kwargs])
diff --git a/docs/component/Chip/sizes.vue b/docs/component/Chip/sizes.vue
new file mode 100644
index 00000000..c39b05c5
--- /dev/null
+++ b/docs/component/Chip/sizes.vue
@@ -0,0 +1,13 @@
+
+
+ x-small chip
+
+ small chip
+
+ Default
+
+ large chip
+
+ x-large chip
+
+
diff --git a/docs/component/Chip/usage.py b/docs/component/Chip/usage.py
new file mode 100644
index 00000000..bc27013f
--- /dev/null
+++ b/docs/component/Chip/usage.py
@@ -0,0 +1,14 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Chip(
+ class_="ma-2",
+ close_icon="mdi-close-outline",
+ close_=True,
+ color="purple",
+ children=["Default"],
+ text_color="white",
+ ),
+ ]
+)
diff --git a/docs/component/ChipGroup.rst b/docs/component/ChipGroup.rst
new file mode 100644
index 00000000..857c7a47
--- /dev/null
+++ b/docs/component/ChipGroup.rst
@@ -0,0 +1,158 @@
+ChipGroup
+=========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`ChipGroup ` supercharges the :py:class:`Chip `
+component by providing groupable functionality. It is used for creating groups of
+selections using chips.
+
+Usage
+-----
+
+Chip groups make it easy for users to select filtering options for more complex
+implementations. By default, :py:class:`ChipGroup ` will
+overflow to the right but can be changed to a **column** only mode.
+
+.. jupyter-execute:: ChipGroup/usage.py
+ :raises:
+
+.. api::
+
+ - :py:class:`ipyvuetify.ChipGroup`
+ - :py:class:`ipyvuetify.Chip`
+
+Column
+------
+
+Chip groups with the ``column`` prop can wrap their chips in a vertical layout.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ChipGroup/column.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ChipGroup/column.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: ChipGroup/column.vue
+
+Filter results
+--------------
+
+Easily create chip groups that provide additional feedback with the ``filter`` prop.
+This creates an alternative visual style that communicates to the user that the
+chip is selected.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ChipGroup/filter_results.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ChipGroup/filter_results.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: ChipGroup/filter_results.vue
+
+Mandatory
+---------
+
+Chip groups with the ``mandatory`` prop must always have a value selected.
+This means a chip cannot be deselected if it's the only selected one.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ChipGroup/mandatory.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ChipGroup/mandatory.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: ChipGroup/mandatory.vue
+
+Multiple
+--------
+
+Chip groups with the ``multiple`` prop can have many values selected.
+This allows you to select multiple chips at once.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ChipGroup/multiple.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ChipGroup/multiple.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: ChipGroup/multiple.vue
+
+Product card
+------------
+
+Chip groups can be used in combination with cards to create rich selection interfaces.
+This example shows a product size selector.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ChipGroup/product_card.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ChipGroup/product_card.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: ChipGroup/product_card.vue
+
+Toothbrush card
+---------------
+
+This example demonstrates how chip groups can be used to select product variations,
+such as toothbrush bristle types.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ChipGroup/toothbrush_card.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ChipGroup/toothbrush_card.py
+
+ .. tab-item:: :fab:`vuejs` Vue
+
+ .. literalinclude:: ChipGroup/toothbrush_card.vue
+
diff --git a/docs/component/ChipGroup/column.py b/docs/component/ChipGroup/column.py
new file mode 100644
index 00000000..f1384049
--- /dev/null
+++ b/docs/component/ChipGroup/column.py
@@ -0,0 +1,35 @@
+import ipyvuetify as v
+
+tags = [
+ "Work",
+ "Home Improvement",
+ "Vacation",
+ "Food",
+ "Drawers",
+ "Shopping",
+ "Art",
+ "Tech",
+ "Creative Writing",
+]
+
+chip_group = v.ChipGroup(
+ column=True, active_class="text-primary", children=[v.Chip(children=[tag]) for tag in tags]
+)
+
+v.Sheet(
+ class_="mx-auto my-2",
+ elevation=10,
+ max_width="500",
+ rounded="xl",
+ children=[
+ v.Sheet(
+ class_="pa-3 bg-primary text-right text-white",
+ rounded="t-xl",
+ children=[
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-content-save"])]),
+ v.Btn(class_="ms-2", icon=True, children=[v.Icon(children=["mdi-check-bold"])]),
+ ],
+ ),
+ v.Html(tag="div", class_="pa-4", children=[chip_group]),
+ ],
+)
diff --git a/docs/component/ChipGroup/column.vue b/docs/component/ChipGroup/column.vue
new file mode 100644
index 00000000..11c2c719
--- /dev/null
+++ b/docs/component/ChipGroup/column.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ mdi-content-save-cog-outline
+
+
+
+ mdi-check-bold
+
+
+
+
+
+
+ {{ tag }}
+
+
+
+
+
+
+
diff --git a/docs/component/ChipGroup/filter_results.py b/docs/component/ChipGroup/filter_results.py
new file mode 100644
index 00000000..6c8832ee
--- /dev/null
+++ b/docs/component/ChipGroup/filter_results.py
@@ -0,0 +1,55 @@
+import ipyvuetify as v
+
+amenities = v.ChipGroup(
+ v_model=[],
+ column=True,
+ multiple=True,
+ children=[
+ v.Chip(children=["Elevator"], outlined=True, filter=True),
+ v.Chip(children=["Washer / Dryer"], outlined=True, filter=True),
+ v.Chip(children=["Fireplace"], outlined=True, filter=True),
+ v.Chip(children=["Wheelchair access"], outlined=True, filter=True),
+ v.Chip(children=["Dogs ok"], outlined=True, filter=True),
+ v.Chip(children=["Cats ok"], outlined=True, filter=True),
+ ],
+)
+
+neighborhoods = v.ChipGroup(
+ v_model=[],
+ column=True,
+ multiple=True,
+ children=[
+ v.Chip(children=["Snowy Rock Place"], outlined=True, filter=True),
+ v.Chip(children=["Honeylane Circle"], outlined=True, filter=True),
+ v.Chip(children=["Donna Drive"], outlined=True, filter=True),
+ v.Chip(children=["Elaine Street"], outlined=True, filter=True),
+ v.Chip(children=["Court Street"], outlined=True, filter=True),
+ v.Chip(children=["Kennedy Park"], outlined=True, filter=True),
+ ],
+)
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width="400",
+ children=[
+ v.Toolbar(
+ color="deep-purple accent-4 text-white",
+ children=[
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-close"])]),
+ v.ToolbarTitle(children=["Filter results"]),
+ ],
+ ),
+ v.CardText(
+ children=[
+ v.Html(tag="h5", class_="my-2", children=["Choose amenities"]),
+ amenities,
+ ]
+ ),
+ v.CardText(
+ children=[
+ v.Html(tag="h5", class_="my-2", children=["Choose neighborhoods"]),
+ neighborhoods,
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/ChipGroup/filter_results.vue b/docs/component/ChipGroup/filter_results.vue
new file mode 100644
index 00000000..bd630787
--- /dev/null
+++ b/docs/component/ChipGroup/filter_results.vue
@@ -0,0 +1,36 @@
+
+
+
+
+ mdi-close
+
+ Filter results
+
+
+
+ Choose amenities
+
+
+ Elevator
+ Washer / Dryer
+ Fireplace
+ Wheelchair access
+ Dogs ok
+ Cats ok
+
+
+
+
+ Choose neighborhoods
+
+
+ Snowy Rock Place
+ Honeylane Circle
+ Donna Drive
+ Elaine Street
+ Court Street
+ Kennedy Park
+
+
+
+
diff --git a/docs/component/ChipGroup/mandatory.py b/docs/component/ChipGroup/mandatory.py
new file mode 100644
index 00000000..35e82070
--- /dev/null
+++ b/docs/component/ChipGroup/mandatory.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="mx-auto my-2",
+ children=[
+ v.ChipGroup(
+ active_class="text-primary",
+ v_model=0,
+ mandatory=True,
+ selected_class="text-primary",
+ children=[
+ v.Chip(children=["Work"]),
+ v.Chip(children=["Home Improvement"]),
+ v.Chip(children=["Vacation"]),
+ v.Chip(children=["Food"]),
+ v.Chip(children=["Drawers"]),
+ v.Chip(children=["Shopping"]),
+ v.Chip(children=["Art"]),
+ v.Chip(children=["Tech"]),
+ v.Chip(children=["Creative Writing"]),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/ChipGroup/mandatory.vue b/docs/component/ChipGroup/mandatory.vue
new file mode 100644
index 00000000..b17b576c
--- /dev/null
+++ b/docs/component/ChipGroup/mandatory.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ {{ tag }}
+
+
+
+
+
+
diff --git a/docs/component/ChipGroup/multiple.py b/docs/component/ChipGroup/multiple.py
new file mode 100644
index 00000000..21ee02ee
--- /dev/null
+++ b/docs/component/ChipGroup/multiple.py
@@ -0,0 +1,23 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="mx-auto my-2",
+ children=[
+ v.ChipGroup(
+ active_class="text-primary",
+ v_model=[0, 2],
+ multiple=True,
+ children=[
+ v.Chip(children=["Work"]),
+ v.Chip(children=["Home Improvement"]),
+ v.Chip(children=["Vacation"]),
+ v.Chip(children=["Food"]),
+ v.Chip(children=["Drawers"]),
+ v.Chip(children=["Shopping"]),
+ v.Chip(children=["Art"]),
+ v.Chip(children=["Tech"]),
+ v.Chip(children=["Creative Writing"]),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/ChipGroup/multiple.vue b/docs/component/ChipGroup/multiple.vue
new file mode 100644
index 00000000..adb74a03
--- /dev/null
+++ b/docs/component/ChipGroup/multiple.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ {{ tag }}
+
+
+
+
+
+
diff --git a/docs/component/ChipGroup/product_card.py b/docs/component/ChipGroup/product_card.py
new file mode 100644
index 00000000..a2230e3d
--- /dev/null
+++ b/docs/component/ChipGroup/product_card.py
@@ -0,0 +1,44 @@
+import ipyvuetify as v
+
+sizes = ["04", "06", "08", "10", "12", "14"]
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width="400",
+ children=[
+ v.CardTitle(
+ children=[
+ v.Html(tag="h2", children=["Shirt Blouse"]),
+ v.Spacer(),
+ v.Html(tag="h3", children=["$44.50"]),
+ ]
+ ),
+ v.CardText(
+ children=[
+ "Our blouses are available in 8 colors. You can custom order a built-in arch support for any of the models."
+ ]
+ ),
+ v.Divider(class_="mx-4"),
+ v.CardText(
+ children=[
+ v.Html(tag="span", class_="subheading", children=["Select size"]),
+ v.ChipGroup(
+ v_model=2,
+ active_class="deep-purple--text text--accent-4",
+ mandatory=True,
+ children=[v.Chip(children=[size]) for size in sizes],
+ ),
+ ]
+ ),
+ v.CardActions(
+ children=[
+ v.Btn(
+ block=True,
+ class_="white--text",
+ color="deep-purple accent-4",
+ children=["Add to Cart"],
+ )
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/ChipGroup/product_card.vue b/docs/component/ChipGroup/product_card.vue
new file mode 100644
index 00000000..a2565a55
--- /dev/null
+++ b/docs/component/ChipGroup/product_card.vue
@@ -0,0 +1,36 @@
+
+
+
+ Shirt Blouse
+
+ $44.50
+
+
+
+ Our blouses are available in 8 colors. You can custom order a built-in
+ arch support for any of the models.
+
+
+
+
+
+ Select size
+
+
+
+ {{ size }}
+
+
+
+
+
+
+ Add to Cart
+
+
+
+
diff --git a/docs/component/ChipGroup/toothbrush_card.py b/docs/component/ChipGroup/toothbrush_card.py
new file mode 100644
index 00000000..c5344454
--- /dev/null
+++ b/docs/component/ChipGroup/toothbrush_card.py
@@ -0,0 +1,44 @@
+import ipyvuetify as v
+
+bristle_types = ["Extra Soft", "Soft", "Medium", "Hard"]
+
+v.Card(
+ class_="mx-auto my-2",
+ max_width="400",
+ children=[
+ v.CardTitle(
+ children=[
+ v.Html(tag="h2", children=["Toothbrush"]),
+ v.Spacer(),
+ v.Html(tag="h3", children=["$4.99"]),
+ ]
+ ),
+ v.CardText(
+ children=[
+ "Our company takes pride in making handmade brushes. Our toothbrushes are available in 4 different bristel types, from extra soft to hard."
+ ]
+ ),
+ v.Divider(class_="mx-4"),
+ v.CardText(
+ children=[
+ v.Html(tag="span", class_="subheading", children=["Select type"]),
+ v.ChipGroup(
+ v_model=0,
+ active_class="deep-purple--text text--accent-4",
+ mandatory=True,
+ children=[v.Chip(children=[bristle]) for bristle in bristle_types],
+ ),
+ ]
+ ),
+ v.CardActions(
+ children=[
+ v.Btn(
+ block=True,
+ class_="white--text",
+ color="deep-purple accent-4",
+ children=["Add to Cart"],
+ )
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/ChipGroup/toothbrush_card.vue b/docs/component/ChipGroup/toothbrush_card.vue
new file mode 100644
index 00000000..b7a0fa9f
--- /dev/null
+++ b/docs/component/ChipGroup/toothbrush_card.vue
@@ -0,0 +1,37 @@
+
+
+
+ Toothbrush
+
+ $4.99
+
+
+
+ Our company takes pride in making handmade brushes. Our toothbrushes are
+ available in 4 different bristel types, from extra soft to hard.
+
+
+
+
+
+ Select type
+
+
+ Extra Soft
+ Soft
+ Medium
+ Hard
+
+
+
+
+
+ Add to Cart
+
+
+
+
diff --git a/docs/component/ChipGroup/usage.py b/docs/component/ChipGroup/usage.py
new file mode 100644
index 00000000..8278c309
--- /dev/null
+++ b/docs/component/ChipGroup/usage.py
@@ -0,0 +1,20 @@
+import ipyvuetify as v
+
+chip_group = v.ChipGroup(
+ active_class="primary--text",
+ children=[
+ v.Chip(children=["Work"]),
+ v.Chip(children=["Home Improvement"]),
+ v.Chip(children=["Vacation"]),
+ v.Chip(children=["Food"]),
+ v.Chip(children=["Drawers"]),
+ v.Chip(children=["Shopping"]),
+ v.Chip(children=["Art"]),
+ v.Chip(children=["Tech"]),
+ v.Chip(children=["Creative Writing"]),
+ ],
+)
+
+output = v.Alert(class_="mt-4", type="info", children=["Select a chip"])
+
+v.Container(children=[chip_group, output])
diff --git a/docs/component/ColorPicker.rst b/docs/component/ColorPicker.rst
new file mode 100644
index 00000000..6d574c3b
--- /dev/null
+++ b/docs/component/ColorPicker.rst
@@ -0,0 +1,145 @@
+ColorPicker
+===========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation
+ `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`ColorPicker ` allows you to select a color
+using a variety of input methods.
+
+Usage
+-----
+
+The :py:class:`ColorPicker ` allows you to select a color
+using a variety of input methods.
+
+.. jupyter-execute:: ColorPicker/usage.py
+ :raises:
+
+.. api::
+
+ - :py:class:`ipyvuetify.ColorPicker`
+ - :py:class:`ipyvuetify.ColorPickerCanvas`
+ - :py:class:`ipyvuetify.ColorPickerSwatches`
+
+Canvas
+------
+
+The canvas can be hidden with the ``hide-canvas`` prop, and you can set its height
+with the prop ``canvas-height``. The size of the selection dot can be controlled
+with the ``dot-size`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ColorPicker/canvas.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ColorPicker/canvas.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ColorPicker/canvas.vue
+
+Elevation
+---------
+
+Adjust the elevation of the :py:class:`ColorPicker `
+component using the ``elevation`` or ``flat`` prop. The ``flat`` is equivalent
+to setting ``elevation`` to 0.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ColorPicker/elevation.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ColorPicker/elevation.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ColorPicker/elevation.vue
+
+Inputs
+------
+
+The number inputs can be hidden with the ``hide-inputs`` prop, and the sliders can
+be hidden with the ``hide-sliders`` prop. You can also hide the mode switch icon
+with the ``hide-mode-switch`` prop. The mode can also be controlled externally
+through the ``mode`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ColorPicker/inputs.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ColorPicker/inputs.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ColorPicker/inputs.vue
+
+Model
+-----
+
+The :py:class:`ColorPicker ` uses the ``v-model`` prop to
+control the color displayed. It supports hex strings such as #FF00FF and
+#FF00FF00, and objects representing RGBA, HSLA and HSVA values.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ColorPicker/model.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ColorPicker/model.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ColorPicker/model.vue
+
+Swatches
+--------
+
+Using the ``show-swatches`` prop you can display an array of color swatches that
+users can pick from. It is also possible to customize what colors are shown using
+the ``swatches`` prop. This prop accepts a two-dimensional array, where the first
+dimension defines a column, and second dimension defines the swatches from top to
+bottom by providing rgba hex strings. You can also set the max height of the swatches
+section with the ``swatches-max-height`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ColorPicker/swatches.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ColorPicker/swatches.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ColorPicker/swatches.vue
+
diff --git a/docs/component/ColorPicker/canvas.py b/docs/component/ColorPicker/canvas.py
new file mode 100644
index 00000000..41948b7c
--- /dev/null
+++ b/docs/component/ColorPicker/canvas.py
@@ -0,0 +1,28 @@
+import ipyvuetify as v
+
+color_picker1 = v.ColorPicker(
+ hide_canvas=True,
+ class_="mx-auto my-2",
+)
+color_picker2 = v.ColorPicker(
+ canvas_height=300,
+ class_="mx-auto my-2",
+)
+color_picker3 = v.ColorPicker(
+ dot_size=30,
+ class_="mx-auto my-2",
+)
+
+v.Container(
+ children=[
+ v.Row(
+ justify="space-around",
+ children=[
+ color_picker1,
+ color_picker2,
+ color_picker3,
+ ],
+ ),
+ ],
+ class_="my-2",
+)
diff --git a/docs/component/ColorPicker/canvas.vue b/docs/component/ColorPicker/canvas.vue
new file mode 100644
index 00000000..09b0f932
--- /dev/null
+++ b/docs/component/ColorPicker/canvas.vue
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/docs/component/ColorPicker/elevation.py b/docs/component/ColorPicker/elevation.py
new file mode 100644
index 00000000..129b0659
--- /dev/null
+++ b/docs/component/ColorPicker/elevation.py
@@ -0,0 +1,23 @@
+import ipyvuetify as v
+
+color_picker1 = v.ColorPicker(
+ class_="mx-auto my-2",
+ flat=True,
+)
+color_picker2 = v.ColorPicker(
+ class_="mx-auto my-2",
+ elevation=15,
+)
+
+v.Container(
+ children=[
+ v.Row(
+ justify="space-around",
+ children=[
+ color_picker1,
+ color_picker2,
+ ],
+ ),
+ ],
+ class_="my-2",
+)
diff --git a/docs/component/ColorPicker/elevation.vue b/docs/component/ColorPicker/elevation.vue
new file mode 100644
index 00000000..01cbb17c
--- /dev/null
+++ b/docs/component/ColorPicker/elevation.vue
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/docs/component/ColorPicker/inputs.py b/docs/component/ColorPicker/inputs.py
new file mode 100644
index 00000000..d66161e6
--- /dev/null
+++ b/docs/component/ColorPicker/inputs.py
@@ -0,0 +1,39 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+color_picker1 = v.ColorPicker(
+ class_="ma-2",
+ hide_inputs=True,
+)
+color_picker2 = v.ColorPicker(
+ class_="ma-2",
+ hide_mode_switch=True,
+)
+color_picker3 = v.ColorPicker(
+ class_="ma-2",
+ mode="hsla",
+)
+color_picker4 = v.ColorPicker(
+ class_="ma-2",
+ mode="hexa",
+)
+
+jslink((color_picker1, "v_model"), (color_picker2, "v_model"))
+jslink((color_picker1, "v_model"), (color_picker3, "v_model"))
+jslink((color_picker1, "v_model"), (color_picker4, "v_model"))
+
+v.Container(
+ children=[
+ v.Row(
+ justify="space-around",
+ children=[
+ color_picker1,
+ color_picker2,
+ color_picker3,
+ color_picker4,
+ ],
+ ),
+ ],
+ class_="my-2",
+)
diff --git a/docs/component/ColorPicker/inputs.vue b/docs/component/ColorPicker/inputs.vue
new file mode 100644
index 00000000..2fdbc45b
--- /dev/null
+++ b/docs/component/ColorPicker/inputs.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/docs/component/ColorPicker/model.py b/docs/component/ColorPicker/model.py
new file mode 100644
index 00000000..2101a0bf
--- /dev/null
+++ b/docs/component/ColorPicker/model.py
@@ -0,0 +1,26 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+color_picker1 = v.ColorPicker(
+ mode="hexa",
+ v_model="#FF5733",
+ class_="ma-2",
+)
+
+color_picker2 = v.ColorPicker(
+ v_model={"r": 255, "g": 87, "b": 51, "a": 1},
+ class_="ma-2",
+)
+
+jslink((color_picker1, "v_model"), (color_picker2, "v_model"))
+
+v.Container(
+ children=[
+ v.Row(
+ justify="space-around",
+ children=[color_picker1, color_picker2],
+ ),
+ ],
+ class_="my-2",
+)
diff --git a/docs/component/ColorPicker/model.vue b/docs/component/ColorPicker/model.vue
new file mode 100644
index 00000000..aaeae92e
--- /dev/null
+++ b/docs/component/ColorPicker/model.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/docs/component/ColorPicker/swatches.py b/docs/component/ColorPicker/swatches.py
new file mode 100644
index 00000000..30051e19
--- /dev/null
+++ b/docs/component/ColorPicker/swatches.py
@@ -0,0 +1,33 @@
+import ipyvuetify as v
+
+colors = [
+ ["#FF0000", "#AA0000", "#550000"],
+ ["#FFFF00", "#AAAA00", "#555500"],
+ ["#00FF00", "#00AA00", "#005500"],
+ ["#00FFFF", "#00AAAA", "#005555"],
+]
+
+v.Container(
+ children=[
+ v.Row(
+ justify="space-around",
+ children=[
+ v.ColorPicker(
+ class_="ma-2",
+ show_swatches=True,
+ ),
+ v.ColorPicker(
+ class_="ma-2",
+ swatches=colors,
+ show_swatches=True,
+ ),
+ v.ColorPicker(
+ class_="ma-2",
+ show_swatches=True,
+ swatches_max_height=300,
+ ),
+ ],
+ ),
+ ],
+ class_="my-2",
+)
diff --git a/docs/component/ColorPicker/swatches.vue b/docs/component/ColorPicker/swatches.vue
new file mode 100644
index 00000000..878bcfc8
--- /dev/null
+++ b/docs/component/ColorPicker/swatches.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/docs/component/ColorPicker/usage.py b/docs/component/ColorPicker/usage.py
new file mode 100644
index 00000000..c577e6b2
--- /dev/null
+++ b/docs/component/ColorPicker/usage.py
@@ -0,0 +1,12 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.ColorPicker(
+ class_="mx-auto",
+ dot_size=25,
+ swatches_max_height=200,
+ ),
+ ],
+ class_="my-2",
+)
diff --git a/docs/component/Combobox.rst b/docs/component/Combobox.rst
new file mode 100644
index 00000000..22d16487
--- /dev/null
+++ b/docs/component/Combobox.rst
@@ -0,0 +1,139 @@
+Combobox
+========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation
+ `_. All examples have been
+ converted to ipyvuetify syntax.
+
+The :py:class:`Combobox ` component is a :py:class:`Autocomplete
+` that allows the user to enter values that do not exist
+within the provided items. Created items will be returned as strings.
+
+Usage
+-----
+
+With :py:class:`Combobox `, you can allow a user to create
+new values that may not be present in a provided items list.
+
+.. jupyter-execute:: Combobox/usage.py
+ :raises:
+ :hide-code:
+
+.. api::
+
+ :py:class:`ipyvuetify.Combobox`
+
+Caveats
+-------
+
+.. danger::
+
+ As the Combobox allows user input, it always returns the full value provided
+ to it (for example a list of Objects will always return an Object when selected).
+ This is because there’s no way to tell if a value is supposed to be user input
+ or an object lookup `GitHub Issue `__.
+
+.. warning::
+
+ The ``auto`` property of ``menu-props`` is only supported for the default input style.
+
+.. note::
+
+ Browser autocomplete is set to off by default, may vary by browser and may be ignored.
+ `MDN `__
+
+Dense
+-----
+
+You can use ``dense`` prop to reduce combobox height and lower max height of list items.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Combobox/dense.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Combobox/dense.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Combobox/dense.vue
+
+Multiple combobox
+-----------------
+
+Previously known as **tags** - user is allowed to enter more than 1 value.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Combobox/multiple_combobox.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Combobox/multiple_combobox.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Combobox/multiple_combobox.vue
+
+No data with chips
+------------------
+
+In this example we utilize a custom ``no-data`` slot to provide context to the user
+when searching / creating items.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Combobox/no_data_with_chips.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Combobox/no_data_with_chips.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Combobox/no_data_with_chips.vue
+
+Advanced custom options
+-----------------------
+
+The :py:class:`Combobox ` improves upon the added functionality
+from :py:class:`Select ` and :py:class:`Autocomplete
+`. This provides you with an expansive interface to
+create truly customized implementations. This example takes advantage of some more
+advanced features such as a custom filter algorithm, inline list editing and
+dynamic input items.
+
+.. todo::
+
+ This example is pending completion as it's a very complex slot-based example.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Combobox/advanced_custom_options.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Combobox/advanced_custom_options.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Combobox/advanced_custom_options.vue
+
diff --git a/docs/component/Combobox/advanced_custom_options.py b/docs/component/Combobox/advanced_custom_options.py
new file mode 100644
index 00000000..c000f5df
--- /dev/null
+++ b/docs/component/Combobox/advanced_custom_options.py
@@ -0,0 +1 @@
+# TODO: Add example code here
diff --git a/docs/component/Combobox/advanced_custom_options.vue b/docs/component/Combobox/advanced_custom_options.vue
new file mode 100644
index 00000000..cc340bc4
--- /dev/null
+++ b/docs/component/Combobox/advanced_custom_options.vue
@@ -0,0 +1 @@
+
diff --git a/docs/component/Combobox/dense.py b/docs/component/Combobox/dense.py
new file mode 100644
index 00000000..6174099a
--- /dev/null
+++ b/docs/component/Combobox/dense.py
@@ -0,0 +1,14 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Combobox(
+ v_model=[],
+ items=["Item 1", "Item 2", "Item 3"],
+ label="Combobox",
+ multiple=True,
+ outlined=True,
+ dense=True,
+ )
+ ]
+)
diff --git a/docs/component/Combobox/dense.vue b/docs/component/Combobox/dense.vue
new file mode 100644
index 00000000..f823dc7a
--- /dev/null
+++ b/docs/component/Combobox/dense.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Combobox/multiple_combobox.py b/docs/component/Combobox/multiple_combobox.py
new file mode 100644
index 00000000..f2449e4b
--- /dev/null
+++ b/docs/component/Combobox/multiple_combobox.py
@@ -0,0 +1,69 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+options = ["Hiking", "Swimming", "Reading", "Cooking", "Traveling", "Gaming"]
+
+combobox1 = v.Combobox(
+ v_model=[],
+ items=options,
+ label="Select a favorite activity or create a new one",
+ multiple=True,
+)
+
+combobox2 = v.Combobox(
+ v_model=[],
+ items=options,
+ label="I use chips",
+ multiple=True,
+ chips=True,
+)
+
+# combobox3 = v.Combobox(
+# v_model=[],
+# items=options,
+# label='I use a scoped slot',
+# multiple=True,
+# chips=True,
+# v_slots=[{
+# 'name': 'selection',
+# 'variable': 'data',
+# 'children': v.Chip(
+# key='JSON.stringify(data.item)',
+# v_bind='data.attrs',
+# input_value='data.selected',
+# disabled='data.disabled',
+# children=[
+# v.Avatar(
+# class_='accent white--text',
+# left=True,
+# children=['{{ data.item.slice(0, 1).toUpperCase() }}'],
+# ),
+# '{{ data.item }}',
+# ],
+# ),
+# }],
+# )
+
+combobox4 = v.Combobox(
+ v_model=[],
+ label="I'm readonly",
+ multiple=True,
+ chips=True,
+ readonly=True,
+)
+
+jslink((combobox1, "v_model"), (combobox2, "v_model"))
+# jslink((combobox1, 'v_model'), (combobox3, 'v_model'))
+jslink((combobox1, "v_model"), (combobox4, "v_model"))
+
+combobox1.v_model = ["Reading", "Gaming"]
+
+v.Container(
+ children=[
+ combobox1,
+ combobox2,
+ # combobox3,
+ combobox4,
+ ]
+)
diff --git a/docs/component/Combobox/multiple_combobox.vue b/docs/component/Combobox/multiple_combobox.vue
new file mode 100644
index 00000000..1ccf0d3b
--- /dev/null
+++ b/docs/component/Combobox/multiple_combobox.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ data.item }}
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Combobox/no_data_with_chips.py b/docs/component/Combobox/no_data_with_chips.py
new file mode 100644
index 00000000..1f450121
--- /dev/null
+++ b/docs/component/Combobox/no_data_with_chips.py
@@ -0,0 +1,41 @@
+import ipyvuetify as v
+
+options = ["Hiking", "Swimming", "Reading", "Cooking", "Traveling", "Gaming"]
+
+v.Container(
+ fluid=True,
+ children=[
+ v.Combobox(
+ v_model=[],
+ items=options,
+ label="Add some tags",
+ multiple=True,
+ small_chips=True,
+ hide_selected=True,
+ hint="Maximum of 5 tags",
+ persistent_hint=True,
+ v_slots=[
+ {
+ "name": "no-data",
+ "children": v.ListItem(
+ children=[
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(
+ children=[
+ "No results matching ",
+ v.Html(tag="strong", children=["{{ search }}"]),
+ ". Press ",
+ v.Html(tag="kbd", children=["enter"]),
+ " to create a new one",
+ ]
+ )
+ ]
+ )
+ ]
+ ),
+ }
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Combobox/no_data_with_chips.vue b/docs/component/Combobox/no_data_with_chips.vue
new file mode 100644
index 00000000..a57cc14f
--- /dev/null
+++ b/docs/component/Combobox/no_data_with_chips.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+ No results matching "{{ search }}". Press enter to create a new one
+
+
+
+
+
+
+
diff --git a/docs/component/Combobox/usage.py b/docs/component/Combobox/usage.py
new file mode 100644
index 00000000..0fce3549
--- /dev/null
+++ b/docs/component/Combobox/usage.py
@@ -0,0 +1,14 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="mx-auto my-2",
+ children=[
+ v.Combobox(
+ multiple=True,
+ label="Select or create an item",
+ items=["Apple", "Banana", "Orange"],
+ clearable=True,
+ chips=True,
+ )
+ ],
+)
diff --git a/docs/component/DataTable.rst b/docs/component/DataTable.rst
new file mode 100644
index 00000000..7e62e02f
--- /dev/null
+++ b/docs/component/DataTable.rst
@@ -0,0 +1,422 @@
+DataTable
+=========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation
+ `_. All examples have
+ been converted to ipyvuetify syntax.
+
+The :py:class:`DataTable ` component is used for displaying
+tabular data. Features include sorting, searching, pagination, content-editing,
+and row selection.
+
+.. api::
+
+ - :py:class:`ipyvuetify.DataTable`
+ - :py:class:`ipyvuetify.DataTableHeader`
+ - :py:class:`ipyvuetify.DataFooter`
+ - :py:class:`ipyvuetify.Data`
+ - :py:class:`ipyvuetify.EditDialog`
+
+.. seealso::
+
+ - :py:class:`ipyvuetify.DataIterator`
+
+Usage
+-----
+
+The standard :py:class:`DataTable ` will by default render
+your data as simple rows.
+
+.. jupyter-execute:: DataTable/usage.py
+ :raises:
+
+Custom filter
+-------------
+
+You can override the default filtering used with ``search`` prop by supplying a
+function to the ``custom-filter`` prop. If you need to customize the filtering of
+a specific column, you can supply a function to the ``filter`` property on header
+items. The signature is ``(value: any, search: string | null, item: any) => boolean``.
+This function will always be run even if ``search`` prop has not been provided.
+Thus you need to make sure to exit early with a value of ``true`` if filter should
+not be applied.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/custom_filter.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/custom_filter.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/custom_filter.vue
+
+Dense
+-----
+
+Using the ``dense`` prop you are able to give your data tables an alternate style.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/dense.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/dense.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/dense.vue
+
+Filterable
+----------
+
+You can easily disable specific columns from being included when searching through
+table rows by setting the property ``filterable`` to false on the header item(s).
+In the example below the dessert name column is no longer searchable.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/filterable.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/filterable.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/filterable.vue
+
+Footer props
+------------
+
+The :py:class:`DataTable ` renders a default footer using
+the :py:class:`DataFooter ` component. You can pass props
+to this component using ``footer-props``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/footer_props.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/footer_props.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/footer_props.vue
+
+Grouping
+--------
+
+Using the ``group-by`` and ``group-desc`` props you can group rows on an item property.
+The ``show-group-by`` prop will show a group button in the default header. You can
+use the ``groupable`` property on header items to disable the group button.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/grouping.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/grouping.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/grouping.vue
+
+Hide default header and footer
+-------------------------------
+
+You can apply the ``hide-default-header`` and ``hide-default-footer`` props to
+remove the default header and footer respectively.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/hide_default_header_and_footer.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/hide_default_header_and_footer.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/hide_default_header_and_footer.vue
+
+Loading
+-------
+
+You can use the ``loading`` prop to indicate that data in the table is currently
+loading. If there is no data in the table, a loading message will also be displayed.
+This message can be customized using the ``loading-text`` prop or the
+``loading`` slot.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/loading.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/loading.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/loading.vue
+
+Multi sort
+----------
+
+Using the ``multi-sort`` prop will enable you to sort on multiple columns at the
+same time. When enabled, you can pass arrays to both ``sort-by`` and ``sort-desc``
+to programmatically control the sorting, instead of single values.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/multi_sort.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/multi_sort.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/multi_sort.vue
+
+Row selection
+-------------
+
+The ``show-select`` prop will render a checkbox in the default header to toggle
+all rows, and a checkbox for each default row. You can customize these with the
+slots ``header.data-table-select`` and ``item.data-table-select`` respectively.
+You can also switch between allowing multiple selected rows at the same time or
+just one with the ``single-select`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/row_selection.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/row_selection.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/row_selection.vue
+
+Search
+------
+
+The :py:class:`DataTable ` exposes a ``search`` prop that allows you to filter your data.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/search.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/search.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/search.vue
+
+Slots
+-----
+
+The :py:class:`DataTable ` provides a large number of slots
+for customizing the table. This example showcases some of these slots and what you
+can do with each. It is important to note some slots (e.g., ``item``/``body``/``header``)
+will completely take over the internal rendering of the component which will require
+you to re-implement functionalities such as selection and expansion. Some slots
+will override each other such as: ``body`` > ``item`` > ``item.`` and
+``header``/``header.``.
+
+Header
+^^^^^^
+
+You can use the dynamic slots ``header.`` to customize only certain columns.
+```` is the name of the ``value`` property in the corresponding header item
+sent to headers.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/header.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/header.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/header.vue
+
+Item
+^^^^
+
+You can use the dynamic slots ``item.`` to customize only certain columns.
+```` is the name of the ``value`` property in the corresponding header item
+sent to headers. So to customize the calories column we're using the
+``item.calories`` slot.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/item.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/item.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/item.vue
+
+Simple checkbox
+---------------
+
+When wanting to use a checkbox component inside of a slot template in your data
+tables, use the :py:class:`SimpleCheckbox ` component
+rather than the :py:class:`Checkbox ` component. The
+:py:class:`SimpleCheckbox ` component is used internally
+and will respect header alignment.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DataTable/simple_checkbox.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DataTable/simple_checkbox.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DataTable/simple_checkbox.vue
+
+Miscellaneous examples
+----------------------
+
+CRUD Actions
+^^^^^^^^^^^^
+
+:py:class:`DataTable ` with CRUD actions using a
+:py:class:`Dialog ` component for editing each row.
+
+.. todo::
+
+ The example below is incomplete. Please help us finish it!
+
+Edit dialog
+^^^^^^^^^^^
+
+The :py:class:`EditDialog ` component can be used for
+editing data directly within a :py:class:`DataTable `. You
+can block the closing of the :py:class:`EditDialog ` when
+clicked outside by adding the ``persistent`` prop.
+
+.. todo::
+
+ The example below is incomplete. Please help us finish it!
+
+Expandable rows
+---------------
+
+The ``show-expand`` prop will render an expand icon on each default row. You can
+customize this with the ``item.data-table-expand`` slot. The position of this slot
+can be customized by adding a column with ``value: 'data-table-expand'`` to the
+headers array. You can also switch between allowing multiple expanded rows at the
+same time or just one with the ``single-expand`` prop. The expanded rows are
+available on the synced prop ``expanded.sync``. Row items require a unique key
+property for expansion to work. The default is ``id``, but you can use the
+``item-key`` prop to specify a different item property.
+
+.. todo::
+
+ The example below is incomplete. Please help us finish it!
+
+External pagination
+-------------------
+
+Pagination can be controlled externally by using the individual props, or by using
+the ``options`` prop. Remember that you must apply the ``.sync`` modifier.
+
+.. todo::
+
+ The example below is incomplete. Please help us finish it!
+
+External sorting
+----------------
+
+Sorting can also be controlled externally by using the individual props, or by using
+the ``options`` prop. Remember that you must apply the ``.sync`` modifier.
+
+.. todo::
+
+ The example below is incomplete. Please help us finish it!
+
+Server-side paginate and sort
+------------------------------
+
+If you're loading data already paginated and sorted from a backend, you can use
+the ``server-items-length`` prop. Defining this prop will disable the built-in
+sorting and pagination, and you will instead need to use the available events
+(``update:page``, ``update:sortBy``, ``update:options``, etc) to know when to
+request new pages from your backend. Use the ``loading`` prop to display a
+progress bar while fetching data.
+
+.. todo::
+
+ The example below is incomplete. Please help us finish it!
diff --git a/docs/component/DataTable/custom_filter.py b/docs/component/DataTable/custom_filter.py
new file mode 100644
index 00000000..c28afaf7
--- /dev/null
+++ b/docs/component/DataTable/custom_filter.py
@@ -0,0 +1,50 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+search = v.TextField(
+ v_model=None,
+ label="Search",
+ class_="mx-4",
+)
+
+data_table = v.DataTable(
+ headers=headers,
+ items=desserts,
+ item_key="name",
+ search=None,
+ v_slots=[{"name": "top", "children": search}],
+)
+
+jslink((search, "v_model"), (data_table, "search"))
+
+data_table
diff --git a/docs/component/DataTable/custom_filter.vue b/docs/component/DataTable/custom_filter.vue
new file mode 100644
index 00000000..4dcc379f
--- /dev/null
+++ b/docs/component/DataTable/custom_filter.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+ |
+
+
+ |
+ |
+
+
+
+
+
diff --git a/docs/component/DataTable/dense.py b/docs/component/DataTable/dense.py
new file mode 100644
index 00000000..d3891e1a
--- /dev/null
+++ b/docs/component/DataTable/dense.py
@@ -0,0 +1,37 @@
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+v.DataTable(
+ dense=True,
+ headers=headers,
+ items=desserts,
+ items_per_page=5,
+)
diff --git a/docs/component/DataTable/dense.vue b/docs/component/DataTable/dense.vue
new file mode 100644
index 00000000..52fd8d1d
--- /dev/null
+++ b/docs/component/DataTable/dense.vue
@@ -0,0 +1,9 @@
+
+
+
diff --git a/docs/component/DataTable/filterable.py b/docs/component/DataTable/filterable.py
new file mode 100644
index 00000000..c28afaf7
--- /dev/null
+++ b/docs/component/DataTable/filterable.py
@@ -0,0 +1,50 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+search = v.TextField(
+ v_model=None,
+ label="Search",
+ class_="mx-4",
+)
+
+data_table = v.DataTable(
+ headers=headers,
+ items=desserts,
+ item_key="name",
+ search=None,
+ v_slots=[{"name": "top", "children": search}],
+)
+
+jslink((search, "v_model"), (data_table, "search"))
+
+data_table
diff --git a/docs/component/DataTable/filterable.vue b/docs/component/DataTable/filterable.vue
new file mode 100644
index 00000000..c0ba6980
--- /dev/null
+++ b/docs/component/DataTable/filterable.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/docs/component/DataTable/footer_props.py b/docs/component/DataTable/footer_props.py
new file mode 100644
index 00000000..121cddee
--- /dev/null
+++ b/docs/component/DataTable/footer_props.py
@@ -0,0 +1,44 @@
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+v.DataTable(
+ headers=headers,
+ items=desserts,
+ items_per_page=3,
+ item_keys="name",
+ footer_props={
+ "showFirstLastPage": True,
+ "firstIcon": "mdi-arrow-collapse-left",
+ "lastIcon": "mdi-arrow-collapse-right",
+ "prevIcon": "mdi-minus",
+ "nextIcon": "mdi-plus",
+ },
+)
diff --git a/docs/component/DataTable/footer_props.vue b/docs/component/DataTable/footer_props.vue
new file mode 100644
index 00000000..9858888f
--- /dev/null
+++ b/docs/component/DataTable/footer_props.vue
@@ -0,0 +1,16 @@
+
+
+
diff --git a/docs/component/DataTable/grouping.py b/docs/component/DataTable/grouping.py
new file mode 100644
index 00000000..25e59e53
--- /dev/null
+++ b/docs/component/DataTable/grouping.py
@@ -0,0 +1,29 @@
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "align": "start", "value": "name", "groupable": False},
+ {"text": "Category", "value": "category", "align": "right"},
+ {"text": "Dairy", "value": "dairy", "align": "right"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "category": "Ice cream", "dairy": "Yes"},
+ {"name": "Ice cream sandwich", "category": "Ice cream", "dairy": "Yes"},
+ {"name": "Eclair", "category": "Cookie", "dairy": "Yes"},
+ {"name": "Cupcake", "category": "Pastry", "dairy": "Yes"},
+ {"name": "Gingerbread", "category": "Cookie", "dairy": "No"},
+ {"name": "Jelly bean", "category": "Candy", "dairy": "No"},
+ {"name": "Lollipop", "category": "Candy", "dairy": "No"},
+ {"name": "Honeycomb", "category": "Toffee", "dairy": "No"},
+ {"name": "Donut", "category": "Pastry", "dairy": "Yes"},
+ {"name": "KitKat", "category": "Candy", "dairy": "Yes"},
+]
+
+v.DataTable(
+ headers=headers,
+ items=desserts,
+ item_key="name",
+ sort_by="name",
+ group_by="category",
+ show_group_by=True,
+)
diff --git a/docs/component/DataTable/grouping.vue b/docs/component/DataTable/grouping.vue
new file mode 100644
index 00000000..45a444a3
--- /dev/null
+++ b/docs/component/DataTable/grouping.vue
@@ -0,0 +1,11 @@
+
+
+
diff --git a/docs/component/DataTable/header.py b/docs/component/DataTable/header.py
new file mode 100644
index 00000000..900b4bbf
--- /dev/null
+++ b/docs/component/DataTable/header.py
@@ -0,0 +1,42 @@
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+v.DataTable(
+ headers=headers,
+ items=desserts,
+ v_slots=[
+ {
+ "name": "header.name",
+ "variable": "name",
+ "children": "{{ name.header.text.toUpperCase() }}",
+ }
+ ],
+)
diff --git a/docs/component/DataTable/header.vue b/docs/component/DataTable/header.vue
new file mode 100644
index 00000000..13ed67d1
--- /dev/null
+++ b/docs/component/DataTable/header.vue
@@ -0,0 +1,7 @@
+
+
+
+ {{ header.text.toUpperCase() }}
+
+
+
diff --git a/docs/component/DataTable/hide_default_header_and_footer.py b/docs/component/DataTable/hide_default_header_and_footer.py
new file mode 100644
index 00000000..c3752eff
--- /dev/null
+++ b/docs/component/DataTable/hide_default_header_and_footer.py
@@ -0,0 +1,37 @@
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+v.DataTable(
+ headers=headers,
+ items=desserts,
+ hide_default_header=True,
+ hide_default_footer=True,
+)
diff --git a/docs/component/DataTable/hide_default_header_and_footer.vue b/docs/component/DataTable/hide_default_header_and_footer.vue
new file mode 100644
index 00000000..3fa8a6ed
--- /dev/null
+++ b/docs/component/DataTable/hide_default_header_and_footer.vue
@@ -0,0 +1,9 @@
+
+
+
diff --git a/docs/component/DataTable/item.py b/docs/component/DataTable/item.py
new file mode 100644
index 00000000..0e561532
--- /dev/null
+++ b/docs/component/DataTable/item.py
@@ -0,0 +1,46 @@
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+v.DataTable(
+ headers=headers,
+ items=desserts,
+ v_slots=[
+ {
+ "name": "item.calories",
+ "variable": "item",
+ "children": v.Chip(
+ children=["item.item.calories"],
+ # color="getColor(item.calories)",
+ dark=True,
+ ),
+ }
+ ],
+)
diff --git a/docs/component/DataTable/item.vue b/docs/component/DataTable/item.vue
new file mode 100644
index 00000000..119dd8d5
--- /dev/null
+++ b/docs/component/DataTable/item.vue
@@ -0,0 +1,9 @@
+
+
+
+
+ {{ item.calories }}
+
+
+
+
diff --git a/docs/component/DataTable/loading.py b/docs/component/DataTable/loading.py
new file mode 100644
index 00000000..05dcbadf
--- /dev/null
+++ b/docs/component/DataTable/loading.py
@@ -0,0 +1,8 @@
+import ipyvuetify as v
+
+v.DataTable(
+ item_key="name",
+ class_="elevation-1",
+ loading=True,
+ loading_text="Loading... Please wait",
+)
diff --git a/docs/component/DataTable/loading.vue b/docs/component/DataTable/loading.vue
new file mode 100644
index 00000000..3d89697f
--- /dev/null
+++ b/docs/component/DataTable/loading.vue
@@ -0,0 +1,8 @@
+
+
+
diff --git a/docs/component/DataTable/multi_sort.py b/docs/component/DataTable/multi_sort.py
new file mode 100644
index 00000000..fe21c04a
--- /dev/null
+++ b/docs/component/DataTable/multi_sort.py
@@ -0,0 +1,38 @@
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+v.DataTable(
+ headers=headers,
+ items=desserts,
+ sort_by=["calories", "fat"],
+ sort_desc=[False, True],
+ multi_sort=True,
+)
diff --git a/docs/component/DataTable/multi_sort.vue b/docs/component/DataTable/multi_sort.vue
new file mode 100644
index 00000000..319fb96b
--- /dev/null
+++ b/docs/component/DataTable/multi_sort.vue
@@ -0,0 +1,10 @@
+
+
+
diff --git a/docs/component/DataTable/row_selection.py b/docs/component/DataTable/row_selection.py
new file mode 100644
index 00000000..64dc561b
--- /dev/null
+++ b/docs/component/DataTable/row_selection.py
@@ -0,0 +1,50 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+single_select = v.Switch(
+ label="Single select",
+ class_="pa-3",
+ v_model=False,
+)
+
+data_table = v.DataTable(
+ v_model=[],
+ headers=headers,
+ items=desserts,
+ show_select=True,
+ single_select=False,
+)
+
+jslink((single_select, "v_model"), (data_table, "single_select"))
+
+v.Container(children=[single_select, data_table])
diff --git a/docs/component/DataTable/row_selection.vue b/docs/component/DataTable/row_selection.vue
new file mode 100644
index 00000000..0be96617
--- /dev/null
+++ b/docs/component/DataTable/row_selection.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/docs/component/DataTable/search.py b/docs/component/DataTable/search.py
new file mode 100644
index 00000000..835b7b52
--- /dev/null
+++ b/docs/component/DataTable/search.py
@@ -0,0 +1,62 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+search = v.TextField(
+ append_icon="mdi-magnify",
+ label="Search",
+ single_line=True,
+ hide_details=True,
+ v_model=None,
+)
+
+data_table = v.DataTable(
+ v_model=[],
+ headers=headers,
+ items=desserts,
+ search=None,
+)
+
+jslink((search, "v_model"), (data_table, "search"))
+
+v.Card(
+ children=[
+ v.CardTitle(
+ children=[
+ "Nutrition",
+ v.Spacer(),
+ search,
+ ]
+ ),
+ data_table,
+ ]
+)
diff --git a/docs/component/DataTable/search.vue b/docs/component/DataTable/search.vue
new file mode 100644
index 00000000..96c6d935
--- /dev/null
+++ b/docs/component/DataTable/search.vue
@@ -0,0 +1,20 @@
+
+
+
+ Nutrition
+
+
+
+
+
+
diff --git a/docs/component/DataTable/simple_checkbox.py b/docs/component/DataTable/simple_checkbox.py
new file mode 100644
index 00000000..e50fb715
--- /dev/null
+++ b/docs/component/DataTable/simple_checkbox.py
@@ -0,0 +1,118 @@
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {
+ "name": "Frozen Yogurt",
+ "calories": 159,
+ "fat": 6.0,
+ "carbs": 24,
+ "protein": 4.0,
+ "iron": 1,
+ "glutenfree": True,
+ },
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ "glutenfree": False,
+ },
+ {
+ "name": "Eclair",
+ "calories": 262,
+ "fat": 16.0,
+ "carbs": 23,
+ "protein": 6.0,
+ "iron": 7,
+ "glutenfree": False,
+ },
+ {
+ "name": "Cupcake",
+ "calories": 305,
+ "fat": 3.7,
+ "carbs": 67,
+ "protein": 4.3,
+ "iron": 8,
+ "glutenfree": False,
+ },
+ {
+ "name": "Gingerbread",
+ "calories": 356,
+ "fat": 16.0,
+ "carbs": 49,
+ "protein": 3.9,
+ "iron": 16,
+ "glutenfree": True,
+ },
+ {
+ "name": "Jelly bean",
+ "calories": 375,
+ "fat": 0.0,
+ "carbs": 94,
+ "protein": 0.0,
+ "iron": 0,
+ "glutenfree": True,
+ },
+ {
+ "name": "Lollipop",
+ "calories": 392,
+ "fat": 0.2,
+ "carbs": 98,
+ "protein": 0.0,
+ "iron": 2,
+ "glutenfree": True,
+ },
+ {
+ "name": "Honeycomb",
+ "calories": 408,
+ "fat": 3.2,
+ "carbs": 87,
+ "protein": 6.5,
+ "iron": 45,
+ "glutenfree": True,
+ },
+ {
+ "name": "Donut",
+ "calories": 452,
+ "fat": 25.0,
+ "carbs": 51,
+ "protein": 4.9,
+ "iron": 22,
+ "glutenfree": False,
+ },
+ {
+ "name": "KitKat",
+ "calories": 518,
+ "fat": 26.0,
+ "carbs": 65,
+ "protein": 7.0,
+ "iron": 6,
+ "glutenfree": False,
+ },
+]
+
+v.DataTable(
+ headers=headers,
+ items=desserts,
+ v_slots=[
+ {
+ "name": "item.glutenfree",
+ "variable": "item",
+ "children": v.SimpleCheckbox(
+ v_model="item.item.glutenfree",
+ disabled=True,
+ ),
+ }
+ ],
+)
diff --git a/docs/component/DataTable/simple_checkbox.vue b/docs/component/DataTable/simple_checkbox.vue
new file mode 100644
index 00000000..3c857881
--- /dev/null
+++ b/docs/component/DataTable/simple_checkbox.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/DataTable/usage.py b/docs/component/DataTable/usage.py
new file mode 100644
index 00000000..14772ddd
--- /dev/null
+++ b/docs/component/DataTable/usage.py
@@ -0,0 +1,36 @@
+import ipyvuetify as v
+
+headers = [
+ {"text": "Dessert (100g serving)", "value": "name"},
+ {"text": "Calories", "value": "calories"},
+ {"text": "Fat (g)", "value": "fat"},
+ {"text": "Carbs (g)", "value": "carbs"},
+ {"text": "Protein (g)", "value": "protein"},
+ {"text": "Iron (%)", "value": "iron"},
+]
+
+desserts = [
+ {"name": "Frozen Yogurt", "calories": 159, "fat": 6.0, "carbs": 24, "protein": 4.0, "iron": 1},
+ {
+ "name": "Ice cream sandwich",
+ "calories": 237,
+ "fat": 9.0,
+ "carbs": 37,
+ "protein": 4.3,
+ "iron": 1,
+ },
+ {"name": "Eclair", "calories": 262, "fat": 16.0, "carbs": 23, "protein": 6.0, "iron": 7},
+ {"name": "Cupcake", "calories": 305, "fat": 3.7, "carbs": 67, "protein": 4.3, "iron": 8},
+ {"name": "Gingerbread", "calories": 356, "fat": 16.0, "carbs": 49, "protein": 3.9, "iron": 16},
+ {"name": "Jelly bean", "calories": 375, "fat": 0.0, "carbs": 94, "protein": 0.0, "iron": 0},
+ {"name": "Lollipop", "calories": 392, "fat": 0.2, "carbs": 98, "protein": 0.0, "iron": 2},
+ {"name": "Honeycomb", "calories": 408, "fat": 3.2, "carbs": 87, "protein": 6.5, "iron": 45},
+ {"name": "Donut", "calories": 452, "fat": 25.0, "carbs": 51, "protein": 4.9, "iron": 22},
+ {"name": "KitKat", "calories": 518, "fat": 26.0, "carbs": 65, "protein": 7.0, "iron": 6},
+]
+
+v.DataTable(
+ headers=headers,
+ items=desserts,
+ items_per_page=5,
+)
diff --git a/docs/component/DatePicker.rst b/docs/component/DatePicker.rst
new file mode 100644
index 00000000..f1c7dd5c
--- /dev/null
+++ b/docs/component/DatePicker.rst
@@ -0,0 +1,338 @@
+DatePicker
+==========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`DatePicker ` component is used for selecting dates. It supports multiple selection modes, formatting, internationalization, and can be embedded in dialogs or menus.
+
+.. api::
+
+ - :py:class:`ipyvuetify.DatePicker`
+ - :py:class:`ipyvuetify.Menu`
+ - :py:class:`ipyvuetify.Dialog`
+ - :py:class:`ipyvuetify.TextField`
+ - :py:class:`ipyvuetify.DatePickerTable`
+ - :py:class:`ipyvuetify.DatePickerHeader`
+ - :py:class:`ipyvuetify.DatePickerMonthTable`
+ - :py:class:`ipyvuetify.DatePickerYears`
+ - :py:class:`ipyvuetify.DatePickerTitle`
+
+Usage
+-----
+
+Basic usage of :py:class:`DatePicker `.
+
+.. jupyter-execute:: DatePicker/usage.py
+ :raises:
+
+.. warning::
+
+ :py:class:`DatePicker ` accepts ISO 8601 **date** strings
+ (YYYY-MM-DD). For more information regarding ISO 8601 and other standards,
+ visit the official ISO (International Organization for Standardization)
+ `International Standards `__ page.
+
+Colors
+------
+
+Customize the color of :py:class:`DatePicker ` with the ``color`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/colors.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/colors.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/colors.vue
+
+Elevation
+---------
+
+The :py:class:`DatePicker ` component supports elevation
+up to a maximum value of 24. For more information on elevations, visit the
+`official Material Design elevations `__
+page.
+
+.. todo::
+
+ Add example for elevation prop once supported.
+
+Icons
+-----
+
+You can override the default icons used in the picker.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/icons.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/icons.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/icons.vue
+
+Multiple
+--------
+
+Allow selecting multiple dates with :py:class:`DatePicker `.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/multiple.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/multiple.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/multiple.vue
+
+Picker date
+
+You can watch the `picker-date`` which is the displayed month/year (depending on
+the picker type and active view) to perform some action when it changes. This uses
+the `.sync` modifier.
+
+.. todo::
+
+ Help us add an example for picker-date !
+
+
+Range
+-----
+
+Enable date range selection with :py:class:`DatePicker `
+using ``range``. When using ``range`` prop date picker expects its model to be an
+array of length 2 or empty.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/range.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/range.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/range.vue
+
+Readonly
+--------
+
+Selecting new date could be disabled by adding ``readonly`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/readonly.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/readonly.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/readonly.vue
+
+Show current
+------------
+
+By default the current date is displayed using outlined button ``show-current``
+prop allows you to remove the border or select different date to be displayed as
+the current one.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/show_current.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/show_current.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/show_current.vue
+
+Show sibling months
+-------------------
+
+By default days from previous and next months are not visible. They can be
+displayed using the ``show-adjacent-months`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/show_sibling_months.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/show_sibling_months.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/show_sibling_months.vue
+
+Width
+-----
+
+You can specify the picker’s width or make it full width.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/width.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/width.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/width.vue
+
+Date events
+-----------
+
+You can specify events using arrays, objects or functions. To change the default
+color of the event use ``event-color`` prop. Your ``events`` function or object can
+return an array of colors (material or css) in case you want to display multiple
+event indicators.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/date_events.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/date_events.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/date_events.vue
+
+Active picker
+-------------
+
+You can create a birthday picker - starting with year picker by default, restricting
+dates range and closing the picker menu after selecting the day make the perfect
+birthday picker.
+
+.. todo::
+
+ Add example for active-picker once supported.
+
+
+Dialog and menu
+---------------
+
+When integrating a ``picker`` into a :py:class:`TextField `,
+it is recommended to use the ``readonly`` prop. This will prevent mobile keyboards
+from triggering. To save vertical space, you can also hide the picker title.
+
+Pickers expose a slot that allow you to hook into save and cancel functionality.
+This will maintain an old value which can be replaced if the user cancels.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/dialog_and_menu.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/dialog_and_menu.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/dialog_and_menu.vue
+
+Internationalization
+--------------------
+
+The date picker supports internationalization through the JavaScript Date object.
+Specify a BCP 47 language tag using the ``locale`` prop, and then set the first day
+of the week with the ``first-day-of-week`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/internationalization.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/internationalization.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/internationalization.vue
+
+Orientation
+-----------
+
+Date pickers come in two orientation variations, portrait (default) and landscape.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: DatePicker/orientation.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: DatePicker/orientation.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: DatePicker/orientation.vue
+
diff --git a/docs/component/DatePicker/colors.py b/docs/component/DatePicker/colors.py
new file mode 100644
index 00000000..b68a4c0d
--- /dev/null
+++ b/docs/component/DatePicker/colors.py
@@ -0,0 +1,18 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(
+ class_="mx-2",
+ v_model="2019-10-13",
+ color="green lighten-1",
+ ),
+ v.DatePicker(
+ class_="mx-2",
+ v_model="2019-10-13",
+ color="green lighten-1",
+ header_color="primary",
+ ),
+ ],
+)
diff --git a/docs/component/DatePicker/colors.vue b/docs/component/DatePicker/colors.vue
new file mode 100644
index 00000000..c60e0181
--- /dev/null
+++ b/docs/component/DatePicker/colors.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/docs/component/DatePicker/date_events.py b/docs/component/DatePicker/date_events.py
new file mode 100644
index 00000000..ec98422c
--- /dev/null
+++ b/docs/component/DatePicker/date_events.py
@@ -0,0 +1,19 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(
+ class_="mx-2",
+ v_model="2022-06-15",
+ events=["2022-06-10", "2022-06-15", "2022-06-20"],
+ event_color="green lighten-1",
+ ),
+ v.DatePicker(
+ class_="mx-2",
+ v_model="2022-06-15",
+ events=["2022-06-10", "2022-06-15", "2022-06-20"],
+ event_color=["red", "blue", "green"],
+ ),
+ ],
+)
diff --git a/docs/component/DatePicker/date_events.vue b/docs/component/DatePicker/date_events.vue
new file mode 100644
index 00000000..7f8b22e4
--- /dev/null
+++ b/docs/component/DatePicker/date_events.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
Defined by function
+
+
+
+
diff --git a/docs/component/DatePicker/dialog_and_menu.py b/docs/component/DatePicker/dialog_and_menu.py
new file mode 100644
index 00000000..9d84fe1a
--- /dev/null
+++ b/docs/component/DatePicker/dialog_and_menu.py
@@ -0,0 +1,38 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+date_picker = v.DatePicker(v_model=None)
+
+text_field = v.TextField(
+ v_model="",
+ label="Picker in dialog",
+ prepend_icon="mdi-calendar",
+ readonly=True,
+ v_bind="activator.attrs",
+ v_on="activator.on",
+)
+
+jslink((date_picker, "v_model"), (text_field, "v_model"))
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.Menu(
+ v_model=False,
+ close_on_content_click=False,
+ nudge_right=40,
+ transition="scale-transition",
+ offset_y=True,
+ min_width="auto",
+ children=[date_picker],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "activator",
+ "children": text_field,
+ }
+ ],
+ )
+ ],
+)
diff --git a/docs/component/DatePicker/dialog_and_menu.vue b/docs/component/DatePicker/dialog_and_menu.vue
new file mode 100644
index 00000000..eef10147
--- /dev/null
+++ b/docs/component/DatePicker/dialog_and_menu.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/DatePicker/icons.py b/docs/component/DatePicker/icons.py
new file mode 100644
index 00000000..5626cd9b
--- /dev/null
+++ b/docs/component/DatePicker/icons.py
@@ -0,0 +1,13 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(
+ v_model="2019-10-13",
+ year_icon="mdi-calendar-blank",
+ prev_icon="mdi-skip-previous",
+ next_icon="mdi-skip-next",
+ ),
+ ],
+)
diff --git a/docs/component/DatePicker/icons.vue b/docs/component/DatePicker/icons.vue
new file mode 100644
index 00000000..50de0dab
--- /dev/null
+++ b/docs/component/DatePicker/icons.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/docs/component/DatePicker/internationalization.py b/docs/component/DatePicker/internationalization.py
new file mode 100644
index 00000000..26ec5673
--- /dev/null
+++ b/docs/component/DatePicker/internationalization.py
@@ -0,0 +1,19 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(
+ class_="mx-2",
+ v_model="2022-06-15",
+ first_day_of_week=0,
+ locale="zh-cn",
+ ),
+ v.DatePicker(
+ class_="mx-2",
+ v_model="2022-06-15",
+ first_day_of_week=1,
+ locale="sv-se",
+ ),
+ ],
+)
diff --git a/docs/component/DatePicker/internationalization.vue b/docs/component/DatePicker/internationalization.vue
new file mode 100644
index 00000000..38cc2842
--- /dev/null
+++ b/docs/component/DatePicker/internationalization.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
diff --git a/docs/component/DatePicker/multiple.py b/docs/component/DatePicker/multiple.py
new file mode 100644
index 00000000..c7d2a6e7
--- /dev/null
+++ b/docs/component/DatePicker/multiple.py
@@ -0,0 +1,25 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+date_picker = v.DatePicker(
+ v_model=["2019-10-13", "2019-10-16"],
+ multiple=True,
+)
+
+select = v.Combobox(
+ v_model=["2019-10-13", "2019-10-16"],
+ label="Select dates",
+ multiple=True,
+ chips=True,
+ small_chips=True,
+ prepend_inner_icon="mdi-calendar",
+ readonly=True,
+)
+
+jslink((date_picker, "v_model"), (select, "v_model"))
+
+v.Container(
+ class_="my-2",
+ children=[date_picker, select],
+)
diff --git a/docs/component/DatePicker/multiple.vue b/docs/component/DatePicker/multiple.vue
new file mode 100644
index 00000000..7bf3abfd
--- /dev/null
+++ b/docs/component/DatePicker/multiple.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+
+ OK
+
+
+
+
+
+
diff --git a/docs/component/DatePicker/orientation.py b/docs/component/DatePicker/orientation.py
new file mode 100644
index 00000000..a8745b30
--- /dev/null
+++ b/docs/component/DatePicker/orientation.py
@@ -0,0 +1,12 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(
+ class_="mx-2",
+ v_model="2019-10-13",
+ landscape=True,
+ ),
+ ],
+)
diff --git a/docs/component/DatePicker/orientation.vue b/docs/component/DatePicker/orientation.vue
new file mode 100644
index 00000000..70ca79cb
--- /dev/null
+++ b/docs/component/DatePicker/orientation.vue
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/docs/component/DatePicker/range.py b/docs/component/DatePicker/range.py
new file mode 100644
index 00000000..035466eb
--- /dev/null
+++ b/docs/component/DatePicker/range.py
@@ -0,0 +1,25 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+date_picker = v.DatePicker(
+ v_model=["2019-10-13", "2019-10-16"],
+ range=True,
+)
+
+select = v.Combobox(
+ v_model=["2019-10-13", "2019-10-16"],
+ label="Select dates",
+ multiple=True,
+ chips=True,
+ small_chips=True,
+ prepend_inner_icon="mdi-calendar",
+ readonly=True,
+)
+
+jslink((date_picker, "v_model"), (select, "v_model"))
+
+v.Container(
+ class_="my-2",
+ children=[date_picker, select],
+)
diff --git a/docs/component/DatePicker/range.vue b/docs/component/DatePicker/range.vue
new file mode 100644
index 00000000..70f9b6ac
--- /dev/null
+++ b/docs/component/DatePicker/range.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+ model: {{ dates }}
+
+
+
diff --git a/docs/component/DatePicker/readonly.py b/docs/component/DatePicker/readonly.py
new file mode 100644
index 00000000..8811b03f
--- /dev/null
+++ b/docs/component/DatePicker/readonly.py
@@ -0,0 +1,11 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(
+ v_model="2019-10-13",
+ readonly=True,
+ ),
+ ],
+)
diff --git a/docs/component/DatePicker/readonly.vue b/docs/component/DatePicker/readonly.vue
new file mode 100644
index 00000000..bf06986f
--- /dev/null
+++ b/docs/component/DatePicker/readonly.vue
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/docs/component/DatePicker/show_current.py b/docs/component/DatePicker/show_current.py
new file mode 100644
index 00000000..69b12b25
--- /dev/null
+++ b/docs/component/DatePicker/show_current.py
@@ -0,0 +1,17 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(
+ class_="mx-2",
+ v_model="2019-10-13",
+ show_current=False,
+ ),
+ v.DatePicker(
+ class_="mx-2",
+ v_model="2019-10-13",
+ show_current="2013-07-13",
+ ),
+ ],
+)
diff --git a/docs/component/DatePicker/show_current.vue b/docs/component/DatePicker/show_current.vue
new file mode 100644
index 00000000..6f6bb0b2
--- /dev/null
+++ b/docs/component/DatePicker/show_current.vue
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/docs/component/DatePicker/show_sibling_months.py b/docs/component/DatePicker/show_sibling_months.py
new file mode 100644
index 00000000..d16be52a
--- /dev/null
+++ b/docs/component/DatePicker/show_sibling_months.py
@@ -0,0 +1,11 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(
+ v_model="2019-10-13",
+ show_adjacent_months=True,
+ ),
+ ],
+)
diff --git a/docs/component/DatePicker/show_sibling_months.vue b/docs/component/DatePicker/show_sibling_months.vue
new file mode 100644
index 00000000..b3e706e1
--- /dev/null
+++ b/docs/component/DatePicker/show_sibling_months.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/docs/component/DatePicker/usage.py b/docs/component/DatePicker/usage.py
new file mode 100644
index 00000000..60080da8
--- /dev/null
+++ b/docs/component/DatePicker/usage.py
@@ -0,0 +1,8 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(),
+ ],
+)
diff --git a/docs/component/DatePicker/width.py b/docs/component/DatePicker/width.py
new file mode 100644
index 00000000..06cce0c5
--- /dev/null
+++ b/docs/component/DatePicker/width.py
@@ -0,0 +1,17 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="my-2",
+ children=[
+ v.DatePicker(
+ v_model="2019-10-13",
+ width="290",
+ class_="mt-4",
+ ),
+ v.DatePicker(
+ v_model="2019-10-13",
+ full_width=True,
+ class_="mt-4",
+ ),
+ ],
+)
diff --git a/docs/component/DatePicker/width.vue b/docs/component/DatePicker/width.vue
new file mode 100644
index 00000000..a2a2d5cb
--- /dev/null
+++ b/docs/component/DatePicker/width.vue
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/docs/component/Dialog.rst b/docs/component/Dialog.rst
new file mode 100644
index 00000000..185f59b2
--- /dev/null
+++ b/docs/component/Dialog.rst
@@ -0,0 +1,181 @@
+Dialog
+======
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation `_.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Dialog ` component inform users about a specific task and may contain critical information, require decisions, or involve multiple tasks. Use dialogs sparingly because they are interruptive.
+
+.. api::
+
+ - :py:class:`ipyvuetify.Dialog`
+ - :py:class:`ipyvuetify.DialogBottomTransition`
+ - :py:class:`ipyvuetify.DialogTransition`
+
+Usage
+-----
+
+A dialog contains two slots, one for its activator and one for its content (default). Good for Privacy Policies.
+
+.. jupyter-execute:: Dialog/usage.py
+ :raises:
+
+Fullscreen
+----------
+
+Due to limited space, full-screen dialogs may be more appropriate for mobile devices
+than dialogs used on devices with larger screens.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Dialog/fullscreen.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Dialog/fullscreen.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Dialog/fullscreen.vue
+
+Transitions
+-----------
+
+You can make the dialog appear from the top or the bottom.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Dialog/transitions.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Dialog/transitions.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Dialog/transitions.vue
+
+Persistent
+----------
+
+Similar to a Simple Dialog, except that it's not dismissed when touching outside or pressing esc key.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Dialog/persistent.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Dialog/persistent.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Dialog/persistent.vue
+
+Scrollable
+----------
+
+Example of a dialog with scrollable content.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Dialog/scrollable.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Dialog/scrollable.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Dialog/scrollable.vue
+
+Form
+----
+
+A simple example of a form in a dialog.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Dialog/form.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Dialog/form.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Dialog/form.vue
+
+Loader
+------
+
+The :py:class:`Dialog ` component makes it easy to create a
+customized loading experience for your application.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Dialog/loader.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Dialog/loader.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Dialog/loader.vue
+
+Nesting
+-------
+
+Dialogs can be nested: you can open one dialog from another.
+
+.. todo::
+
+ It's a very chalenging example please help us !
+
+Overflowed
+----------
+
+Modals that do not fit within the available window space will scroll the container.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Dialog/overflowed.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Dialog/overflowed.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Dialog/overflowed.vue
+
diff --git a/docs/component/Dialog/form.py b/docs/component/Dialog/form.py
new file mode 100644
index 00000000..7d83a3f3
--- /dev/null
+++ b/docs/component/Dialog/form.py
@@ -0,0 +1,146 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="text-center",
+ children=[
+ v.Dialog(
+ v_model=False,
+ max_width=600,
+ children=[
+ v.Card(
+ children=[
+ v.CardTitle(
+ class_="text-h5",
+ children=["User Profile"],
+ ),
+ v.CardText(
+ children=[
+ v.Container(
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ cols=12,
+ sm=6,
+ md=4,
+ children=[
+ v.TextField(
+ label="Legal first name*",
+ required=True,
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=6,
+ md=4,
+ children=[
+ v.TextField(
+ label="Legal middle name",
+ hint="example of helper text only on focus",
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=6,
+ md=4,
+ children=[
+ v.TextField(
+ label="Legal last name*",
+ hint="example of persistent helper text",
+ persistent_hint=True,
+ required=True,
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ children=[
+ v.TextField(
+ label="Email*",
+ required=True,
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ children=[
+ v.TextField(
+ label="Password*",
+ type_="password",
+ required=True,
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=6,
+ children=[
+ v.Select(
+ items=["0-17", "18-29", "30-54", "54+"],
+ label="Age*",
+ required=True,
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ sm=6,
+ children=[
+ v.Autocomplete(
+ items=[
+ "Skiing",
+ "Ice hockey",
+ "Soccer",
+ "Basketball",
+ "Hockey",
+ "Reading",
+ "Writing",
+ "Coding",
+ "Basejump",
+ ],
+ label="Interests",
+ multiple=True,
+ )
+ ],
+ ),
+ ]
+ ),
+ ]
+ )
+ ]
+ ),
+ v.CardActions(
+ children=[
+ v.Spacer(),
+ v.Btn(
+ text=True,
+ color="blue darken-1",
+ children=["Close"],
+ ),
+ v.Btn(
+ text=True,
+ color="blue darken-1",
+ children=["Save"],
+ ),
+ ]
+ ),
+ ]
+ )
+ ],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "dialog",
+ "children": v.Btn(
+ children=["Open Dialog"],
+ color="primary",
+ v_bind="dialog.attrs",
+ v_on="dialog.on",
+ ),
+ }
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Dialog/form.vue b/docs/component/Dialog/form.vue
new file mode 100644
index 00000000..296a2e73
--- /dev/null
+++ b/docs/component/Dialog/form.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+ Open Dialog
+
+
+
+
+ User Profile
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ *indicates required field
+
+
+
+
+ Close
+
+
+ Save
+
+
+
+
+
+
diff --git a/docs/component/Dialog/fullscreen.py b/docs/component/Dialog/fullscreen.py
new file mode 100644
index 00000000..357554fd
--- /dev/null
+++ b/docs/component/Dialog/fullscreen.py
@@ -0,0 +1,126 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+switch = v.Switch(
+ v_model=False,
+ label="close dialog",
+ class_="mb-4",
+)
+
+dialog = v.Dialog(
+ v_model=False,
+ fullscreen=True,
+ # hide_hoverlay=True,
+ transition="dialog-bottom-transition",
+ children=[
+ v.Card(
+ children=[
+ v.List(
+ three_line=True,
+ subheader=True,
+ children=[
+ v.Subheader(children=["User Controls"]),
+ v.ListItem(
+ children=[
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(children=["Content filtering"]),
+ v.ListItemSubtitle(
+ children=[
+ "Set the content filtering level to restrict apps that can be downloaded"
+ ]
+ ),
+ ]
+ ),
+ ]
+ ),
+ v.ListItem(
+ children=[
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(children=["Password"]),
+ v.ListItemSubtitle(
+ children=[
+ "Require password for purchase or use password to restrict purchase"
+ ]
+ ),
+ ]
+ ),
+ ]
+ ),
+ ],
+ ),
+ v.Divider(),
+ v.List(
+ three_line=True,
+ subheader=True,
+ children=[
+ v.Subheader(children=["General"]),
+ v.ListItem(
+ children=[
+ v.ListItemAction(children=[v.Checkbox(v_model=True)]),
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(children=["Notifications"]),
+ v.ListItemSubtitle(
+ children=[
+ "Notify me about updates to apps or games that I downloaded"
+ ]
+ ),
+ ]
+ ),
+ ]
+ ),
+ v.ListItem(
+ children=[
+ v.ListItemAction(children=[v.Checkbox(v_model=False)]),
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(children=["Sound"]),
+ v.ListItemSubtitle(
+ children=[
+ "Auto-update apps at any time. Data charges may apply"
+ ]
+ ),
+ ]
+ ),
+ ]
+ ),
+ v.ListItem(
+ children=[
+ v.ListItemAction(children=[v.Checkbox(v_model=True)]),
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(children=["Auto-add widgets"]),
+ v.ListItemSubtitle(
+ children=["Automatically add home screen widgets"]
+ ),
+ ]
+ ),
+ ]
+ ),
+ ],
+ ),
+ v.CardActions(class_="justify-center", children=[v.Spacer(), switch, v.Spacer()]),
+ ]
+ )
+ ],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "dialog",
+ "children": v.Btn(
+ children=["Open Dialog"],
+ color="primary",
+ dark=True,
+ v_bind="dialog.attrs",
+ v_on="dialog.on",
+ ),
+ }
+ ],
+)
+
+jslink((switch, "v_model"), (dialog, "v_model"))
+
+v.Container(children=[dialog], class_="text-center")
diff --git a/docs/component/Dialog/fullscreen.vue b/docs/component/Dialog/fullscreen.vue
new file mode 100644
index 00000000..43194e2e
--- /dev/null
+++ b/docs/component/Dialog/fullscreen.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+ Open Dialog
+
+
+
+
+
+ mdi-close
+
+ Settings
+
+
+ Save
+
+
+
+ User Controls
+
+
+ Content filtering
+ Set the content filtering level to restrict apps that can be
+ downloaded
+
+
+
+
+ Password
+ Require password for purchase or use password to restrict
+ purchase
+
+
+
+
+
+ General
+
+
+
+
+
+ Notifications
+ Notify me about updates to apps or games that I
+ downloaded
+
+
+
+
+
+
+
+ Sound
+ Auto-update apps at any time. Data charges may
+ apply
+
+
+
+
+
+
+
+ Auto-add widgets
+ Automatically add home screen widgets
+
+
+
+
+
+
+
diff --git a/docs/component/Dialog/loader.py b/docs/component/Dialog/loader.py
new file mode 100644
index 00000000..33a745ba
--- /dev/null
+++ b/docs/component/Dialog/loader.py
@@ -0,0 +1,42 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="text-center",
+ children=[
+ v.Dialog(
+ v_model=False,
+ width=300,
+ children=[
+ v.Card(
+ color="primary",
+ dark=True,
+ children=[
+ v.CardText(
+ children=[
+ "Please stand by",
+ v.ProgressLinear(
+ indeterminate=True,
+ color="white",
+ class_="mb-0",
+ ),
+ ]
+ )
+ ],
+ )
+ ],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "dialog",
+ "children": v.Btn(
+ children=["Start loading"],
+ color="purple darken-2",
+ class_="white--text",
+ v_bind="dialog.attrs",
+ v_on="dialog.on",
+ ),
+ }
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Dialog/loader.vue b/docs/component/Dialog/loader.vue
new file mode 100644
index 00000000..0ca8c40c
--- /dev/null
+++ b/docs/component/Dialog/loader.vue
@@ -0,0 +1,25 @@
+
+
+
+ Start loading
+
+
+
+
+ Please stand by
+
+
+
+
+
+
diff --git a/docs/component/Dialog/overflowed.py b/docs/component/Dialog/overflowed.py
new file mode 100644
index 00000000..3fec2680
--- /dev/null
+++ b/docs/component/Dialog/overflowed.py
@@ -0,0 +1,63 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="text-center",
+ children=[
+ v.Dialog(
+ v_model=False,
+ width=600,
+ children=[
+ v.Card(
+ children=[
+ v.CardTitle(
+ class_="text-h5",
+ children=["Use Google's location service?"],
+ ),
+ v.CardText(
+ children=[
+ """
+ Lorem ipsum dolor sit amet, semper quis, sapien id natoque elit. Nostra urna at, magna at neque sed sed ante imperdiet, dolor mauris cursus velit, velit non, sem nec. Volutpat sem ridiculus placerat leo, augue in, duis erat proin condimentum in a eget, sed fermentum sed vestibulum varius ac, vestibulum volutpat orci ut elit eget tortor. Ultrices nascetur nulla gravida ante arcu. Pharetra rhoncus morbi ipsum, nunc tempor debitis, ipsum pellentesque, vitae id quam ut mauris dui tempor, aptent non. Quisque turpis. Phasellus quis lectus luctus orci eget rhoncus. Amet donec vestibulum mattis commodo, nulla aliquet, nibh praesent, elementum nulla. Sit lacus pharetra tempus magna neque pellentesque, nulla vel erat.
+ Justo ex quisque nulla accusamus venenatis, sed quis. Nibh phasellus gravida metus in, fusce aenean ut erat commodo eros. Ut turpis, dui integer, nonummy pede placeat nec in sit leo. Faucibus porttitor illo taciti odio, amet viverra scelerisque quis quis et tortor, curabitur morbi a. Enim tempor at, rutrum elit condimentum, amet rutrum vitae tempor torquent nunc. Praesent vestibulum integer maxime felis. Neque aenean quia vitae nostra, tempus elit enim id dui, at egestas pulvinar. Integer libero vestibulum, quis blandit scelerisque mattis fermentum nulla, tortor donec vestibulum dolor amet eget, elit nullam. Aliquam leo phasellus aliquam curabitur metus a, nulla justo mattis duis interdum vel, mollis vitae et id, vestibulum erat ridiculus sit pulvinar justo sed. Vehicula convallis, et nulla wisi, amet vestibulum risus, quam ac egestas.
+ Et vitae, nulla gravida erat scelerisque nullam nunc pellentesque, a dictumst cras augue, purus imperdiet non. Varius montes cursus varius vel tortor, nec leo a qui, magni cras, velit vel consectetuer lobortis vel. Nibh erat et wisi felis leo porttitor, sapien nibh sapien pede mi, sed eget porttitor, repellendus arcu ac quis. Luctus vulputate aut est sem magna, placerat accumsan nunc vestibulum ipsum ac auctor, maecenas lorem in ut nec mauris tortor, doloribus varius sem tortor vestibulum mollis, eleifend tortor felis tempus lacus eu eu. Eleifend vel eu, nullam maecenas mauris nec nunc euismod, tortor porta ridiculus potenti, massa tristique nam magna, et wisi placerat et erat ante. Eget pede erat in facilisis, fermentum venenatis sodales. Ac tortor sociis et non animi tristique, rhoncus malesuada, ut arcu volutpat scelerisque sollicitudin, elit curabitur dui pede purus dolor, integer aenean risus taciti nulla eleifend accumsan. At pulvinar diam parturient, interdum mi velit aliquet et a. Arcu at ac placerat eget justo semper, purus sociis curabitur mi ipsum consequat ut, mollis vestibulum, est ante ornare lacus sem. Neque magna mauris, commodo quisque, praesent semper suscipit lobortis nam. Justo malesuada cursus ac nunc litora nunc. Tellus ac, in lobortis nunc, montes lectus purus fermentum.
+ Ac sit wisi. Sodales aliquam, sed vestibulum nullam arcu sit risus arcu, id luctus vitae lorem nibh, integer nec nullam class cursus mi, purus arcu lectus. Vel ante suscipit volutpat potenti mattis sed, wisi eu placerat aliquam erat, lectus morbi lobortis at assumenda. Consequat neque purus ipsum voluptas odio, netus vestibulum ut nec, suspendisse pellentesque nec enim in. Wisi dictum sed semper a, ipsum erat tellus habitasse est, erat sem ornare, vitae quisque ultricies. Dui sed blandit. Tempor et faucibus justo sed luctus, nec vitae vitae. Nunc nibh pede, ipsum vestibulum aenean leo ante ultricies, nam cras quis sed penatibus amet. In mauris a. Integer metus mauris tortor, et rutrum vestibulum ultricies, ut phasellus in ullamcorper ut mollit, eu justo. Cursus pretium venenatis.
+ Cras pellentesque vel sodales accumsan aenean. Feugiat metus sit nec in aliquet amet, porttitor pretium vulputate massa. Consequat ipsum luctus quisque adipiscing libero. Wisi sollicitudin. Eget vitae ac lobortis, lorem natoque vestibulum et, aliquet faucibus at morbi nibh, vel condimentum. Massa unde orci sed id sed, odio donec congue nec praesent amet. Hymenaeos velit lacus, quis vivamus libero tempus duis, eu nisi eu, ipsum at accumsan pede justo morbi donec, massa et libero sit risus neque tortor. Ut sed sed etiam hendrerit dapibus, quis metus suspendisse nibh.
+ Fringilla tempor felis augue magna. Cum arcu a, id vitae. Pellentesque pharetra in cras sociis adipiscing est. Nibh nec mattis at maecenas, nisl orci aliquam nulla justo egestas venenatis, elementum duis vel porta eros, massa vitae, eligendi imperdiet amet. Nec neque luctus suscipit, justo sem praesent, ut nisl quisque, volutpat torquent wisi tellus aliquam reprehenderit, curabitur cras at quis massa porttitor mauris. Eros sed ultrices. Amet dignissim justo urna feugiat mauris litora, etiam accumsan, lobortis a orci suspendisse. Semper ac mauris, varius bibendum pretium, orci urna nunc ullamcorper auctor, saepe sem integer quam, at feugiat egestas duis. Urna ligula ante. Leo elementum nonummy. Sagittis mauris est in ipsum, nulla amet non justo, proin id potenti platea posuere sit ut, nunc sit erat bibendum. Nibh id auctor, ab nulla vivamus ultrices, posuere morbi nunc tellus gravida vivamus.
+ Mauris nec, facilisi quam fermentum, ut mauris integer, orci tellus tempus diam ut in pellentesque. Wisi faucibus tempor et odio leo diam, eleifend quis integer curabitur sit scelerisque ac, mauris consequat luctus quam penatibus fringilla dis, vitae lacus in, est eu ac tempus. Consectetuer amet ipsum amet dui, sed blandit id sed. Tellus integer, dignissim id pede sodales quis, felis dolorem id mauris orci, orci tempus ut. Nullam hymenaeos. Curabitur in a, tortor ut praesent placerat tincidunt interdum, ac dignissim metus nonummy hendrerit wisi, etiam ut.
+ Semper praesent integer fusce, tortor suspendisse, augue ligula orci ante asperiores ullamcorper. In sit per mi sed sed, mi vestibulum mus nam, morbi mauris neque vitae aliquam proin senectus. Ac amet arcu mollis ante congue elementum, inceptos eget optio quam pellentesque quis lobortis, sollicitudin sed vestibulum sollicitudin, lectus parturient nullam, leo orci ligula ultrices. At tincidunt enim, suspendisse est sit sem ac. Amet tellus molestie est purus magna augue, non etiam et in wisi id. Non commodo, metus lorem facilisi lobortis ac velit, montes neque sed risus consectetuer fringilla dolor. Quam justo et integer aliquam, cursus nulla enim orci, nam cursus adipiscing, integer torquent non, fringilla per maecenas. Libero ipsum sed tellus purus et. Duis molestie placerat erat donec ut. Dolor enim erat massa faucibus ultrices in, ante ultricies orci lacus, libero consectetuer mauris magna feugiat neque dapibus, donec pretium et. Aptent dui, aliquam et et amet nostra ligula.
+ Augue curabitur duis dui volutpat, tempus sed ut pede donec. Interdum luctus, lectus nulla aenean elit, id sit magna, vulputate ultrices pellentesque vel id fermentum morbi. Tortor et. Adipiscing augue lorem cum non lacus, rutrum sodales laoreet duis tortor, modi placerat facilisis et malesuada eros ipsum, vehicula tempus. Ac vivamus amet non aliquam venenatis lectus, sociosqu adipiscing consequat nec arcu odio. Blandit orci nec nec, posuere in pretium, enim ut, consectetuer nullam urna, risus vel. Nullam odio vehicula massa sed, etiam sociis mauris, lacus ullamcorper, libero imperdiet non sodales placerat justo vehicula. Nec morbi imperdiet. Fermentum sem libero iaculis bibendum et eros, eget maecenas non nunc, ad pellentesque. Ut nec diam elementum interdum. Elementum vitae tellus lacus vitae, ipsum phasellus, corporis vehicula in ac sed massa vivamus, rutrum elit, ultricies metus volutpat.
+ Semper wisi et, sollicitudin nunc vestibulum, cursus accumsan nunc pede tempus mi ipsum, ligula sed. Non condimentum ac dolor sit. Mollis eu aliquam, vel mattis mollis massa ut dolor ante, tempus lacinia arcu. Urna vestibulum lorem, nulla fermentum, iaculis ut congue ac vivamus. Nam libero orci, pulvinar nulla, enim pellentesque consectetuer leo, feugiat rhoncus rhoncus vel. Magna sociosqu donec, dictum cursus ullamcorper viverra. Ultricies quis orci lorem, suspendisse ut vestibulum integer, purus sed lorem pulvinar habitasse turpis.
+ +
+ """
+ ],
+ ),
+ v.CardActions(
+ children=[
+ v.Spacer(),
+ v.Btn(
+ color="green darken-1",
+ children=["Disagree"],
+ ),
+ v.Btn(
+ color="green darken-1",
+ children=["Agree"],
+ ),
+ ]
+ ),
+ ]
+ )
+ ],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "dialog",
+ "children": v.Btn(
+ children=["Open Dialog"],
+ color="primary",
+ v_bind="dialog.attrs",
+ v_on="dialog.on",
+ ),
+ }
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Dialog/overflowed.vue b/docs/component/Dialog/overflowed.vue
new file mode 100644
index 00000000..3c02b949
--- /dev/null
+++ b/docs/component/Dialog/overflowed.vue
@@ -0,0 +1,148 @@
+
+
+
+
+
+ Open Dialog
+
+
+
+
+ Use Google's location service?
+
+
+ Lorem ipsum dolor sit amet, semper quis, sapien id natoque elit.
+ Nostra urna at, magna at neque sed sed ante imperdiet, dolor mauris
+ cursus velit, velit non, sem nec. Volutpat sem ridiculus placerat leo,
+ augue in, duis erat proin condimentum in a eget, sed fermentum sed
+ vestibulum varius ac, vestibulum volutpat orci ut elit eget tortor.
+ Ultrices nascetur nulla gravida ante arcu. Pharetra rhoncus morbi
+ ipsum, nunc tempor debitis, ipsum pellentesque, vitae id quam ut
+ mauris dui tempor, aptent non. Quisque turpis. Phasellus quis lectus
+ luctus orci eget rhoncus. Amet donec vestibulum mattis commodo, nulla
+ aliquet, nibh praesent, elementum nulla. Sit lacus pharetra tempus
+ magna neque pellentesque, nulla vel erat. Justo ex quisque nulla
+ accusamus venenatis, sed quis. Nibh phasellus gravida metus in, fusce
+ aenean ut erat commodo eros. Ut turpis, dui integer, nonummy pede
+ placeat nec in sit leo. Faucibus porttitor illo taciti odio, amet
+ viverra scelerisque quis quis et tortor, curabitur morbi a. Enim
+ tempor at, rutrum elit condimentum, amet rutrum vitae tempor torquent
+ nunc. Praesent vestibulum integer maxime felis. Neque aenean quia
+ vitae nostra, tempus elit enim id dui, at egestas pulvinar. Integer
+ libero vestibulum, quis blandit scelerisque mattis fermentum nulla,
+ tortor donec vestibulum dolor amet eget, elit nullam. Aliquam leo
+ phasellus aliquam curabitur metus a, nulla justo mattis duis interdum
+ vel, mollis vitae et id, vestibulum erat ridiculus sit pulvinar justo
+ sed. Vehicula convallis, et nulla wisi, amet vestibulum risus, quam ac
+ egestas. Et vitae, nulla gravida erat scelerisque nullam nunc
+ pellentesque, a dictumst cras augue, purus imperdiet non. Varius
+ montes cursus varius vel tortor, nec leo a qui, magni cras, velit vel
+ consectetuer lobortis vel. Nibh erat et wisi felis leo porttitor,
+ sapien nibh sapien pede mi, sed eget porttitor, repellendus arcu ac
+ quis. Luctus vulputate aut est sem magna, placerat accumsan nunc
+ vestibulum ipsum ac auctor, maecenas lorem in ut nec mauris tortor,
+ doloribus varius sem tortor vestibulum mollis, eleifend tortor felis
+ tempus lacus eu eu. Eleifend vel eu, nullam maecenas mauris nec nunc
+ euismod, tortor porta ridiculus potenti, massa tristique nam magna, et
+ wisi placerat et erat ante. Eget pede erat in facilisis, fermentum
+ venenatis sodales. Ac tortor sociis et non animi tristique, rhoncus
+ malesuada, ut arcu volutpat scelerisque sollicitudin, elit curabitur
+ dui pede purus dolor, integer aenean risus taciti nulla eleifend
+ accumsan. At pulvinar diam parturient, interdum mi velit aliquet et a.
+ Arcu at ac placerat eget justo semper, purus sociis curabitur mi ipsum
+ consequat ut, mollis vestibulum, est ante ornare lacus sem. Neque
+ magna mauris, commodo quisque, praesent semper suscipit lobortis nam.
+ Justo malesuada cursus ac nunc litora nunc. Tellus ac, in lobortis
+ nunc, montes lectus purus fermentum. Ac sit wisi. Sodales aliquam, sed
+ vestibulum nullam arcu sit risus arcu, id luctus vitae lorem nibh,
+ integer nec nullam class cursus mi, purus arcu lectus. Vel ante
+ suscipit volutpat potenti mattis sed, wisi eu placerat aliquam erat,
+ lectus morbi lobortis at assumenda. Consequat neque purus ipsum
+ voluptas odio, netus vestibulum ut nec, suspendisse pellentesque nec
+ enim in. Wisi dictum sed semper a, ipsum erat tellus habitasse est,
+ erat sem ornare, vitae quisque ultricies. Dui sed blandit. Tempor et
+ faucibus justo sed luctus, nec vitae vitae. Nunc nibh pede, ipsum
+ vestibulum aenean leo ante ultricies, nam cras quis sed penatibus
+ amet. In mauris a. Integer metus mauris tortor, et rutrum vestibulum
+ ultricies, ut phasellus in ullamcorper ut mollit, eu justo. Cursus
+ pretium venenatis. Cras pellentesque vel sodales accumsan aenean.
+ Feugiat metus sit nec in aliquet amet, porttitor pretium vulputate
+ massa. Consequat ipsum luctus quisque adipiscing libero. Wisi
+ sollicitudin. Eget vitae ac lobortis, lorem natoque vestibulum et,
+ aliquet faucibus at morbi nibh, vel condimentum. Massa unde orci sed
+ id sed, odio donec congue nec praesent amet. Hymenaeos velit lacus,
+ quis vivamus libero tempus duis, eu nisi eu, ipsum at accumsan pede
+ justo morbi donec, massa et libero sit risus neque tortor. Ut sed sed
+ etiam hendrerit dapibus, quis metus suspendisse nibh. Fringilla tempor
+ felis augue magna. Cum arcu a, id vitae. Pellentesque pharetra in cras
+ sociis adipiscing est. Nibh nec mattis at maecenas, nisl orci aliquam
+ nulla justo egestas venenatis, elementum duis vel porta eros, massa
+ vitae, eligendi imperdiet amet. Nec neque luctus suscipit, justo sem
+ praesent, ut nisl quisque, volutpat torquent wisi tellus aliquam
+ reprehenderit, curabitur cras at quis massa porttitor mauris. Eros sed
+ ultrices. Amet dignissim justo urna feugiat mauris litora, etiam
+ accumsan, lobortis a orci suspendisse. Semper ac mauris, varius
+ bibendum pretium, orci urna nunc ullamcorper auctor, saepe sem integer
+ quam, at feugiat egestas duis. Urna ligula ante. Leo elementum
+ nonummy. Sagittis mauris est in ipsum, nulla amet non justo, proin id
+ potenti platea posuere sit ut, nunc sit erat bibendum. Nibh id auctor,
+ ab nulla vivamus ultrices, posuere morbi nunc tellus gravida vivamus.
+ Mauris nec, facilisi quam fermentum, ut mauris integer, orci tellus
+ tempus diam ut in pellentesque. Wisi faucibus tempor et odio leo diam,
+ eleifend quis integer curabitur sit scelerisque ac, mauris consequat
+ luctus quam penatibus fringilla dis, vitae lacus in, est eu ac tempus.
+ Consectetuer amet ipsum amet dui, sed blandit id sed. Tellus integer,
+ dignissim id pede sodales quis, felis dolorem id mauris orci, orci
+ tempus ut. Nullam hymenaeos. Curabitur in a, tortor ut praesent
+ placerat tincidunt interdum, ac dignissim metus nonummy hendrerit
+ wisi, etiam ut. Semper praesent integer fusce, tortor suspendisse,
+ augue ligula orci ante asperiores ullamcorper. In sit per mi sed sed,
+ mi vestibulum mus nam, morbi mauris neque vitae aliquam proin
+ senectus. Ac amet arcu mollis ante congue elementum, inceptos eget
+ optio quam pellentesque quis lobortis, sollicitudin sed vestibulum
+ sollicitudin, lectus parturient nullam, leo orci ligula ultrices. At
+ tincidunt enim, suspendisse est sit sem ac. Amet tellus molestie est
+ purus magna augue, non etiam et in wisi id. Non commodo, metus lorem
+ facilisi lobortis ac velit, montes neque sed risus consectetuer
+ fringilla dolor. Quam justo et integer aliquam, cursus nulla enim
+ orci, nam cursus adipiscing, integer torquent non, fringilla per
+ maecenas. Libero ipsum sed tellus purus et. Duis molestie placerat
+ erat donec ut. Dolor enim erat massa faucibus ultrices in, ante
+ ultricies orci lacus, libero consectetuer mauris magna feugiat neque
+ dapibus, donec pretium et. Aptent dui, aliquam et et amet nostra
+ ligula. Augue curabitur duis dui volutpat, tempus sed ut pede donec.
+ Interdum luctus, lectus nulla aenean elit, id sit magna, vulputate
+ ultrices pellentesque vel id fermentum morbi. Tortor et. Adipiscing
+ augue lorem cum non lacus, rutrum sodales laoreet duis tortor, modi
+ placerat facilisis et malesuada eros ipsum, vehicula tempus. Ac
+ vivamus amet non aliquam venenatis lectus, sociosqu adipiscing
+ consequat nec arcu odio. Blandit orci nec nec, posuere in pretium,
+ enim ut, consectetuer nullam urna, risus vel. Nullam odio vehicula
+ massa sed, etiam sociis mauris, lacus ullamcorper, libero imperdiet
+ non sodales placerat justo vehicula. Nec morbi imperdiet. Fermentum
+ sem libero iaculis bibendum et eros, eget maecenas non nunc, ad
+ pellentesque. Ut nec diam elementum interdum. Elementum vitae tellus
+ lacus vitae, ipsum phasellus, corporis vehicula in ac sed massa
+ vivamus, rutrum elit, ultricies metus volutpat. Semper wisi et,
+ sollicitudin nunc vestibulum, cursus accumsan nunc pede tempus mi
+ ipsum, ligula sed. Non condimentum ac dolor sit. Mollis eu aliquam,
+ vel mattis mollis massa ut dolor ante, tempus lacinia arcu. Urna
+ vestibulum lorem, nulla fermentum, iaculis ut congue ac vivamus. Nam
+ libero orci, pulvinar nulla, enim pellentesque consectetuer leo,
+ feugiat rhoncus rhoncus vel. Magna sociosqu donec, dictum cursus
+ ullamcorper viverra. Ultricies quis orci lorem, suspendisse ut
+ vestibulum integer, purus sed lorem pulvinar habitasse turpis. +
+
+
+
+
+ Disagree
+
+
+ Agree
+
+
+
+
+
+
diff --git a/docs/component/Dialog/persistent.py b/docs/component/Dialog/persistent.py
new file mode 100644
index 00000000..eba57395
--- /dev/null
+++ b/docs/component/Dialog/persistent.py
@@ -0,0 +1,54 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="text-center",
+ children=[
+ v.Dialog(
+ v_model=False,
+ # persistent=True, # not working in the documentation so we comment it out
+ max_width=290,
+ children=[
+ v.Card(
+ children=[
+ v.CardTitle(
+ class_="text-h5",
+ children=["Use Google's location service?"],
+ ),
+ v.CardText(
+ children=[
+ "Let Google help apps determine location. This means sending anonymous location data to Google, even when no apps are running."
+ ]
+ ),
+ v.CardActions(
+ children=[
+ v.Spacer(),
+ v.Btn(
+ text=True,
+ color="green darken-1",
+ children=["Disagree"],
+ ),
+ v.Btn(
+ text=True,
+ color="green darken-1",
+ children=["Agree"],
+ ),
+ ]
+ ),
+ ]
+ )
+ ],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "dialog",
+ "children": v.Btn(
+ children=["Open Dialog"],
+ color="primary",
+ v_bind="dialog.attrs",
+ v_on="dialog.on",
+ ),
+ }
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Dialog/persistent.vue b/docs/component/Dialog/persistent.vue
new file mode 100644
index 00000000..582677ff
--- /dev/null
+++ b/docs/component/Dialog/persistent.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+ Open Dialog
+
+
+
+
+ Use Google's location service?
+
+ Let Google help apps determine location. This means sending anonymous
+ location data to Google, even when no apps are running.
+
+
+
+ Disagree
+
+
+ Agree
+
+
+
+
+
+
diff --git a/docs/component/Dialog/scrollable.py b/docs/component/Dialog/scrollable.py
new file mode 100644
index 00000000..fb996a66
--- /dev/null
+++ b/docs/component/Dialog/scrollable.py
@@ -0,0 +1,79 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="text-center",
+ children=[
+ v.Dialog(
+ v_model=False,
+ scrollable=True,
+ max_width=300,
+ children=[
+ v.Card(
+ children=[
+ v.CardTitle(
+ class_="text-h5",
+ children=["Select Country"],
+ ),
+ v.Divider(),
+ v.CardText(
+ style_="height: 300px;",
+ children=[
+ v.RadioGroup(
+ v_model=None,
+ column=True,
+ children=[
+ v.Radio(label="Bahamas, The", value="bahamas"),
+ v.Radio(label="Bahrain", value="bahrain"),
+ v.Radio(label="Bangladesh", value="bangladesh"),
+ v.Radio(label="Barbados", value="barbados"),
+ v.Radio(label="Belarus", value="belarus"),
+ v.Radio(label="Belgium", value="belgium"),
+ v.Radio(label="Belize", value="belize"),
+ v.Radio(label="Benin", value="benin"),
+ v.Radio(label="Bhutan", value="bhutan"),
+ v.Radio(label="Bolivia", value="bolivia"),
+ v.Radio(label="Bosnia and Herzegovina", value="bosnia"),
+ v.Radio(label="Botswana", value="botswana"),
+ v.Radio(label="Brazil", value="brazil"),
+ v.Radio(label="Brunei", value="brunei"),
+ v.Radio(label="Bulgaria", value="bulgaria"),
+ v.Radio(label="Burkina Faso", value="burkina"),
+ v.Radio(label="Burma", value="burma"),
+ v.Radio(label="Burundi", value="burundi"),
+ ],
+ )
+ ],
+ ),
+ v.Divider(),
+ v.CardActions(
+ children=[
+ v.Btn(
+ text=True,
+ color="blue darken-1",
+ children=["Close"],
+ ),
+ v.Btn(
+ text=True,
+ color="blue darken-1",
+ children=["Save"],
+ ),
+ ]
+ ),
+ ]
+ )
+ ],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "dialog",
+ "children": v.Btn(
+ children=["Open Dialog"],
+ color="primary",
+ v_bind="dialog.attrs",
+ v_on="dialog.on",
+ ),
+ }
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Dialog/scrollable.vue b/docs/component/Dialog/scrollable.vue
new file mode 100644
index 00000000..c8c47e79
--- /dev/null
+++ b/docs/component/Dialog/scrollable.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+ Open Dialog
+
+
+
+ Select Country
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Close
+
+
+ Save
+
+
+
+
+
+
diff --git a/docs/component/Dialog/transitions.py b/docs/component/Dialog/transitions.py
new file mode 100644
index 00000000..a3d65b99
--- /dev/null
+++ b/docs/component/Dialog/transitions.py
@@ -0,0 +1,89 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="text-center",
+ children=[
+ v.Dialog(
+ transition="dialog-bottom-transition",
+ children=[
+ v.Card(
+ children=[
+ v.Toolbar(
+ children=["Opening from the bottom"],
+ color="primary",
+ dark=True,
+ ),
+ v.CardText(
+ children=[
+ v.Html(tag="div", class_="text-h2 pa-12", children=["Hello world!"])
+ ]
+ ),
+ v.CardActions(
+ class_="justify-end",
+ children=[
+ v.Btn(
+ children=["Close"],
+ text=True,
+ )
+ ],
+ ),
+ ]
+ )
+ ],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "dialog_bottom",
+ "children": v.Btn(
+ class_="mx-4",
+ children=["From the bottom"],
+ color="primary",
+ v_bind="dialog_bottom.attrs",
+ v_on="dialog_bottom.on",
+ ),
+ }
+ ],
+ ),
+ v.Dialog(
+ transition="dialog-top-transition",
+ children=[
+ v.Card(
+ children=[
+ v.Toolbar(
+ children=["Opening from the top"],
+ color="primary",
+ dark=True,
+ ),
+ v.CardText(
+ children=[
+ v.Html(tag="div", class_="text-h2 pa-12", children=["Hello world!"])
+ ]
+ ),
+ v.CardActions(
+ class_="justify-end",
+ children=[
+ v.Btn(
+ children=["Close"],
+ text=True,
+ )
+ ],
+ ),
+ ]
+ )
+ ],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "dialog_top",
+ "children": v.Btn(
+ class_="mx-4",
+ children=["From the top"],
+ color="primary",
+ v_bind="dialog_top.attrs",
+ v_on="dialog_top.on",
+ ),
+ }
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Dialog/transitions.vue b/docs/component/Dialog/transitions.vue
new file mode 100644
index 00000000..6b1fc7b8
--- /dev/null
+++ b/docs/component/Dialog/transitions.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+ From the bottom
+
+
+
+ Opening from the bottom
+
+ Hello world!
+
+
+ Close
+
+
+
+
+
+
+
+
+
+ From the top
+
+
+
+ Opening from the top
+
+ Hello world!
+
+
+ Close
+
+
+
+
+
+
+
diff --git a/docs/component/Dialog/usage.py b/docs/component/Dialog/usage.py
new file mode 100644
index 00000000..5998a2fd
--- /dev/null
+++ b/docs/component/Dialog/usage.py
@@ -0,0 +1,53 @@
+import ipyvuetify as v
+
+dialog = v.Dialog(
+ v_model=False,
+ width=500,
+ children=[
+ v.Card(
+ children=[
+ v.CardTitle(
+ children=["Privacy Policy"],
+ class_="text-h5 grey lighten-2",
+ ),
+ v.CardText(
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, ",
+ "sed do eiusmod tempor incididunt ut labore et dolore magna ",
+ "aliqua. Ut enim ad minim veniam, quis nostrud exercitation "
+ "ullamco laboris nisi ut aliquip ex ea commodo consequat. "
+ "Duis aute irure dolor in reprehenderit in voluptate velit "
+ "esse cillum dolore eu fugiat nulla pariatur. Excepteur "
+ "sint occaecat cupidatat non proident, sunt in culpa qui "
+ "officia deserunt mollit anim id est laborum.",
+ ]
+ ),
+ v.Divider(),
+ v.CardActions(
+ children=[
+ v.Spacer(),
+ v.Btn(
+ children=["I accept"],
+ color="primary",
+ ),
+ ]
+ ),
+ ]
+ )
+ ],
+ v_slots=[
+ {
+ "name": "activator",
+ "variable": "dialog",
+ "children": v.Btn(
+ children=["Click me"],
+ color="red lighten-2",
+ dark=True,
+ v_bind="dialog.attrs",
+ v_on="dialog.on",
+ ),
+ }
+ ],
+)
+
+v.Container(children=[dialog], class_="text-center")
diff --git a/docs/component/Divider.rst b/docs/component/Divider.rst
new file mode 100644
index 00000000..acb66279
--- /dev/null
+++ b/docs/component/Divider.rst
@@ -0,0 +1,127 @@
+Divider
+=======
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Divider documentation
+ `__. All examples have been converted
+ to ipyvuetify syntax.
+
+The :py:class:`Divider ` component is used to separate sections of lists or layouts.
+
+.. api::
+
+ :py:class:`ipyvuetify.Divider`
+
+Usage
+-----
+
+Dividers in their simplest form display a horizontal line.
+
+.. jupyter-execute:: Divider/usage.py
+ :raises:
+
+Examples
+--------
+
+Inset
+^^^^^
+
+Inset dividers are moved 72px to the right. This will cause them to line up with list items.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Divider/inset.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Divider/inset.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Divider/inset.vue
+
+Vertical
+^^^^^^^^
+
+Vertical dividers give you more tools for unique layouts.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Divider/vertical.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Divider/vertical.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Divider/vertical.vue
+
+Portrait View
+^^^^^^^^^^^^^
+
+Create custom cards to fit any use-case.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Divider/portrait_view.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Divider/portrait_view.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Divider/portrait_view.vue
+
+Subheaders
+^^^^^^^^^^
+
+Dividers and :py:class:`Subheader ` components can help break up content
+and can optionally line up with one another by using the same ``inset`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Divider/subheaders.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Divider/subheaders.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Divider/subheaders.vue
+
+Accessibility
+-------------
+
+By default, :py:class:`Divider ` components are assigned the
+`WAI-ARIA `__ role of
+`separator `__ which denotes that the divider
+"separates and distinguishes sections of content or groups of menu items." However, sometimes
+a divider is just a way to make an interface look nice. In those cases, the role of
+`presentation `__ should be used which denotes
+"an element whose implicit native role semantics will not be mapped to the accessibility API."
+
+
+To override the default separator role in a :py:class:`Divider `, simply
+add a ``role="presentation"`` prop to your component. In addition, :py:class:`Divider `
+components have an ``aria-orientation="horizontal"``. If ``vertical=True``, then
+``aria-orientation="vertical"`` will be set automatically as well. If ``role="presentation"``,
+``aria-orientation="undefined"``, its default value.
diff --git a/docs/component/Divider/inset.py b/docs/component/Divider/inset.py
new file mode 100644
index 00000000..399a161b
--- /dev/null
+++ b/docs/component/Divider/inset.py
@@ -0,0 +1,59 @@
+import ipyvuetify as v
+
+items = [
+ {
+ "avatar": "https://cdn.vuetifyjs.com/images/lists/2.jpg",
+ "title": "Summer BBQ",
+ "subtitle": "to Alex, Scott, Jennifer - Wish I could come, but I'm out of town this weekend.",
+ },
+ {
+ "avatar": "https://cdn.vuetifyjs.com/images/lists/3.jpg",
+ "title": "Oui oui",
+ "subtitle": "Sandra Adams - Do you have Paris recommendations? Have you ever been?",
+ },
+ {
+ "avatar": "https://cdn.vuetifyjs.com/images/lists/1.jpg",
+ "title": "Brunch this weekend?",
+ "subtitle": "Ali Connors - I'll be in your neighborhood doing errands this weekend. Do you want to hang out?",
+ },
+]
+
+list_items = [
+ v.ListItem(
+ children=[
+ v.ListItemAvatar(children=[v.Img(src=item["avatar"])]),
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(children=[item["title"]]),
+ v.ListItemSubtitle(children=[item["subtitle"]]),
+ ]
+ ),
+ ]
+ )
+ for item in items
+]
+
+v.Container(
+ children=[
+ v.Card(
+ max_width="400",
+ children=[
+ v.CardTitle(children=[v.Html(tag="h2", children=["Today"])]),
+ v.CardText(
+ children=[
+ v.List(
+ two_line=True,
+ children=[
+ list_items[0],
+ v.Divider(inset=True),
+ list_items[1],
+ v.Divider(inset=True),
+ list_items[2],
+ ],
+ )
+ ]
+ ),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Divider/inset.vue b/docs/component/Divider/inset.vue
new file mode 100644
index 00000000..f09d8645
--- /dev/null
+++ b/docs/component/Divider/inset.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+ {{ item.header }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Divider/portrait_view.py b/docs/component/Divider/portrait_view.py
new file mode 100644
index 00000000..707d621c
--- /dev/null
+++ b/docs/component/Divider/portrait_view.py
@@ -0,0 +1,69 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Card(
+ xlass_="mx-auto",
+ max_width=600,
+ children=[
+ v.CardTitle(
+ class_="cyan darken-1",
+ children=[
+ v.Html(tag="span", class_="text-h5 white--text", children=["Sarah Mcbeal"]),
+ v.Spacer(),
+ v.Btn(
+ icon=True, dark=True, children=[v.Icon(children=["mdi-chevron-left"])]
+ ),
+ v.Btn(icon=True, dark=True, children=[v.Icon(children=["mdi-pencil"])]),
+ v.Btn(
+ icon=True, dark=True, children=[v.Icon(children=["mdi-dots-vertical"])]
+ ),
+ ],
+ ),
+ v.List(
+ children=[
+ v.ListItem(
+ children=[
+ v.ListItemAction(children=[v.Icon(children=["mdi-phone"])]),
+ v.ListItemContent(
+ children=[v.ListItemTitle(children=["(650) 555-1234"])]
+ ),
+ v.ListItemAction(children=[v.Icon(children=["mdi-message-text"])]),
+ ]
+ ),
+ v.Divider(inset=True, class_="mt-0"),
+ v.ListItem(
+ children=[
+ v.ListItemAction(children=[v.Icon(children=["mdi-phone"])]),
+ v.ListItemContent(
+ children=[v.ListItemTitle(children=["(323) 555-6789"])]
+ ),
+ v.ListItemAction(children=[v.Icon(children=["mdi-message-text"])]),
+ ]
+ ),
+ v.Divider(inset=True, class_="mt-0"),
+ v.ListItem(
+ children=[
+ v.ListItemAction(children=[v.Icon(children=["mdi-email"])]),
+ v.ListItemContent(
+ children=[v.ListItemTitle(children=["sarah@example.com"])]
+ ),
+ v.ListItemAction(children=[v.Icon(children=["mdi-message-text"])]),
+ ]
+ ),
+ v.Divider(inset=True, class_="mt-0"),
+ v.ListItem(
+ children=[
+ v.ListItemAction(children=[v.Icon(children=["mdi-email"])]),
+ v.ListItemContent(
+ children=[v.ListItemTitle(children=["Orlando, FL 79938"])]
+ ),
+ ]
+ ),
+ ]
+ ),
+ v.Img(src="https://picsum.photos/700?image=996", height="200px"),
+ ],
+ )
+ ]
+)
diff --git a/docs/component/Divider/portrait_view.vue b/docs/component/Divider/portrait_view.vue
new file mode 100644
index 00000000..ad4b1569
--- /dev/null
+++ b/docs/component/Divider/portrait_view.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+ Sarah Mcbeal
+
+
+
+
+ mdi-chevron-left
+
+
+
+ mdi-pencil
+
+
+
+ mdi-dots-vertical
+
+
+
+
+
+
+ mdi-phone
+
+
+
+ (650) 555-1234
+
+
+ mdi-message-text
+
+
+
+
+
+
+
+ mdi-phone
+
+
+
+ (323) 555-6789
+
+
+
+ mdi-message-text
+
+
+
+
+
+
+
+ mdi-email
+
+
+
+ mcbeal@example.com
+
+
+
+
+
+
+
+ mdi-map-marker
+
+
+
+ Orlando, FL 79938
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Divider/subheaders.py b/docs/component/Divider/subheaders.py
new file mode 100644
index 00000000..da6a2474
--- /dev/null
+++ b/docs/component/Divider/subheaders.py
@@ -0,0 +1,93 @@
+import ipyvuetify as v
+
+items = [
+ {
+ "avatar": "https://picsum.photos/250/300?image=660",
+ "title": "Meeting @ Noon",
+ "subtitle": "Spike Lee - I'll be in your neighborhood",
+ },
+ {
+ "avatar": "https://picsum.photos/250/300?image=821",
+ "title": "Summer BBQ",
+ "subtitle": "to Operations support - Wish I could come.",
+ },
+ {
+ "avatar": "https://picsum.photos/250/300?image=783",
+ "title": "Yes yes",
+ "subtitle": "Bella - Do you have Paris recommendations",
+ },
+ {
+ "avatar": "https://picsum.photos/250/300?image=1006",
+ "title": "Dinner tonight?",
+ "subtitle": "LaToya - Do you want to hang out?",
+ },
+ {
+ "avatar": "https://picsum.photos/250/300?image=146",
+ "title": "So long",
+ "subtitle": "Nancy - Do you see what time it is?",
+ },
+ {
+ "avatar": "https://picsum.photos/250/300?image=1008",
+ "title": "Breakfast?",
+ "subtitle": "LaToya - Do you want to hang out?",
+ },
+ {
+ "avatar": "https://picsum.photos/250/300?image=839",
+ "title": "Winter Porridge",
+ "subtitle": "cc: Daniel - Tell me more...",
+ },
+ {
+ "avatar": "https://picsum.photos/250/300?image=145",
+ "title": "Oui oui",
+ "subtitle": "Nancy - Do you see what time it is?",
+ },
+]
+
+list_items = [
+ v.ListItem(
+ children=[
+ v.ListItemAvatar(children=[v.Img(src=item["avatar"])]),
+ v.ListItemContent(
+ children=[
+ v.ListItemTitle(children=[item["title"]]),
+ v.ListItemSubtitle(children=[item["subtitle"]]),
+ ]
+ ),
+ ]
+ )
+ for item in items
+]
+
+v.Container(
+ children=[
+ v.Card(
+ max_width="600",
+ children=[
+ v.Toolbar(
+ color="orange lighten-1",
+ dark=True,
+ children=[
+ v.AppBarNavIcon(),
+ v.ToolbarTitle(children=["Message Board"]),
+ v.Spacer(),
+ v.Btn(icon=True, children=[v.Icon(children=["mdi-magnify"])]),
+ ],
+ ),
+ v.List(
+ two_line=True,
+ children=[
+ v.Subheader(inset=True, children=["Today"]),
+ v.Divider(inset=True, class_="mt-0"),
+ *list_items[:3],
+ v.Subheader(inset=True, children=["Yesterday"]),
+ v.Divider(inset=True, class_="mt-0"),
+ *list_items[3:6],
+ v.Subheader(inset=True, children=["Last Week"]),
+ v.Divider(inset=True, class_="mt-0"),
+ *list_items[6:],
+ ],
+ ),
+ ],
+ )
+ ]
+)
diff --git a/docs/component/Divider/subheaders.vue b/docs/component/Divider/subheaders.vue
new file mode 100644
index 00000000..407b8208
--- /dev/null
+++ b/docs/component/Divider/subheaders.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+ Message Board
+
+
+
+
+ mdi-magnify
+
+
+
+
+
+
+ {{ item.header }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Divider/usage.py b/docs/component/Divider/usage.py
new file mode 100644
index 00000000..39151bdf
--- /dev/null
+++ b/docs/component/Divider/usage.py
@@ -0,0 +1,3 @@
+import ipyvuetify as v
+
+v.Divider()
diff --git a/docs/component/Divider/vertical.py b/docs/component/Divider/vertical.py
new file mode 100644
index 00000000..3dd871fa
--- /dev/null
+++ b/docs/component/Divider/vertical.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+v.Toolbar(
+ color="purple",
+ dark=True,
+ children=[
+ v.ToolbarTitle(children=["Title"]),
+ v.Divider(class_="mx-4", vertical=True),
+ v.Html(tag="span", class_="subheading", children=["My Home"]),
+ v.Spacer(),
+ v.ToolbarItems(
+ class_="hidden-sm-and-down",
+ children=[
+ v.Btn(text=True, children=["News"]),
+ v.Divider(vertical=True),
+ v.Btn(text=True, children=["Blog"]),
+ v.Divider(vertical=True),
+ v.Btn(text=True, children=["Music"]),
+ v.Divider(vertical=True),
+ ],
+ ),
+ v.AppBarNavIcon(),
+ ],
+)
diff --git a/docs/component/Divider/vertical.vue b/docs/component/Divider/vertical.vue
new file mode 100644
index 00000000..ce9ba3e3
--- /dev/null
+++ b/docs/component/Divider/vertical.vue
@@ -0,0 +1,27 @@
+
+
+ Title
+
+
+
+ My Home
+
+
+
+
+ News
+
+
+
+ Blog
+
+
+
+ Music
+
+
+
+
+
+
+
diff --git a/docs/component/ExpansionPanels.rst b/docs/component/ExpansionPanels.rst
new file mode 100644
index 00000000..2d5b12c8
--- /dev/null
+++ b/docs/component/ExpansionPanels.rst
@@ -0,0 +1,219 @@
+ExpansionPanels
+===============
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Expansion Panels documentation
+ `__. All examples have been converted
+ to ipyvuetify syntax.
+
+The :py:class:`ExpansionPanel ` component is useful for reducing
+vertical space with large amounts of information. The default functionality of the component is
+to only display one expansion-panel body at a time; however, with the ``multiple`` property,
+the expansion-panel can remain open until explicitly closed.
+
+.. api::
+
+ - :py:class:`ipyvuetify.ExpansionPanels`
+ - :py:class:`ipyvuetify.ExpansionPanel`
+ - :py:class:`ipyvuetify.ExpansionPanelHeader`
+ - :py:class:`ipyvuetify.ExpansionPanelContent`
+ - :py:class:`ipyvuetify.ExpandTransition`
+
+Usage
+-----
+
+Expansion panels in their simplest form display a list of expandable items.
+
+.. jupyter-execute:: ExpansionPanels/usage.py
+ :raises:
+
+Examples
+--------
+
+Accordion
+^^^^^^^^^
+
+Accordion expansion-panel hasn't got margins around active panel.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ExpansionPanels/accordion.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ExpansionPanels/accordion.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ExpansionPanels/accordion.vue
+
+Disabled
+^^^^^^^^
+
+Both the :py:class:`ExpansionPanel ` and its content
+can be disabled using the ``disabled`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ExpansionPanels/disabled.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ExpansionPanels/disabled.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ExpansionPanels/disabled.vue
+
+Focusable
+^^^^^^^^^
+
+The expansion-panel headers can be made focusable with the prop ``focusable``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ExpansionPanels/focusable.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ExpansionPanels/focusable.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ExpansionPanels/focusable.vue
+
+Inset
+^^^^^
+
+Inset expansion-panel becomes smaller when activated.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ExpansionPanels/inset.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ExpansionPanels/inset.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ExpansionPanels/inset.vue
+
+Model
+^^^^^
+
+Expansion panels can be controlled externally by modifying the ``v_model``. Its
+value corresponds to a zero-based index of the currently opened expansion panel
+content. If ``multiple`` prop is used then it is an array containing the indices
+of the open items.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ExpansionPanels/model.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ExpansionPanels/model.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ExpansionPanels/model.vue
+
+Popout
+^^^^^^
+
+The expansion-panel also has ``popout`` design. With it, expansion-panel is
+enlarged when activated.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ExpansionPanels/popout.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ExpansionPanels/popout.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ExpansionPanels/popout.vue
+
+Readonly
+^^^^^^^^
+
+The ``readonly`` prop does the same thing as ``disabled``, but it doesn't touch styles.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ExpansionPanels/readonly.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ExpansionPanels/readonly.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ExpansionPanels/readonly.vue
+
+Advanced
+^^^^^^^^
+
+The expansion panel component provides a rich playground to build truly advanced
+implementations. Here we take advantage of slots in the
+:py:class:`ExpansionPanelHeader ` component to
+react to the state of being open or closed by fading content in and out.
+
+.. todo::
+
+ This example depends heavily on the slot system which is quite sophisticated,
+ any brave soul willing to translate it to ipyvuetify syntax will be greatly appreciated.
+ :fas:`heart`
+
+Custom icon
+^^^^^^^^^^^
+
+Expand action icon can be customized with ``expand_icon`` prop or the ``actions`` slot.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: ExpansionPanels/custom_icon.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: ExpansionPanels/custom_icon.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: ExpansionPanels/custom_icon.vue
+
diff --git a/docs/component/ExpansionPanels/accordion.py b/docs/component/ExpansionPanels/accordion.py
new file mode 100644
index 00000000..663fad77
--- /dev/null
+++ b/docs/component/ExpansionPanels/accordion.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+v.Card(
+ elevation=15,
+ class_="pa-2",
+ children=[
+ v.ExpansionPanels(
+ accordion=True,
+ children=[
+ v.ExpansionPanel(
+ children=[
+ v.ExpansionPanelHeader(children=["Item"]),
+ v.ExpansionPanelContent(
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+ ]
+ ),
+ ]
+ )
+ for i in range(5)
+ ],
+ )
+ ],
+)
diff --git a/docs/component/ExpansionPanels/accordion.vue b/docs/component/ExpansionPanels/accordion.vue
new file mode 100644
index 00000000..ab619868
--- /dev/null
+++ b/docs/component/ExpansionPanels/accordion.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ Item
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+ minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat.
+
+
+
+
+
diff --git a/docs/component/ExpansionPanels/custom_icon.py b/docs/component/ExpansionPanels/custom_icon.py
new file mode 100644
index 00000000..d1726dfc
--- /dev/null
+++ b/docs/component/ExpansionPanels/custom_icon.py
@@ -0,0 +1,41 @@
+import ipyvuetify as v
+
+list_icons = [
+ {"icon": "mdi-chevron-up", "color": "primary"},
+ {"icon": "mdi-check", "color": "teal"},
+ {"icon": "mdi-alert-circle", "color": "error"},
+]
+
+v.Card(
+ elevation=15,
+ class_="pa-2",
+ children=[
+ v.ExpansionPanels(
+ children=[
+ v.ExpansionPanel(
+ children=[
+ v.ExpansionPanelHeader(
+ disable_icon_rotate=i != 0,
+ children=["Item"],
+ v_slots=[
+ {
+ "name": "actions",
+ "children": v.Icon(
+ color=list_icons[i]["color"],
+ children=[list_icons[i]["icon"]],
+ ),
+ }
+ ],
+ ),
+ v.ExpansionPanelContent(
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+ ]
+ ),
+ ]
+ )
+ for i in range(3)
+ ]
+ )
+ ],
+)
diff --git a/docs/component/ExpansionPanels/custom_icon.vue b/docs/component/ExpansionPanels/custom_icon.vue
new file mode 100644
index 00000000..668e4927
--- /dev/null
+++ b/docs/component/ExpansionPanels/custom_icon.vue
@@ -0,0 +1,64 @@
+
+
+
+
+
+ Item
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+ minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat.
+
+
+
+
+
+
+ Item
+
+ $expand
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+ minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat.
+
+
+
+
+
+ Item
+
+ mdi-check
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+ minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat.
+
+
+
+
+
+ Item
+
+ mdi-alert-circle
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+ minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat.
+
+
+
+
+
diff --git a/docs/component/ExpansionPanels/disabled.py b/docs/component/ExpansionPanels/disabled.py
new file mode 100644
index 00000000..60bf0b21
--- /dev/null
+++ b/docs/component/ExpansionPanels/disabled.py
@@ -0,0 +1,22 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+checkbox = v.Checkbox(label="Disabled", v_model=False)
+
+panels = v.ExpansionPanels(
+ disabled=False,
+ children=[
+ v.ExpansionPanel(
+ children=[
+ v.ExpansionPanelHeader(children=[f"Panel {i+1}"]),
+ v.ExpansionPanelContent(children=["Some content"]),
+ ]
+ )
+ for i in range(3)
+ ],
+)
+
+jslink((checkbox, "v_model"), (panels, "disabled"))
+
+v.Container(children=[v.Row(children=[checkbox]), panels])
diff --git a/docs/component/ExpansionPanels/disabled.vue b/docs/component/ExpansionPanels/disabled.vue
new file mode 100644
index 00000000..7674db98
--- /dev/null
+++ b/docs/component/ExpansionPanels/disabled.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+ Panel 1
+ Some content
+
+
+
+ Panel 2
+ Some content
+
+
+
+ Panel 3
+ Some content
+
+
+
+
diff --git a/docs/component/ExpansionPanels/focusable.py b/docs/component/ExpansionPanels/focusable.py
new file mode 100644
index 00000000..037569eb
--- /dev/null
+++ b/docs/component/ExpansionPanels/focusable.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+v.Card(
+ elevation=15,
+ class_="pa-2",
+ children=[
+ v.ExpansionPanels(
+ focusable=True,
+ children=[
+ v.ExpansionPanel(
+ children=[
+ v.ExpansionPanelHeader(children=["Item"]),
+ v.ExpansionPanelContent(
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+ ]
+ ),
+ ]
+ )
+ for i in range(5)
+ ],
+ )
+ ],
+)
diff --git a/docs/component/ExpansionPanels/focusable.vue b/docs/component/ExpansionPanels/focusable.vue
new file mode 100644
index 00000000..a2e5e61e
--- /dev/null
+++ b/docs/component/ExpansionPanels/focusable.vue
@@ -0,0 +1,13 @@
+
+
+
+ Item
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
+ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+ commodo consequat.
+
+
+
+
diff --git a/docs/component/ExpansionPanels/inset.py b/docs/component/ExpansionPanels/inset.py
new file mode 100644
index 00000000..bd1628b6
--- /dev/null
+++ b/docs/component/ExpansionPanels/inset.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+v.Card(
+ elevation=15,
+ class_="pa-2",
+ children=[
+ v.ExpansionPanels(
+ inset=True,
+ children=[
+ v.ExpansionPanel(
+ children=[
+ v.ExpansionPanelHeader(children=["Item"]),
+ v.ExpansionPanelContent(
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+ ]
+ ),
+ ]
+ )
+ for i in range(5)
+ ],
+ )
+ ],
+)
diff --git a/docs/component/ExpansionPanels/inset.vue b/docs/component/ExpansionPanels/inset.vue
new file mode 100644
index 00000000..c78163c6
--- /dev/null
+++ b/docs/component/ExpansionPanels/inset.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ Item
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+ minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat.
+
+
+
+
+
diff --git a/docs/component/ExpansionPanels/model.py b/docs/component/ExpansionPanels/model.py
new file mode 100644
index 00000000..0a408d2e
--- /dev/null
+++ b/docs/component/ExpansionPanels/model.py
@@ -0,0 +1,35 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+select = v.Select(
+ label="Select panels",
+ v_model=[],
+ items=[{"text": f"Panel {i+1}", "value": i} for i in range(5)],
+ multiple=True,
+ readonly=True,
+ chips=True,
+)
+
+panels = v.ExpansionPanels(
+ v_model=[],
+ inset=True,
+ multiple=True,
+ children=[
+ v.ExpansionPanel(
+ children=[
+ v.ExpansionPanelHeader(children=["Item"]),
+ v.ExpansionPanelContent(
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+ ]
+ ),
+ ]
+ )
+ for i in range(5)
+ ],
+)
+
+jslink((select, "v_model"), (panels, "v_model"))
+
+v.Card(class_="pa-2", children=[select, panels])
diff --git a/docs/component/ExpansionPanels/model.vue b/docs/component/ExpansionPanels/model.vue
new file mode 100644
index 00000000..e793a137
--- /dev/null
+++ b/docs/component/ExpansionPanels/model.vue
@@ -0,0 +1,21 @@
+
+
+
+
all
+
{{ panel }}
+
none
+
+
+
+
+ Header {{ item }}
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+ minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat.
+
+
+
+
+
diff --git a/docs/component/ExpansionPanels/popout.py b/docs/component/ExpansionPanels/popout.py
new file mode 100644
index 00000000..526d6494
--- /dev/null
+++ b/docs/component/ExpansionPanels/popout.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+v.Card(
+ elevation=15,
+ class_="pa-2",
+ children=[
+ v.ExpansionPanels(
+ popout=True,
+ children=[
+ v.ExpansionPanel(
+ children=[
+ v.ExpansionPanelHeader(children=["Item"]),
+ v.ExpansionPanelContent(
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+ ]
+ ),
+ ]
+ )
+ for i in range(5)
+ ],
+ )
+ ],
+)
diff --git a/docs/component/ExpansionPanels/popout.vue b/docs/component/ExpansionPanels/popout.vue
new file mode 100644
index 00000000..e02f3794
--- /dev/null
+++ b/docs/component/ExpansionPanels/popout.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ Item
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
+ eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
+ minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+ aliquip ex ea commodo consequat.
+
+
+
+
+
diff --git a/docs/component/ExpansionPanels/readonly.py b/docs/component/ExpansionPanels/readonly.py
new file mode 100644
index 00000000..23f6b31a
--- /dev/null
+++ b/docs/component/ExpansionPanels/readonly.py
@@ -0,0 +1,22 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+checkbox = v.Checkbox(label="Readonly", v_model=False)
+
+panels = v.ExpansionPanels(
+ readonly=False,
+ children=[
+ v.ExpansionPanel(
+ children=[
+ v.ExpansionPanelHeader(children=[f"Panel {i+1}"]),
+ v.ExpansionPanelContent(children=["Some content"]),
+ ]
+ )
+ for i in range(3)
+ ],
+)
+
+jslink((checkbox, "v_model"), (panels, "disabled"))
+
+v.Container(children=[v.Row(children=[checkbox]), panels])
diff --git a/docs/component/ExpansionPanels/readonly.vue b/docs/component/ExpansionPanels/readonly.vue
new file mode 100644
index 00000000..8e7f7be9
--- /dev/null
+++ b/docs/component/ExpansionPanels/readonly.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+ Panel 1
+ Some content
+
+
+
+ Panel 2
+ Some content
+
+
+
+ Panel 3
+ Some content
+
+
+
+
diff --git a/docs/component/ExpansionPanels/usage.py b/docs/component/ExpansionPanels/usage.py
new file mode 100644
index 00000000..4cbd3b20
--- /dev/null
+++ b/docs/component/ExpansionPanels/usage.py
@@ -0,0 +1,23 @@
+import ipyvuetify as v
+
+v.Card(
+ elevation=15,
+ class_="pa-2",
+ children=[
+ v.ExpansionPanels(
+ children=[
+ v.ExpansionPanel(
+ children=[
+ v.ExpansionPanelHeader(children=["Item"]),
+ v.ExpansionPanelContent(
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+ ]
+ ),
+ ]
+ )
+ for i in range(5)
+ ]
+ )
+ ],
+)
diff --git a/docs/component/FileInput.rst b/docs/component/FileInput.rst
new file mode 100644
index 00000000..62314f7c
--- /dev/null
+++ b/docs/component/FileInput.rst
@@ -0,0 +1,229 @@
+FileInput
+=========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify File Input documentation
+ `__. All examples have been converted
+ to ipyvuetify syntax.
+
+The :py:class:`FileInput ` component is a specialized input that provides
+a clean interface for selecting files, showing detailed selection information and upload progress.
+It is meant to be a direct replacement for a standard file input.
+
+.. api::
+
+ :py:class:`ipyvuetify.FileInput`
+
+Usage
+-----
+
+At its core, the :py:class:`FileInput ` component is a basic
+container that extends :py:class:`TextField `.
+
+.. jupyter-execute:: FileInput/usage.py
+ :raises:
+
+Examples
+--------
+
+Accept
+^^^^^^
+
+:py:class:`FileInput ` component can accept only specific
+media formats/file types if you want. For more information, checkout the documentation
+on the `accept attribute `__.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: FileInput/accept.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: FileInput/accept.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: FileInput/accept.vue
+
+Chips
+^^^^^
+
+A selected file can be displayed as a :py:class:`Chip `. When using
+the ``chips`` and ``multiple`` props, each chip will be displayed (as opposed to
+the file count).
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: FileInput/chips.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: FileInput/chips.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: FileInput/chips.vue
+
+Counter
+^^^^^^^
+
+When using the ``show_size`` property along with ``counter``, the total number of
+files and size will be displayed under the input.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: FileInput/counter.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: FileInput/counter.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: FileInput/counter.vue
+
+Dense
+^^^^^
+
+You can reduces the file input height with ``dense`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: FileInput/dense.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: FileInput/dense.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: FileInput/dense.vue
+
+Multiple
+^^^^^^^^
+
+The :py:class:`FileInput ` can contain multiple files at the
+same time when using the ``multiple`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: FileInput/multiple.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: FileInput/multiple.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: FileInput/multiple.vue
+
+Prepend icon
+^^^^^^^^^^^^
+
+The :py:class:`FileInput ` has a default ``prepend_icon``
+that can be set on the component or adjusted globally. More information on
+changing global components can be found on the
+`customizing icons page `__.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: FileInput/prepend_icon.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: FileInput/prepend_icon.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: FileInput/prepend_icon.vue
+
+Show size
+^^^^^^^^^
+
+The displayed size of the selected file(s) can be configured with the ``show_size``
+property. Display sizes can be either 1024 (the default used when providing
+``True``) or 1000.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: FileInput/show_size.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: FileInput/show_size.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: FileInput/show_size.vue
+
+Validation
+^^^^^^^^^^
+
+Similar to other inputs, you can use the ``rules`` prop to create your own
+custom validation parameters.
+
+.. todo::
+
+ I'm not sure it's possible to make this work in ipyvuetify since it rely on javascript
+ functions. Maybe a genius from the community can figure it out :fas:`face-smile-wink`
+
+Selection slot
+^^^^^^^^^^^^^^
+
+Using the ``selection`` slot, you can customize the appearance of your input selections.
+This is typically done with :py:class:`Chip ` components, however
+any component or markup can be used.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: FileInput/selection_slot.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: FileInput/selection_slot.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: FileInput/selection_slot.vue
+
+Complex selection slot
+^^^^^^^^^^^^^^^^^^^^^^
+
+The flexibility of the selection slot allows you accommodate complex use-cases. In this example we show the first 2 selections as chips while adding a number indicator for the remaining amount.
+
+.. todo::
+
+ I'm not sure it's possible to make this work in ipyvuetify since it rely on javascript
+ functions. Maybe a genius from the community can figure it out :fas:`face-smile-wink`
diff --git a/docs/component/FileInput/accept.py b/docs/component/FileInput/accept.py
new file mode 100644
index 00000000..9113c4db
--- /dev/null
+++ b/docs/component/FileInput/accept.py
@@ -0,0 +1,6 @@
+import ipyvuetify as v
+
+v.FileInput(
+ accept="image/*",
+ label="File input",
+)
diff --git a/docs/component/FileInput/accept.vue b/docs/component/FileInput/accept.vue
new file mode 100644
index 00000000..1d1c2536
--- /dev/null
+++ b/docs/component/FileInput/accept.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/docs/component/FileInput/chips.py b/docs/component/FileInput/chips.py
new file mode 100644
index 00000000..ed4c89e8
--- /dev/null
+++ b/docs/component/FileInput/chips.py
@@ -0,0 +1,18 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+chip = v.FileInput(
+ v_model=None,
+ chips=True,
+ label="File input w/ chips",
+)
+small_chip = v.FileInput(
+ v_model=None,
+ small_chips=True,
+ label="File input w/ small chips",
+)
+
+jslink((chip, "v_model"), (small_chip, "v_model"))
+
+v.Container(children=[chip, small_chip])
diff --git a/docs/component/FileInput/chips.vue b/docs/component/FileInput/chips.vue
new file mode 100644
index 00000000..45c2facf
--- /dev/null
+++ b/docs/component/FileInput/chips.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/docs/component/FileInput/counter.py b/docs/component/FileInput/counter.py
new file mode 100644
index 00000000..df9274e7
--- /dev/null
+++ b/docs/component/FileInput/counter.py
@@ -0,0 +1,8 @@
+import ipyvuetify as v
+
+v.FileInput(
+ show_size=True,
+ counter=True,
+ multiple=True,
+ label="File input",
+)
diff --git a/docs/component/FileInput/counter.vue b/docs/component/FileInput/counter.vue
new file mode 100644
index 00000000..23726678
--- /dev/null
+++ b/docs/component/FileInput/counter.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/docs/component/FileInput/dense.py b/docs/component/FileInput/dense.py
new file mode 100644
index 00000000..51e7e068
--- /dev/null
+++ b/docs/component/FileInput/dense.py
@@ -0,0 +1,7 @@
+import ipyvuetify as v
+
+v.FileInput(
+ label="File input",
+ outlined=True,
+ dense=True,
+)
diff --git a/docs/component/FileInput/dense.vue b/docs/component/FileInput/dense.vue
new file mode 100644
index 00000000..ab5192cf
--- /dev/null
+++ b/docs/component/FileInput/dense.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/docs/component/FileInput/multiple.py b/docs/component/FileInput/multiple.py
new file mode 100644
index 00000000..d1b435ac
--- /dev/null
+++ b/docs/component/FileInput/multiple.py
@@ -0,0 +1,6 @@
+import ipyvuetify as v
+
+v.FileInput(
+ multiple=True,
+ label="File input",
+)
diff --git a/docs/component/FileInput/multiple.vue b/docs/component/FileInput/multiple.vue
new file mode 100644
index 00000000..5139f82b
--- /dev/null
+++ b/docs/component/FileInput/multiple.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/docs/component/FileInput/prepend_icon.py b/docs/component/FileInput/prepend_icon.py
new file mode 100644
index 00000000..ac574ae6
--- /dev/null
+++ b/docs/component/FileInput/prepend_icon.py
@@ -0,0 +1,7 @@
+import ipyvuetify as v
+
+v.FileInput(
+ label="File input",
+ filled=True,
+ prepend_icon="mdi-camera",
+)
diff --git a/docs/component/FileInput/prepend_icon.vue b/docs/component/FileInput/prepend_icon.vue
new file mode 100644
index 00000000..2ca68f6a
--- /dev/null
+++ b/docs/component/FileInput/prepend_icon.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/docs/component/FileInput/selection_slot.py b/docs/component/FileInput/selection_slot.py
new file mode 100644
index 00000000..59a2c987
--- /dev/null
+++ b/docs/component/FileInput/selection_slot.py
@@ -0,0 +1,21 @@
+import ipyvuetify as v
+
+v.FileInput(
+ v_model=None,
+ label="File input",
+ multiple=True,
+ placeholder="Upload your documents",
+ prepend_icon="mdi-paperclip",
+ v_slots=[
+ {
+ "name": "selection",
+ "variable": "selection",
+ "children": v.Chip(
+ children=["selection.text"],
+ small=True,
+ label=True,
+ color="primary",
+ ),
+ }
+ ],
+)
diff --git a/docs/component/FileInput/selection_slot.vue b/docs/component/FileInput/selection_slot.vue
new file mode 100644
index 00000000..24fb8b92
--- /dev/null
+++ b/docs/component/FileInput/selection_slot.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ {{ text }}
+
+
+
+
diff --git a/docs/component/FileInput/show_size.py b/docs/component/FileInput/show_size.py
new file mode 100644
index 00000000..c8c9d306
--- /dev/null
+++ b/docs/component/FileInput/show_size.py
@@ -0,0 +1,3 @@
+import ipyvuetify as v
+
+v.FileInput(show_size=True, label="File input")
diff --git a/docs/component/FileInput/show_size.vue b/docs/component/FileInput/show_size.vue
new file mode 100644
index 00000000..f0f033dd
--- /dev/null
+++ b/docs/component/FileInput/show_size.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/docs/component/FileInput/usage.py b/docs/component/FileInput/usage.py
new file mode 100644
index 00000000..33c28db0
--- /dev/null
+++ b/docs/component/FileInput/usage.py
@@ -0,0 +1,8 @@
+import ipyvuetify as v
+
+v.FileInput(
+ chips=True,
+ counter=True,
+ show_size=True,
+ truncate_length=20,
+)
diff --git a/docs/component/Flex.rst b/docs/component/Flex.rst
new file mode 100644
index 00000000..9a5bdd3f
--- /dev/null
+++ b/docs/component/Flex.rst
@@ -0,0 +1,1098 @@
+Flex
+====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Flex documentation
+ `__. All examples have been converted
+ to ipyvuetify syntax.
+
+Control the layout of flex containers with alignment, justification and more with
+responsive flexbox utilities.
+
+.. note::
+ Flex is implemented using CSS utility classes that you apply via the ``class_``
+ parameter on ipyvuetify components.
+
+.. Warning::
+
+ The ``d-flex`` class sets the CSS of the according element to
+ ``display: flex !important``. As a result, it overrides any other settings.
+
+
+
+Enabling flexbox
+----------------
+
+Using **display** utilities you can turn any element into a flexbox container
+transforming direct children elements into flex items. Using additional flex
+property utilities, you can customize their interaction even further.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/enabling_flexbox.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/enabling_flexbox.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/enabling_flexbox.vue
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute::
+ :raises:
+ :hide-code:
+
+ import ipyvuetify as v
+
+ v.Card(
+ class_="d-inline-flex pa-2",
+ outlined=True,
+ tile=True,
+ children=[
+ v.Html(tag="div", children=["I'm an inline flexbox container!"])
+ ]
+ )
+
+ .. tab-item:: :fab:`python` Python
+
+ .. code-block:: python
+
+ import ipyvuetify as v
+
+ v.Card(
+ class_="d-inline-flex pa-2",
+ outlined=True,
+ tile=True,
+ children=[
+ v.Html(tag="div", children=["I'm an inline flexbox container!"])
+ ]
+ )
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. code-block:: vue
+
+
+
+
+ I'm an inline flexbox container!
+
+
+
+
+You can also customize flex utilities to apply based upon various breakpoints:
+
+- ``.d-flex``
+- ``.d-inline-flex``
+- ``.d-sm-flex``
+- ``.d-sm-inline-flex``
+- ``.d-md-flex``
+- ``.d-md-inline-flex``
+- ``.d-lg-flex``
+- ``.d-lg-inline-flex``
+- ``.d-xl-flex``
+- ``.d-xl-inline-flex``
+
+Examples
+--------
+
+Flex direction
+^^^^^^^^^^^^^^
+
+By default, ``d-flex`` applies ``flex-direction: row`` and can generally be omitted.
+However, there may be situations where you need to explicitly define it.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/flex_direction.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/flex_direction.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/flex_direction.vue
+
+The ``flex-column`` and ``flex-column-reverse`` utility classes can be used to
+change the orientation of the flexbox container. Keep in mind that IE11 and Safari
+may have issues with the column direction.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute::
+ :raises:
+ :hide-code:
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex flex-column mb-6",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[f"Flex item {n}"]
+ ) for n in range(1, 4)
+ ]
+ ),
+ v.Card(
+ class_="d-flex flex-column-reverse",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[f"Flex item {n}"]
+ ) for n in range(1, 4)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`python` Python
+
+ .. code-block:: python
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex flex-column mb-6",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[f"Flex item {n}"]
+ ) for n in range(1, 4)
+ ]
+ ),
+ v.Card(
+ class_="d-flex flex-column-reverse",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[f"Flex item {n}"]
+ ) for n in range(1, 4)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. code-block:: vue
+
+
+
+
+
+ Flex item {{ n }}
+
+
+
+
+ Flex item {{ n }}
+
+
+
+
+
+There are also responsive variations for ``flex-direction``:
+
+- ``.flex-row``
+- ``.flex-row-reverse``
+- ``.flex-column``
+- ``.flex-column-reverse``
+- ``.flex-sm-row``
+- ``.flex-sm-row-reverse``
+- ``.flex-sm-column``
+- ``.flex-sm-column-reverse``
+- ``.flex-md-row``
+- ``.flex-md-row-reverse``
+- ``.flex-md-column``
+- ``.flex-md-column-reverse``
+- ``.flex-lg-row``
+- ``.flex-lg-row-reverse``
+- ``.flex-lg-column``
+- ``.flex-lg-column-reverse``
+- ``.flex-xl-row``
+- ``.flex-xl-row-reverse``
+- ``.flex-xl-column``
+- ``.flex-xl-column-reverse``
+
+Flex justify
+^^^^^^^^^^^^
+
+The ``justify-content`` flex setting can be changed using the flex justify classes.
+This by default will modify the flexbox items on the x-axis but is reversed when
+using ``flex-direction: column``, modifying the y-axis. Choose from ``start``
+(browser default), ``end``, ``center``, ``space-between``, or ``space-around``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/flex_justify.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/flex_justify.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/flex_justify.vue
+
+There are also responsive variations for ``justify-content``:
+
+- ``.justify-start``
+- ``.justify-end``
+- ``.justify-center``
+- ``.justify-space-between``
+- ``.justify-space-around``
+- ``.justify-sm-start``
+- ``.justify-sm-end``
+- ``.justify-sm-center``
+- ``.justify-sm-space-between``
+- ``.justify-sm-space-around``
+- ``.justify-md-start``
+- ``.justify-md-end``
+- ``.justify-md-center``
+- ``.justify-md-space-between``
+- ``.justify-md-space-around``
+- ``.justify-lg-start``
+- ``.justify-lg-end``
+- ``.justify-lg-center``
+- ``.justify-lg-space-between``
+- ``.justify-lg-space-around``
+- ``.justify-xl-start``
+- ``.justify-xl-end``
+- ``.justify-xl-center``
+- ``.justify-xl-space-between``
+- ``.justify-xl-space-around``
+
+Flex align
+^^^^^^^^^^
+
+The ``align-items`` flex setting can be changed using the flex align classes. This by default will modify the flexbox items on the y-axis but is reversed when using ``flex-direction: column``, modifying the x-axis. Choose from ``start``, ``end``, ``center``, ``baseline``, or ``stretch`` (browser default).
+
+.. note::
+ When using flex align with IE11 you will need to set an explicit ``height`` as ``min-height`` will not suffice and cause undesired results.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/flex_align.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/flex_align.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/flex_align.vue
+
+There are also responsive variations for ``align-items``:
+
+- ``.align-start``
+- ``.align-end``
+- ``.align-center``
+- ``.align-baseline``
+- ``.align-stretch``
+- ``.align-sm-start``
+- ``.align-sm-end``
+- ``.align-sm-center``
+- ``.align-sm-baseline``
+- ``.align-sm-stretch``
+- ``.align-md-start``
+- ``.align-md-end``
+- ``.align-md-center``
+- ``.align-md-baseline``
+- ``.align-md-stretch``
+- ``.align-lg-start``
+- ``.align-lg-end``
+- ``.align-lg-center``
+- ``.align-lg-baseline``
+- ``.align-lg-stretch``
+- ``.align-xl-start``
+- ``.align-xl-end``
+- ``.align-xl-center``
+- ``.align-xl-baseline``
+- ``.align-xl-stretch``
+
+Flex align self
+^^^^^^^^^^^^^^^
+
+The ``align-self`` flex setting can be changed using the flex align-self classes. This by default will modify the flexbox items on the x-axis but is reversed when using ``flex-direction: column``, modifying the y-axis. Choose from ``start``, ``end``, ``center``, ``baseline``, ``auto``, or ``stretch`` (browser default).
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/flex_align_self.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/flex_align_self.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/flex_align_self.vue
+
+There are also responsive variations for ``align-self``:
+
+- ``.align-self-start``
+- ``.align-self-end``
+- ``.align-self-center``
+- ``.align-self-baseline``
+- ``.align-self-auto``
+- ``.align-self-stretch``
+- ``.align-self-sm-start``
+- ``.align-self-sm-end``
+- ``.align-self-sm-center``
+- ``.align-self-sm-baseline``
+- ``.align-self-sm-auto``
+- ``.align-self-sm-stretch``
+- ``.align-self-md-start``
+- ``.align-self-md-end``
+- ``.align-self-md-center``
+- ``.align-self-md-baseline``
+- ``.align-self-md-auto``
+- ``.align-self-md-stretch``
+- ``.align-self-lg-start``
+- ``.align-self-lg-end``
+- ``.align-self-lg-center``
+- ``.align-self-lg-baseline``
+- ``.align-self-lg-auto``
+- ``.align-self-lg-stretch``
+- ``.align-self-xl-start``
+- ``.align-self-xl-end``
+- ``.align-self-xl-center``
+- ``.align-self-xl-baseline``
+- ``.align-self-xl-auto``
+- ``.align-self-xl-stretch``
+
+Auto margins
+^^^^^^^^^^^^
+
+Using the margin helper classes in a flexbox container, you can control the
+positioning of flex items on the x-axis or y-axis when using ``flex-row`` or
+``flex-column`` respectively.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/auto_margins.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/auto_margins.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/auto_margins.vue
+
+Using align-items
+"""""""""""""""""
+
+Mixing ``flex-direction: column`` and ``align-items``, you can utilize ``.mt-auto``
+and ``.mb-auto`` helper classes to adjust flex item positioning.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/using_align_items.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/using_align_items.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/using_align_items.vue
+
+Flex wrap
+^^^^^^^^^
+
+By default ``.d-flex`` does not provide any wrapping (behaves similarly to
+``flex-wrap: nowrap``). This can be modified by applying flex-wrap helper classes
+in the format ``flex-{condition}`` where condition can be ``nowrap``, ``wrap``,
+or ``wrap-reverse``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/flex_wrap.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/flex_wrap.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/flex_wrap.vue
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute::
+ :raises:
+ :hide-code:
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[f"Flex item {n}"]
+ ) for n in range(1, 21)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`python` Python
+
+ .. code-block:: python
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[f"Flex item {n}"]
+ ) for n in range(1, 21)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. code-block:: vue
+
+
+
+
+
+ Flex item {{ n }}
+
+
+
+
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute::
+ :raises:
+ :hide-code:
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex flex-wrap-reverse",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[f"Flex item {n}"]
+ ) for n in range(1, 21)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`python` Python
+
+ .. code-block:: python
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex flex-wrap-reverse",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[f"Flex item {n}"]
+ ) for n in range(1, 21)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. code-block:: vue
+
+
+
+
+
+ Flex item {{ n }}
+
+
+
+
+
+These helper classes can also be applied in the format ``flex-{breakpoint}-{condition}``
+to create more responsive variations based on breakpoints:
+
+- ``.flex-nowrap``
+- ``.flex-wrap``
+- ``.flex-wrap-reverse``
+- ``.flex-sm-nowrap``
+- ``.flex-sm-wrap``
+- ``.flex-sm-wrap-reverse``
+- ``.flex-md-nowrap``
+- ``.flex-md-wrap``
+- ``.flex-md-wrap-reverse``
+- ``.flex-lg-nowrap``
+- ``.flex-lg-wrap``
+- ``.flex-lg-wrap-reverse``
+- ``.flex-xl-nowrap``
+- ``.flex-xl-wrap``
+- ``.flex-xl-wrap-reverse``
+
+Flex order
+^^^^^^^^^^
+
+You can change the visual order of flex items with the ``order`` utilities.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/flex_order.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/flex_order.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/flex_order.vue
+
+There are also responsive variations for ``order``:
+
+- ``.order-first``
+- ``.order-0`` through ``.order-12``
+- ``.order-last``
+- ``.order-sm-first``
+- ``.order-sm-0`` through ``.order-sm-12``
+- ``.order-sm-last``
+- ``.order-md-first``
+- ``.order-md-0`` through ``.order-md-12``
+- ``.order-md-last``
+- ``.order-lg-first``
+- ``.order-lg-0`` through ``.order-lg-12``
+- ``.order-lg-last``
+- ``.order-xl-first``
+- ``.order-xl-0`` through ``.order-xl-12``
+- ``.order-xl-last``
+
+Flex align content
+^^^^^^^^^^^^^^^^^^
+
+The ``align-content`` flex setting can be changed using the flex align-content classes. This by default will modify the flexbox items on the x-axis but is reversed when using ``flex-direction: column``, modifying the y-axis. Choose from ``start`` (browser default), ``end``, ``center``, ``between``, ``around`` or ``stretch``.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/flex_align_content.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/flex_align_content.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/flex_align_content.vue
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute::
+ :raises:
+ :hide-code:
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-content-end flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ min_height="200",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["Flex item"]
+ ) for _ in range(20)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`python` Python
+
+ .. code-block:: python
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-content-end flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ min_height="200",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["Flex item"]
+ ) for _ in range(20)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. code-block:: vue
+
+
+
+
+
+ Flex item
+
+
+
+
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute::
+ :raises:
+ :hide-code:
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-content-center flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ min_height="200",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["Flex item"]
+ ) for _ in range(20)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`python` Python
+
+ .. code-block:: python
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-content-center flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ min_height="200",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["Flex item"]
+ ) for _ in range(20)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. code-block:: vue
+
+
+
+
+
+ Flex item
+
+
+
+
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/flex_align_content_2.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/flex_align_content_2.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/flex_align_content_2.vue
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute::
+ :raises:
+ :hide-code:
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-content-space-around flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ min_height="200",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["Flex item"]
+ ) for _ in range(20)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`python` Python
+
+ .. code-block:: python
+
+ import ipyvuetify as v
+
+ v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-content-space-around flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ min_height="200",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["Flex item"]
+ ) for _ in range(20)
+ ]
+ )
+ ]
+ )
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. code-block:: vue
+
+
+
+
+
+ Flex item
+
+
+
+
+
+There are also responsive variations for ``align-content``:
+
+- ``.align-content-start``
+- ``.align-content-end``
+- ``.align-content-center``
+- ``.align-content-space-between``
+- ``.align-content-space-around``
+- ``.align-content-stretch``
+- ``.align-sm-content-start``
+- ``.align-sm-content-end``
+- ``.align-sm-content-center``
+- ``.align-sm-content-space-between``
+- ``.align-sm-content-space-around``
+- ``.align-sm-content-stretch``
+- ``.align-md-content-start``
+- ``.align-md-content-end``
+- ``.align-md-content-center``
+- ``.align-md-content-space-between``
+- ``.align-md-content-space-around``
+- ``.align-md-content-stretch``
+- ``.align-lg-content-start``
+- ``.align-lg-content-end``
+- ``.align-lg-content-center``
+- ``.align-lg-content-space-between``
+- ``.align-lg-content-space-around``
+- ``.align-lg-content-stretch``
+- ``.align-xl-content-start``
+- ``.align-xl-content-end``
+- ``.align-xl-content-center``
+- ``.align-xl-content-space-between``
+- ``.align-xl-content-space-around``
+- ``.align-xl-content-stretch``
+
+Flex grow and shrink
+^^^^^^^^^^^^^^^^^^^^
+
+Vuetify has helper classes for applying grow and shrink manually. These can be applied
+by adding the helper class in the format ``flex-{condition}-{value}``, where condition
+can be either ``grow`` or ``shrink`` and value can be either ``0`` or ``1``. The
+condition ``grow`` will permit an element to grow to fill available space, whereas
+``shrink`` will permit an element to shrink down to only the space needs for its
+contents. However, this will only happen if the element must shrink to fit their
+container such as a container resize or being effected by a ``flex-grow-1``. The
+value ``0`` will prevent the condition from occurring whereas ``1`` will permit
+the condition.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Flex/flex_grow_and_shrink.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Flex/flex_grow_and_shrink.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Flex/flex_grow_and_shrink.vue
+
+The following classes are available:
+
+- ``.flex-grow-0``
+- ``.flex-grow-1``
+- ``.flex-shrink-0``
+- ``.flex-shrink-1``
+
+These helper classes can also be applied in the format ``flex-{breakpoint}-{condition}-{state}`` to create more responsive variations based on breakpoints:
+
+- ``.flex-sm-grow-0``
+- ``.flex-md-grow-0``
+- ``.flex-lg-grow-0``
+- ``.flex-xl-grow-0``
+- ``.flex-sm-grow-1``
+- ``.flex-md-grow-1``
+- ``.flex-lg-grow-1``
+- ``.flex-xl-grow-1``
+- ``.flex-sm-shrink-0``
+- ``.flex-md-shrink-0``
+- ``.flex-lg-shrink-0``
+- ``.flex-xl-shrink-0``
+- ``.flex-sm-shrink-1``
+- ``.flex-md-shrink-1``
+- ``.flex-lg-shrink-1``
+- ``.flex-xl-shrink-1``
diff --git a/docs/component/Flex/auto_margins.py b/docs/component/Flex/auto_margins.py
new file mode 100644
index 00000000..893ffb35
--- /dev/null
+++ b/docs/component/Flex/auto_margins.py
@@ -0,0 +1,39 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex mb-6",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"])
+ for _ in range(3)
+ ],
+ ),
+ v.Card(
+ class_="d-flex mb-6",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2 mr-auto", outlined=True, tile=True, children=["Flex item"]),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"]),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"]),
+ ],
+ ),
+ v.Card(
+ class_="d-flex",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"]),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"]),
+ v.Card(class_="pa-2 ml-auto", outlined=True, tile=True, children=["Flex item"]),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Flex/auto_margins.vue b/docs/component/Flex/auto_margins.vue
new file mode 100644
index 00000000..eb2f8ab5
--- /dev/null
+++ b/docs/component/Flex/auto_margins.vue
@@ -0,0 +1,25 @@
+
+
+
+
+ Flex item
+
+
+
+
+ Flex item
+
+ Flex item
+
+ Flex item
+
+
+
+ Flex item
+
+ Flex item
+
+ Flex item
+
+
+
diff --git a/docs/component/Flex/enabling_flexbox.py b/docs/component/Flex/enabling_flexbox.py
new file mode 100644
index 00000000..77daec5f
--- /dev/null
+++ b/docs/component/Flex/enabling_flexbox.py
@@ -0,0 +1,8 @@
+import ipyvuetify as v
+
+v.Card(
+ class_="d-flex pa-2",
+ outlined=True,
+ tile=True,
+ children=[v.Html(tag="div", children=["I'm a flexbox container!"])],
+)
diff --git a/docs/component/Flex/enabling_flexbox.vue b/docs/component/Flex/enabling_flexbox.vue
new file mode 100644
index 00000000..1e3ef83b
--- /dev/null
+++ b/docs/component/Flex/enabling_flexbox.vue
@@ -0,0 +1,5 @@
+
+
+ I'm a flexbox container!
+
+
diff --git a/docs/component/Flex/flex_align.py b/docs/component/Flex/flex_align.py
new file mode 100644
index 00000000..51e22b11
--- /dev/null
+++ b/docs/component/Flex/flex_align.py
@@ -0,0 +1,62 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-start mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["align-start"])
+ for n in range(1, 4)
+ ],
+ ),
+ v.Card(
+ class_="d-flex align-end mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["align-end"])
+ for n in range(1, 4)
+ ],
+ ),
+ v.Card(
+ class_="d-flex align-center mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["align-center"])
+ for n in range(1, 4)
+ ],
+ ),
+ v.Card(
+ class_="d-flex align-baseline mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["align-baseline"])
+ for n in range(1, 4)
+ ],
+ ),
+ v.Card(
+ class_="d-flex align-stretch mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["align-stretch"])
+ for n in range(1, 4)
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Flex/flex_align.vue b/docs/component/Flex/flex_align.vue
new file mode 100644
index 00000000..2d1a3c5a
--- /dev/null
+++ b/docs/component/Flex/flex_align.vue
@@ -0,0 +1,63 @@
+
+
+
+
+ align-start
+
+
+
+
+
+ align-end
+
+
+
+
+
+ align-center
+
+
+
+
+
+ align-baseline
+
+
+
+
+
+ align-stretch
+
+
+
+
diff --git a/docs/component/Flex/flex_align_content.py b/docs/component/Flex/flex_align_content.py
new file mode 100644
index 00000000..194c18f9
--- /dev/null
+++ b/docs/component/Flex/flex_align_content.py
@@ -0,0 +1,18 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-content-start flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ min_height="200",
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"])
+ for _ in range(20)
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Flex/flex_align_content.vue b/docs/component/Flex/flex_align_content.vue
new file mode 100644
index 00000000..24339b68
--- /dev/null
+++ b/docs/component/Flex/flex_align_content.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ Flex item
+
+
+
+
diff --git a/docs/component/Flex/flex_align_content_2.py b/docs/component/Flex/flex_align_content_2.py
new file mode 100644
index 00000000..03e9bd77
--- /dev/null
+++ b/docs/component/Flex/flex_align_content_2.py
@@ -0,0 +1,18 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-content-space-between flex-wrap",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ min_height="200",
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"])
+ for _ in range(20)
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Flex/flex_align_content_2.vue b/docs/component/Flex/flex_align_content_2.vue
new file mode 100644
index 00000000..195f7c60
--- /dev/null
+++ b/docs/component/Flex/flex_align_content_2.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ Flex item
+
+
+
+
diff --git a/docs/component/Flex/flex_align_self.py b/docs/component/Flex/flex_align_self.py
new file mode 100644
index 00000000..2c784684
--- /dev/null
+++ b/docs/component/Flex/flex_align_self.py
@@ -0,0 +1,106 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ v.Card(
+ class_="pa-2 align-self-start",
+ outlined=True,
+ tile=True,
+ children=["Aligned start"],
+ ),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ ],
+ ),
+ v.Card(
+ class_="d-flex mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ v.Card(
+ class_="pa-2 align-self-center",
+ outlined=True,
+ tile=True,
+ children=["Aligned center"],
+ ),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ ],
+ ),
+ v.Card(
+ class_="d-flex mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ v.Card(
+ class_="pa-2 align-self-end", outlined=True, tile=True, children=["Aligned end"]
+ ),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ ],
+ ),
+ v.Card(
+ class_="d-flex mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ v.Card(
+ class_="pa-2 align-self-baseline",
+ outlined=True,
+ tile=True,
+ children=["Aligned baseline"],
+ ),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ ],
+ ),
+ v.Card(
+ class_="d-flex mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ v.Card(
+ class_="pa-2 align-self-auto",
+ outlined=True,
+ tile=True,
+ children=["Aligned auto"],
+ ),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ ],
+ ),
+ v.Card(
+ class_="d-flex mb-6",
+ color="grey lighten-2",
+ flat=True,
+ height="100",
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ v.Card(
+ class_="pa-2 align-self-stretch",
+ outlined=True,
+ tile=True,
+ children=["Aligned stretch"],
+ ),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["flex item"]),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Flex/flex_align_self.vue b/docs/component/Flex/flex_align_self.vue
new file mode 100644
index 00000000..aae9fac0
--- /dev/null
+++ b/docs/component/Flex/flex_align_self.vue
@@ -0,0 +1,59 @@
+
+
+
+ flex item
+
+
+ Aligned start
+
+
+ flex item
+
+
+
+ flex item
+
+
+ Aligned center
+
+
+ flex item
+
+
+
+ flex item
+
+ Aligned end
+
+ flex item
+
+
+
+ flex item
+
+
+ Aligned baseline
+
+
+ flex item
+
+
+
+ flex item
+
+ Aligned auto
+
+ flex item
+
+
+
+ flex item
+
+
+ Aligned stretch
+
+
+ flex item
+
+
+
diff --git a/docs/component/Flex/flex_direction.py b/docs/component/Flex/flex_direction.py
new file mode 100644
index 00000000..195b9e39
--- /dev/null
+++ b/docs/component/Flex/flex_direction.py
@@ -0,0 +1,27 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex flex-row mb-6",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=[f"Flex item {n}"])
+ for n in range(1, 4)
+ ],
+ ),
+ v.Card(
+ class_="d-flex flex-row-reverse",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=[f"Flex item {n}"])
+ for n in range(1, 4)
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Flex/flex_direction.vue b/docs/component/Flex/flex_direction.vue
new file mode 100644
index 00000000..91516082
--- /dev/null
+++ b/docs/component/Flex/flex_direction.vue
@@ -0,0 +1,24 @@
+
+
+
+
+ Flex item {{ n }}
+
+
+
+
+ Flex item {{ n }}
+
+
+
+
diff --git a/docs/component/Flex/flex_grow_and_shrink.py b/docs/component/Flex/flex_grow_and_shrink.py
new file mode 100644
index 00000000..12ca74c8
--- /dev/null
+++ b/docs/component/Flex/flex_grow_and_shrink.py
@@ -0,0 +1,58 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ no_gutters=True,
+ style_="flex-wrap: nowrap;",
+ children=[
+ v.Col(
+ cols=2,
+ class_="flex-grow-0 flex-shrink-0",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["I'm 2 column wide"],
+ )
+ ],
+ ),
+ v.Col(
+ cols=1,
+ style_="min-width: 100px; max-width: 100%;",
+ class_="flex-grow-1 flex-shrink-0",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["I'm 1 column wide and I grow to take all the space"],
+ )
+ ],
+ ),
+ v.Col(
+ cols=5,
+ style_="min-width: 100px;",
+ class_="flex-grow-0 flex-shrink-1",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[
+ "I'm 5 column wide and I shrink if there's not enough space"
+ ],
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Flex/flex_grow_and_shrink.vue b/docs/component/Flex/flex_grow_and_shrink.vue
new file mode 100644
index 00000000..e231cf8e
--- /dev/null
+++ b/docs/component/Flex/flex_grow_and_shrink.vue
@@ -0,0 +1,27 @@
+
+
+
+
+ I'm 2 column wide
+
+
+
+ I'm 1 column wide and I grow to take all the space
+
+
+
+
+ I'm 5 column wide and I shrink if there's not enough space
+
+
+
+
+
diff --git a/docs/component/Flex/flex_justify.py b/docs/component/Flex/flex_justify.py
new file mode 100644
index 00000000..b6eeb9f6
--- /dev/null
+++ b/docs/component/Flex/flex_justify.py
@@ -0,0 +1,58 @@
+import ipyvuetify as v
+
+v.Html(
+ class_="ma-2",
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex justify-start mb-6",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["justify-start"])
+ for n in range(1, 4)
+ ],
+ ),
+ v.Card(
+ class_="d-flex justify-end mb-6",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["justify-end"])
+ for n in range(1, 4)
+ ],
+ ),
+ v.Card(
+ class_="d-flex justify-center mb-6",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["justify-center"])
+ for n in range(1, 4)
+ ],
+ ),
+ v.Card(
+ class_="d-flex justify-space-between mb-6",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["justify-space-between"])
+ for n in range(1, 4)
+ ],
+ ),
+ v.Card(
+ class_="d-flex justify-space-around mb-6",
+ color="grey lighten-4",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["justify-space-around"])
+ for n in range(1, 4)
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Flex/flex_justify.vue b/docs/component/Flex/flex_justify.vue
new file mode 100644
index 00000000..b1fee2f1
--- /dev/null
+++ b/docs/component/Flex/flex_justify.vue
@@ -0,0 +1,58 @@
+
+
+
+
+ justify-start
+
+
+
+
+
+ justify-end
+
+
+
+
+
+ justify-center
+
+
+
+
+
+ justify-space-between
+
+
+
+
+
+ justify-space-around
+
+
+
+
diff --git a/docs/component/Flex/flex_order.py b/docs/component/Flex/flex_order.py
new file mode 100644
index 00000000..e94da6a1
--- /dev/null
+++ b/docs/component/Flex/flex_order.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex flex-wrap-reverse",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ children=[
+ v.Card(
+ class_="order-3 pa-2", outlined=True, tile=True, children=["First flex item"]
+ ),
+ v.Card(
+ class_="order-1 pa-2", outlined=True, tile=True, children=["Second flex item"]
+ ),
+ v.Card(
+ class_="order-2 pa-2", outlined=True, tile=True, children=["Third flex item"]
+ ),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Flex/flex_order.vue b/docs/component/Flex/flex_order.vue
new file mode 100644
index 00000000..33148d22
--- /dev/null
+++ b/docs/component/Flex/flex_order.vue
@@ -0,0 +1,11 @@
+
+
+
+ First flex item
+
+ Second flex item
+
+ Third flex item
+
+
+
diff --git a/docs/component/Flex/flex_wrap.py b/docs/component/Flex/flex_wrap.py
new file mode 100644
index 00000000..414eb643
--- /dev/null
+++ b/docs/component/Flex/flex_wrap.py
@@ -0,0 +1,18 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex flex-nowrap py-3",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ width="125",
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"])
+ for _ in range(5)
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Flex/flex_wrap.vue b/docs/component/Flex/flex_wrap.vue
new file mode 100644
index 00000000..2b857f15
--- /dev/null
+++ b/docs/component/Flex/flex_wrap.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ Flex item
+
+
+
+
diff --git a/docs/component/Flex/using_align_items.py b/docs/component/Flex/using_align_items.py
new file mode 100644
index 00000000..defb817f
--- /dev/null
+++ b/docs/component/Flex/using_align_items.py
@@ -0,0 +1,31 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Card(
+ class_="d-flex align-start flex-column mb-6",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ height="200",
+ children=[
+ v.Card(class_="pa-2 mb-auto", outlined=True, tile=True, children=["Flex item"]),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"]),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"]),
+ ],
+ ),
+ v.Card(
+ class_="d-flex align-end flex-column",
+ color="grey lighten-2",
+ flat=True,
+ tile=True,
+ height="200",
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"]),
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["Flex item"]),
+ v.Card(class_="pa-2 mt-auto", outlined=True, tile=True, children=["Flex item"]),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Flex/using_align_items.vue b/docs/component/Flex/using_align_items.vue
new file mode 100644
index 00000000..6130fc01
--- /dev/null
+++ b/docs/component/Flex/using_align_items.vue
@@ -0,0 +1,31 @@
+
+
+
+ Flex item
+
+ Flex item
+
+ Flex item
+
+
+
+ Flex item
+
+ Flex item
+
+ Flex item
+
+
+
diff --git a/docs/component/Footer.rst b/docs/component/Footer.rst
new file mode 100644
index 00000000..bb007d16
--- /dev/null
+++ b/docs/component/Footer.rst
@@ -0,0 +1,110 @@
+Footer
+======
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Footer documentation
+ `__. All examples have been converted
+ to ipyvuetify syntax.
+
+The :py:class:`Footer ` component is used for displaying general
+information that a user might want to access from any page within your site.
+
+.. api::
+
+ :py:class:`ipyvuetify.Footer`
+
+Usage
+-----
+
+The :py:class:`Footer ` component in its simplest form is a container.
+
+.. jupyter-execute:: Footer/usage.py
+ :raises:
+
+Examples
+--------
+
+Padless Footer
+^^^^^^^^^^^^^^
+
+The ``padless`` prop removes all default padding from the footer component.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Footer/padless_footer.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Footer/padless_footer.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Footer/padless_footer.vue
+
+Company Footer
+^^^^^^^^^^^^^^
+
+The footer component as a basic company footer with links.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Footer/company_footer.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Footer/company_footer.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Footer/company_footer.vue
+
+Indigo Footer
+^^^^^^^^^^^^^
+
+The footer component with Indigo background color and social media icons and button.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Footer/indigo_footer.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Footer/indigo_footer.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Footer/indigo_footer.vue
+
+Teal Footer
+^^^^^^^^^^^
+
+The footer component with a Teal color header and columns and rows of links.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Footer/teal_footer.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Footer/teal_footer.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Footer/teal_footer.vue
+
diff --git a/docs/component/Footer/company_footer.py b/docs/component/Footer/company_footer.py
new file mode 100644
index 00000000..d19a5690
--- /dev/null
+++ b/docs/component/Footer/company_footer.py
@@ -0,0 +1,30 @@
+from datetime import datetime as dt
+
+import ipyvuetify as v
+
+v.Footer(
+ color="primary",
+ padless=True,
+ children=[
+ v.Col(
+ class_="text-center",
+ justify_center=True,
+ no_gutters=True,
+ children=[
+ v.Btn(
+ color="white",
+ text=True,
+ rounded=True,
+ class_="my-2 d-inline",
+ children=[link.title()],
+ )
+ for link in ["home", "about us", "services", "contact"]
+ ],
+ ),
+ v.Col(
+ class_="primary py-4 text-center white--text",
+ cols="12",
+ children=[f"{dt.now().year} — ", v.Html(tag="strong", children=["Vuetify"])],
+ ),
+ ],
+)
diff --git a/docs/component/Footer/company_footer.vue b/docs/component/Footer/company_footer.vue
new file mode 100644
index 00000000..98fcca95
--- /dev/null
+++ b/docs/component/Footer/company_footer.vue
@@ -0,0 +1,19 @@
+
+
+
+
+ {{ link }}
+
+
+ {{ new Date().getFullYear() }} — Vuetify
+
+
+
+
diff --git a/docs/component/Footer/indigo_footer.py b/docs/component/Footer/indigo_footer.py
new file mode 100644
index 00000000..bcefbf99
--- /dev/null
+++ b/docs/component/Footer/indigo_footer.py
@@ -0,0 +1,47 @@
+from datetime import datetime as dt
+
+import ipyvuetify as v
+
+icons = ["mdi-facebook", "mdi-twitter", "mdi-instagram", "mdi-linkedin"]
+
+v.Footer(
+ dark=True,
+ padless=True,
+ children=[
+ v.Card(
+ flat=True,
+ tile=True,
+ class_="indigo lighten-1 white--text text-center",
+ children=[
+ v.CardText(
+ children=[
+ v.Btn(
+ icon=True,
+ class_="mx-4 white--text",
+ children=[v.Icon(size="24px", children=[i])],
+ )
+ for i in icons
+ ],
+ ),
+ v.CardText(
+ class_="white--text pt-0",
+ children=[
+ "Phasellus feugiat arcu sapien, et iaculis ipsum elementum sit amet. "
+ "Mauris cursus commodo interdum. Praesent ut risus eget metus luctus "
+ "accumsan id ultrices nunc. Sed at orci sed massa consectetur dignissim "
+ "a sit amet dui. Duis commodo vitae velit et faucibus. Morbi vehicula "
+ "lacinia malesuada. Nulla placerat augue vel ipsum ultrices, cursus "
+ "iaculis dui sollicitudin. Vestibulum eu ipsum vel diam elementum tempor "
+ "vel ut orci. Orci varius natoque penatibus et magnis dis parturient "
+ "montes, nascetur ridiculus mus."
+ ],
+ ),
+ v.Divider(),
+ v.CardText(
+ class_="white--text",
+ children=[f"{dt.now().year} — ", v.Html(tag="strong", children=["Vuetify"])],
+ ),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Footer/indigo_footer.vue b/docs/component/Footer/indigo_footer.vue
new file mode 100644
index 00000000..f23fd994
--- /dev/null
+++ b/docs/component/Footer/indigo_footer.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+ {{ icon }}
+
+
+
+
+
+ Phasellus feugiat arcu sapien, et iaculis ipsum elementum sit amet.
+ Mauris cursus commodo interdum. Praesent ut risus eget metus luctus
+ accumsan id ultrices nunc. Sed at orci sed massa consectetur dignissim a
+ sit amet dui. Duis commodo vitae velit et faucibus. Morbi vehicula
+ lacinia malesuada. Nulla placerat augue vel ipsum ultrices, cursus
+ iaculis dui sollicitudin. Vestibulum eu ipsum vel diam elementum tempor
+ vel ut orci. Orci varius natoque penatibus et magnis dis parturient
+ montes, nascetur ridiculus mus.
+
+
+
+
+
+ {{ new Date().getFullYear() }} — Vuetify
+
+
+
+
diff --git a/docs/component/Footer/padless_footer.py b/docs/component/Footer/padless_footer.py
new file mode 100644
index 00000000..9d63a295
--- /dev/null
+++ b/docs/component/Footer/padless_footer.py
@@ -0,0 +1,14 @@
+from datetime import datetime as dt
+
+import ipyvuetify as v
+
+v.Footer(
+ padless=True,
+ children=[
+ v.Col(
+ class_="text-center",
+ cols="12",
+ children=[f"{dt.now().year} — ", v.Html(tag="strong", children=["Vuetify"])],
+ ),
+ ],
+)
diff --git a/docs/component/Footer/padless_footer.vue b/docs/component/Footer/padless_footer.vue
new file mode 100644
index 00000000..733c39d5
--- /dev/null
+++ b/docs/component/Footer/padless_footer.vue
@@ -0,0 +1,7 @@
+
+
+
+ {{ new Date().getFullYear() }} — Vuetify
+
+
+
diff --git a/docs/component/Footer/teal_footer.py b/docs/component/Footer/teal_footer.py
new file mode 100644
index 00000000..7fb50e5b
--- /dev/null
+++ b/docs/component/Footer/teal_footer.py
@@ -0,0 +1,42 @@
+from datetime import datetime as dt
+
+import ipyvuetify as v
+
+icons = ["mdi-facebook", "mdi-twitter", "mdi-instagram", "mdi-linkedin"]
+
+v.Footer(
+ dark=True,
+ padless=True,
+ children=[
+ v.Card(
+ width="100%",
+ flat=True,
+ tile=True,
+ children=[
+ v.CardTitle(
+ class_="teal",
+ children=[
+ v.Html(
+ tag="strong",
+ class_="subheading",
+ children=["Get connected with us on social networks!"],
+ ),
+ v.Spacer(),
+ *[
+ v.Btn(
+ icon=True,
+ class_="mx-4",
+ children=[v.Icon(size="24px", children=[i])],
+ )
+ for i in icons
+ ],
+ ],
+ ),
+ v.CardText(
+ class_="py-2 white--text text-center",
+ children=[f"{dt.now().year} — ", v.Html(tag="strong", children=["Vuetify"])],
+ ),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Footer/teal_footer.vue b/docs/component/Footer/teal_footer.vue
new file mode 100644
index 00000000..b73bba3f
--- /dev/null
+++ b/docs/component/Footer/teal_footer.vue
@@ -0,0 +1,23 @@
+
+
+
+
+ Get connected with us on social networks!
+
+
+
+
+
+ {{ icon }}
+
+
+
+
+
+ {{ new Date().getFullYear() }} — Vuetify
+
+
+
+
diff --git a/docs/component/Footer/usage.py b/docs/component/Footer/usage.py
new file mode 100644
index 00000000..8c9189e9
--- /dev/null
+++ b/docs/component/Footer/usage.py
@@ -0,0 +1,34 @@
+from datetime import datetime as dt
+
+import ipyvuetify as v
+
+icons = ["mdi-home", "mdi-email", "mdi-calendar", "mdi-delete"]
+
+v.Footer(
+ children=[
+ v.Card(
+ flat=True,
+ tile=True,
+ width="100%",
+ padless=True,
+ class_="red lighten-1 text-center",
+ children=[
+ v.CardText(
+ children=[
+ v.Btn(
+ icon=True,
+ class_="mx-4",
+ children=[v.Icon(children=[i])],
+ )
+ for i in icons
+ ],
+ ),
+ v.Divider(),
+ v.CardText(
+ class_="white--text",
+ children=[f"{dt.now().year} — ", v.Html(tag="strong", children=["IpyVuetify"])],
+ ),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Form.rst b/docs/component/Form.rst
new file mode 100644
index 00000000..aa1a306b
--- /dev/null
+++ b/docs/component/Form.rst
@@ -0,0 +1,104 @@
+Form
+====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Form documentation
+ `__.
+ All examples have been converted to ipyvuetify syntax.
+
+When it comes to form validation, Vuetify has a multitude of integrations and baked
+in functionality. Want to use a 3rd party validation plugin? Out of the box you
+can use `Vee-validate `__ and
+`vuelidate `__.
+
+.. api::
+
+ :py:class:`ipyvuetify.Form`
+
+Usage
+-----
+
+The internal :py:class:`Form ` component makes it easy to add
+validation to form inputs. All input components have a ``rules`` prop which accepts
+a mixed array of types ``function``, ``boolean`` and ``string``. These allow you
+to specify conditions in which the input is valid or invalid. Whenever the value
+of an input is changed, each function in the array will receive the new value and
+each array element will be evaluated. If a function or array element returns
+``false`` or a ``string``, validation has failed and the ``string`` value
+will be presented as an error message.
+
+.. jupyter-execute:: Form/usage.py
+ :raises:
+
+Examples
+--------
+
+Rules
+^^^^^
+
+Rules allow you to apply custom validation on all form components. These are validated
+sequentially and will display a **maximum** of 1 error at a time, so make sure you
+order your rules accordingly.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Form/rules.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Form/rules.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Form/rules.vue
+
+Validation with submit & clear
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The :py:class:`Form ` component has **three** functions that can be
+accessed by setting a ref on the component. A ref allows us to access internal
+methods on a component, for example, ````.
+``this.$refs.form.validate()`` will validate all inputs and return if they are
+all valid or not. ``this.$refs.form.reset()`` will clear all inputs and reset
+their validation errors. ``this.$refs.form.resetValidation()`` will only reset
+input validation and not alter their state.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Form/validation_with_submit_clear.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Form/validation_with_submit_clear.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Form/validation_with_submit_clear.vue
+
+Vee-validate
+^^^^^^^^^^^^
+
+vee-validate is a template Based Validation Framework for Vue.js.
+`Documentation `__
+
+.. todo::
+
+ Add Vee-validate example when ipyvuetify supports it.
+
+Vuelidate
+^^^^^^^^^
+
+vuelidate is a simple, lightweight model-based validation for Vue.js.
+`Documentation `__
+
+.. todo::
+
+ Add Vuelidate example when ipyvuetify supports it.
diff --git a/docs/component/Form/rules.py b/docs/component/Form/rules.py
new file mode 100644
index 00000000..5096d3ff
--- /dev/null
+++ b/docs/component/Form/rules.py
@@ -0,0 +1,46 @@
+import ipyvuetify as v
+
+v.Container(
+ children=[
+ v.Row(
+ justify="space-between",
+ children=[
+ v.Col(
+ cols=12,
+ md=4,
+ children=[
+ v.Form(
+ ref="form",
+ children=[
+ v.TextField(
+ v_model="",
+ counter=20,
+ # rules will be set in Vue template
+ label="First name",
+ )
+ ],
+ )
+ ],
+ ),
+ v.Col(
+ cols=12,
+ md=6,
+ children=[
+ v.Slider(
+ v_model=20,
+ label="Max characters",
+ ),
+ v.Checkbox(
+ v_model=True,
+ label="Allow spaces",
+ ),
+ v.TextField(
+ v_model="",
+ label="Value must match",
+ ),
+ ],
+ ),
+ ],
+ )
+ ]
+)
diff --git a/docs/component/Form/rules.vue b/docs/component/Form/rules.vue
new file mode 100644
index 00000000..9d328310
--- /dev/null
+++ b/docs/component/Form/rules.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Form/usage.py b/docs/component/Form/usage.py
new file mode 100644
index 00000000..2d0105e5
--- /dev/null
+++ b/docs/component/Form/usage.py
@@ -0,0 +1,36 @@
+import ipyvuetify as v
+
+v.Form(
+ v_model=True,
+ children=[
+ v.TextField(
+ v_model="",
+ # rules=[
+ # lambda v: bool(v) or 'Name is required',
+ # lambda v: len(v) <= 10 or 'Name must be less than 10 characters',
+ # ],
+ counter=10,
+ label="Name",
+ required=True,
+ ),
+ v.TextField(
+ v_model="",
+ # rules=[
+ # lambda v: bool(v) or 'E-mail is required',
+ # lambda v: '@' in v or 'E-mail must be valid',
+ # ],
+ label="E-mail",
+ required=True,
+ ),
+ v.TextField(
+ v_model="",
+ # rules=[
+ # lambda v: bool(v) or 'Password is required',
+ # lambda v: len(v) >= 8 or 'Password must be at least 8 characters',
+ # ],
+ type="password",
+ label="Password",
+ required=True,
+ ),
+ ],
+)
diff --git a/docs/component/Form/validation_with_submit_clear.py b/docs/component/Form/validation_with_submit_clear.py
new file mode 100644
index 00000000..9cfacc3d
--- /dev/null
+++ b/docs/component/Form/validation_with_submit_clear.py
@@ -0,0 +1,47 @@
+import ipyvuetify as v
+
+v.Form(
+ ref="form",
+ children=[
+ v.TextField(
+ v_model="",
+ counter=10,
+ # rules will be set in Vue template
+ label="Name",
+ required=True,
+ ),
+ v.TextField(
+ v_model="",
+ # rules will be set in Vue template
+ label="E-mail",
+ required=True,
+ ),
+ v.Select(
+ v_model=None,
+ items=["Item 1", "Item 2", "Item 3"],
+ # rules will be set in Vue template
+ label="Item",
+ required=True,
+ ),
+ v.Checkbox(
+ v_model=False,
+ # rules will be set in Vue template
+ label="Do you agree?",
+ required=True,
+ ),
+ v.Btn(
+ children=["Validate"],
+ color="success",
+ class_="mr-4",
+ ),
+ v.Btn(
+ children=["Reset Form"],
+ color="error",
+ class_="mr-4",
+ ),
+ v.Btn(
+ children=["Reset Validation"],
+ color="warning",
+ ),
+ ],
+)
diff --git a/docs/component/Form/validation_with_submit_clear.vue b/docs/component/Form/validation_with_submit_clear.vue
new file mode 100644
index 00000000..abd46c79
--- /dev/null
+++ b/docs/component/Form/validation_with_submit_clear.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+ Validate
+
+
+ Reset Form
+
+ Reset Validation
+
+
diff --git a/docs/component/Grid.rst b/docs/component/Grid.rst
new file mode 100644
index 00000000..6da480ab
--- /dev/null
+++ b/docs/component/Grid.rst
@@ -0,0 +1,468 @@
+Grid
+====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify documentation
+ `_. All examples have been
+ converted to ipyvuetify syntax.
+
+Vuetify comes with a 12 point grid system built using flexbox. The grid is used to
+create specific layouts within an application's content. It contains 5 types of
+media breakpoints that are used for targeting specific screen sizes or orientations:
+``xs``, ``sm``, ``md``, ``lg`` and ``xl``. These resolutions are defined below in
+the Viewport Breakpoints table.
+
+.. jupyter-execute:: Grid/grid.py
+ :raises:
+ :hide-code:
+
+.. api::
+
+ - :py:class:`ipyvuetify.Container`
+ - :py:class:`ipyvuetify.Row`
+ - :py:class:`ipyvuetify.Col`
+ - :py:class:`ipyvuetify.Spacer`
+
+Sub-components
+--------------
+
+Container
+~~~~~~~~~
+
+:py:class:`Container ` provides the ability to center and
+horizontally pad your site's contents. You can also use the ``fluid`` prop to
+fully extend the container across all viewport and device sizes. Maintains previous
+1.x functionality in which props are passed through as classes on
+:py:class:`Container ` allowing for the application of helper
+classes (such as ``ma-#``/``pa-#``/``fill-height``) to easily be applied.
+
+Col
+~~~
+
+:py:class:`Col ` is a content holder that must be a direct child
+of :py:class:`Row `. This is the 2.x replacement for v-flex in 1.x.
+
+Row
+~~~
+
+:py:class:`Row ` is a wrapper component for
+:py:class:`Col `. It utilizes flex properties to control the
+layout and flow of its inner columns. It uses a standard gutter of 24px. This
+can be reduced with the ``dense`` prop or removed completely with ``no-gutters``.
+This is the 2.x replacement for v-layout in 1.x.
+
+Spacer
+~~~~~~
+
+:py:class:`Spacer ` is a basic yet versatile spacing component
+used to distribute remaining width in-between a parent's child components. When
+placing a single :py:class:`Spacer ` before or after the child
+components, the components will push to the right and left of its container. When
+more than one :py:class:`Spacer ` are used between multiple
+components, the remaining width is evenly distributed between each spacer.
+
+Usage
+-----
+
+The Vuetify grid is heavily inspired by the `Bootstrap grid
+`__. It is integrated by using a
+series of containers, rows, and columns to layout and align content.If you are **new to flexbox**,
+`Read the CSS Tricks flexbox guide for background `__,
+terminology, guidelines, and code snippets.
+
+.. jupyter-execute:: Grid/usage.py
+ :raises:
+ :hide-code:
+
+.. note::
+
+ ``fill-height`` applies ``height: 100%`` to an element. When applied to
+ :py:class:`Container ` it will also ``align-items: center``.
+
+.. note::
+
+ Breakpoints based props on grid components work in an ``andUp`` fashion. With this
+ in mind the ``xs`` breakpoint is assumed and has been removed from the props context.
+ This applies to ``offset``, ``justify``, ``align``, and single breakpoint props on
+ :py:class:`Col `.
+
+ Props like ``justify-sm`` and ``justify-md`` exist, but ``justify-xs`` does not, it is
+ simply ``justify``. The ``xs`` prop does not exist on :py:class:`Col `.
+ The equivalent to this is the ``cols`` prop
+
+Align
+-----
+
+Change the vertical alignment of flex items and their parents using the ``align`` and ``align-self`` properties.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/align.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/align.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/align.vue
+
+Breakpoint sizing
+-----------------
+
+Columns will automatically take up an equal amount of space within their parent container. This can be modified using the ``cols`` prop. You can also utilize the ``sm``, ``md``, ``lg``, and ``xl`` props to further define how the column will be sized in different viewport sizes.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/breakpoint_sizing.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/breakpoint_sizing.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/breakpoint_sizing.vue
+
+Justify
+-------
+
+Change the horizontal alignment of flex items using the ``justify`` property.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/justify.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/justify.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/justify.vue
+
+No gutters
+----------
+
+You can remove the negative margins from :py:class:`Row ` and the
+padding from its direct :py:class:`Col ` children using the
+``no-gutters`` property.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/no_gutters.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/no_gutters.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/no_gutters.vue
+
+Offset
+------
+
+Offsets are useful for compensating for elements that may not be visible yet, or
+to control the position of content. Just as with breakpoints, you can set an offset
+for any available sizes. This allows you to fine tune your application layout
+precisely to your needs.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/offset.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/offset.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/offset.vue
+
+Offset breakpoint
+-----------------
+
+Offset can also be applied on a per breakpoint basis.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/offset_breakpoint.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/offset_breakpoint.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/offset_breakpoint.vue
+
+Order
+-----
+
+You can control the ordering of grid items. As with offsets, you can set different
+orders for different sizes. Design specialized screen layouts that accommodate
+to any application.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/order.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/order.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/order.vue
+
+Order first and last
+--------------------
+
+You can also designate explicitly ``first`` or ``last`` which will assign ``-1``
+or ``13`` values respectively to the ``order`` CSS property.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/order_first_and_last.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/order_first_and_last.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/order_first_and_last.vue
+
+Column wrapping
+---------------
+
+When more than 12 columns are placed within a given row (that is not using the
+``.flex-nowrap`` utility class), each group of extra columns will wrap onto a new
+line.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/column_wrapping.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/column_wrapping.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/column_wrapping.vue
+
+Equal width columns
+-------------------
+
+You can break equal width columns into multiple lines.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/equal_width_columns.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/equal_width_columns.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/equal_width_columns.vue
+
+Grow and Shrink
+---------------
+
+By default, flex components will automatically fill the available space in a row
+or column. They will also shrink relative to the rest of the flex items in the flex
+container when a specific size is not designated. You can define the column width
+of the :py:class:`Col ` by using the ``cols`` prop and providing
+a value from 1 to 12.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/grow_and_shrink.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/grow_and_shrink.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/grow_and_shrink.vue
+
+Margin helpers
+--------------
+
+Using the `auto margin helper utilities `__
+you can force sibling columns away from each other.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/margin_helpers.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/margin_helpers.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/margin_helpers.vue
+
+Nested grid
+-----------
+
+Grids can be nested, similar to other frameworks, in order to achieve very custom
+layouts.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/nested_grid.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/nested_grid.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/nested_grid.vue
+
+One column width
+----------------
+
+When using the auto-layout, you can define the width of only one column and still
+have its siblings to automatically resize around it.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/one_column_width.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/one_column_width.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/one_column_width.vue
+
+Spacers
+-------
+
+The :py:class:`Spacer ` component is useful when you want to fill available space or make space between two components.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/spacers.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/spacers.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/spacers.vue
+
+Unique layouts
+--------------
+
+The power and flexibility of the Vuetify grid system allows you to create amazing
+user interfaces.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/unique_layouts.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/unique_layouts.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/unique_layouts.vue
+
+Variable content width
+----------------------
+
+Assigning breakpoint width for columns can be configured to resize based upon the
+nature width of their content.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Grid/variable_content_width.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Grid/variable_content_width.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Grid/variable_content_width.vue
+
diff --git a/docs/component/Grid/align.py b/docs/component/Grid/align.py
new file mode 100644
index 00000000..a056c18c
--- /dev/null
+++ b/docs/component/Grid/align.py
@@ -0,0 +1,53 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Container(
+ class_="ma-0",
+ children=[
+ v.Row(
+ class_="grey lighten-5 mb-3",
+ align=align,
+ no_gutters=True,
+ style_="height: 150px;",
+ children=[
+ v.Col(
+ children=[
+ v.Card(
+ class_="pa-2 ma-2",
+ outlined=True,
+ tile=True,
+ children=["One of three columns"],
+ )
+ ]
+ )
+ for n in range(3)
+ ],
+ )
+ for align in ["start", "center", "end", "stretch"]
+ ]
+ + [
+ v.Row(
+ class_="grey lighten-5",
+ no_gutters=True,
+ style_="height: 150px;",
+ children=[
+ v.Col(
+ align_self=align,
+ children=[
+ v.Card(
+ class_="pa-2 ma-2",
+ outlined=True,
+ tile=True,
+ children=["One of three columns"],
+ )
+ ],
+ )
+ for align in ["start", "center", "end"]
+ ],
+ )
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Grid/align.vue b/docs/component/Grid/align.vue
new file mode 100644
index 00000000..4ae29211
--- /dev/null
+++ b/docs/component/Grid/align.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+ One of three columns
+
+
+
+
+
+
+
+ One of three columns
+
+
+
+
+
diff --git a/docs/component/Grid/breakpoint_sizing.py b/docs/component/Grid/breakpoint_sizing.py
new file mode 100644
index 00000000..cdb75615
--- /dev/null
+++ b/docs/component/Grid/breakpoint_sizing.py
@@ -0,0 +1,24 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ key=n,
+ class_="mb-6" if n == 1 else "",
+ no_gutters=True,
+ children=[
+ v.Col(
+ key=k,
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=[f"{k} of {n + 1}"]
+ )
+ ],
+ )
+ for k in range(1, n + 2)
+ ],
+ )
+ for n in range(1, 3)
+ ],
+)
diff --git a/docs/component/Grid/breakpoint_sizing.vue b/docs/component/Grid/breakpoint_sizing.vue
new file mode 100644
index 00000000..4bbc100b
--- /dev/null
+++ b/docs/component/Grid/breakpoint_sizing.vue
@@ -0,0 +1,9 @@
+
+
+
+
+ {{ k }} of {{ n + 1 }}
+
+
+
+
diff --git a/docs/component/Grid/column_wrapping.py b/docs/component/Grid/column_wrapping.py
new file mode 100644
index 00000000..64d3dbdf
--- /dev/null
+++ b/docs/component/Grid/column_wrapping.py
@@ -0,0 +1,40 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ cols=9,
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=[".col-9"])],
+ ),
+ v.Col(
+ cols=4,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[
+ ".col-4\nSince 9 + 4 = 13 > 12, this 4-column-wide div gets wrapped onto a new line as one contiguous unit."
+ ],
+ )
+ ],
+ ),
+ v.Col(
+ cols=6,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-6\nSubsequent columns continue along the new line."],
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Grid/column_wrapping.vue b/docs/component/Grid/column_wrapping.vue
new file mode 100644
index 00000000..c2d3f42e
--- /dev/null
+++ b/docs/component/Grid/column_wrapping.vue
@@ -0,0 +1,20 @@
+
+
+
+
+ .col-9
+
+
+
+ .col-4
Since 9 + 4 = 13 > 12, this 4-column-wide div gets
+ wrapped onto a new line as one contiguous unit.
+
+
+
+
+ .col-6
Subsequent columns continue along the new line.
+
+
+
+
+
diff --git a/docs/component/Grid/equal_width_columns.py b/docs/component/Grid/equal_width_columns.py
new file mode 100644
index 00000000..5fee011c
--- /dev/null
+++ b/docs/component/Grid/equal_width_columns.py
@@ -0,0 +1,25 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["Column"])]
+ ),
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["Column"])]
+ ),
+ v.Responsive(v_if="n === 2", width="100%"),
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["Column"])]
+ ),
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["Column"])]
+ ),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Grid/equal_width_columns.vue b/docs/component/Grid/equal_width_columns.vue
new file mode 100644
index 00000000..cc7a33d0
--- /dev/null
+++ b/docs/component/Grid/equal_width_columns.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+ Column
+
+
+
+
+
+
diff --git a/docs/component/Grid/grid.py b/docs/component/Grid/grid.py
new file mode 100644
index 00000000..9283f2b8
--- /dev/null
+++ b/docs/component/Grid/grid.py
@@ -0,0 +1,76 @@
+import ipyvuetify as v
+
+items = [
+ {
+ "icon": "mdi-cellphone",
+ "device": "Extra small",
+ "code": "xs",
+ "type": "Small to large phone",
+ "range": "<600px",
+ },
+ {
+ "icon": "mdi-tablet",
+ "device": "Small",
+ "code": "sm",
+ "type": "Small to medium tablet",
+ "range": "600px - 960px",
+ },
+ {
+ "icon": "mdi-laptop",
+ "device": "Medium",
+ "code": "md",
+ "type": "Large tablet to laptop",
+ "range": "960px - 1264px",
+ },
+ {
+ "icon": "mdi-monitor",
+ "device": "Large",
+ "code": "lg",
+ "type": "Desktop",
+ "range": "1264px - 1904px",
+ },
+ {
+ "icon": "mdi-television",
+ "device": "Extra large",
+ "code": "xl",
+ "type": "4k and ultra-wide",
+ "range": "> 1904px",
+ },
+]
+
+v.SimpleTable(
+ children=[
+ v.Html(
+ tag="thead",
+ children=[
+ v.Html(
+ tag="tr",
+ children=[
+ v.Html(tag="th", class_="text-left", children=["Device"]),
+ v.Html(tag="th", class_="text-left", children=["Breakpoint"]),
+ v.Html(tag="th", class_="text-left", children=["Type"]),
+ v.Html(tag="th", class_="text-left", children=["Range"]),
+ ],
+ )
+ ],
+ ),
+ v.Html(
+ tag="tbody",
+ children=[
+ v.Html(
+ tag="tr",
+ children=[
+ v.Html(
+ tag="td",
+ children=[v.Icon(children=[item["icon"]]), " ", item["device"]],
+ ),
+ v.Html(tag="td", children=[item["code"]]),
+ v.Html(tag="td", children=[item["type"]]),
+ v.Html(tag="td", children=[item["range"]]),
+ ],
+ )
+ for item in items
+ ],
+ ),
+ ]
+)
diff --git a/docs/component/Grid/grow_and_shrink.py b/docs/component/Grid/grow_and_shrink.py
new file mode 100644
index 00000000..0f023118
--- /dev/null
+++ b/docs/component/Grid/grow_and_shrink.py
@@ -0,0 +1,32 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ class_="mb-6",
+ no_gutters=True,
+ children=[
+ v.Col(children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["col"])])
+ for n in range(4)
+ ],
+ ),
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ cols=8 if n == 1 else 4,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[f"col-{8 if n == 1 else 4}"],
+ )
+ ],
+ )
+ for n in range(2)
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Grid/grow_and_shrink.vue b/docs/component/Grid/grow_and_shrink.vue
new file mode 100644
index 00000000..9903675e
--- /dev/null
+++ b/docs/component/Grid/grow_and_shrink.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ col
+
+
+
+
+
+ col-{{ n === 1 ? 8 : 4 }}
+
+
+
+
diff --git a/docs/component/Grid/justify.py b/docs/component/Grid/justify.py
new file mode 100644
index 00000000..fdab52b4
--- /dev/null
+++ b/docs/component/Grid/justify.py
@@ -0,0 +1,23 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ key=j,
+ justify=j,
+ children=[
+ v.Col(
+ md=4,
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=["One of two columns"]
+ )
+ ],
+ )
+ for k in range(2)
+ ],
+ )
+ for j in ["start", "center", "end", "space-between", "space-around", "space-evenly"]
+ ],
+)
diff --git a/docs/component/Grid/justify.vue b/docs/component/Grid/justify.vue
new file mode 100644
index 00000000..85b23141
--- /dev/null
+++ b/docs/component/Grid/justify.vue
@@ -0,0 +1,9 @@
+
+
+
+
+ One of two columns
+
+
+
+
diff --git a/docs/component/Grid/margin_helpers.py b/docs/component/Grid/margin_helpers.py
new file mode 100644
index 00000000..379d3a93
--- /dev/null
+++ b/docs/component/Grid/margin_helpers.py
@@ -0,0 +1,73 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ md=4,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=[".col-md-4"])
+ ],
+ ),
+ v.Col(
+ md=4,
+ class_="ml-auto",
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=[".col-md-4 .ml-auto"]
+ )
+ ],
+ ),
+ ]
+ ),
+ v.Row(
+ children=[
+ v.Col(
+ md=3,
+ class_="ml-md-auto",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-md-3 .ml-md-auto"],
+ )
+ ],
+ ),
+ v.Col(
+ md=3,
+ class_="ml-md-auto",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-md-3 .ml-md-auto"],
+ )
+ ],
+ ),
+ ]
+ ),
+ v.Row(
+ children=[
+ v.Col(
+ cols="auto",
+ class_="mr-auto",
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=[".col-auto .mr-auto"]
+ )
+ ],
+ ),
+ v.Col(
+ cols="auto",
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=[".col-auto"])
+ ],
+ ),
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Grid/margin_helpers.vue b/docs/component/Grid/margin_helpers.vue
new file mode 100644
index 00000000..fb1aa847
--- /dev/null
+++ b/docs/component/Grid/margin_helpers.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+ .col-md-4
+
+
+ .col-md-4 .ml-auto
+
+
+
+
+ .col-md-3 .ml-md-auto
+
+
+ .col-md-3 .ml-md-auto
+
+
+
+
+ .col-auto .mr-auto
+
+
+ .col-auto
+
+
+
+
+
diff --git a/docs/component/Grid/nested_grid.py b/docs/component/Grid/nested_grid.py
new file mode 100644
index 00000000..786437e0
--- /dev/null
+++ b/docs/component/Grid/nested_grid.py
@@ -0,0 +1,50 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ sm=9,
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=["Level 1: .col-sm-9"]
+ ),
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ cols=8,
+ sm=6,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ style_="background-color: lightgrey;",
+ children=["Level 2: .col-8 .col-sm-6"],
+ )
+ ],
+ ),
+ v.Col(
+ cols=4,
+ sm=6,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ style_="background-color: lightgrey;",
+ children=["Level 3: .col-4 .col-sm-6"],
+ )
+ ],
+ ),
+ ],
+ ),
+ ],
+ )
+ ]
+ )
+ ],
+)
diff --git a/docs/component/Grid/nested_grid.vue b/docs/component/Grid/nested_grid.vue
new file mode 100644
index 00000000..9d406d03
--- /dev/null
+++ b/docs/component/Grid/nested_grid.vue
@@ -0,0 +1,31 @@
+
+
+
+
+ Level 1: .col-sm-9
+
+
+
+ Level 2: .col-8 .col-sm-6
+
+
+
+
+ Level 3: .col-4 .col-sm-6
+
+
+
+
+
+
+
diff --git a/docs/component/Grid/no_gutters.py b/docs/component/Grid/no_gutters.py
new file mode 100644
index 00000000..079c64a8
--- /dev/null
+++ b/docs/component/Grid/no_gutters.py
@@ -0,0 +1,34 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ cols=12,
+ sm=6,
+ md=8,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-12 .col-sm-6 .col-md-8"],
+ )
+ ],
+ ),
+ v.Col(
+ cols=6,
+ md=4,
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=[".col-6 .col-md-4"]
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Grid/no_gutters.vue b/docs/component/Grid/no_gutters.vue
new file mode 100644
index 00000000..45129194
--- /dev/null
+++ b/docs/component/Grid/no_gutters.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+ .col-12 .col-sm-6 .col-md-8
+
+
+
+ .col-6 .col-md-4
+
+
+
+
diff --git a/docs/component/Grid/offset.py b/docs/component/Grid/offset.py
new file mode 100644
index 00000000..6278cf29
--- /dev/null
+++ b/docs/component/Grid/offset.py
@@ -0,0 +1,78 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ class_="mb-6",
+ no_gutters=True,
+ children=[
+ v.Col(
+ md=4,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=[".col-md-4"])
+ ],
+ ),
+ v.Col(
+ md=4,
+ offset_md=4,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-md-4 .offset-md-4"],
+ )
+ ],
+ ),
+ ],
+ ),
+ v.Row(
+ class_="mb-6",
+ no_gutters=True,
+ children=[
+ v.Col(
+ md=3,
+ offset_md=3,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-md-3 .offset-md-3"],
+ )
+ ],
+ ),
+ v.Col(
+ md=3,
+ offset_md=3,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-md-3 .offset-md-3"],
+ )
+ ],
+ ),
+ ],
+ ),
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ md=6,
+ offset_md=3,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-md-6 .offset-md-3"],
+ )
+ ],
+ )
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Grid/offset.vue b/docs/component/Grid/offset.vue
new file mode 100644
index 00000000..9cdf70b3
--- /dev/null
+++ b/docs/component/Grid/offset.vue
@@ -0,0 +1,25 @@
+
+
+
+
+ .col-md-4
+
+
+ .col-md-4 .offset-md-4
+
+
+
+
+ .col-md-3 .offset-md-3
+
+
+ .col-md-3 .offset-md-3
+
+
+
+
+ .col-md-6 .offset-md-3
+
+
+
+
diff --git a/docs/component/Grid/offset_breakpoint.py b/docs/component/Grid/offset_breakpoint.py
new file mode 100644
index 00000000..cd0f0e21
--- /dev/null
+++ b/docs/component/Grid/offset_breakpoint.py
@@ -0,0 +1,72 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ class_="mb-6",
+ no_gutters=True,
+ children=[
+ v.Col(
+ sm=5,
+ md=6,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-sm-5 .col-md-6"],
+ )
+ ],
+ ),
+ v.Col(
+ sm=5,
+ offset_sm=2,
+ md=6,
+ offset_md=0,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-sm-5 .offset-sm-2 .col-md-6 .offset-md-0"],
+ )
+ ],
+ ),
+ ],
+ ),
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ sm=6,
+ md=5,
+ lg=6,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-sm-6 .col-md-5 .col-lg-6"],
+ )
+ ],
+ ),
+ v.Col(
+ sm=6,
+ md=5,
+ offset_md=2,
+ lg=6,
+ offset_lg=0,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=[".col-sm-6 .col-md-5 .offset-md-2 .col-lg-6 .offset-lg-0"],
+ )
+ ],
+ ),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Grid/offset_breakpoint.vue b/docs/component/Grid/offset_breakpoint.vue
new file mode 100644
index 00000000..88a14af8
--- /dev/null
+++ b/docs/component/Grid/offset_breakpoint.vue
@@ -0,0 +1,26 @@
+
+
+
+
+ .col-sm-5 .col-md-6
+
+
+
+ .col-sm-5 .offset-sm-2 .col-md-6 .offset-md-0
+
+
+
+
+
+
+ .col-sm-6 .col-md-5 .col-lg-6
+
+
+
+
+ .col-sm-6 .col-md-5 .offset-md-2 .col-lg-6 .offset-lg-0
+
+
+
+
+
diff --git a/docs/component/Grid/one_column_width.py b/docs/component/Grid/one_column_width.py
new file mode 100644
index 00000000..0bf7a9ce
--- /dev/null
+++ b/docs/component/Grid/one_column_width.py
@@ -0,0 +1,42 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ class_="mb-6",
+ no_gutters=True,
+ children=[
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["1 of 3"])]
+ ),
+ v.Col(
+ cols=6,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["2 of 3 (wider)"])
+ ],
+ ),
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["3 of 3"])]
+ ),
+ ],
+ ),
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["1 of 3"])]
+ ),
+ v.Col(
+ cols=5,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=["2 of 3 (wider)"])
+ ],
+ ),
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["3 of 3"])]
+ ),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Grid/one_column_width.vue b/docs/component/Grid/one_column_width.vue
new file mode 100644
index 00000000..ea87aa54
--- /dev/null
+++ b/docs/component/Grid/one_column_width.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+ {{ n }} of 3 {{ n === 2 ? "(wider)" : "" }}
+
+
+
+
+
+
+ {{ n }} of 3 {{ n === 2 ? "(wider)" : "" }}
+
+
+
+
+
diff --git a/docs/component/Grid/order.py b/docs/component/Grid/order.py
new file mode 100644
index 00000000..24cac18c
--- /dev/null
+++ b/docs/component/Grid/order.py
@@ -0,0 +1,38 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["First, but unordered"],
+ )
+ ]
+ ),
+ v.Col(
+ order=12,
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=["Second, but last"]
+ )
+ ],
+ ),
+ v.Col(
+ order=1,
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=["Third, but first"]
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Grid/order.vue b/docs/component/Grid/order.vue
new file mode 100644
index 00000000..d7bdf2f9
--- /dev/null
+++ b/docs/component/Grid/order.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ First, but unordered
+
+
+ Second, but last
+
+
+ Third, but first
+
+
+
+
diff --git a/docs/component/Grid/order_first_and_last.py b/docs/component/Grid/order_first_and_last.py
new file mode 100644
index 00000000..de3f1510
--- /dev/null
+++ b/docs/component/Grid/order_first_and_last.py
@@ -0,0 +1,38 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ order="last",
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=["First, but last"]
+ )
+ ],
+ ),
+ v.Col(
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["Second, but unordered"],
+ )
+ ]
+ ),
+ v.Col(
+ order="first",
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=["Third, but first"]
+ )
+ ],
+ ),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Grid/order_first_and_last.vue b/docs/component/Grid/order_first_and_last.vue
new file mode 100644
index 00000000..9116d09e
--- /dev/null
+++ b/docs/component/Grid/order_first_and_last.vue
@@ -0,0 +1,15 @@
+
+
+
+
+ First, but last
+
+
+ Second, but unordered
+
+
+ Third, but first
+
+
+
+
diff --git a/docs/component/Grid/spacers.py b/docs/component/Grid/spacers.py
new file mode 100644
index 00000000..7139d685
--- /dev/null
+++ b/docs/component/Grid/spacers.py
@@ -0,0 +1,46 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=[".col"])]
+ ),
+ v.Spacer(),
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=[".col"])]
+ ),
+ ]
+ ),
+ v.Row(
+ children=[
+ v.Col(
+ cols="auto",
+ lg=3,
+ children=[
+ v.Card(class_="pa-2", outlined=True, tile=True, children=[".col-auto"])
+ ],
+ ),
+ v.Spacer(),
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=[".col"])]
+ ),
+ v.Spacer(),
+ v.Col(
+ md=5,
+ children=[
+ v.Card(
+ class_="pa-2",
+ cols="auto",
+ outlined=True,
+ tile=True,
+ children=[".col-md-5"],
+ )
+ ],
+ ),
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Grid/spacers.vue b/docs/component/Grid/spacers.vue
new file mode 100644
index 00000000..4cc8084f
--- /dev/null
+++ b/docs/component/Grid/spacers.vue
@@ -0,0 +1,33 @@
+
+
+
+
+ .col
+
+
+
+
+
+ .col
+
+
+
+
+
+ .col-auto
+
+
+
+
+
+ .col
+
+
+
+
+
+ .col-md-5
+
+
+
+
diff --git a/docs/component/Grid/unique_layouts.py b/docs/component/Grid/unique_layouts.py
new file mode 100644
index 00000000..9d0965e4
--- /dev/null
+++ b/docs/component/Grid/unique_layouts.py
@@ -0,0 +1,52 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ cols=12,
+ md=8,
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=[".col-12 .col-md-8"]
+ )
+ ],
+ ),
+ v.Col(
+ cols=6,
+ md=4,
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=[".col-6 .col-md-4"]
+ )
+ ],
+ ),
+ ]
+ ),
+ v.Row(
+ children=[
+ v.Col(
+ cols=6,
+ md=4,
+ children=[
+ v.Card(
+ class_="pa-2", outlined=True, tile=True, children=[".col-6 .col-md-4"]
+ )
+ ],
+ )
+ for _ in range(3)
+ ]
+ ),
+ v.Row(
+ children=[
+ v.Col(
+ cols=6,
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=[".col-6"])],
+ )
+ for _ in range(2)
+ ]
+ ),
+ ],
+)
diff --git a/docs/component/Grid/unique_layouts.vue b/docs/component/Grid/unique_layouts.vue
new file mode 100644
index 00000000..60d39fcf
--- /dev/null
+++ b/docs/component/Grid/unique_layouts.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+ .col-12 .col-md-8
+
+
+ .col-6 .col-md-4
+
+
+
+
+
+
+ .col-6 .col-md-4
+
+
+
+
+
+
+ .col-6
+
+
+
+
diff --git a/docs/component/Grid/usage.py b/docs/component/Grid/usage.py
new file mode 100644
index 00000000..7ab8235a
--- /dev/null
+++ b/docs/component/Grid/usage.py
@@ -0,0 +1,25 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ cols=12,
+ sm=4,
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["One of three columns"],
+ )
+ ],
+ )
+ for n in range(3)
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Grid/variable_content_width.py b/docs/component/Grid/variable_content_width.py
new file mode 100644
index 00000000..98e77b1f
--- /dev/null
+++ b/docs/component/Grid/variable_content_width.py
@@ -0,0 +1,56 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="grey lighten-5",
+ children=[
+ v.Row(
+ class_="mb-6",
+ justify="center",
+ no_gutters=True,
+ children=[
+ v.Col(
+ lg=2,
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["1 of 3"])],
+ ),
+ v.Col(
+ md="auto",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["Variable width content"],
+ )
+ ],
+ ),
+ v.Col(
+ lg=2,
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["3 of 3"])],
+ ),
+ ],
+ ),
+ v.Row(
+ no_gutters=True,
+ children=[
+ v.Col(
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["1 of 3"])]
+ ),
+ v.Col(
+ md="auto",
+ children=[
+ v.Card(
+ class_="pa-2",
+ outlined=True,
+ tile=True,
+ children=["Variable width content"],
+ )
+ ],
+ ),
+ v.Col(
+ lg=2,
+ children=[v.Card(class_="pa-2", outlined=True, tile=True, children=["3 of 3"])],
+ ),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Grid/variable_content_width.vue b/docs/component/Grid/variable_content_width.vue
new file mode 100644
index 00000000..ae2b2e32
--- /dev/null
+++ b/docs/component/Grid/variable_content_width.vue
@@ -0,0 +1,26 @@
+
+
+
+
+ 1 of 3
+
+
+ Variable width content
+
+
+ 3 of 3
+
+
+
+
+ 1 of 3
+
+
+ Variable width content
+
+
+ 3 of 3
+
+
+
+
diff --git a/docs/component/Hover.rst b/docs/component/Hover.rst
new file mode 100644
index 00000000..a066dff5
--- /dev/null
+++ b/docs/component/Hover.rst
@@ -0,0 +1,70 @@
+Hover
+=====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Hover documentation
+ `__.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Hover ` component provides a clean interface for
+handling hover states for any component.
+
+.. api::
+
+ :py:class:`ipyvuetify.Hover`
+
+Usage
+-----
+
+The :py:class:`Hover ` component is a wrapper that should contain
+only one child element, and can trigger an event when hovered over. In order for
+:py:class:`Hover ` to work properly, either the value prop should
+be set to ``true`` or the wrapped element should contain ``v-slot="{ wrapper }"``.
+
+.. todo::
+
+ I don't understand how to use the slot syntax here. Please help me improve this section.
+
+Examples
+--------
+
+Disabled
+^^^^^^^^
+
+The ``disabled`` prop disables the hover functionality.
+
+.. todo::
+
+ I don't understand how to use the slot syntax here. Please help me improve this section.
+
+Open and close delay
+^^^^^^^^^^^^^^^^^^^^
+
+Delay :py:class:`Hover ` events by using ``open-delay`` and
+``close-delay`` props in combination or separately.
+
+.. todo::
+
+ I don't understand how to use the slot syntax here. Please help me improve
+ this section.
+
+Hover list
+^^^^^^^^^^
+
+:py:class:`Hover ` can be used in combination with ``v-for``
+to make a single item stand out when the user interacts with the list.
+
+.. todo::
+
+ I don't understand how to use the slot syntax here. Please help me improve
+ this section.
+
+Transition
+^^^^^^^^^^
+
+Create highly customized components that respond to user interaction.
+
+.. todo::
+
+ I don't understand how to use the slot syntax here. Please help me improve
+ this section.
\ No newline at end of file
diff --git a/docs/component/Icon.rst b/docs/component/Icon.rst
new file mode 100644
index 00000000..83f31e5e
--- /dev/null
+++ b/docs/component/Icon.rst
@@ -0,0 +1,150 @@
+Icon
+====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Icon documentation
+ `__.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Icon ` component provides a large set of
+glyphs to provide context to various aspects of your application. For a list of
+all available icons, visit the official `Material Design Icons
+`__ page. To use any of these icons simply
+use the ``mdi-`` prefix followed by the icon name.
+
+.. api::
+
+ - :py:class:`ipyvuetify.Icon`
+
+Usage
+-----
+
+Icons come in two themes (light and dark), and five different sizes (x-small,
+small, medium (default), large, and x-large).
+
+.. jupyter-execute:: Icon/usage.py
+ :raises:
+
+Examples
+--------
+
+Color
+^^^^^
+
+Using color helpers you can change the color of an icon from the standard dark
+and light themes.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Icon/color.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Icon/color.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Icon/color.vue
+
+Click
+^^^^^
+
+Binding any click event to :py:class:`Icon ` will
+automatically change the cursor to a pointer.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Icon/click.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Icon/click.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Icon/click.vue
+
+Buttons
+^^^^^^^
+
+Icons can be used inside of buttons to add emphasis to the action.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Icon/buttons.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Icon/buttons.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Icon/buttons.vue
+
+Font Awesome
+^^^^^^^^^^^^
+
+`Font Awesome `__ is also supported. Simply use
+the ``fa-`` prefixed icon name. Please note that you still need to include the
+Font Awesome icons in your project. For more information on how to install it,
+please navigate to the `installation page
+`__.
+
+.. danger::
+
+ change of icon font is not yet supported by ipyvuetify.
+
+Material Design
+^^^^^^^^^^^^^^^
+
+`Material Design `__ is also
+supported. For more information on how to install it please `navigate here
+`__.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Icon/material_design.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Icon/material_design.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Icon/material_design.vue
+
+Accessibility
+-------------
+
+Icons can convey all sorts of meaningful information, so it's important that
+they reach the largest amount of people possible. There are two use cases you'll
+want to consider:
+
+- **Decorative Icons** are only being used for visual or branding reinforcement.
+ If they were removed from the page, users would still understand and be able
+ to use your page.
+- **Semantic Icons** are ones that you're using to convey meaning, rather than
+ just pure decoration. This includes icons without text next to them used as
+ interactive controls — buttons, form elements, toggles, etc.
+
+.. danger::
+
+ WAI-ARIA Authoring Practices 1.1 notes that ``aria-hidden="false"`` currently
+ `behaves inconsistently across browsers `__.
+
diff --git a/docs/component/Icon/buttons.py b/docs/component/Icon/buttons.py
new file mode 100644
index 00000000..0bc6045d
--- /dev/null
+++ b/docs/component/Icon/buttons.py
@@ -0,0 +1,123 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.Html(
+ tag="div",
+ class_="text-center",
+ children=[
+ v.Html(
+ tag="div",
+ children=[
+ v.Btn(
+ class_="ma-2",
+ color="primary",
+ dark=True,
+ children=[
+ "Accept",
+ v.Icon(
+ dark=True,
+ right=True,
+ children=["mdi-checkbox-marked-circle"],
+ ),
+ ],
+ ),
+ v.Btn(
+ class_="ma-2",
+ color="red",
+ dark=True,
+ children=[
+ "Decline",
+ v.Icon(
+ dark=True,
+ right=True,
+ children=["mdi-cancel"],
+ ),
+ ],
+ ),
+ v.Btn(
+ class_="ma-2",
+ dark=True,
+ children=[
+ v.Icon(
+ dark=True,
+ left=True,
+ children=["mdi-minus-circle"],
+ ),
+ "Cancel",
+ ],
+ ),
+ ],
+ ),
+ v.Html(
+ tag="div",
+ children=[
+ v.Btn(
+ class_="ma-2",
+ color="orange darken-2",
+ dark=True,
+ children=[
+ v.Icon(
+ dark=True,
+ left=True,
+ children=["mdi-arrow-left"],
+ ),
+ "Back",
+ ],
+ ),
+ v.Btn(
+ class_="ma-2",
+ color="purple",
+ dark=True,
+ children=[
+ v.Icon(
+ dark=True,
+ children=["mdi-wrench"],
+ ),
+ ],
+ ),
+ v.Btn(
+ class_="ma-2",
+ color="indigo",
+ dark=True,
+ children=[
+ v.Icon(
+ dark=True,
+ children=["mdi-cloud-upload"],
+ ),
+ ],
+ ),
+ ],
+ ),
+ v.Html(
+ tag="div",
+ children=[
+ v.Btn(
+ class_="ma-2",
+ text=True,
+ icon=True,
+ color="blue lighten-2",
+ children=[
+ v.Icon(
+ children=["mdi-thumb-up"],
+ ),
+ ],
+ ),
+ v.Btn(
+ class_="ma-2",
+ text=True,
+ icon=True,
+ color="red lighten-2",
+ children=[
+ v.Icon(
+ children=["mdi-thumb-down"],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+)
diff --git a/docs/component/Icon/buttons.vue b/docs/component/Icon/buttons.vue
new file mode 100644
index 00000000..7a20d6bb
--- /dev/null
+++ b/docs/component/Icon/buttons.vue
@@ -0,0 +1,43 @@
+
+
+
+
+ Accept
+ mdi-checkbox-marked-circle
+
+
+
+ Decline
+ mdi-cancel
+
+
+
+ mdi-minus-circle Cancel
+
+
+
+
+
+ mdi-arrow-left Back
+
+
+
+ mdi-wrench
+
+
+
+ mdi-cloud-upload
+
+
+
+
+
+ mdi-thumb-up
+
+
+
+ mdi-thumb-down
+
+
+
+
diff --git a/docs/component/Icon/click.py b/docs/component/Icon/click.py
new file mode 100644
index 00000000..2cb39567
--- /dev/null
+++ b/docs/component/Icon/click.py
@@ -0,0 +1,40 @@
+import ipyvuetify as v
+
+v.Card(
+ children=[
+ v.Toolbar(
+ color="pink",
+ dark=True,
+ dense=True,
+ flat=True,
+ children=[
+ v.ToolbarTitle(
+ class_="text-body-2",
+ children=["Upcoming Changes"],
+ ),
+ ],
+ ),
+ v.CardText(
+ children=[
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
+ "sed do eiusmod tempor incididunt ut labore et dolore magna "
+ "aliqua. Ut enim ad minim veniam, quis nostrud exercitation "
+ "ullamco laboris nisi ut aliquip ex ea commodo consequat. "
+ "Duis aute irure dolor in reprehenderit in voluptate velit "
+ "esse cillum dolore eu fugiat nulla pariatur. Excepteur "
+ "sint occaecat cupidatat non proident, sunt in culpa qui "
+ "officia deserunt mollit anim id est laborum."
+ ]
+ ),
+ v.CardActions(
+ children=[
+ v.Spacer(),
+ v.Icon(
+ large=True,
+ children=["mdi-chevron-right"],
+ # on_click=lambda x: print("Icon clicked!"),
+ ),
+ ]
+ ),
+ ]
+)
diff --git a/docs/component/Icon/click.vue b/docs/component/Icon/click.vue
new file mode 100644
index 00000000..7208297f
--- /dev/null
+++ b/docs/component/Icon/click.vue
@@ -0,0 +1,21 @@
+
+
+
+ Upcoming Changes
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
+ tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
+ veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
+ commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
+ velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
+ cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
+ est laborum.
+
+
+
+
+ mdi-chevron-right
+
+
+
diff --git a/docs/component/Icon/color.py b/docs/component/Icon/color.py
new file mode 100644
index 00000000..b263a80e
--- /dev/null
+++ b/docs/component/Icon/color.py
@@ -0,0 +1,28 @@
+import ipyvuetify as v
+
+icons = [
+ ("mdi-domain", "green darken-2"),
+ ("mdi-message-text", "blue darken-2"),
+ ("mdi-dialpad", "purple darken-2"),
+ ("mdi-email", "teal darken-2"),
+ ("mdi-call-split", "blue-grey darken-2"),
+ ("mdi-arrow-up-bold-box-outline", "orange darken-2"),
+]
+
+v.Layout(
+ class_="d-flex flex-row justify-space-evenly",
+ children=[
+ v.Html(
+ tag="div",
+ class_="d-flex flex-grow-1 justify-center",
+ children=[
+ v.Icon(
+ children=[icon_name],
+ large=True,
+ color=color,
+ )
+ ],
+ )
+ for icon_name, color in icons
+ ],
+)
diff --git a/docs/component/Icon/color.vue b/docs/component/Icon/color.vue
new file mode 100644
index 00000000..769d5423
--- /dev/null
+++ b/docs/component/Icon/color.vue
@@ -0,0 +1,17 @@
+
+
+ mdi-domain
+
+ mdi-message-text
+
+ mdi-dialpad
+
+ mdi-email
+
+ mdi-call-split
+
+
+ mdi-arrow-up-bold-box-outline
+
+
+
diff --git a/docs/component/Icon/material_design.py b/docs/component/Icon/material_design.py
new file mode 100644
index 00000000..bfa08f3c
--- /dev/null
+++ b/docs/component/Icon/material_design.py
@@ -0,0 +1,47 @@
+import ipyvuetify as v
+
+icons = ["mdi-home", "mdi-calendar", "mdi-information"]
+green_icons = ["mdi-folder-open", "mdi-widgets", "mdi-gavel"]
+sizes = ["small", "medium", "large", "x-large"]
+
+
+v.Container(
+ fluid=True,
+ children=[
+ v.Layout(
+ class_="d-flex flex-row justify-space-evenly my-2",
+ children=[
+ v.Html(
+ tag="div",
+ class_="d-flex flex-grow-1 justify-center py-2",
+ children=[
+ v.Icon(
+ small=(size == "small"),
+ large=(size == "large"),
+ x_large=(size == "x-large"),
+ children=[icon],
+ )
+ ],
+ )
+ for icon in icons
+ ]
+ + [
+ v.Html(
+ tag="div",
+ class_="teal d-flex flex-grow-1 justify-center py-2",
+ children=[
+ v.Icon(
+ dark=True,
+ small=(size == "small"),
+ large=(size == "large"),
+ x_large=(size == "x-large"),
+ children=[icon],
+ )
+ ],
+ )
+ for icon in green_icons
+ ],
+ )
+ for size in sizes
+ ],
+)
diff --git a/docs/component/Icon/material_design.vue b/docs/component/Icon/material_design.vue
new file mode 100644
index 00000000..d45ab320
--- /dev/null
+++ b/docs/component/Icon/material_design.vue
@@ -0,0 +1,59 @@
+
+
+
+
+ home
+ event
+ info
+
+
+
+ folder_open
+ widgets
+ gavel
+
+
+
+
+
+ home
+ event
+ info
+
+
+
+ folder_open
+ widgets
+ gavel
+
+
+
+
+
+ home
+ event
+ info
+
+
+
+ folder_open
+ widgets
+ gavel
+
+
+
+
+
+ home
+ event
+ info
+
+
+
+ folder_open
+ widgets
+ gavel
+
+
+
+
diff --git a/docs/component/Icon/usage.py b/docs/component/Icon/usage.py
new file mode 100644
index 00000000..651606d4
--- /dev/null
+++ b/docs/component/Icon/usage.py
@@ -0,0 +1,7 @@
+import ipyvuetify as v
+
+v.Icon(
+ children=["mdi-home"],
+ color="primary",
+ large=True,
+)
diff --git a/docs/component/Img.rst b/docs/component/Img.rst
new file mode 100644
index 00000000..69ea5f2f
--- /dev/null
+++ b/docs/component/Img.rst
@@ -0,0 +1,165 @@
+Img
+===
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Images documentation
+ `__.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Img ` component is packed with features to
+support rich media. Combined with the `vuetify-loader
+`__, you can add dynamic
+progressive images to provide a better user experience.
+
+.. api::
+
+ :py:class:`ipyvuetify.Img`
+
+Usage
+-----
+
+:py:class:`Img ` component is used to display a responsive
+image with lazy-load and placeholder.
+
+.. jupyter-execute:: Img/usage.py
+ :raises:
+
+Examples
+--------
+
+Aspect ratio
+^^^^^^^^^^^^
+
+You can set a fixed aspect ratio if you want to change aspect ratio of the
+image.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Img/aspect_ratio.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Img/aspect_ratio.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Img/aspect_ratio.vue
+
+Contain
+^^^^^^^
+
+If the provided aspect ratio doesn't match that of the actual image, the default
+behavior is to fill as much space as possible, clipping the sides of the image.
+Enabling the ``contain`` prop will prevent this, but will result in empty space
+at the sides.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Img/contain.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Img/contain.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Img/contain.vue
+
+Gradients
+^^^^^^^^^
+
+The ``gradient`` prop can be used to apply a simple gradient overlay to the
+image.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Img/gradients.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Img/gradients.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Img/gradients.vue
+
+Height
+^^^^^^
+
+:py:class:`Img ` will automatically grow to the size of its
+``src``, preserving the correct aspect ratio. You can limit this with the
+``height`` and ``max-height`` props.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Img/height.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Img/height.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Img/height.vue
+
+Placeholder
+^^^^^^^^^^^
+
+:py:class:`Img ` has a special ``placeholder`` slot for
+placeholder to display while image's loading. Note: the example below has bad
+src which won't load for you to see placeholder.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Img/placeholder.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Img/placeholder.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Img/placeholder.vue
+
+Grid
+^^^^
+
+You can use :py:class:`Img ` to make, for example, a picture
+gallery.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Img/grid.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Img/grid.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Img/grid.vue
+
diff --git a/docs/component/Img/aspect_ratio.py b/docs/component/Img/aspect_ratio.py
new file mode 100644
index 00000000..18728d5f
--- /dev/null
+++ b/docs/component/Img/aspect_ratio.py
@@ -0,0 +1,11 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+slider = v.Slider(min=200, max=500, step=1, v_model=300)
+img = v.Img(
+ aspect_ratio=16 / 9, width=300, src="https://cdn.vuetifyjs.com/images/parallax/material.jpg"
+)
+jslink((slider, "v_model"), (img, "width"))
+
+v.Container(children=[slider, img])
diff --git a/docs/component/Img/aspect_ratio.vue b/docs/component/Img/aspect_ratio.vue
new file mode 100644
index 00000000..1d1d1b3b
--- /dev/null
+++ b/docs/component/Img/aspect_ratio.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
diff --git a/docs/component/Img/contain.py b/docs/component/Img/contain.py
new file mode 100644
index 00000000..31096823
--- /dev/null
+++ b/docs/component/Img/contain.py
@@ -0,0 +1,46 @@
+import ipyvuetify as v
+
+v.Container(
+ fluid=True,
+ children=[
+ v.Row(
+ justify="space-around",
+ children=[
+ v.Col(
+ cols=5,
+ children=[
+ v.Html(tag="h3", children=["Default (cover)"], class_="mb-1"),
+ v.Html(tag="h4", children=["Matching"], class_="subheading"),
+ v.Img(src="https://picsum.photos/510/300?random", aspect_ratio=1.7),
+ v.Html(tag="h4", children=["Too high"], class_="subheading pt-4"),
+ v.Img(src="https://picsum.photos/510/300?random", aspect_ratio=2),
+ v.Html(tag="h4", children=["Too low"], class_="subheading pt-4"),
+ v.Img(src="https://picsum.photos/510/300?random", aspect_ratio=1.4),
+ ],
+ ),
+ v.Col(
+ cols=5,
+ children=[
+ v.Html(tag="h3", children=["Contain"], class_="mb-1"),
+ v.Html(tag="h4", children=["Matching"], class_="subheading"),
+ v.Img(
+ src="https://picsum.photos/510/300?random",
+ aspect_ratio=1.7,
+ contain=True,
+ ),
+ v.Html(tag="h4", children=["Too high"], class_="subheading pt-4"),
+ v.Img(
+ src="https://picsum.photos/510/300?random", aspect_ratio=2, contain=True
+ ),
+ v.Html(tag="h4", children=["Too low"], class_="subheading pt-4"),
+ v.Img(
+ src="https://picsum.photos/510/300?random",
+ aspect_ratio=1.4,
+ contain=True,
+ ),
+ ],
+ ),
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Img/contain.vue b/docs/component/Img/contain.vue
new file mode 100644
index 00000000..8b57b7dc
--- /dev/null
+++ b/docs/component/Img/contain.vue
@@ -0,0 +1,46 @@
+
+
+
+
+ Default (cover)
+ Matching
+
+ Too high
+
+ Too low
+
+
+
+
+ Contain
+ Matching
+
+ Too high
+
+ Too low
+
+
+
+
+
diff --git a/docs/component/Img/gradients.py b/docs/component/Img/gradients.py
new file mode 100644
index 00000000..db955bd9
--- /dev/null
+++ b/docs/component/Img/gradients.py
@@ -0,0 +1,6 @@
+import ipyvuetify as v
+
+v.Img(
+ src="https://cdn.vuetifyjs.com/images/parallax/material2.jpg",
+ gradient="to top right, rgba(100,115,201,.33), rgba(25,32,72,.7)",
+)
diff --git a/docs/component/Img/gradients.vue b/docs/component/Img/gradients.vue
new file mode 100644
index 00000000..b6d0aa62
--- /dev/null
+++ b/docs/component/Img/gradients.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Img/grid.py b/docs/component/Img/grid.py
new file mode 100644
index 00000000..baed5c36
--- /dev/null
+++ b/docs/component/Img/grid.py
@@ -0,0 +1,36 @@
+import ipyvuetify as v
+
+v.Row(
+ children=[
+ v.Col(
+ cols=4,
+ class_="d-flex child-flex",
+ children=[
+ v.Img(
+ src=f"https://picsum.photos/500/300?image={n * 5 + 10}",
+ lazy_src=f"https://picsum.photos/10/6?image={n * 5 + 10}",
+ aspect_ratio=1,
+ class_="grey lighten-2",
+ v_slots=[
+ {
+ "name": "placeholder",
+ "children": [
+ v.Row(
+ class_="fill-height ma-0",
+ align="center",
+ justify="center",
+ children=[
+ v.ProgressCircular(
+ indeterminate=True, color="grey lighten-5"
+ )
+ ],
+ )
+ ],
+ }
+ ],
+ )
+ ],
+ )
+ for n in range(9)
+ ]
+)
diff --git a/docs/component/Img/grid.vue b/docs/component/Img/grid.vue
new file mode 100644
index 00000000..ecbdf72b
--- /dev/null
+++ b/docs/component/Img/grid.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Img/height.py b/docs/component/Img/height.py
new file mode 100644
index 00000000..2e33579d
--- /dev/null
+++ b/docs/component/Img/height.py
@@ -0,0 +1,84 @@
+import ipyvuetify as v
+
+v.Container(
+ class_="fill-height",
+ fluid=True,
+ min_height="434px",
+ children=[
+ v.FadeTransition(
+ mode="out-in",
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ cols=6,
+ children=[
+ v.Card(
+ children=[
+ v.Img(
+ src="https://picsum.photos/350/165?random",
+ height="125",
+ class_="grey darken-4",
+ ),
+ v.CardTitle(class_="text-h6", children=["height"]),
+ ]
+ )
+ ],
+ ),
+ v.Col(
+ cols=6,
+ children=[
+ v.Card(
+ children=[
+ v.Img(
+ src="https://picsum.photos/350/165?random",
+ height="125",
+ contain=True,
+ class_="grey darken-4",
+ ),
+ v.CardTitle(
+ class_="text-h6", children=["height with contain"]
+ ),
+ ]
+ )
+ ],
+ ),
+ v.Col(
+ cols=6,
+ children=[
+ v.Card(
+ children=[
+ v.Img(
+ src="https://picsum.photos/350/165?random",
+ max_height="125",
+ class_="grey darken-4",
+ ),
+ v.CardTitle(class_="text-h6", children=["max-height"]),
+ ]
+ )
+ ],
+ ),
+ v.Col(
+ cols=6,
+ children=[
+ v.Card(
+ children=[
+ v.Img(
+ src="https://picsum.photos/350/165?random",
+ max_height="125",
+ contain=True,
+ class_="grey darken-4",
+ ),
+ v.CardTitle(
+ class_="text-h6", children=["max-height with contain"]
+ ),
+ ]
+ )
+ ],
+ ),
+ ]
+ )
+ ],
+ )
+ ],
+)
diff --git a/docs/component/Img/height.vue b/docs/component/Img/height.vue
new file mode 100644
index 00000000..0c0dc71d
--- /dev/null
+++ b/docs/component/Img/height.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+ height
+
+
+
+
+
+
+ height with contain
+
+
+
+
+
+
+ max-height
+
+
+
+
+
+
+
+ max-height with contain
+
+
+
+
+
+
+
diff --git a/docs/component/Img/placeholder.py b/docs/component/Img/placeholder.py
new file mode 100644
index 00000000..3b24db98
--- /dev/null
+++ b/docs/component/Img/placeholder.py
@@ -0,0 +1,22 @@
+import ipyvuetify as v
+
+v.Row(
+ justify="center",
+ children=[
+ v.Img(
+ src="https://bad.src/not/valid",
+ lazy_src="https://picsum.photos/id/11/100/60",
+ max_width="500",
+ max_height="300",
+ children=[
+ v.Row(
+ class_="fill-height ma-0",
+ align="center",
+ justify="center",
+ children=[v.ProgressCircular(indeterminate=True, color="grey lighten-5")],
+ )
+ ],
+ slots={"placeholder": "placeholder"},
+ )
+ ],
+)
diff --git a/docs/component/Img/placeholder.vue b/docs/component/Img/placeholder.vue
new file mode 100644
index 00000000..c5705350
--- /dev/null
+++ b/docs/component/Img/placeholder.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/component/Img/usage.py b/docs/component/Img/usage.py
new file mode 100644
index 00000000..cd791762
--- /dev/null
+++ b/docs/component/Img/usage.py
@@ -0,0 +1,15 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+contains = v.Checkbox(label="Contain", v_model=False)
+max_height = v.Slider(label="Max Height", min=100, max=500, step=1, v_model=300)
+max_width = v.Slider(label="Max Width", min=100, max=500, step=1, v_model=400)
+
+img = v.Img(src="https://picsum.photos/id/11/500/300", contain=False, max_height=300, max_width=400)
+
+jslink((contains, "v_model"), (img, "contain"))
+jslink((max_height, "v_model"), (img, "max_height"))
+jslink((max_width, "v_model"), (img, "max_width"))
+
+v.Container(children=[contains, max_height, max_width, img])
diff --git a/docs/component/Input.rst b/docs/component/Input.rst
new file mode 100644
index 00000000..bba774ad
--- /dev/null
+++ b/docs/component/Input.rst
@@ -0,0 +1,241 @@
+Input
+=====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Input documentation
+ `__.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Input ` component gives you a baseline to
+create your own custom inputs. It consists of a prepend/append slot, messages,
+and a default slot. It is recommended that you extend this component, but it can
+be used as a standalone.
+
+.. api::
+
+ :py:class:`ipyvuetify.Input`
+
+Usage
+-----
+
+:py:class:`Input ` has 4 main areas. The prepended slot, the
+appended slot, the default slot, and messages. These make up the core logic
+shared between all form components.
+
+.. jupyter-execute:: Input/usage.py
+ :raises:
+
+.. warning::
+
+ The :py:class:`Input ` component is used as a wrapper for all
+ of the Vuetify form controls. It does NOT inherit attributes as they are
+ expected to be passed down to inner inputs.
+
+Examples
+--------
+
+Error
+^^^^^
+
+As any validatable Vuetify component, :py:class:`Input ` can
+be set to error state using ``error`` prop, messages can be added using
+``error-messages`` prop. You can determine error messages count to show using
+``error-count`` property.
+
+Error count
+^^^^^^^^^^^
+
+You can add multiple errors to :py:class:`Input ` using
+``error-count`` property.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Input/error_count.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Input/error_count.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Input/error_count.vue
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute::
+ :raises:
+ :hide-code:
+
+ import ipyvuetify as v
+
+ v.Input(
+ error_messages=['Fatal error'],
+ error=True,
+ disabled=True,
+ children=['Input']
+ )
+
+ .. tab-item:: :fab:`python` Python
+
+ .. code-block:: python
+
+ import ipyvuetify as v
+
+ v.Input(
+ error_messages=['Fatal error'],
+ error=True,
+ disabled=True,
+ children=['Input']
+ )
+
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. code-block:: vue
+
+
+
+ Input
+
+
+
+Hide details
+^^^^^^^^^^^^
+
+When the ``hide-details`` prop is set to ``auto`` messages will be rendered only
+if there's a message (hint, error message etc) to display.
+
+.. todo::
+
+ The rule syntax is not clearly available through ipyvuetify at the moment.
+ Please help me improve this section.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Input/hide_details.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Input/hide_details.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Input/hide_details.vue
+
+Hint
+^^^^
+
+:py:class:`Input ` can have hint which can tell user how to
+use the input. ``persistent-hint`` prop makes the hint visible always if no
+messages are displayed.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Input/hint.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Input/hint.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Input/hint.vue
+
+Loading
+^^^^^^^
+
+:py:class:`Input ` has loading state which can be used, e.g.
+for data loading indication. Note: :py:class:`TextField `
+is used just for example.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Input/loading.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Input/loading.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Input/loading.vue
+
+Rules
+^^^^^
+
+You can add custom validation rules to :py:class:`Input `,
+add them as functions returning ``true``/error message. Note:
+:py:class:`TextField ` is used just for example.
+
+.. todo::
+
+ We need to better understand how to set customized rules in ipyvuetify.
+ help welcomed :fas:`coffee`
+
+Success
+^^^^^^^
+
+As any validatable Vuetify component, :py:class:`Input ` can
+be set to success state using ``success`` prop, you can add message to it using
+``success-messages`` prop.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Input/success.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Input/success.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Input/success.vue
+
+Append and prepend
+^^^^^^^^^^^^^^^^^^
+
+:py:class:`Input ` has ``append`` and ``prepend`` slots. You
+can place custom icons in them.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: Input/append_and_prepend.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: Input/append_and_prepend.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: Input/append_and_prepend.vue
+
diff --git a/docs/component/Input/append_and_prepend.py b/docs/component/Input/append_and_prepend.py
new file mode 100644
index 00000000..694b7b6f
--- /dev/null
+++ b/docs/component/Input/append_and_prepend.py
@@ -0,0 +1,26 @@
+import ipyvuetify as v
+
+v.TextField(
+ v_slots=[
+ {
+ "name": "append",
+ "children": [
+ v.Icon(
+ children=["mdi-plus"],
+ slot="append",
+ color="red",
+ ),
+ ],
+ },
+ {
+ "name": "prepend",
+ "children": [
+ v.Icon(
+ children=["mdi-minus"],
+ slot="prepend",
+ color="green",
+ )
+ ],
+ },
+ ],
+)
diff --git a/docs/component/Input/append_and_prepend.vue b/docs/component/Input/append_and_prepend.vue
new file mode 100644
index 00000000..b36fc40b
--- /dev/null
+++ b/docs/component/Input/append_and_prepend.vue
@@ -0,0 +1,6 @@
+
+
+ mdi-plus
+ mdi-minus
+
+
diff --git a/docs/component/Input/error_count.py b/docs/component/Input/error_count.py
new file mode 100644
index 00000000..00c7221f
--- /dev/null
+++ b/docs/component/Input/error_count.py
@@ -0,0 +1,9 @@
+import ipyvuetify as v
+
+v.Input(
+ error_count=2,
+ error_messages=["Fatal error", "Another error"],
+ error=True,
+ disabled=True,
+ children=["Input"],
+)
diff --git a/docs/component/Input/error_count.vue b/docs/component/Input/error_count.vue
new file mode 100644
index 00000000..1dfbabc5
--- /dev/null
+++ b/docs/component/Input/error_count.vue
@@ -0,0 +1,10 @@
+
+
+ Input
+
+
diff --git a/docs/component/Input/hide_details.py b/docs/component/Input/hide_details.py
new file mode 100644
index 00000000..74ab999c
--- /dev/null
+++ b/docs/component/Input/hide_details.py
@@ -0,0 +1,12 @@
+import ipyvuetify as v
+
+v.Html(
+ tag="div",
+ children=[
+ v.TextField(
+ label="Main input",
+ hide_details="auto",
+ ),
+ v.TextField(label="Another input"),
+ ],
+)
diff --git a/docs/component/Input/hide_details.vue b/docs/component/Input/hide_details.vue
new file mode 100644
index 00000000..9baf431c
--- /dev/null
+++ b/docs/component/Input/hide_details.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/docs/component/Input/hint.py b/docs/component/Input/hint.py
new file mode 100644
index 00000000..fcc9b181
--- /dev/null
+++ b/docs/component/Input/hint.py
@@ -0,0 +1,16 @@
+from ipywidgets import jslink
+
+import ipyvuetify as v
+
+message = v.Select(
+ v_model=[],
+ items=["message"],
+ label="Message",
+ multiple=True,
+ clearable=True,
+)
+input_field = v.Input(hint="I am hint", persistent_hint=True, messages=[], children=["Input"])
+
+jslink((message, "v_model"), (input_field, "messages"))
+
+v.Container(children=[message, input_field])
diff --git a/docs/component/Input/hint.vue b/docs/component/Input/hint.vue
new file mode 100644
index 00000000..630d2ae3
--- /dev/null
+++ b/docs/component/Input/hint.vue
@@ -0,0 +1,8 @@
+
+
+
+
+ Input
+
+
+
diff --git a/docs/component/Input/loading.py b/docs/component/Input/loading.py
new file mode 100644
index 00000000..8e5dc1b0
--- /dev/null
+++ b/docs/component/Input/loading.py
@@ -0,0 +1,7 @@
+import ipyvuetify as v
+
+v.TextField(
+ color="success",
+ loading=True,
+ disabled=True,
+)
diff --git a/docs/component/Input/loading.vue b/docs/component/Input/loading.vue
new file mode 100644
index 00000000..79e47acc
--- /dev/null
+++ b/docs/component/Input/loading.vue
@@ -0,0 +1,3 @@
+
+
+
diff --git a/docs/component/Input/success.py b/docs/component/Input/success.py
new file mode 100644
index 00000000..5f3d8d3d
--- /dev/null
+++ b/docs/component/Input/success.py
@@ -0,0 +1,3 @@
+import ipyvuetify as v
+
+v.Input(success_messages=["Success"], success=True, disabled=True, children=["Input"])
diff --git a/docs/component/Input/success.vue b/docs/component/Input/success.vue
new file mode 100644
index 00000000..66f95e78
--- /dev/null
+++ b/docs/component/Input/success.vue
@@ -0,0 +1,3 @@
+
+ Input
+
diff --git a/docs/component/Input/usage.py b/docs/component/Input/usage.py
new file mode 100644
index 00000000..d8631b2a
--- /dev/null
+++ b/docs/component/Input/usage.py
@@ -0,0 +1,23 @@
+import ipyvuetify as v
+
+v.Container(
+ id="input-usage",
+ fluid=True,
+ children=[
+ v.Row(
+ children=[
+ v.Col(
+ cols=12,
+ children=[
+ v.Input(
+ messages=["Messages"],
+ append_icon="mdi-close",
+ prepend_icon="mdi-phone",
+ children=["Default Slot"],
+ )
+ ],
+ )
+ ]
+ )
+ ],
+)
diff --git a/docs/component/ItemGroup.rst b/docs/component/ItemGroup.rst
new file mode 100644
index 00000000..a7a965ae
--- /dev/null
+++ b/docs/component/ItemGroup.rst
@@ -0,0 +1,82 @@
+ItemGroup
+=========
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Item groups
+ documentation `__.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`ItemGroup ` provides the ability to create
+a group of selectable items out of any component. This is the baseline
+functionality for components such as :py:class:`Tabs ` and
+:py:class:`Carousel `.
+
+.. api::
+
+ - :py:class:`ipyvuetify.ItemGroup`
+ - :py:class:`ipyvuetify.Item`
+
+Usage
+-----
+
+The core usage of the :py:class:`ItemGroup ` is to create
+groups of anything that should be controlled by a model.
+
+.. todo::
+
+ The itemGroup object rely on the use of the @click event and trigger it with a slo variable
+ called item. It's not possible with the current implementation of ipyvuetify.
+
+Examples
+--------
+
+Active class
+^^^^^^^^^^^^
+
+The ``active-class`` property allows you to set custom CSS class on active
+items.
+
+.. todo::
+
+ The itemGroup object rely on the use of the @click event and trigger it with a slo variable
+ called item. It's not possible with the current implementation of ipyvuetify.
+
+Mandatory
+^^^^^^^^^
+
+``mandatory`` item groups must have at least 1 item selected.
+
+.. todo::
+
+ The itemGroup object rely on the use of the @click event and trigger it with a slo variable
+ called item. It's not possible with the current implementation of ipyvuetify.
+
+Multiple
+^^^^^^^^
+
+Item groups can have multiple items selected.
+
+.. todo::
+
+ The itemGroup object rely on the use of the @click event and trigger it with a slo variable
+ called item. It's not possible with the current implementation of ipyvuetify.
+Chips
+^^^^^
+
+Easily hook up a custom chip group.
+
+.. todo::
+
+ The itemGroup object rely on the use of the @click event and trigger it with a slo variable
+ called item. It's not possible with the current implementation of ipyvuetify.
+
+Selection
+^^^^^^^^^
+
+Icons can be used as toggle buttons when they allow selection, or deselection,
+of a single choice, such as marking an item as a favorite.
+
+.. todo::
+
+ The itemGroup object rely on the use of the @click event and trigger it with a slo variable
+ called item. It's not possible with the current implementation of ipyvuetify.
diff --git a/docs/component/Lazy.rst b/docs/component/Lazy.rst
new file mode 100644
index 00000000..90d17a31
--- /dev/null
+++ b/docs/component/Lazy.rst
@@ -0,0 +1,34 @@
+Lazy
+====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Lazy documentation
+ `__.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`Lazy ` component is used to dynamically load
+components based upon an elements visibility.
+
+.. api::
+
+ :py:class:`ipyvuetify.Lazy`
+
+Usage
+-----
+
+The :py:class:`Lazy ` component by default will not render its
+contents until it has been intersected. Scroll down and watch the element render
+as you go past it.
+
+.. todo::
+
+ very complex implementation that cannot be rendered in a static documetnation.
+
+Caveats
+-------
+
+The :py:class:`Lazy ` component uses the `v-intersect
+`__ directive which requires
+a `Polyfill `__ in
+order to work on IE11 / Safari. It's possible on some iOS versions will also
+require the use of this polyfill.
diff --git a/docs/component/List.rst b/docs/component/List.rst
new file mode 100644
index 00000000..3162c4a8
--- /dev/null
+++ b/docs/component/List.rst
@@ -0,0 +1,400 @@
+List
+====
+
+.. aknowledgement::
+ This page is a Python adaptation of the `official Vuetify Lists documentation
+ `__.
+ All examples have been converted to ipyvuetify syntax.
+
+The :py:class:`List ` component is used to display information.
+It can contain an avatar, content, actions, subheaders and much more. Lists
+present content in a way that makes it easy to identify a specific item in a
+collection. They provide a consistent styling for organizing groups of text and
+images.
+
+.. api::
+
+ - :py:class:`ipyvuetify.List`
+ - :py:class:`ipyvuetify.ListGroup`
+ - :py:class:`ipyvuetify.ListItem`
+ - :py:class:`ipyvuetify.ListItemAction`
+ - :py:class:`ipyvuetify.ListItemActionText`
+ - :py:class:`ipyvuetify.ListItemAvatar`
+ - :py:class:`ipyvuetify.ListItemContent`
+ - :py:class:`ipyvuetify.ListItemGroup`
+ - :py:class:`ipyvuetify.ListItemIcon`
+ - :py:class:`ipyvuetify.ListItemSubtitle`
+ - :py:class:`ipyvuetify.ListItemTitle`
+
+Usage
+-----
+
+Lists come in three main variations. single-line (default), two-line and
+three-line. The line declaration specifies the minimum height of the item and
+can also be controlled from :py:class:`List ` with the same
+prop.
+
+.. jupyter-execute:: List/usage.py
+ :raises:
+
+.. note::
+
+ If you are looking for stateful list items, please check out
+ :py:class:`ListItemGroup `.
+
+Examples
+--------
+
+Dense
+^^^^^
+
+:py:class:`List ` can be lowered with ``dense`` property.
+
+.. tab-set::
+
+ .. tab-item:: :fas:`eye` Rendered
+
+ .. jupyter-execute:: List/dense.py
+ :raises:
+ :hide-code:
+
+ .. tab-item:: :fab:`python` Python
+
+ .. literalinclude:: List/dense.py
+
+ .. tab-item:: :fab:`vuejs` Vue template
+
+ .. literalinclude:: List/dense.vue
+
+Disabled
+^^^^^^^^
+
+You cannot interact with disabled :py:class:`List