Skip to content

Commit

Permalink
Merge pull request #39 from kkinder/add-typeahead-example
Browse files Browse the repository at this point in the history
Add experimental typeahead example
  • Loading branch information
kkinder authored Aug 3, 2024
2 parents d13b7c4 + 32c492e commit d048cc8
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ <h1>Integrations</h1>
<li><a href="integrations/11_micropython_datetimes/index.html">Datetimes in MicroPython</a></li>
<li><a href="integrations/12_ltk/index.html">Using LTK and PuePy</a></li>
<li><a href="integrations/13_jinja/index.html">Using Jinja2 and PuePy</a></li>
<li><a href="integrations/14_shoelace_autocomplete/index.html">Auto-Complete with Shoelace.style</a></li>
</ul>
</body>
</html>
18 changes: 18 additions & 0 deletions examples/integrations/14_shoelace_autocomplete/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>PuePy Type Ahead</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="https://pyscript.net/releases/2024.8.1/core.css">
<script type="module" src="https://pyscript.net/releases/2024.8.1/core.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.15.1/cdn/themes/light.css"/>
<script type="module"
src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.15.1/cdn/shoelace-autoloader.js"></script>

</head>
<body>
<div id="app">Loading...</div>
<script type="mpy" src="./typeahead.py" config="../../pyscript.json"></script>
</body>
</html>
89 changes: 89 additions & 0 deletions examples/integrations/14_shoelace_autocomplete/typeahead.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from puepy import Component, Page, Application, t
from puepy.runtime import next_tick

app = Application()


@t.component()
class TypeAhead(Component):
props = ["choices", "value", "placeholder"]

def initial(self):
return dict(
input_value=self.value or "",
)

def populate(self):
with t.sl_popup(ref="popup", placement="bottom", on_focusout=self.on_focusout, sync="width"):
t.sl_input(
slot="anchor",
bind="input_value",
placeholder=self.placeholder or "",
on_sl_focus=self.on_focus,
ref="input",
autocomplete="off",
clearable=True,
)
with t.sl_menu(on_sl_select=self.on_menu_select):
for choice in self.get_available_choices():
t.sl_menu_item(choice, value=choice)

def on_focusout(self, event):
if not self.refs["popup"].element.contains(event.relatedTarget):
self.close_popup()

def on_focus(self, event):
self.open_popup()

def on_clear(self, event):
self.state["input_value"] = ""
self.send_bind_event()

def on_menu_select(self, event):
self.state["input_value"] = event.detail.item.value
self.send_bind_event()
next_tick(self.close_popup)

def close_popup(self):
self.refs["popup"].element.active = False

def open_popup(self):
self.refs["popup"].element.active = True

def send_bind_event(self):
if self.bind:
self.origin.state[self.bind] = self.state["input_value"]

def get_available_choices(self):
input_value = self.state["input_value"]
if input_value:
return [item for item in self.choices if input_value in item]
else:
return self.choices


@app.page()
class TypeAheadPage(Page):
def initial(self):
return {"cheese": None}

def populate(self):
t.h1("Typeahead/autocomplete demo")
t.type_ahead(
ref="select_cheese",
bind="cheese",
placeholder="What is your favorite type of cheese?",
choices=[
"cheddar cheese",
"gouda",
"brie",
"swiss",
"gorgonzola",
"feta",
"mozzarella",
],
)
t.p(f"You selected: {self.state['cheese'] or 'nothing yet'}")


app.mount("#app")

0 comments on commit d048cc8

Please sign in to comment.