Dropdown works well
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
(ns auto-ap.ssr.components.inputs
|
||||
(:require [auto-ap.ssr.components.buttons :as buttons]
|
||||
[auto-ap.ssr.components.tags :as tags]
|
||||
(:require [auto-ap.ssr.components.tags :as tags]
|
||||
[auto-ap.ssr.hiccup-helper :as hh]
|
||||
[auto-ap.ssr.hx :as hx]
|
||||
[auto-ap.ssr.hx :as hx :refer [js-fn]]
|
||||
[auto-ap.ssr.svg :as svg]
|
||||
[clojure.string :as str]
|
||||
[hiccup2.core :as hiccup]))
|
||||
@@ -21,7 +20,7 @@
|
||||
"group-[.has-error]:dark:border-red-500"])
|
||||
|
||||
(def default-checkbox-classes
|
||||
"w-4 h-4 bg-gray-100 border-gray-300 rounded text-primary-600 focus:ring-primary-500 dark:focus:ring-primary-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600")
|
||||
"w-4 h-4 bg-gray-100 indeterminate:bg-gray-300 border-gray-300 rounded text-primary-600 focus:ring-primary-500 dark:focus:ring-primary-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600")
|
||||
|
||||
(defn select- [params & children]
|
||||
(into
|
||||
@@ -38,11 +37,17 @@
|
||||
|
||||
(defn checkbox- [params & rest]
|
||||
(if (seq rest)
|
||||
[:label {:class "text-sm text-gray-800 dark:text-gray-300"}
|
||||
[:input (merge params {:type "checkbox" :class (hh/add-class default-checkbox-classes (:class params ""))})]
|
||||
[:label {:class "text-sm text-gray-800 dark:text-gray-300 "}
|
||||
[:input (merge (dissoc params :indeterminate?)
|
||||
{:type "checkbox" :class (hh/add-class default-checkbox-classes (:class params ""))}
|
||||
(when (:indeterminate? params)
|
||||
{:x-init "$el.indeterminate = true"}))]
|
||||
[:span.ml-2
|
||||
rest]]
|
||||
[:input (merge params {:type "checkbox" :class (hh/add-class default-checkbox-classes (:class params ""))})
|
||||
[:input (merge (dissoc params :indeterminate params)
|
||||
{:type "checkbox" :class (hh/add-class default-checkbox-classes (:class params ""))}
|
||||
(when (:indeterminate? params)
|
||||
{:x-init "$el.indeterminate = true"}))
|
||||
]))
|
||||
|
||||
(defn typeahead- [params]
|
||||
@@ -110,9 +115,10 @@
|
||||
"x-init" "$el.focus(); $watch('search', s => { if($el.value.length > 2) {fetch(baseUrl + s).then(data=>data.json()).then(data => {elements = data; active=-1; tippy.popperInstance.update()}) }})"}]
|
||||
[:div.dropdown-options {:class "rounded-b-lg overflow-hidden"}
|
||||
[:template {:x-for "(element, index) in elements"}
|
||||
[:li [:a {:class "px-4 py-2 flex gap-2 items-center outline-0 focus:bg-neutral-100 hover:bg-neutral-100 whitespace-nowrap [&.active]:bg-primary-300 [&.active]:dark:bg-primary-700 text-gray-800 dark:text-gray-100"
|
||||
[:li [:a {:class "px-4 py-2 flex gap-2 items-center outline-0 focus:bg-neutral-100 hover:bg-neutral-100 whitespace-nowrap [&.active]:bg-primary-500 [&.active]:dark:bg-primary-700 text-gray-800 dark:text-gray-100"
|
||||
:href "#"
|
||||
":class" "active == index ? 'active' : ''"
|
||||
|
||||
"@mouseover" "active = index"
|
||||
"@mouseout" "active = -1"
|
||||
"@click.prevent" "value = element; tippy.hide(); $refs.input.focus()"
|
||||
@@ -141,20 +147,24 @@
|
||||
"@keydown.down.prevent" "active ++; active = active >= elements.length - 1 ? elements.length - 1 : active"
|
||||
"@keydown.up.prevent" "active --; active = active < 0 ? 0 : active"
|
||||
"@keydown.enter.prevent.stop" "if ($data.elements[active]) { if (value.has($data.elements[active].value)) { value.delete($data.elements[active].value) } else {value.add($data.elements[active].value); lookup[$data.elements[active].value] = $data.elements[active].label} } "
|
||||
"x-init" " $el.focus(); $watch('search', s => { if($el.value.length > 2) {fetch(baseUrl + s).then(data=>data.json()).then(data => {elements = data; active=-1}) }})"}]]
|
||||
"x-init" " $el.focus(); $watch('search', s => { if($el.value.length > 2) {fetch(baseUrl + s).then(data=>data.json()).then(data => reset_elements(data)) }})"}]]
|
||||
[:div.dropdown-options {:class "overflow-hidden divide-y divide-gray-200 "}
|
||||
|
||||
[:template {:x-for "(element, index) in elements"}
|
||||
[:li {":style" "index == 0 && 'border: 0 !important;'"}
|
||||
[:label {:class "p-3 rounded flex gap-2 items-center outline-0 focus:bg-neutral-100 hover:bg-neutral-100 whitespace-nowrap [&.active]:bg-primary-300 [&.active]:dark:bg-primary-700 text-gray-800 dark:text-gray-100 cursor-pointer"
|
||||
[:li {":style" "index == 0 && 'border: 0 !important;'"}
|
||||
[:label {:class "p-3 group rounded flex gap-2 items-center outline-0 focus:bg-neutral-100 hover:bg-neutral-100 whitespace-nowrap [&.active]:bg-primary-300 [&.active]:dark:bg-primary-700 [&.implied]:text-gray-500 text-gray-800 dark:text-gray-100 cursor-pointer"
|
||||
|
||||
|
||||
:href "#"
|
||||
":class" "active == index ? 'active' : ''"
|
||||
":class" (hx/json {"active" (hx/js-fn "active==index")
|
||||
"implied" (hx/js-fn "all_selected && index != 0")
|
||||
} )
|
||||
"@mouseover" "active = index"
|
||||
"@mouseout" "active = -1"
|
||||
"@click.prevent" "if (value.has(element.value)) { value.delete(element.value) } else {value.add(element.value); lookup[element.value] = element.label}"}
|
||||
(checkbox- {":checked" "value.has(element.value)"}
|
||||
)
|
||||
"@click.prevent" "toggle(element)"}
|
||||
(checkbox- {":checked" "value.has(element.value) || all_selected"
|
||||
:class "group-[&.implied]:bg-green-200"
|
||||
|
||||
})
|
||||
#_[:input {:type "checkbox" }]
|
||||
[:span {"x-html" "element.label"}]]]]
|
||||
[:template {:x-if "elements.length == 0"}
|
||||
@@ -164,39 +174,79 @@
|
||||
(defn multi-typeahead-selected-pill- [params]
|
||||
[:div.flex-grow.flex
|
||||
[:template {:x-if "value.size > 0"}
|
||||
[:a.bg-blue-100.rounded-full.px-3 {:x-tooltip "{content: ()=>$refs.selected_tt.innerHTML, popperOptions: {strategy: 'fixed', modifiers: [{name: 'flip', options: {fallbackPlacements: ['top']}}]}, placement: 'bottom', theme: 'light', allowHTML: true, appendTo: $el}"}
|
||||
[:span.text-left {:x-ref "source"}
|
||||
[:span {"x-text" "value.size"}]
|
||||
[:a.bg-blue-100.rounded-full.px-3
|
||||
[:span.text-left
|
||||
[:span {"x-text" "value.has('all') ? 'All' : value.size"}]
|
||||
" selected"]
|
||||
[:template {:x-ref "selected_tt"}
|
||||
[:div.flex.flex-wrap.gap-4.w-64.p-4
|
||||
[:template {:x-for "v in Array.from(value.values())"}
|
||||
[:div.bg-green-50.rounded-full.px-3.text-ellipsis.whitespace-nowrap.shrink.overflow-hidden.text-green-800 {:x-text "lookup[v]"}]]]]]]
|
||||
|
||||
]]
|
||||
[:template {:x-if "value.size == 0"}
|
||||
[:span.text-left.text-gray-400 "None selected"]]
|
||||
[:div {:class "w-4 h-4 ml-2 inline text-gray-500 self-center rounded-full bg-gray-100 text-gray-500"
|
||||
"@click.prevent.stop" "value = new Set([])"
|
||||
"@click.prevent.stop" "value = new Set([]); all_selected=false;"
|
||||
:x-show "value.size > 0"}
|
||||
svg/x]])
|
||||
|
||||
|
||||
(defn multi-typeahead- [params]
|
||||
[:div.relative {:x-data (hx/json {:baseUrl (if (str/includes? (:url params) "?")
|
||||
(str (:url params) "&q=")
|
||||
(str (:url params) "?q="))
|
||||
:value (map (fn [v] ((:value-fn params identity) v))
|
||||
(:value params))
|
||||
:tippy nil
|
||||
:lookup (into {}
|
||||
(map (fn [v] [((:value-fn params identity) v)
|
||||
((:content-fn params identity) v)])
|
||||
(:value params)))
|
||||
:x-init (str "$watch('value', v => $dispatch('change')); ")
|
||||
:search ""
|
||||
:active -1
|
||||
:elements (if ((:value-fn params identity) (:value params))
|
||||
[{:value ((:value-fn params identity) (:value params)) :label ((:content-fn params identity) (:value params))}]
|
||||
[])
|
||||
:x-ref "r"})
|
||||
[:div.relative {:x-data (doto (hx/json {:baseUrl (if (str/includes? (:url params) "?")
|
||||
(str (:url params) "&q=")
|
||||
(str (:url params) "?q="))
|
||||
:reset_elements (js-fn "function(e) {
|
||||
this.elements = [{value: 'all', label:'All'}].concat(e);
|
||||
this.active = -1
|
||||
}")
|
||||
:toggle (js-fn "function(e) {
|
||||
if (e.value == 'all') {
|
||||
if (this.value.size > 0) {
|
||||
this.value = new Set([]);
|
||||
this.all_selected = false;
|
||||
} else {
|
||||
this.value = new Set(['all']);
|
||||
this.all_selected = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.all_selected) {
|
||||
this.value.delete('all')
|
||||
this.all_selected = false;
|
||||
|
||||
}
|
||||
if (this.value.has(e.value)) {
|
||||
this.value.delete(e.value)
|
||||
} else {
|
||||
this.value.add(e.value); this.lookup[e.value] = e.label
|
||||
}
|
||||
}
|
||||
}")
|
||||
:all_selected (boolean (= (:value params) :all)),
|
||||
:value (cond
|
||||
(= :all (:value params))
|
||||
["all"]
|
||||
|
||||
(sequential? (:value params))
|
||||
(map (fn [v] ((:value-fn params identity) v))
|
||||
(:value params))
|
||||
|
||||
:else
|
||||
[])
|
||||
:tippy nil
|
||||
:lookup (into {}
|
||||
(when (sequential? (:value params))
|
||||
(map (fn [v] [((:value-fn params identity) v)
|
||||
((:content-fn params identity) v)])
|
||||
(:value params))))
|
||||
:x-init (str "$watch('value', v => $dispatch('change')); ")
|
||||
:search ""
|
||||
:active -1
|
||||
:elements (cond-> [{:value "all" :label "All"}]
|
||||
(sequential? (:value params))
|
||||
(into (map (fn [v]
|
||||
{:value ((:value-fn params identity) v)
|
||||
:label ((:content-fn params identity) v)})
|
||||
(:value params))))
|
||||
:x-ref "r"})
|
||||
println)
|
||||
;; :x-modelable "value.value" TODO
|
||||
;; :x-model (:x-model params) TODO
|
||||
:x-init "value=new Set(value || []); "}
|
||||
@@ -355,4 +405,4 @@
|
||||
[:label {:class "inline-flex items-center cursor-pointer"}
|
||||
[:input (merge {:type "checkbox", :class "sr-only peer"} params)]
|
||||
[:div {:class "relative w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-300 dark:peer-focus:ring-blue-800 rounded-full peer dark:bg-gray-700 peer-checked:after:translate-x-full rtl:peer-checked:after:-translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:start-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-600"}]
|
||||
[:span {:class "ms-3 text-sm font-medium text-gray-900 dark:text-gray-300"} children]])
|
||||
[:span {:class "ms-3 text-sm font-medium text-gray-900 dark:text-gray-300"} children]])
|
||||
|
||||
Reference in New Issue
Block a user