Consider doing a "modal" layer in the UI
Modals are notoriously tricky on re-renders. Look into something like joystick.modal() and have a global registry spot in the DOM for loading these. Same component API, just a different way to route the HTML and have a global dispatcher to show/hide/update.
Brainwave: just add a modal: true property to components. Makes it easy to scoop them up at build/mount time.
Bumping this to 1.0.0. Have run into far too many headaches with modals and it makes a ton of sense. Should make UIs faster overall and makes markup clean as a bonus.
Had a thought in the car...
The ideal way to do this is to just have an object on a parent component or layout where modals can be registered like this:
import ui from '@joystick.js/ui';
import ProfileModal from '/path/to/profileModal';
const SomeParent = ui.component({
modals: {
profile: ProfileModal,
},
events: {
'click .edit-profile': (event = {}, component = {}) => {
component.modals('profile').open();
// Later: component.modals('profile').close();
},
},
render: () => {
return `
<div>
<button class="edit-profile">Edit Profile</button>
</div>
`;
},
});
export default SomeParent;
So, when ANY component registers a modals property we do two things:
- Scoop up those components and render them into the modal layer.
- Make each modal available on the component instance of the parent that loaded it via
component.modals('someModalName').
The only part of this that needs to be figured out is how do we automatically pass .open() and .close() methods down to modals and respect them?
The only part of this that needs to be figured out is how do we automatically pass .open() and .close() methods down to modals and respect them?
The real problem here is just global access to state. Could just rig up a Cache specific to modals (e.g., const modals = cache('_modals')): https://github.com/cheatcode/joystick#global-state. Just use a _ prefix to mark it as internal and prevent conflicts.
Under the hood, set a joystick.modals() function with its .open() and .close() methods pointing to this. So whether in the parent or in the modal itself, you could trigger an open/close of any modal in the app. Would make composition of modal UIs super clean.
import ui from '@joystick.js/ui';
import ProfileModal from '/path/to/profileModal';
const Dashboard = ui.component({
modals: {
profile: ProfileModal,
},
events: {
'click button': (event, component) => {
ui.modals('profile').open({
userId: 'someUserIdAsAProp',
});
},
},
render: () => {
return `
<div>
<button>Edit Profile</button>
</div>
`;
},
});
export default Dashboard;
Here ui is the window.joystick value and we just call ui.modals() from that, expecting the returned modal instance to have an .open() method that receives some props at open time.