@reviewpush/rp-treeselect 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +172 -0
  2. package/dist/rp-treeselect.cjs.js +3656 -0
  3. package/dist/rp-treeselect.cjs.js.map +1 -0
  4. package/dist/rp-treeselect.cjs.min.js +2 -0
  5. package/dist/rp-treeselect.cjs.min.js.map +1 -0
  6. package/dist/rp-treeselect.css +947 -0
  7. package/dist/rp-treeselect.css.map +1 -0
  8. package/dist/rp-treeselect.min.css +1 -0
  9. package/dist/rp-treeselect.umd.js +4837 -0
  10. package/dist/rp-treeselect.umd.js.map +1 -0
  11. package/dist/rp-treeselect.umd.min.js +2 -0
  12. package/dist/rp-treeselect.umd.min.js.map +1 -0
  13. package/package.json +140 -0
  14. package/src/assets/checkbox-checked-disabled.png +0 -0
  15. package/src/assets/checkbox-checked-disabled@2x.png +0 -0
  16. package/src/assets/checkbox-checked-disabled@3x.png +0 -0
  17. package/src/assets/checkbox-checked.png +0 -0
  18. package/src/assets/checkbox-checked@2x.png +0 -0
  19. package/src/assets/checkbox-checked@3x.png +0 -0
  20. package/src/assets/checkbox-indeterminate-disabled.png +0 -0
  21. package/src/assets/checkbox-indeterminate-disabled@2x.png +0 -0
  22. package/src/assets/checkbox-indeterminate-disabled@3x.png +0 -0
  23. package/src/assets/checkbox-indeterminate.png +0 -0
  24. package/src/assets/checkbox-indeterminate@2x.png +0 -0
  25. package/src/assets/checkbox-indeterminate@3x.png +0 -0
  26. package/src/components/Control.vue +153 -0
  27. package/src/components/HiddenFields.vue +37 -0
  28. package/src/components/Input.vue +295 -0
  29. package/src/components/Menu.vue +313 -0
  30. package/src/components/MenuPortal.vue +179 -0
  31. package/src/components/MultiValue.vue +56 -0
  32. package/src/components/MultiValueItem.vue +45 -0
  33. package/src/components/Option.vue +300 -0
  34. package/src/components/Placeholder.vue +21 -0
  35. package/src/components/SingleValue.vue +34 -0
  36. package/src/components/Tip.vue +32 -0
  37. package/src/components/Treeselect.vue +42 -0
  38. package/src/components/icons/Arrow.vue +11 -0
  39. package/src/components/icons/Delete.vue +11 -0
  40. package/src/constants.js +50 -0
  41. package/src/index.js +14 -0
  42. package/src/mixins/treeselectMixin.js +1949 -0
  43. package/src/style.less +1147 -0
  44. package/src/utils/.eslintrc.js +6 -0
  45. package/src/utils/constant.js +1 -0
  46. package/src/utils/createMap.js +1 -0
  47. package/src/utils/debounce.js +1 -0
  48. package/src/utils/deepExtend.js +25 -0
  49. package/src/utils/find.js +6 -0
  50. package/src/utils/identity.js +1 -0
  51. package/src/utils/includes.js +3 -0
  52. package/src/utils/index.js +38 -0
  53. package/src/utils/isNaN.js +3 -0
  54. package/src/utils/isPromise.js +1 -0
  55. package/src/utils/last.js +1 -0
  56. package/src/utils/noop.js +1 -0
  57. package/src/utils/onLeftClick.js +7 -0
  58. package/src/utils/once.js +1 -0
  59. package/src/utils/quickDiff.js +9 -0
  60. package/src/utils/removeFromArray.js +4 -0
  61. package/src/utils/scrollIntoView.js +15 -0
  62. package/src/utils/setupResizeAndScrollEventListeners.js +34 -0
  63. package/src/utils/warning.js +11 -0
  64. package/src/utils/watchSize.js +67 -0
