feat: add in-app notification, refactor toast (#15642)

This commit is contained in:
yqrashawn 2023-04-17 14:01:25 +08:00 committed by GitHub
parent 8af7011eb4
commit 9b756544fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 740 additions and 459 deletions

View File

@ -23,13 +23,13 @@ setups and runs the test suite once.
setups and runs the test suite and watches for code changes will then retrigger the test suite.
## Writing Tests
New test files will need their namespace added to either the file "src/quo2/core_spec.cljs" or "src/status_im2/core_spec.cljs. These locations may update overtime but it is dependent on the entrypoint in shadowcljs config discussed below.
New test files will need their namespace added to either the file "src/quo2/core_spec.cljs" or "src/status_im2/core_spec.cljs. These locations may update overtime but it is dependent on the entrypoint in shadow-cljs config discussed below.
### Best practices
For the moment we will keep best practices for tests in our other guidelines document:
To that point these guidelines will follow the conventions of Jest and React Native Testing Library recomendations and Status mobile will just stack their preferences on top.
To that point these guidelines will follow the conventions of Jest and React Native Testing Library recommendations and Status mobile will just stack their preferences on top.
### Utilities
There is a file of utility functions defined in "src/test_helpers/component.cljs" and "src/test_helpers/component.clj". It will be great to use these utilities and to add any common testing tools to these files as it should make writing tests easier and faster.

View File

@ -71,7 +71,7 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]]))
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]]))

View File

@ -79,7 +79,7 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -44,8 +44,8 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -113,9 +113,9 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -91,9 +91,9 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -83,9 +83,9 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -31,8 +31,8 @@
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:data all-props
:render-fn render-item
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:data all-props
:render-fn render-item
:key-fn str}]])

View File

@ -0,0 +1,38 @@
(ns quo2.components.notifications.notification.component-spec
(:require
[quo2.components.markdown.text :as text]
[quo2.components.notifications.notification.view :as notification]
[test-helpers.component :as h]))
(h/describe "notification"
(h/test "empty notification"
(h/render [notification/notification {}])
(h/is-null (h/query-by-label-text :notification-avatar))
(h/is-null (h/query-by-label-text :notification-header))
(h/is-null (h/query-by-label-text :notification-body)))
(h/test "notification with title and text"
(h/render [notification/notification
{:title "title"
:title-weight :medium
:text "text"}])
(-> (h/expect (h/get-by-label-text :notification-header))
(.toHaveTextContent "title"))
(-> (h/expect (h/get-by-label-text :notification-body))
(.toHaveTextContent "text")))
(h/test "notification with custom input"
(h/render [notification/notification
{:header [text/text {:accessibility-label :header} "custom header"]
:avatar [text/text {:accessibility-label :avatar} "custom avatar"]
:body [text/text {:accessibility-label :body} "custom body"]}])
(h/is-truthy (h/get-by-label-text :notification-avatar))
(h/is-truthy (h/get-by-label-text :notification-header))
(h/is-truthy (h/get-by-label-text :notification-body))
(h/is-truthy (h/get-by-label-text :avatar))
(h/is-truthy (h/get-by-label-text :header))
(h/is-truthy (h/get-by-label-text :body))
(-> (h/expect (h/get-by-label-text :notification-header))
(.toHaveTextContent "custom header"))
(-> (h/expect (h/get-by-label-text :notification-avatar))
(.toHaveTextContent "custom avatar"))
(-> (h/expect (h/get-by-label-text :notification-body))
(.toHaveTextContent "custom body"))))

View File

