cleanup pull-to-action into reusable component