@xy-planning-network/trees 0.4.0-rc-7 → 0.4.2

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 (61) hide show
  1. package/README.md +236 -53
  2. package/dist/trees.es.js +1069 -330
  3. package/dist/trees.umd.js +6 -6
  4. package/package.json +6 -4
  5. package/src/lib-components/forms/BaseInput.vue +83 -0
  6. package/src/lib-components/forms/Checkbox.vue +46 -0
  7. package/src/lib-components/forms/DateRangePicker.vue +65 -0
  8. package/src/lib-components/forms/InputHelp.vue +24 -0
  9. package/src/lib-components/forms/InputLabel.vue +23 -0
  10. package/src/lib-components/forms/MultiCheckboxes.vue +55 -0
  11. package/src/lib-components/forms/Radio.vue +58 -0
  12. package/src/lib-components/forms/Select.vue +65 -0
  13. package/src/lib-components/forms/TextArea.vue +50 -0
  14. package/src/lib-components/forms/Toggle.vue +25 -0
  15. package/src/lib-components/forms/YesOrNoRadio.vue +70 -0
  16. package/src/lib-components/layout/DateFilter.vue +54 -0
  17. package/src/lib-components/layout/SidebarLayout.vue +239 -0
  18. package/src/lib-components/layout/StackedLayout.vue +172 -0
  19. package/src/lib-components/lists/Cards.vue +33 -0
  20. package/src/lib-components/lists/DetailList.vue +114 -0
  21. package/src/lib-components/lists/DownloadCell.vue +12 -0
  22. package/src/lib-components/lists/StaticTable.vue +83 -0
  23. package/src/lib-components/lists/Table.vue +291 -0
  24. package/src/lib-components/navigation/ActionsDropdown.vue +78 -0
  25. package/src/lib-components/navigation/Paginator.vue +111 -0
  26. package/src/lib-components/navigation/Steps.vue +83 -0
  27. package/src/lib-components/navigation/Tabs.vue +92 -0
  28. package/src/lib-components/overlays/ContentModal.vue +95 -0
  29. package/src/lib-components/overlays/Flash.vue +131 -0
  30. package/src/lib-components/overlays/Modal.vue +133 -0
  31. package/src/lib-components/overlays/Popover/Popover.vue +229 -0
  32. package/src/lib-components/overlays/Popover/PopoverContent.vue +8 -0
  33. package/src/lib-components/overlays/Slideover.vue +87 -0
  34. package/src/lib-components/overlays/Spinner.vue +149 -0
  35. package/src/lib-components/overlays/Tooltip.vue +34 -0
  36. package/types/components.d.ts +6 -2
  37. package/types/composables/date.d.ts +4 -0
  38. package/types/composables/nav.d.ts +13 -0
  39. package/types/composables/overlay.d.ts +4 -0
  40. package/types/composables/table.d.ts +32 -0
  41. package/types/composables/user.d.ts +6 -0
  42. package/types/global.d.ts +5 -2
  43. package/types/helpers/Debounce.d.ts +1 -0
  44. package/types/helpers/Throttle.d.ts +1 -0
  45. package/types/lib-components/forms/Select.vue.d.ts +2 -2
  46. package/types/lib-components/index.d.ts +9 -9
  47. package/types/lib-components/layout/DateFilter.vue.d.ts +1 -4
  48. package/types/lib-components/layout/SidebarLayout.vue.d.ts +1 -1
  49. package/types/lib-components/layout/StackedLayout.vue.d.ts +2 -2
  50. package/types/lib-components/lists/StaticTable.vue.d.ts +1 -1
  51. package/types/lib-components/lists/Table.vue.d.ts +1 -1
  52. package/types/lib-components/navigation/ActionsDropdown.vue.d.ts +2 -2
  53. package/types/lib-components/navigation/Paginator.vue.d.ts +1 -6
  54. package/types/lib-components/overlays/Flash.vue.d.ts +0 -4
  55. package/types/lib-components/overlays/Popover/Popover.vue.d.ts +23 -0
  56. package/types/lib-components/overlays/Popover/PopoverContent.vue.d.ts +2 -0
  57. package/types/lib-components/overlays/Tooltip.vue.d.ts +23 -0
  58. package/types/index.d.ts +0 -3
  59. package/types/nav.d.ts +0 -8
  60. package/types/table.d.ts +0 -36
  61. package/types/users.d.ts +0 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xy-planning-network/trees",
3
- "version": "0.4.0-rc-7",
3
+ "version": "0.4.2",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "repository": "github:xy-planning-network/trees",
@@ -8,6 +8,7 @@
8
8
  "config/*",
9
9
  "dist/*",
10
10
  "src/**/*.css",
11
+ "src/**/*.vue",
11
12
  "types/*"
12
13
  ],
13
14
  "main": "dist/trees.es.js",
@@ -21,12 +22,13 @@
21
22
  ],
22
23
  "scripts": {
23
24
  "dev": "vite",
24
- "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",
25
26
  "build:docs": "vue-tsc -p dev --noEmit && vite build --config vite.docs.config.ts",
26
- "copy:types": "copyfiles -f ./src/types/**/*.d.ts ./types",
27
+ "copy:types": "copyfiles -f ./src/*.d.ts ./types",
27
28
  "lint": "eslint --ext .js,.ts,.vue src",
28
29
  "lint:fix": "eslint --fix --ext .js,.ts,.vue src dev && prettier -w -u src dev",
29
- "preview": "vite preview --config vite.docs.config.ts"
30
+ "preview": "vite preview --config vite.docs.config.ts",
31
+ "typecheck": "vue-tsc -p src --noEmit"
30
32
  },
31
33
  "devDependencies": {
32
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>