Skip to content

Commit

Permalink
project page
Browse files Browse the repository at this point in the history
- edit title, description
- cleaner handling of :classes for text-field
  • Loading branch information
mhuebert committed Jan 4, 2024
1 parent f9abb08 commit f5c51b9
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 104 deletions.
5 changes: 2 additions & 3 deletions src/sb/app/board/ui.cljc
Expand Up @@ -50,7 +50,7 @@

(when owners
[:div.flex-v.gap-2
[:label.field-label {} (t :tr/owner)]
[:label.field-label (t :tr/owner)]
(radix/select-menu {:value @?owner
:on-value-change (partial reset! ?owner)
:field/options
Expand Down Expand Up @@ -91,8 +91,7 @@
[:div.btn.btn-white.overflow-hidden.relative
(-> props
(v/merge-props {:class (when error "ring-destructive ring-2")})
(assoc :on-click
(when-not loading? on-click)))
(assoc :on-click (when-not loading? on-click)))
(t :tr/new-project)
(when (:loading? @!async-state)
[:div.loading-bar.absolute.top-0.left-0.right-0.h-1])]]))
Expand Down
2 changes: 1 addition & 1 deletion src/sb/app/domain_name/ui.cljc
Expand Up @@ -45,6 +45,6 @@
(field.ui/text-field ?name (merge props
{:auto-complete "off"
:spell-check false
:field/wrapper-class "flex-auto"
:field/classes {:wrapper "flex-auto"}
:field/label false}))
[:div.flex.items-center.text-sm.text-gray-500.h-10 ".sparkboard.com"]]])
6 changes: 2 additions & 4 deletions src/sb/app/entity/ui.cljc
Expand Up @@ -46,14 +46,12 @@
(defn use-persisted-attr [e a & {:as props}]
#?(:cljs
(let [persisted-value (get e a)
make-field (or (:make-field props)
(:make-field (io/global-meta a))
make-field (or (:make-field (io/global-meta a))
(fn [init _props] (io/field :init init)))
?field (h/use-memo #(doto (make-field persisted-value props)
(add-meta! {:attribute a
:db/id (sch/wrap-id e)
:field/label (u/some-or (:field/label props)
(form.ui/attribute-label a))
:field/label (:field/label props)
:field/persisted? true}))
;; create a new field when the persisted value changes
(h/use-deps persisted-value))]
Expand Down
23 changes: 12 additions & 11 deletions src/sb/app/field/admin_ui.cljc
Expand Up @@ -31,11 +31,11 @@
"opacity-0 group-hover:opacity-100"
"cursor-drag"]})
[icons/drag-dots]]]
[field.ui/text-field ?label {:field/label false
:field/wrapper-class "flex-auto"
:class "rounded-sm relative focus:z-2"
:style {:background-color @?color
:color (color/contrasting-text-color @?color)}}]
[field.ui/text-field ?label {:field/label false
:field/classes {:wrapper "flex-auto"}
:class "rounded-sm relative focus:z-2"
:style {:background-color @?color
:color (color/contrasting-text-color @?color)}}]
[:div.relative.w-10.focus-within-ring.rounded.overflow-hidden.self-stretch
[field.ui/color-field ?color {:style {:top -10
:left -10
Expand Down Expand Up @@ -72,7 +72,8 @@
(p/let [result (entity.data/maybe-save-field ?options)]
(reset! ?new (:init ?new))
result)))}
[field.ui/text-field ?new {:placeholder "Option label" :field/wrapper-class "flex-auto"}]
[field.ui/text-field ?new {:placeholder "Option label"
:field/classes {:wrapper "flex-auto"}}]
[:div.btn.bg-white.px-3.py-1.shadow "Add Option"]])
#_[ui/pprinted @?options]]))

Expand Down Expand Up @@ -161,14 +162,14 @@
:field/show-on-card? ?show-on-card?})
:init init))

