Skip to content

Commit

Permalink
manipulating props through looks
Browse files Browse the repository at this point in the history
  • Loading branch information
rodja committed Feb 4, 2023
1 parent 4dee595 commit a3b3f48
Show file tree
Hide file tree
Showing 38 changed files with 144 additions and 115 deletions.
2 changes: 1 addition & 1 deletion examples/custom_vue_component/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Counter(Element):

def __init__(self, title: str, *, on_change: Optional[Callable] = None) -> None:
super().__init__('counter')
self._props['title'] = title
self.looks._props['title'] = title
self.on('change', on_change)

def reset(self) -> None:
Expand Down
6 changes: 3 additions & 3 deletions looks_demo.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
from nicegui import Looks, ui
from nicegui import ButtonLooks, Looks, ui

shared = Looks().width.full().background.secondary()

Expand All @@ -8,11 +8,11 @@
with ui.card():
ui.label(str(i))

button_looks = Looks().background.teal(0.9)
button_looks = ButtonLooks().rounded().background.teal(0.9)
hover = Looks().text.gray(0.6)

with ui.row().looks.add(shared).height.fixed.twenty().background.grey(0.4).align.main_axis.evenly().align.cross_axis.center().element:
ui.button('12').looks.width.fixed.twelve().add(button_looks)
ui.button('12').looks.square().width.fixed.twelve().add(button_looks)
ui.button('64').looks.width.fixed.sixty_four().add(button_looks).height.fractional.two_thirds()
ui.button('1/6').looks.width.fractional.one_sixth().add(button_looks).on_hover(hover)

