@xy-planning-network/trees 0.15.2 → 0.15.3
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.
- package/dist/trees.es.js +17051 -12088
- package/dist/trees.umd.js +81 -13
- package/package.json +3 -2
- package/src/index.css +10 -0
- package/src/lib-components/forms/Combobox.vue +240 -0
- package/src/lib-components/forms/FileUpload.vue +596 -0
- package/src/lib-components/forms/FormCell.vue +52 -0
- package/src/lib-components/forms/FormDisplay.vue +96 -0
- package/src/lib-components/forms/FormGrid.vue +23 -0
- package/src/lib-components/forms/FormSection.vue +57 -0
- package/src/lib-components/forms/InputDisplay.vue +36 -0
- package/src/lib-components/forms/InputHelp.vue +9 -2
- package/src/lib-components/forms/MultiSelect.vue +404 -0
- package/src/lib-components/forms/RadioCards.vue +14 -1
- package/src/lib-components/forms/RepeaterDisplay.vue +214 -0
- package/src/lib-components/indicators/DismissableBadge.vue +31 -0
- package/types/composables/badge.d.ts +8 -0
- package/types/composables/forms.d.ts +22 -0
- package/types/composables/http.d.ts +8 -0
- package/types/composables/index.d.ts +4 -0
- package/types/composables/useFieldsSchema.d.ts +115 -0
- package/types/composables/useInlineMarkdown.d.ts +20 -0
- package/types/composables/useRepeater.d.ts +116 -0
- package/types/entry.d.ts +2 -1
- package/types/helpers/Bytes.d.ts +14 -0
- package/types/helpers/GetProperty.d.ts +21 -0
- package/types/helpers/SetProperty.d.ts +18 -0
- package/types/lib-components/forms/BaseInput.vue.d.ts +1 -1
- package/types/lib-components/forms/Checkbox.vue.d.ts +1 -1
- package/types/lib-components/forms/Combobox.vue.d.ts +16 -0
- package/types/lib-components/forms/DateRangePicker.vue.d.ts +3 -3
- package/types/lib-components/forms/DateTimeInput.vue.d.ts +1 -1
- package/types/lib-components/forms/FileUpload.vue.d.ts +19 -0
- package/types/lib-components/forms/FormCell.vue.d.ts +15 -0
- package/types/lib-components/forms/FormDisplay.vue.d.ts +30 -0
- package/types/lib-components/forms/FormGrid.vue.d.ts +19 -0
- package/types/lib-components/forms/FormSection.vue.d.ts +16 -0
- package/types/lib-components/forms/InputDisplay.vue.d.ts +14 -0
- package/types/lib-components/forms/MultiCheckboxes.vue.d.ts +1 -1
- package/types/lib-components/forms/MultiSelect.vue.d.ts +22 -0
- package/types/lib-components/forms/NumberInput.vue.d.ts +3 -3
- package/types/lib-components/forms/Radio.vue.d.ts +1 -1
- package/types/lib-components/forms/RadioCards.vue.d.ts +3 -0
- package/types/lib-components/forms/RangeCalendar.vue.d.ts +1 -1
- package/types/lib-components/forms/RepeaterDisplay.vue.d.ts +29 -0
- package/types/lib-components/forms/Select.vue.d.ts +1 -1
- package/types/lib-components/forms/TextArea.vue.d.ts +1 -1
- package/types/lib-components/forms/YesOrNoRadio.vue.d.ts +1 -1
- package/types/lib-components/index.d.ts +54 -89
- package/types/lib-components/indicators/DismissableBadge.vue.d.ts +13 -0
- package/types/lib-components/overlays/ContentModal.vue.d.ts +1 -1
- package/types/lib-components/overlays/Modal.vue.d.ts +1 -1
- package/types/lib-components/overlays/Slideover.vue.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xy-planning-network/trees",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.3",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -62,12 +62,13 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@floating-ui/vue": "^1.0.1",
|
|
65
|
-
"@headlessui/vue": "^1.
|
|
65
|
+
"@headlessui/vue": "^1.7.23",
|
|
66
66
|
"@heroicons/vue": "^2.2.0",
|
|
67
67
|
"@maskito/core": "^3.5.0",
|
|
68
68
|
"@maskito/kit": "^3.5.0",
|
|
69
69
|
"@maskito/vue": "^3.5.0",
|
|
70
70
|
"axios": "^1.19.0",
|
|
71
|
+
"marked": "^18.0.14",
|
|
71
72
|
"reka-ui": "^2.9.9"
|
|
72
73
|
},
|
|
73
74
|
"peerDependencies": {
|
package/src/index.css
CHANGED
|
@@ -183,6 +183,11 @@
|
|
|
183
183
|
@apply inline-flex justify-center items-center py-2.5 border-b-2 border-b-red-700 text-base font-display font-semibold shadow-none text-neutral-800 hover:text-red-700 hover:border-b-transparent focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-xy-blue-500 disabled:text-neutral-800 disabled:border-b-red-700 disabled:opacity-70 disabled:cursor-not-allowed transition-colors ease-linear duration-150;
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
/* Combobox */
|
|
187
|
+
.xy-combobox .xy-combobox-input {
|
|
188
|
+
@apply shadow-none border-none bg-transparent focus:ring-0 p-0;
|
|
189
|
+
}
|
|
190
|
+
|
|
186
191
|
/* Header classes */
|
|
187
192
|
.h1 {
|
|
188
193
|
@apply text-3xl leading-9 font-semibold;
|
|
@@ -229,6 +234,11 @@
|
|
|
229
234
|
@apply font-medium border-b-2 border-b-xy-blue hover:border-b-transparent hover:text-xy-blue;
|
|
230
235
|
}
|
|
231
236
|
|
|
237
|
+
/* MultiSelect */
|
|
238
|
+
.xy-multiselect .xy-multiselect-input {
|
|
239
|
+
@apply shadow-none border-none bg-transparent focus:ring-0 p-0;
|
|
240
|
+
}
|
|
241
|
+
|
|
232
242
|
/* RangeCalendar */
|
|
233
243
|
|
|
234
244
|
/* Calendar Prev/Next navigation */
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref } from "vue"
|
|
3
|
+
import {
|
|
4
|
+
Combobox,
|
|
5
|
+
ComboboxButton,
|
|
6
|
+
ComboboxInput,
|
|
7
|
+
ComboboxLabel,
|
|
8
|
+
ComboboxOption,
|
|
9
|
+
ComboboxOptions,
|
|
10
|
+
} from "@headlessui/vue"
|
|
11
|
+
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/solid"
|
|
12
|
+
import { useInputField, type OptionsInput } from "@/composables/forms"
|
|
13
|
+
import InputHelp from "@/lib-components/forms/InputHelp.vue"
|
|
14
|
+
import InputError from "@/lib-components/forms/InputError.vue"
|
|
15
|
+
import InputLabel from "@/lib-components/forms/InputLabel.vue"
|
|
16
|
+
|
|
17
|
+
// NOTE(spk): What this doesn't do:
|
|
18
|
+
//
|
|
19
|
+
// - allow "custom-values" i.e. user supplied values
|
|
20
|
+
// - support async options based on query
|
|
21
|
+
// - limited support for HTML5 input events
|
|
22
|
+
// - grouped options
|
|
23
|
+
// - no deselection - it works like a <select />, but is searchable
|
|
24
|
+
|
|
25
|
+
defineOptions({
|
|
26
|
+
inheritAttrs: false,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const props = withDefaults(defineProps<OptionsInput>(), {
|
|
30
|
+
help: "",
|
|
31
|
+
label: "",
|
|
32
|
+
modelValue: undefined,
|
|
33
|
+
placeholder: "Select an option",
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const modelState = defineModel<OptionsInput["modelValue"]>({
|
|
37
|
+
default: null,
|
|
38
|
+
required: false,
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const {
|
|
42
|
+
aria,
|
|
43
|
+
errorState,
|
|
44
|
+
inputID,
|
|
45
|
+
isDisabled,
|
|
46
|
+
isRequired,
|
|
47
|
+
nameAttr,
|
|
48
|
+
onInvalid,
|
|
49
|
+
validate,
|
|
50
|
+
} = useInputField(props)
|
|
51
|
+
|
|
52
|
+
const maxOptions = 50
|
|
53
|
+
|
|
54
|
+
const query = ref("")
|
|
55
|
+
|
|
56
|
+
const filteredOptions = computed(() => {
|
|
57
|
+
return query.value === ""
|
|
58
|
+
? props.options
|
|
59
|
+
: props.options.filter((opt) => {
|
|
60
|
+
return (
|
|
61
|
+
opt.label?.toLowerCase().includes(query.value.toLowerCase()) ||
|
|
62
|
+
opt.help?.toLowerCase().includes(query.value.toLowerCase())
|
|
63
|
+
)
|
|
64
|
+
})
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
const renderableOptions = computed(() => {
|
|
68
|
+
return filteredOptions.value.slice(0, maxOptions)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
const totalOptions = computed(() => {
|
|
72
|
+
return filteredOptions.value.length
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const selectedOption = computed(() => {
|
|
76
|
+
return props.options.find((opt) => {
|
|
77
|
+
return opt.value === modelState.value
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
const isPaginated = computed(() => {
|
|
82
|
+
return totalOptions.value > maxOptions
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const onUpdate = (val: unknown) => {
|
|
86
|
+
if (val) {
|
|
87
|
+
query.value = ""
|
|
88
|
+
errorState.value = ""
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// NOTE(spk): when @headlessui/Combobox is not in multiple mode mousedown
|
|
93
|
+
// events that bubble outside the parent are picked up
|
|
94
|
+
// by the "outside click" event that closes active modals.
|
|
95
|
+
// It's not expected that this event should need to be captured
|
|
96
|
+
// outside the component - @mousedown.stop prevents the event from
|
|
97
|
+
// bubbling outside the parent.
|
|
98
|
+
</script>
|
|
99
|
+
|
|
100
|
+
<template>
|
|
101
|
+
<div class="xy-combobox relative" @mousedown.stop>
|
|
102
|
+
<Combobox
|
|
103
|
+
v-model="modelState"
|
|
104
|
+
as="div"
|
|
105
|
+
:disabled="isDisabled"
|
|
106
|
+
:name="nameAttr"
|
|
107
|
+
@update:model-value="onUpdate"
|
|
108
|
+
>
|
|
109
|
+
<ComboboxLabel
|
|
110
|
+
v-if="label"
|
|
111
|
+
:id="aria.labelledby"
|
|
112
|
+
:as="InputLabel"
|
|
113
|
+
class="mb-2"
|
|
114
|
+
:label="label"
|
|
115
|
+
:required="isRequired"
|
|
116
|
+
/>
|
|
117
|
+
|
|
118
|
+
<div
|
|
119
|
+
:class="[
|
|
120
|
+
'relative w-full rounded-md border-0 py-2 pl-3 pr-1.5 shadow-sm ring-1 ring-inset has-[input:focus]:ring-2',
|
|
121
|
+
'has-[input:disabled]:cursor-not-allowed has-[input:disabled]:bg-gray-50 has-[input:disabled]:text-gray-700 has-[input:disabled]:ring-gray-200',
|
|
122
|
+
errorState
|
|
123
|
+
? 'text-red-900 ring-red-700 has-[input:focus]:ring-red-700'
|
|
124
|
+
: 'text-gray-900 ring-gray-300 has-[input:focus]:ring-xy-blue-500',
|
|
125
|
+
]"
|
|
126
|
+
>
|
|
127
|
+
<div class="pr-10">
|
|
128
|
+
<ComboboxButton as="div" class="leading-none" aria-hidden>
|
|
129
|
+
<ComboboxInput
|
|
130
|
+
:id="inputID"
|
|
131
|
+
:aria-labelledby="aria.labelledby"
|
|
132
|
+
:aria-describedby="aria.describedby"
|
|
133
|
+
:aria-errormessage="aria.errormessage"
|
|
134
|
+
:class="[
|
|
135
|
+
'xy-combobox-input truncate w-full sm:text-sm sm:leading-6',
|
|
136
|
+
errorState
|
|
137
|
+
? 'placeholder:text-red-300'
|
|
138
|
+
: 'placeholder:text-gray-400',
|
|
139
|
+
]"
|
|
140
|
+
:disabled="isDisabled"
|
|
141
|
+
:display-value="() => selectedOption?.label || ''"
|
|
142
|
+
:placeholder="placeholder"
|
|
143
|
+
@change="query = $event.target.value"
|
|
144
|
+
/>
|
|
145
|
+
</ComboboxButton>
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<ComboboxButton
|
|
149
|
+
class="absolute inset-y-0 right-0 flex items-center px-2 focus:outline-none"
|
|
150
|
+
>
|
|
151
|
+
<ChevronUpDownIcon class="h-5 w-5 text-gray-500" aria-hidden="true" />
|
|
152
|
+
</ComboboxButton>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<ComboboxOptions
|
|
156
|
+
class="absolute z-[5] mt-1 max-h-60 w-full overflow-auto rounded-md bg-white text-base shadow-lg ring-1 ring-black/5 focus:outline-none sm:text-sm scroll-pt-10"
|
|
157
|
+
>
|
|
158
|
+
<li
|
|
159
|
+
v-if="isPaginated"
|
|
160
|
+
class="bg-neutral-100 font-medium border-b border-neutral-200 sticky top-0 py-1.5 px-3 z-[5]"
|
|
161
|
+
>
|
|
162
|
+
Showing {{ renderableOptions.length }} of {{ totalOptions }} results.
|
|
163
|
+
</li>
|
|
164
|
+
|
|
165
|
+
<ComboboxOption
|
|
166
|
+
v-for="option in renderableOptions"
|
|
167
|
+
v-slot="{
|
|
168
|
+
active,
|
|
169
|
+
disabled,
|
|
170
|
+
selected,
|
|
171
|
+
}: {
|
|
172
|
+
active: boolean
|
|
173
|
+
disabled: boolean
|
|
174
|
+
selected: boolean
|
|
175
|
+
}"
|
|
176
|
+
:key="option.value"
|
|
177
|
+
:value="option.value"
|
|
178
|
+
:disabled="isDisabled || option.disabled"
|
|
179
|
+
>
|
|
180
|
+
<div
|
|
181
|
+
:class="[
|
|
182
|
+
'relative select-none py-2 pl-8 pr-4',
|
|
183
|
+
active ? 'text-gray-900 bg-neutral-50 outline-none' : '',
|
|
184
|
+
disabled ? 'text-gray-500 cursor-not-allowed' : 'cursor-pointer',
|
|
185
|
+
]"
|
|
186
|
+
>
|
|
187
|
+
<div>
|
|
188
|
+
<div
|
|
189
|
+
:class="[
|
|
190
|
+
'block truncate',
|
|
191
|
+
selected ? 'font-semibold' : 'font-medium',
|
|
192
|
+
]"
|
|
193
|
+
>
|
|
194
|
+
{{ option.label }}
|
|
195
|
+
</div>
|
|
196
|
+
<div v-if="option.help" class="block truncate">
|
|
197
|
+
{{ option.help }}
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
<span
|
|
202
|
+
v-if="selected"
|
|
203
|
+
class="absolute inset-y-0 left-0 flex items-center pl-1.5 text-xy-blue-500"
|
|
204
|
+
>
|
|
205
|
+
<CheckIcon class="h-5 w-5" aria-hidden="true" />
|
|
206
|
+
</span>
|
|
207
|
+
</div>
|
|
208
|
+
</ComboboxOption>
|
|
209
|
+
</ComboboxOptions>
|
|
210
|
+
</Combobox>
|
|
211
|
+
|
|
212
|
+
<InputHelp
|
|
213
|
+
v-if="help"
|
|
214
|
+
:id="aria.describedby"
|
|
215
|
+
class="mt-1"
|
|
216
|
+
tag="p"
|
|
217
|
+
:text="help"
|
|
218
|
+
/>
|
|
219
|
+
|
|
220
|
+
<InputError :id="aria.errormessage" class="mt-1" :text="errorState" />
|
|
221
|
+
|
|
222
|
+
<!--Hidden input for validation-->
|
|
223
|
+
<select
|
|
224
|
+
v-model="modelState"
|
|
225
|
+
aria-hidden
|
|
226
|
+
class="sr-only top-1 left-1"
|
|
227
|
+
:disabled="isDisabled"
|
|
228
|
+
:required="isRequired"
|
|
229
|
+
:tabindex="errorState ? undefined : -1"
|
|
230
|
+
@change="validate"
|
|
231
|
+
@invalid="onInvalid"
|
|
232
|
+
>
|
|
233
|
+
<option
|
|
234
|
+
v-for="option in options"
|
|
235
|
+
:key="option.value"
|
|
236
|
+
:value="option.value"
|
|
237
|
+
/>
|
|
238
|
+
</select>
|
|
239
|
+
</div>
|
|
240
|
+
</template>
|