@ -0,0 +1,39 @@
(ns quo2.components.notifications.notification.style
(:require
[quo2.foundations.colors :as colors]
[quo2.foundations.shadows :as shadows]))
(def box-container
{:margin-horizontal 8
:border-radius 16
:overflow :hidden})
(def blur-container
{:height "100%"
:width "100%"
:position :absolute
:padding-vertical 8
:padding-left 10
:padding-right 8
:background-color :transparent})
(defn content-container
[override-theme]
(merge
(:shadow-1 shadows/normal-scale)
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
:flex-direction :row
:padding-vertical 8
:padding-horizontal 12}))
(def right-side-container {:flex 1})
(defn title
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
(defn text
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
(def avatar-container {:margin-right 8 :margin-top 4})

View File

@ -0,0 +1,74 @@
(ns quo2.components.notifications.notification.view
(:require [quo2.components.markdown.text :as text]
[quo2.components.notifications.notification.style :as style]
[react-native.blur :as blur]
[react-native.core :as rn]))
(defn header-container
[& children]
[into
[rn/view {:accessibility-label :notification-header}] children])
(defn body-container
[& children]
[into [rn/view {:accessibility-label :notification-body}] children])
(defn avatar-container
[& children]
[into
[rn/view
{:style style/avatar-container
:accessibility-label :notification-avatar}]
children])
(defn title
([text weight] (title text weight nil))
([text weight override-theme]
[text/text
{:size :paragraph-1
:weight (or weight :semi-bold)
:style (style/title override-theme)
:accessibility-label :notification-title}
text]))
(defn message
[text override-theme]
[text/text
{:size :paragraph-2
:style (style/text override-theme)
:accessibility-label :notification-content}
text])
(defn- notification-container
[{:keys [avatar header body container-style override-theme]}]
[rn/view
{:style (merge style/box-container container-style)}
[blur/view
{:style style/blur-container
:blur-amount 13
:blur-radius 10
:blur-type :transparent
:overlay-color :transparent}]
[rn/view
{:style (style/content-container override-theme)}
avatar
[rn/view
{:style style/right-side-container}
header
body]]])
(defn notification
[{title-text :title :keys [avatar header title-weight text body container-style override-theme]}]
(let [header (or header
(when title-text
[title title-text title-weight override-theme]))
header (when header [header-container header])
body (or body (when text [message text override-theme]))
body (when body [body-container body])
avatar (when avatar [avatar-container avatar])]
[notification-container
{:avatar avatar
:header header
:body body
:container-style container-style
:override-theme override-theme}]))

View File

@ -1,122 +0,0 @@
(ns quo2.components.notifications.toast
(:require [quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.components.notifications.count-down-circle :as count-down-circle]
[quo2.foundations.colors :as colors]
[quo2.foundations.shadows :as shadows]
[quo2.theme :as theme]
[utils.i18n :as i18n]
[react-native.blur :as blur]
[react-native.core :as rn]))
(def ^:private themes
{:container {:dark {:background-color colors/white-opa-70}
:light {:background-color colors/neutral-80-opa-70}}
:title {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:text {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:icon {:dark {:color colors/neutral-100}
:light {:color colors/white}}
:action-container {:dark {:background-color colors/neutral-80-opa-5}
:light {:background-color colors/white-opa-5}}})
(defn- merge-theme-style
[component-key styles override-theme]
(merge (get-in themes [component-key (or override-theme (theme/get-theme))]) styles))
(defn toast-action-container
[{:keys [on-press style]} & children]
[rn/touchable-highlight
{:on-press on-press
:underlay-color :transparent}
[into
[rn/view
{:style (merge
{:flex-direction :row
:padding-vertical 3
:padding-horizontal 8
:align-items :center
:border-radius 8
:background-color (get-in themes
[:action-container (theme/get-theme)
:background-color])}
style)}]
children]])
(defn toast-undo-action
[duration on-press override-theme]
[toast-action-container
{:on-press on-press :accessibility-label :toast-undo-action}
[rn/view {:style {:margin-right 5}}
[count-down-circle/circle-timer {:duration duration}]]
[text/text
{:size :paragraph-2 :weight :medium :style (merge-theme-style :text {} override-theme)}
[i18n/label :t/undo]]])
(defn- toast-container
[{:keys [left title text right container-style override-theme]}]
[rn/view
{:style (merge {:margin-horizontal 12
:border-radius 12
:overflow :hidden}
container-style)}
[blur/view
{:style {:height "100%"
:width "100%"
:position :absolute
:padding-vertical 8
:padding-left 10
:padding-right 8
:background-color :transparent}
:blur-amount 13
:blur-radius 10
:blur-type :transparent
:overlay-color :transparent}]
[rn/view
{:style (merge-theme-style :container
(merge
(:shadow-1 shadows/normal-scale)
{:flex-direction :row
:justify-content :space-between
:padding-vertical 8
:padding-left 10
:padding-right 8
:border-radius 12})
override-theme)}
[rn/view {:style {:padding 2}} left]
[rn/view {:style {:padding 4 :flex 1}}
(when title
[text/text
{:size :paragraph-1
:weight :semi-bold
:style (merge-theme-style :title {} override-theme)
:accessibility-label :toast-title}
title])
(when text
[text/text
{:size :paragraph-2
:weight :medium
:style (merge-theme-style :text {} override-theme)
:accessibility-label :toast-content}
text])]
(when right right)]])
(defn toast
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
override-theme]}]
[toast-container
{:left (when icon
[icon/icon icon
{:container-style {:width 20 :height 20}
:color (or icon-color
(get-in themes
[:icon (or override-theme (theme/get-theme))
:color]))}])
:title title
:text text
:right (if undo-duration
[toast-undo-action undo-duration undo-on-press override-theme]
action)
:container-style container-style
:override-theme override-theme}])

View File

@ -0,0 +1,55 @@
(ns quo2.components.notifications.toast.style
(:require
[quo2.foundations.colors :as colors]
[quo2.foundations.shadows :as shadows]))
(def box-container
{:margin-horizontal 12
:border-radius 12
:overflow :hidden})
(def blur-container
{:height "100%"
:width "100%"
:position :absolute
:padding-vertical 8
:padding-left 10
:padding-right 8
:background-color :transparent})
(defn content-container
[override-theme]
(merge
(:shadow-1 shadows/normal-scale)
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
:flex-direction :row
:justify-content :space-between
:padding-vertical 8
:padding-left 10
:padding-right 8
:border-radius 12}))
(defn title
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
(defn text
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
(defn icon
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)
:container-style {:width 20 :height 20}})
(def left-side-container {:padding 2})
(def right-side-container {:padding 4 :flex 1})
(defn action-container
[override-theme]
{:background-color (colors/theme-colors colors/white-opa-5 colors/neutral-80-opa-5 override-theme)
:flex-direction :row
:padding-vertical 3
:padding-horizontal 8
:align-items :center
:border-radius 8})