Expand Down
2 changes: 1 addition & 1 deletion nicegui/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from . import elements, globals, ui
from .client import Client
from .looks import Looks
from .looks import ButtonLooks, Looks
from .nicegui import app
11 changes: 5 additions & 6 deletions nicegui/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def __init__(self, tag: str, *, _client: Optional[Client] = None) -> None:
self.tag = tag
self.looks = Looks(self)
self._style: Dict[str, str] = {}
self._props: Dict[str, Any] = {}
self._event_listeners: List[EventListener] = []
self._text: str = ''
self.slots: Dict[str, Slot] = {}
Expand Down Expand Up @@ -72,7 +71,7 @@ def to_dict(self) -> Dict:
'tag': self.tag,
'class': self.looks.classes,
'style': self._style,
'props': self._props,
'props': self.looks._props,
'events': events,
'text': self._text,
'slots': {name: [child.id for child in slot.children] for name, slot in self.slots.items()},
Expand Down Expand Up @@ -138,13 +137,13 @@ def props(self, add: Optional[str] = None, *, remove: Optional[str] = None):
'''
needs_update = False
for key in self._parse_props(remove):
if key in self._props:
if key in self.looks._props:
needs_update = True
del self._props[key]
del self.looks._props[key]
for key, value in self._parse_props(add).items():
if self._props.get(key) != value:
if self.looks._props.get(key) != value:
needs_update = True
self._props[key] = value
self.looks._props[key] = value
if needs_update:
self.update()
return self
Expand Down
10 changes: 5 additions & 5 deletions nicegui/elements/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def __init__(self, src: str, *,
for a list of events you can subscribe to using the generic event subscription `on()`.
"""
super().__init__('audio')
self._props['src'] = src
self._props['type'] = type
self._props['controls'] = controls
self._props['autoplay'] = autoplay
self._props['muted'] = muted
self.looks._props['src'] = src
self.looks._props['type'] = type
self.looks._props['controls'] = controls
self.looks._props['autoplay'] = autoplay
self.looks._props['muted'] = muted
6 changes: 3 additions & 3 deletions nicegui/elements/badge.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ def __init__(self, text: str = '', *,
:param outline: use 'outline' design (colored text and borders only) (default: False)
"""
super().__init__(tag='q-badge', text=text)
self._props['color'] = color
self._props['text_color'] = text_color
self._props['outline'] = outline
self.looks._props['color'] = color
self.looks._props['text_color'] = text_color
self.looks._props['outline'] = outline
9 changes: 7 additions & 2 deletions nicegui/elements/button.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Callable, Optional

from ..events import ClickEventArguments, handle_event
from ..looks import ButtonLooks
from .mixins.text_element import TextElement


Expand All @@ -13,9 +14,13 @@ def __init__(self, text: str = '', *, on_click: Optional[Callable] = None) -> No
:param on_click: callback which is invoked when button is pressed
"""
super().__init__(tag='q-btn', text=text)
self._props['color'] = 'primary'
orig = self.looks
self.looks = ButtonLooks(self)
self.looks.classes = orig.classes
self.looks._props = orig._props
self.looks._props['color'] = 'primary'

self.on('click', lambda _: handle_event(on_click, ClickEventArguments(sender=self, client=self.client)))

def _text_to_model_text(self, text: str) -> None:
self._props['label'] = text
self.looks._props['label'] = text
8 changes: 4 additions & 4 deletions nicegui/elements/chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,17 @@ def __init__(self, options: Dict, *, type: str = 'chart', extras: List[str] = []
:param extras: list of extra dependencies to include (e.g. "annotations", "arc-diagram", "solid-gauge", ...)
"""
super().__init__('chart')
self._props['type'] = type
self._props['options'] = options
self._props['extras'] = [
self.looks._props['type'] = type
self.looks._props['options'] = options
self.looks._props['extras'] = [
dependency.import_path
for dependency in js_dependencies.values()
if dependency.optional and dependency.path.stem in extras and 'chart' in dependency.dependents
]

@property
def options(self) -> Dict:
return self._props['options']
return self.looks._props['options']

def update(self) -> None:
super().update()
Expand Down
2 changes: 1 addition & 1 deletion nicegui/elements/choice_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def _update_values_and_labels(self) -> None:
self._labels = self.options if isinstance(self.options, list) else list(self.options.values())

def _update_options(self) -> None:
self._props['options'] = [{'value': index, 'label': option} for index, option in enumerate(self._labels)]
self.looks._props['options'] = [{'value': index, 'label': option} for index, option in enumerate(self._labels)]

def update(self) -> None:
self._update_values_and_labels()
Expand Down
4 changes: 2 additions & 2 deletions nicegui/elements/color_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ def __init__(self, label: Optional[str] = None, *,
"""
super().__init__(tag='q-input', value=value, on_value_change=on_change)
if label is not None:
self._props['label'] = label
self.looks._props['label'] = label
if placeholder is not None:
self._props['placeholder'] = placeholder
self.looks._props['placeholder'] = placeholder

with self.add_slot('append'):
self.picker = ColorPicker(on_pick=lambda e: self.set_value(e.color))
Expand Down
14 changes: 7 additions & 7 deletions nicegui/elements/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ def __init__(self, *,
Sets the main colors (primary, secondary, accent, ...) used by `Quasar <https://quasar.dev/>`_.
"""
super().__init__('colors')
self._props['primary'] = primary
self._props['secondary'] = secondary
self._props['accent'] = accent
self._props['positive'] = positive
self._props['negative'] = negative
self._props['info'] = info
self._props['warning'] = warning
self.looks._props['primary'] = primary
self.looks._props['secondary'] = secondary
self.looks._props['accent'] = accent
self.looks._props['positive'] = positive
self.looks._props['negative'] = negative
self.looks._props['info'] = info
self.looks._props['warning'] = warning
self.update()
2 changes: 1 addition & 1 deletion nicegui/elements/date.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ def __init__(self,
:param on_change: callback to execute when changing the date
"""
super().__init__(tag='q-date', value=value, on_value_change=on_change)
self._props['mask'] = mask
self.looks._props['mask'] = mask
4 changes: 2 additions & 2 deletions nicegui/elements/expansion.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ def __init__(self, text: str, *, icon: Optional[str] = None, value: bool = False
:param value: whether the expansion should be opened on creation (default: `False`)
'''
super().__init__(tag='q-expansion-item', value=value, on_value_change=None)
self._props['label'] = text
self._props['icon'] = icon
self.looks._props['label'] = text
self.looks._props['icon'] = icon

