Fork me on GitHub
#clojure-sweden
<
2024-05-31
>
slipset05:05:44

Morsning, korsning!

😀 2
pez06:05:15

God morgon! Jag behöver en mekanism i min webbapp som stĂ€nger vissa saker som visas om man klickar utanför dem. Typ menyer och liknande. Bara en sĂ„dan hĂ€r sak fĂ„r visas i taget. Funderar om jag kan lyssna pĂ„ mousedown i min “main” div och att den sĂ€tter en nyckel i app-db, typ: :sak-som-visas false. NĂ€r nĂ„got skall visas registrerar man det i databasen :stĂ€ng-den-hĂ€r-saken :sak-som-visas, samt :sak-som-visas true. Ganska enkelt sĂ„ lĂ„ngt. Kruxet Ă€r att knappar som öppnar saker ocksĂ„ kan bli klickade pĂ„. Har inte klurat ut hur jag kan lösa det Ă€n
 NĂ„gon som hĂ€nger med pĂ„ vad jag försöker göra?

pez09:05:34

Jag kom sÄ hÀr lÄngt:

[:ui/ax-open-thing k]
    {:new-state (assoc state
                       k true
                       :ui/close-this-thing k)}

    [:ui/ax-maybe-close-thing]
    (when-let [close-this-thing (:ui/close-this-thing state)]
      {:new-state (-> state
                      (assoc close-this-thing false)
                      (dissoc :ui/close-this-thing))})
Men övergav det eftersom jag inte lyckades lösa problemet jag förutsÄg med att grejen öppnas igen om man klickar pÄ öppna-knappen. Dessutom stÀngs allt om man klickar inuti saken som Àr öppen. (facepalm ). Löste det med att lÀgga en transparent div som tÀcker hela skÀrmen under saker som ska stÀngas:
[:div.thing-closer {:on-mousedown [[:db/ax-assoc :is-this-thing-visible? false]]}]
Funkar, men det lite trĂ„kiga Ă€r att om anvĂ€ndaren försöker göra nĂ„got utanför saken-som-ska-stĂ€ngas (t ex, klickar pĂ„ en knapp nĂ„nstans) sĂ„ hĂ€nder inte det. VĂ„gar inte göra preventDefault för dĂ„ kommer öppna-knappen i spel igen. 😃

leifericf12:05:55

Dette hÞres ut som en greie @U0MKRS1FX muligens har peiling pÄ.

🙏 1
augustl12:05:47

bÄde ja og nei
. ting som dette gjÞr meg litt bear pÄ cljs-frontends med all state-hÄndtering pÄ toppnivÄ, siden biblioteker som https://headlessui.com/ lÞser dette i React-land

augustl12:05:39

og det er noksĂ„ lett Ă„ gjĂžre det manuelt ogsĂ„ - en hook i komponentet selv kan lytte til “click” pĂ„ hele window, og dismisse seg selv om target pĂ„ click-eventet ikke er knappen eller menyen selv

pez12:05:21

Jag kör varken React eller hooks. 😃

augustl12:05:02

ikke for Ă„ “oute” noen her altsĂ„, men har lagt merke til at Portfolio f.eks ikke stĂžtter dette, menyene holder seg Ă„pne nĂ„r man klikker utenfor. Spent pĂ„ hva f.eks Magnar og Christian sier om dette! Mulig det lar seg lĂžse vel sĂ„ enkelt med global hĂ„ndtering av all state, det er bare ikke sĂ„ kjent terreng for min del 🙂

augustl12:05:39

men generelt er jo lĂžsningen den samme - ha en event listener pĂ„ window, som sjekker hva som trykkes pĂ„, og lukker ting basert pĂ„ hva som blir trykket pĂ„ 🙂 Kan like gjerne lĂžses globalt, men da mĂ„ man vel fort putte DOM-elementer i global state og sĂ„nt for Ă„ gjĂžre sjekken pĂ„ “hvem trykket pĂ„ meg”. Men igjen, mulig dette er FUD, jeg har ikke faktisk laget sĂ„ mange GUI-er pĂ„ den mĂ„ten, har bare lekt litt med det

