Visual debugging of components (#17729)
* feat: debug/show components from the REPL * ref: some renames and cleanup * chore: removed comments/imports * feat: added remount on every eval & small changes * doc: added tip to debugging doc * doc: formatting * doc: more formatting * fix: fixed docs and other review comments * fix: moved & renamed into the dev.component-preview ns * style: adjusted debugging readme spacing * fix: removed trailing line
This commit is contained in:
parent
2aeafa30bd
commit
954373105d
|
@ -99,3 +99,38 @@ Also to inspect logs in a more flexible manner, instead of the strict output fro
|
|||
adb logcat | grep 'ReactNativeJS\|StatusModule\|GoLog'
|
||||
```
|
||||
|
||||
### From @clauxx (visual debugging):
|
||||
|
||||
When building/fixing/refactoring components, it can be annoying to set-up the component for instant visual feedback (i.e. finding it in the UI when fixing/refactoring; finding a place for it when building from scratch). Very often if the location of the screen containing your component nested deeply in the app, you might have to do a lot of repeated navigation, nevermind logging in every time the app reloads (even with fast refresh disabled this happens quite often).
|
||||
|
||||
To alleviate this discomfort and make the development cycle more *pleasant*, you can use one of the following options (*_both of which involve the ... REPL ༼ つ ╹ ╹ ༽つ, so make sure you have that set-up with your IDE/editor_*)
|
||||
|
||||
#### REPL-ing to a screen
|
||||
|
||||
This one is straightforward, just evaluate a navigation dispatch form from anywhere:
|
||||
|
||||
```cljs
|
||||
(comment (rf/dispatch [:navigate-to :your-favorite-buggy-screen]))
|
||||
```
|
||||
|
||||
> TIP: you can run this from an untracked user namespace `(ns user)`, from which you can experiment or interact with the REPL. This is where I usually keep my development navigation forms.
|
||||
|
||||
#### REPL-ing a component
|
||||
|
||||
This is also straighforward, but there are some small differences. Just like above, we only have to evaluate a dispatch form, as follows:
|
||||
|
||||
```cljs
|
||||
;; example debugging a quo component, although it could be any other component e.g. from the `status-im2` ns.
|
||||
(comment (re-frame/dispatch [:dev/preview-component
|
||||
[quo/slide-button
|
||||
{:track-icon :face-id
|
||||
:track-text "preview component example"
|
||||
:customization-color :blue
|
||||
:on-complete identity}]]))
|
||||
```
|
||||
|
||||
When evaluated, a full-screen bottom sheet will appear with your component inside. You can make changes to the props or the component internals and re-evaluate the changed forms, after which the component will be re-mounted without running a reload (unless you save the file). Other times it's quicker to just hit save and the component will be reloaded as usual (except for the props you evaluated, which have to be re-evaluated when changed).
|
||||
|
||||
> TIP: You can have multiple versions of the component as separate comments to check for the component variations
|
||||
|
||||
> TIP: You can leave `comment` blocks at the end of component files (other than quo, since can be previewed in other ways) with usages of components, which other developers can use for visualisation/testing.
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
(ns dev.component-preview.events
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(def preview-screen-name :dev-component-preview)
|
||||
|
||||
(when js/goog.DEBUG
|
||||
(re-frame/reg-event-fx :dev/preview-component
|
||||
(fn [{:keys [db]} [[component-tag props & args]]]
|
||||
(let [view-id (:view-id db)
|
||||
;; NOTE: re-render on every evaluation e.g. reset component state without changes
|
||||
component (into [component-tag (assoc props :key (random-uuid))] args)
|
||||
navigate? (not= view-id preview-screen-name)]
|
||||
(cond-> {:db (assoc db :dev/previewed-component component)}
|
||||
navigate? (assoc :fx [[:dispatch [:navigate-to preview-screen-name]]]))))))
|
||||
|
||||
;; Usage example
|
||||
(comment
|
||||
(re-frame/dispatch [:dev/preview-component
|
||||
[quo/slide-button
|
||||
{:track-icon :face-id
|
||||
:track-text ":debug-component example"
|
||||
:customization-color :blue
|
||||
:on-complete identity}]]))
|
|
@ -0,0 +1,16 @@
|
|||
(ns dev.component-preview.view
|
||||
(:require
|
||||
[react-native.core :as rn]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def ^:private container-style
|
||||
{:flex 1
|
||||
:padding-horizontal 20
|
||||
:padding-top 80
|
||||
:align-items :center})
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [component (rf/sub [:dev/previewed-component])]
|
||||
[rn/view {:style container-style}
|
||||
(when component component)]))
|
|
@ -1,5 +1,6 @@
|
|||
(ns status-im2.navigation.screens
|
||||
(:require
|
||||
[dev.component-preview.view :as component-preview]
|
||||
[status-im.ui.screens.screens :as old-screens]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.contexts.add-new-contact.views :as add-new-contact]
|
||||
|
@ -272,6 +273,11 @@
|
|||
{:modalPresentationStyle :overCurrentContext})
|
||||
:component scan-address/view}]
|
||||
|
||||
(when js/goog.DEBUG
|
||||
[{:name :dev-component-preview
|
||||
:options {:sheet? true}
|
||||
:component component-preview/view}])
|
||||
|
||||
(when config/quo-preview-enabled?
|
||||
quo.preview/screens)
|
||||
|
||||
|
|
|
@ -147,3 +147,7 @@
|
|||
;;wallet
|
||||
(reg-root-key-sub :wallet/scanned-address :wallet/scanned-address)
|
||||
(reg-root-key-sub :wallet/create-account :wallet/create-account)
|
||||
|
||||
;;debug
|
||||
(when js/goog.DEBUG
|
||||
(reg-root-key-sub :dev/previewed-component :dev/previewed-component))
|
||||
|
|
Loading…
Reference in New Issue