italia / design-web-toolkit

Questa libreria è deprecata, si consiglia l'utilizzo di Bootstrap Italia (https://italia.github.io/bootstrap-italia/)
Creative Commons Zero v1.0 Universal
93 stars 87 forks source link

Abbiamo ancora bisogno di jQuery? #84

Open LucaColonnello opened 7 years ago

LucaColonnello commented 7 years ago

Vorrei chiedere come mai abbiamo bisogno di jQuery?

Essendo un sito Italiano legato alla PMA dovrebbe essere di esempio, e credo che ad oggi jQuery sia una tecnologia datata, almeno sostituibile facilmente con le DOM API se proprio bisogna scegliere un pattern imperativo e non dichiarativo.

C'è possibilità di uscire da questo pattern e essere di esempio per altri portali e siti web nella realtà tecnologica italiana, o ci sono motivazioni pratiche per cui non è possibile?

LucaColonnello commented 7 years ago

Se volete considerare un approccio web component based, potrebbe essere un bene fare un po di decoupling e astenersi da usare il toolkit come fosse un framework.

Suggerirei di usare un approccio simile a questo: https://www.webpackbin.com/bins/-KkaraJYp0vdMQFvJ8Qy

Migliorabile, ma in questo modo lasciamo fare al browser quello che fa meglio, gestire i componenti! (chiaramente richiede polyfills ma se ne andranno in breve tempo).

Questo approccio garantisce il decoupling dell'UI da qualsiasi framework o libreria un applicazione voglia usare per comporre le viste.

gunzip commented 7 years ago

ciao @LucaColonnello, spunto interessante. puoi indicare i vantaggi che si otterrebbero nell'eliminare jQuery ? (tralasciando il risparmio di Kb, negligibile rispetto alla dimensione media delle immagini e considerando il fatto che spesso viene servito tramite CDN)

Cito alcuni aspetti che orienterebbero verso l'inclusione di jQuery:

sostituibile facilmente con le DOM API

sostituibile: sicuramente, facilmente: ho qualche dubbio. jQuery è più che una libreria per manipolare DOM, astrae una serie di aspetti garantendo la compatibilità tra i browser. in genere, i progetti che non usano jQuery, finiscono per re-implementare le funzionalità fornite da jQ tramite funzioni di utilità. tantovale assestarsi su una lib che ha un utilizzo diffuso.

LucaColonnello commented 7 years ago

@gunzip comprendo perfettamente quanto scritto e ringrazio per la risposta.

Bisogna pero anche considerare che:

Tirando le somme, è difficile allontanarsi da jQuery, ma non è una moda... Lo si fa per avere codice scalabile. Domani, quando dovrete sviluppare soluzioni con tecnologie diverse, gioverete dello stesso toolkit, fornendo una soluzione nativa al problema dell'interoperabilità. Un web component è un codice che si può copiare ed incollare molto più facilmente che un codice jQuery, ed è di base reattivo perché può reagire ai cambiamenti degli attributi. Inoltre il css é isolato, in quanto scoped.

Ci sono moltissimi vantaggi come detto sopra! Se ci sono altre preoccupazioni, sarò felice di rispondere, e comprendo comunque se non volete switchare, ma vale la pena considerare cosa il web di oggi propone.

equinusocio commented 7 years ago

Nello specifico, l'implementazione dei web components (con vdom o no), permetterebbe di approcciarsi allo sviluppo del toolkit con una logica totalmente component-based, e grazie allo shadow dom si avrebbe un CSS localizzato nel componente.

Si eliminerebbero i problemi legati allo scopo globale del css e di sovrascrittura indesiderata delle regole. Si aprirebbero portoni che sono davvero orientati verso il futuro (vedi css custom properties, custom media queries ecc con postcss + cssnext), al contrario adesso, si ha un bootstrap con un nome differente. Funzionante? si. Utile? relativamente. Risolve i problemi di oggi? no.