@@ -0,0 +1,300 @@
1
+ <script>
2
+ import { UNCHECKED, INDETERMINATE, CHECKED } from '../constants'
3
+ import { onLeftClick } from '../utils'
4
+ import Tip from './Tip'
5
+ import ArrowIcon from './icons/Arrow'
6
+
7
+ let arrowPlaceholder, checkMark, minusMark
8
+
9
+ const Option = {
10
+ name: 'rp-treeselect--option',
11
+ inject: [ 'instance' ],
12
+
13
+ props: {
14
+ node: {
15
+ type: Object,
16
+ required: true,
17
+ },
18
+ },
19
+
20
+ computed: {
21
+ shouldExpand() {
22
+ const { instance, node } = this
23
+
24
+ return node.isBranch && instance.shouldExpand(node)
25
+ },
26
+
27
+ shouldShow() {
28
+ const { instance, node } = this
29
+
30
+ return instance.shouldShowOptionInMenu(node)
31
+ },
32
+ },
33
+
34
+ methods: {
35
+ renderOption() {
36
+ const { instance, node } = this
37
+ const optionClass = {
38
+ 'rp-treeselect__option': true,
39
+ 'rp-treeselect__option--disabled': node.isDisabled,
40
+ 'rp-treeselect__option--selected': instance.isSelected(node),
41
+ 'rp-treeselect__option--highlight': node.isHighlighted,
42
+ 'rp-treeselect__option--matched': instance.localSearch.active && node.isMatched,
43
+ 'rp-treeselect__option--hide': !this.shouldShow,
44
+ }
45
+
46
+ return (
47
+ <div class={optionClass} onMouseenter={this.handleMouseEnterOption} data-id={node.id}>
48
+ {this.renderArrow()}
49
+ {this.renderLabelContainer([
50
+ this.renderCheckboxContainer([
51
+ this.renderCheckbox(),
52
+ ]),
53
+ this.renderLabel(),
54
+ ])}
55
+ </div>
56
+ )
57
+ },
58
+
59
+ renderSubOptionsList() {
60
+ if (!this.shouldExpand) return null
61
+
62
+ return (
63
+ <div class="rp-treeselect__list">
64
+ {this.renderSubOptions()}
65
+ {this.renderNoChildrenTip()}
66
+ {this.renderLoadingChildrenTip()}
67
+ {this.renderLoadingChildrenErrorTip()}
68
+ </div>
69
+ )
70
+ },
71
+
72
+ renderArrow() {
73
+ const { instance, node } = this
74
+
75
+ if (instance.shouldFlattenOptions && this.shouldShow) return null
76
+
77
+ if (node.isBranch) {
78
+ const transitionProps = {
79
+ props: {
80
+ name: 'rp-treeselect__option-arrow--prepare',
81
+ appear: true,
82
+ },
83
+ }
84
+ const arrowClass = {
85
+ 'rp-treeselect__option-arrow': true,
86
+ 'rp-treeselect__option-arrow--rotated': this.shouldExpand,
87
+ }
88
+
89
+ return (
90
+ <div class="rp-treeselect__option-arrow-container" onMousedown={this.handleMouseDownOnArrow}>
91
+ <transition {...transitionProps}>
92
+ <ArrowIcon class={arrowClass} />
93
+ </transition>
94
+ </div>
95
+ )
96
+ }
97
+
98
+ // For leaf nodes, we render a placeholder to keep its label aligned to
99
+ // branch nodes. Unless there is no branch nodes at all (a normal
100
+ // non-tree select).
101
+ if (/*node.isLeaf && */instance.hasBranchNodes) {
102
+ if (!arrowPlaceholder) arrowPlaceholder = (
103
+ <div class="rp-treeselect__option-arrow-placeholder">&nbsp;</div>
104
+ )
105
+
106
+ return arrowPlaceholder
107
+ }
108
+
109
+ return null
110
+ },
111
+
112
+ renderLabelContainer(children) {
113
+ return (
114
+ <div class="rp-treeselect__label-container" onMousedown={this.handleMouseDownOnLabelContainer}>
115
+ {children}
116
+ </div>
117
+ )
118
+ },
119
+
120
+ renderCheckboxContainer(children) {
121
+ const { instance, node } = this
122
+
123
+ if (instance.single) return null
124
+ if (instance.disableBranchNodes && node.isBranch) return null
125
+
126
+ return (
127
+ <div class="rp-treeselect__checkbox-container">
128
+ {children}
129
+ </div>
130
+ )
131
+ },
132
+
133
+ renderCheckbox() {
134
+ const { instance, node } = this
135
+ const checkedState = instance.forest.checkedStateMap[node.id]
136
+ const checkboxClass = {
137
+ 'rp-treeselect__checkbox': true,
138
+ 'rp-treeselect__checkbox--checked': checkedState === CHECKED,
139
+ 'rp-treeselect__checkbox--indeterminate': checkedState === INDETERMINATE,
140
+ 'rp-treeselect__checkbox--unchecked': checkedState === UNCHECKED,
141
+ 'rp-treeselect__checkbox--disabled': node.isDisabled,
142
+ }
143
+
144
+ if (!checkMark) checkMark = (
145
+ <span class="rp-treeselect__check-mark" />
146
+ )
147
+ if (!minusMark) minusMark = (
148
+ <span class="rp-treeselect__minus-mark" />
149
+ )
150
+
151
+ return (
152
+ <span class={checkboxClass}>
153
+ {checkMark}
154
+ {minusMark}
155
+ </span>
156
+ )
157
+ },
158
+
159
+ renderLabel() {
160
+ const { instance, node } = this
161
+ const shouldShowCount = (
162
+ node.isBranch && (instance.localSearch.active
163
+ ? instance.showCountOnSearchComputed
164
+ : instance.showCount
165
+ )
166
+ )
167
+ const count = shouldShowCount
168
+ ? instance.localSearch.active
169
+ ? instance.localSearch.countMap[node.id][instance.showCountOf]
170
+ : node.count[instance.showCountOf]
171
+ : NaN
172
+ const labelClassName = 'rp-treeselect__label'
173
+ const countClassName = 'rp-treeselect__count'
174
+ const customLabelRenderer = instance.$scopedSlots['option-label']
175
+
176
+ if (customLabelRenderer) return customLabelRenderer({
177
+ node,
178
+ shouldShowCount,
179
+ count,
180
+ labelClassName,
181
+ countClassName,
182
+ })
183
+
184
+ return (
185
+ <label class={labelClassName}>
186
+ {node.label}
187
+ {shouldShowCount && (
188
+ <span class={countClassName}>({count})</span>
189
+ )}
190
+ </label>
191
+ )
192
+ },
193
+
194
+ renderSubOptions() {
195
+ const { node } = this
196
+
197
+ if (!node.childrenStates.isLoaded) return null
198
+
199
+ return node.children.map(childNode => (
200
+ <Option node={childNode} key={childNode.id} />
201
+ ))
202
+ },
203
+
204
+ renderNoChildrenTip() {
205
+ const { instance, node } = this
206
+
207
+ if (!node.childrenStates.isLoaded || node.children.length) return null
208
+
209
+ return (
210
+ <Tip type="no-children" icon="warning">{ instance.noChildrenText }</Tip>
211
+ )
212
+ },
213
+
214
+ renderLoadingChildrenTip() {
215
+ const { instance, node } = this
216
+
217
+ if (!node.childrenStates.isLoading) return null
218
+
219
+ return (
220
+ <Tip type="loading" icon="loader">{ instance.loadingText }</Tip>
221
+ )
222
+ },
223
+
224
+ renderLoadingChildrenErrorTip() {
225
+ const { instance, node } = this
226
+
227
+ if (!node.childrenStates.loadingError) return null
228
+
229
+ return (
230
+ <Tip type="error" icon="error">
231
+ { node.childrenStates.loadingError }
232
+ <a class="rp-treeselect__retry" title={instance.retryTitle} onMousedown={this.handleMouseDownOnRetry}>
233
+ { instance.retryText }
234
+ </a>
235
+ </Tip>
236
+ )
237
+ },
238
+
239
+ handleMouseEnterOption(evt) {
240
+ const { instance, node } = this
241
+
242
+ // Equivalent to `self` modifier.
243
+ // istanbul ignore next
244
+ if (evt.target !== evt.currentTarget) return
245
+
246
+ instance.setCurrentHighlightedOption(node, false)
247
+ },
248
+
249
+ handleMouseDownOnArrow: onLeftClick(function handleMouseDownOnOptionArrow() {
250
+ const { instance, node } = this
251
+
252
+ instance.toggleExpanded(node)
253
+ }),
254
+
255
+ handleMouseDownOnLabelContainer: onLeftClick(function handleMouseDownOnLabelContainer() {
256
+ const { instance, node } = this
257
+
258
+ if (node.isBranch && instance.disableBranchNodes) {
259
+ instance.toggleExpanded(node)
260
+ } else {
261
+ instance.select(node)
262
+ }
263
+ }),
264
+
265
+ handleMouseDownOnRetry: onLeftClick(function handleMouseDownOnRetry() {
266
+ const { instance, node } = this
267
+
268
+ instance.loadChildrenOptions(node)
269
+ }),
270
+ },
271
+
272
+ render() {
273
+ const { node } = this
274
+ const indentLevel = this.instance.shouldFlattenOptions ? 0 : node.level
275
+ const listItemClass = {
276
+ 'rp-treeselect__list-item': true,
277
+ [`rp-treeselect__indent-level-${indentLevel}`]: true,
278
+ }
279
+ const transitionProps = {
280
+ props: {
281
+ name: 'rp-treeselect__list--transition',
282
+ },
283
+ }
284
+
285
+ return (
286
+ <div class={listItemClass}>
287
+ {this.renderOption()}
288
+ {node.isBranch && (
289
+ <transition {...transitionProps}>
290
+ {this.renderSubOptionsList()}
291
+ </transition>
292
+ )}
293
+ </div>
294
+ )
295
+ },
296
+ }
297
+
298
+ // eslint-disable-next-line vue/require-direct-export
299
+ export default Option
300
+ </script>
@@ -0,0 +1,21 @@
1
+ <script>
2
+ export default {
3
+ name: 'rp-treeselect--placeholder',
4
+ inject: [ 'instance' ],
5
+
6
+ render() {
7
+ const { instance } = this
8
+ const placeholderClass = {
9
+ 'rp-treeselect__placeholder': true,
10
+ 'rp-treeselect-helper-zoom-effect-off': true,
11
+ 'rp-treeselect-helper-hide': instance.hasValue || instance.trigger.searchQuery,
12
+ }
13
+
14
+ return (
15
+ <div class={placeholderClass}>
16
+ { instance.placeholder }
17
+ </div>
18
+ )
19
+ },
20
+ }
21
+ </script>
@@ -0,0 +1,34 @@
1
+ <script>
2
+ import Input from './Input'
3
+ import Placeholder from './Placeholder'
4
+
5
+ export default {
6
+ name: 'rp-treeselect--single-value',
7
+ inject: [ 'instance' ],
8
+ methods: {
9
+ renderSingleValueLabel() {
10
+ const { instance } = this
11
+ const node = instance.selectedNodes[0]
12
+
13
+ const customValueLabelRenderer = instance.$scopedSlots['value-label']
14
+ return customValueLabelRenderer
15
+ ? customValueLabelRenderer({ node })
16
+ : node.label
17
+ },
18
+ },
19
+ render() {
20
+ const { instance, $parent: { renderValueContainer } } = this
21
+ const shouldShowValue = instance.hasValue && !instance.trigger.searchQuery
22
+
23
+ return renderValueContainer([
24
+ shouldShowValue && (
25
+ <div class="rp-treeselect__single-value">
26
+ { this.renderSingleValueLabel() }
27
+ </div>
28
+ ),
29
+ <Placeholder />,
30
+ <Input ref="input" />,
31
+ ])
32
+ },
33
+ }
34
+ </script>
@@ -0,0 +1,32 @@
1
+ <script>
2
+ export default {
3
+ name: 'rp-treeselect--tip',
4
+ functional: true,
5
+
6
+ props: {
7
+ type: {
8
+ type: String,
9
+ required: true,
10
+ },
11
+ icon: {
12
+ type: String,
13
+ required: true,
14
+ },
15
+ },
16
+
17
+ render(_, context) {
18
+ const { props, children } = context
19
+
20
+ return (
21
+ <div class={`rp-treeselect__tip rp-treeselect__${props.type}-tip`}>
22
+ <div class="rp-treeselect__icon-container">
23
+ <span class={`rp-treeselect__icon-${props.icon}`} />
24
+ </div>
25
+ <span class={`rp-treeselect__tip-text rp-treeselect__${props.type}-tip-text`}>
26
+ {children}
27
+ </span>
28
+ </div>
29
+ )
30
+ },
31
+ }
32
+ </script>
@@ -0,0 +1,42 @@
1
+ <script>
2
+ import treeselectMixin from '../mixins/treeselectMixin'
3
+ import HiddenFields from './HiddenFields'
4
+ import Control from './Control'
5
+ import Menu from './Menu'
6
+ import MenuPortal from './MenuPortal'
7
+
8
+ export default {
9
+ name: 'rp-treeselect',
10
+ mixins: [ treeselectMixin ],
11
+
12
+ computed: {
13
+ wrapperClass() {
14
+ return {
15
+ 'rp-treeselect': true,
16
+ 'rp-treeselect--single': this.single,
17
+ 'rp-treeselect--multi': this.multiple,
18
+ 'rp-treeselect--searchable': this.searchable,
19
+ 'rp-treeselect--disabled': this.disabled,
20
+ 'rp-treeselect--focused': this.trigger.isFocused,
21
+ 'rp-treeselect--has-value': this.hasValue,
22
+ 'rp-treeselect--open': this.menu.isOpen,
23
+ 'rp-treeselect--open-above': this.menu.placement === 'top',
24
+ 'rp-treeselect--open-below': this.menu.placement === 'bottom',
25
+ 'rp-treeselect--branch-nodes-disabled': this.disableBranchNodes,
26
+ 'rp-treeselect--append-to-body': this.appendToBody,
27
+ 'rp-treeselect--test': true,
28
+ }
29
+ },
30
+ },
31
+
32
+ render() {
33
+ return (
34
+ <div ref="wrapper" class={this.wrapperClass}>
35
+ <HiddenFields />
36
+ <Control ref="control" />
37
+ {this.appendToBody ? <MenuPortal ref="portal" /> : <Menu ref="menu" />}
38
+ </div>
39
+ )
40
+ },
41
+ }
42
+ </script>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 292.362 292.362">
3
+ <path d="M286.935 69.377c-3.614-3.617-7.898-5.424-12.848-5.424H18.274c-4.952 0-9.233 1.807-12.85 5.424C1.807 72.998 0 77.279 0 82.228c0 4.948 1.807 9.229 5.424 12.847l127.907 127.907c3.621 3.617 7.902 5.428 12.85 5.428s9.233-1.811 12.847-5.428L286.935 95.074c3.613-3.617 5.427-7.898 5.427-12.847 0-4.948-1.814-9.229-5.427-12.85z" />
4
+ </svg>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'rp-treeselect--arrow',
10
+ }
11
+ </script>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 348.333 348.333">
3
+ <path d="M336.559 68.611L231.016 174.165l105.543 105.549c15.699 15.705 15.699 41.145 0 56.85-7.844 7.844-18.128 11.769-28.407 11.769-10.296 0-20.581-3.919-28.419-11.769L174.167 231.003 68.609 336.563c-7.843 7.844-18.128 11.769-28.416 11.769-10.285 0-20.563-3.919-28.413-11.769-15.699-15.698-15.699-41.139 0-56.85l105.54-105.549L11.774 68.611c-15.699-15.699-15.699-41.145 0-56.844 15.696-15.687 41.127-15.687 56.829 0l105.563 105.554L279.721 11.767c15.705-15.687 41.139-15.687 56.832 0 15.705 15.699 15.705 41.145.006 56.844z" />
4
+ </svg>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'rp-treeselect--x',
10
+ }
11
+ </script>
@@ -0,0 +1,50 @@
1
+ // Magic value that indicates a root level node.
2
+ export const NO_PARENT_NODE = null
3
+
4
+ // Types of checked state.
5
+ export const UNCHECKED = 0
6
+ export const INDETERMINATE = 1
7
+ export const CHECKED = 2
8
+
9
+ // Types of count number.
10
+ export const ALL_CHILDREN = 'ALL_CHILDREN'
11
+ export const ALL_DESCENDANTS = 'ALL_DESCENDANTS'
12
+ export const LEAF_CHILDREN = 'LEAF_CHILDREN'
13
+ export const LEAF_DESCENDANTS = 'LEAF_DESCENDANTS'
14
+
15
+ // Action types of delayed loading.
16
+ export const LOAD_ROOT_OPTIONS = 'LOAD_ROOT_OPTIONS'
17
+ export const LOAD_CHILDREN_OPTIONS = 'LOAD_CHILDREN_OPTIONS'
18
+ export const ASYNC_SEARCH = 'ASYNC_SEARCH'
19
+
20
+ // Acceptable values of `valueConsistsOf` prop.
21
+ export const ALL = 'ALL'
22
+ export const BRANCH_PRIORITY = 'BRANCH_PRIORITY'
23
+ export const LEAF_PRIORITY = 'LEAF_PRIORITY'
24
+ export const ALL_WITH_INDETERMINATE = 'ALL_WITH_INDETERMINATE'
25
+
26
+ // Acceptable values of `sortValueBy` prop.
27
+ export const ORDER_SELECTED = 'ORDER_SELECTED'
28
+ export const LEVEL = 'LEVEL'
29
+ export const INDEX = 'INDEX'
30
+
31
+ // Key codes look-up table.
32
+ export const KEY_CODES = {
33
+ BACKSPACE: 8,
34
+ ENTER: 13,
35
+ ESCAPE: 27,
36
+ END: 35,
37
+ HOME: 36,
38
+ ARROW_LEFT: 37,
39
+ ARROW_UP: 38,
40
+ ARROW_RIGHT: 39,
41
+ ARROW_DOWN: 40,
42
+ DELETE: 46,
43
+ }
44
+
45
+ // Other constants.
46
+ export const INPUT_DEBOUNCE_DELAY = process.env.NODE_ENV === 'testing'
47
+ ? /* to speed up unit testing */ 10
48
+ : /* istanbul ignore next */ 200
49
+ export const MIN_INPUT_WIDTH = 5
50
+ export const MENU_BUFFER = 40
package/src/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import Treeselect from './components/Treeselect'
2
+ import treeselectMixin from './mixins/treeselectMixin'
3
+ import './style.less'
4
+
5
+ export default Treeselect
6
+ export { Treeselect, treeselectMixin }
7
+ export {
8
+ // Delayed loading.
9
+ LOAD_ROOT_OPTIONS,
10
+ LOAD_CHILDREN_OPTIONS,
11
+ ASYNC_SEARCH,
12
+ } from './constants'
13
+
14
+ export const VERSION = PKG_VERSION