View File

@ -0,0 +1,76 @@
(ns quo2.components.notifications.toast.view
(:require [quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.components.notifications.count-down-circle :as count-down-circle]
[quo2.components.notifications.toast.style :as style]
[quo2.theme :as theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[utils.i18n :as i18n]))
(defn toast-action-container
[{:keys [on-press style]} & children]
[rn/touchable-highlight
{:on-press on-press
:underlay-color :transparent}
[into
[rn/view
{:style (merge (style/action-container (theme/get-theme)) style)}]
children]])
(defn toast-undo-action
[duration on-press override-theme]
[toast-action-container
{:on-press on-press :accessibility-label :toast-undo-action}
[rn/view {:style {:margin-right 5}}
[count-down-circle/circle-timer {:duration duration}]]
[text/text
{:size :paragraph-2 :weight :medium :style (style/text override-theme)}
[i18n/label :t/undo]]])
(defn- toast-container
[{:keys [left title text right container-style override-theme]}]
[rn/view
{:style (merge style/box-container container-style)}
[blur/view
{:style style/blur-container
:blur-amount 13
:blur-radius 10
:blur-type :transparent
:overlay-color :transparent}]
[rn/view
{:style (style/content-container override-theme)}
[rn/view {:style style/left-side-container} left]
[rn/view {:style style/right-side-container}
(when title
[text/text
{:size :paragraph-1
:weight :semi-bold
:style (style/title override-theme)
:accessibility-label :toast-title}
title])
(when text
[text/text
{:size :paragraph-2
:weight :medium
:style (style/text override-theme)
:accessibility-label :toast-content}
text])]
(when right right)]])
(defn toast
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
override-theme]}]
[toast-container
{:left (when icon
[icon/icon icon
(cond-> (style/icon override-theme)
icon-color
(assoc :color icon-color))])
:title title
:text text
:right (if undo-duration
[toast-undo-action undo-duration undo-on-press override-theme]
action)
:container-style container-style
:override-theme override-theme}])

View File

