Um editor que preserva seu estado
Experimente janelas e PiP, drag-and-drop, transições e keep-alive com duas microapps reais.
Abra Apps em movimento. O React mantém o rascunho do editor e o Vue mantém uma caixa de notas recebidas. O WU monta ambas as apps no mesmo documento, com Shadow DOM independente, e coordena sua interação. O exemplo usa WU Framework 4.0.0 incluído no build.
Quatro tarefas, um cenário
| Experimente | O que observar |
|---|---|
| Escreva e envie uma nota | Arraste o cartão até o Vue ou use o botão de envio. A caixa recebe uma cópia dos dados após verificar tipo e permissões. |
| Oculte e mostre o editor | O rascunho e a instância React permanecem. Não ocorre uma nova montagem. |
| Mude o layout | A transição muda o layout; escrever e receber notas continuam funcionando. |
| Destaque e retorne o editor | Abra uma janela, escreva nela e retorne. Os mesmos nós voltam ao host. PiP é oferecido quando o navegador expõe essa API. |
O que pertence a cada app
O shell possui uma instância new WuCore(), registra as duas apps e concede permissões. O React possui o rascunho e oferece o tipo docs.note; o Vue valida e recebe esse tipo. Os controles visuais são Custom Elements Lit. O contexto context.wu preserva a autoridade de cada microapp ao enviar ou aceitar dados.
Os trechos a seguir executam após inicializar o runtime e montar as apps. runtime é a instância do shell. Para reproduzir a inicialização completa, consulte os arquivos ao final deste guia.
Janelas e Picture-in-Picture
// Prepare the optional subsystem before the user clicks.
await runtime.windowsReady();
openButton.addEventListener('click', async () => {
try {
await runtime.detach('interaction-editor', {
window: 'popup', width: 560, height: 520,
});
status.textContent = String(runtime.isDetached('interaction-editor'));
} catch (error) {
status.textContent = error.message;
}
});
returnButton.addEventListener('click', () => {
runtime.attach('interaction-editor');
});
Crie openButton, returnButton e status antes do trecho. Para PiP, use window: "pip" a partir de um clique após verificar o suporte. windowOf(name) consulta a janela atual. Fechar a janela retorna a app; sair do cenário a desmonta. O módulo continua executando na página original e o editor preserva os mesmos nós e estado.
Entrega tipada com mouse ou teclado
// Sending app: its manifest requests drag.offer:docs.note.
const stopOffer = await context.wu.drag.offer(card, {
type: 'docs.note',
payload: () => ({ text: readDraft() }),
});
// The send button uses the same permission and validation path.
await context.wu.drag.deliver('docs.note', { text: readDraft() }, {
to: 'interaction-board',
});
// Receiving app: its manifest requests drag.accept:docs.note.
const stopAccept = await context.wu.drop.accept(inbox, {
type: 'docs.note',
validate(note) {
if (!note || typeof note.text !== 'string' || !note.text.trim()) {
throw new TypeError('A non-empty note is required');
}
return note;
},
onDrop: note => addToInbox(note),
});
Este trecho reúne dois lados: oferecer e enviar pertencem ao editor; aceitar pertence à caixa de entrada. Substitua card, inbox, readDraft e addToInbox pelas referências de cada app. O host deve conceder as permissões às respectivas apps. Guarde stopOffer e stopAccept e execute-os durante o unmount.
Preservar estado e mudar o layout
await runtime.unmount('interaction-editor', { keepAlive: true });
await runtime.show('interaction-editor');
// panelA and panelB have stable data-wu-vt keys inside workspace.
const animation = runtime.transition(() => {
workspace.classList.toggle('stacked');
}, { root: workspace, duration: 320 });
await animation.updateCallbackDone;
await animation.finished;
Defina a classe stacked para organizar seus painéis em uma coluna e adicione data-wu-vt aos elementos que WU medirá. Ocultar preserva a instância; não interrompe automaticamente intervalos ou conexões criados por você. A transição respeita movimento reduzido. Para remover todo o cenário, chame runtime.destroy() e libere os recursos externos do host.
Arquivos e referências
O exemplo completo no repositório oficial inclui os manifestos e as instruções de build. Seus controles Lit pertencem ao mesmo projeto. Clone o repositório completo e siga seu README para executá-lo; os três downloads abaixo mostram as integrações e o controlador.
Leia o controlador do shell, o editor React e a caixa de entrada Vue. São os arquivos usados para compilar o exemplo. Consulte drag-and-drop, janelas e foco e lifecycle para conhecer assinaturas, permissões e erros.
O suporte a PiP depende do navegador; a documentação do Chrome descreve o gesto do usuário e o ciclo de vida da janela. O botão de envio permite concluir a tarefa sem arrastar, seguindo o critério WCAG sobre movimentos de arraste.