|
130 | 130 | :required false
|
131 | 131 | :default false
|
132 | 132 | :type "boolean"
|
133 |
| - :description "if true, no user selection is allowed"} |
| 133 | + :description "When true, no user selection is allowed"} |
| 134 | + {:name :required? |
| 135 | + :default false |
| 136 | + :type "boolean" |
| 137 | + :description [:span "When true, requires at least 1 choice to be selected. " |
| 138 | + "If clicking a choice would result in 0 choices being selected (i.e. a model value of #{}), " |
| 139 | + "then " [:code ":on-change"] " will not be called."]} |
134 | 140 | {:name :groups-first?
|
135 | 141 | :required false
|
136 | 142 | :default false
|
137 | 143 | :type "boolean"
|
138 |
| - :description "If true, puts groups at the top of the list. Ungrouped items will appear last."} |
| 144 | + :description "When true, puts groups at the top of the list. Ungrouped items will appear last."} |
139 | 145 | {:name :choice-disabled-fn
|
140 | 146 | :required false
|
141 | 147 | :default nil
|
|
412 | 418 | min-width max-width min-height max-height
|
413 | 419 | on-change choice-disabled-fn label-fn
|
414 | 420 | choice on-group-expand
|
415 |
| - empty-means-full? |
| 421 | + empty-means-full? required? |
416 | 422 | parts class style attr]
|
417 | 423 | :as args}]
|
418 | 424 | (or
|
|
437 | 443 | full? :all
|
438 | 444 | (every? model descendant-ids) :all
|
439 | 445 | (some model descendant-ids) :some)
|
440 |
| - new-model (->> (cond->> descendants choice-disabled-fn (remove choice-disabled-fn)) |
441 |
| - (map id-fn) |
442 |
| - ((if (= :all checked?) set/difference set/union) model) |
443 |
| - set) |
444 |
| - new-groups (into #{} (map :group) (full-groups new-model choices {:id-fn id-fn})) |
| 446 | + toggle-group #(->> (cond->> descendants choice-disabled-fn (remove choice-disabled-fn)) |
| 447 | + (map id-fn) |
| 448 | + ((if (= :all checked?) set/difference set/union) %) |
| 449 | + set) |
| 450 | + new-groups (into #{} (map :group) (full-groups (toggle-group model) |
| 451 | + choices |
| 452 | + {:id-fn id-fn})) |
445 | 453 | group-props {:group item-props
|
446 | 454 | :label (group-label-fn item-props)
|
447 | 455 | :parts parts
|
448 | 456 | :hide-show! (handler-fn (on-group-expand (toggle expanded-groups group)))
|
449 |
| - :toggle! (handler-fn (on-change new-model new-groups)) |
| 457 | + :toggle! (handler-fn |
| 458 | + (let [new-model (toggle-group model)] |
| 459 | + (when (or (not required?) (seq new-model)) |
| 460 | + (on-change new-model new-groups)))) |
450 | 461 | :solo! (handler-fn (let [new-model (set descendant-ids)
|
451 | 462 | new-groups (into #{} (map :group) (full-groups new-model choices {:id-fn id-fn}))]
|
452 | 463 | (on-change new-model new-groups)))
|
|
472 | 483 | (on-change new-model new-groups)))
|
473 | 484 | :toggle! (handler-fn (let [new-model (toggle model (id-fn item-props))
|
474 | 485 | new-groups (into #{} (map :group) (full-groups new-model choices {:id-fn id-fn}))]
|
475 |
| - (on-change new-model new-groups))) |
| 486 | + (when (or (not required?) (seq new-model)) |
| 487 | + (on-change new-model new-groups)))) |
476 | 488 | :checked? (or full? (get model (id-fn item-props)))
|
477 | 489 | :level level}]
|
478 | 490 | [choice-wrapper choice-props]))))]
|
|
517 | 529 | (let [showing? (r/atom false)
|
518 | 530 | expanded-groups (r/atom nil)]
|
519 | 531 | (fn tree-select-dropdown-render
|
520 |
| - [& {:keys [choices disabled? |
| 532 | + [& {:keys [choices disabled? required? |
521 | 533 | width min-width max-width min-height max-height on-change
|
522 | 534 | label-fn alt-text-fn group-label-fn model placeholder id-fn field-label-fn
|
523 | 535 | groups-first? initial-expanded-groups
|
|
578 | 590 | (themed ::dropdown-body
|
579 | 591 | {:choices choices
|
580 | 592 | :choice choice
|
| 593 | + :required? required? |
581 | 594 | :group-label-fn group-label-fn
|
582 | 595 | :expanded-groups expanded-groups
|
583 | 596 | :disabled? disabled?
|
|
0 commit comments