@ -31,13 +31,14 @@
quo2.components.info.info-message
quo2.components.info.information-box
quo2.components.inputs.input.view
quo2.components.inputs.title-input.view
quo2.components.inputs.profile-input.view
quo2.components.links.url-preview.view
quo2.components.inputs.title-input.view
quo2.components.links.url-preview-list.view
quo2.components.links.url-preview.view
quo2.components.list-items.channel
quo2.components.list-items.menu-item
quo2.components.list-items.preview-list
quo2.components.list-items.user-list
quo2.components.loaders.skeleton
quo2.components.markdown.text
quo2.components.messages.author.view
@ -49,7 +50,9 @@
quo2.components.notifications.count-down-circle
quo2.components.notifications.info-count
quo2.components.notifications.notification-dot
quo2.components.notifications.toast
quo2.components.notifications.notification.view
quo2.components.notifications.toast.view
quo2.components.onboarding.small-option-card.view
quo2.components.password.tips.view
quo2.components.profile.profile-card.view
quo2.components.profile.select-profile.view
@ -63,20 +66,17 @@
quo2.components.settings.privacy-option
quo2.components.share.qr-code.view
quo2.components.share.share-qr-code.view
quo2.components.onboarding.small-option-card.view
quo2.components.tabs.segmented-tab
quo2.components.tabs.account-selector
quo2.components.tabs.segmented-tab
quo2.components.tabs.tabs
quo2.components.tags.context-tag.view
quo2.components.tags.status-tags
quo2.components.tags.permission-tag
quo2.components.tags.status-tags
quo2.components.tags.tag
quo2.components.tags.tags
quo2.components.tags.token-tag
quo2.components.text-combinations.title.view
quo2.components.list-items.user-list))
quo2.components.text-combinations.title.view))
(def toast quo2.components.notifications.toast/toast)
(def button quo2.components.buttons.button/button)
(def dynamic-button quo2.components.buttons.dynamic-button/dynamic-button)
(def text quo2.components.markdown.text/text)
@ -163,6 +163,8 @@
(def info-count quo2.components.notifications.info-count/info-count)
(def notification-dot quo2.components.notifications.notification-dot/notification-dot)
(def count-down-circle quo2.components.notifications.count-down-circle/circle-timer)
(def notification quo2.components.notifications.notification.view/notification)
(def toast quo2.components.notifications.toast.view/toast)
;;;; PASSWORD
(def tips quo2.components.password.tips.view/view)

View File

@ -16,6 +16,7 @@
[quo2.components.links.url-preview-list.component-spec]
[quo2.components.links.url-preview.component-spec]
[quo2.components.markdown.--tests--.text-component-spec]
[quo2.components.notifications.notification.component-spec]
[quo2.components.onboarding.small-option-card.component-spec]
[quo2.components.password.tips.component-spec]
[quo2.components.profile.select-profile.component-spec]

View File

@ -331,13 +331,13 @@
[rn/view
{:style {:height height}}
[list/flat-list
{:keyboardShouldPersistTaps :always
:footer [rn/view {:style {:height 8}}]
:header [rn/view {:style {:height 8}}]
:data suggestions
:key-fn first
:render-data text-input-ref
:render-fn mention-item}]]]))))
{:keyboard-should-persist-taps :always
:footer [rn/view {:style {:height 8}}]
:header [rn/view {:style {:height 8}}]
:data suggestions
:key-fn first
:render-data text-input-ref
:render-fn mention-item}]]]))))
(defn on-chat-toolbar-layout
[^js ev]

View File

@ -65,9 +65,9 @@
[]
(letsubs [blocked-contacts [:contacts/blocked]]
[list.views/flat-list
{:data blocked-contacts
:key-fn :address
:render-fn contacts-list-item
:default-separator? true
:enableEmptySections true
:keyboardShouldPersistTaps :always}]))
{:data blocked-contacts
:key-fn :address
:render-fn contacts-list-item
:default-separator? true
:enableEmptySections true
:keyboard-should-persist-taps :always}]))

View File

@ -44,10 +44,10 @@
:on-change (fn [text]
(re-frame/dispatch [:search/currency-filter-changed text]))}]]
[list/flat-list
{:data (->> currencies
vals
(sort #(compare (:code %1) (:code %2))))
:key-fn :code
:render-data currency-id
:render-fn render-currency
:keyboardShouldPersistTaps :always}]]]))
{:data (->> currencies
vals
(sort #(compare (:code %1) (:code %2))))
:key-fn :code
:render-data currency-id
:render-fn render-currency
:keyboard-should-persist-taps :always}]]]))

View File

