* adds focusTrap wrapper to preact Modal component * add view specific code for focus trap in admin add nav link * add script to return a focustrap toggle, use in add nav link modal partial * add trap to edit nav link modal * add handlers for sign up modal * update modal controller for admin section, update nav link modals to use * update other admin modals with new data values for trap * remove unneeded erb script file * remove unneeded target * refactor to remove extra unneeded param * remove duplicate code, store getFocusTrapToggle in window * trap focus in comment and bookmark showModal instances for not logged in user * remove need for activator id * clean up id refs no longer needed * remove custom code and re-use focsu-trap lib * update storybook docs * update default export in focusTrap * prevent close button click triggering a modal toggle twice * ensure if user navigates from a modal the trap is deactivated * add jsdoc comments and add dynamic import * ensure admin controller modal traps are cleaned up on disconnect * update sign up modal to use crayons * update modal controller and admin nav links modals to use preact modal * update profile fields modals for new controller * tweak styling of sign up and admin modals to match previous * update listings modal to use crayons modal, adapt focus trap to work with click outside * memoize deactivate callback to ensure modal can be presented on first page load * add missed focustrap changes * fix focus trap issues in onboarding flow * refactor onboarding focus trap, remove getFocusTrapToggle * tweaks for styling and article modal toggle * add click outside tests to modal * add cypress tests for the login modal * update liquid tag tests affected by change * refactors to address review comments * fix issue with login modal presented twice on comment add * change ids to selectors in admin modals * small pr comment refactors * add listings e2e tests * add nav link modal tests * fix issue with help modal * tweak to fix ui bug from merge * remove context from showLoginModal * rename toggleModal * rename state property for clarity Co-authored-by: Nick Taylor <nick@dev.to>
98 lines
2.6 KiB
JavaScript
98 lines
2.6 KiB
JavaScript
import { h, Component } from 'preact';
|
|
import PropTypes from 'prop-types';
|
|
import { FocusTrap } from '../shared/components/focusTrap';
|
|
import { IntroSlide } from './components/IntroSlide';
|
|
import { EmailPreferencesForm } from './components/EmailPreferencesForm';
|
|
import { FollowTags } from './components/FollowTags';
|
|
import { FollowUsers } from './components/FollowUsers';
|
|
import { ProfileForm } from './components/ProfileForm';
|
|
|
|
export class Onboarding extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
const url = new URL(window.location);
|
|
const previousLocation = url.searchParams.get('referrer');
|
|
|
|
const slides = [
|
|
IntroSlide,
|
|
FollowTags,
|
|
ProfileForm,
|
|
FollowUsers,
|
|
EmailPreferencesForm,
|
|
];
|
|
|
|
this.nextSlide = this.nextSlide.bind(this);
|
|
this.prevSlide = this.prevSlide.bind(this);
|
|
this.slidesCount = slides.length;
|
|
|
|
this.state = {
|
|
currentSlide: 0,
|
|
};
|
|
|
|
this.slides = slides.map((SlideComponent, index) => (
|
|
<SlideComponent
|
|
next={this.nextSlide}
|
|
prev={this.prevSlide}
|
|
slidesCount={this.slidesCount}
|
|
currentSlideIndex={index}
|
|
communityConfig={props.communityConfig}
|
|
previousLocation={previousLocation}
|
|
/>
|
|
));
|
|
}
|
|
|
|
nextSlide() {
|
|
const { currentSlide } = this.state;
|
|
const nextSlide = currentSlide + 1;
|
|
if (nextSlide < this.slides.length) {
|
|
this.setState({
|
|
currentSlide: nextSlide,
|
|
});
|
|
} else {
|
|
// Redirect to the main feed at the end of onboarding.
|
|
window.location.href = '/';
|
|
}
|
|
}
|
|
|
|
prevSlide() {
|
|
const { currentSlide } = this.state;
|
|
const prevSlide = currentSlide - 1;
|
|
if (prevSlide >= 0) {
|
|
this.setState({
|
|
currentSlide: prevSlide,
|
|
});
|
|
}
|
|
}
|
|
|
|
// TODO: Update main element id to enable skip link. See issue #1153.
|
|
render() {
|
|
const { currentSlide } = this.state;
|
|
const { communityConfig } = this.props;
|
|
return (
|
|
<main
|
|
className="onboarding-body"
|
|
style={
|
|
communityConfig.communityBackground
|
|
? {
|
|
backgroundImage: `url(${communityConfig.communityBackground})`,
|
|
}
|
|
: null
|
|
}
|
|
>
|
|
<FocusTrap key={`onboarding-${currentSlide}`}>
|
|
{this.slides[currentSlide]}
|
|
</FocusTrap>
|
|
</main>
|
|
);
|
|
}
|
|
}
|
|
|
|
Onboarding.propTypes = {
|
|
communityConfig: PropTypes.shape({
|
|
communityName: PropTypes.string.isRequired,
|
|
communityBackground: PropTypes.string.isRequired,
|
|
communityLogo: PropTypes.string.isRequired,
|
|
communityDescription: PropTypes.string.isRequired,
|
|
}).isRequired,
|
|
};
|