split out common functionality to component