@ -219,11 +219,11 @@
[:ens/search-screen]]
[react/keyboard-avoiding-view {:flex 1}
[react/scroll-view
{:style {:flex 1}
{:style {:flex 1}
;;NOTE required so that switching custom-domain
;;works on first tap and persists keyboard
;;instead of dismissing keyboard and requiring two taps
:keyboardShouldPersistTaps :always}
:keyboard-should-persist-taps :always}
[react/view {:style {:flex 1}}
[react/view
{:style {:flex 1

View File

@ -76,11 +76,11 @@
(defn toggle-list
[{:keys [contacts render-fn render-data]}]
[list/flat-list
{:data contacts
:key-fn :public-key
:render-data render-data
:render-fn render-fn
:keyboardShouldPersistTaps :always}])
{:data contacts
:key-fn :public-key
:render-data render-data
:render-fn render-fn
:keyboard-should-persist-taps :always}])
(defn no-contacts
[{:keys [no-contacts]}]

View File

@ -58,8 +58,8 @@
banner-hidden [:keycard/banner-hidden]]
[react/keyboard-avoiding-view {:style ast/multiaccounts-view}
[react/scroll-view
{:keyboardShouldPersistTaps :always
:style styles/login-view}
{:keyboard-should-persist-taps :always
:style styles/login-view}
[react/view styles/login-badge-container
[multiaccount-login-badge multiaccount]
[react/view {:style styles/password-container}

View File

@ -28,8 +28,10 @@
(defn toast
[id]
(let [toast-opts (rf/sub [:toasts/toast id])]
[quo/toast toast-opts]))
(let [{:keys [type] :as toast-opts} (rf/sub [:toasts/toast id])]
(if (= type :notification)
[quo/notification toast-opts]
[quo/toast toast-opts])))
(defn container
[id]
@ -81,7 +83,7 @@
(rn/use-unmount on-dismissed)
[gesture/gesture-detector {:gesture pan}
[reanimated/view
{;; TODO: this will eanble layout animation at runtime and causing flicker on android
{;; TODO: this will enable layout animation at runtime and causing flicker on android
;; we need to resolve this and re-enable layout animation
;; issue at https://github.com/status-im/status-mobile/issues/14752
;; :entering slide-in-up-animation

View File

@ -29,9 +29,9 @@
:elevation 5
:max-height (/ max-y 2)})}
[rn/flat-list
{:keyboardShouldPersistTaps :always
:data (vals suggestions)
:key-fn :key
:render-fn mention-item
:render-data (:text-input-ref refs)
:accessibility-label :mentions-list}]]))])
{:keyboard-should-persist-taps :always
:data (vals suggestions)
:key-fn :key
:render-fn mention-item
:render-data (:text-input-ref refs)
:accessibility-label :mentions-list}]]))])

View File

@ -46,7 +46,7 @@
[]
[rn/view {:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -49,7 +49,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -48,7 +48,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -53,7 +53,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -80,7 +80,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -51,7 +51,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -40,7 +40,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -59,7 +59,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -93,7 +93,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -49,7 +49,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -117,7 +117,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -1,9 +1,9 @@
(ns status-im2.contexts.quo-preview.colors.color-picker
(:require [react-native.core :as rn]
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[reagent.core :as reagent]
[quo2.core :as quo]
[react-native.blur :as blur]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
@ -39,8 +39,8 @@
colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -61,8 +61,8 @@
colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -63,7 +63,7 @@
colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -63,7 +63,7 @@
colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -36,7 +36,7 @@
colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -39,7 +39,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -27,7 +27,7 @@
colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -48,7 +48,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -56,7 +56,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -72,8 +72,8 @@
{:background-color (colors/theme-colors colors/white colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:nestedScrollEnabled true
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn (fn [_ index] (str "actions-drawers-" index))}]])
{:flex 1
:nestedScrollEnabled true
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn (fn [_ index] (str "actions-drawers-" index))}]])

View File

@ -67,8 +67,8 @@
{:background-color (colors/theme-colors colors/white colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:nestedScrollEnabled true
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn :id}]])
{:flex 1
:nestedScrollEnabled true
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn :id}]])

View File

@ -78,9 +78,9 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:flex-grow 1
:nestedScrollEnabled true
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:flex-grow 1
:nestedScrollEnabled true
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -47,7 +47,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -51,7 +51,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -103,7 +103,7 @@
{:style {:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}}
[rn/flat-list
{:style {:flex 1}
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:style {:flex 1}
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -74,7 +74,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]]])

