@xy-planning-network/trees 0.4.0-rc-6 → 0.4.1
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/README.md +236 -53
- package/dist/trees.es.js +910 -274
- package/dist/trees.umd.js +6 -6
- package/package.json +9 -6
- package/src/lib-components/forms/BaseInput.vue +83 -0
- package/src/lib-components/forms/Checkbox.vue +46 -0
- package/src/lib-components/forms/DateRangePicker.vue +65 -0
- package/src/lib-components/forms/InputHelp.vue +24 -0
- package/src/lib-components/forms/InputLabel.vue +23 -0
- package/src/lib-components/forms/MultiCheckboxes.vue +55 -0
- package/src/lib-components/forms/Radio.vue +58 -0
- package/src/lib-components/forms/Select.vue +65 -0
- package/src/lib-components/forms/TextArea.vue +50 -0
- package/src/lib-components/forms/Toggle.vue +25 -0
- package/src/lib-components/forms/YesOrNoRadio.vue +70 -0
- package/src/lib-components/layout/DateFilter.vue +54 -0
- package/src/lib-components/layout/SidebarLayout.vue +239 -0
- package/src/lib-components/layout/StackedLayout.vue +172 -0
- package/src/lib-components/lists/Cards.vue +33 -0
- package/src/lib-components/lists/DetailList.vue +114 -0
- package/src/lib-components/lists/DownloadCell.vue +12 -0
- package/src/lib-components/lists/StaticTable.vue +83 -0
- package/src/lib-components/lists/Table.vue +291 -0
- package/src/lib-components/navigation/ActionsDropdown.vue +78 -0
- package/src/lib-components/navigation/Paginator.vue +115 -0
- package/src/lib-components/navigation/Steps.vue +83 -0
- package/src/lib-components/navigation/Tabs.vue +92 -0
- package/src/lib-components/overlays/ContentModal.vue +95 -0
- package/src/lib-components/overlays/Flash.vue +131 -0
- package/src/lib-components/overlays/Modal.vue +133 -0
- package/src/lib-components/overlays/Popover/Popover.vue +109 -0
- package/src/lib-components/overlays/Popover/PopoverContent.vue +8 -0
- package/src/lib-components/overlays/Slideover.vue +87 -0
- package/src/lib-components/overlays/Spinner.vue +149 -0
- package/src/lib-components/overlays/Tooltip.vue +31 -0
- package/{dist → types}/api/base.d.ts +0 -0
- package/types/components.d.ts +12 -0
- package/types/composables/date.d.ts +4 -0
- package/types/composables/nav.d.ts +13 -0
- package/types/composables/overlay.d.ts +4 -0
- package/types/composables/table.d.ts +32 -0
- package/types/composables/user.d.ts +6 -0
- package/{dist → types}/entry.d.ts +0 -0
- package/types/global.d.ts +13 -0
- package/{dist → types}/helpers/Uniques.d.ts +0 -0
- package/{dist → types}/lib-components/forms/BaseInput.vue.d.ts +0 -0
- package/{dist → types}/lib-components/forms/Checkbox.vue.d.ts +0 -0
- package/{dist → types}/lib-components/forms/DateRangePicker.vue.d.ts +0 -0
- package/{dist → types}/lib-components/forms/InputHelp.vue.d.ts +0 -0
- package/{dist → types}/lib-components/forms/InputLabel.vue.d.ts +0 -0
- package/{dist → types}/lib-components/forms/MultiCheckboxes.vue.d.ts +0 -0
- package/{dist → types}/lib-components/forms/Radio.vue.d.ts +0 -0
- package/{dist → types}/lib-components/forms/Select.vue.d.ts +2 -2
- package/{dist → types}/lib-components/forms/TextArea.vue.d.ts +0 -0
- package/{dist → types}/lib-components/forms/Toggle.vue.d.ts +0 -0
- package/{dist → types}/lib-components/forms/YesOrNoRadio.vue.d.ts +0 -0
- package/{dist → types}/lib-components/index.d.ts +9 -9
- package/{dist → types}/lib-components/layout/DateFilter.vue.d.ts +1 -4
- package/{dist → types}/lib-components/layout/SidebarLayout.vue.d.ts +1 -1
- package/{dist → types}/lib-components/layout/StackedLayout.vue.d.ts +2 -2
- package/{dist → types}/lib-components/lists/Cards.vue.d.ts +0 -0
- package/{dist → types}/lib-components/lists/DetailList.vue.d.ts +0 -0
- package/{dist → types}/lib-components/lists/DownloadCell.vue.d.ts +0 -0
- package/{dist → types}/lib-components/lists/StaticTable.vue.d.ts +1 -1
- package/{dist → types}/lib-components/lists/Table.vue.d.ts +1 -1
- package/{dist → types}/lib-components/navigation/ActionsDropdown.vue.d.ts +2 -2
- package/{dist → types}/lib-components/navigation/Paginator.vue.d.ts +1 -6
- package/{dist → types}/lib-components/navigation/Steps.vue.d.ts +0 -0
- package/{dist → types}/lib-components/navigation/Tabs.vue.d.ts +0 -0
- package/{dist → types}/lib-components/overlays/ContentModal.vue.d.ts +0 -0
- package/{dist/lib-components/overlays/Spinner.vue.d.ts → types/lib-components/overlays/Flash.vue.d.ts} +0 -0
- package/{dist → types}/lib-components/overlays/Modal.vue.d.ts +0 -0
- package/types/lib-components/overlays/Popover/Popover.vue.d.ts +15 -0
- package/types/lib-components/overlays/Popover/PopoverContent.vue.d.ts +2 -0
- package/{dist → types}/lib-components/overlays/Slideover.vue.d.ts +0 -0
- package/{dist/lib-components/overlays/Flash.vue.d.ts → types/lib-components/overlays/Spinner.vue.d.ts} +0 -4
- package/types/lib-components/overlays/Tooltip.vue.d.ts +16 -0
- package/dist/types/components.d.ts +0 -6
- package/dist/types/global.d.ts +0 -10
- package/dist/types/nav.d.ts +0 -8
- package/dist/types/table.d.ts +0 -36
- package/dist/types/users.d.ts +0 -10
package/package.json
CHANGED
|
@@ -1,31 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xy-planning-network/trees",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "github:xy-planning-network/trees",
|
|
7
7
|
"files": [
|
|
8
8
|
"config/*",
|
|
9
9
|
"dist/*",
|
|
10
|
-
"src/**/*.css"
|
|
10
|
+
"src/**/*.css",
|
|
11
|
+
"src/**/*.vue",
|
|
12
|
+
"types/*"
|
|
11
13
|
],
|
|
12
14
|
"main": "dist/trees.es.js",
|
|
13
15
|
"module": "dist/trees.es.js",
|
|
14
16
|
"style": "src/index.css",
|
|
15
17
|
"unpkg": "dist/trees.umd.js",
|
|
16
|
-
"types": "
|
|
18
|
+
"types": "types/entry.d.ts",
|
|
17
19
|
"sideEffects": [
|
|
18
20
|
"*.css",
|
|
19
21
|
"*.vue"
|
|
20
22
|
],
|
|
21
23
|
"scripts": {
|
|
22
24
|
"dev": "vite",
|
|
23
|
-
"build": "vite build && vue-tsc -p src && npm run copy:types && tsc-alias -p src/tsconfig.json",
|
|
25
|
+
"build": "vite build && vue-tsc -p src --emitDeclarationOnly && npm run copy:types && tsc-alias -p src/tsconfig.json",
|
|
24
26
|
"build:docs": "vue-tsc -p dev --noEmit && vite build --config vite.docs.config.ts",
|
|
25
|
-
"copy:types": "copyfiles -f ./src
|
|
27
|
+
"copy:types": "copyfiles -f ./src/*.d.ts ./types",
|
|
26
28
|
"lint": "eslint --ext .js,.ts,.vue src",
|
|
27
29
|
"lint:fix": "eslint --fix --ext .js,.ts,.vue src dev && prettier -w -u src dev",
|
|
28
|
-
"preview": "vite preview --config vite.docs.config.ts"
|
|
30
|
+
"preview": "vite preview --config vite.docs.config.ts",
|
|
31
|
+
"typecheck": "vue-tsc -p src --noEmit"
|
|
29
32
|
},
|
|
30
33
|
"devDependencies": {
|
|
31
34
|
"@types/node": "^16.11.13",
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Uniques from "@/helpers/Uniques"
|
|
3
|
+
import InputLabel from "./InputLabel.vue"
|
|
4
|
+
import InputHelp from "./InputHelp.vue"
|
|
5
|
+
import { computed, useAttrs } from "vue"
|
|
6
|
+
|
|
7
|
+
const attrs = useAttrs()
|
|
8
|
+
const props = withDefaults(
|
|
9
|
+
defineProps<{
|
|
10
|
+
type: string
|
|
11
|
+
help?: string
|
|
12
|
+
label?: string
|
|
13
|
+
modelValue?: string | number
|
|
14
|
+
}>(),
|
|
15
|
+
{
|
|
16
|
+
help: "",
|
|
17
|
+
label: "",
|
|
18
|
+
modelValue: "",
|
|
19
|
+
}
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
const emit = defineEmits(["update:modelValue"])
|
|
23
|
+
|
|
24
|
+
const uuid = (attrs.id as string) || Uniques.CreateIdAttribute()
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* common text based inputs
|
|
28
|
+
*/
|
|
29
|
+
const textInputTypes = [
|
|
30
|
+
"date",
|
|
31
|
+
"datetime-local",
|
|
32
|
+
"email",
|
|
33
|
+
"month",
|
|
34
|
+
"number",
|
|
35
|
+
"password",
|
|
36
|
+
"search",
|
|
37
|
+
"tel",
|
|
38
|
+
"text",
|
|
39
|
+
"time",
|
|
40
|
+
"url",
|
|
41
|
+
"week",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* determine if this input is a common text based input
|
|
46
|
+
*/
|
|
47
|
+
const isTextType = computed((): boolean => {
|
|
48
|
+
return typeof props.type === "string" && textInputTypes.includes(props.type)
|
|
49
|
+
})
|
|
50
|
+
</script>
|
|
51
|
+
<template>
|
|
52
|
+
<InputLabel
|
|
53
|
+
class="block"
|
|
54
|
+
:id="`${uuid}-label`"
|
|
55
|
+
:for="uuid"
|
|
56
|
+
:label="label"
|
|
57
|
+
></InputLabel>
|
|
58
|
+
<input
|
|
59
|
+
:aria-labelledby="label ? `${uuid}-label` : undefined"
|
|
60
|
+
:aria-describedby="help ? `${uuid}-help` : undefined"
|
|
61
|
+
:class="[
|
|
62
|
+
...['mt-1', 'sm:text-sm'],
|
|
63
|
+
...(isTextType
|
|
64
|
+
? [
|
|
65
|
+
'block',
|
|
66
|
+
'shadow-sm',
|
|
67
|
+
'focus:ring-blue-500',
|
|
68
|
+
'focus:border-blue-500',
|
|
69
|
+
'border-gray-600',
|
|
70
|
+
'rounded-md',
|
|
71
|
+
'w-full',
|
|
72
|
+
]
|
|
73
|
+
: []),
|
|
74
|
+
]"
|
|
75
|
+
:id="uuid"
|
|
76
|
+
:placeholder="label"
|
|
77
|
+
:type="type"
|
|
78
|
+
:value="modelValue"
|
|
79
|
+
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
|
|
80
|
+
v-bind="$attrs"
|
|
81
|
+
/>
|
|
82
|
+
<InputHelp :id="`${uuid}-help`" :text="help"></InputHelp>
|
|
83
|
+
</template>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import InputLabel from "./InputLabel.vue"
|
|
3
|
+
import Uniques from "@/helpers/Uniques"
|
|
4
|
+
import { useAttrs } from "vue"
|
|
5
|
+
|
|
6
|
+
// TODO: checkbox should support the help text prop - possibly as a tooltip
|
|
7
|
+
// TODO: aria-labelledby may be superfluous here since the input is wrapped in a label
|
|
8
|
+
withDefaults(
|
|
9
|
+
defineProps<{
|
|
10
|
+
label?: string
|
|
11
|
+
modelValue: boolean
|
|
12
|
+
}>(),
|
|
13
|
+
{
|
|
14
|
+
label: "",
|
|
15
|
+
}
|
|
16
|
+
)
|
|
17
|
+
const emits = defineEmits(["update:modelValue"])
|
|
18
|
+
const attrs = useAttrs()
|
|
19
|
+
const uuid = (attrs.id as string) || Uniques.CreateIdAttribute()
|
|
20
|
+
</script>
|
|
21
|
+
<template>
|
|
22
|
+
<div>
|
|
23
|
+
<label class="inline-flex items-center">
|
|
24
|
+
<input
|
|
25
|
+
:aria-labelledby="label ? `${uuid}-label` : undefined"
|
|
26
|
+
:checked="modelValue"
|
|
27
|
+
class="focus:ring-blue-500 h-4 w-4 text-blue-500 border-gray-600 rounded disabled:opacity-50 disabled:cursor-not-allowed"
|
|
28
|
+
:id="uuid"
|
|
29
|
+
type="checkbox"
|
|
30
|
+
v-bind="{
|
|
31
|
+
...$attrs,
|
|
32
|
+
onChange: ($event) => {
|
|
33
|
+
emits('update:modelValue', ($event.target as HTMLInputElement).checked)
|
|
34
|
+
},
|
|
35
|
+
}"
|
|
36
|
+
/>
|
|
37
|
+
<InputLabel
|
|
38
|
+
class="ml-2"
|
|
39
|
+
:id="`${uuid}-label`"
|
|
40
|
+
:for="uuid"
|
|
41
|
+
:label="label"
|
|
42
|
+
tag="span"
|
|
43
|
+
></InputLabel>
|
|
44
|
+
</label>
|
|
45
|
+
</div>
|
|
46
|
+
</template>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Uniques from "@/helpers/Uniques"
|
|
3
|
+
import flatpickr from "flatpickr"
|
|
4
|
+
import "flatpickr/dist/flatpickr.min.css"
|
|
5
|
+
import { onMounted, useAttrs } from "vue"
|
|
6
|
+
import BaseInput from "./BaseInput.vue"
|
|
7
|
+
|
|
8
|
+
const props = withDefaults(
|
|
9
|
+
defineProps<{
|
|
10
|
+
modelValue: {
|
|
11
|
+
minDate: number
|
|
12
|
+
maxDate: number
|
|
13
|
+
}
|
|
14
|
+
startDate?: number
|
|
15
|
+
label?: string
|
|
16
|
+
help?: string
|
|
17
|
+
}>(),
|
|
18
|
+
{
|
|
19
|
+
startDate: 0,
|
|
20
|
+
label: "",
|
|
21
|
+
help: "",
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
const emits = defineEmits(["update:modelValue"])
|
|
26
|
+
const attrs = useAttrs()
|
|
27
|
+
const uuid = (attrs.id as string) || Uniques.CreateIdAttribute()
|
|
28
|
+
|
|
29
|
+
const updateModelValue = (value: { minDate: number; maxDate: number }) => {
|
|
30
|
+
emits("update:modelValue", value)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
onMounted(() => {
|
|
34
|
+
flatpickr(`#${uuid}`, {
|
|
35
|
+
dateFormat: "m-d-Y",
|
|
36
|
+
mode: "range",
|
|
37
|
+
maxDate: new Date(), // So far, we cannot have options past today for ranges
|
|
38
|
+
minDate: props.startDate,
|
|
39
|
+
onClose: (selectedDates) => {
|
|
40
|
+
if (selectedDates.length === 2) {
|
|
41
|
+
updateModelValue({
|
|
42
|
+
minDate: selectedDates[0].setUTCHours(0, 0, 0, 0) / 1000,
|
|
43
|
+
maxDate: Math.floor(
|
|
44
|
+
selectedDates[1].setUTCHours(23, 59, 59, 999) / 1000
|
|
45
|
+
),
|
|
46
|
+
})
|
|
47
|
+
} else if (selectedDates.length === 0) {
|
|
48
|
+
updateModelValue({
|
|
49
|
+
minDate: 0,
|
|
50
|
+
maxDate: 0,
|
|
51
|
+
})
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
})
|
|
56
|
+
</script>
|
|
57
|
+
<template>
|
|
58
|
+
<BaseInput
|
|
59
|
+
type="text"
|
|
60
|
+
placeholder="mm-dd-yyyy range"
|
|
61
|
+
:id="uuid"
|
|
62
|
+
:label="label"
|
|
63
|
+
:help="help"
|
|
64
|
+
></BaseInput>
|
|
65
|
+
</template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
withDefaults(
|
|
3
|
+
defineProps<{
|
|
4
|
+
tag?: string
|
|
5
|
+
text?: string
|
|
6
|
+
}>(),
|
|
7
|
+
{
|
|
8
|
+
tag: "div",
|
|
9
|
+
text: "",
|
|
10
|
+
}
|
|
11
|
+
)
|
|
12
|
+
</script>
|
|
13
|
+
<template>
|
|
14
|
+
<component
|
|
15
|
+
:is="tag"
|
|
16
|
+
v-if="text"
|
|
17
|
+
v-bind="{
|
|
18
|
+
...$attrs,
|
|
19
|
+
class: 'mt-2 text-sm leading-snug font-semibold text-gray-700',
|
|
20
|
+
}"
|
|
21
|
+
>
|
|
22
|
+
{{ text }}
|
|
23
|
+
</component>
|
|
24
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
withDefaults(
|
|
3
|
+
defineProps<{
|
|
4
|
+
label?: string
|
|
5
|
+
tag?: string
|
|
6
|
+
}>(),
|
|
7
|
+
{
|
|
8
|
+
label: "",
|
|
9
|
+
tag: "label",
|
|
10
|
+
}
|
|
11
|
+
)
|
|
12
|
+
</script>
|
|
13
|
+
<template>
|
|
14
|
+
<component
|
|
15
|
+
:is="tag"
|
|
16
|
+
v-if="label"
|
|
17
|
+
v-bind="{
|
|
18
|
+
...$attrs,
|
|
19
|
+
class: 'block my-1 text-sm font-semibold leading-snug text-gray-900',
|
|
20
|
+
}"
|
|
21
|
+
>{{ label }}</component
|
|
22
|
+
>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Uniques from "@/helpers/Uniques"
|
|
3
|
+
import { ref, useAttrs } from "vue"
|
|
4
|
+
import InputLabel from "./InputLabel.vue"
|
|
5
|
+
|
|
6
|
+
// TODO: checkbox should support the help text prop - possibly as a tooltip
|
|
7
|
+
// TODO: aria-labelledby may be superfluous here since the input is wrapped in a label
|
|
8
|
+
|
|
9
|
+
const props = withDefaults(
|
|
10
|
+
defineProps<{
|
|
11
|
+
options: {
|
|
12
|
+
label: string
|
|
13
|
+
value: string
|
|
14
|
+
}[]
|
|
15
|
+
legend?: string
|
|
16
|
+
modelValue: string[]
|
|
17
|
+
}>(),
|
|
18
|
+
{
|
|
19
|
+
legend: "",
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const emits = defineEmits(["update:modelValue"])
|
|
24
|
+
const attrs = useAttrs()
|
|
25
|
+
const uuid = (attrs.id as string) || Uniques.CreateIdAttribute()
|
|
26
|
+
const model = ref<string[]>(props.modelValue)
|
|
27
|
+
</script>
|
|
28
|
+
<template>
|
|
29
|
+
<fieldset>
|
|
30
|
+
<InputLabel class="block mb-0" :label="legend" tag="legend"></InputLabel>
|
|
31
|
+
<div class="mt-4" v-for="(option, index) in options" :key="option.value">
|
|
32
|
+
<label class="inline-flex items-center">
|
|
33
|
+
<input
|
|
34
|
+
type="checkbox"
|
|
35
|
+
class="focus:ring-blue-500 h-4 w-4 text-xy-blue border-gray-600 rounded disabled:opacity-50 disabled:cursor-not-allowed"
|
|
36
|
+
:id="`${uuid}-${index}`"
|
|
37
|
+
:value="option.value"
|
|
38
|
+
v-model="model"
|
|
39
|
+
v-bind="{
|
|
40
|
+
...$attrs,
|
|
41
|
+
onChange: () => {
|
|
42
|
+
emits('update:modelValue', model)
|
|
43
|
+
},
|
|
44
|
+
}"
|
|
45
|
+
/>
|
|
46
|
+
<InputLabel
|
|
47
|
+
class="ml-2"
|
|
48
|
+
:for="`${uuid}-${index}`"
|
|
49
|
+
:label="option.label"
|
|
50
|
+
tag="span"
|
|
51
|
+
></InputLabel>
|
|
52
|
+
</label>
|
|
53
|
+
</div>
|
|
54
|
+
</fieldset>
|
|
55
|
+
</template>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Uniques from "@/helpers/Uniques"
|
|
3
|
+
import { useAttrs } from "vue"
|
|
4
|
+
import InputLabel from "./InputLabel.vue"
|
|
5
|
+
|
|
6
|
+
// TODO: add horizontal layout support
|
|
7
|
+
const props = withDefaults(
|
|
8
|
+
defineProps<{
|
|
9
|
+
options: {
|
|
10
|
+
label: string
|
|
11
|
+
value: string
|
|
12
|
+
}[]
|
|
13
|
+
legend?: string
|
|
14
|
+
modelValue?: string
|
|
15
|
+
vertical?: boolean
|
|
16
|
+
}>(),
|
|
17
|
+
{
|
|
18
|
+
legend: "",
|
|
19
|
+
modelValue: "",
|
|
20
|
+
vertical: true,
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
const emits = defineEmits(["update:modelValue"])
|
|
24
|
+
const attrs = useAttrs()
|
|
25
|
+
const uuid = (attrs.id as string) || Uniques.CreateIdAttribute()
|
|
26
|
+
</script>
|
|
27
|
+
<template>
|
|
28
|
+
<fieldset class="mt-1 space-y-2">
|
|
29
|
+
<InputLabel class="block" :label="legend" tag="legend"></InputLabel>
|
|
30
|
+
<component
|
|
31
|
+
v-for="(option, index) in options"
|
|
32
|
+
:key="option.value"
|
|
33
|
+
:is="props.vertical ? 'div' : 'span'"
|
|
34
|
+
>
|
|
35
|
+
<label
|
|
36
|
+
class="inline-flex items-center"
|
|
37
|
+
:class="{ 'cursor-not-allowed': $attrs.disabled }"
|
|
38
|
+
:for="`${uuid}-${index}`"
|
|
39
|
+
>
|
|
40
|
+
<input
|
|
41
|
+
:checked="modelValue === option.value"
|
|
42
|
+
class="w-4 h-4 border-gray-600 focus:ring-blue-500 text-xy-blue"
|
|
43
|
+
:id="`${uuid}-${index}`"
|
|
44
|
+
:name="uuid"
|
|
45
|
+
type="radio"
|
|
46
|
+
:value="option.value"
|
|
47
|
+
v-bind="{
|
|
48
|
+
...$attrs,
|
|
49
|
+
onChange: ($event) => {
|
|
50
|
+
emits('update:modelValue', ($event.target as HTMLInputElement).value)
|
|
51
|
+
},
|
|
52
|
+
}"
|
|
53
|
+
/>
|
|
54
|
+
<InputLabel class="ml-2" :label="option.label" tag="span"></InputLabel>
|
|
55
|
+
</label>
|
|
56
|
+
</component>
|
|
57
|
+
</fieldset>
|
|
58
|
+
</template>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Uniques from "@/helpers/Uniques"
|
|
3
|
+
import InputLabel from "./InputLabel.vue"
|
|
4
|
+
import InputHelp from "./InputHelp.vue"
|
|
5
|
+
import { computed, useAttrs } from "vue"
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(
|
|
8
|
+
defineProps<{
|
|
9
|
+
design?: "standard" | "compressed"
|
|
10
|
+
label?: string
|
|
11
|
+
help?: string
|
|
12
|
+
placeholder?: string
|
|
13
|
+
options: { label: string; value: string | number }[]
|
|
14
|
+
modelValue: string | number | undefined
|
|
15
|
+
}>(),
|
|
16
|
+
{
|
|
17
|
+
design: "standard",
|
|
18
|
+
label: "",
|
|
19
|
+
help: "",
|
|
20
|
+
placeholder: "Select an option",
|
|
21
|
+
}
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
const emit = defineEmits(["update:modelValue"])
|
|
25
|
+
const attrs = useAttrs()
|
|
26
|
+
const uuid = (attrs.id as string) || Uniques.CreateIdAttribute()
|
|
27
|
+
|
|
28
|
+
const classes = computed((): string => {
|
|
29
|
+
return (
|
|
30
|
+
{
|
|
31
|
+
standard:
|
|
32
|
+
"mt-1 block w-full border border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm",
|
|
33
|
+
compressed:
|
|
34
|
+
"appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-600 text-gray-900 focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm",
|
|
35
|
+
} as any
|
|
36
|
+
)[props.design]
|
|
37
|
+
})
|
|
38
|
+
</script>
|
|
39
|
+
<template>
|
|
40
|
+
<InputLabel :id="`${uuid}-label`" :for="uuid" :label="label"></InputLabel>
|
|
41
|
+
<select
|
|
42
|
+
:aria-labelledby="label ? `${uuid}-label` : undefined"
|
|
43
|
+
:aria-describedby="help ? `${uuid}-help` : undefined"
|
|
44
|
+
:class="classes"
|
|
45
|
+
:id="uuid"
|
|
46
|
+
:value="modelValue"
|
|
47
|
+
v-bind="{
|
|
48
|
+
...$attrs,
|
|
49
|
+
onChange: ($event) => {
|
|
50
|
+
emit('update:modelValue', ($event.target as HTMLInputElement).value)
|
|
51
|
+
},
|
|
52
|
+
}"
|
|
53
|
+
>
|
|
54
|
+
<option v-if="placeholder" value="" disabled selected>
|
|
55
|
+
{{ placeholder }}
|
|
56
|
+
</option>
|
|
57
|
+
<option
|
|
58
|
+
v-for="option in options"
|
|
59
|
+
:value="option.value"
|
|
60
|
+
v-text="option.label"
|
|
61
|
+
:key="option.value"
|
|
62
|
+
></option>
|
|
63
|
+
</select>
|
|
64
|
+
<InputHelp :id="`${uuid}-help`" :text="help"></InputHelp>
|
|
65
|
+
</template>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Uniques from "@/helpers/Uniques"
|
|
3
|
+
import InputLabel from "./InputLabel.vue"
|
|
4
|
+
import InputHelp from "./InputHelp.vue"
|
|
5
|
+
import { useAttrs } from "vue"
|
|
6
|
+
withDefaults(
|
|
7
|
+
defineProps<{
|
|
8
|
+
help?: string
|
|
9
|
+
label?: string
|
|
10
|
+
modelValue?: string | number
|
|
11
|
+
}>(),
|
|
12
|
+
{
|
|
13
|
+
help: "",
|
|
14
|
+
label: "",
|
|
15
|
+
modelValue: "",
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
const attrs = useAttrs()
|
|
19
|
+
const emit = defineEmits(["update:modelValue"])
|
|
20
|
+
const uuid = (attrs.id as string) || Uniques.CreateIdAttribute()
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template>
|
|
24
|
+
<InputLabel
|
|
25
|
+
class="block"
|
|
26
|
+
:id="`${uuid}-label`"
|
|
27
|
+
:for="uuid"
|
|
28
|
+
:label="label"
|
|
29
|
+
></InputLabel>
|
|
30
|
+
<textarea
|
|
31
|
+
:aria-labelledby="label ? `${uuid}-label` : undefined"
|
|
32
|
+
:aria-describedby="help ? `${uuid}-help` : undefined"
|
|
33
|
+
:class="[
|
|
34
|
+
'mt-1',
|
|
35
|
+
'sm:text-sm',
|
|
36
|
+
'block',
|
|
37
|
+
'shadow-sm',
|
|
38
|
+
'focus:ring-blue-500',
|
|
39
|
+
'focus:border-blue-500',
|
|
40
|
+
'border-gray-600',
|
|
41
|
+
'rounded-md',
|
|
42
|
+
'w-full',
|
|
43
|
+
]"
|
|
44
|
+
:id="uuid"
|
|
45
|
+
:value="modelValue"
|
|
46
|
+
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
|
|
47
|
+
v-bind="$attrs"
|
|
48
|
+
/>
|
|
49
|
+
<InputHelp :id="`${uuid}-help`" :text="help"></InputHelp>
|
|
50
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Switch } from "@headlessui/vue"
|
|
3
|
+
|
|
4
|
+
withDefaults(defineProps<{ modelValue: boolean }>(), { modelValue: false })
|
|
5
|
+
const emits = defineEmits(["update:modelValue"])
|
|
6
|
+
</script>
|
|
7
|
+
<template>
|
|
8
|
+
<Switch
|
|
9
|
+
:class="[
|
|
10
|
+
modelValue ? 'bg-blue-600' : 'bg-gray-200',
|
|
11
|
+
'relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500',
|
|
12
|
+
]"
|
|
13
|
+
:modelValue="modelValue"
|
|
14
|
+
@update:modelValue="emits('update:modelValue', $event)"
|
|
15
|
+
>
|
|
16
|
+
<span class="sr-only">Use</span>
|
|
17
|
+
<span
|
|
18
|
+
aria-hidden="true"
|
|
19
|
+
:class="[
|
|
20
|
+
modelValue ? 'translate-x-5' : 'translate-x-0',
|
|
21
|
+
'pointer-events-none inline-block h-5 w-5 rounded-full bg-white shadow transform ring-0 transition ease-in-out duration-200',
|
|
22
|
+
]"
|
|
23
|
+
/>
|
|
24
|
+
</Switch>
|
|
25
|
+
</template>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Uniques from "@/helpers/Uniques"
|
|
3
|
+
import { computed, useAttrs } from "vue"
|
|
4
|
+
import InputLabel from "./InputLabel.vue"
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(
|
|
7
|
+
defineProps<{
|
|
8
|
+
modelValue?: boolean
|
|
9
|
+
legend?: string
|
|
10
|
+
name?: string
|
|
11
|
+
}>(),
|
|
12
|
+
{
|
|
13
|
+
modelValue: undefined,
|
|
14
|
+
legend: "",
|
|
15
|
+
name: "",
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
const emits = defineEmits(["update:modelValue"])
|
|
19
|
+
const attrs = useAttrs()
|
|
20
|
+
const uuid = (attrs.id as string) || Uniques.CreateIdAttribute()
|
|
21
|
+
const hasNameAttr = computed((): boolean => {
|
|
22
|
+
return typeof props.name === "string" && props.name !== ""
|
|
23
|
+
})
|
|
24
|
+
const onChange = (e: Event) => {
|
|
25
|
+
emits("update:modelValue", (e.target as HTMLInputElement).value === "true")
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
<template>
|
|
29
|
+
<fieldset>
|
|
30
|
+
<InputLabel class="block" :label="legend" tag="legend"></InputLabel>
|
|
31
|
+
<label
|
|
32
|
+
class="inline-flex items-center"
|
|
33
|
+
:class="{ 'cursor-not-allowed': $attrs.disabled }"
|
|
34
|
+
:for="`${hasNameAttr ? name : uuid}-true`"
|
|
35
|
+
>
|
|
36
|
+
<input
|
|
37
|
+
type="radio"
|
|
38
|
+
class="w-4 h-4 border-gray-600 focus:ring-blue-500 text-xy-blue"
|
|
39
|
+
:id="`${hasNameAttr ? name : uuid}-true`"
|
|
40
|
+
:name="hasNameAttr ? name : uuid"
|
|
41
|
+
:value="true"
|
|
42
|
+
:checked="modelValue === true"
|
|
43
|
+
v-bind="{
|
|
44
|
+
...$attrs,
|
|
45
|
+
onChange: onChange,
|
|
46
|
+
}"
|
|
47
|
+
/>
|
|
48
|
+
<InputLabel class="ml-2" label="Yes" tag="span"></InputLabel>
|
|
49
|
+
</label>
|
|
50
|
+
<label
|
|
51
|
+
class="inline-flex items-center ml-6"
|
|
52
|
+
:class="{ 'cursor-not-allowed': $attrs.disabled }"
|
|
53
|
+
:for="`${hasNameAttr ? name : uuid}-false`"
|
|
54
|
+
>
|
|
55
|
+
<input
|
|
56
|
+
type="radio"
|
|
57
|
+
class="w-4 h-4 border-gray-600 focus:ring-blue-500 text-xy-blue"
|
|
58
|
+
:id="`${hasNameAttr ? name : uuid}-false`"
|
|
59
|
+
:name="hasNameAttr ? name : uuid"
|
|
60
|
+
:value="false"
|
|
61
|
+
:checked="modelValue === false"
|
|
62
|
+
v-bind="{
|
|
63
|
+
...$attrs,
|
|
64
|
+
onChange: onChange,
|
|
65
|
+
}"
|
|
66
|
+
/>
|
|
67
|
+
<InputLabel class="ml-2" label="No" tag="span"></InputLabel>
|
|
68
|
+
</label>
|
|
69
|
+
</fieldset>
|
|
70
|
+
</template>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { DateRange } from "@/composables/date"
|
|
3
|
+
import { ref } from "vue"
|
|
4
|
+
import DateRangePicker from "../forms/DateRangePicker.vue"
|
|
5
|
+
import Select from "@/lib-components/forms/Select.vue"
|
|
6
|
+
|
|
7
|
+
const props = defineProps<{
|
|
8
|
+
dateRange: DateRange
|
|
9
|
+
sortDir: string
|
|
10
|
+
title: string
|
|
11
|
+
}>()
|
|
12
|
+
const dateRange = ref<DateRange>(props.dateRange)
|
|
13
|
+
const sortDir = ref<string>(props.sortDir)
|
|
14
|
+
const sortOptions = [
|
|
15
|
+
{ label: "Newest-Oldest", value: "DESC" },
|
|
16
|
+
{ label: "Oldest-Newest", value: "ASC" },
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
const emits = defineEmits<{
|
|
20
|
+
(e: "sort-dir-changed", val: string): void
|
|
21
|
+
(e: "date-range-changed", val: DateRange): void
|
|
22
|
+
}>()
|
|
23
|
+
|
|
24
|
+
const sortDirChanged = (sortDir: string) => {
|
|
25
|
+
emits("sort-dir-changed", sortDir)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const dateRangeChanged = (dateRange: DateRange) => {
|
|
29
|
+
emits("date-range-changed", dateRange)
|
|
30
|
+
}
|
|
31
|
+
</script>
|
|
32
|
+
<template>
|
|
33
|
+
<div
|
|
34
|
+
class="md:flex md:items-center md:justify-between bg-white mx-auto py-4 border-t border-gray-100"
|
|
35
|
+
>
|
|
36
|
+
<div class="flex-1 min-w-0">
|
|
37
|
+
<h1 class="text-lg leading-6 font-semibold text-gray-900">
|
|
38
|
+
{{ title }}
|
|
39
|
+
</h1>
|
|
40
|
+
</div>
|
|
41
|
+
<div class="mt-4 flex md:mt-0 md:ml-4">
|
|
42
|
+
<Select
|
|
43
|
+
v-model="sortDir"
|
|
44
|
+
:options="sortOptions"
|
|
45
|
+
@update:modelValue="sortDirChanged"
|
|
46
|
+
></Select>
|
|
47
|
+
<DateRangePicker
|
|
48
|
+
v-model="dateRange"
|
|
49
|
+
@update:modelValue="dateRangeChanged"
|
|
50
|
+
class="ml-3"
|
|
51
|
+
/>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</template>
|