Add reorder-item component (#16225)

This commit is contained in:
mmilad75 2023-06-16 14:26:38 +03:30 committed by GitHub
parent 2cbc94320d
commit 563a266803
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 453 additions and 30 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,29 @@
(ns quo2.components.settings.reorder-item.component-spec
(:require [test-helpers.component :as h]
[quo2.core :as quo]
[quo2.components.settings.reorder-item.types :as types]))
(h/describe
"sortable list items tests"
(h/test "renders item"
(h/render [quo/reorder-item
{:id 1
:type "item"
:image-size 24
:title "Item 1"} types/item])
(h/is-truthy (h/get-by-text "Item 1")))
(h/test "renders item placeholder"
(h/render [quo/reorder-item {:label "Item 1"} types/placeholder])
(h/is-truthy (h/get-by-text "Item 1")))
(h/test "renders item skeleton"
(let [component (h/render [quo/reorder-item nil types/skeleton])]
(h/is-truthy component)))
(h/test "renders item tab"
(h/render [quo/reorder-item
{:data [{:id 1
:label "Item 1"}
]} types/tab])
(h/is-truthy (h/get-by-text "Item 1"))))

View File

@ -0,0 +1,47 @@
(ns quo2.components.settings.reorder-item.items.item
(:require [react-native.core :as rn]
[quo2.components.settings.reorder-item.style :as style]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]))
(defn view
[{:keys
[title
subtitle
image
image-size
right-text
right-icon
on-press]}]
[rn/touchable-opacity
{:on-press on-press
:style (merge (style/item-container) (when subtitle style/item-container-extended))}
[icon/icon :main-icons/drag
{:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)}]
[rn/view
{:style style/body-container}
[rn/view
{:style style/image-container}
[rn/image
{:source image
:style (style/image image-size)}]]
[rn/view
{:style style/text-container}
[rn/view
[text/text
{:style style/item-text
:weight :medium}
title]
(when subtitle
[text/text
{:style style/item-subtitle
:weight :regular}
subtitle])]
(when right-text
[text/text {:style style/right-text} right-text])
(when right-icon
[rn/view {:style style/right-icon-container} [icon/icon right-icon (style/right-icon)]])]]
[icon/icon :tiny-icons/chevron-right (style/chevron)]])

View File

@ -0,0 +1,15 @@
(ns quo2.components.settings.reorder-item.items.item-placeholder
(:require [react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.components.settings.reorder-item.style :as style]))
(defn view
[item]
(let [label (:label item)]
[rn/view
{:accessibility-label :reorder-placerholder-drag-handle
:style (style/placeholder-container)}
[text/text
{:style (style/placeholder-text)
:weight :regular}
label]]))

View File

@ -0,0 +1,8 @@
(ns quo2.components.settings.reorder-item.items.item-skeleton
(:require [quo.react-native :as rn]
[quo2.components.settings.reorder-item.style :as style]))
(defn view
[]
[rn/view
{:style (style/skeleton-container)}])

View File

