@hina-ui/vue 1.7.7 → 1.7.9
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/index.js +1338 -562
- package/dist/index.js.map +1 -1
- package/dist/shared/behavior/anchor-follow.ts +20 -11
- package/dist/shared/behavior/form.ts +5 -9
- package/dist/shared/lib/command-palette/match.ts +9 -0
- package/dist/shared/lib/line-clamp.ts +76 -0
- package/dist/shared/lib/scroll-restore.ts +163 -0
- package/dist/shared/locale/en-US.ts +4 -0
- package/dist/shared/locale/index.ts +2 -0
- package/dist/shared/locale/ja-JP.ts +229 -0
- package/dist/shared/locale/types.ts +4 -0
- package/dist/shared/locale/zh-CN.ts +4 -0
- package/dist/shared/styles/density.css +4 -0
- package/dist/shared/styles/line-clamp.css +98 -0
- package/dist/shared/styles/tokens.css +1 -0
- package/dist/shared/styles/typography.css +18 -0
- package/dist/shared/variants/button.ts +2 -0
- package/dist/shared/variants/command-palette.ts +4 -0
- package/dist/shared/variants/line-clamp.ts +13 -0
- package/dist/shared/variants/tag.ts +1 -0
- package/dist/types/shared/src/behavior/anchor-follow.d.ts.map +1 -1
- package/dist/types/shared/src/behavior/form.d.ts.map +1 -1
- package/dist/types/shared/src/lib/command-palette/match.d.ts +5 -0
- package/dist/types/shared/src/lib/command-palette/match.d.ts.map +1 -1
- package/dist/types/shared/src/lib/line-clamp.d.ts +6 -0
- package/dist/types/shared/src/lib/line-clamp.d.ts.map +1 -0
- package/dist/types/shared/src/lib/scroll-restore.d.ts +16 -0
- package/dist/types/shared/src/lib/scroll-restore.d.ts.map +1 -1
- package/dist/types/shared/src/locale/en-US.d.ts.map +1 -1
- package/dist/types/shared/src/locale/index.d.ts +1 -0
- package/dist/types/shared/src/locale/index.d.ts.map +1 -1
- package/dist/types/shared/src/locale/ja-JP.d.ts +3 -0
- package/dist/types/shared/src/locale/ja-JP.d.ts.map +1 -0
- package/dist/types/shared/src/locale/types.d.ts +4 -0
- package/dist/types/shared/src/locale/types.d.ts.map +1 -1
- package/dist/types/shared/src/locale/zh-CN.d.ts.map +1 -1
- package/dist/types/shared/src/variants/button.d.ts +6 -0
- package/dist/types/shared/src/variants/button.d.ts.map +1 -1
- package/dist/types/shared/src/variants/command-palette.d.ts +1 -0
- package/dist/types/shared/src/variants/command-palette.d.ts.map +1 -1
- package/dist/types/shared/src/variants/line-clamp.d.ts +4 -0
- package/dist/types/shared/src/variants/line-clamp.d.ts.map +1 -0
- package/dist/types/shared/src/variants/tag.d.ts +3 -0
- package/dist/types/shared/src/variants/tag.d.ts.map +1 -1
- package/dist/types/shared/src/variants/toggle.d.ts +7 -0
- package/dist/types/shared/src/variants/toggle.d.ts.map +1 -1
- package/dist/types/vue/src/components/app-shell/AppShell.vue.d.ts +2 -2
- package/dist/types/vue/src/components/app-shell/AppShell.vue.d.ts.map +1 -1
- package/dist/types/vue/src/components/close-button/CloseButton.vue.d.ts +1 -1
- package/dist/types/vue/src/components/command-palette/CommandPalette.vue.d.ts +40 -34
- package/dist/types/vue/src/components/command-palette/CommandPalette.vue.d.ts.map +1 -1
- package/dist/types/vue/src/components/command-palette/CommandPaletteInput.vue.d.ts +8 -0
- package/dist/types/vue/src/components/command-palette/CommandPaletteInput.vue.d.ts.map +1 -0
- package/dist/types/vue/src/components/command-palette/CommandPaletteItem.vue.d.ts +21 -7
- package/dist/types/vue/src/components/command-palette/CommandPaletteItem.vue.d.ts.map +1 -1
- package/dist/types/vue/src/components/command-palette/CommandPalettePanel.vue.d.ts +37 -31
- package/dist/types/vue/src/components/command-palette/CommandPalettePanel.vue.d.ts.map +1 -1
- package/dist/types/vue/src/components/command-palette/composables/useCommandItems.d.ts +6 -6
- package/dist/types/vue/src/components/command-palette/composables/useCommandItems.d.ts.map +1 -1
- package/dist/types/vue/src/components/command-palette/context.d.ts +11 -0
- package/dist/types/vue/src/components/command-palette/context.d.ts.map +1 -0
- package/dist/types/vue/src/components/command-palette/types.d.ts +16 -5
- package/dist/types/vue/src/components/command-palette/types.d.ts.map +1 -1
- package/dist/types/vue/src/components/command-palette/utils/match.d.ts +3 -3
- package/dist/types/vue/src/components/command-palette/utils/match.d.ts.map +1 -1
- package/dist/types/vue/src/components/copy-button/CopyButton.vue.d.ts +1 -1
- package/dist/types/vue/src/components/description-list/DescriptionList.vue.d.ts +1 -0
- package/dist/types/vue/src/components/description-list/DescriptionList.vue.d.ts.map +1 -1
- package/dist/types/vue/src/components/dialog/Dialog.vue.d.ts +3 -0
- package/dist/types/vue/src/components/dialog/Dialog.vue.d.ts.map +1 -1
- package/dist/types/vue/src/components/drawer/Drawer.vue.d.ts +3 -0
- package/dist/types/vue/src/components/drawer/Drawer.vue.d.ts.map +1 -1
- package/dist/types/vue/src/components/form/Form.vue.d.ts +5 -0
- package/dist/types/vue/src/components/form/Form.vue.d.ts.map +1 -1
- package/dist/types/vue/src/components/form/scope.d.ts +4 -0
- package/dist/types/vue/src/components/form/scope.d.ts.map +1 -0
- package/dist/types/vue/src/components/line-clamp/LineClamp.vue.d.ts +28 -0
- package/dist/types/vue/src/components/line-clamp/LineClamp.vue.d.ts.map +1 -0
- package/dist/types/vue/src/components/line-clamp/line-clamp.variants.d.ts +2 -0
- package/dist/types/vue/src/components/line-clamp/line-clamp.variants.d.ts.map +1 -0
- package/dist/types/vue/src/components/sheet/Sheet.vue.d.ts +3 -0
- package/dist/types/vue/src/components/sheet/Sheet.vue.d.ts.map +1 -1
- package/dist/types/vue/src/index.d.ts +6 -4
- package/dist/types/vue/src/index.d.ts.map +1 -1
- package/dist/types/vue/src/locale/index.d.ts +1 -1
- package/dist/types/vue/src/locale/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/app-shell/AppShell.vue +54 -4
- package/src/components/command-palette/CommandPalette.vue +53 -16
- package/src/components/command-palette/CommandPaletteInput.vue +32 -0
- package/src/components/command-palette/CommandPaletteItem.vue +7 -5
- package/src/components/command-palette/CommandPalettePanel.vue +95 -34
- package/src/components/command-palette/composables/useCommandItems.ts +16 -14
- package/src/components/command-palette/context.ts +28 -0
- package/src/components/command-palette/types.ts +21 -5
- package/src/components/command-palette/utils/match.ts +6 -3
- package/src/components/description-list/DescriptionList.vue +8 -2
- package/src/components/dialog/Dialog.vue +13 -8
- package/src/components/drawer/Drawer.vue +13 -8
- package/src/components/form/Form.vue +14 -1
- package/src/components/form/scope.ts +39 -0
- package/src/components/line-clamp/LineClamp.vue +105 -0
- package/src/components/line-clamp/line-clamp.variants.ts +1 -0
- package/src/components/sheet/Sheet.vue +14 -10
- package/src/index.ts +16 -2
- package/src/locale/index.ts +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
2
3
|
import {
|
|
3
4
|
DialogRoot,
|
|
4
5
|
DialogTrigger,
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
import { useOverlayPortal } from '../../lib/overlay-portal'
|
|
18
19
|
import { useScrollViewport } from '../../lib/scroll-viewport'
|
|
19
20
|
import { cn } from '../../lib/cn'
|
|
21
|
+
import { provideFormScope } from '../form/scope'
|
|
20
22
|
import { dialogWrapper, dialogCard, type DialogVariants } from './dialog.variants'
|
|
21
23
|
|
|
22
24
|
defineOptions({ name: 'HnDialog' })
|
|
@@ -39,13 +41,16 @@
|
|
|
39
41
|
default?(): unknown
|
|
40
42
|
icon?(): unknown
|
|
41
43
|
title?(): unknown
|
|
42
|
-
body?(props: { close: () => void }): unknown
|
|
43
|
-
content?(props: { close: () => void }): unknown
|
|
44
|
-
footer?(props: { close: () => void }): unknown
|
|
44
|
+
body?(props: { close: () => void; submitting: boolean }): unknown
|
|
45
|
+
content?(props: { close: () => void; submitting: boolean }): unknown
|
|
46
|
+
footer?(props: { close: () => void; submitting: boolean }): unknown
|
|
45
47
|
}>()
|
|
46
48
|
|
|
49
|
+
const submitting = provideFormScope()
|
|
50
|
+
const locked = computed(() => props.locked || submitting.value)
|
|
51
|
+
|
|
47
52
|
function guard(e: Event) {
|
|
48
|
-
if (
|
|
53
|
+
if (locked.value) e.preventDefault()
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
const { scrollArea, viewport } = useScrollViewport()
|
|
@@ -92,7 +97,7 @@
|
|
|
92
97
|
{{ props.description }}
|
|
93
98
|
</DialogDescription>
|
|
94
99
|
</template>
|
|
95
|
-
<slot v-if="slots.body" name="body" :close="close" />
|
|
100
|
+
<slot v-if="slots.body" name="body" :close="close" :submitting="submitting" />
|
|
96
101
|
<template v-else>
|
|
97
102
|
<div
|
|
98
103
|
v-if="props.header"
|
|
@@ -118,19 +123,19 @@
|
|
|
118
123
|
</DialogDescription>
|
|
119
124
|
</div>
|
|
120
125
|
<DialogClose v-if="props.closable" as-child>
|
|
121
|
-
<CloseButton :disabled="
|
|
126
|
+
<CloseButton :disabled="locked" class="-mt-1.5 -me-1.5 shrink-0" />
|
|
122
127
|
</DialogClose>
|
|
123
128
|
</div>
|
|
124
129
|
<ScrollArea v-if="$slots.content" ref="scrollArea" class="min-h-0">
|
|
125
130
|
<div class="px-(--hn-panel-p) py-1">
|
|
126
|
-
<slot name="content" :close="close" />
|
|
131
|
+
<slot name="content" :close="close" :submitting="submitting" />
|
|
127
132
|
</div>
|
|
128
133
|
</ScrollArea>
|
|
129
134
|
<div
|
|
130
135
|
v-if="$slots.footer"
|
|
131
136
|
class="flex shrink-0 justify-end gap-(--hn-inline-gap) px-(--hn-panel-p)"
|
|
132
137
|
>
|
|
133
|
-
<slot name="footer" :close="close" />
|
|
138
|
+
<slot name="footer" :close="close" :submitting="submitting" />
|
|
134
139
|
</div>
|
|
135
140
|
</template>
|
|
136
141
|
</Card>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
2
3
|
import {
|
|
3
4
|
DialogRoot,
|
|
4
5
|
DialogTrigger,
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
import { useOverlayPortal } from '../../lib/overlay-portal'
|
|
18
19
|
import { useScrollViewport } from '../../lib/scroll-viewport'
|
|
19
20
|
import { cn } from '../../lib/cn'
|
|
21
|
+
import { provideFormScope } from '../form/scope'
|
|
20
22
|
import { drawerCard } from './drawer.variants'
|
|
21
23
|
|
|
22
24
|
defineOptions({ name: 'HnDrawer' })
|
|
@@ -39,13 +41,16 @@
|
|
|
39
41
|
default?(): unknown
|
|
40
42
|
icon?(): unknown
|
|
41
43
|
title?(): unknown
|
|
42
|
-
body?(props: { close: () => void }): unknown
|
|
43
|
-
content?(props: { close: () => void }): unknown
|
|
44
|
-
footer?(props: { close: () => void }): unknown
|
|
44
|
+
body?(props: { close: () => void; submitting: boolean }): unknown
|
|
45
|
+
content?(props: { close: () => void; submitting: boolean }): unknown
|
|
46
|
+
footer?(props: { close: () => void; submitting: boolean }): unknown
|
|
45
47
|
}>()
|
|
46
48
|
|
|
49
|
+
const submitting = provideFormScope()
|
|
50
|
+
const locked = computed(() => props.locked || submitting.value)
|
|
51
|
+
|
|
47
52
|
function guard(e: Event) {
|
|
48
|
-
if (
|
|
53
|
+
if (locked.value) e.preventDefault()
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
const { scrollArea, viewport } = useScrollViewport()
|
|
@@ -84,7 +89,7 @@
|
|
|
84
89
|
{{ props.description }}
|
|
85
90
|
</DialogDescription>
|
|
86
91
|
</template>
|
|
87
|
-
<slot v-if="slots.body" name="body" :close="close" />
|
|
92
|
+
<slot v-if="slots.body" name="body" :close="close" :submitting="submitting" />
|
|
88
93
|
<template v-else>
|
|
89
94
|
<div
|
|
90
95
|
v-if="props.header"
|
|
@@ -110,19 +115,19 @@
|
|
|
110
115
|
</DialogDescription>
|
|
111
116
|
</div>
|
|
112
117
|
<DialogClose v-if="props.closable" as-child>
|
|
113
|
-
<CloseButton :disabled="
|
|
118
|
+
<CloseButton :disabled="locked" class="-mt-1.5 -me-1.5 shrink-0" />
|
|
114
119
|
</DialogClose>
|
|
115
120
|
</div>
|
|
116
121
|
<ScrollArea v-if="$slots.content" ref="scrollArea" class="min-h-0 grow">
|
|
117
122
|
<div class="px-(--hn-panel-p) py-1">
|
|
118
|
-
<slot name="content" :close="close" />
|
|
123
|
+
<slot name="content" :close="close" :submitting="submitting" />
|
|
119
124
|
</div>
|
|
120
125
|
</ScrollArea>
|
|
121
126
|
<div
|
|
122
127
|
v-if="$slots.footer"
|
|
123
128
|
class="flex shrink-0 justify-end gap-(--hn-inline-gap) px-(--hn-panel-p)"
|
|
124
129
|
>
|
|
125
|
-
<slot name="footer" :close="close" />
|
|
130
|
+
<slot name="footer" :close="close" :submitting="submitting" />
|
|
126
131
|
</div>
|
|
127
132
|
</template>
|
|
128
133
|
</Card>
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { cn } from '../../lib/cn'
|
|
4
4
|
import { useForm, type FormValidateOn } from './composables/useForm'
|
|
5
5
|
import { provideForm } from './context'
|
|
6
|
+
import { reportFormScope } from './scope'
|
|
6
7
|
import { formRoot } from './form.variants'
|
|
7
8
|
import { focusFirstInvalid } from './utils/focus'
|
|
8
9
|
import type { FormErrors, FormRules, FormValues } from './standard-schema'
|
|
@@ -47,7 +48,19 @@
|
|
|
47
48
|
form.setErrors(errors)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
reportFormScope(form.submitting)
|
|
52
|
+
|
|
53
|
+
defineExpose({
|
|
54
|
+
submit,
|
|
55
|
+
validate: form.validate,
|
|
56
|
+
reset: form.reset,
|
|
57
|
+
setErrors,
|
|
58
|
+
errors: form.errors,
|
|
59
|
+
error: form.formError,
|
|
60
|
+
invalid: form.invalid,
|
|
61
|
+
submitting: form.submitting,
|
|
62
|
+
submitted: form.submitted,
|
|
63
|
+
})
|
|
51
64
|
</script>
|
|
52
65
|
|
|
53
66
|
<template>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
computed,
|
|
3
|
+
inject,
|
|
4
|
+
onScopeDispose,
|
|
5
|
+
provide,
|
|
6
|
+
shallowRef,
|
|
7
|
+
watch,
|
|
8
|
+
type ComputedRef,
|
|
9
|
+
type InjectionKey,
|
|
10
|
+
type Ref,
|
|
11
|
+
} from 'vue'
|
|
12
|
+
|
|
13
|
+
interface FormScope {
|
|
14
|
+
set: (id: symbol, submitting: boolean) => void
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const FORM_SCOPE_KEY = Symbol('hn-form-scope') as InjectionKey<FormScope>
|
|
18
|
+
|
|
19
|
+
export function provideFormScope(): ComputedRef<boolean> {
|
|
20
|
+
const active = shallowRef<ReadonlySet<symbol>>(new Set())
|
|
21
|
+
provide(FORM_SCOPE_KEY, {
|
|
22
|
+
set(id, submitting) {
|
|
23
|
+
if (active.value.has(id) === submitting) return
|
|
24
|
+
const next = new Set(active.value)
|
|
25
|
+
if (submitting) next.add(id)
|
|
26
|
+
else next.delete(id)
|
|
27
|
+
active.value = next
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
return computed(() => active.value.size > 0)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function reportFormScope(submitting: Ref<boolean>) {
|
|
34
|
+
const scope = inject(FORM_SCOPE_KEY, null)
|
|
35
|
+
if (!scope) return
|
|
36
|
+
const id = Symbol('form')
|
|
37
|
+
watch(submitting, value => scope.set(id, value), { immediate: true, flush: 'sync' })
|
|
38
|
+
onScopeDispose(() => scope.set(id, false))
|
|
39
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, onBeforeUnmount, onMounted, onUpdated, shallowRef, useId } from 'vue'
|
|
3
|
+
import { useResizeObserver } from '@vueuse/core'
|
|
4
|
+
import { cn } from '../../lib/cn'
|
|
5
|
+
import { useUiLocale } from '../../locale'
|
|
6
|
+
import Button from '../button/Button.vue'
|
|
7
|
+
import {
|
|
8
|
+
animateLineClamp,
|
|
9
|
+
lineClampCount,
|
|
10
|
+
measureLineClamp,
|
|
11
|
+
revealLineClamp,
|
|
12
|
+
} from '../../../../shared/src/lib/line-clamp'
|
|
13
|
+
import { lineClampContent, lineClampRoot, lineClampToggle } from './line-clamp.variants'
|
|
14
|
+
|
|
15
|
+
defineOptions({ name: 'HnLineClamp' })
|
|
16
|
+
|
|
17
|
+
const props = defineProps<{
|
|
18
|
+
lines?: number
|
|
19
|
+
expandLabel?: string
|
|
20
|
+
collapseLabel?: string
|
|
21
|
+
class?: string
|
|
22
|
+
}>()
|
|
23
|
+
|
|
24
|
+
const expanded = defineModel<boolean>('expanded', { default: false })
|
|
25
|
+
|
|
26
|
+
const t = useUiLocale()
|
|
27
|
+
const id = useId()
|
|
28
|
+
const root = shallowRef<HTMLElement | null>(null)
|
|
29
|
+
const content = shallowRef<HTMLElement | null>(null)
|
|
30
|
+
const truncated = shallowRef<boolean | null>(null)
|
|
31
|
+
const truncation = computed(() => (truncated.value === null ? undefined : `${truncated.value}`))
|
|
32
|
+
const count = computed(() => lineClampCount(props.lines))
|
|
33
|
+
|
|
34
|
+
let shown = expanded.value
|
|
35
|
+
let reveal = false
|
|
36
|
+
let stop: (() => void) | undefined
|
|
37
|
+
|
|
38
|
+
function measure() {
|
|
39
|
+
if (!content.value) return
|
|
40
|
+
const next = measureLineClamp(content.value)
|
|
41
|
+
if (next !== null) truncated.value = next
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function sync() {
|
|
45
|
+
const element = content.value
|
|
46
|
+
if (element && shown !== expanded.value) {
|
|
47
|
+
shown = expanded.value
|
|
48
|
+
const scroll = reveal && !shown
|
|
49
|
+
reveal = false
|
|
50
|
+
stop?.()
|
|
51
|
+
stop = animateLineClamp(element, shown, () => {
|
|
52
|
+
measure()
|
|
53
|
+
if (scroll) revealLineClamp(root.value)
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
measure()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
onMounted(() => {
|
|
60
|
+
measure()
|
|
61
|
+
void document.fonts?.ready.then(measure)
|
|
62
|
+
})
|
|
63
|
+
onUpdated(sync)
|
|
64
|
+
useResizeObserver(content, measure)
|
|
65
|
+
onBeforeUnmount(() => stop?.())
|
|
66
|
+
|
|
67
|
+
function toggle() {
|
|
68
|
+
reveal = expanded.value
|
|
69
|
+
expanded.value = !expanded.value
|
|
70
|
+
}
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<template>
|
|
74
|
+
<div
|
|
75
|
+
ref="root"
|
|
76
|
+
:data-expanded="expanded ? '' : undefined"
|
|
77
|
+
:data-truncated="truncation"
|
|
78
|
+
:class="cn(lineClampRoot(), props.class)"
|
|
79
|
+
>
|
|
80
|
+
<div
|
|
81
|
+
:id="id"
|
|
82
|
+
ref="content"
|
|
83
|
+
:data-expanded="expanded ? '' : undefined"
|
|
84
|
+
:style="{ '--hn-line-clamp': count }"
|
|
85
|
+
:class="lineClampContent()"
|
|
86
|
+
>
|
|
87
|
+
<slot />
|
|
88
|
+
</div>
|
|
89
|
+
<span :class="lineClampToggle()">
|
|
90
|
+
<Button
|
|
91
|
+
variant="link"
|
|
92
|
+
size="sm"
|
|
93
|
+
:aria-expanded="expanded"
|
|
94
|
+
:aria-controls="id"
|
|
95
|
+
@click="toggle"
|
|
96
|
+
>
|
|
97
|
+
{{
|
|
98
|
+
expanded
|
|
99
|
+
? (props.collapseLabel ?? t.lineClamp.collapse)
|
|
100
|
+
: (props.expandLabel ?? t.lineClamp.expand)
|
|
101
|
+
}}
|
|
102
|
+
</Button>
|
|
103
|
+
</span>
|
|
104
|
+
</div>
|
|
105
|
+
</template>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../../../../shared/src/variants/line-clamp'
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { useOverlayPortal } from '../../lib/overlay-portal'
|
|
14
14
|
import { useScrollViewport } from '../../lib/scroll-viewport'
|
|
15
15
|
import { cn } from '../../lib/cn'
|
|
16
|
+
import { provideFormScope } from '../form/scope'
|
|
16
17
|
import Card from '../card/Card.vue'
|
|
17
18
|
import CloseButton from '../close-button/CloseButton.vue'
|
|
18
19
|
import Heading from '../heading/Heading.vue'
|
|
@@ -36,13 +37,16 @@
|
|
|
36
37
|
{ header: true, closable: true, handle: true, locked: false },
|
|
37
38
|
)
|
|
38
39
|
|
|
40
|
+
const submitting = provideFormScope()
|
|
41
|
+
const locked = computed(() => props.locked || submitting.value)
|
|
42
|
+
|
|
39
43
|
const slots = defineSlots<{
|
|
40
44
|
default?(): unknown
|
|
41
45
|
icon?(): unknown
|
|
42
46
|
title?(): unknown
|
|
43
|
-
body?(props: { close: () => void }): unknown
|
|
44
|
-
content?(props: { close: () => void }): unknown
|
|
45
|
-
footer?(props: { close: () => void }): unknown
|
|
47
|
+
body?(props: { close: () => void; submitting: boolean }): unknown
|
|
48
|
+
content?(props: { close: () => void; submitting: boolean }): unknown
|
|
49
|
+
footer?(props: { close: () => void; submitting: boolean }): unknown
|
|
46
50
|
}>()
|
|
47
51
|
|
|
48
52
|
const { scrollArea, viewport } = useScrollViewport()
|
|
@@ -52,7 +56,7 @@
|
|
|
52
56
|
const { content: panel, present } = useOverlayPortal(open)
|
|
53
57
|
|
|
54
58
|
const { dragging, offset, onPointerDown } = useDragToDismiss(() => panel.value?.$el ?? null, {
|
|
55
|
-
enabled: () => !
|
|
59
|
+
enabled: () => !locked.value,
|
|
56
60
|
open,
|
|
57
61
|
dismiss: () => (open.value = false),
|
|
58
62
|
})
|
|
@@ -64,7 +68,7 @@
|
|
|
64
68
|
)
|
|
65
69
|
|
|
66
70
|
function guard(event: Event) {
|
|
67
|
-
if (
|
|
71
|
+
if (locked.value) event.preventDefault()
|
|
68
72
|
}
|
|
69
73
|
|
|
70
74
|
function close() {
|
|
@@ -109,7 +113,7 @@
|
|
|
109
113
|
<div
|
|
110
114
|
v-if="props.handle"
|
|
111
115
|
aria-hidden="true"
|
|
112
|
-
:data-disabled="
|
|
116
|
+
:data-disabled="locked ? '' : undefined"
|
|
113
117
|
:class="sheetHandle({ header: props.header && !slots.body })"
|
|
114
118
|
/>
|
|
115
119
|
<div
|
|
@@ -136,22 +140,22 @@
|
|
|
136
140
|
</DialogDescription>
|
|
137
141
|
</div>
|
|
138
142
|
<DialogClose v-if="!props.handle && props.closable" as-child>
|
|
139
|
-
<CloseButton :disabled="
|
|
143
|
+
<CloseButton :disabled="locked" class="-mt-1.5 -me-1.5 shrink-0" />
|
|
140
144
|
</DialogClose>
|
|
141
145
|
</div>
|
|
142
146
|
</div>
|
|
143
|
-
<slot v-if="slots.body" name="body" :close="close" />
|
|
147
|
+
<slot v-if="slots.body" name="body" :close="close" :submitting="submitting" />
|
|
144
148
|
<template v-else>
|
|
145
149
|
<ScrollArea v-if="$slots.content" ref="scrollArea" class="min-h-0 grow">
|
|
146
150
|
<div class="px-(--hn-panel-p) py-1">
|
|
147
|
-
<slot name="content" :close="close" />
|
|
151
|
+
<slot name="content" :close="close" :submitting="submitting" />
|
|
148
152
|
</div>
|
|
149
153
|
</ScrollArea>
|
|
150
154
|
<div
|
|
151
155
|
v-if="$slots.footer"
|
|
152
156
|
class="flex shrink-0 justify-end gap-(--hn-inline-gap) px-(--hn-panel-p)"
|
|
153
157
|
>
|
|
154
|
-
<slot name="footer" :close="close" />
|
|
158
|
+
<slot name="footer" :close="close" :submitting="submitting" />
|
|
155
159
|
</div>
|
|
156
160
|
</template>
|
|
157
161
|
</Card>
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ export type { VariantProps } from './lib/tv'
|
|
|
5
5
|
export { EASE, DURATION, TRAVEL, STAGGER, TRANSITION, cssEase } from './motion'
|
|
6
6
|
export type { Bezier, TransitionName } from './motion'
|
|
7
7
|
|
|
8
|
-
export { provideUiLocale, useUiLocale, zhCN, enUS } from './locale'
|
|
8
|
+
export { provideUiLocale, useUiLocale, zhCN, enUS, jaJP } from './locale'
|
|
9
9
|
export type { UiMessages, PartialUiMessages } from './locale'
|
|
10
10
|
|
|
11
11
|
export { REQUIRED_SINGLETONS } from './singletons'
|
|
@@ -74,7 +74,15 @@ export type {
|
|
|
74
74
|
CompletionEdit,
|
|
75
75
|
} from './components/autocomplete/types'
|
|
76
76
|
export { default as CommandPalette } from './components/command-palette/CommandPalette.vue'
|
|
77
|
-
export
|
|
77
|
+
export { default as CommandPaletteInput } from './components/command-palette/CommandPaletteInput.vue'
|
|
78
|
+
export type {
|
|
79
|
+
CommandItem,
|
|
80
|
+
CommandGroup,
|
|
81
|
+
CommandItems,
|
|
82
|
+
CommandItemMatch,
|
|
83
|
+
CommandItemSlotProps,
|
|
84
|
+
CommandEmptySlotProps,
|
|
85
|
+
} from './components/command-palette/types'
|
|
78
86
|
export { default as Listbox } from './components/listbox/Listbox.vue'
|
|
79
87
|
export type { ListboxVariants } from './components/listbox/listbox.variants'
|
|
80
88
|
export { default as Tree } from './components/tree/Tree.vue'
|
|
@@ -274,6 +282,7 @@ export { default as Toaster } from './components/toast/Toaster.vue'
|
|
|
274
282
|
export { toast } from './components/toast/store'
|
|
275
283
|
export type { ToastTone, ToastOptions, ToasterPosition } from './components/toast/store'
|
|
276
284
|
export { default as Spoiler } from './components/spoiler/Spoiler.vue'
|
|
285
|
+
export { default as LineClamp } from './components/line-clamp/LineClamp.vue'
|
|
277
286
|
export { default as Skeleton } from './components/skeleton/Skeleton.vue'
|
|
278
287
|
export { default as Image } from './components/image/Image.vue'
|
|
279
288
|
export { default as ImageGroup } from './components/image/ImageGroup.vue'
|
|
@@ -297,11 +306,16 @@ export {
|
|
|
297
306
|
readScrollRecord,
|
|
298
307
|
writeScrollRecord,
|
|
299
308
|
createScrollRestorer,
|
|
309
|
+
createScrollRestoreSession,
|
|
310
|
+
keepScrollPosition,
|
|
311
|
+
scrollRestoreScript,
|
|
300
312
|
} from './components/scroll-area/scroll-restore'
|
|
301
313
|
export type {
|
|
302
314
|
ScrollRecord,
|
|
303
315
|
ScrollRestorer,
|
|
304
316
|
ScrollRestorerPorts,
|
|
317
|
+
ScrollRestoreSession,
|
|
318
|
+
ScrollRestoreSessionOptions,
|
|
305
319
|
} from './components/scroll-area/scroll-restore'
|
|
306
320
|
|
|
307
321
|
export { default as DataTable } from './components/data-table/DataTable.vue'
|
package/src/locale/index.ts
CHANGED
|
@@ -30,5 +30,5 @@ export function useUiLocale(): ComputedRef<UiMessages> {
|
|
|
30
30
|
return inject(UI_LOCALE_KEY, fallbackLocale)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export { zhCN, enUS } from '../../../shared/src/locale'
|
|
33
|
+
export { zhCN, enUS, jaJP } from '../../../shared/src/locale'
|
|
34
34
|
export type { UiMessages, PartialUiMessages } from '../../../shared/src/locale'
|