def open(self) -> None:
self.value = True
Expand Down
2 changes: 1 addition & 1 deletion nicegui/elements/icon.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ def __init__(self, name: str) -> None:
:param name: the name of the icon
"""
super().__init__('q-icon')
self._props['name'] = name
self.looks._props['name'] = name
8 changes: 4 additions & 4 deletions nicegui/elements/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ def __init__(self,
"""
super().__init__(tag='q-input', value=value, on_value_change=on_change)
if label is not None:
self._props['label'] = label
self.looks._props['label'] = label
if placeholder is not None:
self._props['placeholder'] = placeholder
self._props['type'] = 'password' if password else 'text'
self.looks._props['placeholder'] = placeholder
self.looks._props['type'] = 'password' if password else 'text'

if password_toggle_button:
with self.add_slot('append'):
def toggle_type(_):
is_hidden = self._props.get('type') == 'password'
is_hidden = self.looks._props.get('type') == 'password'
icon.props(f'name={"visibility" if is_hidden else "visibility_off"}')
self.props(f'type={"text" if is_hidden else "password"}')
icon = Icon('visibility_off').classes('cursor-pointer').on('click', toggle_type)
4 changes: 2 additions & 2 deletions nicegui/elements/interactive_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ def __init__(self, source: str = '', *,
:param cross: whether to show crosshairs (default: `False`)
"""
super().__init__(tag='interactive_image', source=source, content=content)
self._props['events'] = events
self._props['cross'] = cross
self.looks._props['events'] = events
self.looks._props['cross'] = cross

def handle_mouse(msg: Dict) -> None:
if on_mouse is None:
Expand Down
2 changes: 1 addition & 1 deletion nicegui/elements/joystick.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ def __init__(self, *,
lambda _: handle_event(on_end, JoystickEventArguments(sender=self,
client=self.client,
action='end')))
self._props['options'] = options
self.looks._props['options'] = options
4 changes: 2 additions & 2 deletions nicegui/elements/keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ def __init__(self, on_key: Callable, *, active: bool = True, repeating: bool = T
super().__init__('keyboard')
self.key_handler = on_key
self.active = active
self._props['events'] = ['keydown', 'keyup']
self._props['repeating'] = repeating
self.looks._props['events'] = ['keydown', 'keyup']
self.looks._props['repeating'] = repeating
self.style('display: none')
self.on('key', self.handle_key)

Expand Down
6 changes: 3 additions & 3 deletions nicegui/elements/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def __init__(self, text: str = '', target: Union[Callable, str] = '#', new_tab:
:param new_tab: open link in new tab (default: False)
"""
super().__init__(tag='a', text=text)
self._props['href'] = target if isinstance(target, str) else globals.page_routes[target]
self._props['target'] = '_blank' if new_tab else '_self'
self.looks._props['href'] = target if isinstance(target, str) else globals.page_routes[target]
self.looks._props['target'] = '_blank' if new_tab else '_self'
self.looks.classes.extend(['underline', 'text-blue-500'])


Expand All @@ -35,4 +35,4 @@ def __init__(self, name: str) -> None:
:param name: target name
"""
super().__init__('a')
self._props['name'] = name
self.looks._props['name'] = name
6 changes: 3 additions & 3 deletions nicegui/elements/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ def __init__(self, max_lines: Optional[int] = None) -> None:
:param max_lines: maximum number of lines before dropping oldest ones (default: `None`)
"""
super().__init__('log')
self._props['max_lines'] = max_lines
self._props['lines'] = ''
self.looks._props['max_lines'] = max_lines
self.looks._props['lines'] = ''
self.classes('border whitespace-pre font-mono')
self.style('opacity: 1 !important; cursor: text !important')
self.lines: deque[str] = deque(maxlen=max_lines)

def push(self, line: str) -> None:
self.lines.extend(line.splitlines())
self._props['lines'] = '\n'.join(self.lines)
self.looks._props['lines'] = '\n'.join(self.lines)
self.run_method('push', line)
4 changes: 2 additions & 2 deletions nicegui/elements/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ def __init__(self, content: str = '', *, extras: List[str] = ['fenced-code-block

def on_content_change(self, content: str) -> None:
html = prepare_content(content, extras=' '.join(self.extras))
if self._props.get('innerHTML') != html:
self._props['innerHTML'] = html
if self.looks._props.get('innerHTML') != html:
self.looks._props['innerHTML'] = html
self.update()


Expand Down
4 changes: 2 additions & 2 deletions nicegui/elements/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def __init__(self, *, value: bool = False) -> None:
:param value: whether the menu is already opened (default: `False`)
"""
super().__init__(tag='q-menu', value=value, on_value_change=None)
self._props['no-parent-event'] = True
self.looks._props['no-parent-event'] = True

def open(self) -> None:
self.value = True
Expand All @@ -38,7 +38,7 @@ def __init__(self, text: str = '', on_click: Optional[Callable] = None, *, auto_
"""
super().__init__(tag='q-item', text=text)
self.menu = globals.get_slot().parent
self._props['clickable'] = True
self.looks._props['clickable'] = True

def handle_click(_) -> None:
handle_event(on_click, ClickEventArguments(sender=self, client=self.client))
Expand Down
2 changes: 1 addition & 1 deletion nicegui/elements/mixins/content_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ def set_content(self, content: str) -> None:
def on_content_change(self, content: str) -> None:
if self.CONTENT_PROP == 'innerHTML' and '</script>' in content:
raise ValueError('HTML elements must not contain <script> tags. Use ui.add_body_html() instead.')
self._props[self.CONTENT_PROP] = content
self.looks._props[self.CONTENT_PROP] = content
self.update()
4 changes: 2 additions & 2 deletions nicegui/elements/mixins/source_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class SourceElement(Element):
def __init__(self, *, source: str, **kwargs) -> None:
super().__init__(**kwargs)
self.source = source
self._props['src'] = source
self.looks._props['src'] = source

def bind_source_to(self, target_object: Any, target_name: str = 'source', forward: Callable = lambda x: x):
bind_to(self, 'source', target_object, target_name, forward)
Expand All @@ -29,5 +29,5 @@ def set_source(self, source: str) -> None:
self.source = source

def on_source_change(self, source: str) -> None:
self._props['src'] = source
self.looks._props['src'] = source
self.update()
6 changes: 3 additions & 3 deletions nicegui/elements/mixins/value_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class ValueElement(Element):
def __init__(self, *, value: Any, on_value_change: Optional[Callable], throttle: float = 0, **kwargs) -> None:
super().__init__(**kwargs)
self.set_value(value)
self._props[self.VALUE_PROP] = self._value_to_model_value(value)
self._props['loopback'] = self.LOOPBACK
self.looks._props[self.VALUE_PROP] = self._value_to_model_value(value)
self.looks._props['loopback'] = self.LOOPBACK
self._send_update_on_value_change = True
self.change_handler = on_value_change

Expand All @@ -42,7 +42,7 @@ def set_value(self, value: Any) -> None:
self.value = value

def on_value_change(self, value: Any) -> None:
self._props[self.VALUE_PROP] = self._value_to_model_value(value)
self.looks._props[self.VALUE_PROP] = self._value_to_model_value(value)
if self._send_update_on_value_change:
self.update()
args = ValueChangeEventArguments(sender=self, client=self.client, value=self._value_to_event_value(value))
Expand Down
6 changes: 3 additions & 3 deletions nicegui/elements/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ def __init__(self,
"""
self.format = format
super().__init__(tag='q-input', value=value, on_value_change=on_change)
self._props['type'] = 'number'
self.looks._props['type'] = 'number'
if label is not None:
self._props['label'] = label
self.looks._props['label'] = label
if placeholder is not None:
self._props['placeholder'] = placeholder
self.looks._props['placeholder'] = placeholder

def _msg_to_value(self, msg: Dict) -> Any:
return float(msg['args']) if msg['args'] else None
Expand Down
2 changes: 1 addition & 1 deletion nicegui/elements/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def __init__(self, *, close: bool = True, **kwargs) -> None:
def _convert_to_html(self) -> None:
with io.StringIO() as output:
self.fig.savefig(output, format='svg')
self._props['innerHTML'] = output.getvalue()
self.looks._props['innerHTML'] = output.getvalue()

def __enter__(self):
plt.figure(self.fig)
Expand Down
Loading

0 comments on commit a3b3f48

Please sign in to comment.