View File

@ -69,7 +69,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -67,7 +67,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]]])

View File

@ -37,12 +37,14 @@
[status-im2.contexts.quo-preview.foundations.shadows :as shadows]
[status-im2.contexts.quo-preview.info.info-message :as info-message]
[status-im2.contexts.quo-preview.info.information-box :as information-box]
[status-im2.contexts.quo-preview.inputs.input :as input]
[status-im2.contexts.quo-preview.inputs.profile-input :as profile-input]
[status-im2.contexts.quo-preview.inputs.title-input :as title-input]
[status-im2.contexts.quo-preview.links.url-preview :as url-preview]
[status-im2.contexts.quo-preview.links.url-preview-list :as url-preview-list]
[status-im2.contexts.quo-preview.list-items.channel :as channel]
[status-im2.contexts.quo-preview.list-items.preview-lists :as preview-lists]
[status-im2.contexts.quo-preview.list-items.user-list :as user-list]
[status-im2.contexts.quo-preview.markdown.text :as text]
[status-im2.contexts.quo-preview.messages.author :as messages-author]
[status-im2.contexts.quo-preview.messages.gap :as messages-gap]
@ -52,6 +54,7 @@
[status-im2.contexts.quo-preview.navigation.page-nav :as page-nav]
[status-im2.contexts.quo-preview.navigation.top-nav :as top-nav]
[status-im2.contexts.quo-preview.notifications.activity-logs :as activity-logs]
[status-im2.contexts.quo-preview.notifications.notification :as notification]
[status-im2.contexts.quo-preview.notifications.toast :as toast]
[status-im2.contexts.quo-preview.onboarding.small-option-card :as small-option-card]
[status-im2.contexts.quo-preview.password.tips :as tips]
@ -78,12 +81,10 @@
[status-im2.contexts.quo-preview.tags.tags :as tags]
[status-im2.contexts.quo-preview.tags.token-tag :as token-tag]
[status-im2.contexts.quo-preview.title.title :as title]
[status-im2.contexts.quo-preview.inputs.input :as input]
[status-im2.contexts.quo-preview.wallet.lowest-price :as lowest-price]
[status-im2.contexts.quo-preview.wallet.network-amount :as network-amount]
[status-im2.contexts.quo-preview.wallet.network-breakdown :as network-breakdown]
[status-im2.contexts.quo-preview.wallet.token-overview :as token-overview]
[status-im2.contexts.quo-preview.list-items.user-list :as user-list]))
[status-im2.contexts.quo-preview.wallet.token-overview :as token-overview]))
(def screens-categories
{:foundations [{:name :shadows
@ -226,7 +227,10 @@
:component activity-logs/preview-activity-logs}
{:name :toast
:insets {:top false}
:component toast/preview-toasts}]
:component toast/preview-toasts}
{:name :notification
:insets {:top false}
:component notification/preview-notification}]
:onboarding [{:name :small-option-card
:insets {:top false}
:component small-option-card/preview-small-option-card}]

View File

@ -48,7 +48,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -62,7 +62,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]]])

View File

@ -73,7 +73,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:header [preview]
:key-fn str
:keyboardShouldPersistTaps :always}]])
{:flex 1
:header [preview]
:key-fn str
:keyboard-should-persist-taps :always}]])

View File

@ -76,7 +76,7 @@
{:background-color colors/neutral-100
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -64,7 +64,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -126,7 +126,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [@trackable-cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [@trackable-cool-preview]
:key-fn str}]])

View File

@ -51,7 +51,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -188,7 +188,7 @@
[]
[rn/view {:flex 1}
[rn/flat-list
{:flex 1
:header [preview]
:key-fn str
:keyboardShouldPersistTaps :always}]])
{:flex 1
:header [preview]
:key-fn str
:keyboard-should-persist-taps :always}]])

View File

