Compare commits

..
Author SHA1 Message Date
Ibrahem Khalil 2931eb46aa Merge branch 'develop' into 17315 2023-09-21 10:34:10 +03:00
ibrkhalil 3fd26a0c07 Hardcode blue 2023-09-20 19:56:44 +03:00
Ibrahem Khalil 9f5feca2eb Merge branch 'develop' into 17315 2023-09-20 19:54:22 +03:00
Ibrahem Khalil d6d1313f86 Merge branch 'develop' into 17315 2023-09-20 16:26:15 +03:00
Ibrahem Khalil c1350f45f5 Merge branch 'develop' into 17315 2023-09-19 17:29:53 +03:00
Ibrkhalil bcd756f2cc Better approach 2023-09-19 16:03:33 +03:00
Ibrahem Khalil ec08fb2b1c Merge branch 'develop' into 17315 2023-09-19 11:13:05 +03:00
Ibrkhalil 32b91ed31e Group chat icon not showing 2023-09-19 11:10:11 +03:00
369 changed files with 3755 additions and 5880 deletions
+5
View File
@@ -136,6 +136,11 @@ quo.animated/re-timing
quo.design-system.colors/white
quo.design-system.colors/black
status-im.transport.core-test/messages
status-im.ethereum.core/sidechain?
status-im.ethereum.core/network-with-upstream-rpc?
status-im.ethereum.core/current-address
status-im.ethereum.core/network->network-name
status-im.ethereum.core/estimate-gas
quo.core/animated-header
quo.core/safe-area-provider
quo.core/safe-area-consumer
-1
View File
@@ -33,4 +33,3 @@ SWAP_ENABLED=1
STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
TEST_STATEOFUS=1
FAST_CREATE_COMMUNITY_ENABLED=1
-1
View File
@@ -19,4 +19,3 @@ ENABLE_ROOT_ALERT=1
MAX_IMAGES_BATCH=1
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=0
-6
View File
@@ -63,10 +63,4 @@ Documentation change PR (review please): https://github.com/status-im/status.im/
<!-- (PRs will only be accepted if squashed into single commit.) -->
### Before and after screenshots comparison
| Figma (if available) | iOS (if available) | Android (if available)
| --- | --- | --- |
| Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. |
status: ready <!-- Can be ready or wip -->
+1 -5
View File
@@ -309,11 +309,9 @@ $$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort
endef
lint: export TARGET := clojure
lint: export CLJ_LINTER_PRINT_WARNINGS ?= false
lint: ##@test Run code style checks
@sh scripts/lint-re-frame-in-quo-components.sh && \
sh scripts/lint-old-quo-usage.sh && \
clj-kondo --config .clj-kondo/config.edn --cache false --fail-level error --lint src $(if $(filter $(CLJ_LINTER_PRINT_WARNINGS),true),,| grep -v ': warning: ') && \
clj-kondo --config .clj-kondo/config.edn --cache false --fail-level error --lint src && \
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
sh scripts/lint-trailing-newline.sh && \
@@ -362,7 +360,6 @@ component-test-watch: export TARGET := clojure
component-test-watch: export COMPONENT_TEST := true
component-test-watch: export BABEL_ENV := test
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
rm -rf ./component-spec
yarn install
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js' -e cljs
@@ -370,7 +367,6 @@ component-test: export TARGET := clojure
component-test: export COMPONENT_TEST := true
component-test: export BABEL_ENV := test
component-test: ##@test Run component tests once in NodeJS
rm -rf ./component-spec
yarn install
yarn shadow-cljs compile component-test && \
jest --config=test/jest/jest.config.js
+1 -1
View File
@@ -16,7 +16,7 @@ We believe in a medium of pure free trade, economies with fair, permission-less
We want to take responsibility for our data, the way we conduct ourselves privately and promote this way of life to a mass audience.
We want deep insights into our own economies so we can make informed, data-driven decisions on how to make our lives better. The Ethereum blockchain, Smart Contracts, Swarm and Whisper provide us a path forward.
We want deep insights into our own economies so we can make informed, data-driven decisions on how to make our lives better. The Ethereum blockchain, Smart Contracts, Swarm and Whisper provides us a path forward.
If this interests you, **help us make Status a reality** - anyone can contribute and we need everyone at any skill level to participate.
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@set_ios_status_go_targets'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -48,7 +48,7 @@ pipeline {
steps {
sh """#!/bin/bash
set -eo pipefail
make lint CLJ_LINTER_PRINT_WARNINGS=true 2>&1 | tee ${LOG_FILE}
make lint 2>&1 | tee ${LOG_FILE}
"""
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
pipeline {
agent { label 'macos' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
pipeline {
agent { label params.AGENT_LABEL }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.7.15'
library 'status-jenkins-lib@v1.7.14'
pipeline {
agent {
-5
View File
@@ -35,11 +35,6 @@
[Component tests (jest) overview](component-tests-overview.md)
## Project details
[status-go introduction (recorded meeting)](https://drive.google.com/file/d/1B7TljmTZ8fHkqJH8ChU1Cp4FGDFM03gq/view)
[re-frame usage (recorded meeting)](https://drive.google.com/file/d/1qv_E0CEGzQpu_zGXD0gCTU5EvhC2k8Jy/view)
## Misc
-37
View File
@@ -45,42 +45,6 @@ To do this:
![geth.log path](images/debugging/geth-path.png)
## Inspecting database content
Encrypted database can be found using commands:
```
cd ~/Library/Developer/CoreSimulator/Devices
find ./ -name accounts.sql
```
To get unencrypted database you need to export it first:
- open the status app in simulator
- on login screen enter the correct password without logging in
- using repl execute statement to export db:
```
(re-frame.core/dispatch [:multiaccounts.login.ui/export-db-submitted])
```
- save generated `export.db` file
Now you can locate the `export.db` and open it with preferred db viewer.
**Android:**
```sh
adb root
adb pull /storage/emulated/0/Android/data/im.status.ethereum.debug/files/Download/export.db /path/to/store/export.db
```
If you're using a release build, change the path to `/storage/emulated/0/Android/data/im.status.ethereum/files/Download`
**iOS**
```
cd ~/Library/Developer/CoreSimulator/Devices
find ./ -name export.db
```
## Tips
### From @ilmotta:
@@ -98,4 +62,3 @@ Also to inspect logs in a more flexible manner, instead of the strict output fro
```
adb logcat | grep 'ReactNativeJS\|StatusModule\|GoLog'
```
+1 -1
View File
@@ -12,4 +12,4 @@
[vector-icons/icon :icon-name {:color ...}]
```
2x@2x
4. If you want platform specific icon use `.android` or `.ios` suffixes. Example `icon_name@2x.android.png`.:w
4. If you want paltform specific icon use `.android` or `.ios` suffixes. Example `icon_name@2x.android.png`.:w
+3 -3
View File
@@ -19,7 +19,7 @@ For now we support e2e for Android only.
## What's happening when any e2e job is running
Whenever we need to push set of test scripts we create 16 parallel sessions (max, but depending on amount of cases that are included in job) and each thread: 1) uploads Android .apk file to SauceLabs -> 2) runs through the test steps -> 3) receives results whether test failed on particular step or succeeded with no errors -> 3) Parse test results and push them as a Github comment (if the suite ran against respective PR) and into TestRail.
We push **whole automation test suite (currently 155, amount is changing)** against each nightly build (if the nightly builds job succeeded). Results of the test run are saved in TestRail.
We push **whole automation test suite (currently 155, amout is changing)** against each nightly build (if the nightly builds job succeeded). Results of the test run are saved in TestRail.
And also we push set of autotests whenever PR with successful builds got moved in to `E2E Tests` column from [Pipeline for QA dashboard ](https://github.com/status-im/status-react/projects/7).
In that case we save results in TestRail as well and push a comment with test results in a respective PR.
@@ -49,8 +49,8 @@ Params to specify:
- apk: [url_to_apk_build_here]
- pr_id: pull request number (e.g. 1234)
- branch: branch name from which the test are taken (in most of cases `develop`)
- keyword expression: tests by area (let's say `ens` or `chat`, they can be combined`ens or chat or send_tx`. All keywords can be found in testrail, ping Chu for details)
- test_marks: tests by priorities (by default: `critical or high or medium`, which corresponds the whole suite; to launch the same suite as in PRs, use `critical or high`)
- keyword expression: tests by area (let's say `ens` or `chat`, thay can be combined`ens or chat or send_tx`. All keywords can be found in testrail, ping Chu for details)
- test_marks: tests by priorities (by default: `critical or high or medium`, which corresponds the whole suite; to lauch the same suite as in PRs, use `critical or high`)
- testrail_case_id: here is the list of test cases which you may find in test rail (4-digit value)
For easier access you can hit `Rerun tests` in GH comment and testrail_case_id/ apk_name/ pr_id will be filled automatically. For making sure that tests are being rerun on most recent e2e build it is recommended to paste link to the last e2e build in apk_name field. The list of PR builds can be found in Jenkins Builds block on PR page.
+1 -1
View File
@@ -90,7 +90,7 @@ Press the green run button
<img src="images/ide-setup/8_REPL_6.png" width=75% />
You should now see a dialog with the following message:
You should now see an dialog with the following message:
```shell
Connecting to remote nREPL server...
+4 -4
View File
@@ -4,7 +4,7 @@ This document provides information on how to start developing Status App.
# Getting Started
To start developing start a shell for the platform you are interested in.
To start developing start a shell for platform you are interested in.
```
make shell TARGET=android
```
@@ -55,7 +55,7 @@ Some manual steps are necessary for [developing on a physical iOS Device](#physi
# Build release
To build the app, you can simply run on of the following:
To build the app, your can simply run on of the following:
```
make release-android
make release-ios
@@ -88,9 +88,9 @@ https://facebook.github.io/react-native/docs/getting-started.html
## Configure GitHub Account
The optimal way of pushing to GitHub is using SSH instead of user/pass auth.
The optimal way of pushing to GitHubis using SSH instead of user/pass auth.
It's recommended that you [add your public SSH key to your GitHub account](https://help.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account).
It's recommented that you [add your public SSH key to your GitHub account](https://help.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account).
## Configure GPG Keys for signing commits
+1 -1
View File
@@ -707,7 +707,7 @@ SPEC CHECKSUMS:
FBLazyVector: a8af91c2b5a0029d12ff6b32e428863d63c48991
FBReactNativeSpec: 1b2309b096448a1dc9d0c43999216f8fda809ae8
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 166d178815c300e8126de9a7900101814eb16253
glog: d93527a855523adb8c113837db4be68fb00e230d
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
+1 -1
View File
@@ -22,7 +22,7 @@ buildGoPackage {
runHook preBuild
go build \
-buildmode='c-archive' \
-tags='gowaku_skip_migrations gowaku_no_rln' \
-tags='gowaku_skip_migrations' \
-o "$out/libstatus.a" \
$NIX_BUILD_TOP/main.go
runHook postBuild
+1 -1
View File
@@ -48,7 +48,7 @@ in buildGoPackage {
-target=${concatStringsSep "," targets} \
${optionalString isAndroid "-androidapi=${platformVersion}" } \
${optionalString isIOS "-iosversion=${platformVersion}" } \
-tags='${optionalString isIOS "nowatchdog"} gowaku_skip_migrations gowaku_no_rln' \
-tags='${optionalString isIOS "nowatchdog"} gowaku_skip_migrations' \
-o ${outputFileName} \
${source.goPackagePath}/mobile
BIN
View File
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1001 B

After

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 781 B

-13
View File
@@ -1,13 +0,0 @@
#!/usr/bin/env sh
set -euo pipefail
QUO_USAGES=$(grep -r -E '\[quo\.[^ ]* :(?:as|refer)|\[quo\.[^ ]*\]' --include '*.cljs' --include '*.clj' './src/status_im2' --exclude='./src/status_im2/common/theme/core.cljs' || true)
echo -e "\nChecking 'status_im2' namespace for 'quo' namespace usage."
if [ -n "$QUO_USAGES" ]; then
echo -e "\033[0;31mERROR: Usage of the old 'quo' namespace detected in 'status_im2' code. Please update to 'quo2'. \n"
echo -e "$QUO_USAGES \033[0m"
exit 1
fi
-1
View File
@@ -129,7 +129,6 @@
;; needed because we use deref in tests
:static-fns false
:optimizations :simple
:warnings {:fn-deprecated false}
:infer-externs true}}
;; mock.js-dependencies is mocking the react-native libraries
+3 -5
View File
@@ -470,8 +470,7 @@
(defn sha3
[s]
(log/debug "[native-module] sha3")
(when s
(.sha3 ^js (status) (str s))))
(.sha3 ^js (status) s))
(defn utf8-to-hex
[s]
@@ -492,9 +491,8 @@
(defn address?
[address]
(log/debug "[native-module] address?")
(when address
(let [result (.isAddress ^js (status) address)]
(types/json->clj result))))
(let [result (.isAddress ^js (status) address)]
(types/json->clj result)))
(defn to-checksum-address
[address]
-29
View File
@@ -69,35 +69,6 @@ In the image above we can see the properties are `Type`, `State`, `Size`,
...)
```
### Handling Sizes
In the designs, sizes are referred to as integers. To avoid having the codebase littered with magic numbers we instead have a keyword convention to use in components to map these keywords with their sizes.
The convention is `:size-<number>`, e.g size `20` is `:size-20`
```clojure
;; bad
(defn button
[{:keys [size]}]
[rn/view
{:style {:height (case size
20 20
40 40
0)}}]
...)
```
```clojure
;; good
(defn button
[{:keys [size]}]
[rn/view
{:style {:height (case size
:size-20 20
:size-40 40
0)}}]
...)
```
## Clojure var conventions
- Due to the fact that every `view` namespace should export only one component
@@ -6,20 +6,16 @@
(def default-padding 16)
(def default-emoji-size 36)
(def ^:private container-size
{:size-64 64})
(defn get-border-radius
[size]
(case size
80 16
:size-64 16
48 12
32 10
28 8
24 8
20 6
16 4
80 16
48 12
32 10
28 8
24 8
20 6
16 4
default-border-radius))
(defn get-padding
@@ -37,32 +33,29 @@
(defn get-emoji-size
[size]
(case size
80 36
:size-64 30
48 24
32 15
28 12
24 11
20 11
16 11
80 36
48 24
32 15
28 12
24 11
20 11
16 11
default-emoji-size))
(defn get-border-width
[size]
(if (= size 16)
0.8 ;; 0.8 px is for only size 16
1)) ;; Rest of the size will have 1 px
(case size
16 0.8 ;; 0.8 px is for only size 16
;; Rest of the size will have 1 px
1))
(defn root-container
[{:keys [type size theme customization-color]
:or {size default-size
customization-color :blue}}]
(let [watch-only? (= type :watch-only)
width (cond-> size
(keyword? size) (container-size size))]
(cond-> {:width width
:height width
(let [watch-only? (= type :watch-only)]
(cond-> {:width size
:height size
:background-color (colors/custom-color-by-theme customization-color 50 60 nil nil theme)
:border-radius (get-border-radius size)
:border-color (if (= theme :light) colors/neutral-80-opa-5 colors/white-opa-5)
@@ -11,7 +11,7 @@
(h/test "with emoji, no lock set, large size"
(let [emoji "🍓"]
(h/render [component/view {:emoji emoji :size :size-32}])
(h/render [component/view {:emoji emoji :size :size/l}])
(h/is-null (h/query-by-label-text :initials))
(h/is-truthy (h/query-by-text emoji))
(h/is-null (h/query-by-label-text :lock))))
@@ -31,5 +31,5 @@
(h/test "no emoji, large size"
(h/render [component/view
{:full-name "Status Mobile"
:size :size-32}])
:size :size/l}])
(h/is-truthy (h/query-by-text "SM"))))
@@ -5,27 +5,17 @@
(defn outer-container
[{:keys [size color]}]
(let [container-size (case size
:size-64 64
:size-32 32
24)]
{:width container-size
:height container-size
:border-radius container-size
(let [size (if (= size :size/l) 32 24)]
{:width size
:height size
:border-radius size
:justify-content :center
:align-items :center
:background-color (colors/theme-alpha color 0.1 0.1)}))
(defn emoji-size
[size]
{:font-size (case size
:size-64 24
:size-32 15
11)})
(defn lock-container
[size]
(let [distance (if (= size :size-32) 20 12)]
(let [distance (if (= size :size/l) 20 12)]
{:position :absolute
:left distance
:top distance
@@ -5,19 +5,17 @@
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[utils.string]))
utils.string))
(defn- initials
[full-name size color]
(let [amount-initials (if (#{:size-32 :size-64} size) 2 1)
(let [amount-initials (if (= size :size/l) 2 1)
channel-name (string/replace full-name "#" "")]
[text/text
(cond-> {:accessibility-label :initials
:style {:color color}
:size :paragraph-2
:weight :semi-bold}
(= size :size-64) (assoc :size :heading-1
:weight :medium))
{:accessibility-label :initials
:size :paragraph-2
:weight :semi-bold
:style {:color color}}
(utils.string/get-initials channel-name amount-initials)]))
(defn- lock
@@ -56,8 +54,8 @@
:style (style/outer-container {:size size :color customization-color})}
(if (string/blank? emoji)
[initials full-name size customization-color]
[rn/text
{:style (style/emoji-size size)
:accessibility-label :emoji}
[text/text
{:accessibility-label :emoji
:size (if (= size :size/l) :paragraph-1 :label)}
(string/trim emoji)])
[lock locked? size]])
@@ -1,16 +0,0 @@
(ns quo2.components.avatars.collection-avatar.component-spec
(:require [quo2.components.avatars.collection-avatar.view :as collection-avatar]
[quo2.foundations.resources :as resources]
[test-helpers.component :as h]))
(h/describe "collection avatar"
(h/describe "Profile picture"
(h/test "Doesn't crash without image"
(h/render
[collection-avatar/view])
(h/is-truthy (h/get-by-label-text :collection-avatar)))
(h/test "Renders with image"
(h/render
[collection-avatar/view {:image (resources/get-image :bored-ape)}])
(h/is-truthy (h/get-by-label-text :collection-avatar)))))
@@ -1,10 +0,0 @@
(ns quo2.components.avatars.collection-avatar.style
(:require [quo2.foundations.colors :as colors]))
(defn collection-avatar
[theme]
{:width 24
:height 24
:border-width 1
:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
:border-radius 6})
@@ -1,17 +0,0 @@
(ns quo2.components.avatars.collection-avatar.view
(:require [quo2.components.avatars.collection-avatar.style :as style]
[quo2.theme :as quo.theme]
[react-native.fast-image :as fast-image]))
(defn- view-internal
"Opts:
:image - collection image
:theme - keyword -> :light/:dark"
[{:keys [image theme]}]
[fast-image/fast-image
{:accessibility-label :collection-avatar
:source image
:style (style/collection-avatar theme)}])
(def view (quo.theme/with-theme view-internal))
@@ -3,12 +3,15 @@
(defn container
[{:keys [container-size customization-color theme]}]
{:width container-size
:height container-size
:align-items :center
:justify-content :center
:border-radius (/ container-size 2)
:overflow :hidden
:background-color (colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)})
(let [color (if (keyword? customization-color)
customization-color
:blue)]
{:width container-size
:height container-size
:align-items :center
:justify-content :center
:border-radius (/ container-size 2)
:overflow :hidden
:background-color (colors/theme-colors (colors/custom-color color 50)
(colors/custom-color color 60)
theme)}))
@@ -7,31 +7,30 @@
[quo2.components.avatars.group-avatar.style :as style]))
(def sizes
{:size-20 {:icon 12
:container 20}
:size-28 {:icon 16
:container 28}
:size-32 {:icon 16
:container 32}
:size-48 {:icon 20
:container 48}
:size-80 {:icon 32
:container 80}})
{:size/s-20 {:icon 12
:container 20}
:size/s-28 {:icon 16
:container 28}
:size/s-32 {:icon 16
:container 32}
:size/s-48 {:icon 20
:container 48}
:size/s-80 {:icon 32
:container 80}})
(defn- view-internal
[_]
(fn [{:keys [size theme customization-color picture icon-name]
:or {size :size-20
:or {size :size/s-20
customization-color :blue
picture nil
icon-name :i/group}}]
(let [container-size (get-in sizes [size :container])
icon-size (get-in sizes [size :icon])]
[rn/view
{:accessibility-label :group-avatar
:style (style/container {:container-size container-size
:customization-color customization-color
:theme theme})}
{:style (style/container {:container-size container-size
:customization-color customization-color
:theme theme})}
(if picture
[fast-image/fast-image
{:source picture
+9 -9
View File
@@ -5,19 +5,19 @@
[react-native.core :as rn]))
(def ^:private sizes
{:size-48 {:component 48
:icon 20}
:size-32 {:component 32
:icon 20}
:size-24 {:component 24
:icon 16}
:size-20 {:component 20
:icon 12}})
{:size/s-48 {:component 48
:icon 20}
:size/s-32 {:component 32
:icon 20}
:size/s-24 {:component 24
:icon 16}
:size/s-20 {:component 20
:icon 12}})
(defn icon-avatar-internal
[{:keys [size icon color opacity border? theme]
:or {opacity 20
size :size-32}}]
size :size/s-32}}]
(let [{component-size :component icon-size :icon} (get sizes size)
circle-color (colors/custom-color color 50 opacity)
icon-color (colors/custom-color-by-theme color 50 60)]
@@ -2,54 +2,48 @@
(:require [quo2.foundations.colors :as colors]))
(def sizes
{:big {:dimensions 80
:status-indicator 12
:status-indicator-border 4
:status-indicator-center-to-edge 12
:font-size :heading-1
:ring-width 4}
:size-64 {:dimensions 64
:status-indicator 8
:status-indicator-border 2
:status-indicator-center-to-edge 6
:font-size :heading-1
:ring-width 2}
:medium {:dimensions 48
:status-indicator 8
:status-indicator-border 2
:status-indicator-center-to-edge 6
:font-size :heading-2
:ring-width 2}
:small {:dimensions 32
:status-indicator 8
:status-indicator-border 2
:status-indicator-center-to-edge 4
:font-size :paragraph-2
:ring-width 2}
28 {:dimensions 28
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :paragraph-2
:ring-width 0}
:xs {:dimensions 24
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :paragraph-2
:ring-width 2}
:xxs {:dimensions 20
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :label
:ring-width 2}
:xxxs {:dimensions 16
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :label
:ring-width 2}})
{:big {:dimensions 80
:status-indicator 12
:status-indicator-border 4
:status-indicator-center-to-edge 12
:font-size :heading-1
:ring-width 4}
:medium {:dimensions 48
:status-indicator 8
:status-indicator-border 2
:status-indicator-center-to-edge 6
:font-size :heading-2
:ring-width 2}
:small {:dimensions 32
:status-indicator 8
:status-indicator-border 2
:status-indicator-center-to-edge 4
:font-size :paragraph-2
:ring-width 2}
28 {:dimensions 28
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :paragraph-2
:ring-width 0}
:xs {:dimensions 24
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :paragraph-2
:ring-width 2}
:xxs {:dimensions 20
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :label
:ring-width 2}
:xxxs {:dimensions 16
:status-indicator 0
:status-indicator-border 0
:status-indicator-center-to-edge 0
:font-size :label
:ring-width 2}})
(defn initials-avatar
[size customization-color theme]
@@ -39,7 +39,7 @@
:background-color intials avatar background color
:color intials avatar text color
:size intials avatar radius
:ring? render ident ring around avatar? NOTE: this option may not work if override-ring? is not nil}
:ring? render ident ring around avatar?}
supported color formats:
#RRGGBB
@@ -8,21 +8,18 @@
{:small 20
:medium 32
:large 48
:size-64 64
:x-large 80})
(def font-sizes
{:small :label
:medium :paragraph-2
:large :paragraph-1
:size-64 :heading-1
:x-large :heading-1})
(def font-weights
{:small :medium
:medium :semi-bold
:large :semi-bold
:size-64 :medium
:x-large :medium})
(defn wallet-user-avatar
@@ -1,8 +1,6 @@
(ns quo2.components.buttons.button.properties
(:require [quo2.foundations.colors :as colors]))
(def backgrounds #{:photo :blur})
(defn custom-color-type
[customization-color icon-only?]
{:icon-color colors/white-opa-70
+6 -11
View File
@@ -29,11 +29,10 @@
only icon
[button {:icon-only? true} :i/close-circle]"
[_ _]
(let [pressed-state? (reagent/atom false)]
(let [pressed? (reagent/atom false)]
(fn
[{:keys [on-press on-long-press disabled? type background size icon-left icon-right icon-top
customization-color theme accessibility-label icon-only? container-style inner-style
pressed? on-press-in on-press-out]
customization-color theme accessibility-label icon-only? container-style inner-style]
:or {type :primary
size 40
customization-color (cond (= type :primary) :blue
@@ -47,18 +46,14 @@
:background background
:type type
:theme theme
:pressed? (if pressed? pressed? @pressed-state?)
:pressed? @pressed?
:icon-only? icon-only?})
icon-size (when (= 24 size) 12)]
[rn/touchable-without-feedback
{:disabled disabled?
:accessibility-label accessibility-label
:on-press-in (fn []
(reset! pressed-state? true)
(when on-press-in (on-press-in)))
:on-press-out (fn []
(reset! pressed-state? nil)
(when on-press-out (on-press-out)))
:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? nil)
:on-press on-press
:on-long-press on-long-press}
[rn/view
@@ -81,7 +76,7 @@
[customization-colors/overlay
{:customization-color customization-color
:theme theme
:pressed? (if pressed? pressed? @pressed-state?)}])
:pressed? @pressed?}])
(when (= background :photo)
[blur/view
{:blur-radius 20
@@ -70,7 +70,7 @@
[sliding-complete?]
(reset! sliding-complete? true))
(defn reset-track-position
(defn- reset-track-position
[x-pos]
(animate-spring x-pos 0))
@@ -1,6 +1,7 @@
(ns quo2.components.buttons.slide-button.component-spec
(:require [quo2.components.buttons.slide-button.view :as slide-button]
[quo2.components.buttons.slide-button.constants :as constants]
[quo2.components.buttons.slide-button.utils :as utils]
["@testing-library/react-native" :as rtl]
["react-native-gesture-handler/jest-utils" :as gestures-jest]
[reagent.core :as r]
@@ -81,11 +82,17 @@
(h/has-style track-mock {:opacity constants/disable-opacity})))
(h/test "render the small button"
(h/render [slide-button/view (assoc default-props :size :size/s-40)])
(h/render [slide-button/view (assoc default-props :size :small)])
(let [mock (h/get-by-test-id :slide-button-track)
small-height (:track-height constants/small-dimensions)]
(h/has-style mock {:height small-height})))
(h/test "render with the correct customization-color"
(h/render [slide-button/view (assoc default-props :customization-color :purple)])
(let [track-mock (h/get-by-test-id :slide-button-track)
purple-color (utils/slider-color :track :purple)]
(h/has-style track-mock {:backgroundColor purple-color})))
(h/test
"calls on-complete when dragged"
(let [props (merge default-props {:on-complete (h/mock-fn)})
@@ -13,10 +13,10 @@
:right 0})
(defn thumb-container
[{:keys [interpolate-track thumb-size customization-color theme]}]
[interpolate-track thumb-size customization-color]
(reanimated/apply-animations-to-style
{:transform [{:translate-x (interpolate-track :track-clamp)}]}
{:background-color (utils/slider-color :main customization-color theme)
{:background-color (utils/slider-color :main customization-color)
:border-radius 12
:height thumb-size
:width thumb-size
@@ -46,7 +46,7 @@
:justify-content :space-around}))
(defn track
[{:keys [disabled? customization-color height theme]}]
[disabled? customization-color height]
{:align-items :flex-start
:justify-content :center
:border-radius 14
@@ -54,7 +54,7 @@
:align-self :stretch
:padding constants/track-padding
:opacity (if disabled? 0.3 1)
:background-color (utils/slider-color :track customization-color theme)})
:background-color (utils/slider-color :track customization-color)})
(defn track-cover
[interpolate-track]
@@ -74,7 +74,7 @@
:width track-width})
(defn track-text
[customization-color theme]
[customization-color]
(-> typography/paragraph-1
(merge typography/font-medium)
(assoc :color (utils/slider-color :main customization-color theme))))
(assoc :color (utils/slider-color :main customization-color))))
@@ -6,15 +6,9 @@
(defn slider-color
"- `color-key` `:main`/`:track`
- `customization-color` Customization color"
[color-key customization-color theme]
(let [colors-by-key {:main (colors/theme-colors
(colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)
:track (colors/theme-colors
(colors/custom-color customization-color 50 10)
(colors/custom-color customization-color 60 10)
theme)}]
[color-key customization-color]
(let [colors-by-key {:main (colors/custom-color-by-theme customization-color 50 60)
:track (colors/custom-color-by-theme customization-color 50 60 10 10)}]
(color-key colors-by-key)))
(defn clamp-value
@@ -34,8 +28,8 @@
(defn get-dimensions
[track-width size dimension-key]
(let [default-dimensions (case size
:size/s-40 constants/small-dimensions
:size/s-48 constants/large-dimensions
:small constants/small-dimensions
:large constants/large-dimensions
constants/large-dimensions)]
(-> default-dimensions
(merge {:usable-track (calc-usable-track
@@ -10,8 +10,7 @@
[reagent.core :as reagent]
[oops.core :as oops]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.slide-button.constants :as constants]
[quo2.theme :as quo.theme]))
[quo2.components.buttons.slide-button.constants :as constants]))
(defn- f-slider
[{:keys [disabled?]}]
@@ -21,15 +20,14 @@
on-track-layout (fn [evt]
(let [width (oops/oget evt "nativeEvent.layout.width")]
(reset! track-width width)))]
(fn [{:keys [on-reset
on-complete
(fn [{:keys [on-complete
track-text
track-icon
disabled?
customization-color
size
container-style
theme]}]
container-style]}]
(let [x-pos (reanimated/use-shared-value 0)
dimensions (partial utils/get-dimensions
(or @track-width constants/default-width)
@@ -38,19 +36,12 @@
x-pos
(dimensions :usable-track)
(dimensions :thumb))]
(rn/use-effect (fn []
(when @sliding-complete?
(on-complete)))
[@sliding-complete?])
(rn/use-effect (fn []
(when on-reset
(reset! sliding-complete? false)
(reset! gestures-disabled? false)
(animations/reset-track-position x-pos)
(on-reset)))
[on-reset])
[gesture/gesture-detector
{:gesture (animations/drag-gesture x-pos
gestures-disabled?
@@ -59,25 +50,21 @@
sliding-complete?)}
[reanimated/view
{:test-ID :slide-button-track
:style (merge (style/track {:disabled? disabled?
:customization-color customization-color
:height (dimensions :track-height)
:theme theme})
:style (merge (style/track disabled? customization-color (dimensions :track-height))
container-style)
:on-layout (when-not (some? @track-width)
on-track-layout)}
[reanimated/view {:style (style/track-cover interpolate-track)}
[rn/view {:style (style/track-cover-text-container @track-width)}
[icon/icon track-icon
{:color (utils/slider-color :main customization-color theme)
{:color (utils/slider-color :main customization-color)
:size 20}]
[rn/view {:width 4}]
[rn/text {:style (style/track-text customization-color theme)} track-text]]]
[rn/text {:style (style/track-text customization-color)} track-text]]]
[reanimated/view
{:style (style/thumb-container {:interpolate-track interpolate-track
:thumb-size (dimensions :thumb)
:customization-color customization-color
:theme theme})}
{:style (style/thumb-container interpolate-track
(dimensions :thumb)
customization-color)}
[reanimated/view {:style (style/arrow-icon-container interpolate-track)}
[icon/icon :arrow-right
{:color colors/white
@@ -89,19 +76,16 @@
{:color colors/white
:size 20}]]]]]))))
(defn- view-internal
(defn view
"Options
- `on-complete` Callback called when the sliding is complete
- `disabled?` Boolean that disables the button
(_and gestures_)
- `size` :size/s-40`/`:size/s-48`
- `size` `:small`/`:large`
- `track-text` Text that is shown on the track
- `track-icon` Key of the icon shown on the track
(e.g. `:face-id`)
- `customization-color` Customization color
- `on-reset` A callback which can be used to reset the component and run required functionality
"
[props]
[:f> f-slider props])
(def view (quo.theme/with-theme view-internal))
+87
View File
@@ -0,0 +1,87 @@
(ns quo2.components.code.code.style
(:require [quo2.foundations.colors :as colors]))
;; Example themes:
;; https://github.com/react-syntax-highlighter/react-syntax-highlighter/tree/master/src/styles/hljs
(defn theme
[theme-key]
(case theme-key
:hljs-comment (colors/theme-colors colors/neutral-40 colors/neutral-60)
:hljs-title (colors/custom-color-by-theme :sky 50 60)
:hljs-keyword (colors/custom-color-by-theme :green 50 60)
:hljs-string (colors/custom-color-by-theme :turquoise 50 60)
:hljs-literal (colors/custom-color-by-theme :turquoise 50 60)
:hljs-number (colors/custom-color-by-theme :turquoise 50 60)
:line-number colors/neutral-40
nil))
(defn text-style
[class-names]
(let [text-color (->> class-names
(map keyword)
(some (fn [class-name]
(when-let [text-color (theme class-name)]
text-color))))]
(cond-> {:flex-shrink 1
:line-height 18}
text-color (assoc :color text-color))))
(defn border-color
[]
(colors/theme-colors colors/neutral-20 colors/neutral-80))
(defn container
[]
{:overflow :hidden
:padding 8
:background-color (colors/theme-colors colors/white colors/neutral-80-opa-40)
:border-color (border-color)
:border-width 1
:border-radius 16})
(def gradient-container
{:position :absolute
:bottom 0
:left 0
:right 0
:z-index 1})
(def gradient {:height 48})
(defn line-number-container
[line-number-width]
{:position :absolute
:bottom 0
:top 0
:left 0
:width (+ line-number-width 8 7)
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80)})
(defn divider
[line-number-width]
{:position :absolute
:bottom 0
:top 0
:left (+ line-number-width 7 7)
:width 1
:z-index 2
:background-color (border-color)})
(def line {:flex-direction :row})
(defn line-number
[width]
{:margin-right 20 ; 8+12 margin
:width width})
(def copy-button
{:position :absolute
:bottom 8
:right 8
:z-index 1})
(defn gradient-color [] (colors/theme-colors colors/white colors/neutral-80))
(defn button-background-color
[]
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5))
-107
View File
@@ -1,107 +0,0 @@
(ns quo2.components.code.common.style
(:require [quo2.foundations.colors :as colors]))
;; Example themes:
;; https://github.com/react-syntax-highlighter/react-syntax-highlighter/tree/master/src/styles/hljs
(defn highlight-theme
[theme-key]
(case theme-key
:hljs-comment (colors/theme-colors colors/neutral-40 colors/neutral-60)
:hljs-title (colors/custom-color-by-theme :sky 50 60)
:hljs-keyword (colors/custom-color-by-theme :green 50 60)
:hljs-string (colors/custom-color-by-theme :turquoise 50 60)
:hljs-literal (colors/custom-color-by-theme :turquoise 50 60)
:hljs-number (colors/custom-color-by-theme :turquoise 50 60)
:hljs-symbol (colors/custom-color-by-theme :orange 50 50)
:hljs-builtin-name (colors/custom-color-by-theme :pink 50 50)
:line-number colors/neutral-40
nil))
(defn text-style
[class-names preview?]
(let [text-color (->> class-names
(map keyword)
(some (fn [class-name]
(when-let [text-color (highlight-theme class-name)]
text-color))))]
(cond-> {:flex-shrink 1
:line-height 18}
preview? (assoc :color colors/white)
text-color (assoc :color text-color))))
(defn border-color
[]
(colors/theme-colors colors/neutral-20 colors/neutral-80))
(defn container
[preview? theme]
(if preview?
{:overflow :hidden
:width 108
:background-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:border-radius 8}
{:overflow :hidden
:padding 8
:background-color (colors/theme-colors colors/white colors/neutral-80-opa-40 theme)
:border-color (border-color)
:border-width 1
:border-radius 16}))
(def gradient-container
{:position :absolute
:bottom 0
:left 0
:right 0
:z-index 1})
(def gradient {:height 48})
(defn line-number-container
[line-number-width preview? theme]
(cond-> {:position :absolute
:bottom 0
:top 0
:left 0
:width (+ line-number-width 8 7)
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-80 theme)}
preview? (assoc :width 20
:background-color (colors/theme-colors colors/neutral-10 colors/neutral-70 theme))))
(defn divider
[line-number-width]
{:position :absolute
:bottom 0
:top 0
:left (+ line-number-width 7 7)
:width 1
:z-index 2
:background-color (border-color)})
(def line {:flex-direction :row})
(defn line-number
[width preview?]
(if preview?
{:width width
:padding-vertical 3
:padding-left 8
:padding-right 4}
{:margin-right 20 ; 8+12 margin
:width width}))
(def line-content
{:flex 1
:padding-horizontal 8
:padding-vertical 3})
(def copy-button
{:position :absolute
:bottom 8
:right 8
:z-index 1})
(defn gradient-color [] (colors/theme-colors colors/white colors/neutral-80))
(defn button-background-color
[]
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5))
@@ -1,8 +1,8 @@
(ns quo2.components.code.common.view
(ns quo2.components.code.snippet
(:require [cljs-bean.core :as bean]
[clojure.string :as string]
[quo2.components.buttons.button.view :as button]
[quo2.components.code.common.style :as style]
[quo2.components.code.code.style :as style]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]
[react-native.linear-gradient :as linear-gradient]
@@ -10,41 +10,39 @@
[reagent.core :as reagent]))
(defn- render-nodes
[nodes preview?]
[nodes]
(map (fn [{:keys [children value last-line?] :as node}]
(if children
(into [text/text
(cond-> {:weight :code
:size :paragraph-2
:style (style/text-style (get-in node [:properties :className]) preview?)}
:style (style/text-style (get-in node [:properties :className]))}
last-line? (assoc :number-of-lines 1))]
(render-nodes children preview?))
(render-nodes children))
;; Remove newlines as we already render each line separately.
(string/trim-newline value)))
nodes))
(defn- line
[{:keys [line-number line-number-width preview?]} children]
[{:keys [line-number line-number-width]} children]
[rn/view {:style style/line}
[rn/view {:style (style/line-number line-number-width preview?)}
[rn/view {:style (style/line-number line-number-width)}
[text/text
{:style (style/text-style ["line-number"] preview?)
{:style (style/text-style ["line-number"])
:weight :code
:size :paragraph-2}
line-number]]
(cond->> children
preview? (conj [rn/view {:style style/line-content}]))])
children])
(defn- code-block
[{:keys [rows line-number-width preview?]}]
[{:keys [rows line-number-width]}]
[rn/view
(->> preview?
(render-nodes rows)
(->> rows
(render-nodes)
(map-indexed (fn [idx row-content]
[line
{:line-number (inc idx)
:line-number-width line-number-width
:preview? preview?}
:line-number-width line-number-width}
row-content]))
(into [:<>]))])
@@ -68,44 +66,36 @@
(* 9 max-line-digits font-scale))))
(defn- f-native-renderer
[{:keys [rows max-lines on-copy-press preview? theme]
[{:keys [rows max-lines on-copy-press]
:or {max-lines ##Inf}}]
(let [font-scale (:font-scale (rn/get-window))
total-rows (count rows)
number-rows-to-show (if preview?
0
(min (count rows) max-lines))
line-number-width (if preview? 20 (calc-line-number-width font-scale number-rows-to-show))
number-rows-to-show (min (count rows) max-lines)
line-number-width (calc-line-number-width font-scale number-rows-to-show)
truncated? (< number-rows-to-show total-rows)
rows-to-show-coll (if truncated?
(as-> rows $
(update $ number-rows-to-show assoc :last-line? true)
(take (inc number-rows-to-show) $))
rows)]
[rn/view {:style (style/container preview? theme)}
[rn/view {:style (style/line-number-container line-number-width preview? theme)}]
(if preview?
[code-block
{:rows rows-to-show-coll
:line-number-width line-number-width
:preview? preview?}]
[:<>
[rn/view {:style (style/divider line-number-width)}]
[mask-view {:apply-mask? truncated?}
[code-block
{:rows rows-to-show-coll
:line-number-width line-number-width}]]
[rn/view {:style style/copy-button}
[button/button
{:icon-only? true
:type :grey
:background :blur
:size 24
:on-press on-copy-press}
:main-icons/copy]]])]))
[rn/view {:style (style/container)}
[rn/view {:style (style/line-number-container line-number-width)}]
[rn/view {:style (style/divider line-number-width)}]
[mask-view {:apply-mask? truncated?}
[code-block
{:rows rows-to-show-coll
:line-number-width line-number-width}]]
[rn/view {:style style/copy-button}
[button/button
{:icon-only? true
:type :grey
:background :blur
:size 24
:on-press on-copy-press}
:main-icons/copy]]]))
(defn view
[{:keys [language max-lines on-copy-press preview? theme]} children]
(defn snippet
[{:keys [language max-lines on-copy-press]} children]
[highlighter/highlighter
{:language language
:renderer (fn [^js/Object props]
@@ -113,11 +103,8 @@
[:f> f-native-renderer
{:rows (-> props .-rows bean/->clj)
:on-copy-press #(when on-copy-press (on-copy-press children))
:max-lines max-lines
:preview? preview?
:theme theme}]))
:max-lines max-lines}]))
:show-line-numbers false
:style {}
:custom-style {:background-color nil}}
children])
@@ -1,15 +0,0 @@
(ns quo2.components.code.snippet.view
(:require [quo2.theme :as theme]
[quo2.components.code.common.view :as code-common]))
(defn- view-internal
[_]
(fn [{:keys [language max-lines on-copy-press]} children]
[code-common/view
{:language language
:max-lines max-lines
:on-copy-press on-copy-press
:preview? false}
children]))
(def view (theme/with-theme view-internal))
@@ -1,11 +0,0 @@
(ns quo2.components.code.snippet-preview.view
(:require [quo2.components.code.common.view :as code-common]))
(defn view
[{:keys [language]} children]
[code-common/view
{:preview? true
:language language
:max-lines 0
:theme :dark}
children])
@@ -1,54 +0,0 @@
(ns quo2.components.colors.color.style
(:require [quo2.foundations.colors :as colors]))
(def color-button-common
{:width 48
:height 48
:border-width 4
:border-radius 24
:margin-horizontal 4
:transform [{:rotate "45deg"}]
:border-color :transparent})
(defn color-button
[color selected?]
(merge color-button-common
(when selected?
{:border-top-color (colors/alpha color 0.4)
:border-end-color (colors/alpha color 0.4)
:border-bottom-color (colors/alpha color 0.2)
:border-start-color (colors/alpha color 0.2)})))
(defn color-circle
[color border?]
{:width 40
:height 40
:transform [{:rotate "-45deg"}]
:background-color color
:justify-content :center
:align-items :center
:border-color color
:border-width (if border? 2 0)
:overflow :hidden
:border-radius 20})
(defn feng-shui
[theme]
{:width 40
:height 40
:transform [{:rotate "45deg"}]
:overflow :hidden
:border-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-width 2
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-radius 20})
(defn left-half
[theme]
{:flex 1
:background-color (colors/theme-colors colors/white colors/neutral-100 theme)})
(defn right-half
[theme]
{:flex 1
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)})
@@ -1,50 +0,0 @@
(ns quo2.components.colors.color.view
(:require
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.colors.color.style :as style]))
(defn- feng-shui
[{:keys [color theme]}]
[rn/view
{:accessibility-label color
:style (style/feng-shui theme)}
[rn/view {:style (style/left-half theme)}]
[rn/view {:style (style/right-half theme)}]])
(defn- view-internal
[{:keys [color
selected?
on-press
blur?
theme]
:as props}]
(let [border? (and (not blur?) (not selected?))
hex-color (if (= :feng-shui color)
(colors/theme-colors colors/neutral-100 colors/white theme)
(colors/theme-colors (colors/custom-color color 50)
(colors/custom-color color 60)
theme))]
[rn/pressable
{:style (style/color-button hex-color selected?)
:accessibility-label :color-picker-item
:on-press #(on-press color)}
(if (and (= :feng-shui color) (not selected?))
[feng-shui
(assoc props
:hex-color hex-color
:border? border?)]
[rn/view
{:accessibility-label color
:style (style/color-circle hex-color border?)}
(when selected?
[icon/icon :i/check
{:size 20
:color (if (= :feng-shui color)
(colors/theme-colors colors/white colors/neutral-100 theme)
colors/white)}])])]))
(def view (quo.theme/with-theme view-internal))
@@ -3,6 +3,8 @@
[reagent.core :as reagent]
[test-helpers.component :as h]))
(def color-list [:blue :yellow :turquoise :copper :sky :camel :orange :army :pink :purple :magenta])
(h/describe "color-picker"
(h/test "color picker rendered"
(h/render [color-picker/view])
@@ -24,6 +26,6 @@
(h/render [color-picker/view])
(js/Promise.all (map (fn [color]
(h/is-truthy (h/get-all-by-label-text color)))
color-picker/color-list))))
color-list))))
@@ -0,0 +1,50 @@
(ns quo2.components.colors.color-picker.style
(:require [quo2.foundations.colors :as colors]))
(def color-picker-container
{:flex-direction :row
:flex-wrap :wrap
:justify-content :space-between})
(def flex-break
{:flex-basis "100%"
:height 10})
(def color-button-common
{:width 48
:height 48
:border-width 4
:border-radius 24
:transform [{:rotate "45deg"}]
:border-color :transparent})
(defn color-button
[color selected?]
(merge color-button-common
(when selected?
{:border-top-color (colors/alpha color 0.4)
:border-end-color (colors/alpha color 0.4)
:border-bottom-color (colors/alpha color 0.2)
:border-start-color (colors/alpha color 0.2)})))
(defn color-circle
[color border?]
{:width 40
:height 40
:transform [{:rotate "-45deg"}]
:background-color color
:justify-content :center
:align-items :center
:border-color color
:border-width (if border? 2 0)
:overflow :hidden
:border-radius 20})
(defn secondary-overlay
[secondary-color border?]
{:width (if border? 18 20)
:height 40
:position :absolute
:right 0
:background-color secondary-color})
@@ -1,35 +1,77 @@
(ns quo2.components.colors.color-picker.view
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as icon]
[reagent.core :as reagent]
[quo2.components.colors.color.view :as color]))
[quo2.components.colors.color-picker.style :as style]))
;; TODO: using :no-color this to keep alignment of colors correct while b & w is being developed.
;; https://github.com/status-im/status-mobile/issues/15442
(def color-list
[:blue :yellow :purple :turquoise :magenta :sky :orange :army :flamingo :camel :copper])
[:blue :yellow :turquoise :copper :sky :camel :orange :army :pink :purple :magenta :no-color])
(defn picker-colors
[blur?]
(map (fn [color]
{:name color
:color (colors/custom-color-by-theme color (if blur? 60 50) 60)})
color-list))
(defn- on-change-handler
[selected color-name on-change]
(reset! selected color-name)
(when on-change (on-change color-name)))
(defn empty-color-item
[]
[rn/view {:style style/color-button-common}])
(defn- color-item
[{:keys [name
color
secondary-color
selected?
on-press
blur?]}]
(let [border? (and (not blur?) (and secondary-color (not selected?)))]
(if (= :no-color name)
[empty-color-item]
[rn/touchable-opacity
{:style (style/color-button color selected?)
:accessibility-label :color-picker-item
:on-press #(on-press name)}
[rn/view
{:accessibile true
:accessibility-label name
:style (style/color-circle color border?)}
(when (and secondary-color (not selected?))
[rn/view
{:style (style/secondary-overlay secondary-color border?)}])
(when selected?
[icon/icon :i/check
{:size 20
:color (or secondary-color
colors/white)}])]])))
(defn view
"Options
- `default-selected` Default selected color name.
- `default-selected?` Default selected color name.
- `selected` Selected color name.
- `on-change` Callback called when a color is selected `(fn [color-name])`.
- `blur?` Boolean to enable blur background support.}"
[{:keys [default-selected]}]
(let [selected (reagent/atom default-selected)]
(fn [{:keys [blur? on-change feng-shui? container-style]}]
[rn/scroll-view
{:horizontal true
:shows-horizontal-scroll-indicator false
:content-container-style container-style}
(doall (map (fn [color]
[color/view
{:selected? (= color @selected)
:on-press #(on-change-handler selected % on-change)
:blur? blur?
:key color
:color color}])
;; TODO: using :feng-shui? temporarily while b & w is being developed.
;; https://github.com/status-im/status-mobile/discussions/16676
(if feng-shui? (conj color-list :feng-shui) color-list)))])))
[{:keys [default-selected?]}]
(let [internal-selected (reagent/atom default-selected?)]
(fn [{:keys [blur? on-change selected]}]
(when (and (not (nil? selected)) (not= @internal-selected selected))
(reset! internal-selected selected))
[rn/view {:style style/color-picker-container}
(doall (map-indexed (fn [index color]
[:<> {:key (color :name)}
[color-item
(merge color
{:selected? (= (color :name) @internal-selected)
:on-press #(on-change-handler internal-selected % on-change)
:blur? blur?})]
(when (= index 5) [rn/view {:style style/flex-break}])])
(picker-colors blur?)))])))
@@ -4,9 +4,7 @@
(defn get-color
[type customization-color theme]
(case type
:default (colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)
:default (colors/custom-color customization-color 50)
:secondary (colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme)
:grey (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)
:outline (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
@@ -0,0 +1,20 @@
(ns quo2.components.dropdowns.dropdown
(:require [quo2.components.dropdowns.old-button-view :as old-button]))
(defn dropdown
[_ _]
(fn [{:keys [on-change selected] :as opts} children]
;TODO: Dropdown needs to be implemented/refactored to be its own component -
;https://github.com/status-im/status-mobile/issues/16456
[old-button/button
(merge
opts
{:after (if selected :i/chevron-top :i/chevron-down)
:icon-size 12
:icon-container-size 14
:icon-container-rounded? true
:override-after-margins {:left 7
:right 9}
:pressed selected
:on-press #(when on-change (on-change selected))})
children]))
@@ -1,35 +0,0 @@
(ns quo2.components.dropdowns.dropdown.component-spec
(:require [quo2.components.dropdowns.dropdown.view :as dropdown]
[test-helpers.component :as h]))
(h/describe "Dropdown"
(h/test "default render"
(let [label "Recent"]
(h/render [dropdown/view {} label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-null (h/query-by-label-text :left-icon))
(h/is-truthy (h/get-by-text label))
(h/is-truthy (h/get-by-label-text :right-icon))))
(h/test "render with icon"
(let [label "Recent"]
(h/render [dropdown/view {:icon? true} label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-truthy (h/get-by-label-text :left-icon))
(h/is-truthy (h/get-by-text label))
(h/is-truthy (h/get-by-label-text :right-icon))))
(h/test "render only emoji"
(let [label "🍑"]
(h/render [dropdown/view {:emoji? true} label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-null (h/query-by-label-text :left-icon))
(h/is-truthy (h/get-by-text label))
(h/is-null (h/query-by-label-text :right-icon))))
(h/test "on-press"
(let [event (h/mock-fn)
label "Recent"]
(h/render [dropdown/view {:on-press event} label])
(h/fire-event :press (h/get-by-text label))
(h/was-called event))))
@@ -1,120 +0,0 @@
(ns quo2.components.dropdowns.dropdown.properties
(:require [quo2.foundations.colors :as colors]))
(def backgrounds #{:photo :blur})
(def sizes
{:size-40 {:size 40
:icon-size 20
:emoji-size 20
:emoji-padding 10
:padding-vertical 9
:padding-left {:default 16 :icon 12}
:padding-right 12
:border-radius 12
:text-size :paragraph-1}
:size-32 {:size 32
:icon-size 20
:emoji-size 20
:emoji-padding 6
:padding-vertical 5
:padding-left {:default 12 :icon 8}
:padding-right 8
:border-radius 10
:text-size :paragraph-1}
:size-24 {:size 24
:icon-size 12
:emoji-size 12
:emoji-padding 6
:padding-vertical 3
:padding-left {:default 8 :icon 8}
:padding-right 8
:border-radius 8
:text-size :paragraph-2}})
(defn- custom-color-type
[customization-color]
{:left-icon-color colors/white-opa-70
:right-icon-color colors/white-opa-20
:right-icon-color-2 colors/white
:label-color colors/white
:background-color (colors/custom-color customization-color 50)})
(def sizes-to-exclude-blur-in-photo-bg #{:size-40})
(defn- grey-photo
[theme active? size]
{:left-icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
:right-icon-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:blur-overlay-color (when (and (= theme :dark) (nil? (sizes-to-exclude-blur-in-photo-bg size)))
(if active? colors/neutral-80-opa-50 colors/neutral-80-opa-40))
:blur-type (if (= theme :light) :light :dark)
:background-color (cond
(= theme :light)
(if active? colors/white-opa-50 colors/white-opa-40)
(and (= theme :dark) (sizes-to-exclude-blur-in-photo-bg size))
(if active? colors/neutral-80-opa-50 colors/neutral-80-opa-40))})
(defn- grey-blur
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
:right-icon-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:background-color (if active?
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme))})
(defn- outline-blur
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
:right-icon-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if active?
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme))})
(defn- outline
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if active?
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))})
(defn- grey
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:background-color (if active?
(colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
(colors/theme-colors colors/neutral-5 colors/neutral-90 theme))})
(defn- ghost
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:background-color (when active?
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
(defn get-colors
[{:keys [customization-color theme type state background size]}]
(let [active? (= state :active)]
(cond
(and (= background :photo) (= type :grey)) (grey-photo theme active? size)
(and (= background :blur) (= type :grey)) (grey-blur theme active?)
(and (= background :blur) (= type :outline)) (outline-blur theme active?)
(= type :outline) (outline theme active?)
(= type :grey) (grey theme active?)
(= type :ghost) (ghost theme active?)
(= type :customization) (custom-color-type customization-color))))
@@ -1,53 +0,0 @@
(ns quo2.components.dropdowns.dropdown.style)
(def gap 4)
(def blur-view
{:position :absolute
:top 0
:left 0
:right 0
:bottom 0})
(def left-icon
{:margin-right gap})
(defn right-icon
[label-color]
{:color label-color
:margin-right gap})
(defn- add-styles-for-emoji
[style size emoji-padding]
(-> style
(dissoc :padding-vertical :padding-left :padding-right)
(assoc :width size
:padding emoji-padding)))
(defn root-container
[{:keys [size border-radius padding-vertical padding-right padding-left emoji-padding]}
{:keys [background-color border-color]}
{:keys [icon? emoji? state]}]
(cond-> {:height size
:align-items :center
:justify-content :center
:flex-direction :row
:padding-vertical padding-vertical
:padding-left (:default padding-left)
:padding-right padding-right
:overflow :hidden
:background-color background-color
:border-radius border-radius}
icon?
(assoc :padding-left (:icon padding-left))
emoji?
(add-styles-for-emoji size emoji-padding)
border-color
(assoc :border-color border-color
:border-width 1)
(= state :disabled)
(assoc :opacity 0.3)))
@@ -1,87 +0,0 @@
(ns quo2.components.dropdowns.dropdown.view
(:require [quo2.components.dropdowns.dropdown.properties :as properties]
[quo2.components.dropdowns.dropdown.style :as style]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.foundations.customization-colors :as customization-colors]
[quo2.theme :as theme]
[react-native.blur :as blur]
[react-native.core :as rn]))
(defn- view-internal
[{:keys [type size state background customization-color theme on-press icon-name icon? emoji?
accessibility-label]
:or {type :grey
size :size-40
state :default
icon? false
emoji? false
icon-name :i/placeholder}
:as props}
text]
(let [{:keys [icon-size text-size emoji-size border-radius]
:as size-properties} (properties/sizes size)
{:keys [left-icon-color right-icon-color right-icon-color-2 label-color blur-type
blur-overlay-color]
:as colors} (properties/get-colors props)
right-icon (if (= state :active) :i/pullup :i/dropdown)
customization-type? (= type :customization)
show-blur-background? (and (= background :photo)
(= type :grey)
(nil? (properties/sizes-to-exclude-blur-in-photo-bg size)))]
[rn/pressable
{:accessibility-label (or accessibility-label :dropdown)
:disabled (= state :disabled)
:on-press on-press
:style (style/root-container size-properties colors props)}
(when show-blur-background?
[blur/view
{:blur-radius 20
:blur-type blur-type
:overlay-color blur-overlay-color
:style style/blur-view}])
(when customization-type?
[customization-colors/overlay
{:customization-color customization-color
:theme theme
:pressed? (= state :active)
:border-radius border-radius}])
(if emoji?
[rn/text
{:adjusts-font-size-to-fit true
:style {:font-size emoji-size}}
text]
[:<>
(when icon?
[icon/icon
icon-name
{:accessibility-label :left-icon
:color left-icon-color
:size icon-size
:container-style style/left-icon}])
[text/text
{:size text-size
:weight :medium
:number-of-lines 1
:style (style/right-icon label-color)}
text]
[icon/icon
right-icon
{:size icon-size
:accessibility-label :right-icon
:color right-icon-color
:color-2 right-icon-color-2}]])]))
(def view
"Props:
- type: :outline |:grey (default) | :ghost | :customization
- size: :size-40 (default) | :size-32 | :size-24
- state: :default (default) | :active | :disabled
- emoji?: boolean
- icon?: boolean
- background: :blur | :photo (optional)
- icon-name: keyword
- on-press: function
Child: string - used as label or emoji (for emoji only)"
(theme/with-theme view-internal))
@@ -4,10 +4,10 @@
(defn container-border-color
[{:keys [state blur? theme pressed?]}]
(let [default-color (if blur?
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme)
colors/neutral-80-opa-5
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))
active-color (if blur?
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
colors/neutral-80-opa-10
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme))]
(condp = state
:disabled default-color
@@ -20,7 +20,7 @@
[preview-list/view
{:type :network
:list-size (count networks)
:size :size-20}
:size :size/s-20}
networks]])))
(def view (quo.theme/with-theme internal-view))
@@ -0,0 +1,264 @@
(ns quo2.components.dropdowns.old-button-style
(:require [quo2.foundations.colors :as colors]))
(def blur-view
{:position :absolute
:top 0
:left 0
:right 0
:bottom 0})
(defn before-icon-style
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
icon-size]}]
(merge
{:margin-left (or (get override-margins :left)
(if (= size 40) 12 8))
:margin-right (or (get override-margins :right) 4)
:align-items :center
:justify-content :center}
(when icon-container-size
{:width icon-container-size
:height icon-container-size})
(when icon-background-color
{:background-color icon-background-color})
(when icon-container-rounded?
{:border-radius (/ (or icon-container-size icon-size) 2)})))
(defn after-icon-style
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
icon-size]}]
(merge
{:margin-left (or (get override-margins :left) 4)
:margin-right (or (get override-margins :right)
(if (= size 40) 12 8))
:align-items :center
:justify-content :center}
(when icon-container-size
{:width icon-container-size
:height icon-container-size})
(when icon-background-color
{:background-color icon-background-color})
(when icon-container-rounded?
{:border-radius (/ (or icon-container-size icon-size) 2)})))
(defn themes
[customization-color]
{:light
{:primary {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default (colors/custom-color customization-color 50)
:pressed (colors/custom-color customization-color 60)
:disabled (colors/custom-color customization-color 50)}}
:secondary {:icon-color colors/primary-50
:label-color colors/primary-50
:background-color {:default colors/primary-50-opa-20
:pressed colors/primary-50-opa-40
:disabled colors/primary-50-opa-20}}
:grey {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:background-color {:default colors/neutral-10
:pressed colors/neutral-20
:disabled colors/neutral-10}}
:dark-grey {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:background-color {:default colors/neutral-20
:pressed colors/neutral-30
:disabled colors/neutral-20}}
:outline {:icon-color colors/neutral-50
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:border-color {:default colors/neutral-30
:pressed colors/neutral-40
:disabled colors/neutral-30}}
:ghost {:icon-color colors/neutral-50
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:background-color {:pressed colors/neutral-10}}
:danger {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/danger-50
:pressed colors/danger-60
:disabled colors/danger-50}}
:positive {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/success-50
:pressed colors/success-60
:disabled colors/success-50-opa-30}}
:photo-bg {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label-color colors/neutral-100
:background-color {:default colors/white-opa-40
:pressed colors/white-opa-50
:disabled colors/white-opa-40}}
:blur-bg {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label-color colors/neutral-100
:background-color {:default colors/neutral-80-opa-5
:pressed colors/neutral-80-opa-10
:disabled colors/neutral-80-opa-5}}
:blurred {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-100
:icon-background-color {:default colors/neutral-20
:blurred colors/neutral-80-opa-10}
:label-color colors/neutral-100
:background-color {:default colors/neutral-10
:pressed colors/neutral-10
:disabled colors/neutral-10-opa-10-blur}
:blur-overlay-color colors/neutral-10-opa-40-blur
:blur-type :light}
:blur-bg-outline {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label-color colors/neutral-100
:border-color {:default colors/neutral-80-opa-10
:pressed colors/neutral-80-opa-20
:disabled colors/neutral-80-opa-10}}
:shell {:icon-color colors/white
:label-color colors/white
:background-color {:default colors/neutral-95
:pressed colors/neutral-95
:disabled colors/neutral-95}}}
:dark
{:primary {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default (colors/custom-color customization-color 60)
:pressed (colors/custom-color customization-color 50)
:disabled (colors/custom-color customization-color 60)}}
:secondary {:icon-color colors/primary-50
:label-color colors/primary-50
:background-color {:default colors/primary-50-opa-20
:pressed colors/primary-50-opa-30
:disabled colors/primary-50-opa-20}}
:grey {:icon-color colors/white
:icon-secondary-color colors/neutral-40
:label-color colors/white
:background-color {:default colors/neutral-90
:pressed colors/neutral-60
:disabled colors/neutral-90}}
:dark-grey {:icon-color colors/white
:icon-secondary-color colors/neutral-40
:label-color colors/white
:background-color {:default colors/neutral-70
:pressed colors/neutral-60
:disabled colors/neutral-70}}
:outline {:icon-color colors/neutral-40
:icon-secondary-color colors/neutral-40
:label-color colors/white
:border-color {:default colors/neutral-70
:pressed colors/neutral-60
:disabled colors/neutral-70}}
:ghost {:icon-color colors/neutral-40
:icon-secondary-color colors/neutral-40
:label-color colors/white
:background-color {:pressed colors/neutral-80}}
:danger {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/danger-60
:pressed colors/danger-50
:disabled colors/danger-60}}
:positive {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/success-60
:pressed colors/success-50
:disabled colors/success-60-opa-30}}
:photo-bg {:icon-color colors/white
:icon-secondary-color colors/neutral-30
:label-color colors/white
:background-color {:default colors/neutral-80-opa-40
:pressed colors/neutral-80-opa-50
:disabled colors/neutral-80-opa-40}}
:blur-bg {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/white-opa-5
:pressed colors/white-opa-10
:disabled colors/white-opa-5}}
:blurred {:icon-color colors/white
:icon-secondary-color colors/white
:icon-background-color {:default colors/neutral-80
:blurred colors/white-opa-10}
:label-color colors/white
:background-color {:default colors/neutral-90
:pressed colors/neutral-90
:disabled colors/neutral-90-opa-10-blur}
:blur-overlay-color colors/neutral-80-opa-40
:blur-type :dark}
:blur-bg-outline {:icon-color colors/white
:icon-secondary-color colors/white-opa-40
:label-color colors/white
:border-color {:default colors/white-opa-10
:pressed colors/white-opa-20
:disabled colors/white-opa-5}}
:shell {:icon-color colors/white
:label-color colors/white
:background-color {:default colors/neutral-95}}}})
(defn shape-style-container
[type icon size]
{:height size
:border-radius (if (and icon (#{:primary :secondary :danger} type))
24
(case size
56 12
40 12
32 10
24 8))})
(defn style-container
[{:keys [type size disabled background-color border-color icon above width before after blur-active?]}]
(merge {:height size
:align-items :center
:justify-content :center
:flex-direction (if above :column :row)
:padding-horizontal (when-not (or icon before after)
(case size
56 16
40 16
32 12
24 8))
:padding-left (when-not (or icon before)
(case size
56 16
40 16
32 12
24 8))
:padding-right (when-not (or icon after)
(case size
56 16
40 16
32 12
24 8))
:padding-top (when-not (or icon before after)
(case size
56 0
40 9
32 5
24 3))
:padding-bottom (when-not (or icon before after)
(case size
56 0
40 9
32 5
24 4))
:overflow :hidden}
(when (or (and (= type :blurred) (not blur-active?))
(not= type :blurred))
{:background-color background-color})
(shape-style-container type icon size)
(when width
{:width width})
(when icon
{:width size})
(when border-color
{:border-color border-color
:border-width 1})
(when disabled
{:opacity 0.3})))
@@ -0,0 +1,138 @@
(ns quo2.components.dropdowns.old-button-view
(:require [quo2.components.icon :as quo2.icons]
[quo2.components.markdown.text :as text]
[quo2.theme :as theme]
[react-native.core :as rn]
[react-native.blur :as blur]
[reagent.core :as reagent]
[quo2.components.dropdowns.old-button-style :as style]))
(defn- button-internal
"with label
[button opts \"label\"]
opts
{:type :primary/:secondary/:grey/:dark-grey/:outline/:ghost/
:danger/:photo-bg/:blur-bg/:blur-bg-outline/:shell/:community
:size 40 [default] /32/24
:icon true/false
:community-color '#FFFFFF'
:community-text-color '#000000'
:before :icon-keyword
:after :icon-keyword}
only icon
[button {:icon true} :i/close-circle]"
[_ _]
(let [pressed-in (reagent/atom false)]
(fn
[{:keys [on-press disabled type size before after above icon-secondary-no-color
width customization-color theme override-background-color pressed
on-long-press accessibility-label icon icon-no-color style inner-style test-ID
blur-active? override-before-margins override-after-margins icon-size icon-container-size
icon-container-rounded?]
:or {type :primary
size 40
customization-color :primary
blur-active? true}}
children]
(let [{:keys [icon-color icon-secondary-color background-color label-color border-color blur-type
blur-overlay-color icon-background-color]}
(get-in (style/themes customization-color)
[theme type])
state (cond disabled :disabled
(or @pressed-in pressed) :pressed
:else :default)
blur-state (if blur-active? :blurred :default)
icon-size (or icon-size (when (= 24 size) 12))
icon-secondary-color (or icon-secondary-color icon-color)]
[rn/touchable-without-feedback
(merge {:test-ID test-ID
:disabled disabled
:accessibility-label accessibility-label
:on-press-in #(reset! pressed-in true)
:on-press-out #(reset! pressed-in nil)}
(when on-press
{:on-press on-press})
(when on-long-press
{:on-long-press on-long-press}))
[rn/view
{:style (merge
(style/shape-style-container type icon size)
{:width width}
style)}
[rn/view
{:style (merge
(style/style-container {:type type
:size size
:disabled disabled
:background-color
(or override-background-color (get background-color state))
:border-color
(get border-color state)
:icon icon
:above above
:width width
:before before
:after after
:blur-active? blur-active?})
(when (= state :pressed) {:opacity 0.9})
inner-style)}
(when (and (= type :blurred)
blur-active?)
[blur/view
{:blur-radius 20
:blur-type blur-type
:overlay-color blur-overlay-color
:style style/blur-view}])
(when above
[rn/view
[quo2.icons/icon above
{:container-style {:margin-bottom 2}
:color icon-secondary-color
:size icon-size}]])
(when before
[rn/view
{:style (style/before-icon-style
{:override-margins override-before-margins
:size size
:icon-container-size icon-container-size
:icon-background-color (get icon-background-color blur-state)
:icon-container-rounded? icon-container-rounded?
:icon-size icon-size})}
[quo2.icons/icon before
{:color icon-secondary-color
:size icon-size}]])
[rn/view
(cond
(or icon icon-no-color)
[quo2.icons/icon children
{:color icon-color
:no-color icon-no-color
:size icon-size}]
(string? children)
[text/text
{:size (when (#{56 24} size) :paragraph-2)
:weight :medium
:number-of-lines 1
:style {:color label-color}}
children]
(vector? children)
children)]
(when after
[rn/view
{:style (style/after-icon-style
{:override-margins override-after-margins
:size size
:icon-container-size icon-container-size
:icon-background-color (get icon-background-color blur-state)
:icon-container-rounded? icon-container-rounded?
:icon-size icon-size})}
[quo2.icons/icon after
{:no-color icon-secondary-no-color
:color icon-secondary-color
:size icon-size}]])]]]))))
(def button (theme/with-theme button-internal))
+13 -101
View File
@@ -21,109 +21,21 @@
children))
(defn- clear-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/path
{:d
"M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z"
:fill color}]
[svg/path
{:d
"M9.15142 9.99998L7.07566 12.0757L7.9242 12.9243L9.99994 10.8485L12.0757 12.9242L12.9242 12.0757L10.8485 9.99998L12.9242 7.92421L12.0757 7.07568L9.99994 9.15145L7.92421 7.07572L7.07568 7.92425L9.15142 9.99998Z"
:fill color-2}]])
(defn- dropdown-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/path
{:d
"M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z"
:fill color}]
[svg/path
{:d
"M7 8.5L10 11.5L13 8.5"
:stroke color-2
:stroke-width 1.2}]])
(defn- pullup-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/path
{:d
"M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z"
:fill color}]
[svg/path
{:d
"M7 11.5L10 8.5L13 11.5"
:stroke color-2
:stroke-width 1.2}]])
(defn- dropdown-12
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/circle
{:cx 6
:cy 6
:r 6
:fill color}]
[svg/path
{:d
"M3.5 5L6 7.5L8.5 5"
:stroke color-2
:stroke-width 1.1}]])
(defn- pullup-12
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/circle
{:cx 6
:cy 6
:r 6
:fill color}]
[svg/path
{:d
"M3.5 7L6 4.5L8.5 7"
:stroke color-2
:stroke-width 1.1}]])
(defn- contact-12
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/circle
{:cx 6
:cy 6
:r 6
:fill color}]
[svg/path
{:d
"M2.79504 9.01494C2.89473 8.85584 3.00297 8.70977 3.11963 8.5761C3.90594 7.67512 4.97212 7.45024 5.99992 7.45024C7.02772 7.45024 8.0939 7.67512 8.88021 8.5761C8.99688 8.70978 9.10512 8.85585 9.2048 9.01495C8.9501 9.28561 8.66149 9.52401 8.34577 9.72335C8.25403 9.55824 8.15512 9.41818 8.05145 9.29939C7.56503 8.74204 6.88121 8.55024 5.99992 8.55024C5.11862 8.55024 4.43481 8.74204 3.94839 9.29939C3.84472 9.41818 3.74582 9.55824 3.65408 9.72334C3.33835 9.524 3.04975 9.2856 2.79504 9.01494ZM5.99992 3.5502C5.47525 3.5502 5.04992 3.97552 5.04992 4.5002C5.04992 5.02487 5.47525 5.4502 5.99992 5.4502C6.52459 5.4502 6.94992 5.02487 6.94992 4.5002C6.94992 3.97552 6.52459 3.5502 5.99992 3.5502ZM3.94992 4.5002C3.94992 3.36801 4.86773 2.4502 5.99992 2.4502C7.1321 2.4502 8.04992 3.36801 8.04992 4.5002C8.04992 5.63238 7.1321 6.5502 5.99992 6.5502C4.86773 6.5502 3.94992 5.63238 3.94992 4.5002Z"
:fill color-2}]])
[{:keys [color color-2] :as props}]
(let [color (or color colors/neutral-100)
color-2 (or color-2 colors/white)]
[container props
[svg/path
{:d
"M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z"
:fill color}]
[svg/path
{:d
"M9.15142 9.99998L7.07566 12.0757L7.9242 12.9243L9.99994 10.8485L12.0757 12.9242L12.9242 12.0757L10.8485 9.99998L12.9242 7.92421L12.0757 7.07568L9.99994 9.15145L7.92421 7.07572L7.07568 7.92425L9.15142 9.99998Z"
:fill color-2}]]))
(def ^:private icons
{:i/clear-20 clear-20
:i/dropdown-20 dropdown-20
:i/pullup-20 pullup-20
:i/dropdown-12 dropdown-12
:i/pullup-12 pullup-12
:i/contact-12 contact-12})
{:i/clear-20 clear-20})
(defn- append-to-keyword
[k & xs]
+2 -2
View File
@@ -82,8 +82,8 @@
:size 20})
(defn input
[colors-by-status small? multiple-lines? weight]
(let [base-props (assoc (text/text-style {:size :paragraph-1 :weight (or weight :regular)})
[colors-by-status small? multiple-lines?]
(let [base-props (assoc (text/text-style {:size :paragraph-1 :weight :regular})
:flex 1
:padding-right 0
:padding-left (if small? 4 8)
+4 -5
View File
@@ -58,7 +58,7 @@
:label :char-limit :on-char-limit-reach :icon-name :multiline? :on-focus :on-blur])
(defn- base-input
[{:keys [on-change-text on-char-limit-reach container-style weight]}]
[{:keys [on-change-text on-char-limit-reach]}]
(let [status (reagent/atom :default)
internal-on-focus #(reset! status :focus)
internal-on-blur #(reset! status :default)
@@ -84,22 +84,21 @@
colors-by-status (style/status-colors status-kw blur? theme)
variant-colors (style/variants-colors blur? theme)
clean-props (apply dissoc props custom-props)]
[rn/view {:style container-style}
[:<>
(when (or label char-limit)
[label-&-counter
{:variant-colors variant-colors
:label label
:current-chars @char-count
:char-limit char-limit}])
[rn/view
{:style (style/input-container colors-by-status small? disabled?)}
[rn/view {:style (style/input-container colors-by-status small? disabled?)}
(when-let [{:keys [icon-name]} left-icon]
[left-accessory
{:variant-colors variant-colors
:small? small?
:icon-name icon-name}])
[rn/text-input
(cond-> {:style (style/input colors-by-status small? @multiple-lines? weight)
(cond-> {:style (style/input colors-by-status small? @multiple-lines?)
:accessibility-label :input
:placeholder-text-color (:placeholder colors-by-status)
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
@@ -49,6 +49,5 @@
[title-input/view
(merge title-input-props
{:blur? true
:size :heading-2
:placeholder placeholder
:customization-color customization-color})]]]))
@@ -20,7 +20,6 @@
placeholder
max-length
default-value
size
theme
container-style]
:or {max-length 0
@@ -40,7 +39,7 @@
[rn/text-input
{:style
(text/text-style
{:size (or size :heading-1)
{:size :heading-2
:weight :semi-bold
:style (style/title-text theme)})
:default-value default-value
@@ -1,86 +0,0 @@
(ns quo2.components.list-items.account.component-spec
(:require [test-helpers.component :as h]
[quo2.components.list-items.account.view :as account]
[quo2.foundations.colors :as colors]))
(h/describe "List items: account"
(h/test "default render'"
(h/render [account/view])
(h/is-truthy (h/query-by-label-text :container)))
(h/test "on-press-in changes state to :pressed"
(h/render [account/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 5)})))
(h/test "on-press-in changes state to :pressed with blur? enabled"
(h/render [account/view {:blur? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-5})))
(h/test "on-press-out changes state to :active"
(h/render [account/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 10)})))
(h/test "on-press-out changes state to :active with blur? enabled"
(h/render [account/view {:blur? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-10})))
(h/test "on-press-out changes state to :selected"
(h/render [account/view {:selectable? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/is-truthy (h/query-by-label-text :check-icon))))
(h/test "on-press-out calls on-press"
(let [on-press (h/mock-fn)]
(h/render [account/view {:on-press on-press}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/was-called on-press)))
(h/test "renders token props if type :tag"
(h/render [account/view {:type :tag}])
(h/is-truthy (h/query-by-label-text :tag-container)))
(h/test "renders keycard icon if title-icon? is true"
(h/render [account/view {:title-icon? true}])
(h/is-truthy (h/query-by-label-text :keycard-icon)))
(h/test "doesn't render keycard icon if title-icon? is false"
(h/render [account/view])
(h/is-falsy (h/query-by-label-text :keycard-icon)))
(h/test "renders balance container but not arrow icon if type :balance-neutral"
(h/render [account/view {:type :balance-neutral}])
(h/is-truthy (h/query-by-label-text :balance-container))
(h/is-falsy (h/query-by-label-text :arrow-icon)))
(h/test "renders balance container and negative arrow icon if type :balance-negative"
(h/render [account/view {:type :balance-negative}])
(h/is-truthy (h/query-by-label-text :balance-container))
(h/is-truthy (h/query-by-label-text :icon-negative))
(h/is-falsy (h/query-by-label-text :icon-positive)))
(h/test "renders balance container and positive arrow icon if type :balance-positive"
(h/render [account/view {:type :balance-positive}])
(h/is-truthy (h/query-by-label-text :balance-container))
(h/is-falsy (h/query-by-label-text :icon-negative))
(h/is-truthy (h/query-by-label-text :icon-positive)))
(h/test "renders options button if type :action"
(let [on-options-press (h/mock-fn)]
(h/render [account/view
{:type :action
:on-options-press on-options-press}])
(h/is-truthy (h/query-by-label-text :options-button))
(h/fire-event :on-press (h/get-by-label-text :options-button))
(h/was-called on-options-press))))
@@ -1,110 +0,0 @@
(ns quo2.components.list-items.account.style
(:require [quo2.foundations.colors :as colors]))
(defn- background-color
[{:keys [state blur? customization-color]}]
(cond (or (= state :pressed) (= state :selected))
(if blur? colors/white-opa-5 (colors/custom-color customization-color 50 5))
(= state :active)
(if blur? colors/white-opa-10 (colors/custom-color customization-color 50 10))
(and (= state :pressed) blur?) colors/white-opa-10
:else :transparent))
(defn container
[props]
{:height 56
:border-radius 12
:background-color (background-color props)
:flex-direction :row
:align-items :center
:padding-horizontal 12
:padding-vertical 6
:justify-content :space-between})
(def left-container
{:flex-direction :row
:align-items :center})
(defn metric-text
[type theme]
{:color (case type
:balance-positive (colors/theme-colors colors/success-50 colors/success-60 theme)
:balance-negative (colors/theme-colors colors/danger-50 colors/danger-60 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
(defn dot-divider
[type theme]
{:width 2
:height 2
:border-radius 2
:margin-horizontal 4
:background-color (case type
:balance-positive (colors/theme-colors colors/success-50-opa-40
colors/success-60-opa-40
theme)
:balance-negative (colors/theme-colors colors/danger-50-opa-40
colors/danger-50-opa-40
theme)
(colors/theme-colors colors/neutral-80-opa-40 colors/neutral-50-opa-40 theme))})
(defn arrow-icon
[type theme]
{:size 16
:color (if (= type :balance-positive)
(colors/theme-colors colors/success-50 colors/success-60 theme)
(colors/theme-colors colors/danger-50 colors/danger-60 theme))})
(def arrow-icon-container
{:margin-left 4})
(def account-container
{:margin-left 8})
(def account-title-container
{:flex-direction :row
:height 22
:align-items :center})
(defn account-address
[blur? theme]
{:height 18
:color (if blur?
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
(def keycard-icon-container
{:margin-left 4})
(def token-tag-container
{:height 40
:padding-top 4})
(defn token-tag-text-container
[blur? theme]
{:flex-direction :row
:align-items :center
:height 16
:padding-horizontal 3
:border-width 1
:border-radius 6
:border-color (if blur?
colors/white-opa-10
(colors/theme-colors colors/neutral-20
colors/neutral-80
theme))})
(defn token-tag-text
[blur? theme]
{:margin-top -1
:color (if blur?
colors/white-opa-70
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
(def balance-container
{:align-items :flex-end
:justify-content :space-between})
(def metrics-container
{:flex-direction :row
:align-items :center
:margin-top 2})
@@ -1,155 +0,0 @@
(ns quo2.components.list-items.account.view
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.list-items.account.style :as style]
[reagent.core :as reagent]
[quo2.components.icon :as icon]))
(defn- account-view
[{:keys [account-props title-icon? blur? theme]
:or {title-icon? false}}]
[rn/view {:style style/left-container}
[account-avatar/view (assoc account-props :size 32)]
[rn/view {:style style/account-container}
[rn/view
{:style style/account-title-container}
[text/text
{:weight :semi-bold
:size :paragraph-1}
(:name account-props)]
(when title-icon?
[rn/view
{:style style/keycard-icon-container
:accessibility-label :keycard-icon}
[icon/icon :i/keycard
{:size 20
:color (if blur?
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}]])]
[text/text {:size :paragraph-2}
[text/text
{:size :paragraph-2
:weight :monospace
:style (style/account-address blur? theme)}
(:address account-props)]]]])
(defn- balance-view
[{:keys [balance-props type theme]}]
[rn/view
{:style style/balance-container
:accessibility-label :balance-container}
[text/text
{:weight :medium
:size :paragraph-2}
(:fiat-value balance-props)]
[rn/view
{:style style/metrics-container}
[text/text
{:size :paragraph-2
:style (style/metric-text type theme)}
(str (:percentage-change balance-props) "%")]
[rn/view {:style (style/dot-divider type theme)}]
[text/text
{:size :paragraph-2
:style (style/metric-text type theme)}
(:fiat-change balance-props)]
(when (not= type :balance-neutral)
[rn/view
{:style style/arrow-icon-container
:accessibility-label :arrow-icon}
[icon/icon (if (= type :balance-positive) :i/positive :i/negative)
(assoc (style/arrow-icon type theme)
:accessibility-label
(if (= type :balance-positive) :icon-positive :icon-negative))]])]])
(defn- token-tag
[{:keys [token-props blur? theme]}]
;; TODO: Use Tiny tag component when available (issue #17341)
[rn/view
{:style (style/token-tag-text-container blur? theme)
:accessibility-label :tag-container}
[text/text
{:size :label
:weight :medium
:style (style/token-tag-text blur? theme)}
(str (:value token-props) " " (:symbol token-props))]])
(defn- options-button
[{:keys [on-options-press blur? theme]}]
[rn/pressable
{:accessibility-label :options-button
:on-press #(when on-options-press
(on-options-press))}
[icon/icon :i/options
{:color (if blur?
colors/white-opa-70
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}]])
(defn- check-icon
[{:keys [blur? customization-color theme]}]
[rn/view {:accessibility-label :check-icon}
[icon/icon :i/check
{:color (if blur?
colors/white
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme))}]])
(defn- f-internal-view
[]
(let [state (reagent/atom :default)
active-or-selected? (atom false)
timer (atom nil)
on-press-in (fn []
(when-not (= @state :selected)
(reset! timer (js/setTimeout #(reset! state :pressed) 100))))]
(fn [{:keys [type selectable? blur? customization-color on-press]
:or {customization-color :blue
type :default
blur? false}
:as props}]
(let [on-press-out (fn []
(let [new-state (if @active-or-selected?
:default
(if (and (= type :default) selectable?)
:selected
:active))]
(when @timer (js/clearTimeout @timer))
(reset! timer nil)
(reset! active-or-selected? (or (= new-state :active)
(= new-state :selected)))
(reset! state new-state)
(when on-press
(on-press))))]
(rn/use-effect
#(cond (and selectable? (= type :default) (= @state :active)) (reset! state :selected)
(and (not selectable?) (= type :default) (= @state :selected)) (reset! state :active))
[selectable?])
[rn/pressable
{:style (style/container
{:state @state :blur? blur? :customization-color customization-color})
:on-press-in on-press-in
:on-press-out on-press-out
:accessibility-label :container}
[account-view props]
[rn/view {:style (when (= type :tag) style/token-tag-container)}
(when (or (= type :balance-neutral)
(= type :balance-negative)
(= type :balance-positive))
[balance-view props])
(when (= type :tag)
[token-tag props])
(when (= type :action)
[options-button props])
(when (and (= type :default)
(= @state :selected))
[check-icon props])]]))))
(defn- internal-view
[props]
[:f> f-internal-view props])
(def view (quo.theme/with-theme internal-view))
@@ -38,7 +38,7 @@
:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? false)}
[channel-avatar/view
{:size :size-32
{:size :size/l
:locked? locked?
:full-name name
:customization-color customization-color
@@ -7,43 +7,43 @@
(if (types-for-squared-border type) :squared :rounded))
(def sizes
{:size-32 {:size 32
:user-avatar-size :small
:border-radius {:rounded 16 :squared 10}
:hole-radius {:rounded 18 :squared 12}
:margin-left -8
:hole-size 36
:hole-x 22
:hole-y -2}
:size-24 {:size 24
:user-avatar-size :xs
:border-radius {:rounded 12 :squared 8}
:hole-radius {:rounded 13 :squared 9}
:margin-left -4
:hole-size 26
:hole-x 19
:hole-y -1}
:size-20 {:size 20
:user-avatar-size :xxs
:border-radius {:rounded 10 :squared 8}
:hole-radius {:rounded 11 :squared 9}
:margin-left -4
:hole-size 22
:hole-x 15
:hole-y -1}
:size-16 {:size 16
:user-avatar-size :xxxs
:border-radius {:rounded 8 :squared 8}
:hole-radius {:rounded 9 :squared 9}
:margin-left -4
:hole-size 18
:hole-x 11
:hole-y -1}
:size-14 {:size 14
:user-avatar-size :xxxs
:border-radius {:rounded 7 :squared 7}
:hole-radius {:rounded 8 :squared 8}
:margin-left -2
:hole-size 16
:hole-x 11
:hole-y -1}})
{:size/s-32 {:size 32
:user-avatar-size :small
:border-radius {:rounded 16 :squared 10}
:hole-radius {:rounded 18 :squared 12}
:margin-left -8
:hole-size 36
:hole-x 22
:hole-y -2}
:size/s-24 {:size 24
:user-avatar-size :xs
:border-radius {:rounded 12 :squared 8}
:hole-radius {:rounded 13 :squared 9}
:margin-left -4
:hole-size 26
:hole-x 19
:hole-y -1}
:size/s-20 {:size 20
:user-avatar-size :xxs
:border-radius {:rounded 10 :squared 8}
:hole-radius {:rounded 11 :squared 9}
:margin-left -4
:hole-size 22
:hole-x 15
:hole-y -1}
:size/s-16 {:size 16
:user-avatar-size :xxxs
:border-radius {:rounded 8 :squared 8}
:hole-radius {:rounded 9 :squared 9}
:margin-left -4
:hole-size 18
:hole-x 11
:hole-y -1}
:size/s-14 {:size 14
:user-avatar-size :xxxs
:border-radius {:rounded 7 :squared 7}
:hole-radius {:rounded 8 :squared 8}
:margin-left -2
:hole-size 16
:hole-x 11
:hole-y -1}})
@@ -1,13 +1,67 @@
(ns quo2.components.list-items.preview-list.view
(:require [quo2.components.avatars.account-avatar.view :as account-avatar]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.list-items.preview-list.properties :as properties]
[quo2.components.tags.number-tag.view :as number-tag]
[quo2.components.icon :as quo2.icons]
[quo2.components.markdown.text :as quo2.text]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[quo2.components.list-items.preview-list.properties :as properties]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
[react-native.hole-view :as hole-view]))
;; This overflow item needs to be cleaned up once the "number tag" component is implemented
;; https://github.com/status-im/status-mobile/issues/17045
(defn get-overflow-color
[blur? blur-light-color blur-dark-color light-color dark-color theme]
(if blur?
(colors/theme-colors blur-light-color blur-dark-color theme)
(colors/theme-colors light-color dark-color theme)))
(def more-icon-for-sizes #{16 14})
(defn overflow-label
[{:keys [label size blur? border-radius margin-left theme more-than-99-label]}]
[rn/view
{:style {:width size
:height size
:margin-left margin-left
:border-radius border-radius
:justify-content :center
:align-items :center
:background-color (get-overflow-color
blur?
colors/neutral-80-opa-5
colors/white-opa-5
colors/neutral-20
colors/neutral-90
theme)}}
(if (more-icon-for-sizes size)
[quo2.icons/icon :i/more
{:size 12
:color (get-overflow-color
blur?
colors/neutral-80-opa-70
colors/white-opa-70
colors/neutral-50
colors/neutral-40
theme)}]
[quo2.text/text
{:size (if (= size 32) :paragraph-2 :label)
:weight :medium
:style {:color (get-overflow-color
blur?
colors/neutral-80-opa-70
colors/white-opa-70
colors/neutral-50
colors/neutral-40
theme)
:margin-left -2}}
;; If overflow label is below 100, show label as +label (ex. +30), else just show 99+
(if (< label 100)
(str "+" label)
more-than-99-label)])])
(defn- preview-item
[{:keys [item type size-key]}]
(let [size (get-in properties/sizes [size-key :size])
@@ -16,22 +70,22 @@
[size-key :border-radius (properties/border-type type)])]
(case type
:user [user-avatar/user-avatar
(assoc item
:ring? false
:status-indicator? false
:size user-avatar-size)]
(merge {:ring? false
:status-indicator? false
:size user-avatar-size}
item)]
:accounts [account-avatar/view
(assoc item :size size)]
(merge item {:size size})]
(:communities :collectibles) [fast-image/fast-image
{:source (or (:source item) item)
{:source (:source item)
:style {:width size
:height size
:border-radius border-radius}}]
(:tokens :network :dapps) [fast-image/fast-image
{:source (or (:source item) item)
{:source (:source item)
:style {:width size
:height size
:border-radius border-radius}}]
@@ -64,16 +118,16 @@
"[preview-list opts items]
opts
{:type :user/:communities/:accounts/:tokens/:collectibles/:dapps/:network
:size :size-32 | :size-24 | :size-20 | :size-16 | :size-14
:size :size/s-32 | :size/s-24 | :size/s-20 | :size/s-16 | :size/s-14
:number number of items in the list (optional)
:blur? overflow-label blur?}
items preview list items (only 4 items is required for preview)
"
[{:keys [type size number blur?]} items]
(let [size-key (if (contains? properties/sizes size) size :size-24)
number (or number (count items))
border-type (properties/border-type type)
margin-left (get-in properties/sizes [size-key :margin-left])]
[{:keys [type size number blur? theme more-than-99-label]} items]
(let [size-key (if (contains? properties/sizes size) size :size/s-24)
number (or number (count items))
margin-left (get-in properties/sizes [size-key :margin-left])
border-radius (get-in properties/sizes [size-key :border-radius (properties/border-type type)])]
[rn/view {:style {:flex-direction :row}}
(for [index (range (if (> number 4) 3 number))]
^{:key (str index number)}
@@ -84,11 +138,13 @@
:item (get (vec items) index)
:number number}])
(when (> number 4)
[number-tag/view
{:type border-type
:number (str (- number 3))
:size size-key
:blur? blur?
:container-style {:margin-left margin-left}}])]))
[overflow-label
{:label (- number 3)
:size (get-in properties/sizes [size-key :size])
:blur? blur?
:border-radius border-radius
:margin-left margin-left
:theme theme
:more-than-99-label more-than-99-label}])]))
(def view (quo.theme/with-theme view-internal))
@@ -1,51 +0,0 @@
(ns quo2.components.list-items.saved-address.component-spec
(:require [test-helpers.component :as h]
[quo2.components.list-items.saved-address.view :as saved-address]
[quo2.foundations.colors :as colors]))
(h/describe "List items: saved address"
(h/test "default render"
(h/render [saved-address/view])
(h/is-truthy (h/query-by-label-text :container)))
(h/test "on-press-in changes state to :pressed"
(h/render [saved-address/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 5)})))
(h/test "on-press-in changes state to :pressed with blur? enabled"
(h/render [saved-address/view {:blur? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-5})))
(h/test "on-press-out changes state to :active"
(h/render [saved-address/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 10)})))
(h/test "on-press-out changes state to :active with blur? enabled"
(h/render [saved-address/view {:blur? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-10})))
(h/test "on-press-out calls on-press"
(let [on-press (h/mock-fn)]
(h/render [saved-address/view {:on-press on-press}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/was-called on-press)))
(h/test "renders options button if type :action"
(let [on-options-press (h/mock-fn)]
(h/render [saved-address/view
{:type :action
:on-options-press on-options-press}])
(h/is-truthy (h/query-by-label-text :options-button))
(h/fire-event :on-press (h/get-by-label-text :options-button))
(h/was-called on-options-press))))
@@ -1,42 +0,0 @@
(ns quo2.components.list-items.saved-address.style
(:require [quo2.foundations.colors :as colors]))
(defn- background-color
[{:keys [state blur? customization-color]}]
(cond (and (or (= state :pressed) (= state :selected)) (not blur?))
(colors/custom-color customization-color 50 5)
(and (or (= state :pressed) (= state :selected)) blur?)
colors/white-opa-5
(and (= state :active) (not blur?))
(colors/custom-color customization-color 50 10)
(and (= state :active) blur?)
colors/white-opa-10
(and (= state :pressed) blur?) colors/white-opa-10
:else :transparent))
(defn container
[props]
{:height 56
:border-radius 12
:background-color (background-color props)
:flex-direction :row
:align-items :center
:padding-horizontal 12
:padding-vertical 6
:justify-content :space-between})
(def left-container
{:flex-direction :row
:align-items :center})
(def name-text
{:height 22})
(def account-container
{:margin-left 8})
(defn account-address
[blur? theme]
{:color (if blur?
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
@@ -1,79 +0,0 @@
(ns quo2.components.list-items.saved-address.view
(:require [quo2.components.avatars.wallet-user-avatar :as wallet-user-avatar]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.list-items.saved-address.style :as style]
[reagent.core :as reagent]
[quo2.components.icon :as icon]
[clojure.string :as string]))
(defn- left-container
[{:keys [blur? theme name address customization-color]}]
(let [names (remove string/blank? (string/split name " "))
first-name (if (> (count names) 0) (first names) "")
last-name (if (> (count names) 1) (last names) "")]
[rn/view {:style style/left-container}
[wallet-user-avatar/wallet-user-avatar
{:size :medium
:f-name first-name
:l-name last-name
:color customization-color}]
[rn/view {:style style/account-container}
[text/text
{:weight :semi-bold
:size :paragraph-1
:style style/name-text}
name]
[text/text {:size :paragraph-2}
[text/text
{:size :paragraph-2
:weight :monospace
:style (style/account-address blur? theme)}
address]]]]))
(defn- internal-view
[]
(let [state (reagent/atom :default)
active? (atom false)
timer (atom nil)
on-press-in (fn []
(when-not (= @state :selected)
(reset! timer (js/setTimeout #(reset! state :pressed) 100))))]
(fn [{:keys [blur? user-props customization-color
on-press
on-options-press
theme]
:or {customization-color :blue
blur? false}}]
(let [on-press-out (fn []
(let [new-state (if @active? :default :active)]
(when @timer (js/clearTimeout @timer))
(reset! timer nil)
(reset! active? (= new-state :active))
(reset! state new-state)
(when on-press
(on-press))))]
[rn/pressable
{:style (style/container
{:state @state :blur? blur? :customization-color customization-color})
:on-press-in on-press-in
:on-press-out on-press-out
:accessibility-label :container}
[left-container
{:blur? blur?
:theme theme
:name (:name user-props)
:address (:address user-props)
:customization-color (:customization-color user-props)}]
[rn/pressable
{:accessibility-label :options-button
:on-press #(when on-options-press
(on-options-press))}
[icon/icon :i/options
{:color (if blur?
colors/white-opa-70
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}]]]))))
(def view (quo.theme/with-theme internal-view))
@@ -1,53 +0,0 @@
(ns quo2.components.list-items.saved-contact-address.component-spec
(:require [test-helpers.component :as h]
[quo2.components.list-items.saved-contact-address.view :as saved-contact-address]
[quo2.foundations.colors :as colors]))
(def account
{:name "New House"
:address "0x21a...49e"
:emoji "🍔"
:customization-color :purple})
(h/describe "List items: saved contact address"
(h/test "default render"
(h/render [saved-contact-address/view])
(h/is-truthy (h/query-by-label-text :container)))
(h/test "renders account detail when passing one account"
(h/render [saved-contact-address/view {:accounts (repeat 1 account)}])
(h/is-truthy (h/query-by-label-text :account-container)))
(h/test "renders account count when passing multiple accounts"
(h/render [saved-contact-address/view {:accounts (repeat 2 account)}])
(h/is-truthy (h/query-by-label-text :accounts-count)))
(h/test "on-press-in changes state to :pressed"
(h/render [saved-contact-address/view {:accounts (repeat 1 account)}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 5)})))
(h/test "on-press-out changes state to :active if active-state? is true (default value)"
(h/render [saved-contact-address/view {:accounts (repeat 1 account)}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 10)})))
(h/test "on-press-out changes state to :default if active-state? is false"
(h/render [saved-contact-address/view
{:accounts (repeat 1 account)
:active-state? false}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor :transparent})))
(h/test "on-press calls on-press"
(let [on-press (h/mock-fn)]
(h/render [saved-contact-address/view
{:on-press on-press
:accounts (repeat 1 account)}])
(h/fire-event :on-press (h/get-by-label-text :container))
(h/was-called on-press))))
@@ -1,62 +0,0 @@
(ns quo2.components.list-items.saved-contact-address.style
(:require [quo2.foundations.colors :as colors]))
(defn- background-color
[{:keys [state customization-color]}]
(cond (or (= state :pressed) (= state :selected))
(colors/custom-color customization-color 50 5)
(= state :active)
(colors/custom-color customization-color 50 10)
:else :transparent))
(defn container
[props]
{:height 56
:border-radius 12
:background-color (background-color props)
:flex-direction :row
:align-items :center
:padding-horizontal 12
:padding-vertical 6
:justify-content :space-between})
(def left-container
{:flex-direction :row
:align-items :center})
(defn dot-divider
[theme]
{:width 2
:height 2
:border-radius 2
:margin-horizontal 4
:background-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(def saved-contact-container
{:margin-left 8})
(def account-container
{:flex-direction :row
:align-items :center})
(def account-title-container
{:flex-direction :row
:height 22
:align-items :center})
(defn account-name
[theme]
{:margin-left 4
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(defn accounts-count
[theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(defn account-address
[theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(def contact-icon-container
{:margin-left 4
:margin-top 1.5})
@@ -1,93 +0,0 @@
(ns quo2.components.list-items.saved-contact-address.view
(:require [quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.avatars.account-avatar.view :as account-avatar]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.list-items.saved-contact-address.style :as style]
[reagent.core :as reagent]
[quo2.components.icon :as icon]
[utils.i18n :as i18n]))
(defn- account
[{:keys [emoji name address customization-color theme]}]
[rn/view
{:accessibility-label :account-container
:style style/account-container}
[account-avatar/view
{:emoji emoji
:size 16
:customization-color customization-color}]
[text/text
{:size :paragraph-2
:weight :monospace
:style (style/account-name theme)}
name]
[rn/view {:style (style/dot-divider theme)}]
[text/text
{:size :paragraph-2
:weight :monospace
:style (style/account-address theme)}
address]])
(defn- internal-view
[]
(let [state (reagent/atom :default)
active? (atom false)
timer (atom nil)
on-press-in (fn []
(when-not (= @state :selected)
(reset! timer (js/setTimeout #(reset! state :pressed) 100))))]
(fn [{:keys [contact-props accounts active-state? customization-color on-press theme]
:or {customization-color :blue
accounts []
active-state? true}}]
(let [accounts-count (count accounts)
account-props (when (= accounts-count 1)
(first accounts))
on-press-out (fn []
(let [new-state (if (or (not active-state?) @active?) :default :active)]
(when @timer (js/clearTimeout @timer))
(reset! timer nil)
(reset! active? (= new-state :active))
(reset! state new-state)))]
[rn/pressable
{:style (style/container
{:state @state :customization-color customization-color})
:on-press-in on-press-in
:on-press-out on-press-out
:on-press #(when on-press
(on-press))
:accessibility-label :container}
[rn/view {:style style/left-container}
[user-avatar/user-avatar (assoc contact-props :size :small)]
[rn/view {:style style/saved-contact-container}
[rn/view
{:style style/account-title-container}
[text/text
{:weight :semi-bold
:size :paragraph-1}
(:full-name contact-props)]
[icon/icon :i/contact
{:container-style style/contact-icon-container
:accessibility-label :contact-icon
:size 12
:color (colors/theme-colors colors/primary-50 colors/primary-60 theme)
:color-2 colors/white}]]
(if account-props
[account (assoc account-props :theme theme)]
[text/text
{:accessibility-label :accounts-count
:size :paragraph-2
:style (style/accounts-count theme)}
(i18n/label :t/accounts-count {:count accounts-count})])]]
(when (> accounts-count 1)
[icon/icon :i/chevron-right
{:accessibility-label :check-icon
:size 20
:color (colors/theme-colors colors/neutral-50
colors/neutral-40
theme)}])]))))
(def view (quo.theme/with-theme internal-view))
@@ -12,9 +12,9 @@
[reagent.core :as reagent]))
(defn- internal-view
[]
[{:keys [theme customization-color status token metrics? values on-press]}]
(let [state (reagent/atom :default)]
(fn [{:keys [theme customization-color status token metrics? values on-press]}]
(fn []
(let [bg-opacity (case @state
:active 10
:pressed 5
@@ -42,7 +42,7 @@
[text/text
{:size :paragraph-2
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
(str crypto-value " " (if token (string/upper-case (clj->js token)) ""))]]]
(str crypto-value " " (string/upper-case (clj->js token)))]]]
[rn/view
{:style {:align-items :flex-end
:justify-content :space-between}}
@@ -21,7 +21,7 @@
[rn/view
{:margin-right 8}
[icon-avatar/icon-avatar
{:size :size-32
{:size :size/s-32
:icon icon
:color color
:opacity opacity}]])
@@ -86,6 +86,6 @@
counter-label]
[rn/view {:style (styles/notification-dot customization-color)}]))]]))
(defn view
(defn bottom-nav-tab
[opts]
[:f> f-bottom-nav-tab opts])
@@ -19,6 +19,12 @@
:align-items :center
:justify-content (if centered? :center :flex-start)})
(def account-switcher-placeholder
{:width 32
:height 32
:border-radius 10
:background-color (colors/custom-color :purple 50)})
(def right-actions-container
{:flex-direction :row})
@@ -1,10 +1,7 @@
(ns quo2.components.navigation.page-nav.view
(:require [quo2.components.avatars.group-avatar.view :as group-avatar]
[quo2.components.buttons.button.view :as button]
[quo2.components.buttons.button.properties :as button-properties]
[quo2.components.dropdowns.dropdown.view :as dropdown]
[quo2.components.dropdowns.dropdown.properties :as dropdown-properties]
[quo2.components.dropdowns.network-dropdown.view :as network-dropdown]
[quo2.components.dropdowns.dropdown :as dropdown]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.components.navigation.page-nav.style :as style]
@@ -21,7 +18,7 @@
:blur :grey})
(defn- page-nav-base
[{:keys [margin-top background on-press accessibility-label icon-name behind-overlay?]
[{:keys [margin-top background on-press accessibility-label icon-name]
:or {background :white}}
& children]
(into [rn/view {:style (style/container margin-top)}
@@ -31,9 +28,6 @@
:icon-only? true
:size 32
:on-press on-press
:background (if behind-overlay?
:blur
(button-properties/backgrounds background))
:accessibility-label accessibility-label}
icon-name])]
children))
@@ -41,7 +35,7 @@
(defn- right-section-spacing [] [rn/view {:style style/right-actions-spacing}])
(defn- add-right-buttons-xf
[max-actions background behind-overlay?]
[max-actions background]
(comp (filter map?)
(take max-actions)
(map (fn [{:keys [icon-name label] :as button-props}]
@@ -51,35 +45,24 @@
:icon-only? icon-name
:size 32
:accessible true
:background (if behind-overlay?
:blur
(when (button-properties/backgrounds background) background)))
:background (when (#{:photo :blur} background) background))
(or label icon-name)]))
(interpose [right-section-spacing])))
(defn- account-switcher-content
[{:keys [customization-color on-press emoji state]}]
[dropdown/view
{:type :customization
:customization-color customization-color
:state (or state :default)
:size :size-32
:on-press on-press
:emoji? true}
emoji])
(defn- right-content
[{:keys [background content max-actions min-size? support-account-switcher? account-switcher
behind-overlay?]
[{:keys [background content max-actions min-size? support-account-switcher?]
:or {support-account-switcher? true}}]
[rn/view (when min-size? {:style style/right-content-min-size})
(cond
;; TODO: use account-switcher when available (issue #16456)
(and support-account-switcher? (= content :account-switcher))
[account-switcher-content account-switcher]
[rn/pressable
{:style style/account-switcher-placeholder
:on-press #(js/alert "Not implemented yet")}]
(coll? content)
(into [rn/view {:style style/right-actions-container}]
(add-right-buttons-xf max-actions background behind-overlay?)
(add-right-buttons-xf max-actions background)
content)
:else
@@ -95,19 +78,17 @@
title]])
(defn- dropdown-center
[{:keys [theme background dropdown-on-press dropdown-selected? dropdown-text]}]
(let [dropdown-type (cond
(= background :photo) :grey
(and (= theme :dark) (= background :blur)) :grey
:else :ghost)
dropdown-state (if dropdown-selected? :active :default)]
[{:keys [theme background dropdown-on-change dropdown-selected? dropdown-text]}]
(let [dropdown-type (cond
(= background :photo) :grey
(and (= theme :dark) (= background :blur)) :grey
:else :ghost)]
[rn/view {:style (style/center-content-container true)}
[dropdown/view
{:type dropdown-type
:state dropdown-state
:size :size-32
:background (when (dropdown-properties/backgrounds background) background)
:on-press dropdown-on-press}
[dropdown/dropdown
{:type dropdown-type
:size 32
:on-change dropdown-on-change
:selected dropdown-selected?}
dropdown-text]]))
(defn- token-center
@@ -175,17 +156,8 @@
:number-of-lines 1}
shown-name]]))
(defn- wallet-networks-center
[{:keys [networks networks-on-press background]}]
[rn/view {:style (style/center-content-container true)}
[network-dropdown/view
{:state :default
:on-press networks-on-press
:blur? (= background :blur)} networks]])
(defn- view-internal
"behind-overlay is necessary for us to know if the page-nav buttons are under the bottom sheet overlay or not."
[{:keys [type right-side background text-align account-switcher behind-overlay?]
[{:keys [type right-side background text-align]
:or {type :no-title
text-align :center
right-side :none
@@ -194,37 +166,35 @@
(case type
:no-title
[page-nav-base props
[right-content
{:background background :content right-side :max-actions 3 :behind-overlay? behind-overlay?}]]
[right-content {:background background :content right-side :max-actions 3}]]
:title
(let [centered? (= text-align :center)]
[page-nav-base props
[title-center (assoc props :centered? centered?)]
[right-content
{:background background
:content right-side
:max-actions (if centered? 1 3)
:min-size? centered?
:account-switcher account-switcher}]])
{:background background
:content right-side
:max-actions (if centered? 1 3)
:min-size? centered?}]])
:dropdown
[page-nav-base props
[dropdown-center props]
[right-content
{:background background
:content right-side
:max-actions 1
:support-account-switcher? false}]]
[rn/view {:style style/right-actions-container}
(let [{button-icon :icon-name :as button-props} (first right-side)]
[button/button
(assoc button-props
:type (button-type background)
:icon-only? true
:size 32
:accessible true)
button-icon])]]
:token
[page-nav-base props
[token-center props]
[right-content
{:background background
:content right-side
:max-actions 3
:account-switcher account-switcher}]]
[right-content {:background background :content right-side :max-actions 3}]]
:channel
[page-nav-base props
@@ -246,13 +216,18 @@
:wallet-networks
[page-nav-base props
[wallet-networks-center props]
;; TODO: use wallet-networks when available (issue #16946)
[rn/view {:style (style/center-content-container true)}
[text/text
{:weight :regular
:size :paragraph-1
:number-of-lines 1}
"NETWORK DROPDOWN"]]
[right-content
{:background background
:content right-side
:max-actions 1
:min-size? true
:account-switcher account-switcher}]]
{:background background
:content right-side
:max-actions 1
:min-size? true}]]
(:community :network)
[page-nav-base props
@@ -280,19 +255,12 @@
:on-press (fn callback [] nil)
:accessibility-label \"an optional label\"}
- account-switcher (optional)
- props to render dropdown component (emoji only) e.g.:
{:customization-color :purple
:on-press (fn [] nil)
:state :default (inherit dropdown states)
:emoji \"🍑\"}
Depending on the `type` selected, different properties are accepted:
`:title`
- title
- text-align: `:center` or `:left`
`:dropdown`
- dropdown-on-press: a callback
- dropdown-on-change: a callback
- dropdown-selected?: a boolean
- dropdown-text
`:token`
@@ -308,8 +276,7 @@
- description
- picture: a valid rn/image `:source` value
`:wallet-network`
- networks: a vector of network image source
- networks-on-press: a callback
(Not implemented yet)
`:community`
- community-name
- community-logo: a valid rn/image `:source` value
@@ -26,15 +26,11 @@
{:color colors/white})
(defn message-container
[attachment text-with-photos?]
[attachment]
{:border-radius 12
:margin-top 10
:padding-horizontal 12
:padding-vertical (if (and
(not text-with-photos?)
(#{:photo :gif} attachment))
12
8)
:padding-vertical (if (#{:photo :gif} attachment) 12 8)
:background-color colors/white-opa-5})
(def footer-container
@@ -73,33 +73,24 @@
detail]]))
context))))
(defn- hiccup-props
[body]
(and (vector? body)
(map? (second body))
(second body)))
(defn- activity-message
[{:keys [title body title-number-of-lines body-number-of-lines attachment]}]
(let [{:keys [photos message-text]} (hiccup-props body)
text-with-photos? (and (not (string/blank? message-text))
(seq photos))]
[rn/view {:style (style/message-container attachment text-with-photos?)}
(when title
[text/text
{:size :paragraph-2
:accessibility-label :activity-message-title
:style style/message-title
:number-of-lines title-number-of-lines}
title])
(if (string? body)
[text/text
{:style style/message-body
:accessibility-label :activity-message-body
:size :paragraph-1
:number-of-lines body-number-of-lines}
body]
body)]))
[rn/view {:style (style/message-container attachment)}
(when title
[text/text
{:size :paragraph-2
:accessibility-label :activity-message-title
:style style/message-title
:number-of-lines title-number-of-lines}
title])
(if (string? body)
[text/text
{:style style/message-body
:accessibility-label :activity-message-body
:size :paragraph-1
:number-of-lines body-number-of-lines}
body]
body)])
(defn- activity-title
[title replying?]
@@ -1,7 +1,5 @@
(ns quo2.components.notifications.activity-logs-photos.style)
(def text {:margin-bottom 8})
(def photos-container
{:flex 1
:height 40

Some files were not shown because too many files have changed in this diff Show More