ecomplus / storefront-cms

Content and page builder for Storefront based on Netlify CMS
MIT License
0 stars 0 forks source link

Preview reativo ao campo em foco #11

Open leomp12 opened 2 years ago

leomp12 commented 2 years ago

Atualmente o preview só pode ser reativo a alterações nos campos do CMS, para melhorar a experiência de construtor de página o ideal é que o preview também possa ser reativo ao campo em foco (como acontece no TinaCMS, a section respectiva ao campo fica em destaque).

Para isso precisaremos que o CMS passe em uma nova prop (eg.: this.prop.focus) o campo atualmente editado para o componente do custom preview.

oscargross commented 2 years ago

@leomp12 PR https://github.com/ecomplus/storefront-cms/pull/20 Fiz vários testes, mas não consegui finalizar a task. O PR esta incompleto.

Nele estão sendo pego os eventos do onFocus no widgets, repassados até o componente que dispara a alteração no redux, porém não consegui pegar essa alteração do outro lado (preview), para a coluna ser novamente renderizada. Como faz o onChange, quando há alguma alteração, o Preview é remontado, com todos os dados, porém para o onFocus, é necessário encontrar qual o widget que foi acionado.

Fiz testes alterando o #ducument (aqui https://github.com/ecomplus/storefront-cms/blob/main/netlify-cms%402/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js#:~:text=%7B(%7B-,document,-%2C%20window%20%7D)%20%3D%3E%20%7B ) Nele é possível adicionar/alterar com o AppendChild tags no DOM que será construído no EditorPreviewContent. Porém ficou com bugs para saber qual div child do body precisa ser alterada e quando há movimentação das listas, a contagem de divs é perdida.

Outro teste foi adicionando o style a div selecionada, pelo registerPreviewStyle, ex: registry.previewStyles.push({ raw: true, value: "h1{border-color: aquamarine;border-style: dotted;}"}); (aqui https://github.com/ecomplus/storefront-cms/blob/main/netlify-cms%402/packages/netlify-cms-core/src/lib/registry.js#:~:text=export%20function-,getPreviewStyles,-()%20%7B) Porém com o mesmo problema de destacar o widget com focus.

leomp12 commented 2 years ago

@oscargross mano não tenho certeza se entendi tudo...

Como faz o onChange, quando há alguma alteração, o Preview é remontado, com todos os dados, porém para o onFocus, é necessário encontrar qual o widget que foi acionado.

E se você só setar uma global no focus (🇬🇲 rra)? Nesse caso você não precisaria descobrir "reversamente" qual field triggou a alteração, certo?

Nele é possível adicionar/alterar com o AppendChild tags no DOM que será construído no EditorPreviewContent. Porém ficou com bugs para saber qual div child do body precisa ser alterada e quando há movimentação das listas, a contagem de divs é perdida.

Mas nem é o caso, você só precisaria informar ao preview de alguma forma (sinal de fumaça que seja) que certo campo está em foco, aí o preview seria responsável por dar um highlight nele, isso a gente faria no JS do componente do custom preview, fora do source do CMS...


De qualquer forma isso é um enhancement opcional e o issue era uma PoC só por enquanto, só para vermos se era viável sem deixar o CMS muito lento, se você preferir deixamos isso de lado por enquanto, pensamos melhor e fazemos depois.

O CMS vai ser atualizado no Storefront com as suas edições mesmo sem isso aqui (see https://github.com/ecomplus/storefront/pull/596).

oscargross commented 2 years ago

@leomp12 Certo, fiz analise do seguinte: o componente criado no preview vem do campo #document e os styles do registry. Eles montam os campos como divs e a estilização fica direto nas suas tags... não teria alguma prop para conseguirmos encontrar um campo específico.

Testei enviando o label quando o onFocus é acionado, porém é possível que tenham vários labels iguais, por conta das lists e typed lists do cms. Aí complicou. Também testei fazendo contagem dos campos, por exemplo, "foi o quinto field que entrou em focus", e então, daria para procurar o quinto elemento no preview e aplicar o highlight nele, porém complicou tbm, pois as lists possuem vários widgets nelas, e aparece diferente na montagem dos componentes, além de podermos alterar a ordem das listas no drag, e "abrir o FrameContextConsumer", alterar os dados, e depois montar novamente o iframe foi sem sucesso.

O que comentou sobre estilizar o componente do custom preview, fora do source do CMS... não encontrei esse lugar para testar, pode ser bem mais facil mesmo, pois estava só testando pelos comp. que estão prontos para ser renderizados (#document).

leomp12 commented 2 years ago

Testei enviando o label quando o onFocus é acionado, porém é possível que tenham vários labels iguais, por conta das lists e typed lists do cms. Aí complicou. Também testei fazendo contagem dos campos, por exemplo, "foi o quinto field que entrou em focus", e então, daria para procurar o quinto elemento no preview e aplicar o highlight nele, porém complicou tbm, pois as lists possuem vários widgets nelas, e aparece diferente na montagem dos componentes, além de podermos alterar a ordem das listas no drag, e "abrir o FrameContextConsumer", alterar os dados, e depois montar novamente o iframe foi sem sucesso.

Saquei...

O que comentou sobre estilizar o componente do custom preview, fora do source do CMS... não encontrei esse lugar para testar, pode ser bem mais facil mesmo, pois estava só testando pelos comp. que estão prontos para ser renderizados (#document).

No nosso caso o custom preview vem daqui https://github.com/ecomplus/storefront/tree/master/%40ecomplus/storefront-template/template/js/netlify-cms/preview

Numa última alternativa, você acha que é viável só consumir uma global? Por exemplo, podemos definir window.storefrontCmsOnFocus como uma função, aí sempre que o campo em foco é alterado você verifica:

if (window.storefrontCmsOnFocus) {
  window.storefrontCmsOnFocus({ fieldPath });
}

Em que fieldPath seria uma string do field em dot notation, eg.: sections[0].src.

oscargross commented 2 years ago

@leomp12 No novo commit está com a variável global controlando o campo em foco, sendo necessário triggar no redux para o preview dar um refresh quando os campos são ativados no onFocus.

https://user-images.githubusercontent.com/55117353/149777619-6eef4c60-1c41-4aca-98ee-2851ef3eb512.mp4

leomp12 commented 2 years ago

@oscargross então, nesse caso o redux é necessário porque sua global é um objeto né, eu sugeri uma função porque usaria ela como um hook, não sei se você tinha entendido... De qualquer forma, algum prejuízo em implementar dessa maneira com o redux? Ficou lento ou algo do tipo?

Pelo que vi na PR talvez você ainda esteja confuso com relação ao preview de cada widget e tal, na verdade não usamos aquilo, temos um outro com componente e usamos registerPreviewTemplate, esse nosso custom preview renderiza a página toda, não há no nosso caso um preview pra cada widget, então esse cara iria declarar o hook global e ser reativo a ele, sacou?

oscargross commented 2 years ago

Não não, só comento que fiz pelo redux pq lá encontrei a forma para o preview renderizar quando esse evento acontecer(focus). Respondi os reviews lá no PR