migrate reagent part 3 (#19165)
This commit is contained in:
parent
98cdf00276
commit
e26d3a856d
|
@ -1,7 +1,6 @@
|
||||||
(ns quo.components.colors.color-picker.component-spec
|
(ns quo.components.colors.color-picker.component-spec
|
||||||
(:require
|
(:require
|
||||||
[quo.components.colors.color-picker.view :as color-picker]
|
[quo.components.colors.color-picker.view :as color-picker]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[test-helpers.component :as h]))
|
[test-helpers.component :as h]))
|
||||||
|
|
||||||
(h/describe "color-picker"
|
(h/describe "color-picker"
|
||||||
|
@ -12,7 +11,7 @@
|
||||||
(-> (h/expect event)
|
(-> (h/expect event)
|
||||||
(.toHaveBeenCalled))))
|
(.toHaveBeenCalled))))
|
||||||
(h/test "color picker color changed"
|
(h/test "color picker color changed"
|
||||||
(let [selected (reagent/atom nil)]
|
(let [selected (atom nil)]
|
||||||
(h/render [color-picker/view {:on-change #(reset! selected %)}])
|
(h/render [color-picker/view {:on-change #(reset! selected %)}])
|
||||||
(h/fire-event :press (get (h/get-all-by-label-text :color-picker-item) 0))
|
(h/fire-event :press (get (h/get-all-by-label-text :color-picker-item) 0))
|
||||||
(-> (h/expect @selected)
|
(-> (h/expect @selected)
|
||||||
|
|
|
@ -6,8 +6,7 @@
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.reanimated :as reanimated]
|
[react-native.reanimated :as reanimated]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(def header-height 56)
|
(def header-height 56)
|
||||||
|
|
||||||
|
@ -57,7 +56,7 @@
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
:align-items :flex-end})
|
:align-items :flex-end})
|
||||||
|
|
||||||
(defn title-style
|
(defn get-title-style
|
||||||
[{:keys [left right]} title-align]
|
[{:keys [left right]} title-align]
|
||||||
(merge
|
(merge
|
||||||
absolute-fill
|
absolute-fill
|
||||||
|
@ -133,15 +132,22 @@
|
||||||
:size :large}
|
:size :large}
|
||||||
title])])
|
title])])
|
||||||
|
|
||||||
(defn- header-internal
|
(defn header
|
||||||
[{:keys [left-width right-width]}]
|
[{:keys [left-accessories left-component border-bottom left-width right-width
|
||||||
(let [layout (reagent/atom {:left {:width (or left-width 8)
|
right-accessories right-component insets get-layout
|
||||||
|
title subtitle title-component style title-align
|
||||||
|
background]
|
||||||
|
:or {title-align :center
|
||||||
|
border-bottom false}}]
|
||||||
|
(let [theme (quo.theme/use-theme-value)
|
||||||
|
[layout set-layout] (rn/use-state {:left {:width (or left-width 8)
|
||||||
:height header-height}
|
:height header-height}
|
||||||
:right {:width (or right-width 8)
|
:right {:width (or right-width 8)
|
||||||
:height header-height}
|
:height header-height}
|
||||||
:title {:width 0
|
:title {:width 0
|
||||||
:height header-height}})
|
:height header-height}})
|
||||||
handle-layout (fn [el get-layout]
|
handle-layout (rn/use-callback
|
||||||
|
(fn [el get-layout]
|
||||||
(fn [evt]
|
(fn [evt]
|
||||||
(let [width (oget evt "nativeEvent" "layout" "width")
|
(let [width (oget evt "nativeEvent" "layout" "width")
|
||||||
height (oget evt "nativeEvent" "layout" "height")]
|
height (oget evt "nativeEvent" "layout" "height")]
|
||||||
|
@ -149,19 +155,16 @@
|
||||||
(get-layout el
|
(get-layout el
|
||||||
{:width width
|
{:width width
|
||||||
:height height}))
|
:height height}))
|
||||||
(swap! layout assoc
|
(set-layout
|
||||||
|
(assoc layout
|
||||||
el
|
el
|
||||||
{:width width
|
{:width width
|
||||||
:height height}))))]
|
:height height})))))
|
||||||
(fn
|
[layout])
|
||||||
[{:keys [left-accessories left-component border-bottom
|
status-bar-height (get insets :top 0)
|
||||||
right-accessories right-component insets get-layout
|
height (+ header-height status-bar-height)
|
||||||
title subtitle title-component style title-align
|
title-style (rn/use-memo (fn [] (get-title-style layout title-align))
|
||||||
background theme]
|
[layout title-align])]
|
||||||
:or {title-align :center
|
|
||||||
border-bottom false}}]
|
|
||||||
(let [status-bar-height (get insets :top 0)
|
|
||||||
height (+ header-height status-bar-height)]
|
|
||||||
[reanimated/view
|
[reanimated/view
|
||||||
{:style (header-wrapper-style {:height height
|
{:style (header-wrapper-style {:height height
|
||||||
:background background
|
:background background
|
||||||
|
@ -187,9 +190,8 @@
|
||||||
[header-actions
|
[header-actions
|
||||||
{:accessories left-accessories
|
{:accessories left-accessories
|
||||||
:component left-component}]]
|
:component left-component}]]
|
||||||
|
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style (title-style @layout title-align)
|
{:style title-style
|
||||||
:on-layout (handle-layout :title get-layout)
|
:on-layout (handle-layout :title get-layout)
|
||||||
:pointer-events :box-none}
|
:pointer-events :box-none}
|
||||||
[header-title
|
[header-title
|
||||||
|
@ -203,6 +205,4 @@
|
||||||
:pointer-events :box-none}
|
:pointer-events :box-none}
|
||||||
[header-actions
|
[header-actions
|
||||||
{:accessories right-accessories
|
{:accessories right-accessories
|
||||||
:component right-component}]]]]]]))))
|
:component right-component}]]]]]]))
|
||||||
|
|
||||||
(def header (quo.theme/with-theme header-internal))
|
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
[quo.components.markdown.text :as text]
|
[quo.components.markdown.text :as text]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme :as theme]
|
[quo.theme :as theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
;;; helpers
|
;;; helpers
|
||||||
(def themes
|
(def themes
|
||||||
|
@ -137,10 +136,11 @@
|
||||||
style
|
style
|
||||||
on-press
|
on-press
|
||||||
warning-label]}]
|
warning-label]}]
|
||||||
(let [body-height (reagent/atom nil)]
|
(let [[body-height set-body-height] (rn/use-state nil)
|
||||||
(fn []
|
on-layout (rn/use-callback #(set-body-height
|
||||||
|
(oget % "nativeEvent.layout.height")))]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:on-layout #(reset! body-height (oget % "nativeEvent.layout.height"))
|
{:on-layout on-layout
|
||||||
:overflow :hidden
|
:overflow :hidden
|
||||||
:flex 1}
|
:flex 1}
|
||||||
[hborder {:type :top}]
|
[hborder {:type :top}]
|
||||||
|
@ -157,4 +157,4 @@
|
||||||
[timeline]
|
[timeline]
|
||||||
[body timestamp-far timestamp-near on-info-button-pressed on-press warning-label]]
|
[body timestamp-far timestamp-near on-info-button-pressed on-press warning-label]]
|
||||||
[vborder :left body-height]
|
[vborder :left body-height]
|
||||||
[vborder :right body-height]])))
|
[vborder :right body-height]]))
|
||||||
|
|
|
@ -4,32 +4,32 @@
|
||||||
[quo.components.markdown.text :as text]
|
[quo.components.markdown.text :as text]
|
||||||
[quo.components.numbered-keyboard.keyboard-key.style :as style]
|
[quo.components.numbered-keyboard.keyboard-key.style :as style]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- label->accessibility-label
|
(defn- label->accessibility-label
|
||||||
[label]
|
[label]
|
||||||
(let [label-name (if (keyword? label) (name label) label)]
|
(let [label-name (if (keyword? label) (name label) label)]
|
||||||
(keyword (str "keyboard-key-" label-name))))
|
(keyword (str "keyboard-key-" label-name))))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn view
|
||||||
[]
|
[{:keys [disabled? blur? on-press on-long-press type]} label]
|
||||||
(let [pressed? (reagent/atom false)]
|
(let [theme (quo.theme/use-theme-value)
|
||||||
(fn [{:keys [disabled? theme blur? on-press on-long-press type]} label]
|
[pressed? set-pressed?] (rn/use-state false)
|
||||||
(let [label-color (style/get-label-color disabled? theme blur?)
|
on-press (rn/use-callback #(when on-press (on-press label)) [label])
|
||||||
background-color (style/toggle-background-color @pressed? blur? theme)]
|
on-long-press (rn/use-callback #(when (fn? on-long-press) (on-long-press label))
|
||||||
|
[label])
|
||||||
|
on-press-in (rn/use-callback #(set-pressed? true))
|
||||||
|
on-press-out (rn/use-callback #(set-pressed? false))
|
||||||
|
label-color (style/get-label-color disabled? theme blur?)
|
||||||
|
background-color (style/toggle-background-color pressed? blur? theme)]
|
||||||
[rn/pressable
|
[rn/pressable
|
||||||
{:accessibility-label (label->accessibility-label label)
|
{:accessibility-label (label->accessibility-label label)
|
||||||
:disabled (or disabled? (not label))
|
:disabled (or disabled? (not label))
|
||||||
:on-press (fn []
|
:on-press on-press
|
||||||
(when on-press
|
:on-long-press on-long-press
|
||||||
(on-press label)))
|
|
||||||
:on-long-press (fn []
|
|
||||||
(when (fn? on-long-press)
|
|
||||||
(on-long-press label)))
|
|
||||||
:allow-multiple-presses? true
|
:allow-multiple-presses? true
|
||||||
:on-press-in #(reset! pressed? true)
|
:on-press-in on-press-in
|
||||||
:on-press-out #(reset! pressed? false)
|
:on-press-out on-press-out
|
||||||
:hit-slop {:top 8 :bottom 8 :left 25 :right 25}
|
:hit-slop {:top 8 :bottom 8 :left 25 :right 25}
|
||||||
:style (style/container background-color)}
|
:style (style/container background-color)}
|
||||||
(case type
|
(case type
|
||||||
|
@ -48,6 +48,4 @@
|
||||||
{:color label-color
|
{:color label-color
|
||||||
:size 32
|
:size 32
|
||||||
:accessibility-label :derivation-path-label}]
|
:accessibility-label :derivation-path-label}]
|
||||||
nil)]))))
|
nil)]))
|
||||||
|
|
||||||
(def view (quo.theme/with-theme view-internal))
|
|
||||||
|
|
|
@ -3,37 +3,21 @@
|
||||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||||
[quo.components.markdown.text :as text]
|
[quo.components.markdown.text :as text]
|
||||||
[quo.components.profile.select-profile.style :as style]
|
[quo.components.profile.select-profile.style :as style]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn- on-change-handler
|
|
||||||
[selected? on-change]
|
|
||||||
(swap! selected? not)
|
|
||||||
(when on-change (on-change @selected?)))
|
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
"Options
|
"Options
|
||||||
- `default-selected?` The default selected state. Use when the component is not controlled.
|
|
||||||
- `selected?` Selected state. Use when the component is controlled.
|
- `selected?` Selected state. Use when the component is controlled.
|
||||||
- `name` Full name
|
- `name` Full name
|
||||||
- `profile-picture` Profile picture
|
- `profile-picture` Profile picture
|
||||||
- `customization-color` Customization color
|
- `customization-color` Customization color
|
||||||
- `(on-change selected?)` On change event handler
|
- `(on-change selected?)` On change event handler
|
||||||
"
|
"
|
||||||
[{:keys [default-selected?]}]
|
[{:keys [selected? profile-picture name customization-color on-change]
|
||||||
(let [internal-selected? (reagent/atom (or default-selected? false))]
|
|
||||||
(fn [{:keys [selected?
|
|
||||||
profile-picture
|
|
||||||
name
|
|
||||||
customization-color
|
|
||||||
on-change]
|
|
||||||
:or {customization-color :turquoise}}]
|
:or {customization-color :turquoise}}]
|
||||||
(when (and (not (nil? selected?)) (not= @internal-selected? selected?))
|
|
||||||
(reset! internal-selected? selected?))
|
|
||||||
[rn/touchable-opacity
|
[rn/touchable-opacity
|
||||||
{:style (style/container customization-color @internal-selected?)
|
{:style (style/container customization-color selected?)
|
||||||
:on-press #(on-change-handler internal-selected? on-change)
|
:on-press #(when on-change (on-change (not selected?)))
|
||||||
:active-opacity 1
|
|
||||||
:accessibility-label :select-profile}
|
:accessibility-label :select-profile}
|
||||||
[rn/view {:style style/header}
|
[rn/view {:style style/header}
|
||||||
[user-avatar/user-avatar
|
[user-avatar/user-avatar
|
||||||
|
@ -41,10 +25,11 @@
|
||||||
:status-indicator? false
|
:status-indicator? false
|
||||||
:size :medium
|
:size :medium
|
||||||
:profile-picture profile-picture}]
|
:profile-picture profile-picture}]
|
||||||
[rn/view {:style (style/select-radio @internal-selected?)}
|
[rn/view {:style (style/select-radio selected?)}
|
||||||
(when @internal-selected? [rn/view {:style style/select-radio-inner}])]]
|
(when selected?
|
||||||
|
[rn/view {:style style/select-radio-inner}])]]
|
||||||
[text/text
|
[text/text
|
||||||
{:size :heading-2
|
{:size :heading-2
|
||||||
:weight :semi-bold
|
:weight :semi-bold
|
||||||
:style style/profile-name}
|
:style style/profile-name}
|
||||||
name]])))
|
name]])
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
(ns quo.components.profile.showcase-nav.component-spec
|
(ns quo.components.profile.showcase-nav.component-spec
|
||||||
(:require
|
(:require
|
||||||
[quo.components.profile.showcase-nav.view :as view]
|
[quo.components.profile.showcase-nav.view :as view]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[test-helpers.component :as h]))
|
[test-helpers.component :as h]))
|
||||||
|
|
||||||
(def nav-data
|
(def nav-data
|
||||||
|
@ -35,7 +34,7 @@
|
||||||
(.toHaveBeenCalled))))
|
(.toHaveBeenCalled))))
|
||||||
|
|
||||||
(h/test "active id updated"
|
(h/test "active id updated"
|
||||||
(let [active-id (reagent/atom :recent)]
|
(let [active-id (atom :recent)]
|
||||||
(h/render [view/view
|
(h/render [view/view
|
||||||
{:data nav-data
|
{:data nav-data
|
||||||
:on-press #(reset! active-id %)}])
|
:on-press #(reset! active-id %)}])
|
||||||
|
|
|
@ -7,17 +7,23 @@
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.draggable-flatlist :as draggable-flatlist]
|
[react-native.draggable-flatlist :as draggable-flatlist]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(defn on-drag-end-fn
|
(defn key-fn [item index] (str (:title item) index))
|
||||||
[data atom-data]
|
|
||||||
(reset! atom-data data)
|
|
||||||
(reagent/flush))
|
|
||||||
|
|
||||||
(defn- reorder-category-internal
|
(defn reorder-category
|
||||||
[{:keys [label data blur? theme container-style]}]
|
[{:keys [label data blur? container-style]}]
|
||||||
(reagent/with-let [atom-data (reagent/atom data)]
|
(let [theme (quo.theme/use-theme-value)
|
||||||
|
[atom-data set-atom-data] (rn/use-state data)
|
||||||
|
render-fn (rn/use-callback
|
||||||
|
(fn [item _ _ _ _ drag]
|
||||||
|
[reorder-item/reorder-item item types/item
|
||||||
|
{:blur? blur? :drag drag}])
|
||||||
|
[blur?])
|
||||||
|
on-drag-end-fn (rn/use-callback (fn [_ _ data] (set-atom-data data)))
|
||||||
|
separator (rn/use-memo (fn [] [rn/view
|
||||||
|
{:style (style/reorder-separator blur? theme)}])
|
||||||
|
[blur? theme])]
|
||||||
[rn/view {:style (merge (style/container label) container-style)}
|
[rn/view {:style (merge (style/container label) container-style)}
|
||||||
[text/text
|
[text/text
|
||||||
{:weight :medium
|
{:weight :medium
|
||||||
|
@ -25,14 +31,9 @@
|
||||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||||
label]
|
label]
|
||||||
[draggable-flatlist/draggable-flatlist
|
[draggable-flatlist/draggable-flatlist
|
||||||
{:data @atom-data
|
{:data atom-data
|
||||||
:key-fn (fn [item index] (str (:title item) index))
|
:key-fn key-fn
|
||||||
:style style/reorder-items
|
:style style/reorder-items
|
||||||
:render-fn (fn [item _ _ _ _ drag] [reorder-item/reorder-item item types/item
|
:render-fn render-fn
|
||||||
{:blur? blur? :drag drag}])
|
:on-drag-end-fn on-drag-end-fn
|
||||||
:on-drag-end-fn (fn [_ _ data]
|
:separator separator}]]))
|
||||||
(on-drag-end-fn data atom-data))
|
|
||||||
:separator [rn/view
|
|
||||||
{:style (style/reorder-separator blur? theme)}]}]]))
|
|
||||||
|
|
||||||
(def reorder-category (quo.theme/with-theme reorder-category-internal))
|
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme]
|
[quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[schema.core :as schema]
|
[schema.core :as schema]
|
||||||
[utils.i18n :as i18n]))
|
[utils.i18n :as i18n]))
|
||||||
|
|
||||||
|
@ -190,20 +189,20 @@
|
||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[props]
|
[props]
|
||||||
(reagent/with-let [component-width (reagent/atom nil)
|
(let [[component-width
|
||||||
container-component [rn/view {:background-color style/overlay-color}]]
|
set-component-width] (rn/use-state nil)
|
||||||
|
on-layout (rn/use-callback #(set-component-width
|
||||||
|
(oops/oget % "nativeEvent.layout.width")))
|
||||||
|
props (-> props
|
||||||
|
(assoc :component-width component-width)
|
||||||
|
(clojure.set/rename-keys {:type :share-qr-type}))]
|
||||||
[quo.theme/provider {:theme :dark}
|
[quo.theme/provider {:theme :dark}
|
||||||
[rn/view
|
[rn/view
|
||||||
{:accessibility-label :share-qr-code
|
{:accessibility-label :share-qr-code
|
||||||
:style style/outer-container
|
:style style/outer-container
|
||||||
:on-layout #(reset! component-width (oops/oget % "nativeEvent.layout.width"))}
|
:on-layout on-layout}
|
||||||
(conj container-component
|
[rn/view {:style {:background-color style/overlay-color}}
|
||||||
(when @component-width
|
(when component-width
|
||||||
[share-qr-code
|
[share-qr-code props])]]]))
|
||||||
(-> props
|
|
||||||
(assoc :component-width @component-width)
|
|
||||||
(clojure.set/rename-keys {:type :share-qr-type}))]))]]))
|
|
||||||
|
|
||||||
(def view
|
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||||
(quo.theme/with-theme
|
|
||||||
(schema/instrument #'view-internal component-schema/?schema)))
|
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
[quo.components.tabs.tab.view :as tab]
|
[quo.components.tabs.tab.view :as tab]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]))
|
||||||
[reagent.core :as reagent]))
|
|
||||||
|
|
||||||
(def themes-for-blur
|
(def themes-for-blur
|
||||||
{:light {:background-color colors/neutral-80-opa-5}
|
{:light {:background-color colors/neutral-80-opa-5}
|
||||||
|
@ -14,12 +13,17 @@
|
||||||
{:light {:background-color colors/neutral-10}
|
{:light {:background-color colors/neutral-10}
|
||||||
:dark {:background-color colors/neutral-90}})
|
:dark {:background-color colors/neutral-90}})
|
||||||
|
|
||||||
(defn- segmented-control-internal
|
(defn segmented-control
|
||||||
[{:keys [default-active on-change]}]
|
[{:keys [data size blur? container-style item-container-style
|
||||||
(let [active-tab-id (reagent/atom default-active)]
|
active-item-container-style default-active on-change]}]
|
||||||
(fn [{:keys [data size theme blur? container-style item-container-style
|
(let [theme (quo.theme/use-theme-value)
|
||||||
active-item-container-style]}]
|
[active-tab-id
|
||||||
(let [active-id @active-tab-id]
|
set-active-tab-id] (rn/use-state default-active)
|
||||||
|
on-press (rn/use-callback
|
||||||
|
(fn [tab-id]
|
||||||
|
(set-active-tab-id tab-id)
|
||||||
|
(when on-change (on-change tab-id)))
|
||||||
|
[on-change])]
|
||||||
[rn/view
|
[rn/view
|
||||||
(merge
|
(merge
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
|
@ -44,11 +48,6 @@
|
||||||
:segmented? true
|
:segmented? true
|
||||||
:size size
|
:size size
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:active (= id active-id)
|
:active (= id active-tab-id)
|
||||||
:on-press (fn [tab-id]
|
:on-press on-press}
|
||||||
(reset! active-tab-id tab-id)
|
label]])]))
|
||||||
(when on-change
|
|
||||||
(on-change tab-id)))}
|
|
||||||
label]])]))))
|
|
||||||
|
|
||||||
(def segmented-control (quo.theme/with-theme segmented-control-internal))
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
(into [:<>] children)))
|
(into [:<>] children)))
|
||||||
|
|
||||||
(defn- on-scroll-handler
|
(defn- on-scroll-handler
|
||||||
[{:keys [on-scroll fading fade-end-percentage fade-end?]} ^js e]
|
[{:keys [on-scroll fading set-fading fade-end-percentage fade-end?]} ^js e]
|
||||||
(when fade-end?
|
(when fade-end?
|
||||||
(let [offset-x (oget e "nativeEvent.contentOffset.x")
|
(let [offset-x (oget e "nativeEvent.contentOffset.x")
|
||||||
content-width (oget e "nativeEvent.contentSize.width")
|
content-width (oget e "nativeEvent.contentSize.width")
|
||||||
|
@ -52,11 +52,8 @@
|
||||||
:layout-width layout-width
|
:layout-width layout-width
|
||||||
:max-fade-percentage fade-end-percentage})]
|
:max-fade-percentage fade-end-percentage})]
|
||||||
;; Avoid unnecessary re-rendering.
|
;; Avoid unnecessary re-rendering.
|
||||||
(when (not= new-percentage
|
(when (not= new-percentage (get fading :fade-end-percentage))
|
||||||
(get @fading :fade-end-percentage))
|
(set-fading (assoc fading :fade-end-percentage new-percentage)))))
|
||||||
(swap! fading assoc
|
|
||||||
:fade-end-percentage
|
|
||||||
new-percentage))))
|
|
||||||
(when on-scroll
|
(when on-scroll
|
||||||
(on-scroll e)))
|
(on-scroll e)))
|
||||||
|
|
||||||
|
@ -64,6 +61,7 @@
|
||||||
[{:keys [id label notification-dot? accessibility-label]}
|
[{:keys [id label notification-dot? accessibility-label]}
|
||||||
index _
|
index _
|
||||||
{:keys [active-tab-id
|
{:keys [active-tab-id
|
||||||
|
set-active-tab-id
|
||||||
blur?
|
blur?
|
||||||
customization-color
|
customization-color
|
||||||
flat-list-ref
|
flat-list-ref
|
||||||
|
@ -85,9 +83,9 @@
|
||||||
:accessibility-label accessibility-label
|
:accessibility-label accessibility-label
|
||||||
:size size
|
:size size
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:active (= id @active-tab-id)
|
:active (= id active-tab-id)
|
||||||
:on-press (fn [id]
|
:on-press (fn [id]
|
||||||
(reset! active-tab-id id)
|
(set-active-tab-id id)
|
||||||
(when (and scroll-on-press? @flat-list-ref)
|
(when (and scroll-on-press? @flat-list-ref)
|
||||||
(.scrollToIndex ^js @flat-list-ref
|
(.scrollToIndex ^js @flat-list-ref
|
||||||
#js
|
#js
|
||||||
|
@ -118,48 +116,44 @@
|
||||||
- `scroll-on-press?` When non-nil, clicking on a tag centers it the middle
|
- `scroll-on-press?` When non-nil, clicking on a tag centers it the middle
|
||||||
(with animation enabled).
|
(with animation enabled).
|
||||||
"
|
"
|
||||||
[{:keys [default-active fade-end-percentage]
|
[{:keys [default-active data fade-end-percentage fade-end? on-change on-scroll scroll-on-press?
|
||||||
:or {fade-end-percentage 0.8}}]
|
scrollable? style container-style size blur? in-scroll-view? customization-color]
|
||||||
(let [active-tab-id (reagent/atom default-active)
|
:or {fade-end-percentage 0.8
|
||||||
fading (reagent/atom {:fade-end-percentage fade-end-percentage})
|
|
||||||
flat-list-ref (atom nil)]
|
|
||||||
(fn
|
|
||||||
[{:keys [data
|
|
||||||
fade-end-percentage
|
|
||||||
fade-end?
|
|
||||||
on-change
|
|
||||||
on-scroll
|
|
||||||
scroll-on-press?
|
|
||||||
scrollable?
|
|
||||||
style
|
|
||||||
container-style
|
|
||||||
size
|
|
||||||
blur?
|
|
||||||
in-scroll-view?
|
|
||||||
customization-color]
|
|
||||||
:or {fade-end-percentage fade-end-percentage
|
|
||||||
fade-end? false
|
fade-end? false
|
||||||
scrollable? false
|
scrollable? false
|
||||||
scroll-on-press? false
|
scroll-on-press? false
|
||||||
size default-tab-size}
|
size default-tab-size}
|
||||||
:as props}]
|
:as props}]
|
||||||
(if scrollable?
|
(let [[active-tab-id
|
||||||
[rn/view {:style {:margin-top (- (dec unread-count-offset))}}
|
set-active-tab-id] (rn/use-state default-active)
|
||||||
[masked-view-wrapper
|
[fading set-fading] (rn/use-state {:fade-end-percentage fade-end-percentage})
|
||||||
{:fade-end-percentage (get @fading :fade-end-percentage) :fade-end? fade-end?}
|
flat-list-ref (rn/use-ref-atom nil)
|
||||||
[(if in-scroll-view?
|
clean-props (dissoc props
|
||||||
gesture/flat-list
|
|
||||||
rn/flat-list)
|
|
||||||
(merge
|
|
||||||
(dissoc props
|
|
||||||
:default-active
|
:default-active
|
||||||
:fade-end-percentage
|
:fade-end-percentage
|
||||||
:fade-end?
|
:fade-end?
|
||||||
:on-change
|
:on-change
|
||||||
:scroll-on-press?
|
:scroll-on-press?
|
||||||
:size)
|
:size)
|
||||||
|
on-scroll (rn/use-callback
|
||||||
|
(partial on-scroll-handler
|
||||||
|
{:fade-end-percentage fade-end-percentage
|
||||||
|
:fade-end? fade-end?
|
||||||
|
:fading fading
|
||||||
|
:set-fading set-fading
|
||||||
|
:on-scroll on-scroll})
|
||||||
|
[fade-end? fading])]
|
||||||
|
(if scrollable?
|
||||||
|
[rn/view {:style {:margin-top (- (dec unread-count-offset))}}
|
||||||
|
[masked-view-wrapper
|
||||||
|
{:fade-end-percentage (get fading :fade-end-percentage) :fade-end? fade-end?}
|
||||||
|
[(if in-scroll-view?
|
||||||
|
gesture/flat-list
|
||||||
|
rn/flat-list)
|
||||||
|
(merge
|
||||||
|
clean-props
|
||||||
(when scroll-on-press?
|
(when scroll-on-press?
|
||||||
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
|
{:initial-scroll-index (utils.collection/first-index #(= active-tab-id (:id %)) data)})
|
||||||
{:ref #(reset! flat-list-ref %)
|
{:ref #(reset! flat-list-ref %)
|
||||||
:style style
|
:style style
|
||||||
;; The padding-top workaround is needed because on Android
|
;; The padding-top workaround is needed because on Android
|
||||||
|
@ -175,13 +169,10 @@
|
||||||
:data data
|
:data data
|
||||||
:key-fn (comp str :id)
|
:key-fn (comp str :id)
|
||||||
:on-scroll-to-index-failed identity
|
:on-scroll-to-index-failed identity
|
||||||
:on-scroll (partial on-scroll-handler
|
:on-scroll on-scroll
|
||||||
{:fade-end-percentage fade-end-percentage
|
|
||||||
:fade-end? fade-end?
|
|
||||||
:fading fading
|
|
||||||
:on-scroll on-scroll})
|
|
||||||
:render-fn tab-view
|
:render-fn tab-view
|
||||||
:render-data {:active-tab-id active-tab-id
|
:render-data {:active-tab-id active-tab-id
|
||||||
|
:set-active-tab-id set-active-tab-id
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:flat-list-ref flat-list-ref
|
:flat-list-ref flat-list-ref
|
||||||
|
@ -195,10 +186,11 @@
|
||||||
^{:key (:id item)}
|
^{:key (:id item)}
|
||||||
[tab-view item index nil
|
[tab-view item index nil
|
||||||
{:active-tab-id active-tab-id
|
{:active-tab-id active-tab-id
|
||||||
|
:set-active-tab-id set-active-tab-id
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:number-of-items (count data)
|
:number-of-items (count data)
|
||||||
:on-change on-change
|
:on-change on-change
|
||||||
:size size
|
:size size
|
||||||
:style style}])
|
:style style}])
|
||||||
data)]))))
|
data)])))
|
||||||
|
|
Loading…
Reference in New Issue