chore: short names for ionic components

This commit is contained in:
Tienson Qin
2025-05-26 02:42:00 +08:00
parent 582ac76958
commit 6d77521e04
6 changed files with 376 additions and 381 deletions

View File

@@ -7,7 +7,7 @@
[capacitor.components.settings :as settings]
[capacitor.components.ui :as ui]
[capacitor.handler :as handler]
[capacitor.ionic :as ionic]
[capacitor.ionic :as ion]
[capacitor.state :as state]
[clojure.string :as string]
[frontend.components.journal :as journal]
@@ -35,7 +35,7 @@
(db-conn/get-short-repo-name current-repo)
"Select a Graph")]
[:<>
(ionic/ion-button
(ion/button
{:fill "clear"
:mode "ios"
:class "border-none w-full rounded-lg"
@@ -62,18 +62,18 @@
(rum/defc bottom-tabs
[]
(ionic/ion-tab-bar
(ion/tab-bar
{:slot "bottom"}
(ionic/ion-tab-button
(ion/tab-button
{:tab "home"
:selected true}
(ionic/tabler-icon "home" {:size 22}) "Journals")
(ionic/ion-tab-button
(ion/tabler-icon "home" {:size 22}) "Journals")
(ion/tab-button
{:tab "search"}
(ionic/tabler-icon "search" {:size 22}) "Search")
(ionic/ion-tab-button
(ion/tabler-icon "search" {:size 22}) "Search")
(ion/tab-button
{:tab "settings"}
(ionic/tabler-icon "settings" {:size 22}) "Settings")))
(ion/tabler-icon "settings" {:size 22}) "Settings")))
(rum/defc journals-list < rum/reactive db-mixins/query
[]
@@ -93,7 +93,7 @@
[:div.py-4
[:h1.text-4xl.flex.gap-1.items-center.mb-4.pt-2.font-mono
(ionic/tabler-icon "file" {:size 30}) "Contents"]
(ion/tabler-icon "file" {:size 30}) "Contents"]
(cc-blocks/page-blocks "Contents")])
(rum/defc keep-keyboard-open
@@ -103,8 +103,8 @@
(rum/defc journals []
(let [[reload set-reload!] (hooks/use-state 0)]
(ionic/ion-content
(ionic/ion-refresher
(ion/content
(ion/refresher
{:slot "fixed"
:pull-factor 0.5
:pull-min 100
@@ -114,7 +114,7 @@
(fn [] (.complete (.-detail e))
(set-reload! (inc reload)))
1000))}
(ionic/ion-refresher-content))
(ion/refresher-content))
[:div.pt-4.px-4
[:main#app-container-wrapper.ls-fold-button-on-right
@@ -126,68 +126,68 @@
(rum/defc home < rum/reactive
[]
(let [db-restoring? (fstate/sub :db/restoring?)]
(ionic/ion-page
(ion/page
{:id "app-main-content"}
(ionic/ion-header
(ionic/ion-toolbar
(ionic/ion-buttons {:slot "start"}
(app-graphs-select))
(ion/header
(ion/toolbar
(ion/buttons {:slot "start"}
(app-graphs-select))
(ionic/ion-buttons {:slot "end"}
(ionic/ion-button
{:size "small" :fill "clear"
:on-click (fn []
(let [apply-date! (fn [date]
(let [page-name (frontend-date/journal-name (gdate/Date. (js/Date. date)))
nav-to-journal! #(cc-utils/nav-to-block! % {:reload-pages! (fn [] ())})]
(if-let [journal (handler/local-page page-name)]
(nav-to-journal! journal)
(-> (handler/<create-page! page-name)
(p/then #(nav-to-journal! (handler/local-page page-name)))))))]
(ion/buttons {:slot "end"}
(ion/button
{:size "small" :fill "clear"
:on-click (fn []
(let [apply-date! (fn [date]
(let [page-name (frontend-date/journal-name (gdate/Date. (js/Date. date)))
nav-to-journal! #(cc-utils/nav-to-block! % {:reload-pages! (fn [] ())})]
(if-let [journal (handler/local-page page-name)]
(nav-to-journal! journal)
(-> (handler/<create-page! page-name)
(p/then #(nav-to-journal! (handler/local-page page-name)))))))]
(if (mobile-util/native-android?)
(-> (.showDatePicker mobile-util/ui-local)
(p/then (fn [^js e] (some-> e (.-value) (apply-date!)))))
(if (mobile-util/native-android?)
(-> (.showDatePicker mobile-util/ui-local)
(p/then (fn [^js e] (some-> e (.-value) (apply-date!)))))
(ui/open-modal!
(fn [{:keys [close!]}]
(ionic/ion-datetime
{:presentation "date"
:onIonChange (fn [^js e]
(let [val (.-value (.-detail e))]
(apply-date! val)
(close!)))}))))))}
[:span {:slot "icon-only"} (ionic/tabler-icon "calendar-month" {:size 24})])
(ui/open-modal!
(fn [{:keys [close!]}]
(ion/datetime
{:presentation "date"
:onIonChange (fn [^js e]
(let [val (.-value (.-detail e))]
(apply-date! val)
(close!)))}))))))}
[:span {:slot "icon-only"} (ion/tabler-icon "calendar-month" {:size 24})])
(ionic/ion-button {:fill "clear"}
(ionic/ion-nav-link
{:routerDirection "forward"
:class "w-full"
:component settings/page}
[:span {:slot "icon-only"} (ionic/tabler-icon "dots" {:size 24})])))))
(ion/button {:fill "clear"}
(ion/nav-link
{:routerDirection "forward"
:class "w-full"
:component settings/page}
[:span {:slot "icon-only"} (ion/tabler-icon "dots" {:size 24})])))))
;; main content
(if db-restoring?
(ionic/ion-content
(ion/content
[:strong.flex.justify-center.items-center.py-24
(ionic/tabler-icon "loader" {:class "animate animate-spin opacity-50" :size 30})])
(ion/tabler-icon "loader" {:class "animate animate-spin opacity-50" :size 30})])
(journals)))))
(rum/defc search
[]
(ionic/ion-page
(ion/page
{:id "search-tab"}
(ionic/ion-header
(ionic/ion-toolbar
(ion/header
(ion/toolbar
"Search"))
[:div.flex.flex-1.p-4 "Search results"]))
(rum/defc settings
[]
(ionic/ion-page
(ion/page
{:id "settings-tab"}
(ionic/ion-header
(ionic/ion-toolbar
(ion/header
(ion/toolbar
"Settings"))
[:div.flex.flex-1.p-4 "TODO..."]))
@@ -201,20 +201,20 @@
(set-nav-root! nav))
#())
[(rum/deref nav-ref)])
(ionic/ion-tabs
(ionic/ion-tab
(ion/tabs
(ion/tab
{:tab "home"}
(ionic/ion-nav {:ref nav-ref
:root home ;;settings/page
:animated true
:swipeGesture true}))
(ionic/ion-tab
(ion/nav {:ref nav-ref
:root home ;;settings/page
:animated true
:swipeGesture true}))
(ion/tab
{:tab "search"}
(ionic/ion-content
(ion/content
(search)))
(ionic/ion-tab
(ion/tab
{:tab "settings"}
(ionic/ion-content
(ion/content
(settings)))
(bottom-tabs)

View File

@@ -1,7 +1,7 @@
(ns capacitor.components.blocks
(:require [capacitor.components.common :as cc-common]
[capacitor.components.editor :as cc-editor]
[capacitor.ionic :as ionic]
[capacitor.ionic :as ion]
[capacitor.state :as state]
[clojure.string :as string]
[dommy.core :as dom]
@@ -38,50 +38,50 @@
#())
[])
(ionic/ion-page
(ionic/ion-header
(ionic/ion-toolbar
(ionic/ion-buttons {:slot "end"}
(when (not (nil? (:db/id block)))
(ionic/ion-button {:fill "clear"
:class "opacity-80 text-red-500"
:on-click (fn []
(-> (editor-handler/delete-block-aux! block)
(p/then (fn []
(close!)
(reload-page!)))))}
(ionic/tabler-icon "trash" {:size 26}))))
(ionic/ion-title (or title "Untitled"))))
(ion/page
(ion/header
(ion/toolbar
(ion/buttons {:slot "end"}
(when (not (nil? (:db/id block)))
(ion/button {:fill "clear"
:class "opacity-80 text-red-500"
:on-click (fn []
(-> (editor-handler/delete-block-aux! block)
(p/then (fn []
(close!)
(reload-page!)))))}
(ion/tabler-icon "trash" {:size 26}))))
(ion/title (or title "Untitled"))))
(ionic/ion-content {:class "ion-padding"}
[:div.py-2
(ionic/ion-textarea {:placeholder "block content"
:ref *input
:class "bg-gray-100"
:auto-grow true
:autofocus true
:value (:block/title block)})]
[:div.flex.py-2.justify-between
(ionic/ion-button
{:on-click #(close!)
:fill "clear"}
"Cancel")
(ionic/ion-button
{:on-click (fn []
(let [new? (nil? (:db/id block))
val (.-value (.querySelector (rum/deref *input) "textarea"))]
(if-let [page (and new? (:block/page block))]
(-> (editor-handler/api-insert-new-block! val {:page (:db/id page)
:sibling? true})
(p/then (fn []
(close!)
(reload-page!))))
(-> (editor-handler/save-block! (fstate/get-current-repo)
(:block/uuid block) val)
(p/then (fn []
(close!)
(reload-page!)))))))
:class ""} "Save")]))))
(ion/content {:class "ion-padding"}
[:div.py-2
(ion/textarea {:placeholder "block content"
:ref *input
:class "bg-gray-100"
:auto-grow true
:autofocus true
:value (:block/title block)})]
[:div.flex.py-2.justify-between
(ion/button
{:on-click #(close!)
:fill "clear"}
"Cancel")
(ion/button
{:on-click (fn []
(let [new? (nil? (:db/id block))
val (.-value (.querySelector (rum/deref *input) "textarea"))]
(if-let [page (and new? (:block/page block))]
(-> (editor-handler/api-insert-new-block! val {:page (:db/id page)
:sibling? true})
(p/then (fn []
(close!)
(reload-page!))))
(-> (editor-handler/save-block! (fstate/get-current-repo)
(:block/uuid block) val)
(p/then (fn []
(close!)
(reload-page!)))))))
:class ""} "Save")]))))
;; handlers
(defn insert-new-block!
@@ -310,34 +310,34 @@
#())
[])
(ionic/ion-page
(ionic/ion-header
(ionic/ion-toolbar
(ionic/ion-buttons {:slot "start"}
(ionic/ion-button {:fill "clear"
:on-click #(.pop nav)}
(ionic/tabler-icon "arrow-left" {:size 26})))
(ion/page
(ion/header
(ion/toolbar
(ion/buttons {:slot "start"}
(ion/button {:fill "clear"
:on-click #(.pop nav)}
(ion/tabler-icon "arrow-left" {:size 26})))
(ionic/ion-buttons {:slot "end"}
(ionic/ion-button {:fill "clear"
:class "opacity-80"
:on-click rerender!}
(ionic/tabler-icon "refresh" {:size 26}))
(ionic/ion-button {:fill "clear"
:class "opacity-80 text-red-500"
:on-click (fn []
(page-handler/<delete! (:block/uuid block)
(fn []
(.pop nav)
(when (fn? reload-pages!)
(reload-pages!)))
{:error-handler (fn [^js e]
(js/console.error e))}))}
(ionic/tabler-icon "trash" {:size 26})))
(ion/buttons {:slot "end"}
(ion/button {:fill "clear"
:class "opacity-80"
:on-click rerender!}
(ion/tabler-icon "refresh" {:size 26}))
(ion/button {:fill "clear"
:class "opacity-80 text-red-500"
:on-click (fn []
(page-handler/<delete! (:block/uuid block)
(fn []
(.pop nav)
(when (fn? reload-pages!)
(reload-pages!)))
{:error-handler (fn [^js e]
(js/console.error e))}))}
(ion/tabler-icon "trash" {:size 26})))
(ionic/ion-title title)))
(ion/title title)))
(ionic/ion-content {:class "ion-padding"}
(if loading?
[:p.text-xl.text-center "Loading ..."]
(page-blocks-classic page))))))
(ion/content {:class "ion-padding"}
(if loading?
[:p.text-xl.text-center "Loading ..."]
(page-blocks-classic page))))))

View File

@@ -1,11 +1,10 @@
(ns capacitor.components.editor
(:require [rum.core :as rum]
[capacitor.components.ui :as ui]
(:require [capacitor.components.ui :as ui]
[capacitor.ionic :as ion]
[cljs-bean.core :as bean]
[capacitor.ionic :as ionic]
[frontend.util.cursor :as cursor]
[frontend.util :as util]
[frontend.handler.notification :as notification]))
[frontend.util.cursor :as cursor]
[rum.core :as rum]))
(rum/defc editor-aux
[content {:keys [on-outside! on-save! on-delete! on-focused! on-keydown! on-keyup! on-bounded!]}]
@@ -13,26 +12,26 @@
(let [*input (rum/use-ref nil)]
(rum/use-layout-effect!
(fn []
(js/requestAnimationFrame
(fn []
(when-let [^js input (some-> (rum/deref *input))]
(.focus input)
(when on-focused!
(on-focused! input))
(fn []
(js/requestAnimationFrame
(fn []
(when-let [^js input (some-> (rum/deref *input))]
(.focus input)
(when on-focused!
(on-focused! input))
;(.scrollIntoView input #js {:behavior "smooth", :block "start"})
)))
#())
[])
)))
#())
[])
(rum/use-effect!
(fn []
(let [handle-outside! (fn [^js e]
(when-not (some-> e (.-target) (.closest ".editor-aux-input"))
(on-outside! e)))]
(js/window.addEventListener "pointerdown" handle-outside!)
#(js/window.removeEventListener "pointerdown" handle-outside!)))
[])
(fn []
(let [handle-outside! (fn [^js e]
(when-not (some-> e (.-target) (.closest ".editor-aux-input"))
(on-outside! e)))]
(js/window.addEventListener "pointerdown" handle-outside!)
#(js/window.removeEventListener "pointerdown" handle-outside!)))
[])
(let [save-handle!
(fn [opts]
@@ -47,44 +46,43 @@
(on-delete! content opts))))
debounce-save-handle! (util/debounce save-handle! 128)]
(ui/textarea
{:class "editor-aux-input bg-gray-200 border-none resize-none"
:ref *input
:on-change (fn [] (debounce-save-handle!))
:on-key-down (fn [^js e]
(let [ekey (.-key e)
target (.-target e)
enter? (= ekey "Enter")
esc? (= ekey "Escape")
backspace? (= ekey "Backspace")
arrow-up? (= ekey "ArrowUp")
arrow-down? (= ekey "ArrowDown")]
{:class "editor-aux-input bg-gray-200 border-none resize-none"
:ref *input
:on-change (fn [] (debounce-save-handle!))
:on-key-down (fn [^js e]
(let [ekey (.-key e)
target (.-target e)
enter? (= ekey "Enter")
esc? (= ekey "Escape")
backspace? (= ekey "Backspace")
arrow-up? (= ekey "ArrowUp")
arrow-down? (= ekey "ArrowDown")]
(when (or (nil? on-keydown!)
(not (false? (on-keydown! e))))
(cond
(or arrow-up? arrow-down?)
(when-let [{:keys [isFirstLine isLastLine]} (some-> (.checkCursorLine js/window.externalsjs target) (bean/->clj))]
(when (and on-bounded! (or (and arrow-up? isFirstLine)
(and arrow-down? isLastLine)))
(on-bounded! (if arrow-up? :up :down) target)
(util/stop e)))
(when (or (nil? on-keydown!)
(not (false? (on-keydown! e))))
(cond
(or arrow-up? arrow-down?)
(when-let [{:keys [isFirstLine isLastLine]} (some-> (.checkCursorLine js/window.externalsjs target) (bean/->clj))]
(when (and on-bounded! (or (and arrow-up? isFirstLine)
(and arrow-down? isLastLine)))
(on-bounded! (if arrow-up? :up :down) target)
(util/stop e)))
(or (and enter? (cursor/end? target)) esc?)
(do (save-handle! {:enter? enter? :esc? esc?})
(util/stop e))
(or (and enter? (cursor/end? target)) esc?)
(do (save-handle! {:enter? enter? :esc? esc?})
(util/stop e))
(and backspace?
(cursor/start? target)
(not (util/input-text-selected? target)))
(do (delete-handle! {})
(util/stop e))
))))
:on-key-up (fn [^js e]
(when on-keyup!
(on-keyup! e)))
:default-value content}))))
(and backspace?
(cursor/start? target)
(not (util/input-text-selected? target)))
(do (delete-handle! {})
(util/stop e))))))
:on-key-up (fn [^js e]
(when on-keyup!
(on-keyup! e)))
:default-value content}))))
(rum/defc content-aux
[content & opts]
[:div.content-aux-container content])
[:div.content-aux-container content])

View File

@@ -1,33 +1,33 @@
(ns capacitor.components.settings
(:require [capacitor.handler :as handler]
[capacitor.components.nav-utils :as cc-util]
[promesa.core :as p]
[rum.core :as rum]
(:require [capacitor.components.nav-utils :as cc-util]
[capacitor.handler :as handler]
[capacitor.ionic :as ion]
[capacitor.state :as state]
[capacitor.ionic :as ionic]))
[promesa.core :as p]
[rum.core :as rum]))
(rum/defc create-page-input
[{:keys [close! reload-pages!]}]
(ionic/ion-alert
{:is-open true
:header "Create new page"
:onWillDismiss (fn [^js e]
(let [^js detail (.-detail e)]
(when-let [val (and (= "confirm" (.-role detail))
(aget (.-values (.-data detail)) 0))]
(-> (handler/<create-page! val)
(p/finally reload-pages!)))
(close!)))
:onDidPresent (fn [^js e]
(let [^js target (.-target e)]
(when-let [input (.querySelector target "input")]
(js/setTimeout #(.focus input)))))
:buttons [#js {:text "Cancel"
:role "cancel"}
#js {:text "Confirm"
:role "confirm"}]
:inputs [#js {:placeholder "page name"
:auto-focus true}]}))
(ion/alert
{:is-open true
:header "Create new page"
:onWillDismiss (fn [^js e]
(let [^js detail (.-detail e)]
(when-let [val (and (= "confirm" (.-role detail))
(aget (.-values (.-data detail)) 0))]
(-> (handler/<create-page! val)
(p/finally reload-pages!)))
(close!)))
:onDidPresent (fn [^js e]
(let [^js target (.-target e)]
(when-let [input (.querySelector target "input")]
(js/setTimeout #(.focus input)))))
:buttons [#js {:text "Cancel"
:role "cancel"}
#js {:text "Confirm"
:role "confirm"}]
:inputs [#js {:placeholder "page name"
:auto-focus true}]}))
(rum/defc all-pages
[]
@@ -37,21 +37,20 @@
[page-input-open? set-page-input-open?] (rum/use-state false)]
(rum/use-effect!
(fn []
(set-all-pages! (handler/local-all-pages))
#())
[reload])
(fn []
(set-all-pages! (handler/local-all-pages))
#())
[reload])
(rum/use-effect!
(fn []
(let [pages (filterv (fn [page]
(let [ident (some-> (:block/tags page) first :db/ident)]
(not (contains? #{:logseq.class/Journal :logseq.class/Property} ident))))
all-pages)]
(set-filtered-pages! pages))
#())
[all-pages])
(fn []
(let [pages (filterv (fn [page]
(let [ident (some-> (:block/tags page) first :db/ident)]
(not (contains? #{:logseq.class/Journal :logseq.class/Property} ident))))
all-pages)]
(set-filtered-pages! pages))
#())
[all-pages])
[:<>
(when page-input-open?
@@ -64,8 +63,8 @@
[:small.text-xs.pl-2.opacity-50 (count filtered-pages)]]
[:div.flex.gap-1
(ionic/ion-button {:size "small" :fill "clear" :on-click #(set-page-input-open? true)}
[:span {:slot "icon-only"} (ionic/tabler-icon "file-plus" {:size 22})])
(ion/button {:size "small" :fill "clear" :on-click #(set-page-input-open? true)}
[:span {:slot "icon-only"} (ion/tabler-icon "file-plus" {:size 22})])
;(ionic/ion-button {:size "small" :fill "clear" :on-click #(set-reload! (inc reload))}
; [:span {:slot "icon-only"} (ionic/tabler-icon "refresh")])
]]
@@ -76,43 +75,41 @@
[:li.font-mono.flex.items-center.py-1.active:opacity-50.active:underline.whitespace-nowrap
{:on-click #(cc-util/nav-to-block! page {:reload-pages! (fn [] (set-reload! (inc reload)))})}
(case ident
:logseq.class/Property (ionic/tabler-icon "letter-t")
:logseq.class/Page (ionic/tabler-icon "file")
:logseq.class/Journal (ionic/tabler-icon "calendar")
(ionic/tabler-icon "hash"))
:logseq.class/Property (ion/tabler-icon "letter-t")
:logseq.class/Page (ion/tabler-icon "file")
:logseq.class/Journal (ion/tabler-icon "calendar")
(ion/tabler-icon "hash"))
[:span.pl-1 (:block/title page)]
[:code.opacity-30.scale-75 (.toLocaleDateString (js/Date. (:block/created-at page)))]]))]
]]))
[:code.opacity-30.scale-75 (.toLocaleDateString (js/Date. (:block/created-at page)))]]))]]]))
(rum/defc page
[]
(let [[^js nav] (state/use-nav-root)]
(ionic/ion-page
(ionic/ion-header
(ionic/ion-toolbar
(ionic/ion-buttons {:slot "start"}
(ionic/ion-button {:fill "clear"
:on-click #(.pop nav)}
(ionic/tabler-icon "arrow-left" {:size 26})))
(ion/page
(ion/header
(ion/toolbar
(ion/buttons {:slot "start"}
(ion/button {:fill "clear"
:on-click #(.pop nav)}
(ion/tabler-icon "arrow-left" {:size 26})))
(ionic/ion-buttons {:slot "end"}
(ionic/ion-button {:fill "clear"
:on-click #(.pop nav)}
(ionic/tabler-icon "share" {:size 26})))
(ion/buttons {:slot "end"}
(ion/button {:fill "clear"
:on-click #(.pop nav)}
(ion/tabler-icon "share" {:size 26})))
(ionic/ion-title "Settings")))
(ion/title "Settings")))
(ionic/ion-content {:class "ion-padding"}
(ionic/ion-refresher
{:slot "fixed"
:pull-factor 0.5
:pull-min 100
:pull-max 200
:on-ion-refresh (fn [^js e]
(js/setTimeout
#(.complete (.-detail e))
3000))}
(ionic/ion-refresher-content))
(ion/content {:class "ion-padding"}
(ion/refresher
{:slot "fixed"
:pull-factor 0.5
:pull-min 100
:pull-max 200
:on-ion-refresh (fn [^js e]
(js/setTimeout
#(.complete (.-detail e))
3000))}
(ion/refresher-content))
(all-pages)
))))
(all-pages)))))

View File

@@ -1,14 +1,14 @@
(ns capacitor.components.ui
(:require [cljs-bean.core :as bean]
(:require [capacitor.ionic :as ion]
[cljs-bean.core :as bean]
[frontend.handler.notification :as notification]
[frontend.rum :as r]
[frontend.state :as fstate]
[medley.core :as medley]
[react-transition-group :refer [CSSTransition TransitionGroup]]
[react-textarea-autosize :as TextareaAutosize]
[goog.object :as gobj]
[rum.core :as rum]
[capacitor.ionic :as ionic]))
[medley.core :as medley]
[react-textarea-autosize :as TextareaAutosize]
[react-transition-group :refer [CSSTransition TransitionGroup]]
[rum.core :as rum]))
(defonce transition-group (r/adapt-class TransitionGroup))
(defonce css-transition (r/adapt-class CSSTransition))
@@ -16,21 +16,21 @@
(rum/defc safe-page-container
[content {:keys [header-content page-props content-props]}]
(ionic/ion-page
(merge {:class "app-safe-page"} page-props)
(some-> header-content (ionic/ion-header))
(ionic/ion-content
(merge {:class "ion-padding"} content-props)
content)))
(ion/page
(merge {:class "app-safe-page"} page-props)
(some-> header-content (ion/header))
(ion/content
(merge {:class "ion-padding"} content-props)
content)))
(rum/defc notification-clear-all
[]
[:div.ui__notifications-content
[:div.pointer-events-auto.notification-clear
(ionic/ion-button
{:on-click (fn []
(notification/clear-all!))}
"clear all")]])
(ion/button
{:on-click (fn []
(notification/clear-all!))}
"clear all")]])
(rum/defc notification-content
[state content status uid]
@@ -39,20 +39,20 @@
(if (keyword? status)
(case status
:success
(ionic/tabler-icon "circle-check" {:class "text-green-600" :size "20"})
(ion/tabler-icon "circle-check" {:class "text-green-600" :size "20"})
:warning
(ionic/tabler-icon "alert-circle" {:class "text-yellow-600" :size "20"})
(ion/tabler-icon "alert-circle" {:class "text-yellow-600" :size "20"})
:error
(ionic/tabler-icon "circle-x" {:class "text-red-600" :size "20"})
(ion/tabler-icon "circle-x" {:class "text-red-600" :size "20"})
(ionic/tabler-icon "info-circle" {:class "text-indigo-600" :size "20"}))
(ion/tabler-icon "info-circle" {:class "text-indigo-600" :size "20"}))
status)]
[:div.ui__notifications-content
{:style
(when (or (= state "exiting")
(= state "exited"))
(= state "exited"))
{:z-index -1})}
[:div.max-w-sm.w-full.shadow-lg.rounded-lg.pointer-events-auto.notification-area
{:class (case state
@@ -73,38 +73,38 @@
content]]
[:div.flex-shrink-0.flex {:style {:margin-top -9
:margin-right -18}}
(ionic/ion-button
{:fill "clear"
:mode "ios"
:shape "round"
:on-click (fn []
(notification/clear! uid))}
[:span {:slot "icon-only"}
(ionic/tabler-icon "x")])]]]]]])))
(ion/button
{:fill "clear"
:mode "ios"
:shape "round"
:on-click (fn []
(notification/clear! uid))}
[:span {:slot "icon-only"}
(ion/tabler-icon "x")])]]]]]])))
(rum/defc install-notifications < rum/reactive
[]
(let [contents (fstate/sub :notification/contents)]
(transition-group
{:class-name "notifications ui__notifications"}
(let [notifications
(map (fn [el]
(let [k (first el)
v (second el)]
(css-transition
{:timeout 100
:key (name k)}
(fn [state]
(notification-content state (:content v) (:status v) k)))))
contents)
clear-all (when (> (count contents) 3)
(css-transition
{:timeout 100
:k "clear-all"}
(fn [_state]
(notification-clear-all))))
items (if clear-all (cons clear-all notifications) notifications)]
(doall items)))))
{:class-name "notifications ui__notifications"}
(let [notifications
(map (fn [el]
(let [k (first el)
v (second el)]
(css-transition
{:timeout 100
:key (name k)}
(fn [state]
(notification-content state (:content v) (:status v) k)))))
contents)
clear-all (when (> (count contents) 3)
(css-transition
{:timeout 100
:k "clear-all"}
(fn [_state]
(notification-clear-all))))
items (if clear-all (cons clear-all notifications) notifications)]
(doall items)))))
(defonce *modals (atom []))
(defonce ^:private *id (atom 0))
@@ -115,45 +115,45 @@
(let [{:keys [class header]} modal-props]
(case type
:alert
(ionic/ion-alert
(merge modal-props
{:is-open true
:header (or title header)
:message content
:backdropDismiss false
:onWillDismiss (fn [^js e]
(when on-action
(on-action (bean/->clj (.-detail e))))
(close!))
:buttons (bean/->js (or buttons (:buttons modal-props)))
:inputs (bean/->js (or inputs (:inputs modal-props) []))}))
(ion/alert
(merge modal-props
{:is-open true
:header (or title header)
:message content
:backdropDismiss false
:onWillDismiss (fn [^js e]
(when on-action
(on-action (bean/->clj (.-detail e))))
(close!))
:buttons (bean/->js (or buttons (:buttons modal-props)))
:inputs (bean/->js (or inputs (:inputs modal-props) []))}))
:action-sheet
(ionic/ion-action-sheet
(merge modal-props
{:is-open true
:header (or content title header)
:onWillDismiss (fn [^js e]
(when on-action
(on-action (bean/->clj (.-detail e))))
(close!))
:buttons (bean/->js (or buttons (:buttons modal-props)))}))
(ion/action-sheet
(merge modal-props
{:is-open true
:header (or content title header)
:onWillDismiss (fn [^js e]
(when on-action
(on-action (bean/->clj (.-detail e))))
(close!))
:buttons (bean/->js (or buttons (:buttons modal-props)))}))
;; default
(ionic/ion-modal
(merge modal-props
{:is-open true
:onWillDismiss (fn [] (close!))
:class (str class (when (not (true? as-page?)) " ion-datetime-button-overlay"))})
(if (fn? content)
(content) content)))))
(ion/modal
(merge modal-props
{:is-open true
:onWillDismiss (fn [] (close!))
:class (str class (when (not (true? as-page?)) " ion-datetime-button-overlay"))})
(if (fn? content)
(content) content)))))
(defn get-modal
([] (some-> @*modals last))
([id]
(when id
(some->> (medley/indexed @*modals)
(filter #(= id (:id (second %)))) (first)))))
(filter #(= id (:id (second %)))) (first)))))
(defn- upsert-modal!
[config]
@@ -170,11 +170,11 @@
(defn open-modal!
[content & {:keys [id type] :as props}]
(upsert-modal!
(merge props
{:id (or id (gen-id))
:type (or type :default) ;; :alert :confirm :page
:as-page? (= type :page)
:content content})))
(merge props
{:id (or id (gen-id))
:type (or type :default) ;; :alert :confirm :page
:as-page? (= type :page)
:content content})))
(defn close-modal!
([] (some-> @*modals (last) :id (close-modal!)))
@@ -187,4 +187,4 @@
:let [close! #(close-modal! id)
props' (assoc props :close! close!)]]
(x-modal props'
(if (fn? content) (content props') content)))]))
(if (fn? content) (content props') content)))]))

View File

@@ -6,40 +6,40 @@
;(def define-custom-component ionicLoader/defineCustomElements)
(def ^js ionic-react ionicReact)
(def ^js ionic-camera (.-Camera ionicCamera))
(def ^js ionic-camera-result-type (.-CameraResultType ionicCamera))
(def ^js camera (.-Camera ionicCamera))
(def ^js camera-result-type (.-CameraResultType ionicCamera))
(def tabler-icon shui-icon/root)
(defonce ion-app (shui-util/react->rum (.-IonApp ionic-react) true))
(defonce ion-page (shui-util/react->rum (.-IonPage ionic-react) true))
(defonce ion-nav (shui-util/react->rum (.-IonNav ionic-react) true))
(defonce ion-nav-link (shui-util/react->rum (.-IonNavLink ionic-react) true))
(defonce ion-content (shui-util/react->rum (.-IonContent ionic-react) true))
(defonce ion-header (shui-util/react->rum (.-IonHeader ionic-react) true))
(defonce ion-back-button (shui-util/react->rum (.-IonBackButton ionic-react) false))
(defonce ion-buttons (shui-util/react->rum (.-IonButtons ionic-react) true))
(defonce ion-toolbar (shui-util/react->rum (.-IonToolbar ionic-react) true))
(defonce ion-loading (shui-util/react->rum (.-IonLoading ionic-react) true))
(defonce ion-title (shui-util/react->rum (.-IonTitle ionic-react) true))
(defonce ion-button (shui-util/react->rum (.-IonButton ionic-react) true))
(defonce ion-alert (shui-util/react->rum (.-IonAlert ionic-react) true))
(defonce ion-input (shui-util/react->rum (.-IonInput ionic-react) true))
(defonce ion-textarea (shui-util/react->rum (.-IonTextarea ionic-react) true))
(defonce ion-icon (shui-util/react->rum (.-IonIcon ionic-react) true))
(defonce ion-badge (shui-util/react->rum (.-IonBadge ionic-react) true))
(defonce ion-tabs (shui-util/react->rum (.-IonTabs ionic-react) false))
(defonce ion-tab (shui-util/react->rum (.-IonTab ionic-react) false))
(defonce ion-tab-bar (shui-util/react->rum (.-IonTabBar ionic-react) false))
(defonce ion-tab-button (shui-util/react->rum (.-IonTabButton ionic-react) false))
(defonce ion-modal (shui-util/react->rum (.-IonModal ionic-react) false))
(defonce ion-label (shui-util/react->rum (.-IonLabel ionic-react) false))
(defonce ion-list (shui-util/react->rum (.-IonList ionic-react) false))
(defonce ion-item (shui-util/react->rum (.-IonItem ionic-react) false))
(defonce ion-datetime (shui-util/react->rum (.-IonDatetime ionic-react) false))
(defonce ion-datetime-button (shui-util/react->rum (.-IonDatetimeButton ionic-react) false))
(defonce ion-refresher (shui-util/react->rum (.-IonRefresher ionic-react) false))
(defonce ion-refresher-content (shui-util/react->rum (.-IonRefresherContent ionic-react) false))
(defonce ion-menu (shui-util/react->rum (.-IonMenu ionic-react) false))
(defonce ion-menu-button (shui-util/react->rum (.-IonMenuButton ionic-react) false))
(defonce ion-action-sheet (shui-util/react->rum (.-IonActionSheet ionic-react) false))
(defonce app (shui-util/react->rum (.-IonApp ionic-react) true))
(defonce page (shui-util/react->rum (.-IonPage ionic-react) true))
(defonce nav (shui-util/react->rum (.-IonNav ionic-react) true))
(defonce nav-link (shui-util/react->rum (.-IonNavLink ionic-react) true))
(defonce content (shui-util/react->rum (.-IonContent ionic-react) true))
(defonce header (shui-util/react->rum (.-IonHeader ionic-react) true))
(defonce back-button (shui-util/react->rum (.-IonBackButton ionic-react) false))
(defonce buttons (shui-util/react->rum (.-IonButtons ionic-react) true))
(defonce toolbar (shui-util/react->rum (.-IonToolbar ionic-react) true))
(defonce loading (shui-util/react->rum (.-IonLoading ionic-react) true))
(defonce title (shui-util/react->rum (.-IonTitle ionic-react) true))
(defonce button (shui-util/react->rum (.-IonButton ionic-react) true))
(defonce alert (shui-util/react->rum (.-IonAlert ionic-react) true))
(defonce input (shui-util/react->rum (.-IonInput ionic-react) true))
(defonce textarea (shui-util/react->rum (.-IonTextarea ionic-react) true))
(defonce icon (shui-util/react->rum (.-IonIcon ionic-react) true))
(defonce badge (shui-util/react->rum (.-IonBadge ionic-react) true))
(defonce tabs (shui-util/react->rum (.-IonTabs ionic-react) false))
(defonce tab (shui-util/react->rum (.-IonTab ionic-react) false))
(defonce tab-bar (shui-util/react->rum (.-IonTabBar ionic-react) false))
(defonce tab-button (shui-util/react->rum (.-IonTabButton ionic-react) false))
(defonce modal (shui-util/react->rum (.-IonModal ionic-react) false))
(defonce label (shui-util/react->rum (.-IonLabel ionic-react) false))
(defonce list (shui-util/react->rum (.-IonList ionic-react) false))
(defonce item (shui-util/react->rum (.-IonItem ionic-react) false))
(defonce datetime (shui-util/react->rum (.-IonDatetime ionic-react) false))
(defonce datetime-button (shui-util/react->rum (.-IonDatetimeButton ionic-react) false))
(defonce refresher (shui-util/react->rum (.-IonRefresher ionic-react) false))
(defonce refresher-content (shui-util/react->rum (.-IonRefresherContent ionic-react) false))
(defonce menu (shui-util/react->rum (.-IonMenu ionic-react) false))
(defonce menu-button (shui-util/react->rum (.-IonMenuButton ionic-react) false))
(defonce action-sheet (shui-util/react->rum (.-IonActionSheet ionic-react) false))