@ -0,0 +1,40 @@
(ns quo2.components.settings.reorder-item.items.item-tabs
(:require [quo2.components.tabs.segmented-tab :as quo2]
[quo.react-native :as rn]
[quo.components.text :as text]
[quo2.components.settings.reorder-item.style :as style]
[quo2.components.icon :as quo2-icons]))
(defn render-tab-item
[item]
(let [tab-image (cond
(item :image) [rn/image
{:source (:image item)
:style style/tab-item-image}]
(item :icon) [rn/view {:style style/tab-item-image}
(quo2-icons/icon (:icon item) (style/tab-icon))])]
[rn/view
{:style style/tab-item-container}
tab-image
[text/text
{:style style/tab-item-label
:width :medium}
(:label item)]]))
(defn transform-data
[data]
(map #(hash-map :id (:id %) :label (render-tab-item %)) data))
(defn view
[{:keys [data default-active on-change]
:or {default-active 1
on-change (constantly nil)}}]
[quo2/segmented-control
{:default-active default-active
:size 32
:blur? false
:container-style (style/tab-container)
:item-container-style (style/segmented-tab-item-container)
:active-item-container-style (style/active-segmented-tab-item-container)
:data (transform-data data)
:on-change on-change}])

View File

@ -0,0 +1,145 @@
(ns quo2.components.settings.reorder-item.style
(:require [quo2.foundations.colors :as colors]))
(defn item-container
[]
{:flex-direction :row
:align-items :center
:padding-horizontal 10
:border-radius 14
:margin-bottom 23
:height 45
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
(def item-container-extended
{:height 52})
(def body-container
{:flex 1
:margin-left 12
:flex-direction :row
:align-items :center
:margin-right -6})
(def image-container
{:margin-right 8})
(defn image
[size]
{:width size
:height size})
(def item-text
{:font-size 14})
(defn chevron
[]
{:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)
:height 14
:width 14})
(def item-subtitle
{:color colors/neutral-50
:font-size 13})
(def right-text
{:font-size 15
:color colors/neutral-40})
(def text-container
{:flex 1
:flex-direction :row
:justify-content :space-between
:margin-right 8})
(defn right-icon
[]
{:height 20
:width 20
:color (colors/theme-colors
colors/neutral-40
colors/neutral-40)})
(def right-icon-container
{:justify-content :center})
(defn placeholder-container
[]
{:background-color :transparent
:border-width 1
:border-color (colors/theme-colors
colors/neutral-30
colors/neutral-80)
:padding 12
:justify-content :center
:align-items :center
:border-radius 16
:margin-bottom 24
:border-style :dashed})
(defn placeholder-text
[]
{:color (colors/theme-colors
colors/neutral-40
colors/neutral-50)
:font-size 13})
(defn skeleton-container
[]
{:background-color (colors/theme-colors
colors/neutral-5
colors/neutral-95)
:border-radius 16
:margin-bottom 24
:height 48})
(defn tab-container
[]
{:background-color (colors/theme-colors
colors/neutral-5
colors/neutral-95)
:padding-horizontal 4
:padding-vertical 6
:margin-bottom 24})
(defn segmented-tab-item-container
[]
{:height 40
:border-width 1
:border-style :dashed
:margin-horizontal 2
:border-color (colors/theme-colors
colors/neutral-30
colors/neutral-60)})
(defn active-segmented-tab-item-container
[]
{:height 40
:background-color (colors/theme-colors
colors/neutral-30
colors/neutral-90)})
(def tab-item-container
{:flex-direction :row
:justify-content :center
:align-items :center})
(def tab-item-image
{:height 19
:width 19
:margin-right 3})
(def tab-item-label
{:font-size 14})
(defn tab-icon
[]
{:height 16
:width 16
:color (colors/theme-colors
colors/neutral-40
colors/neutral-40)})

View File

@ -0,0 +1,6 @@
(ns quo2.components.settings.reorder-item.types)
(def ^:const item 0)
(def ^:const placeholder 1)
(def ^:const skeleton 2)
(def ^:const tab 3)

View File

@ -0,0 +1,16 @@
(ns quo2.components.settings.reorder-item.view
(:require
[quo2.components.settings.reorder-item.items.item :as item]
[quo2.components.settings.reorder-item.items.item-placeholder :as placeholder]
[quo2.components.settings.reorder-item.items.item-skeleton :as skeleton]
[quo2.components.settings.reorder-item.items.item-tabs :as tab]
[quo2.components.settings.reorder-item.types :as types]))
(defn reorder-item
[item type]
(case type
types/item [item/view item]
types/placeholder [placeholder/view item]
types/skeleton [skeleton/view]
types/tab [tab/view item]
nil))

View File

@ -16,32 +16,37 @@
(defn segmented-control (defn segmented-control
[{:keys [default-active on-change]}] [{:keys [default-active on-change]}]
(let [active-tab-id (reagent/atom default-active)] (let [active-tab-id (reagent/atom default-active)]
(fn [{:keys [data size override-theme blur?]}] (fn [{:keys [data size override-theme blur? container-style item-container-style
active-item-container-style]}]
(let [active-id @active-tab-id] (let [active-id @active-tab-id]
[rn/view [rn/view
{:flex-direction :row (merge
:background-color (get-in (if blur? themes-for-blur themes) {:flex-direction :row
[(or override-theme (theme/get-theme)) :background-color]) :background-color (get-in (if blur? themes-for-blur themes)
:border-radius (case size [(or override-theme (theme/get-theme)) :background-color])
32 10 :border-radius (case size
28 8 32 10
24 8 28 8
20 6) 24 8
:padding 2} 20 6)
:padding 2}
container-style)
(for [[indx {:keys [label id]}] (map-indexed vector data)] (for [[indx {:keys [label id]}] (map-indexed vector data)]
^{:key id} ^{:key id}
[rn/view [rn/view
{:margin-left (if (= 0 indx) 0 2) {:margin-left (if (= 0 indx) 0 2)
:flex 1} :flex 1}
[tab/view [tab/view
{:id id {:id id
:segmented? true :active-item-container-style active-item-container-style
:size size :item-container-style item-container-style
:override-theme override-theme :segmented? true
:blur? blur? :size size
:active (= id active-id) :override-theme override-theme
:on-press (fn [tab-id] :blur? blur?
(reset! active-tab-id tab-id) :active (= id active-id)
(when on-change :on-press (fn [tab-id]
(on-change tab-id)))} (reset! active-tab-id tab-id)
(when on-change
(on-change tab-id)))}
label]])])))) label]])]))))

View File

@ -50,6 +50,8 @@
[{:keys [accessibility-label [{:keys [accessibility-label
active active
before before
item-container-style
active-item-container-style
blur? blur?
disabled disabled
id id
@ -79,12 +81,16 @@
[notification-dot/notification-dot [notification-dot/notification-dot
{:style style/notification-dot}]) {:style style/notification-dot}])
[rn/view [rn/view
{:style (style/tab {:style (merge
{:size size (style/tab
:disabled disabled {:size size
:segmented? segmented? :background-color (if (and segmented? (not active))
:background-color (if (and segmented? (not active)) :transparent background-color) :transparent
:show-notification-dot? show-notification-dot?})} background-color)
:disabled disabled
:segmented? segmented?
:show-notification-dot? show-notification-dot?})
(if active active-item-container-style item-container-style))}
(when before (when before
[rn/view [rn/view
[icons/icon before {:color icon-color}]]) [icons/icon before {:color icon-color}]])

View File

@ -87,7 +87,8 @@
quo2.components.tags.tags quo2.components.tags.tags
quo2.components.tags.token-tag quo2.components.tags.token-tag
quo2.components.text-combinations.title.view quo2.components.text-combinations.title.view
quo2.components.settings.settings-list.view)) quo2.components.settings.settings-list.view
quo2.components.settings.reorder-item.view))
(def text quo2.components.markdown.text/text) (def text quo2.components.markdown.text/text)
(def icon quo2.components.icon/icon) (def icon quo2.components.icon/icon)
@ -210,6 +211,7 @@
(def privacy-option quo2.components.settings.privacy-option/card) (def privacy-option quo2.components.settings.privacy-option/card)
(def account quo2.components.settings.accounts.view/account) (def account quo2.components.settings.accounts.view/account)
(def settings-list quo2.components.settings.settings-list.view/settings-list) (def settings-list quo2.components.settings.settings-list.view/settings-list)
(def reorder-item quo2.components.settings.reorder-item.view/reorder-item)
;;;; SHARE ;;;; SHARE
(def qr-code quo2.components.share.qr-code.view/qr-code) (def qr-code quo2.components.share.qr-code.view/qr-code)

View File

@ -34,4 +34,5 @@
[quo2.components.selectors.selectors.component-spec] [quo2.components.selectors.selectors.component-spec]
[quo2.components.settings.settings-list.component-spec] [quo2.components.settings.settings-list.component-spec]
[quo2.components.share.share-qr-code.component-spec] [quo2.components.share.share-qr-code.component-spec]
[quo2.components.tags.--tests--.status-tags-component-spec])) [quo2.components.tags.--tests--.status-tags-component-spec]
[quo2.components.settings.reorder-item.component-spec]))

View File

@ -44,16 +44,20 @@
:no-notifications-dark (js/require "../resources/images/ui2/no-notifications-dark.png")}) :no-notifications-dark (js/require "../resources/images/ui2/no-notifications-dark.png")})
(def mock-images (def mock-images
{:coinbase (js/require "../resources/images/mock2/coinbase.png") {:diamond (js/require "../resources/images/mock2/diamond.png")
:coinbase (js/require "../resources/images/mock2/coinbase.png")
:collectible (js/require "../resources/images/mock2/collectible.png") :collectible (js/require "../resources/images/mock2/collectible.png")
:contact (js/require "../resources/images/mock2/contact.png")
:community-banner (js/require "../resources/images/mock2/community-banner.png") :community-banner (js/require "../resources/images/mock2/community-banner.png")
:community-logo (js/require "../resources/images/mock2/community-logo.png") :community-logo (js/require "../resources/images/mock2/community-logo.png")
:community-cover (js/require "../resources/images/mock2/community-cover.png") :community-cover (js/require "../resources/images/mock2/community-cover.png")
:decentraland (js/require "../resources/images/mock2/decentraland.png") :decentraland (js/require "../resources/images/mock2/decentraland.png")
:gif (js/require "../resources/images/mock2/gif.png") :gif (js/require "../resources/images/mock2/gif.png")
:monkey (js/require "../resources/images/mock2/monkey.png")
:photo1 (js/require "../resources/images/mock2/photo1.png") :photo1 (js/require "../resources/images/mock2/photo1.png")
:photo2 (js/require "../resources/images/mock2/photo2.png") :photo2 (js/require "../resources/images/mock2/photo2.png")
:photo3 (js/require "../resources/images/mock2/photo3.png") :photo3 (js/require "../resources/images/mock2/photo3.png")
:pinterest (js/require "../resources/images/mock2/pinterest.png")
:qr-code (js/require "../resources/images/mock2/qr-code.png") :qr-code (js/require "../resources/images/mock2/qr-code.png")
:rarible (js/require "../resources/images/mock2/rarible.png") :rarible (js/require "../resources/images/mock2/rarible.png")
:small-opt-card-icon (js/require "../resources/images/mock2/small_opt_card_icon.png") :small-opt-card-icon (js/require "../resources/images/mock2/small_opt_card_icon.png")
@ -61,6 +65,7 @@
:status-logo (js/require "../resources/images/mock2/status-logo.png") :status-logo (js/require "../resources/images/mock2/status-logo.png")
:sticker (js/require "../resources/images/mock2/sticker.png") :sticker (js/require "../resources/images/mock2/sticker.png")
:ring (js/require "../resources/images/mock2/ring.png") :ring (js/require "../resources/images/mock2/ring.png")
:verified (js/require "../resources/images/mock2/verified.png")
:user-picture-female2 (js/require "../resources/images/mock2/user_picture_female2.png") :user-picture-female2 (js/require "../resources/images/mock2/user_picture_female2.png")
:user-picture-male4 (js/require "../resources/images/mock2/user_picture_male4.png") :user-picture-male4 (js/require "../resources/images/mock2/user_picture_male4.png")
:user-picture-male5 (js/require "../resources/images/mock2/user_picture_male5.png")}) :user-picture-male5 (js/require "../resources/images/mock2/user_picture_male5.png")})

