mirror of
https://github.com/status-im/status-react.git
synced 2025-02-02 06:07:33 +00:00
Scrollable tags (#14182)
* refactored scrollable-tags to share the same logic with scrollable-tabs * refactored tabs component to support scrollable-behaviour
This commit is contained in:
parent
4cdc166e41
commit
1cdcd298b0
@ -46,12 +46,12 @@
|
||||
^{:key id}
|
||||
[rn/view {:margin-right 8}
|
||||
[tag/tag
|
||||
{:id id
|
||||
:size 24
|
||||
:label tag-label
|
||||
:type :emoji
|
||||
:labelled true
|
||||
:resource resource}]])])
|
||||
{:id id
|
||||
:size 24
|
||||
:label tag-label
|
||||
:type :emoji
|
||||
:labelled? true
|
||||
:resource resource}]])])
|
||||
|
||||
(defn community-title
|
||||
[{:keys [title description size] :or {size :small}}]
|
||||
|
@ -28,28 +28,6 @@
|
||||
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)}}
|
||||
[notification-dot]])
|
||||
|
||||
(defn tabs
|
||||
[{:keys [default-active on-change style]}]
|
||||
(let [active-tab-id (reagent/atom default-active)]
|
||||
(fn [{:keys [data size] :or {size default-tab-size}}]
|
||||
[rn/view (merge {:flex-direction :row} style)
|
||||
(doall
|
||||
(for [{:keys [label id notification-dot? accessibility-label]} data]
|
||||
^{:key id}
|
||||
[rn/view {:style {:margin-right (if (= size default-tab-size) 12 8)}}
|
||||
(when notification-dot?
|
||||
[indicator])
|
||||
[tab/tab
|
||||
{:id id
|
||||
:size size
|
||||
:accessibility-label accessibility-label
|
||||
:active (= id @active-tab-id)
|
||||
:on-press (fn []
|
||||
(reset! active-tab-id id)
|
||||
(when on-change
|
||||
(on-change id)))}
|
||||
label]]))])))
|
||||
|
||||
(defn- calculate-fade-end-percentage
|
||||
[{:keys [offset-x content-width layout-width max-fade-percentage]}]
|
||||
(let [fade-percentage (max max-fade-percentage
|
||||
@ -60,30 +38,35 @@
|
||||
0.99
|
||||
(utils.number/naive-round fade-percentage 2))))
|
||||
|
||||
(defn scrollable-tabs
|
||||
"Just like the component `tabs`, displays horizontally scrollable tabs with
|
||||
extra options to control if/how the end of the scroll view fades.
|
||||
|
||||
Tabs are rendered using ReactNative's FlatList, which offers the convenient
|
||||
`scrollToIndex` method. FlatList accepts VirtualizedList and ScrollView props,
|
||||
and so does this component.
|
||||
|
||||
Usage:
|
||||
[tabs/scrollable-tabs
|
||||
{:scroll-on-press? true
|
||||
:fade-end? true
|
||||
:on-change #(...)
|
||||
:default-active :tab-a
|
||||
:data [{:id :tab-a :label \"Tab A\"}
|
||||
{:id :tab-b :label \"Tab B\"}]}]]
|
||||
|
||||
(defn tabs
|
||||
"Usage:
|
||||
{:type :icon/:emoji/:label
|
||||
:component tag/tab
|
||||
:size 32/24
|
||||
:on-press fn
|
||||
:blurred? true/false
|
||||
:labelled? true/false
|
||||
:disabled? true/false
|
||||
:scrollable? false
|
||||
:scroll-on-press? true
|
||||
:fade-end? true
|
||||
:on-change fn
|
||||
:default-active tag-id
|
||||
:data [{:id :label \"\" :resource \"url\"}
|
||||
{:id :label \"\" :resource \"url\"}]}
|
||||
Opts:
|
||||
- `size` number
|
||||
- `scroll-on-press?` When non-nil, clicking on a tab centers it the middle
|
||||
- `component` this is to determine which component is to be rendered since the
|
||||
logic in this view is shared between tab and tag component
|
||||
- `blurred` boolean: use to determine border color if the background is blurred
|
||||
- `type` can be icon or emoji with or without a tag label
|
||||
- `labelled` boolean: is true if tag has label else false
|
||||
- `size` number
|
||||
- `scroll-on-press?` When non-nil, clicking on a tag centers it the middle
|
||||
(with animation enabled).
|
||||
- `fade-end?` When non-nil, causes the end of the scrollable view to fade out.
|
||||
- `fade-end-percentage` Percentage where fading starts relative to the total
|
||||
- `fade-end?` When non-nil, causes the end of the scrollable view to fade out.
|
||||
- `fade-end-percentage` Percentage where fading starts relative to the total
|
||||
layout width of the `flat-list` data."
|
||||
|
||||
[{:keys [default-active fade-end-percentage]
|
||||
:or {fade-end-percentage 0.8}}]
|
||||
(let [active-tab-id (reagent/atom default-active)
|
||||
@ -97,99 +80,123 @@
|
||||
on-scroll
|
||||
scroll-event-throttle
|
||||
scroll-on-press?
|
||||
scrollable?
|
||||
style
|
||||
size
|
||||
blur?
|
||||
override-theme]
|
||||
:or {fade-end-percentage fade-end-percentage
|
||||
fade-end? false
|
||||
scroll-event-throttle 64
|
||||
scrollable? false
|
||||
scroll-on-press? false
|
||||
size default-tab-size}
|
||||
:as props}]
|
||||
(let [maybe-mask-wrapper (if fade-end?
|
||||
[masked-view/masked-view
|
||||
{:mask-element
|
||||
(reagent/as-element
|
||||
[linear-gradient/linear-gradient
|
||||
{:colors [:black :transparent]
|
||||
:locations [(get @fading :fade-end-percentage) 1]
|
||||
:start {:x 0 :y 0}
|
||||
:end {:x 1 :y 0}
|
||||
:pointer-events :none
|
||||
:style {:width "100%"
|
||||
:height "100%"}}])}]
|
||||
[:<>])]
|
||||
(conj
|
||||
maybe-mask-wrapper
|
||||
[rn/flat-list
|
||||
(merge
|
||||
(dissoc props
|
||||
:default-active
|
||||
:fade-end-percentage
|
||||
:fade-end?
|
||||
:on-change
|
||||
:scroll-on-press?
|
||||
:size)
|
||||
(when scroll-on-press?
|
||||
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
|
||||
{:ref #(reset! flat-list-ref %)
|
||||
:extra-data (str @active-tab-id)
|
||||
:horizontal true
|
||||
:scroll-event-throttle scroll-event-throttle
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:data data
|
||||
:key-fn (comp str :id)
|
||||
:on-scroll-to-index-failed identity
|
||||
:on-scroll (fn [^js e]
|
||||
(when fade-end?
|
||||
(let [offset-x (oget
|
||||
e
|
||||
"nativeEvent.contentOffset.x")
|
||||
content-width (oget
|
||||
e
|
||||
"nativeEvent.contentSize.width")
|
||||
layout-width
|
||||
(oget e "nativeEvent.layoutMeasurement.width")
|
||||
new-percentage
|
||||
(calculate-fade-end-percentage
|
||||
{:offset-x offset-x
|
||||
:content-width content-width
|
||||
:layout-width layout-width
|
||||
:max-fade-percentage fade-end-percentage})]
|
||||
;; Avoid unnecessary re-rendering.
|
||||
(when (not= new-percentage
|
||||
(get @fading :fade-end-percentage))
|
||||
(swap! fading assoc
|
||||
:fade-end-percentage
|
||||
new-percentage))))
|
||||
(when on-scroll
|
||||
(on-scroll e)))
|
||||
:render-fn (fn [{:keys [id label]} index]
|
||||
[rn/view
|
||||
{:style {:margin-right (if (= size default-tab-size)
|
||||
12
|
||||
8)
|
||||
:padding-right (when (= index
|
||||
(dec (count data)))
|
||||
(get-in props
|
||||
[:style
|
||||
:padding-left]))}}
|
||||
[tab/tab
|
||||
{:id id
|
||||
:size size
|
||||
:override-theme override-theme
|
||||
:blur? blur?
|
||||
:active (= id @active-tab-id)
|
||||
:on-press (fn [id]
|
||||
(reset! active-tab-id id)
|
||||
(when scroll-on-press?
|
||||
(.scrollToIndex ^js
|
||||
@flat-list-ref
|
||||
#js
|
||||
{:animated true
|
||||
:index index
|
||||
:viewPosition
|
||||
0.5}))
|
||||
(when on-change
|
||||
(on-change id)))}
|
||||
label]])})])))))
|
||||
(if scrollable?
|
||||
(let [maybe-mask-wrapper (if fade-end?
|
||||
[masked-view/masked-view
|
||||
{:mask-element
|
||||
(reagent/as-element
|
||||
[linear-gradient/linear-gradient
|
||||
{:colors [:black :transparent]
|
||||
:locations [(get @fading :fade-end-percentage) 1]
|
||||
:start {:x 0 :y 0}
|
||||
:end {:x 1 :y 0}
|
||||
:pointer-events :none
|
||||
:style {:width "100%"
|
||||
:height "100%"}}])}]
|
||||
[:<>])]
|
||||
(conj
|
||||
maybe-mask-wrapper
|
||||
[rn/flat-list
|
||||
(merge
|
||||
(dissoc props
|
||||
:default-active
|
||||
:fade-end-percentage
|
||||
:fade-end?
|
||||
:on-change
|
||||
:scroll-on-press?
|
||||
:size)
|
||||
(when scroll-on-press?
|
||||
{:initial-scroll-index (utils.collection/first-index #(= @active-tab-id (:id %)) data)})
|
||||
{:ref #(reset! flat-list-ref %)
|
||||
:extra-data (str @active-tab-id)
|
||||
:horizontal true
|
||||
:scroll-event-throttle scroll-event-throttle
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:data data
|
||||
:key-fn (comp str :id)
|
||||
:on-scroll-to-index-failed identity
|
||||
:on-scroll (fn [^js e]
|
||||
(when fade-end?
|
||||
(let [offset-x (oget
|
||||
e
|
||||
"nativeEvent.contentOffset.x")
|
||||
content-width
|
||||
(oget
|
||||
e
|
||||
"nativeEvent.contentSize.width")
|
||||
layout-width
|
||||
(oget e
|
||||
"nativeEvent.layoutMeasurement.width")
|
||||
new-percentage
|
||||
(calculate-fade-end-percentage
|
||||
{:offset-x offset-x
|
||||
:content-width content-width
|
||||
:layout-width layout-width
|
||||
:max-fade-percentage fade-end-percentage})]
|
||||
;; Avoid unnecessary re-rendering.
|
||||
(when (not= new-percentage
|
||||
(get @fading :fade-end-percentage))
|
||||
(swap! fading assoc
|
||||
:fade-end-percentage
|
||||
new-percentage))))
|
||||
(when on-scroll
|
||||
(on-scroll e)))
|
||||
:render-fn (fn [{:keys [id label]} index]
|
||||
[rn/view
|
||||
{:style {:margin-right (if (= size default-tab-size)
|
||||
12
|
||||
8)
|
||||
:padding-right (when (= index
|
||||
(dec (count data)))
|
||||
(get-in props
|
||||
[:style
|
||||
:padding-left]))}}
|
||||
[tab/tab
|
||||
{:id id
|
||||
:size size
|
||||
:override-theme override-theme
|
||||
:blur? blur?
|
||||
:active (= id @active-tab-id)
|
||||
:on-press (fn [id]
|
||||
(reset! active-tab-id id)
|
||||
(when scroll-on-press?
|
||||
(.scrollToIndex
|
||||
^js
|
||||
@flat-list-ref
|
||||
#js
|
||||
{:animated true
|
||||
:index index
|
||||
:viewPosition
|
||||
0.5}))
|
||||
(when on-change
|
||||
(on-change id)))}
|
||||
label]])})]))
|
||||
[rn/view (merge {:flex-direction :row} style)
|
||||
(doall
|
||||
(for [{:keys [label id notification-dot? accessibility-label]} data]
|
||||
^{:key id}
|
||||
[rn/view {:style {:margin-right (if (= size default-tab-size) 12 8)}}
|
||||
(when notification-dot?
|
||||
[indicator])
|
||||
[tab/tab
|
||||
{:id id
|
||||
:size size
|
||||
:accessibility-label accessibility-label
|
||||
:active (= id @active-tab-id)
|
||||
:on-press (fn []
|
||||
(reset! active-tab-id id)
|
||||
(when on-change
|
||||
(on-change id)))}
|
||||
label]]))]))))
|
||||
|
@ -16,25 +16,21 @@
|
||||
{:width size})))
|
||||
|
||||
(defn base-tag
|
||||
"opts
|
||||
{:type :icon/:emoji/:label/:permission
|
||||
:size 32/24}
|
||||
:labelled true"
|
||||
[_]
|
||||
(fn [{:keys [id size disabled border-color border-width background-color on-press
|
||||
accessibility-label label type]
|
||||
(fn [{:keys [id size disabled? border-color border-width background-color on-press
|
||||
accessibility-label labelled? type]
|
||||
:or {size 32}} children]
|
||||
[rn/touchable-without-feedback
|
||||
(merge {:disabled disabled
|
||||
(merge {:disabled disabled?
|
||||
:accessibility-label accessibility-label}
|
||||
(when on-press
|
||||
{:on-press #(on-press id)}))
|
||||
[rn/view
|
||||
{:style (merge (style-container size
|
||||
disabled
|
||||
disabled?
|
||||
border-color
|
||||
border-width
|
||||
background-color
|
||||
label
|
||||
labelled?
|
||||
type))}
|
||||
children]]))
|
||||
|
@ -68,26 +68,40 @@
|
||||
label])])
|
||||
|
||||
(defn tag
|
||||
"opts
|
||||
{:type :icon/:emoji/:label
|
||||
:size 32/24
|
||||
:on-press fn
|
||||
:blurred? true/false
|
||||
:resource icon/image
|
||||
:labelled? true/false
|
||||
:disabled? true/false}
|
||||
|
||||
opts
|
||||
- `blurred` boolean: use to determine border color if the background is blurred
|
||||
- `type` can be icon or emoji with or without a tag label
|
||||
- `labelled` boolean: is true if tag has label else false"
|
||||
[_ _]
|
||||
(fn [{:keys [id on-press disabled size resource active accessibility-label
|
||||
label type labelled blurred icon-color]
|
||||
(fn [{:keys [id on-press disabled? size resource active accessibility-label
|
||||
label type labelled? blurred? icon-color]
|
||||
:or {size 32}}]
|
||||
(let [state (cond disabled :disabled
|
||||
active :active
|
||||
:else :default)
|
||||
(let [state (cond disabled? :disabled
|
||||
active :active
|
||||
:else :default)
|
||||
{:keys [border-color blurred-border-color text-color]}
|
||||
(get-in themes [(theme/get-theme) state])]
|
||||
[base-tag/base-tag
|
||||
{:id id
|
||||
:size size
|
||||
:border-width 1
|
||||
:border-color (if blurred
|
||||
blurred-border-color
|
||||
border-color)
|
||||
:on-press on-press
|
||||
:accessibility-label accessibility-label
|
||||
:disabled disabled
|
||||
:type type
|
||||
:label label}
|
||||
[tag-resources size type resource icon-color label text-color labelled]])))
|
||||
[rn/view {:style {:align-items :center}}
|
||||
[base-tag/base-tag
|
||||
{:id id
|
||||
:size size
|
||||
:border-width 1
|
||||
:border-color (if blurred?
|
||||
blurred-border-color
|
||||
border-color)
|
||||
:on-press on-press
|
||||
:accessibility-label accessibility-label
|
||||
:disabled? disabled?
|
||||
:type type
|
||||
:labelled? (if (= type :label) true labelled?)}
|
||||
[tag-resources size type resource icon-color label text-color labelled?]]])))
|
||||
|
||||
|
@ -1,29 +1,171 @@
|
||||
(ns quo2.components.tags.tags
|
||||
(:require [quo2.components.tags.tag :as tag]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
(:require [reagent.core :as reagent]
|
||||
[quo.react-native :as rn]
|
||||
[oops.core :refer [oget]]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.core :as utils]
|
||||
[quo2.components.tags.tag :as tag]
|
||||
[utils.number :as number-utils]))
|
||||
|
||||
(def default-tab-size 32)
|
||||
|
||||
(defn calculate-fade-end-percentage
|
||||
[{:keys [offset-x content-width layout-width max-fade-percentage]}]
|
||||
(let [fade-percentage (max max-fade-percentage
|
||||
(/ (+ layout-width offset-x)
|
||||
content-width))]
|
||||
;; Truncate to avoid unnecessary rendering.
|
||||
(if (> fade-percentage 0.99)
|
||||
0.99
|
||||
(number-utils/naive-round fade-percentage 2))))
|
||||
|
||||
(defn tags
|
||||
[{:keys [default-active on-change]}]
|
||||
(let [active-tab-id (reagent/atom default-active)]
|
||||
(fn [{:keys [data size type labelled disabled blurred icon-color] :or {size 32}}]
|
||||
(let [active-id @active-tab-id]
|
||||
[rn/view {:flex-direction :row}
|
||||
(for [{:keys [tag-label id resource]} data]
|
||||
^{:key id}
|
||||
[rn/view {:margin-right 8}
|
||||
[tag/tag
|
||||
(merge {:id id
|
||||
:size size
|
||||
:type type
|
||||
:label (if labelled tag-label (when (= type :label) tag-label))
|
||||
:active (= id active-id)
|
||||
:disabled disabled
|
||||
:blurred blurred
|
||||
:icon-color icon-color
|
||||
:labelled (if (= type :label) true labelled)
|
||||
:resource (if (= type :icon)
|
||||
:i/placeholder
|
||||
resource)
|
||||
:on-press #(do (reset! active-tab-id %)
|
||||
(when on-change (on-change %)))})]])]))))
|
||||
"Usage:
|
||||
{:type :icon/:emoji/:label
|
||||
:component tag/tab
|
||||
:size 32/24
|
||||
:on-press fn
|
||||
:blurred? true/false
|
||||
:labelled? true/false
|
||||
:disabled? true/false
|
||||
:scroll-on-press? true
|
||||
:scrollable? false
|
||||
:fade-end? true
|
||||
:on-change fn
|
||||
:default-active tag-id
|
||||
:data [{:id :label \"\" :resource \"url\"}
|
||||
{:id :label \"\" :resource \"url\"}]}
|
||||
Opts:
|
||||
- `component` this is to determine which component is to be rendered since the
|
||||
logic in this view is shared between tab and tag component
|
||||
- `blurred` boolean: use to determine border color if the background is blurred
|
||||
- `type` can be icon or emoji with or without a tag label
|
||||
- `labelled` boolean: is true if tag has label else false
|
||||
- `size` number
|
||||
- `scroll-on-press?` When non-nil, clicking on a tag centers it the middle
|
||||
(with animation enabled).
|
||||
- `fade-end?` When non-nil, causes the end of the scrollable view to fade out.
|
||||
- `fade-end-percentage` Percentage where fading starts relative to the total
|
||||
layout width of the `flat-list` data."
|
||||
|
||||
[{:keys [default-active fade-end-percentage]
|
||||
:or {fade-end-percentage 0.8}}]
|
||||
(let [active-tab-id (reagent/atom default-active)
|
||||
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-event-throttle
|
||||
scrollable?
|
||||
scroll-on-press?
|
||||
size
|
||||
type
|
||||
labelled?
|
||||
disabled?
|
||||
blurred?
|
||||
icon-color]
|
||||
:or {fade-end-percentage fade-end-percentage
|
||||
fade-end? false
|
||||
scroll-event-throttle 64
|
||||
scrollable? false
|
||||
scroll-on-press? false
|
||||
size default-tab-size}
|
||||
:as props}]
|
||||
(let [maybe-mask-wrapper (if fade-end?
|
||||
[react/masked-view
|
||||
{:mask-element (reagent/as-element
|
||||
[react/linear-gradient
|
||||
{:colors [:black :transparent]
|
||||
:locations [(get @fading :fade-end-percentage)
|
||||
1]
|
||||
:start {:x 0 :y 0}
|
||||
:end {:x 1 :y 0}
|
||||
:pointer-events :none
|
||||
:style {:width "100%"
|
||||
:height "100%"}}])}]
|
||||
[:<>])]
|
||||
(if scrollable?
|
||||
(conj
|
||||
maybe-mask-wrapper
|
||||
[rn/flat-list
|
||||
(merge (dissoc props
|
||||
:default-active
|
||||
:fade-end-percentage
|
||||
:fade-end?
|
||||
:on-change
|
||||
:scroll-on-press?
|
||||
:size)
|
||||
(when scroll-on-press?
|
||||
{:initial-scroll-index (utils/first-index #(= @active-tab-id (:id %)) data)})
|
||||
{:ref #(reset! flat-list-ref %)
|
||||
:extra-data (str @active-tab-id)
|
||||
:horizontal true
|
||||
:scroll-event-throttle scroll-event-throttle
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:data data
|
||||
:key-fn (comp str :id)
|
||||
:on-scroll (fn [^js e]
|
||||
(when fade-end?
|
||||
(let [offset-x (oget e "nativeEvent.contentOffset.x")
|
||||
content-width (oget e "nativeEvent.contentSize.width")
|
||||
layout-width (oget e "nativeEvent.layoutMeasurement.width")
|
||||
new-percentage (calculate-fade-end-percentage
|
||||
{:offset-x offset-x
|
||||
:content-width content-width
|
||||
:layout-width layout-width
|
||||
:max-fade-percentage fade-end-percentage})]
|
||||
;; Avoid unnecessary re-rendering.
|
||||
(when (not= new-percentage (get @fading :fade-end-percentage))
|
||||
(swap! fading assoc :fade-end-percentage new-percentage))))
|
||||
(when on-scroll
|
||||
(on-scroll e)))
|
||||
:render-fn (fn [{:keys [id label resource]} index]
|
||||
[rn/view
|
||||
{:style {:margin-right (if (= size default-tab-size) 12 8)
|
||||
:padding-right (when (= index (dec (count data)))
|
||||
(get-in props [:style :padding-left]))}}
|
||||
[tag/tag
|
||||
{:id id
|
||||
:size size
|
||||
:active (= id @active-tab-id)
|
||||
:resource resource
|
||||
:blurred? blurred?
|
||||
:icon-color icon-color
|
||||
:disabled? disabled?
|
||||
:label label
|
||||
:type type
|
||||
:labelled? labelled?
|
||||
:on-press (fn [id]
|
||||
(reset! active-tab-id id)
|
||||
(when scroll-on-press?
|
||||
(.scrollToIndex @flat-list-ref
|
||||
#js
|
||||
{:animated true
|
||||
:index index
|
||||
:viewPosition 0.5}))
|
||||
(when on-change
|
||||
(on-change id)))}
|
||||
label]])})])
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
(for [{:keys [label id resource]} data]
|
||||
^{:key id}
|
||||
[rn/view {:style {:margin-right 8}}
|
||||
[tag/tag
|
||||
(merge {:id id
|
||||
:size size
|
||||
:type type
|
||||
:label (if labelled? label (when (= type :label) label))
|
||||
:active (= id active-tab-id)
|
||||
:disabled? disabled?
|
||||
:blurred? blurred?
|
||||
:icon-color icon-color
|
||||
:labelled? (if (= type :label) true labelled?)
|
||||
:resource (if (= type :icon)
|
||||
:i/placeholder
|
||||
resource)
|
||||
:on-press #(do (reset! active-tab-id %)
|
||||
(when on-change (on-change %)))})]])])))))
|
||||
|
@ -78,7 +78,6 @@
|
||||
(def audio-tag quo2.components.tags.context-tags/audio-tag)
|
||||
(def community-tag quo2.components.tags.context-tags/community-tag)
|
||||
(def tabs quo2.components.tabs.tabs/tabs)
|
||||
(def scrollable-tabs quo2.components.tabs.tabs/scrollable-tabs)
|
||||
(def account-selector quo2.components.tabs.account-selector/account-selector)
|
||||
(def floating-shell-button quo2.components.navigation.floating-shell-button/floating-shell-button)
|
||||
(def status-tag quo2.components.tags.status-tags/status-tag)
|
||||
|
@ -42,8 +42,9 @@
|
||||
(defn tabs
|
||||
[]
|
||||
(let [filter-type (rf/sub [:activity-center/filter-type])]
|
||||
[quo/scrollable-tabs
|
||||
[quo/tabs
|
||||
{:size 32
|
||||
:scrollable? true
|
||||
:blur? true
|
||||
:override-theme :dark
|
||||
:style style/tabs
|
||||
|
@ -12,11 +12,15 @@
|
||||
:options [{:key 32
|
||||
:value "32"}
|
||||
{:key 24
|
||||
:value "24"}]}])
|
||||
:value "24"}]}
|
||||
{:label "Scrollable:"
|
||||
:key :scrollable?
|
||||
:type :boolean}])
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:size 32})]
|
||||
(let [state (reagent/atom {:size 32
|
||||
:scrollable? false})]
|
||||
(fn []
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view {:padding-bottom 150}
|
||||
@ -33,7 +37,11 @@
|
||||
{:id 2 :label "Tab 2"}
|
||||
{:id 3 :label "Tab 3"}
|
||||
{:id 4 :label "Tab 4"}]
|
||||
:on-change #(println "Active tab" %)})]]]])))
|
||||
:on-change #(println "Active tab" %)}
|
||||
(when (:scrollable? @state)
|
||||
{:scroll-on-press? true
|
||||
:fade-end-percentage 0.4
|
||||
:fade-end? true}))]]]])))
|
||||
|
||||
(defn preview-tabs
|
||||
[]
|
||||
|
98
src/status_im2/contexts/quo_preview/tags/tag.cljs
Normal file
98
src/status_im2/contexts/quo_preview/tags/tag.cljs
Normal file
@ -0,0 +1,98 @@
|
||||
(ns status-im2.contexts.quo-preview.tags.tag
|
||||
(:require [quo.react-native :as rn]
|
||||
[quo.previews.preview :as preview]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.components.tags.tag :as tag]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.react-native.resources :as resources]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Size:"
|
||||
:key :size
|
||||
:type :select
|
||||
:options [{:key 32
|
||||
:value "32"}
|
||||
{:key 24
|
||||
:value "24"}]}
|
||||
{:label "Type:"
|
||||
:key :type
|
||||
:type :select
|
||||
:options [{:key :emoji
|
||||
:value "Emoji"}
|
||||
{:key :icon
|
||||
:value "Icons"}
|
||||
{:key :label
|
||||
:value "Label"}]}
|
||||
{:label "Labelled:"
|
||||
:key :labelled?
|
||||
:type :boolean}
|
||||
{:label "Disabled:"
|
||||
:key :disabled?
|
||||
:type :boolean}
|
||||
{:label "Blurred background:"
|
||||
:key :blurred?
|
||||
:type :boolean}])
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:size 32
|
||||
:labelled? true
|
||||
:type :emoji})]
|
||||
(fn []
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view
|
||||
{:style {:padding-bottom 150
|
||||
:padding-top 60}}
|
||||
[rn/view {:flex 1}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:justify-content :center
|
||||
:top 60
|
||||
:padding-horizontal 16}}
|
||||
(when (:blurred? @state)
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:height 100}}
|
||||
[react/image
|
||||
{:source (resources/get-image :community-cover)
|
||||
:style {:flex 1
|
||||
:width "100%"
|
||||
:border-radius 16}}]
|
||||
[react/blur-view
|
||||
{:flex 1
|
||||
:style {:border-radius 16
|
||||
:height 100
|
||||
:position :absolute
|
||||
:left 0
|
||||
:right 0}
|
||||
:blur-amount 20
|
||||
:overlay-color (colors/theme-colors
|
||||
colors/white-opa-70
|
||||
colors/neutral-80-opa-80)}]])
|
||||
[rn/view
|
||||
{:style {:position :absolute
|
||||
:align-self :center}}
|
||||
[tag/tag
|
||||
(merge @state
|
||||
{:id 1
|
||||
:label "Tag"
|
||||
:labelled? (if (= (:type @state) :label)
|
||||
true
|
||||
(:labelled? @state))
|
||||
:resource (if (= :emoji (:type @state))
|
||||
(resources/get-image :music)
|
||||
:main-icons2/placeholder)})]]]]])))
|
||||
(defn preview-tag
|
||||
[]
|
||||
[rn/view
|
||||
{:flex 1
|
||||
:background-color (colors/theme-colors
|
||||
colors/white
|
||||
colors/neutral-90)}
|
||||
[rn/flat-list
|
||||
{:flex 1
|
||||
:keyboardShouldPersistTaps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
@ -24,70 +24,85 @@
|
||||
:value "Icons"}
|
||||
{:key :label
|
||||
:value "Label"}]}
|
||||
{:label "Scrollable:"
|
||||
:key :scrollable?
|
||||
:type :boolean}
|
||||
{:label "Fade Out:"
|
||||
:key :fade-end-percentage
|
||||
:type :select
|
||||
:options [{:key 1
|
||||
:value "1%"}
|
||||
{:key 0.4
|
||||
:value "0.4%"}]}
|
||||
{:label "Labelled:"
|
||||
:key :labelled
|
||||
:key :labelled?
|
||||
:type :boolean}
|
||||
{:label "Disabled:"
|
||||
:key :disabled
|
||||
:key :disabled?
|
||||
:type :boolean}
|
||||
{:label "Blurred background:"
|
||||
:key :blurred
|
||||
:key :blurred?
|
||||
:type :boolean}])
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:size 32
|
||||
:labelled true
|
||||
:type :emoji})]
|
||||
(let [state (reagent/atom {:size 32
|
||||
:labelled? true
|
||||
:type :emoji
|
||||
:fade-end-percentage 0.4
|
||||
:scrollable? false})]
|
||||
(fn []
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view
|
||||
{:padding-bottom 150
|
||||
:padding-top 60}
|
||||
[rn/view {:flex 1}
|
||||
{:style {:padding-bottom 150
|
||||
:padding-top 60}}
|
||||
[rn/view {:style {:flex 1}}
|
||||
[preview/customizer state descriptor]]
|
||||
[rn/view
|
||||
{:flex 1
|
||||
:justify-content :center
|
||||
:top 60}
|
||||
(when (:blurred @state)
|
||||
[rn/view {:flex 1}
|
||||
[react/view
|
||||
{:flex-direction :row
|
||||
:height 100}
|
||||
[react/image
|
||||
{:source (resources/get-image :community-cover)
|
||||
:style {:flex 1
|
||||
:height 100
|
||||
:border-radius 16}}]]
|
||||
[react/view
|
||||
{:flex-direction :row
|
||||
:height 100
|
||||
:position :absolute
|
||||
:left 0
|
||||
:right 0}
|
||||
[react/blur-view
|
||||
{:flex 1
|
||||
:style {:border-radius 16
|
||||
:height 100}
|
||||
:blur-amount 40
|
||||
:overlay-color (colors/theme-colors
|
||||
colors/white-opa-70
|
||||
colors/neutral-80-opa-80)}]]])
|
||||
[rn/scroll-view
|
||||
{:justify-content :center
|
||||
:align-items :center
|
||||
:position :absolute
|
||||
:padding-horizontal 10}
|
||||
{:style {:flex 1
|
||||
:justify-content :center
|
||||
:top 60
|
||||
:padding-horizontal 16}}
|
||||
(when (:blurred? @state)
|
||||
[rn/view
|
||||
{:align-items :center
|
||||
:height 100
|
||||
:border-radius 16}
|
||||
[react/image
|
||||
{:source (resources/get-image :community-cover)
|
||||
:style {:flex 1
|
||||
:width "100%"
|
||||
:border-radius 16}}]
|
||||
[react/blur-view
|
||||
{:flex 1
|
||||
:style {:border-radius 16
|
||||
:height 100
|
||||
:position :absolute
|
||||
:left 0
|
||||
:right 0}
|
||||
:blur-amount 20
|
||||
:overlay-color (colors/theme-colors
|
||||
colors/white-opa-70
|
||||
colors/neutral-80-opa-80)}]])
|
||||
[rn/view
|
||||
{:style {:position :absolute
|
||||
:align-self :center}}
|
||||
[tags/tags
|
||||
(merge
|
||||
@state
|
||||
{:default-active 1
|
||||
:data [{:id 1 :tag-label "Music" :resource (resources/get-image :music)}
|
||||
{:id 2 :tag-label "Lifestyle" :resource (resources/get-image :lifestyle)}
|
||||
{:id 3
|
||||
:tag-label "Podcasts"
|
||||
:resource (resources/get-image :podcasts)}]})]]]]])))
|
||||
:component :tags
|
||||
:labelled? (if (= :label type) true (:labelled? @state))
|
||||
:resource (when (= type :icon)
|
||||
:main-icons2/placeholder)
|
||||
:data [{:id 1 :label "Music" :resource (resources/get-image :music)}
|
||||
{:id 2 :label "Lifestyle" :resource (resources/get-image :lifestyle)}
|
||||
{:id 2 :label "Podcasts" :resource (resources/get-image :podcasts)}
|
||||
{:id 2 :label "Music" :resource (resources/get-image :music)}
|
||||
{:id 3 :label "Lifestyle" :resource (resources/get-image :lifestyle)}]}
|
||||
(when (:scrollable? @state)
|
||||
{:scroll-on-press? true
|
||||
:fade-end? true}))]]]]])))
|
||||
(defn preview-tags
|
||||
[]
|
||||
[rn/view
|
||||
|
Loading…
x
Reference in New Issue
Block a user