feat: Implement quo2 code-snippet-preview component (#17235)
This commit is contained in:
parent
70d6291c57
commit
96f476fc2b
|
@ -1,87 +0,0 @@
|
||||||
(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))
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
(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.snippet
|
(ns quo2.components.code.common.view
|
||||||
(:require [cljs-bean.core :as bean]
|
(:require [cljs-bean.core :as bean]
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[quo2.components.buttons.button.view :as button]
|
[quo2.components.buttons.button.view :as button]
|
||||||
[quo2.components.code.code.style :as style]
|
[quo2.components.code.common.style :as style]
|
||||||
[quo2.components.markdown.text :as text]
|
[quo2.components.markdown.text :as text]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.linear-gradient :as linear-gradient]
|
[react-native.linear-gradient :as linear-gradient]
|
||||||
|
@ -10,39 +10,41 @@
|
||||||
[reagent.core :as reagent]))
|
[reagent.core :as reagent]))
|
||||||
|
|
||||||
(defn- render-nodes
|
(defn- render-nodes
|
||||||
[nodes]
|
[nodes preview?]
|
||||||
(map (fn [{:keys [children value last-line?] :as node}]
|
(map (fn [{:keys [children value last-line?] :as node}]
|
||||||
(if children
|
(if children
|
||||||
(into [text/text
|
(into [text/text
|
||||||
(cond-> {:weight :code
|
(cond-> {:weight :code
|
||||||
:size :paragraph-2
|
:size :paragraph-2
|
||||||
:style (style/text-style (get-in node [:properties :className]))}
|
:style (style/text-style (get-in node [:properties :className]) preview?)}
|
||||||
last-line? (assoc :number-of-lines 1))]
|
last-line? (assoc :number-of-lines 1))]
|
||||||
(render-nodes children))
|
(render-nodes children preview?))
|
||||||
;; Remove newlines as we already render each line separately.
|
;; Remove newlines as we already render each line separately.
|
||||||
(string/trim-newline value)))
|
(string/trim-newline value)))
|
||||||
nodes))
|
nodes))
|
||||||
|
|
||||||
(defn- line
|
(defn- line
|
||||||
[{:keys [line-number line-number-width]} children]
|
[{:keys [line-number line-number-width preview?]} children]
|
||||||
[rn/view {:style style/line}
|
[rn/view {:style style/line}
|
||||||
[rn/view {:style (style/line-number line-number-width)}
|
[rn/view {:style (style/line-number line-number-width preview?)}
|
||||||
[text/text
|
[text/text
|
||||||
{:style (style/text-style ["line-number"])
|
{:style (style/text-style ["line-number"] preview?)
|
||||||
:weight :code
|
:weight :code
|
||||||
:size :paragraph-2}
|
:size :paragraph-2}
|
||||||
line-number]]
|
line-number]]
|
||||||
children])
|
(cond->> children
|
||||||
|
preview? (conj [rn/view {:style style/line-content}]))])
|
||||||
|
|
||||||
(defn- code-block
|
(defn- code-block
|
||||||
[{:keys [rows line-number-width]}]
|
[{:keys [rows line-number-width preview?]}]
|
||||||
[rn/view
|
[rn/view
|
||||||
(->> rows
|
(->> preview?
|
||||||
(render-nodes)
|
(render-nodes rows)
|
||||||
(map-indexed (fn [idx row-content]
|
(map-indexed (fn [idx row-content]
|
||||||
[line
|
[line
|
||||||
{:line-number (inc idx)
|
{:line-number (inc idx)
|
||||||
:line-number-width line-number-width}
|
:line-number-width line-number-width
|
||||||
|
:preview? preview?}
|
||||||
row-content]))
|
row-content]))
|
||||||
(into [:<>]))])
|
(into [:<>]))])
|
||||||
|
|
||||||
|
@ -66,36 +68,44 @@
|
||||||
(* 9 max-line-digits font-scale))))
|
(* 9 max-line-digits font-scale))))
|
||||||
|
|
||||||
(defn- f-native-renderer
|
(defn- f-native-renderer
|
||||||
[{:keys [rows max-lines on-copy-press]
|
[{:keys [rows max-lines on-copy-press preview? theme]
|
||||||
:or {max-lines ##Inf}}]
|
:or {max-lines ##Inf}}]
|
||||||
(let [font-scale (:font-scale (rn/get-window))
|
(let [font-scale (:font-scale (rn/get-window))
|
||||||
total-rows (count rows)
|
total-rows (count rows)
|
||||||
number-rows-to-show (min (count rows) max-lines)
|
number-rows-to-show (if preview?
|
||||||
line-number-width (calc-line-number-width font-scale number-rows-to-show)
|
0
|
||||||
|
(min (count rows) max-lines))
|
||||||
|
line-number-width (if preview? 20 (calc-line-number-width font-scale number-rows-to-show))
|
||||||
truncated? (< number-rows-to-show total-rows)
|
truncated? (< number-rows-to-show total-rows)
|
||||||
rows-to-show-coll (if truncated?
|
rows-to-show-coll (if truncated?
|
||||||
(as-> rows $
|
(as-> rows $
|
||||||
(update $ number-rows-to-show assoc :last-line? true)
|
(update $ number-rows-to-show assoc :last-line? true)
|
||||||
(take (inc number-rows-to-show) $))
|
(take (inc number-rows-to-show) $))
|
||||||
rows)]
|
rows)]
|
||||||
[rn/view {:style (style/container)}
|
[rn/view {:style (style/container preview? theme)}
|
||||||
[rn/view {:style (style/line-number-container line-number-width)}]
|
[rn/view {:style (style/line-number-container line-number-width preview? theme)}]
|
||||||
[rn/view {:style (style/divider line-number-width)}]
|
(if preview?
|
||||||
[mask-view {:apply-mask? truncated?}
|
[code-block
|
||||||
[code-block
|
{:rows rows-to-show-coll
|
||||||
{:rows rows-to-show-coll
|
:line-number-width line-number-width
|
||||||
:line-number-width line-number-width}]]
|
:preview? preview?}]
|
||||||
[rn/view {:style style/copy-button}
|
[:<>
|
||||||
[button/button
|
[rn/view {:style (style/divider line-number-width)}]
|
||||||
{:icon-only? true
|
[mask-view {:apply-mask? truncated?}
|
||||||
:type :grey
|
[code-block
|
||||||
:background :blur
|
{:rows rows-to-show-coll
|
||||||
:size 24
|
:line-number-width line-number-width}]]
|
||||||
:on-press on-copy-press}
|
[rn/view {:style style/copy-button}
|
||||||
:main-icons/copy]]]))
|
[button/button
|
||||||
|
{:icon-only? true
|
||||||
|
:type :grey
|
||||||
|
:background :blur
|
||||||
|
:size 24
|
||||||
|
:on-press on-copy-press}
|
||||||
|
:main-icons/copy]]])]))
|
||||||
|
|
||||||
(defn snippet
|
(defn view
|
||||||
[{:keys [language max-lines on-copy-press]} children]
|
[{:keys [language max-lines on-copy-press preview? theme]} children]
|
||||||
[highlighter/highlighter
|
[highlighter/highlighter
|
||||||
{:language language
|
{:language language
|
||||||
:renderer (fn [^js/Object props]
|
:renderer (fn [^js/Object props]
|
||||||
|
@ -103,8 +113,11 @@
|
||||||
[:f> f-native-renderer
|
[:f> f-native-renderer
|
||||||
{:rows (-> props .-rows bean/->clj)
|
{:rows (-> props .-rows bean/->clj)
|
||||||
:on-copy-press #(when on-copy-press (on-copy-press children))
|
:on-copy-press #(when on-copy-press (on-copy-press children))
|
||||||
:max-lines max-lines}]))
|
:max-lines max-lines
|
||||||
|
:preview? preview?
|
||||||
|
:theme theme}]))
|
||||||
:show-line-numbers false
|
:show-line-numbers false
|
||||||
:style {}
|
:style {}
|
||||||
:custom-style {:background-color nil}}
|
:custom-style {:background-color nil}}
|
||||||
children])
|
children])
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
(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))
|
|
@ -0,0 +1,11 @@
|
||||||
|
(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])
|
|
@ -19,7 +19,8 @@
|
||||||
quo2.components.calendar.calendar.view
|
quo2.components.calendar.calendar.view
|
||||||
quo2.components.calendar.calendar-day.view
|
quo2.components.calendar.calendar-day.view
|
||||||
quo2.components.calendar.calendar-year.view
|
quo2.components.calendar.calendar-year.view
|
||||||
quo2.components.code.snippet
|
quo2.components.code.snippet.view
|
||||||
|
quo2.components.code.snippet-preview.view
|
||||||
quo2.components.colors.color-picker.view
|
quo2.components.colors.color-picker.view
|
||||||
quo2.components.common.notification-dot.view
|
quo2.components.common.notification-dot.view
|
||||||
quo2.components.common.separator.view
|
quo2.components.common.separator.view
|
||||||
|
@ -165,7 +166,8 @@
|
||||||
(def calendar-year quo2.components.calendar.calendar-year.view/view)
|
(def calendar-year quo2.components.calendar.calendar-year.view/view)
|
||||||
|
|
||||||
;;;; Code
|
;;;; Code
|
||||||
(def snippet quo2.components.code.snippet/snippet)
|
(def snippet quo2.components.code.snippet.view/view)
|
||||||
|
(def snippet-preview quo2.components.code.snippet-preview.view/view)
|
||||||
|
|
||||||
;;;; Cards
|
;;;; Cards
|
||||||
(def small-option-card quo2.components.onboarding.small-option-card.view/small-option-card)
|
(def small-option-card quo2.components.onboarding.small-option-card.view/small-option-card)
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
(ns status-im2.contexts.quo-preview.code.snippet-preview
|
||||||
|
(:require [quo2.core :as quo]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||||
|
|
||||||
|
(def go-example
|
||||||
|
"for(let ind")
|
||||||
|
|
||||||
|
(def clojure-example
|
||||||
|
"(for [{:keys [url title description thumbnail hostname]} previews]")
|
||||||
|
|
||||||
|
(def examples
|
||||||
|
{:clojure {:language :clojure
|
||||||
|
:text clojure-example}
|
||||||
|
:go {:language :go
|
||||||
|
:text go-example}})
|
||||||
|
|
||||||
|
(def descriptor
|
||||||
|
[{:key :language
|
||||||
|
:type :select
|
||||||
|
:options [{:key :clojure}
|
||||||
|
{:key :go}]}
|
||||||
|
{:label "Syntax highlight?"
|
||||||
|
:key :syntax
|
||||||
|
:type :boolean}])
|
||||||
|
|
||||||
|
(defn view
|
||||||
|
[]
|
||||||
|
(let [state (reagent/atom {:language :clojure
|
||||||
|
:max-lines 1
|
||||||
|
:syntax true})]
|
||||||
|
(fn []
|
||||||
|
(let [language (if (:syntax @state) (:language @state) :text)
|
||||||
|
text (-> (:language @state) examples :text)]
|
||||||
|
[preview/preview-container {:state state :descriptor descriptor}
|
||||||
|
[quo/snippet-preview
|
||||||
|
{:language language} text]]))))
|
|
@ -27,6 +27,7 @@
|
||||||
[status-im2.contexts.quo-preview.calendar.calendar-year :as calendar-year]
|
[status-im2.contexts.quo-preview.calendar.calendar-year :as calendar-year]
|
||||||
[status-im2.contexts.quo-preview.browser.browser-input :as browser-input]
|
[status-im2.contexts.quo-preview.browser.browser-input :as browser-input]
|
||||||
[status-im2.contexts.quo-preview.code.snippet :as code-snippet]
|
[status-im2.contexts.quo-preview.code.snippet :as code-snippet]
|
||||||
|
[status-im2.contexts.quo-preview.code.snippet-preview :as code-snippet-preview]
|
||||||
[status-im2.contexts.quo-preview.graph.interactive-graph :as interactive-graph]
|
[status-im2.contexts.quo-preview.graph.interactive-graph :as interactive-graph]
|
||||||
[status-im2.contexts.quo-preview.graph.wallet-graph :as wallet-graph]
|
[status-im2.contexts.quo-preview.graph.wallet-graph :as wallet-graph]
|
||||||
[status-im2.contexts.quo-preview.colors.color-picker :as color-picker]
|
[status-im2.contexts.quo-preview.colors.color-picker :as color-picker]
|
||||||
|
@ -177,7 +178,9 @@
|
||||||
{:name :calendar-year
|
{:name :calendar-year
|
||||||
:component calendar-year/view}]
|
:component calendar-year/view}]
|
||||||
:code [{:name :snippet
|
:code [{:name :snippet
|
||||||
:component code-snippet/view}]
|
:component code-snippet/view}
|
||||||
|
{:name :snippet-preview
|
||||||
|
:component code-snippet-preview/view}]
|
||||||
:colors [{:name :color-picker
|
:colors [{:name :color-picker
|
||||||
:component color-picker/view}]
|
:component color-picker/view}]
|
||||||
:community [{:name :community-card-view
|
:community [{:name :community-card-view
|
||||||
|
|
Loading…
Reference in New Issue