@ -0,0 +1,112 @@
(ns status-im2.contexts.quo-preview.notifications.notification
(:require [quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.buttons.button :as button]
[quo2.components.code.snippet :as snippet]
[quo2.components.info.info-message :as info-message]
[react-native.core :as rn]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.code.snippet :as snippet-preview]
[utils.re-frame :as rf]))
(defn notification-button
([id opts] (notification-button id id opts))
([text id opts]
(let [notification-opts (rf/sub [:toasts/toast id])
dismiss! #(rf/dispatch [:toasts/close id])
notification! #(rf/dispatch [:toasts/upsert (assoc opts :id id)])
dismissed? (not notification-opts)]
[rn/view {:style {:margin-bottom 10}}
[button/button
{:size 32
:on-press #(if dismissed? (notification!) (dismiss!))}
(if dismissed? text (str "DISMISS " text))]])))
(defn notification-button-0
[]
[notification-button
"Notification: empty"
{:duration 4000
:type :notification}])
(defn notification-button-1
[]
[notification-button
"Notification: with title(header)"
{:avatar [user-avatar/user-avatar
{:full-name "A Y"
:status-indicator? true
:online? true
:size :small
:customization-color :blue
:ring-background (resources/get-mock-image :ring)}]
:title "Alisher Yakupov accepted your contact request"
:duration 4000
:title-weight :medium
:type :notification}])
(defn notification-button-2
[]
[notification-button
"with title and body"
{:avatar [user-avatar/user-avatar
{:full-name "A Y"
:status-indicator? true
:online? true
:size :small
:customization-color :blue
:ring-background (resources/get-mock-image :ring)}]
:title "Default to semibold title"
:text "The quick brown fox jumped over the lazy dog and ate a potatoe."
:duration 4000
:type :notification}])
(defn notification-button-3
[]
[notification-button
"with anything as header & body"
{:avatar [user-avatar/user-avatar
{:full-name "A Y"
:status-indicator? true
:online? true
:size :small
:customization-color :blue
:ring-background (resources/get-mock-image :ring)}]
:header [rn/view
[info-message/info-message
{:type :success
:size :tiny
:icon :i/placeholder}
"info-message as title"]]
:body [snippet/snippet {:language :clojure :max-lines 15 :syntax true}
snippet-preview/clojure-example]
:duration 3000
:type :notification}])
(defn preview
[]
(fn []
[rn/view
[rn/view
{:background-color "#508485"
:flex-direction :column
:justify-content :flex-start
:height 300}]
[into
[rn/view
{:flex 1
:padding 16
:margin-top 60}]
[^{:key :0} [notification-button-0]
^{:key :1} [notification-button-1]
^{:key :2} [notification-button-2]
^{:key :3} [notification-button-3]]
]]))
(defn preview-notification
[]
[rn/view {:flex 1}
[rn/flat-list
{:flex 1
:header [preview]
:key-fn str
:keyboard-should-persist-taps :always}]])

View File

@ -109,7 +109,7 @@
[]
[rn/view {:flex 1}
[rn/flat-list
{:flex 1
:header [preview]
:key-fn str
:keyboardShouldPersistTaps :always}]])
{:flex 1
:header [preview]
:key-fn str
:keyboard-should-persist-taps :always}]])

View File

@ -52,7 +52,7 @@
{:style {:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -34,8 +34,8 @@
colors/neutral-95)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -80,7 +80,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -48,8 +48,8 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -45,7 +45,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -58,7 +58,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -50,7 +50,7 @@
{:style {:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}}
[rn/flat-list
{:style {:flex 1}
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:style {:flex 1}
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -65,7 +65,7 @@
{:style {:background-color (colors/theme-colors colors/white colors/neutral-95)
:flex 1}}
[rn/flat-list
{:style {:flex 1}
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:style {:flex 1}
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -45,7 +45,7 @@
[]
[rn/view {:style {:flex 1}}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -95,7 +95,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -174,7 +174,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -69,7 +69,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -55,7 +55,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -160,7 +160,7 @@
colors/neutral-95)
:flex 1}}
[rn/flat-list
{:style {:flex 1}
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:style {:flex 1}
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -200,7 +200,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -63,7 +63,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -92,7 +92,7 @@
colors/white
colors/neutral-90)}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -109,7 +109,7 @@
colors/white
colors/neutral-90)}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -72,7 +72,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -54,7 +54,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -69,7 +69,7 @@
colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])

View File

@ -68,7 +68,7 @@
{:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
{:flex 1
:keyboard-should-persist-taps :always
:header [cool-preview]
:key-fn str}]])