This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-05-31
Channels
- # announcements (1)
- # babashka (11)
- # beginners (33)
- # calva (11)
- # clj-kondo (6)
- # clojars (8)
- # clojure (28)
- # clojure-europe (16)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-sweden (23)
- # clojure-uk (5)
- # clr (10)
- # gratitude (6)
- # hyperfiddle (14)
- # jobs-discuss (1)
- # lsp (7)
- # pathom (6)
- # pedestal (3)
- # polylith (4)
- # ring (4)
- # specter (6)
- # squint (8)
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?
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. (
[: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. đ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
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
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 đ
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
Tror jag ska testa idĂ©n att lĂ€gga dit en hanterare pĂ„ window-objektet och filtrera pĂ„ de tvĂ„ elementenâŠ
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?)
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
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 đ
https://headlessui.com/ er jo egentlig et prakteksempel pĂ„ at det kan vĂŠre kjekt med state pĂ„ komponent-nivĂ„ đ
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.
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
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? đ
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.
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.