mirror of
https://github.com/penpot/penpot.git
synced 2025-03-13 16:21:57 -05:00
✨ Changes to library model
This commit is contained in:
parent
a412fc113d
commit
69fb1426d4
12 changed files with 170 additions and 105 deletions
|
@ -55,6 +55,33 @@
|
|||
(>= % min-safe-int)
|
||||
(<= % max-safe-int)))
|
||||
|
||||
|
||||
(s/def :internal.page.gradient.stop/color ::string)
|
||||
(s/def :internal.page.gradient.stop/opacity ::safe-number)
|
||||
(s/def :internal.page.gradient.stop/offset ::safe-number)
|
||||
|
||||
(s/def :internal.page.gradient/start-x ::safe-number)
|
||||
(s/def :internal.page.gradient/start-y ::safe-number)
|
||||
(s/def :internal.page.gradient/end-x ::safe-number)
|
||||
(s/def :internal.page.gradient/end-y ::safe-number)
|
||||
(s/def :internal.page.gradient/width ::safe-number)
|
||||
|
||||
(s/def :internal.page.gradient/stop
|
||||
(s/keys :req-un [:internal.page.gradient.stop/color
|
||||
:internal.page.gradient.stop/opacity
|
||||
:internal.page.gradient.stop/offset]))
|
||||
|
||||
(s/def :internal.page.gradient/stops
|
||||
(s/map-of ::safe-number :internal.page.gradient/stop))
|
||||
|
||||
(s/def ::gradient
|
||||
(s/keys :req-un [:internal.page.gradient/start-x
|
||||
:internal.page.gradient/start-y
|
||||
:internal.page.gradient/end-x
|
||||
:internal.page.gradient/end-y
|
||||
:internal.page.gradient/width
|
||||
:internal.page.gradient/stops]))
|
||||
|
||||
;; Page Options
|
||||
(s/def :internal.page.grid.color/value string?)
|
||||
(s/def :internal.page.grid.color/opacity ::safe-number)
|
||||
|
@ -110,10 +137,13 @@
|
|||
(s/def :internal.shape/blocked boolean?)
|
||||
(s/def :internal.shape/collapsed boolean?)
|
||||
(s/def :internal.shape/content any?)
|
||||
|
||||
(s/def :internal.shape/fill-color string?)
|
||||
(s/def :internal.shape/fill-opacity ::safe-number)
|
||||
(s/def :internal.shape/fill-gradient (s/nilable ::gradient))
|
||||
(s/def :internal.shape/fill-color-ref-file (s/nilable uuid?))
|
||||
(s/def :internal.shape/fill-color-ref-id (s/nilable uuid?))
|
||||
(s/def :internal.shape/fill-opacity ::safe-number)
|
||||
|
||||
(s/def :internal.shape/font-family string?)
|
||||
(s/def :internal.shape/font-size ::safe-integer)
|
||||
(s/def :internal.shape/font-style string?)
|
||||
|
|
|
@ -280,6 +280,10 @@
|
|||
justify-items: center;
|
||||
grid-column-gap: 0.25rem;
|
||||
|
||||
&.disable-opacity {
|
||||
grid-template-columns: 3.5rem repeat(3, 1fr);
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
gradient-data (select-keys gradient [:start-x :start-y
|
||||
:end-x :end-y
|
||||
:width])]
|
||||
|
||||
(cond-> {:type type
|
||||
:current-color current-color}
|
||||
gradient (assoc :gradient-data gradient-data)
|
||||
|
@ -113,7 +114,7 @@
|
|||
:width 1.0})
|
||||
|
||||
(mf/defc colorpicker
|
||||
[{:keys [data on-change on-accept]}]
|
||||
[{:keys [data disable-gradient disable-opacity on-change on-accept]}]
|
||||
(let [state (mf/use-state (data->state data))
|
||||
active-tab (mf/use-state :ramp #_:harmony #_:hsva)
|
||||
locale (mf/deref i18n/locale)
|
||||
|
@ -138,8 +139,9 @@
|
|||
handle-change-color
|
||||
(fn [changes]
|
||||
(let [editing-stop (:editing-stop @state)]
|
||||
(swap! state update :current-color merge changes)
|
||||
(swap! state update-in [:stops editing-stop] merge changes)
|
||||
(swap! state #(cond-> %
|
||||
true (update :current-color merge changes)
|
||||
editing-stop (update-in [:stops editing-stop] merge changes)))
|
||||
|
||||
#_(when (:hex changes)
|
||||
(reset! value-ref (:hex changes)))
|
||||
|
@ -150,10 +152,12 @@
|
|||
|
||||
handle-change-stop
|
||||
(fn [offset]
|
||||
(let [offset-color (get-in @state [:stops offset])]
|
||||
(swap! state assoc :current-color offset-color)
|
||||
(swap! state assoc :editing-stop offset)
|
||||
(st/emit! (dc/select-gradient-stop offset))))
|
||||
(when-let [offset-color (get-in @state [:stops offset])]
|
||||
(do (swap! state assoc
|
||||
:current-color offset-color
|
||||
:editing-stop offset)
|
||||
|
||||
(st/emit! (dc/select-gradient-stop offset)))))
|
||||
|
||||
on-select-library-color
|
||||
(fn [color] (prn "color" color))
|
||||
|
@ -210,20 +214,21 @@
|
|||
|
||||
(mf/use-effect
|
||||
(mf/deps picking-color? picked-color)
|
||||
(fn [] (when picking-color?
|
||||
(let [[r g b] (or picked-color [0 0 0])
|
||||
hex (uc/rgb->hex [r g b])
|
||||
[h s v] (uc/hex->hsv hex)]
|
||||
|
||||
(swap! state update :current-color assoc
|
||||
:r r :g g :b b
|
||||
:h h :s s :v v
|
||||
:hex hex)
|
||||
(fn []
|
||||
(when picking-color?
|
||||
(let [[r g b] (or picked-color [0 0 0])
|
||||
hex (uc/rgb->hex [r g b])
|
||||
[h s v] (uc/hex->hsv hex)]
|
||||
|
||||
;; TODO: UPDATE TO USE GRADIENTS
|
||||
#_(reset! value-ref hex)
|
||||
#_(when picked-color-select
|
||||
(on-change hex (:alpha current-color) nil nil picked-shift?))))))
|
||||
(swap! state update :current-color assoc
|
||||
:r r :g g :b b
|
||||
:h h :s s :v v
|
||||
:hex hex)
|
||||
|
||||
;; TODO: UPDATE TO USE GRADIENTS
|
||||
#_(reset! value-ref hex)
|
||||
#_(when picked-color-select
|
||||
(on-change hex (:alpha current-color) nil nil picked-shift?))))))
|
||||
|
||||
;; TODO: UPDATE TO USE GRADIENTS
|
||||
#_(mf/use-effect
|
||||
|
@ -256,14 +261,15 @@
|
|||
(st/emit! (dc/start-picker)))}
|
||||
i/picker]
|
||||
|
||||
[:div.gradients-buttons
|
||||
[:button.gradient.linear-gradient
|
||||
{:on-click (on-activate-gradient :linear-gradient)
|
||||
:class (when (= :linear-gradient (:type @state)) "active")}]
|
||||
(when (not disable-gradient)
|
||||
[:div.gradients-buttons
|
||||
[:button.gradient.linear-gradient
|
||||
{:on-click (on-activate-gradient :linear-gradient)
|
||||
:class (when (= :linear-gradient (:type @state)) "active")}]
|
||||
|
||||
[:button.gradient.radial-gradient
|
||||
{:on-click (on-activate-gradient :radial-gradient)
|
||||
:class (when (= :radial-gradient (:type @state)) "active")}]]]
|
||||
[:button.gradient.radial-gradient
|
||||
{:on-click (on-activate-gradient :radial-gradient)
|
||||
:class (when (= :radial-gradient (:type @state)) "active")}]])]
|
||||
|
||||
[:& gradients {:type (:type @state)
|
||||
:stops (:stops @state)
|
||||
|
@ -275,12 +281,19 @@
|
|||
[:div.center-circle]
|
||||
[:canvas#picker-detail {:width 200 :height 160}]]
|
||||
(case @active-tab
|
||||
:ramp [:& ramp-selector {:color current-color :on-change handle-change-color}]
|
||||
:harmony [:& harmony-selector {:color current-color :on-change handle-change-color}]
|
||||
:hsva [:& hsva-selector {:color current-color :on-change handle-change-color}]
|
||||
:ramp [:& ramp-selector {:color current-color
|
||||
:disable-opacity disable-opacity
|
||||
:on-change handle-change-color}]
|
||||
:harmony [:& harmony-selector {:color current-color
|
||||
:disable-opacity disable-opacity
|
||||
:on-change handle-change-color}]
|
||||
:hsva [:& hsva-selector {:color current-color
|
||||
:disable-opacity disable-opacity
|
||||
:on-change handle-change-color}]
|
||||
nil))
|
||||
|
||||
[:& color-inputs {:type (if (= @active-tab :hsva) :hsv :rgb)
|
||||
:disable-opacity disable-opacity
|
||||
:color current-color
|
||||
:on-change handle-change-color}]
|
||||
|
||||
|
@ -321,7 +334,10 @@
|
|||
(mf/defc colorpicker-modal
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :colorpicker}
|
||||
[{:keys [x y default data page position on-change on-close on-accept] :as props}]
|
||||
[{:keys [x y default data page position
|
||||
disable-gradient
|
||||
disable-opacity
|
||||
on-change on-close on-accept] :as props}]
|
||||
(let [vport (mf/deref viewport)
|
||||
dirty? (mf/use-var false)
|
||||
last-change (mf/use-var nil)
|
||||
|
@ -350,6 +366,8 @@
|
|||
[:div.colorpicker-tooltip
|
||||
{:style (clj->js style)}
|
||||
[:& colorpicker {:data data
|
||||
:disable-gradient disable-gradient
|
||||
:disable-opacity disable-opacity
|
||||
:on-change handle-change
|
||||
:on-accept on-accept}]]))
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
[app.main.ui.icons :as i]
|
||||
[app.util.i18n :as i18n :refer [t]]))
|
||||
|
||||
(mf/defc color-inputs [{:keys [type color on-change]}]
|
||||
(mf/defc color-inputs [{:keys [type color disable-opacity on-change]}]
|
||||
(let [{red :r green :g blue :b
|
||||
hue :h saturation :s value :v
|
||||
hex :hex alpha :alpha} color
|
||||
|
@ -94,6 +94,7 @@
|
|||
(dom/set-value! node (math/round property-val)))))))))
|
||||
|
||||
[:div.color-values
|
||||
{:class (when disable-opacity "disable-opacity")}
|
||||
[:input {:id "hex-value"
|
||||
:ref (:hex refs)
|
||||
:default-value hex
|
||||
|
@ -150,14 +151,15 @@
|
|||
:default-value value
|
||||
:on-change (on-change-property :v 255)}]])
|
||||
|
||||
[:input.alpha-value {:id "alpha-value"
|
||||
:ref (:alpha refs)
|
||||
:type "number"
|
||||
:min 0
|
||||
:step 1
|
||||
:max 100
|
||||
:default-value (if (= alpha :multiple) "" (math/precision alpha 2))
|
||||
:on-change on-change-opacity}]
|
||||
(when (not disable-opacity)
|
||||
[:input.alpha-value {:id "alpha-value"
|
||||
:ref (:alpha refs)
|
||||
:type "number"
|
||||
:min 0
|
||||
:step 1
|
||||
:max 100
|
||||
:default-value (if (= alpha :multiple) "" (math/precision alpha 2))
|
||||
:on-change on-change-opacity}])
|
||||
|
||||
[:label.hex-label {:for "hex-value"} "HEX"]
|
||||
(if (= type :rgb)
|
||||
|
@ -169,4 +171,5 @@
|
|||
[:label.red-label {:for "hue-value"} "H"]
|
||||
[:label.green-label {:for "saturation-value"} "S"]
|
||||
[:label.blue-label {:for "value-value"} "V"]])
|
||||
[:label.alpha-label {:for "alpha-value"} "A"]]))
|
||||
(when (not disable-opacity)
|
||||
[:label.alpha-label {:for "alpha-value"} "A"])]))
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
y (+ (/ canvas-side 2) (* comp-y (/ canvas-side 2)))]
|
||||
(gpt/point x y)))
|
||||
|
||||
(mf/defc harmony-selector [{:keys [color on-change]}]
|
||||
(mf/defc harmony-selector [{:keys [color disable-opacity on-change]}]
|
||||
(let [canvas-ref (mf/use-ref nil)
|
||||
{hue :h saturation :s value :v alpha :alpha} color
|
||||
|
||||
|
@ -146,9 +146,10 @@
|
|||
:max-value 255
|
||||
:vertical true
|
||||
:on-change on-change-value}]
|
||||
[:& slider-selector {:class "opacity"
|
||||
:vertical? true
|
||||
:value alpha
|
||||
:max-value 1
|
||||
:vertical true
|
||||
:on-change on-change-opacity}]]]))
|
||||
(when (not disable-opacity)
|
||||
[:& slider-selector {:class "opacity"
|
||||
:vertical? true
|
||||
:value alpha
|
||||
:max-value 1
|
||||
:vertical true
|
||||
:on-change on-change-opacity}])]]))
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
[app.util.i18n :as i18n :refer [t]]
|
||||
[app.main.ui.workspace.colorpicker.slider-selector :refer [slider-selector]]))
|
||||
|
||||
(mf/defc hsva-selector [{:keys [color on-change]}]
|
||||
(mf/defc hsva-selector [{:keys [color disable-opacity on-change]}]
|
||||
(let [{hue :h saturation :s value :v alpha :alpha} color
|
||||
handle-change-slider (fn [key]
|
||||
(fn [new-value]
|
||||
|
@ -52,6 +52,8 @@
|
|||
[:& slider-selector
|
||||
{:class "value" :reverse? true :max-value 255 :value value :on-change (handle-change-slider :v)}]
|
||||
|
||||
[:span.hsva-selector-label "A"]
|
||||
[:& slider-selector
|
||||
{:class "opacity" :max-value 1 :value alpha :on-change on-change-opacity}]]))
|
||||
(when (not disable-opacity)
|
||||
[:*
|
||||
[:span.hsva-selector-label "A"]
|
||||
[:& slider-selector
|
||||
{:class "opacity" :max-value 1 :value alpha :on-change on-change-opacity}]])]))
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
:top (str (* 100 (- 1 (/ value 255))) "%")}}]]))
|
||||
|
||||
|
||||
(mf/defc ramp-selector [{:keys [color on-change]}]
|
||||
(mf/defc ramp-selector [{:keys [color disable-opacity on-change]}]
|
||||
(let [{hue :h saturation :s value :v alpha :alpha} color
|
||||
|
||||
on-change-value-saturation
|
||||
|
@ -86,7 +86,8 @@
|
|||
:value hue
|
||||
:on-change on-change-hue}]
|
||||
|
||||
[:& slider-selector {:class "opacity"
|
||||
:max-value 1
|
||||
:value alpha
|
||||
:on-change on-change-opacity}]]]))
|
||||
(when (not disable-opacity)
|
||||
[:& slider-selector {:class "opacity"
|
||||
:max-value 1
|
||||
:value alpha
|
||||
:on-change on-change-opacity}])]]))
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
[app.main.ui.workspace.shapes.common :as common]
|
||||
[app.main.data.workspace.selection :as dws]
|
||||
[app.main.ui.shapes.frame :as frame]
|
||||
[app.main.ui.shapes.gradients :as grad]
|
||||
[app.main.ui.shapes.filters :as filters]
|
||||
[app.common.geom.matrix :as gmt]
|
||||
[app.common.geom.point :as gpt]
|
||||
|
@ -126,8 +127,18 @@
|
|||
:on-context-menu on-context-menu
|
||||
:on-double-click on-double-click
|
||||
:on-mouse-down on-mouse-down}]
|
||||
|
||||
[:g.frame {:filter (filters/filter-str filter-id shape)}
|
||||
[:& filters/filters {:filter-id filter-id :shape shape}]
|
||||
|
||||
(when (:fill-color-gradient shape)
|
||||
[:& grad/gradient {:attr :fill-color-gradient
|
||||
:shape shape}])
|
||||
|
||||
(when (:stroke-color-gradient shape)
|
||||
[:& grad/gradient {:attr :stroke-color-gradient
|
||||
:shape shape}])
|
||||
|
||||
[:& frame-shape
|
||||
{:shape shape
|
||||
:childs children}]]])))))
|
||||
|
|
|
@ -40,15 +40,15 @@
|
|||
[{:keys [shape shapes-with-children page-id file-id]}]
|
||||
[:*
|
||||
(case (:type shape)
|
||||
:frame [:& frame/options {:shape shape}]
|
||||
:group [:& group/options {:shape shape :shape-with-children shapes-with-children}]
|
||||
:text [:& text/options {:shape shape}]
|
||||
:rect [:& rect/options {:shape shape}]
|
||||
:icon [:& icon/options {:shape shape}]
|
||||
:frame [:& frame/options {:shape shape}]
|
||||
:group [:& group/options {:shape shape :shape-with-children shapes-with-children}]
|
||||
:text [:& text/options {:shape shape}]
|
||||
:rect [:& rect/options {:shape shape}]
|
||||
:icon [:& icon/options {:shape shape}]
|
||||
:circle [:& circle/options {:shape shape}]
|
||||
:path [:& path/options {:shape shape}]
|
||||
:curve [:& path/options {:shape shape}]
|
||||
:image [:& image/options {:shape shape}]
|
||||
:path [:& path/options {:shape shape}]
|
||||
:curve [:& path/options {:shape shape}]
|
||||
:image [:& image/options {:shape shape}]
|
||||
nil)
|
||||
[:& exports-menu
|
||||
{:shape shape
|
||||
|
|
|
@ -63,13 +63,14 @@
|
|||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [event]
|
||||
(st/emit! (dc/change-fill ids cp/default-color nil nil))))
|
||||
(st/emit! (dc/change-fill2 ids {:color cp/default-color
|
||||
:opacity 1}))))
|
||||
|
||||
on-delete
|
||||
(mf/use-callback
|
||||
(mf/deps ids)
|
||||
(fn [event]
|
||||
(st/emit! (dc/change-fill ids nil nil nil))))
|
||||
(st/emit! (dc/change-fill2 ids nil))))
|
||||
|
||||
on-change
|
||||
(mf/use-callback
|
||||
|
|
|
@ -44,8 +44,9 @@
|
|||
[:div.element-set
|
||||
[:div.element-set-title (t locale "workspace.options.canvas-background")]
|
||||
[:div.element-set-content
|
||||
[:& color-row {:disable-opacity true
|
||||
:color {:value (get options :background "#E8E9EA")
|
||||
[:& color-row {:disable-gradient true
|
||||
:disable-opacity true
|
||||
:color {:color (get options :background "#E8E9EA")
|
||||
:opacity 1}
|
||||
:on-change handle-change-color
|
||||
:on-open on-open
|
||||
|
|
|
@ -21,12 +21,14 @@
|
|||
[app.util.color :as uc]))
|
||||
|
||||
(defn color-picker-callback
|
||||
[color handle-change-color handle-open handle-close]
|
||||
[color disable-gradient disable-opacity handle-change-color handle-open handle-close]
|
||||
(fn [event]
|
||||
(let [x (.-clientX event)
|
||||
y (.-clientY event)
|
||||
props {:x x
|
||||
:y y
|
||||
:disable-gradient disable-gradient
|
||||
:disable-opacity disable-opacity
|
||||
:on-change handle-change-color
|
||||
:on-close handle-close
|
||||
:data color}]
|
||||
|
@ -57,7 +59,7 @@
|
|||
(if (= v :multiple) nil v))
|
||||
|
||||
(mf/defc color-row
|
||||
[{:keys [color on-change on-open on-close]}]
|
||||
[{:keys [color disable-gradient disable-opacity on-change on-open on-close]}]
|
||||
(let [file-colors (mf/deref refs/workspace-file-colors)
|
||||
shared-libs (mf/deref refs/workspace-libraries)
|
||||
|
||||
|
@ -69,28 +71,14 @@
|
|||
(-> color
|
||||
(update :color #(or % (:value color)))))
|
||||
|
||||
state (mf/use-state (parse-color color))
|
||||
|
||||
value (:color @state)
|
||||
opacity (:opacity @state)
|
||||
|
||||
change-value (fn [new-value]
|
||||
(swap! state assoc :color new-value)
|
||||
(when on-change (on-change new-value (remove-multiple opacity))))
|
||||
(when on-change (on-change (assoc color :color new-value))))
|
||||
|
||||
change-opacity (fn [new-opacity]
|
||||
(swap! state assoc :opacity new-opacity)
|
||||
(when on-change (on-change (remove-multiple value) new-opacity)))
|
||||
|
||||
;;handle-pick-color (fn [new-value new-opacity id file-id]
|
||||
;; (reset! state {:color new-value :opacity new-opacity})
|
||||
;; (when on-change (on-change new-value new-opacity id file-id)))
|
||||
(when on-change (on-change (assoc color :opacity new-opacity))))
|
||||
|
||||
handle-pick-color (fn [color]
|
||||
(prn "handle-pick-color" color)
|
||||
(reset! state color)
|
||||
(when on-change
|
||||
(on-change color)))
|
||||
(when on-change (on-change color)))
|
||||
|
||||
handle-open (fn [] (when on-open (on-open)))
|
||||
|
||||
|
@ -114,20 +102,24 @@
|
|||
change-opacity))))
|
||||
|
||||
select-all (fn [event]
|
||||
(dom/select-text! (dom/get-target event)))]
|
||||
(dom/select-text! (dom/get-target event)))
|
||||
|
||||
handle-click-color (mf/use-callback
|
||||
(mf/deps color)
|
||||
(color-picker-callback color disable-gradient disable-opacity
|
||||
handle-pick-color handle-open handle-close))]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps color)
|
||||
(fn []
|
||||
(modal/update-props! :colorpicker {:data (parse-color color)})
|
||||
(reset! state (parse-color color))))
|
||||
(modal/update-props! :colorpicker {:data (parse-color color)})))
|
||||
|
||||
[:div.row-flex.color-data
|
||||
[:span.color-th
|
||||
{:class (when (and (:id color) (not= (:id color) :multiple)) "color-name")
|
||||
:style {:background (uc/color->background color)}
|
||||
:on-click (color-picker-callback @state handle-pick-color handle-open handle-close)}
|
||||
(when (= value :multiple) "?")]
|
||||
:on-click handle-click-color}
|
||||
(when (= (:color color) :multiple) "?")]
|
||||
|
||||
(cond
|
||||
;; Rendering a color with ID
|
||||
|
@ -136,7 +128,7 @@
|
|||
[:div.color-name (str (get-color-name color))]]
|
||||
|
||||
;; Rendering a gradient
|
||||
(:gradient color)
|
||||
(and (:gradient color) (get-in color [:gradient :type]))
|
||||
[:div.color-info
|
||||
[:div.color-name
|
||||
(case (get-in color [:gradient :type])
|
||||
|
@ -147,19 +139,20 @@
|
|||
:else
|
||||
[:*
|
||||
[:div.color-info
|
||||
[:input {:value (-> value remove-hash)
|
||||
[:input {:value (-> color :color remove-hash)
|
||||
:pattern "^[0-9a-fA-F]{0,6}$"
|
||||
:placeholder (tr "settings.multiple")
|
||||
:on-click select-all
|
||||
:on-change handle-value-change}]]
|
||||
|
||||
[:div.input-element
|
||||
{:class (classnames :percentail (not= opacity :multiple))}
|
||||
[:input.input-text {:type "number"
|
||||
:value (-> opacity opacity->string)
|
||||
:placeholder (tr "settings.multiple")
|
||||
:on-click select-all
|
||||
:on-change handle-opacity-change
|
||||
:min "0"
|
||||
:max "100"}]]])]))
|
||||
(when (not disable-opacity)
|
||||
[:div.input-element
|
||||
{:class (classnames :percentail (not= (:opacity color) :multiple))}
|
||||
[:input.input-text {:type "number"
|
||||
:value (-> color :opacity opacity->string)
|
||||
:placeholder (tr "settings.multiple")
|
||||
:on-click select-all
|
||||
:on-change handle-opacity-change
|
||||
:min "0"
|
||||
:max "100"}]])])]))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue