using popper instead of handrolled appearing stuff.

This commit is contained in:
2022-07-17 19:40:23 -07:00
parent b1cdd60781
commit 5e49f61265
8 changed files with 158 additions and 71 deletions

68
package-lock.json generated
View File

@@ -16,6 +16,7 @@
"react": "^17.0.1", "react": "^17.0.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-plaid-link": "^3.2.1", "react-plaid-link": "^3.2.1",
"react-popper": "^2.3.0",
"react-prop-types": "^0.4.0", "react-prop-types": "^0.4.0",
"react-signature-canvas": "^1.0.3", "react-signature-canvas": "^1.0.3",
"react-signature-pad": "0.0.6", "react-signature-pad": "0.0.6",
@@ -35,6 +36,16 @@
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
} }
}, },
"node_modules/@popperjs/core": {
"version": "2.11.5",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz",
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==",
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@types/eslint": { "node_modules/@types/eslint": {
"version": "7.2.6", "version": "7.2.6",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz",
@@ -1311,6 +1322,11 @@
"react": "17.0.1" "react": "17.0.1"
} }
}, },
"node_modules/react-fast-compare": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
},
"node_modules/react-is": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -1334,6 +1350,28 @@
"react-dom": "^16.8.0 || ^17.0.0" "react-dom": "^16.8.0 || ^17.0.0"
} }
}, },
"node_modules/react-popper": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
"integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
"dependencies": {
"react-fast-compare": "^3.0.1",
"warning": "^4.0.2"
},
"peerDependencies": {
"@popperjs/core": "^2.0.0",
"react": "^16.8.0 || ^17 || ^18",
"react-dom": "^16.8.0 || ^17 || ^18"
}
},
"node_modules/react-popper/node_modules/warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/react-prop-types": { "node_modules/react-prop-types": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz", "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz",
@@ -2027,6 +2065,12 @@
"regenerator-runtime": "^0.13.4" "regenerator-runtime": "^0.13.4"
} }
}, },
"@popperjs/core": {
"version": "2.11.5",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.5.tgz",
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==",
"peer": true
},
"@types/eslint": { "@types/eslint": {
"version": "7.2.6", "version": "7.2.6",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz",
@@ -3084,6 +3128,11 @@
"scheduler": "^0.20.1" "scheduler": "^0.20.1"
} }
}, },
"react-fast-compare": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA=="
},
"react-is": { "react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -3103,6 +3152,25 @@
"react-script-hook": "1.3.0" "react-script-hook": "1.3.0"
} }
}, },
"react-popper": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
"integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
"requires": {
"react-fast-compare": "^3.0.1",
"warning": "^4.0.2"
},
"dependencies": {
"warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"requires": {
"loose-envify": "^1.0.0"
}
}
}
},
"react-prop-types": { "react-prop-types": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz", "resolved": "https://registry.npmjs.org/react-prop-types/-/react-prop-types-0.4.0.tgz",

View File

@@ -14,6 +14,7 @@
"react": "^17.0.1", "react": "^17.0.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-plaid-link": "^3.2.1", "react-plaid-link": "^3.2.1",
"react-popper": "^2.3.0",
"react-prop-types": "^0.4.0", "react-prop-types": "^0.4.0",
"react-signature-canvas": "^1.0.3", "react-signature-canvas": "^1.0.3",
"react-signature-pad": "0.0.6", "react-signature-pad": "0.0.6",

View File

@@ -10954,15 +10954,8 @@ span[data-tooltip].has-tooltip-primary-two {
} }
.typeahead-menu { .typeahead-menu {
position: absolute;
display: inline-block;
width: 100%;
top: 100%;
left: 0;
z-index: 10000; z-index: 10000;
overflow: auto; min-width: 200px;
float: left;
min-width: 160px;
padding: 5px 0; padding: 5px 0;
margin: 2px 0 0; margin: 2px 0 0;
list-style: none; list-style: none;

File diff suppressed because one or more lines are too long

View File

@@ -75,27 +75,20 @@ $fullhd-enabled: false;
} }
.typeahead-menu { .typeahead-menu {
position:absolute; z-index: 10000;
display: inline-block; min-width: 200px;
width: 100%; padding: 5px 0;
top: 100%; margin: 2px 0 0;
left: 0; list-style: none;
z-index: 10000; font-size: 14px;
overflow: auto; text-align: left;
float: left; background-color: $white;
min-width: 160px; border: 1px solid #cccccc;
padding: 5px 0; border: 1px solid rgba(0, 0, 0, 0.15);
margin: 2px 0 0; border-radius: 4px;
list-style: none; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
font-size: 14px; box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
text-align: left; /* background-clip: padding-box; */
background-color: $white;
border: 1px solid #cccccc;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
/* background-clip: padding-box; */
} }
.modal-card { .modal-card {
overflow: auto; overflow: auto;

View File

@@ -3,12 +3,34 @@
[downshift :as ds :refer [useCombobox]] [downshift :as ds :refer [useCombobox]]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[auto-ap.views.utils :refer [with-user]] [auto-ap.views.utils :refer [with-user]]
[react-popper :refer [usePopper] :as react-popper]
[reagent.core :as r]
[clojure.string :as str] [clojure.string :as str]
[react :as react])) [react :as react]))
(set! *warn-on-infer* true) (set! *warn-on-infer* true)
(defn popper-test-internal [props children]
(let [[reference-element set-reference-element] (react/useState nil)
[popper-element set-popper-element] (react/useState nil)
^js/Popper use (usePopper reference-element popper-element
#js {:placement "bottom-start"
:strategy "fixed"})
popper-props (into {:ref set-popper-element
:style (assoc (js->clj (.. use -styles -popper))
:z-index "1000")
}
(js->clj (.. use -attributes -popper)))]
[:<>
[:div {:ref set-reference-element}]
[:div popper-props
(into [:div {:class (:class props)}] children)]]))
(defn popper []
[:f> popper-test-internal (r/props (r/current-component))
(r/children (r/current-component))])
(re-frame/reg-event-fx (re-frame/reg-event-fx
::search-completed ::search-completed
(fn [_ [_ set-items set-loading-status result]] (fn [_ [_ set-items set-loading-status result]]
@@ -62,8 +84,7 @@
:key ::input-value-settled}}))) :key ::input-value-settled}})))
(defn typeahead-v3-internal [{:keys [class entity->text entities on-input-change style ^js on-change disabled value name auto-focus] :or {disabled false} (defn typeahead-v3-internal [{:keys [class entity->text entities on-input-change style ^js on-change disabled value name auto-focus] :or {disabled false}
prop-value :value prop-value :value}]
:as i}]
(let [[items set-items] (react/useState (or entities (let [[items set-items] (react/useState (or entities
[])) []))
[focused set-focus] (react/useState (boolean auto-focus)) [focused set-focus] (react/useState (boolean auto-focus))
@@ -148,8 +169,8 @@
:autoFocus (if auto-focus :autoFocus (if auto-focus
"autoFocus" "autoFocus"
"")}))]]] "")}))]]]
[:div {:class (when (and isOpen (seq items)) [popper {:class (when (and isOpen (seq items))
"typeahead-menu")} "typeahead-menu")}
[:ul (js->clj (getMenuProps)) [:ul (js->clj (getMenuProps))
(when (and isOpen (seq items)) (when (and isOpen (seq items))
(for [[index item] (map vector (range) (js->clj items :keywordize-keys true))] (for [[index item] (map vector (range) (js->clj items :keywordize-keys true))]
@@ -176,11 +197,10 @@
:on-input-change :on-input-change
(fn [input set-items] (fn [input set-items]
(if entities-by-id (if entities-by-id
(do (set-items
(set-items (into-array
(into-array (->> (.search entity-index (or (aget input "inputValue") "") #js {:fuzzy 0.2} )
(->> (.search entity-index (or (aget input "inputValue") "") #js {:fuzzy 0.2} ) (take 10))))
(take 10)))))
(set-items (into-array (set-items (into-array
(take 10 (filter (fn [x] (str/includes? (or (some-> (entity->text x) str/lower-case) "") (take 10 (filter (fn [x] (str/includes? (or (some-> (entity->text x) str/lower-case) "")

View File

@@ -8,7 +8,11 @@
[auto-ap.views.components.modal :as modal] [auto-ap.views.components.modal :as modal]
[auto-ap.views.components.typeahead :refer [typeahead-v3]] [auto-ap.views.components.typeahead :refer [typeahead-v3]]
[auto-ap.views.utils :refer [dispatch-event multi-field with-user]] [auto-ap.views.utils :refer [dispatch-event multi-field with-user]]
[re-frame.core :as re-frame])) [react-popper :refer [usePopper] :as react-popper]
[re-frame.core :as re-frame]
[react :as react]
[reagent.core :as r]))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::saving ::saving
@@ -33,39 +37,43 @@
{:dispatch [::modal/modal-closed]})) {:dispatch [::modal/modal-closed]}))
(defn form [] (defn form []
(let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form]) (let [{:keys [data]} @(re-frame/subscribe [::forms/form ::form])
clients @(re-frame/subscribe [::subs/clients])] clients @(re-frame/subscribe [::subs/clients])]
[form-builder/builder {:submit-event [::saving] [:<>
:id ::form} [form-builder/builder {:submit-event [::saving]
[form-builder/field :id ::form}
"Name" [form-builder/field
[:input.input {:type "text" "Name"
:field [:name] [:input.input {:type "text"
:spec ::entity/name}]] :field [:name]
[:div.field :spec ::entity/name}]]
[:p.help "Role"] [:div.field
[:div.control [:p.help "Role"]
[:div.select [:div.control
[form-builder/raw-field [:div.select
[:select {:type "select" [form-builder/raw-field
:field [:role]} [:select {:type "select"
[:option {:value ":none"} "None"] :field [:role]}
[:option {:value ":user"} "User"] [:option {:value ":none"} "None"]
[:option {:value ":manager"} "Manager"] [:option {:value ":user"} "User"]
[:option {:value ":power_user"} "Power User"] [:option {:value ":manager"} "Manager"]
[:option {:value ":admin"} "Admin"]]]]]] [:option {:value ":power_user"} "Power User"]
(when (#{":user" ":manager" ":power_user"} (:role data)) [:option {:value ":admin"} "Admin"]]]]]]
[form-builder/field (when (#{":user" ":manager" ":power_user"} (:role data))
"Client" [form-builder/field
[multi-field {:type "multi-field" "Client"
:field [:clients] [multi-field {:type "multi-field"
:template [[typeahead-v3 {:entities clients :field [:clients]
:entity->text :name :template [[typeahead-v3 {:entities clients
:style {:width "13em"} :entity->text :name
:type "typeahead-v3" :style {:width "13em"}
:field [:client]}]]}]]) :type "typeahead-v3"
[form-builder/hidden-submit-button]])) :field [:client]}]]}]])
[form-builder/hidden-submit-button]]]))
(re-frame/reg-event-fx (re-frame/reg-event-fx
::editing ::editing

View File

@@ -349,6 +349,7 @@
[typeahead-v3 {:entities @(re-frame/subscribe [::subs/clients]) [typeahead-v3 {:entities @(re-frame/subscribe [::subs/clients])
:entity->text :name :entity->text :name
:type "typeahead-v3" :type "typeahead-v3"
:style {:width "8em"}
:auto-focus (if active-client false true) :auto-focus (if active-client false true)
:field [:client] :field [:client]
:disabled exists?}]]) :disabled exists?}]])
@@ -360,6 +361,8 @@
{:query i} {:query i}
[:name :id]]) [:name :id]])
:type "typeahead-v3" :type "typeahead-v3"
:style {:width "18em"}
:auto-focus (if active-client true false) :auto-focus (if active-client true false)
:field [:vendor]}]] :field [:vendor]}]]
[form-builder/vertical-control {:required? true} [form-builder/vertical-control {:required? true}
@@ -393,7 +396,8 @@
[form-builder/field {:required? true} [form-builder/field {:required? true}
"Invoice #" "Invoice #"
[:input.input {:type "text" [:input.input {:type "text"
:field [:invoice-number]}]] :field [:invoice-number]
:style {:width "12em"}}]]
[form-builder/field {:required? true} [form-builder/field {:required? true}
"Total" "Total"
[money-field {:type "money" [money-field {:type "money"