(ui/defview fields-editor [{:as ?fields :keys [field/label]} props]
(ui/defview fields-editor [?fields props]
(let [!new-field (h/use-state nil)
!autofocus-ref (ui/use-autofocus-ref)
[expanded expand!] (h/use-state nil)
use-order (ui/use-orderable-parent ?fields {:axis :y})]
use-order (ui/use-orderable-parent ?fields {:axis :y})]
[:div.field-wrapper {:class "labels-semibold"}
[:label.field-label {:class "flex items-center"}
label
(form.ui/get-label ?fields)
[:div.flex.ml-auto.items-center
(when-not @!new-field
(radix/dropdown-menu {:id :add-field
Expand All @@ -187,7 +188,7 @@
(->> ?fields
(map (fn [{:as ?field :syms [?id]}]
(field-row ?field
{:use-order use-order
{:use-order use-order
:expanded? (= expanded @?id)
:toggle-expand! #(expand! (fn [old]
(u/guard @?id (partial not= old))))})))
Expand All @@ -208,7 +209,7 @@
[field.ui/text-field ?label {:field/label false
:ref !autofocus-ref
:placeholder (:field/label ?label)
:field/wrapper-class "flex-auto"}]
:field/classes {:wrapper "flex-auto"}}]
[:button.btn.btn-white.h-10 {:type "submit"}
(t :tr/add)]
[:div.flex.items-center.justify-center.icon-light-gray.h-10.w-7
Expand Down
121 changes: 65 additions & 56 deletions src/sb/app/field/ui.cljc
Expand Up @@ -53,7 +53,7 @@
:on-change (:on-change props
#(reset! v! (j/get-in % [:target :value])))})]
[:div.auto-size
[:div.bg-black (select-keys props [:class :style])
[:div (select-keys props [:class :style])
(str (:value props) " ")]
[:textarea (assoc props :rows 1)]]))

Expand Down Expand Up @@ -91,57 +91,78 @@
(when (seq messages)
(into [:div.text-gray-500] (map form.ui/view-message) messages))]]]))

(defn with-messages-popover [?field anchor]
(v/x [radix/persistent-popover
{:default-open? true
:content (form.ui/show-field-messages ?field)
:classes {:content "z-30 relative bg-white rounded shadow-lg px-3 py-2 border border-2 border-red-500"
:arrow "fill-red-500"
:close "rounded-full inline-flex items-center justify-center w-6 h-6 text-gray-500 absolute top-2 right-2"}}
anchor]))

(ui/defview text-field
"A text-input element that reads metadata from a ?field to display appropriately"
[?field props]
(let [{:as props
:field/keys [multi-line?
:field/keys [classes
multi-line?
wrap
unwrap
wrapper-class]
can-edit?
unstyled?]
:or {wrap identity
unwrap identity}} (merge props (:props (meta ?field)))
blur! (fn [e] (j/call-in e [:target :blur]))
cancel! (fn [^js e]
(.preventDefault e)
(.stopPropagation e)
(reset! ?field (entity.data/persisted-value ?field))
(js/setTimeout #(blur! e) 0))
props (v/merge-props props
(form.ui/?field-props ?field
(merge {:field/event->value (j/get-in [:target :value])
:field/wrap #(when-not (str/blank? %) %)
:field/unwrap #(or % "")}
props))

{:class ["pr-8 rounded default-ring"
(when (:invalid (forms/types (forms/visible-messages ?field)))
"outline-invalid")]
:placeholder (:placeholder props)
:on-key-down (let [save #(when (io/ancestor-by ?field :field/persisted?)
(j/call % :preventDefault)
(entity.data/maybe-save-field ?field))]
(ui/keydown-handler (merge {:Meta-Enter save
:Escape cancel!
:Meta-. cancel!}
(when-not multi-line?
{:Enter save}))))})]
(v/x
[:div.field-wrapper
{:class wrapper-class}
(form.ui/show-label ?field (:field/label props))
[:div.flex-v.relative
[auto-size (v/merge-props {:class "form-text w-full"} (form.ui/pass-props props))]
(when-let [postfix (or (:field/postfix props)
(:field/postfix (meta ?field))
(and (some-> (entity.data/persisted-value ?field)
(not= (:value props)))
[icons/pencil-outline "w-4 h-4 text-txt/40"]))]
[:div.pointer-events-none.absolute.inset-y-0.right-0.top-0.bottom-0.flex.items-center.p-2 postfix])

(when (:loading? ?field)
[:div.loading-bar.absolute.bottom-0.left-0.right-0 {:class "h-[3px]"}])]
(form.ui/show-field-messages ?field)])))
blur! (fn [e] (j/call-in e [:target :blur]))
cancel! (fn [^js e]
(.preventDefault e)
(.stopPropagation e)
(reset! ?field (entity.data/persisted-value ?field))
(js/setTimeout #(blur! e) 0))
props (v/merge-props props
(form.ui/?field-props ?field
(merge {:field/event->value (j/get-in [:target :value])
:field/wrap #(when-not (str/blank? %) %)
:field/unwrap #(or % "")}
props)))
classes (merge (if (or unstyled?
(not can-edit?))
{:wrapper "w-full"
:input (str "border-0 border-b-2 border-transparent text-inherit-all p-0 font-inherit focus:ring-0 "
"focus:border-focus-accent")}
{:wrapper "w-full"
:input "form-text rounded default-ring"})
classes)
data-props {:data-touched (:touched ?field)
:data-invalid (not (io/valid? ?field))
:data-focused (:focused ?field)}]
[:div.field-wrapper
(merge data-props {:class (:wrapper classes)})
(form.ui/show-label ?field (:field/label props) (:label classes))
[:div.flex-v.relative
(with-messages-popover ?field
[auto-size (-> (form.ui/pass-props props)
(v/merge-props
data-props
{:disabled (not can-edit?)
:class ["w-full" (:input classes)]
:placeholder (:placeholder props)
:on-key-down (let [save #(when (io/ancestor-by ?field :field/persisted?)
(j/call % :preventDefault)
(entity.data/maybe-save-field ?field))]
(ui/keydown-handler (merge {:Meta-Enter save
:Escape cancel!
:Meta-. cancel!}
(when-not multi-line?
{:Enter save}))))}))])
(when-let [postfix (or (:field/postfix props)
(:field/postfix (meta ?field))
(and (some-> (entity.data/persisted-value ?field)
(not= (:value props)))
[icons/pencil-outline "w-4 h-4 text-txt/40"]))]
[:div.pointer-events-none.absolute.inset-y-0.right-0.top-0.bottom-0.flex.items-center.p-2 postfix])

(when (:loading? ?field)
[:div.loading-bar.absolute.bottom-0.left-0.right-0 {:class "h-[3px]"}])]]))

(defn wrap-prose [value]
(when-not (str/blank? value)
Expand All @@ -156,18 +177,6 @@
(text-field ?string (merge {:field/multi-line? true}
props)))

(ui/defview show-select [?field {:field/keys [label options can-edit?]} entry]
[:div.flex-v.gap-2
[:label.field-label label]
[radix/select-menu {:value (or @?field "")
:id (str (:entity/id entry))
:field/can-edit? can-edit?
:field/options (->> options
(map (fn [{:field-option/keys [label value color]}]
{:text label
:value (or value "")}))
doall)}]])

(comment

(defn youtube-embed [video-id]
Expand Down
4 changes: 2 additions & 2 deletions src/sb/app/form/ui.cljc
Expand Up @@ -34,9 +34,9 @@
(:field/label ?field)
(io/closest ?field #(some-> (:attribute %) attribute-label))))

(defn show-label [?field & [label]]
(defn show-label [?field & [label class]]
(when-let [label (get-label ?field label)]
[:label.field-label {:for (field-id ?field)} label]))
[:label.field-label {:for (field-id ?field) :class class} label]))

(defn ?field-props [?field
{:keys [field/event->value
Expand Down
39 changes: 13 additions & 26 deletions src/sb/app/project/ui.cljc
Expand Up @@ -120,32 +120,34 @@
field-entries]
:keys [project/badges
member/roles]} (data/show params)
[can-edit? dev-panel] (use-dev-panel project)]
[can-edit? dev-panel] (use-dev-panel project)
field-params {:member/roles roles
:field/can-edit? can-edit?}]
[:<>
dev-panel
[:div.flex-v.gap-6.pb-6
;; title row
[:div.flex

[:h1.font-medium.text-2xl.flex-auto.px-body.flex.items-center.pt-6
;; TODO
;; make title editable for `can-edit?` and have it autofocus if title = (tr :tr/untitled)
;; - think about how to make the title field editable
;; - dotted underline if editable?
title]
(entity.ui/use-persisted-attr project :entity/title (merge field-params
{:field/label false
:field/unstyled? true}))]

[:div.flex.self-start.ml-auto.px-1.rounded-bl-lg.border-b.border-l.relative
[radix/tooltip "Back to board"
[:a {:class title-icon-classes
:href (routing/entity-path (:entity/parent project) 'ui/show)}
[icons/arrow-left]]]
[radix/tooltip "Link to project"
[:a {:class title-icon-classes
:href (routing/entity-path project :show)}
[icons/link-2]]]
(when (:entity/id project)
[radix/tooltip "Link to project"
[:a {:class title-icon-classes
:href (routing/entity-path project :show)}
[icons/link-2]]])
modal-close]]

[:div.px-body.flex-v.gap-6
(field.ui/show-prose description)
(entity.ui/use-persisted-attr project :entity/description (merge field-params {:field/label false}))
(when badges
[:section
(into [:ul]
Expand All @@ -160,18 +162,3 @@
[manage-community-actions project (:project/community-actions project)]]
(when video
[field.ui/show-video video])]]]))

(ui/defview new
{:route "/new/p/:board-id"
:view/router :router/modal}
[{:keys [board-id]}]
(let [fields (data/fields {:board-id board-id})]
(forms/with-form [!project {:project/parent board-id
:entity/title ?title}]
[:<>
[:h3.flex.items-center.border-b.h-14
[:div.px-body.flex-auto (t :tr/new-project)] modal-close]
[:div.p-body

[ui/pprinted (map db/touch fields)]
]])))
13 changes: 12 additions & 1 deletion src/sb/app/views/radix.cljc
Expand Up @@ -4,6 +4,7 @@
#?(:cljs ["@radix-ui/react-alert-dialog" :as alert])
#?(:cljs ["@radix-ui/react-dialog" :as dialog])
#?(:cljs ["@radix-ui/react-dropdown-menu" :as dm])
#?(:cljs ["@radix-ui/react-popover" :as popover])
#?(:cljs ["@radix-ui/react-select" :as sel])
#?(:cljs ["@radix-ui/react-tabs" :as tabs])
#?(:cljs ["@radix-ui/react-tooltip" :as tooltip])
Expand Down Expand Up @@ -222,4 +223,14 @@
[:el ContextMenu/Root
[:el ContextMenu/Trigger (v/x trigger)]
[:el.bg-white.rounded.overflow-hidden.p-1.shadow-md.min-w-32 ContextMenu/Content {:style {:z-index 20}}
(into [:<>] items)]])
(into [:<>] items)]])

(v/defview persistent-popover [{:keys [content classes props]} anchor]
(v/x [:el.foo popover/Root (v/props (merge (:root props)
{:open (boolean content)
:style {:z-index 1}}))
[:el.hidden popover/Trigger]
[:el popover/Anchor anchor]
[:el popover/Content {:class (:content classes)}
[:el popover/Arrow {:class (:arrow classes)}]
content]]))
7 changes: 7 additions & 0 deletions src/sparkboard.css
Expand Up @@ -122,6 +122,13 @@
}

@layer utilities {

.text-inherit-all {
color: inherit;
font-size: inherit;
line-height: inherit;

}
.labels-xs label {
@apply text-xs
}
Expand Down

0 comments on commit f5c51b9

Please sign in to comment.