@octabits-io/nuxt-ui-kit 0.2.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.
- package/LICENSE +21 -0
- package/README.md +151 -0
- package/dist/ai/index.d.ts +255 -0
- package/dist/ai/index.js +389 -0
- package/dist/dates/index.d.ts +42 -0
- package/dist/dates/index.js +108 -0
- package/dist/index.d.ts +453 -0
- package/dist/index.js +526 -0
- package/dist/zod/index.d.ts +24 -0
- package/dist/zod/index.js +17 -0
- package/package.json +102 -0
- package/src/components/AiResultReviewCard.vue +67 -0
- package/src/components/ConfirmDialog.vue +60 -0
- package/src/components/DateInput.vue +66 -0
- package/src/components/DateRangeInput.vue +651 -0
- package/src/components/PeriodDisplay.vue +76 -0
- package/src/components/SubSidebar.vue +85 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// Shipped as source: the consumer's Vite compiles this SFC. All imports are
|
|
3
|
+
// explicit — no reliance on the consumer's auto-import configuration.
|
|
4
|
+
// i18n key contract: ai.review.title / description / currentValue / apply / dismiss.
|
|
5
|
+
import { useI18n } from 'vue-i18n'
|
|
6
|
+
import UCard from '@nuxt/ui/components/Card.vue'
|
|
7
|
+
import UIcon from '@nuxt/ui/components/Icon.vue'
|
|
8
|
+
import UButton from '@nuxt/ui/components/Button.vue'
|
|
9
|
+
|
|
10
|
+
const { t } = useI18n()
|
|
11
|
+
|
|
12
|
+
export interface AiResultField {
|
|
13
|
+
label: string
|
|
14
|
+
value: string
|
|
15
|
+
currentValue?: string | null
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
defineProps<{
|
|
19
|
+
fields: AiResultField[]
|
|
20
|
+
}>()
|
|
21
|
+
|
|
22
|
+
const emit = defineEmits<{
|
|
23
|
+
apply: []
|
|
24
|
+
dismiss: []
|
|
25
|
+
}>()
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<UCard class="mb-4">
|
|
30
|
+
<template #header>
|
|
31
|
+
<div class="flex items-center">
|
|
32
|
+
<UIcon name="i-lucide-sparkles" class="mr-2 size-4 text-primary" />
|
|
33
|
+
<span class="font-medium">{{ t('ai.review.title') }}</span>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<p class="mb-3 text-sm text-muted">
|
|
38
|
+
{{ t('ai.review.description') }}
|
|
39
|
+
</p>
|
|
40
|
+
|
|
41
|
+
<div v-for="(field, index) in fields" :key="index" class="mb-4 last:mb-0">
|
|
42
|
+
<div class="mb-1 text-xs font-medium text-muted">{{ field.label }}</div>
|
|
43
|
+
<div class="rounded-md bg-elevated p-3 text-sm">
|
|
44
|
+
{{ field.value }}
|
|
45
|
+
</div>
|
|
46
|
+
<div v-if="field.currentValue" class="mt-1 text-xs text-muted">
|
|
47
|
+
{{ t('ai.review.currentValue') }}: {{ field.currentValue }}
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<template #footer>
|
|
52
|
+
<div class="flex justify-end gap-2">
|
|
53
|
+
<UButton
|
|
54
|
+
:label="t('ai.review.dismiss')"
|
|
55
|
+
variant="ghost"
|
|
56
|
+
color="neutral"
|
|
57
|
+
@click="emit('dismiss')"
|
|
58
|
+
/>
|
|
59
|
+
<UButton
|
|
60
|
+
:label="t('ai.review.apply')"
|
|
61
|
+
color="primary"
|
|
62
|
+
@click="emit('apply')"
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
</template>
|
|
66
|
+
</UCard>
|
|
67
|
+
</template>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// Shipped as source: the consumer's Vite compiles this SFC. All imports are
|
|
3
|
+
// explicit — no reliance on the consumer's auto-import configuration. The
|
|
4
|
+
// composable comes from the package root (self-reference) so its singleton
|
|
5
|
+
// dialog state is shared with feature code calling useConfirm().
|
|
6
|
+
import { computed } from 'vue'
|
|
7
|
+
import { useI18n } from 'vue-i18n'
|
|
8
|
+
import UModal from '@nuxt/ui/components/Modal.vue'
|
|
9
|
+
import UButton from '@nuxt/ui/components/Button.vue'
|
|
10
|
+
import { useConfirmState } from '@octabits-io/nuxt-ui-kit'
|
|
11
|
+
|
|
12
|
+
const props = defineProps<{
|
|
13
|
+
/**
|
|
14
|
+
* Tailwind z-index class applied to overlay + content (e.g. `z-[100]`) so
|
|
15
|
+
* the dialog stacks above slideovers/modals that triggered it.
|
|
16
|
+
*/
|
|
17
|
+
zIndexClass?: string
|
|
18
|
+
/** i18n key for the cancel button default. */
|
|
19
|
+
cancelTextKey?: string
|
|
20
|
+
/** i18n key for the confirm button default. */
|
|
21
|
+
confirmTextKey?: string
|
|
22
|
+
}>()
|
|
23
|
+
|
|
24
|
+
const { isOpen, options, handleConfirm, handleCancel } = useConfirmState()
|
|
25
|
+
const { t } = useI18n()
|
|
26
|
+
|
|
27
|
+
const ui = computed(() =>
|
|
28
|
+
props.zIndexClass ? { overlay: props.zIndexClass, content: props.zIndexClass } : undefined,
|
|
29
|
+
)
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<template>
|
|
33
|
+
<UModal v-model:open="isOpen" :ui="ui">
|
|
34
|
+
<template #header>
|
|
35
|
+
<h3 class="text-lg font-semibold">{{ options.title }}</h3>
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<template #body>
|
|
39
|
+
<p v-if="options.message" class="text-sm text-muted">
|
|
40
|
+
{{ options.message }}
|
|
41
|
+
</p>
|
|
42
|
+
</template>
|
|
43
|
+
|
|
44
|
+
<template #footer>
|
|
45
|
+
<div class="flex justify-end gap-2">
|
|
46
|
+
<UButton
|
|
47
|
+
:label="options.cancelText ?? t(props.cancelTextKey ?? 'common.cancel')"
|
|
48
|
+
color="neutral"
|
|
49
|
+
variant="outline"
|
|
50
|
+
@click="handleCancel"
|
|
51
|
+
/>
|
|
52
|
+
<UButton
|
|
53
|
+
:label="options.confirmText ?? t(props.confirmTextKey ?? 'common.confirm')"
|
|
54
|
+
:color="options.dangerous ? 'error' : 'primary'"
|
|
55
|
+
@click="handleConfirm"
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
</template>
|
|
59
|
+
</UModal>
|
|
60
|
+
</template>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// Shipped as source: the consumer's Vite compiles this SFC. All imports are
|
|
3
|
+
// explicit — no reliance on the consumer's auto-import configuration.
|
|
4
|
+
import { computed, ref } from 'vue'
|
|
5
|
+
import { useI18n } from 'vue-i18n'
|
|
6
|
+
import { CalendarDate, parseDate } from '@internationalized/date'
|
|
7
|
+
import UPopover from '@nuxt/ui/components/Popover.vue'
|
|
8
|
+
import UButton from '@nuxt/ui/components/Button.vue'
|
|
9
|
+
import UCalendar from '@nuxt/ui/components/Calendar.vue'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Single-date input built on the Nuxt UI 4 date primitives (`UPopover` +
|
|
13
|
+
* `UCalendar`). The model is an ISO `YYYY-MM-DD` string so it drops into Zod
|
|
14
|
+
* schemas and API payloads without conversion. Use this instead of a raw
|
|
15
|
+
* `<UInput type="date">`.
|
|
16
|
+
*/
|
|
17
|
+
const props = withDefaults(defineProps<{
|
|
18
|
+
modelValue: string
|
|
19
|
+
placeholder?: string
|
|
20
|
+
disabled?: boolean
|
|
21
|
+
}>(), { placeholder: undefined, disabled: false })
|
|
22
|
+
|
|
23
|
+
const emit = defineEmits<{ 'update:modelValue': [value: string] }>()
|
|
24
|
+
|
|
25
|
+
const { locale } = useI18n()
|
|
26
|
+
const open = ref(false)
|
|
27
|
+
|
|
28
|
+
const calendarValue = computed<CalendarDate | undefined>({
|
|
29
|
+
get() {
|
|
30
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(props.modelValue)) return undefined
|
|
31
|
+
try {
|
|
32
|
+
return parseDate(props.modelValue)
|
|
33
|
+
} catch {
|
|
34
|
+
return undefined
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
set(val) {
|
|
38
|
+
emit('update:modelValue', val ? val.toString() : '')
|
|
39
|
+
open.value = false
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const label = computed(() => {
|
|
44
|
+
const v = calendarValue.value
|
|
45
|
+
if (!v) return ''
|
|
46
|
+
return new Date(v.year, v.month - 1, v.day).toLocaleDateString(locale.value)
|
|
47
|
+
})
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<UPopover v-model:open="open">
|
|
52
|
+
<UButton
|
|
53
|
+
variant="outline"
|
|
54
|
+
color="neutral"
|
|
55
|
+
icon="i-lucide-calendar"
|
|
56
|
+
class="w-full justify-start font-normal"
|
|
57
|
+
:class="{ 'text-dimmed': !calendarValue }"
|
|
58
|
+
:disabled="disabled"
|
|
59
|
+
>
|
|
60
|
+
{{ label || placeholder }}
|
|
61
|
+
</UButton>
|
|
62
|
+
<template #content>
|
|
63
|
+
<UCalendar v-model="calendarValue" class="p-2" />
|
|
64
|
+
</template>
|
|
65
|
+
</UPopover>
|
|
66
|
+
</template>
|