View File

@ -78,6 +78,7 @@
[status-im2.contexts.quo-preview.settings.accounts :as accounts] [status-im2.contexts.quo-preview.settings.accounts :as accounts]
[status-im2.contexts.quo-preview.settings.settings-list :as settings-list] [status-im2.contexts.quo-preview.settings.settings-list :as settings-list]
[status-im2.contexts.quo-preview.settings.privacy-option :as privacy-option] [status-im2.contexts.quo-preview.settings.privacy-option :as privacy-option]
[status-im2.contexts.quo-preview.settings.reorder-item :as reorder-item]
[status-im2.contexts.quo-preview.share.qr-code :as qr-code] [status-im2.contexts.quo-preview.share.qr-code :as qr-code]
[status-im2.contexts.quo-preview.share.share-qr-code :as share-qr-code] [status-im2.contexts.quo-preview.share.share-qr-code :as share-qr-code]
[status-im2.contexts.quo-preview.switcher.switcher-cards :as switcher-cards] [status-im2.contexts.quo-preview.switcher.switcher-cards :as switcher-cards]
@ -317,7 +318,10 @@
:component accounts/preview-accounts} :component accounts/preview-accounts}
{:name :settings-list {:name :settings-list
:options {:topBar {:visible true}} :options {:topBar {:visible true}}
:component settings-list/preview-settings-list}] :component settings-list/preview-settings-list}
{:name :reorder-item
:options {:topBar {:visible true}}
:component reorder-item/preview-reorder-item}]
:share [{:name :qr-code :share [{:name :qr-code
:options {:topBar {:visible true}} :options {:topBar {:visible true}}
:component qr-code/preview-qr-code} :component qr-code/preview-qr-code}

View File

@ -0,0 +1,94 @@
(ns status-im2.contexts.quo-preview.settings.reorder-item
(:require
[quo2.core :as quo]
[react-native.core :as rn]
[status-im2.common.resources :as resources]
[quo2.foundations.colors :as colors]
[quo2.components.settings.reorder-item.types :as types]))
(def mock-data
[{:id 1
:type types/item
:data {:on-press (println "pressed")
:image (resources/get-mock-image :diamond)
:image-size 21
:right-icon :i/world
:title "Trip to Bahamas"}}
{:id 2
:type types/item
:data {:image (resources/get-mock-image :status-logo)
:image-size 21
:right-icon :i/world
:title "Status"}}
{:id 3
:type types/item
:data {:image (resources/tokens :eth)
:image-size 21
:right-icon :i/world
:title "Ethereum"}}
{:id 4
:type types/item
:data {:image (resources/get-mock-image :monkey)
:image-size 30
:right-icon :i/world
:title "3045"
:subtitle "Bored Ape Yatch Club"}}
{:id 5
:type types/item
:data {:image (resources/get-mock-image :pinterest)
:image-size 21
:right-text "@sheralito"
:title "Pinterest"}}
{:id 6
:type types/placeholder
:data {:label "Label"}}
{:id 7
:type types/placeholder
:data {:label "Label"}}
{:id 8
:type types/skeleton}
{:id 9
:type types/skeleton}
{:id 10
:type types/tab
:data {:data [{:id 1
:label "Everyone"
:icon :i/world}
{:id 2
:label "Contacts"
:image (resources/get-mock-image :contact)}
{:id 3
:label "Verified"
:image (resources/get-mock-image :verified)}]
:on-change (fn [tab-id] (println tab-id))
:default-active 2}}
{:id 11
:type types/tab
:data {:data [{:id 1
:label "Everyone"
:icon :i/world}
{:id 2
:label "Contacts"
:image (resources/get-mock-image :contact)}
{:id 3
:label "Verified"
:image (resources/get-mock-image :verified)}]
:on-change (fn [tab-id] (println tab-id))
:default-active 1}}])
(defn container
[]
{:padding-horizontal 38
:padding-vertical 20
:background-color (colors/theme-colors
colors/neutral-10
colors/neutral-100)
:flex 1})
(defn preview-reorder-item
[]
[rn/scroll-view
{:style (container)}
(for [item mock-data]
[quo/reorder-item (item :data) (item :type)])])