feat: new keycard component (#15892)
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 16 KiB |
|
@ -0,0 +1,20 @@
|
|||
(ns quo2.components.keycard.component-spec
|
||||
(:require [quo2.components.keycard.view :as keycard]
|
||||
[test-helpers.component :as h]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(h/describe "keycard component"
|
||||
(h/test "Render of keycard component when: Status = Empty, Locked = False"
|
||||
(h/render [keycard/keycard])
|
||||
(-> (h/expect (h/query-by-label-text :holder-name))
|
||||
(h/is-equal (i18n/label :t/empty-keycard))))
|
||||
|
||||
(h/test "Render of keycard component when: Status = Filled, Locked = False"
|
||||
(h/render [keycard/keycard {:holder-name? "Alisha"}])
|
||||
(-> (h/expect (h/query-by-label-text :holder-name))
|
||||
(h/is-equal (i18n/label :t/user-keycard {:name :holder-name}))))
|
||||
|
||||
(h/test "Render of keycard component when: Status = Filled, Locked = True"
|
||||
(h/render [keycard/keycard {:holder-name? "Alisha"}])
|
||||
(-> (h/expect (h/query-by-label-text :holder-name))
|
||||
(h/is-equal (i18n/label :t/user-keycard {:name :holder-name})))))
|
|
@ -0,0 +1,42 @@
|
|||
(ns quo2.components.keycard.style
|
||||
(:require [quo2.foundations.colors :as colors]))
|
||||
|
||||
(def keycard-height 210)
|
||||
(def keycard-chip-height 28)
|
||||
|
||||
(defn card-container
|
||||
[locked?]
|
||||
{:overflow :hidden
|
||||
:height keycard-height
|
||||
:align-items :flex-start
|
||||
:justify-content :space-between
|
||||
:border-width 1
|
||||
:border-color (if locked?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-80))
|
||||
:border-style :solid
|
||||
:border-radius 16
|
||||
:padding 16
|
||||
:background-color (if locked?
|
||||
(colors/theme-colors colors/danger colors/danger-opa-40)
|
||||
(colors/theme-colors colors/neutral-5 colors/neutral-90))})
|
||||
|
||||
(defn keycard-logo
|
||||
[locked?]
|
||||
{:tint-color (if locked? colors/white (colors/theme-colors colors/neutral-100 colors/white))})
|
||||
|
||||
(defn keycard-watermark
|
||||
[locked?]
|
||||
{:position :absolute
|
||||
:tint-color (if locked? colors/white-opa-5 (colors/theme-colors colors/neutral-100 colors/white))
|
||||
:align-self :center
|
||||
:height 280.48
|
||||
:transform [{:rotate "-30deg"} {:translateY -30}]
|
||||
:opacity (when-not locked? 0.02)
|
||||
:z-index 1})
|
||||
|
||||
(def keycard-chip
|
||||
{:height keycard-chip-height
|
||||
:position :absolute
|
||||
:right 16
|
||||
:top (/ (- keycard-height 28) 2)})
|
|
@ -0,0 +1,38 @@
|
|||
(ns quo2.components.keycard.view
|
||||
(:require [react-native.core :as rn]
|
||||
[quo2.components.keycard.style :as style]
|
||||
[quo2.components.tags.tag :as tag]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.foundations.resources :as resources]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn keycard
|
||||
"This component based on the following properties:
|
||||
- :holder-name - Can be owner's name. Default is Empty
|
||||
- :locked? - Boolean to specify whether the keycard is locked or not
|
||||
"
|
||||
[{:keys [holder-name locked?]}]
|
||||
(let [label (if (boolean holder-name)
|
||||
(i18n/label :t/user-keycard {:name holder-name})
|
||||
(i18n/label :t/empty-keycard))]
|
||||
[rn/view {:style (style/card-container locked?)}
|
||||
[rn/image
|
||||
{:source (resources/get-image :keycard-logo)
|
||||
:style (style/keycard-logo locked?)}]
|
||||
[rn/image
|
||||
{:source (resources/get-image
|
||||
(if (or locked? (colors/dark?)) :keycard-chip-dark :keycard-chip-light))
|
||||
:style style/keycard-chip}]
|
||||
[rn/image
|
||||
{:source (resources/get-image :keycard-watermark)
|
||||
:style (style/keycard-watermark locked?)}]
|
||||
[tag/tag
|
||||
{:size 32
|
||||
:type (when locked? :icon)
|
||||
:label label
|
||||
:labelled? true
|
||||
:blurred? true
|
||||
:resource (when locked? :i/locked)
|
||||
:accessibility-label :holder-name
|
||||
:icon-color colors/white-70-blur
|
||||
:override-theme (when locked? :dark)}]]))
|
|
@ -38,6 +38,7 @@
|
|||
quo2.components.inputs.recovery-phrase.view
|
||||
quo2.components.inputs.search-input.view
|
||||
quo2.components.inputs.title-input.view
|
||||
quo2.components.keycard.view
|
||||
quo2.components.links.url-preview-list.view
|
||||
quo2.components.links.url-preview.view
|
||||
quo2.components.links.link-preview.view
|
||||
|
@ -126,6 +127,7 @@
|
|||
|
||||
;;;; CARDS
|
||||
(def small-option-card quo2.components.onboarding.small-option-card.view/small-option-card)
|
||||
(def keycard quo2.components.keycard.view/keycard)
|
||||
|
||||
;;;; COLORS
|
||||
(def color-picker quo2.components.colors.color-picker.view/view)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
(ns quo2.foundations.resources)
|
||||
|
||||
(def ui
|
||||
{:keycard-logo (js/require "../resources/images/ui2/keycard-logo.png")
|
||||
:keycard-chip-light (js/require "../resources/images/ui2/keycard-chip-light.png")
|
||||
:keycard-chip-dark (js/require "../resources/images/ui2/keycard-chip-dark.png")
|
||||
:keycard-watermark (js/require "../resources/images/ui2/keycard-watermark.png")})
|
||||
|
||||
(defn get-image
|
||||
[k]
|
||||
(get ui k))
|
|
@ -15,7 +15,10 @@
|
|||
:use-keycard (js/require "../resources/images/ui2/keycard.png")
|
||||
:onboarding-illustration (js/require "../resources/images/ui2/onboarding_illustration.png")
|
||||
:qr-code (js/require "../resources/images/ui2/qr-code.png")
|
||||
})
|
||||
:keycard-logo (js/require "../resources/images/ui2/keycard-logo.png")
|
||||
:keycard-chip-light (js/require "../resources/images/ui2/keycard-chip-light.png")
|
||||
:keycard-chip-dark (js/require "../resources/images/ui2/keycard-chip-dark.png")
|
||||
:keycard-watermark (js/require "../resources/images/ui2/keycard-watermark.png")})
|
||||
|
||||
(def mock-images
|
||||
{:coinbase (js/require "../resources/images/mock2/coinbase.png")
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
(ns status-im2.contexts.quo-preview.keycard.keycard
|
||||
(:require [status-im2.contexts.quo-preview.preview :as preview]
|
||||
[react-native.core :as rn]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.core :as quo]))
|
||||
|
||||
(def descriptor
|
||||
[{:label "Holder"
|
||||
:key :holder-name
|
||||
:type :text}
|
||||
{:label "Locked?"
|
||||
:key :locked?
|
||||
:type :boolean}])
|
||||
|
||||
(defn cool-preview
|
||||
[]
|
||||
(let [state (reagent/atom {:holder-name nil
|
||||
:locked? true})]
|
||||
(fn
|
||||
[]
|
||||
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
|
||||
[rn/view [preview/customizer state descriptor]
|
||||
[quo/keycard
|
||||
{:holder-name? (:holder-name @state)
|
||||
:locked? (:locked? @state)}]]])))
|
||||
|
||||
(defn preview-keycard
|
||||
[]
|
||||
[rn/view
|
||||
{:style {:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||
:flex 1}}
|
||||
[rn/flat-list
|
||||
{:style {:flex 1}
|
||||
:keyboard-should-persist-taps :always
|
||||
:header [cool-preview]
|
||||
:key-fn str}]])
|
|
@ -90,7 +90,8 @@
|
|||
[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.wallet.token-overview :as token-overview]
|
||||
[status-im2.contexts.quo-preview.keycard.keycard :as keycard]))
|
||||
|
||||
(def screens-categories
|
||||
{:foundations [{:name :shadows
|
||||
|
@ -344,7 +345,10 @@
|
|||
:component network-breakdown/preview-network-breakdown}
|
||||
{:name :network-amount
|
||||
:options {:topBar {:visible true}}
|
||||
:component network-amount/preview}]})
|
||||
:component network-amount/preview}]
|
||||
:keycard [{:name :keycard-component
|
||||
:options {:topBar {:visible true}}
|
||||
:component keycard/preview-keycard}]})
|
||||
|
||||
(def screens (flatten (map val screens-categories)))
|
||||
|
||||
|
|
|
@ -992,7 +992,9 @@
|
|||
:your-data-belongs-to-you
|
||||
:your-data-belongs-to-you-description
|
||||
:your-recovery-phrase
|
||||
:your-recovery-phrase-description})
|
||||
:your-recovery-phrase-description
|
||||
:empty-keycard
|
||||
:user-keycard})
|
||||
|
||||
;; NOTE: the rest checkpoints are based on the previous one, defined
|
||||
;; like this:
|
||||
|
|
|
@ -1687,6 +1687,8 @@
|
|||
"database-reset-content": "Chats, contacts and settings have been deleted. You can use your account with your Keycard",
|
||||
"database-reset-warning": "Database will be reset. Chats, contacts and settings will be deleted",
|
||||
"empty-keycard-required": "Requires an empty Keycard",
|
||||
"empty-keycard": "Empty Keycard",
|
||||
"user-keycard": "{{name}} Card",
|
||||
"current": "Current",
|
||||
"choose-storage": "Choose storage",
|
||||
"choose-new-location-for-keystore": "Choose a new location to save your keystore file",
|
||||
|
|