pez12:05:17

Tror jag ska testa idén att lÀgga dit en hanterare pÄ window-objektet och filtrera pÄ de tvÄ elementen


augustl12:05:38

min pÄstand er at lokal state-hÄndtering pÄ komponent-nivÄ er fint en sjelden gang, f.eks til ting som dette (hvem bryr seg om at en <select> har litt oppfÞrsel for nÄr den er Äpen/lukket som likke lagres i GUI-staten din liksom?)

pez12:05:13

Jag total-vÀgrar att lÀgga nÄgon som helst state i mina komponenter.

augustl12:05:58

gjÞr det! Man kommer seg kanskje utenom Ä lagre DOM i staten og. Man kan gi menyen sin en klasse eller noe annet som gjÞr den identifiserbar, og sÄ se pÄ window onclick om e.target.closest(".my-menu-item-selector") finnes, og lukke menyen hvis den ikke er der

pez12:05:19

Jag lagrar DOM-grejor i min app-db hela tiden. 😃

augustl12:05:51

er greit nok det og - men sĂ„ sitter man plutselig med en “stale” cache og det DOM-elementet som er i app-db er ikke faktisk i DOM-en 😄

pez12:05:19

Har nog inte hÀnt mig Àn.

augustl12:05:25

https://headlessui.com/ er jo egentlig et prakteksempel pĂ„ at det kan vĂŠre kjekt med state pĂ„ komponent-nivĂ„ 😄

pez12:05:40

Jag tror man kan gÄ all-in Ät bÄda hÄllen. Men blir förvirrande om jag blandar tycker jag. För mig Àr det lÀtt att resonera kring att all state ligger i app-db och att den strukturen Àr platt som en pannkaka.

augustl12:05:42

for Ä si det pÄ en annen mÄte, domene-state har ingenting pÄ komponentnivÄ Ä gjÞre, men GUI-state er mere et tvilstilfelle vil jeg si

pez12:05:27

Jag ser hela min app i Gadget-inspectorn. Älskar det.

augustl12:05:18

blir du irritert hver gang du ikke kan se i app-staten hvilket element som har fouks, om en <select> er Ă„pen eller lukket, og sĂ„nt? 😄

pez12:05:55

Brukar inte ha sÄdant i app-db heller. Om jag har det Àr det av en anledning och dÄ vill jag ha koll pÄ det i inspectorn.

pez08:06:37

Tack för att du fick mig att försöka igen, @UGDTSFM4M. Det funkar nu! (Minus kön för flera menyer just nu.)

[:ui/ax-event-stop-propagation]
    {:effects [[:ui/fx-event-stop-propagation]]}

    [:ui/ax-toggle-thing-opened k]
    (let [open? (get state k)]
      {:new-state (cond-> state
                    :always (update k not)
                    (not open?) (assoc :ui/close-this-thing k))
       :effects [[:ui/fx-event-stop-propagation]]})

    [:ui/ax-maybe-close-thing]
    (when-let [close-this-thing (:ui/close-this-thing state)]
      {:new-state (-> state
                      (assoc close-this-thing false)
                      (dissoc :ui/close-this-thing))})
Det Àr mitt hemkokta lilla framework för #C06JZ4X334N-events. Men hyfsat likt re-frame sÄ ni fattar va? (Frameworket gör skillnad mellan actions (`ax-`), som jag inte tillÄter att ha sidoeffekter, och effekter (`fx-`) som jag hittills enbart anvÀnder för just sido-effekter. Effekten:
[:ui/fx-event-stop-propagation] (.stopPropagation event)
Main-containern:
[:span {:on-mousedown [[:ui/ax-maybe-close-thing]]}
 ...]
Meny-knappen:
[:span... {:on-mousedown [[:ui/ax-toggle-thing-opened :ui/settings-menu-visible?]]}
   ...]
Menyn:
[:div {:on-mousedown [[:ui/ax-event-stop-propagation]]}
 ...]
Det beter sig exakt som jag vill. 🎉 Återkommer med anpassningen för flera menyer.

🎉 2