gunzip commented 7 years ago

l'attenzione agli aspetti "future-proof" è il motivo per il quale alcune delle tecnologie che citi (css custom properties e custom media queries tramite postcss + cssnext) sono state già utilizzate nel toolkit.

per quanto riguarda l'isolamento dei componenti, non è certamente garantito (come accadrebbe utilizzando web components), ma è quantomeno favorito dal naming delle classi / utilizzo di CSS non globale (per quanto riguarda i fogli di stile) e l'utilizzo di webpack (per quanto riguarda i moduli JS).

ben venga l'idea di valutare l'utilizzo di tecnologie relativamente 'nuove', ma non è possibile prescindere dal contesto nel quale queste si declinano: è più facile, ad oggi, sviluppare un tema per Wordpress / Drupal basandosi su una libreria di web components o su un modello più 'tradizionale' ? è più facile trovare sviluppatori che conoscono bene Sass / PostCSS / un qualsiasi linguaggio di templating o esperti di shadow dom / custom elements ? esiste ad oggi più materiale (framework, tooling, librerie, plugin) da poter riutilizzare con tecnologie 'tradizionali' (CSS/Sass/PostCSS/jQuery) o web components che possono soddisfare esigenze eterogenee ? quali sono le skill richieste a chi vorrà utilizzare il tk ? (posso dirti che, in merito all'ultimo punto, sono già fin troppo elevate adesso e che alcune delle tecnologie utilizzate risultano 'complesse' ai più, per quanto ormai consolidate).

in merito al supporto dei vecchi browser, l'utilizzo dei polyfill vanifica molti dei vantaggi menzionati: (es: https://www.webcomponents.org/polyfills#known-limitations) e richiede alcuni accorgimenti nelle fasi di scittura del codice.

se inoltre per 'alcune versioni di IE' si intende che non funzionano su < IE11+, questo potrebbe essere un problema (le LG raccomandano compatibilità almeno con versioni di IE <= 10) e andrebbe in ogni caso valutata e chiusa la #37

LucaColonnello commented 7 years ago

Per rispondere al discorso limiti dei polyfill, una volta conosciuti, si trovano facili workaround, e molte delle cose come :host(.zot:not(.bar:nth-child(2))) si possono evitare in un approccio strettamente component-base.

Per quanto riguarda l'utilizzo, iniettare un web component se usate webpack si tratta di importare lo script del bundle js, che gia avete, e poi l'integrazione, al posto di attivare jquery, basta mettere nel template i tag in puro html, quindi si elimina addirittura del setup da fare.

Resta solo il codice applicativo, che possono sviluppare come vogliono, jQuery, React ecc...

Sviluppatori web components, è una spec che ha 4 o 5 cose in più rispetto all'uso del DOM nativo, con la differenza che non serve targettare a mano gli elementi per dargli un contesto, perché ci pensa il browser. Gli sviluppatori hanno davvero poco codice da imparare, e ci sono n librerie gia fatte o framework già pronti all'uso, che basta leggere quel poco di doc che hanno.

Davvero tutto quello che offrono é un entry point differente, il codice da sviluppare rimane top level.

gunzip commented 7 years ago

Penso che a tutto questo si possa rispondere con un'altra domanda: Quando saranno conosciute se nessuno inizia ad utilizzarle? Esistono e sono li, aspettano di essere usate.

la proposta è quindi effettuare uno 'shift strategico' da 'progetto rivolto a un pubblico trasversale' verso qualcosa che possa funzionare come driver 'educativo' per chi è più addentro alla materia ?

faccio presente, in merito, che molte delle richieste che ci sono arrivate quest'anno più che a un 'upgrade', auspicavano altresì un 'downgrade' delle tecnologie utilizzate (per quanto meno efficaci) con l'unico scopo di allinearle al know-how già acquisito dagli sviluppatori. andare nella direzione che viene qui suggerita, significa abdicare a questo trade-off 'aspetto pragmatico vs tecnologie cutting edge'.

proporrei di condividere il porting a 'web component' di un widget attualmente basato su jQuery (es. https://italia.github.io/ita-web-toolkit/components/detail/carousel.html) che soddisfa una serie di features complesse (es. comportamento responsive, touch friendly, accessibile, configurabile, etc.). dalla pull request valutiamo l'effort per lo sviluppo e la compatibilità con i diversi browser.

LucaColonnello commented 7 years ago

Si potrebbe fare il porting, ma richiede un lavoro di refactoring architetturale, che posso provare a fare in un branch separato, ma non so se svilupperei poi qualcosa come il carousel, perche richiede parecchio lavoro, e non credo valga la pena per una PR che potrebbe essere buttata.

Comunque se incomincio, vediamo dove arrivo... Se non impiego molto a adattare l'attuale codice ad un approccio component base, posso anche farlo!

equinusocio commented 7 years ago

@LucaColonnello

Se non impiego molto a adattare l'attuale codice ad un approccio component base, posso anche farlo!

Se invece di "adattare" si provasse un approccio ex-novo?

LucaColonnello commented 7 years ago

L'approccio ex-novo potrebbe andare, ma penso fallirebbe la PR perche non fornirebbe una migration path adeguata. Mentre provare a fare il porting adattando risulta comunque codice ex-novo, ma mantenendo la stessa struttura implementativa giá esistente, almeno architetturalmente parlando!

gunzip commented 7 years ago

scusa @equinusocio ho eliminato un commento per errore. ti riporto qui la risposta:

Poi

io sono convinto che scrivere:

<my-button></my-button>

DOve il css è:

:host {
  display: inline-block;
  contain: content;
  background-color: green;
}

.Text {
  color: color(green lightness(80%));
}

sia più facile di scrivere 4 classi (per quanto BEM sia una metodologia molto efficace in un contesto globale):

<button type="button" class="Button Button--default Button--shadow u-text-r-xs">
  Button default shadow
</button>

O no?

è più facile solo se tutti i <my-button> hanno lo stesso colore per lo sfondo e il testo (Button--default), se hanno la stessa ombreggiatura (Button--shadow) e la stessa dimensione per il testo (u-text-r-xs).

gunzip commented 7 years ago

@LucaColonnello

ma non so se svilupperei poi qualcosa come il carousel, perche richiede parecchio lavoro

è possibile sostituirlo con uno dei web components già pronti all'uso, non è necessario implementarlo ex-novo

equinusocio commented 7 years ago

@gunzip no ti sbagli 🙂 È solo un semplice esempio. Le custom-properties permettono di creare un'interfaccia pubblica per la stilizzazione del componente. "Penetrano" lo shadow root e creano un punto di accesso dall'esterno per customizzare il CSS. (Questo vale sia per custom-properties sia per i mixin css).

Prendi quest'altro esempio, un componente per creare link:

:host {
  display: inline-block;
  contain: content;
}

a {
  text-decoration: none;
  color: var(--oa-link-color, #0072BC);
  cursor: pointer;
  font-size: inherit;
  letter-spacing: 0.3px;
  display: block;

  @nest :host([aria-decoration]) & {
    text-decoration: underline;
  }

  @nest :host([aria-disabled]) & {
    pointer-events: none;
    color: var(--oa-link-disabledColor, rgba(0, 0, 0, 0.3));
    pointer-events: none;
  }

  @nest :host(:hover:not([aria-disabled])) & {
    -webkit-text-stroke: 0.04pc;
  }
}

Espone delle proprietà all'esterno che sono customizzabili (e con valore di default)

Questo approccio è fattibile sia con singole custom-properties o con mixin (@apply) transpilati da cssnext. Un esempio più concreto è il nuovo youtube, usa i web components con polymer e le custom-properties per gestirne l'aspetto.

LucaColonnello commented 7 years ago

Se non avete alcun tipo di limite sui plugin da utilizzare ok! Alternativamente si puo usare un carousel che non dipenda da jQuery o Zepto come lib js, e usarlo dentro il web component... Vediamo! Challenge accepted!

gunzip commented 7 years ago

@equinusocio quello che volevo dire è che, nel momento in cui le customizzi (ovvero, assegni un valore alle custom properties) sono sempre e comunque 3 parametri da impostare (il codice è solo 'spostato' dall'html al js). l'esempio è capzioso perché <my-button></my-button> è la configurazione di default :)

gunzip commented 7 years ago

@LucaColonnello unico limite è compatibilità <= IE10.

LucaColonnello commented 7 years ago

@gunzip Questo pero non ha molto senso per me (nel senso che non capisco)! dire IE <= 10 vuol dire che supportate IE sotto 10 o 10 eheheheh non dovrebbe essere IE >= 10 ? Magari sbaglio eh...

equinusocio commented 7 years ago

@gunzip Non ti seguo, perdonami. Hai visto l'esempio del componente link? 🙂

<oa-link> è il custom element creato, è predisposto, da chi lo crea, a ricevere proprietà e personalizzazioni css. Ogni componente si preoccupa del proprio stile/comportamento e non usa classi css globali o condivise. Il CSS poi non è solo "spostato", è incapsulato e legato al componente stesso, non ad un css globale.

Per quanto riguarda la customizzazione invece è possibile creare le proprietà a livello globale o per ogni istanza del componente.

Globale:

html {
  --oa-link: red;
  --oa-linkDisabled: green;
}

Per istanza:

.myHeader oa-link {
  --oa-link: #FF00FF;
  --oa-linkDisabled: #000;
}

.myFooter oa-link {
  --oa-link: pink;
  --oa-linkDisabled: cyan;
}

Quindi chi userà il toolkit può definire un "tema" globale per i componenti, e dove serve, sovrascriverlo. Unico punto di configurazione, il resto del css non è localizzato e a prova di conflitti. Se non si vogliono esporre solo le singole proprietà si possono esporre anche i mixin, che possono contenere set di regole da applicare al componente.

gunzip commented 7 years ago

cerco di chiarire.

tu sostieni che scrivere <my-button></my-button> sia più facile che <button class="Button Button--default Button--shadow u-text-r-xs">Button default shadow</button>.

sarebbe più corretto paragonare <my-button></my-button> a <button class="Button"></button>, ovvero le due configurazioni di default.

quando dovrò impostare uno stile diverso dal default, dovrò in ogni caso comunicarlo al web component e non vedo enormi differenze nello scrivere <my-button class="warning"> piuttosto che <button class="Button Button--warning"> (se è questo che stiamo paragonando, la semplicità nel codice dei template).

nota: le classi CSS Button* potrebbero essere riusate per un <a>. mentre <my-button> è legato al DOM del web component (ovvero lega l'aspetto dello stile incapsulato con quello della semantica HTML, il che non è sempre desiderabile).

equinusocio commented 7 years ago

Nono, quando usi il componente scrivi solo <my-button></my-button>. La personalizzazione del componente la fai tramite CSS come scritto sopra, o a livello globale o per istanza, ma ad ogni modo non usi le classi per stilizzarlo.

Puoi quello che fai con il web component, all'interno lo decidi tu. Puoi avere un bottone che sia una a o un button, o entrambi controllato da una proprietà:

<my-button to="http://www.google.come"><!-- a by default -->
  Sono un bottone "a"
</my-button>

<my-button button to="/#/index.html"><!-- render a button tag -->
  Sono un bottone "button"
</my-button>
gunzip commented 7 years ago

la sostanza non cambia (non importa dove lo fai, ma il fatto che lo devi fare in ogni caso):

.Field-warning my-button { --my-button-color: red }

non è 'più facile' che

<button class="Button--warning">`
equinusocio commented 7 years ago

@gunzip La questione è che se usi lo Shadow DOM il css globale perde di senso ed è anti-pattern far accedere alle classi CSS del componente, che dall'esterno devono rimanere sconosciute, o meglio non direttamente manipolabili.

Non sono la stessa cosa i due esempi.

<button class="Button--warning">`

Questo come web component diventerebbe:

<my-button type="warning"></my-button> <!-- render warning button <a> -->
<my-button type="error"></my-button> <!-- render error button <a> -->
<my-button button type="success" theme="outlined shadow"></my-button> <!-- render success button with shadow and outlined -->

Cosi scegli che tipo di bottone renderizzare, non ne personalizzi le proprietà, quello lo fai con le custom-properties appunto. Le custom-properties vanno a definire l'aspetto di warning, error, success per progetto/istanza.

La facilità sta anche nel fatto che l'utilizzatore si deve preoccupare di conoscere le proprietà del componente e cosa permette di fare. Lo sollevi dal doversi studiare tutte le classi globali come u-text-r-xs e le altre classi condivise. Single responsibility principle. Poi più cose permetti di personalizzare, più "libertà" dai.

Poi attenzione non devi aspettarti di scrivere per forza meno codice, non semplice scrivere meno vuol dire facilitare. La questione è che, in un contesto shadow dom dove il css è locale, non puoi (perchè lo shadow root blocca l'accesso del css) e non devi usare css globale per gestire i componenti dell'ui.

Vuoi cambiare il margin di un bottone che compare dentro l'header?

  <my-button class="HeaderButton"></my-button>

nel css del componente Header avrai:

.HeaderButton {
  margin-top: 100px;
}

HeaderButton viene applicata all'elemento :host, ovvero my-button, l'unico elemento esposto nel light dom, non al suo contenuto.

LucaColonnello commented 7 years ago

@gunzip capisco cosa intendi con a o button e personalizzazione. Ma come dice @equinusocio la differenza è che tendi a fare decoupling dalle due cose. Perché un link dovrebbe assomigliare ad un bottone? C'é un motivo se l'HTML li differenzia, in quanto hanno due scopi semantici differenti.

Il fatto di usare un web component può invece essere visto come un modo per evitare questi comportamenti semanticamente errati per lo standard, e per l'UX.

Ad ogni modo ci possono ovviamente essere downside, nulla é perfetto, tanto meno le tecnologie attuali, ne quelle future.

Ma ci sono diversi vantaggi come spiegato che valgono la pena di scrivere con quelle tecnologie perché se ne beneficia a lungo termine. Questo toolkit se usasse i web components, nonostante c'é da fare un lavoro di refactoring (nemmeno tanto) e si perderebbe alcuni dei plugin che si trovano in jQuery, fornirebbe un codice puro, veloce e sopratutto compatibile con qualunque cosa sia web oggi e domani, persino con jQuery stesso! Chiaro ci possono essere complessità e possiamo stare qua a discuterne fino a domani, ma ci sono altrettante soluzioni, solamente diverse da quelle che già avete usato. Questo non vuol dire che abbia vantaggi.

Ad oggi questo toolkit può essere utilizzato solo in un contesto jQuery. Siamo sicuri che le PWA non abbiano per nessun modo e in nessun caso l'esigenza di creare qualcosa in Angular o Ionic, o React?

Non ci sono web app di alcun tipo? Solo siti in Wordpress? Perché in quel caso, basta un tema Wordpress o Drupal, non serve nemmeno un toolkit! Non credo sia cosi! Credo sia stato fatto un ottimo lavoro di analisi a priori qui, che abbia portato all'esigenza di un toolkit!

Quindi credo sia il caso di sfruttare soluzioni del genere, se non web components, almeno eliminare dipendenze che non reggono l'interoperabilità, ammesso che l'interoperabilità sia uno dei punti chiave, perché se non lo è, liberi di chiudere l'issue! :)