Thinking in Aurora Aurora redefines UI development, adopting a component-based approach. Break designs into components, define states, and behaviors, then seamlessly connect components for data flow. Create intuitive in
Step 1: Define the JSON API and Mockup
Assuming we have a JSON API returning product data like this:
Copy jsonCopy code[
{ "category" : "Fruits" , "price" : "$1" , "stocked" : true , "name" : "Apple" } ,
{ "category" : "Fruits" , "price" : "$1" , "stocked" : true , "name" : "Dragonfruit" } ,
{ "category" : "Fruits" , "price" : "$2" , "stocked" : false , "name" : "Passionfruit" } ,
{ "category" : "Vegetables" , "price" : "$2" , "stocked" : true , "name" : "Spinach" } ,
{ "category" : "Vegetables" , "price" : "$4" , "stocked" : false , "name" : "Pumpkin" } ,
{ "category" : "Vegetables" , "price" : "$1" , "stocked" : true , "name" : "Peas" }
]
And a mockup representing the UI:
[Mockup Image]
Step 2: Break Down the UI into Components
We'll identify the following components based on the mockup:
FilterableProductTable
: Main container for the app.
SearchBar
: Component to receive user input for searching.
ProductTable
: Component to display and filter the product list.
ProductCategoryRow
: Component to display category headings.
ProductRow
: Component to display individual product rows.
Step 3: Build a Static Version
We'll start by building a static version of the app without interactivity. We'll focus on reusability and passing data through props.
Copy pythonCopy code # Define ProductCategoryRow component
component ProductCategoryRow :
def __init__ ( self , category ):
self . category = category
def render ( self ):
return f "<tr><th colspan='2'> { self . category } </th></tr>"
# Define ProductRow component
component ProductRow :
def __init__ ( self , product ):
self . product = product
def render ( self ):
name = f"<span style='color: red'>{self.product['name']}</span>" if not self.product['stocked'] else self.product['name']
return f "<tr><td> { name } </td><td> { self . product [ 'price' ] } </td></tr>"
# Define ProductTable component
component ProductTable :
def __init__ ( self , products ):
self . products = products
def render ( self ):
rows = []
last_category = None
for product in self . products :
if product [ 'category' ] != last_category :
rows . append ( ProductCategoryRow (product[ 'category' ]). render ())
last_category = product [ 'category' ]
rows . append ( ProductRow (product). render ())
return "<table>" + "" . join (rows) + "</table>"
# Define FilterableProductTable component
component FilterableProductTable :
def __init__ ( self , products ):
self . products = products
def render ( self ):
return f "<div><SearchBar/><ProductTable products= { self . products } /></div>"
Step 4: Manage State
Identify the minimal but complete representation of UI state. In this case, it includes the search text and the value of the checkbox.
Copy pythonCopy code # Define FilterableProductTable component with state
component FilterableProductTable :
def __init__ ( self , products ):
self . products = products
self . state = {
'filterText' : '' ,
'inStockOnly' : False
}
def render ( self ):
return f """
<div>
<SearchBar
filterText= { self . state [ 'filterText' ] }
inStockOnly= { self . state [ 'inStockOnly' ] }
onFilterTextChange= { self . handleFilterTextChange }
onInStockOnlyChange= { self . handleInStockOnlyChange }
/>
<ProductTable
products= { self . products }
filterText= { self . state [ 'filterText' ] }
inStockOnly= { self . state [ 'inStockOnly' ] }
/>
</div>
"""
# Define event handlers for updating state
def handleFilterTextChange ( self , new_filter_text ):
self . state [ 'filterText' ] = new_filter_text
def handleInStockOnlyChange ( self , new_value ):
self . state [ 'inStockOnly' ] = new_value
Step 5: Add Interactivity
Now, add inverse data flow to update the state based on user input.
Copy pythonCopy code # Define SearchBar component
component SearchBar :
def __init__ ( self , filterText = '' , inStockOnly = False , onFilterTextChange = None , onInStockOnlyChange = None ):
self . filterText = filterText
self . inStockOnly = inStockOnly
self . onFilterTextChange = onFilterTextChange
self . onInStockOnlyChange = onInStockOnlyChange
def render ( self ):
return f """
<form>
<input
type='text'
value=' { self . filterText } '
placeholder='Search...'
onchange=' { self . handleFilterTextChange } '
/>
<label>
<input
type='checkbox'
checked=' { self . inStockOnly } '
onchange=' { self . handleInStockOnlyChange } '
/>
Only show products in stock
</label>
</form>
"""
# Define event handlers for updating state
def handleFilterTextChange ( self , event ):
self . onFilterTextChange (event.target.value)
def handleInStockOnlyChange ( self , event ):
self . onInStockOnlyChange (event.target.checked)
Now, you have a fully functional searchable product data table in Aurora! You can further enhance this implementation with styling and additional features as needed. Happy coding! 🚀
Last updated 9 months ago