Example Applications
opal-vite includes several example applications that demonstrate different Stimulus API features.
Counter App
A simple counter application demonstrating the Stimulus Values API.
Features demonstrated:
stimulus_value(:name)- Get a valueset_stimulus_value(:name, value)- Set a valueincrement_stimulus_value(:name)- Increment a numeric valuedecrement_stimulus_value(:name)- Decrement a numeric value- Value change callbacks (
count_value_changed)
Location: examples/counter-app/
class CounterController < StimulusController
include OpalVite::Concerns::V1::StimulusHelpers
self.values = { count: :number }
self.targets = ["display"]
def connect
update_display
end
def increment
increment_stimulus_value(:count)
end
def decrement
decrement_stimulus_value(:count)
end
def reset
set_stimulus_value(:count, 0)
end
def count_value_changed
update_display
end
private
def update_display
target_set_text(:display, stimulus_value(:count).to_s)
end
endRun locally:
cd examples/counter-app
bundle install
pnpm install
pnpm devCRUD App
A CRUD (Create, Read, Update, Delete) application demonstrating Stimulus Action Parameters.
Features demonstrated:
action_param(:name)- Get action parameteraction_param_int(:id)- Get integer parameterhas_action_param?(:name)- Check if parameter existsdata-[controller]-[name]-paramHTML attribute syntax- Modal dialogs with event communication
Location: examples/crud-app/
class ListController < StimulusController
include OpalVite::Concerns::V1::StimulusHelpers
self.targets = ["container", "template", "nameInput"]
self.values = { items: :array }
def edit
# Get parameters from data-list-id-param, data-list-name-param attributes
id = action_param_int(:id)
name = action_param(:name)
quantity = action_param_int(:quantity, 1) if has_action_param?(:quantity)
dispatch_window_event('open-modal', { id: id, name: name, quantity: quantity })
end
def delete
id = action_param_int(:id)
# ... delete logic
end
endHTML with action parameters:
<button data-action="click->list#edit"
data-list-id-param="123"
data-list-name-param="Item Name"
data-list-quantity-param="5">
Edit
</button>Run locally:
cd examples/crud-app
bundle install
pnpm install
pnpm devTabs App
A tabbed interface demonstrating Stimulus Outlets and Dispatch.
Features demonstrated:
- Outlet connections (
self.outlets = ["panel"]) has_outlet?(:name)- Check outlet existencecall_outlet(:name, :method)- Call method on outletcall_all_outlets(:name, :method)- Call method on all outletsdispatch_window_event(name, detail)- Dispatch custom eventson_window_event(name)- Listen to window events
Location: examples/tabs-app/
# Tabs Controller
class TabsController < StimulusController
include OpalVite::Concerns::V1::StimulusHelpers
self.targets = ["tab"]
self.outlets = ["panel"]
def select
index = action_param_int(:index)
activate_tab(index)
show_panel_by_index(index)
end
private
def show_panel_by_index(index)
# Hide all panels via outlets
call_all_outlets(:panel, :hide) if has_outlet?(:panel)
# Dispatch event for panels to show
dispatch_window_event('tabs:change', { index: index })
end
end
# Panel Controller
class PanelController < StimulusController
include OpalVite::Concerns::V1::StimulusHelpers
def connect
on_window_event('tabs:change') do |event|
detail = `#{event}.detail`
index = `#{detail}.index`
my_index = action_param_int(:index)
index == my_index ? show : hide
end
end
def show
element_remove_class('panel-hidden')
end
def hide
element_add_class('panel-hidden')
end
endRun locally:
cd examples/tabs-app
bundle install
pnpm install
pnpm devUtilities App
A comprehensive demo of stdlib helper modules and utility functions.
Features demonstrated:
URIHelpers- URL parsing, query parameters, encodingBase64Helpers- Encoding, JWT, Basic Authdebounce,throttle- Rate limitingcopy_to_clipboard,read_from_clipboard- Clipboard APIunique,intersection,difference,union- Set operationsdeep_clone,deep_merge,pick,omit- Object utilitiesvalid_email?,valid_url?,valid_phone?- Validation
Location: examples/utilities-app/
class UrlDemoController < StimulusController
include OpalVite::Concerns::V1::StimulusHelpers
include OpalVite::Concerns::V1::URIHelpers
def parse
url = parse_url(target_value(:urlInput))
return unless url
puts url_hostname(url) # => "example.com"
puts url_pathname(url) # => "/api/v1"
puts url_all_params(url) # => { "page" => "1" }
end
end
class Base64DemoController < StimulusController
include OpalVite::Concerns::V1::Base64Helpers
def encode
text = target_value(:input)
encoded = base64_encode(text)
# => "SGVsbG8gV29ybGQ="
end
def decode_jwt
jwt = target_value(:jwtInput)
payload = decode_jwt_payload(jwt)
expired = jwt_expired?(jwt)
end
endRun locally:
cd examples/utilities-app
bundle install
pnpm install
pnpm devRunning Tests
Each example app includes E2E tests using Capybara + Cuprite:
cd examples/counter-app
pnpm dev &
bundle exec rspecProduction Build
All example apps support production builds:
cd examples/counter-app
pnpm build # Build for production
pnpm preview # Preview production build