@hina-ui/vue 1.7.1 → 1.7.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/index.js +1933 -510
- package/dist/index.js.map +1 -1
- package/dist/types/components/anchor/composables/useScrollSpy.d.ts.map +1 -1
- package/dist/types/components/data-table/DataTable.vue.d.ts.map +1 -1
- package/dist/types/components/data-table/column-sizing-styles.d.ts +4 -0
- package/dist/types/components/data-table/column-sizing-styles.d.ts.map +1 -0
- package/dist/types/components/data-table/composables/useTableColumns.d.ts +1 -0
- package/dist/types/components/data-table/composables/useTableColumns.d.ts.map +1 -1
- package/dist/types/components/navigation-menu/NavigationMenu.vue.d.ts +33 -0
- package/dist/types/components/navigation-menu/NavigationMenu.vue.d.ts.map +1 -0
- package/dist/types/components/navigation-menu/NavigationMenuContent.vue.d.ts +29 -0
- package/dist/types/components/navigation-menu/NavigationMenuContent.vue.d.ts.map +1 -0
- package/dist/types/components/navigation-menu/NavigationMenuItem.vue.d.ts +16 -0
- package/dist/types/components/navigation-menu/NavigationMenuItem.vue.d.ts.map +1 -0
- package/dist/types/components/navigation-menu/NavigationMenuLink.vue.d.ts +33 -0
- package/dist/types/components/navigation-menu/NavigationMenuLink.vue.d.ts.map +1 -0
- package/dist/types/components/navigation-menu/NavigationMenuTrigger.vue.d.ts +19 -0
- package/dist/types/components/navigation-menu/NavigationMenuTrigger.vue.d.ts.map +1 -0
- package/dist/types/components/navigation-menu/composables/useNavigationMenuKeyboard.d.ts +4 -0
- package/dist/types/components/navigation-menu/composables/useNavigationMenuKeyboard.d.ts.map +1 -0
- package/dist/types/components/navigation-menu/composables/useNavigationMenuLayout.d.ts +12 -0
- package/dist/types/components/navigation-menu/composables/useNavigationMenuLayout.d.ts.map +1 -0
- package/dist/types/components/navigation-menu/context.d.ts +10 -0
- package/dist/types/components/navigation-menu/context.d.ts.map +1 -0
- package/dist/types/components/navigation-menu/navigation-menu.variants.d.ts +112 -0
- package/dist/types/components/navigation-menu/navigation-menu.variants.d.ts.map +1 -0
- package/dist/types/components/navigation-menu/types.d.ts +17 -0
- package/dist/types/components/navigation-menu/types.d.ts.map +1 -0
- package/dist/types/components/rating/Rating.vue.d.ts +1 -0
- package/dist/types/components/rating/Rating.vue.d.ts.map +1 -1
- package/dist/types/components/rating/composables/useRatingScale.d.ts +8 -0
- package/dist/types/components/rating/composables/useRatingScale.d.ts.map +1 -0
- package/dist/types/components/stepper/Stepper.vue.d.ts +36 -0
- package/dist/types/components/stepper/Stepper.vue.d.ts.map +1 -0
- package/dist/types/components/stepper/StepperStep.vue.d.ts +33 -0
- package/dist/types/components/stepper/StepperStep.vue.d.ts.map +1 -0
- package/dist/types/components/stepper/composables/useStepper.d.ts +13 -0
- package/dist/types/components/stepper/composables/useStepper.d.ts.map +1 -0
- package/dist/types/components/stepper/stepper.variants.d.ts +58 -0
- package/dist/types/components/stepper/stepper.variants.d.ts.map +1 -0
- package/dist/types/components/stepper/types.d.ts +45 -0
- package/dist/types/components/stepper/types.d.ts.map +1 -0
- package/dist/types/components/table/table.variants.d.ts +1 -1
- package/dist/types/components/table/table.variants.d.ts.map +1 -1
- package/dist/types/components/timeline/Timeline.vue.d.ts +36 -0
- package/dist/types/components/timeline/Timeline.vue.d.ts.map +1 -0
- package/dist/types/components/timeline/timeline.variants.d.ts +51 -0
- package/dist/types/components/timeline/timeline.variants.d.ts.map +1 -0
- package/dist/types/components/timeline/types.d.ts +18 -0
- package/dist/types/components/timeline/types.d.ts.map +1 -0
- package/dist/types/components/toolbar/Toolbar.vue.d.ts +20 -0
- package/dist/types/components/toolbar/Toolbar.vue.d.ts.map +1 -0
- package/dist/types/components/toolbar/ToolbarButton.vue.d.ts +18 -0
- package/dist/types/components/toolbar/ToolbarButton.vue.d.ts.map +1 -0
- package/dist/types/components/toolbar/ToolbarControl.vue.d.ts +22 -0
- package/dist/types/components/toolbar/ToolbarControl.vue.d.ts.map +1 -0
- package/dist/types/components/toolbar/ToolbarLink.vue.d.ts +24 -0
- package/dist/types/components/toolbar/ToolbarLink.vue.d.ts.map +1 -0
- package/dist/types/components/toolbar/ToolbarSeparator.vue.d.ts +10 -0
- package/dist/types/components/toolbar/ToolbarSeparator.vue.d.ts.map +1 -0
- package/dist/types/components/toolbar/ToolbarToggleGroup.vue.d.ts +31 -0
- package/dist/types/components/toolbar/ToolbarToggleGroup.vue.d.ts.map +1 -0
- package/dist/types/components/toolbar/ToolbarToggleItem.vue.d.ts +21 -0
- package/dist/types/components/toolbar/ToolbarToggleItem.vue.d.ts.map +1 -0
- package/dist/types/components/toolbar/context.d.ts +13 -0
- package/dist/types/components/toolbar/context.d.ts.map +1 -0
- package/dist/types/components/toolbar/toolbar.variants.d.ts +64 -0
- package/dist/types/components/toolbar/toolbar.variants.d.ts.map +1 -0
- package/dist/types/components/toolbar/types.d.ts +28 -0
- package/dist/types/components/toolbar/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/locale/en-US.d.ts.map +1 -1
- package/dist/types/locale/index.d.ts.map +1 -1
- package/dist/types/locale/types.d.ts +7 -0
- package/dist/types/locale/types.d.ts.map +1 -1
- package/dist/types/locale/zh-CN.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/anchor/composables/useScrollSpy.ts +8 -11
- package/src/components/data-table/DataTable.vue +1 -0
- package/src/components/data-table/DataTableHead.vue +1 -1
- package/src/components/data-table/column-sizing-styles.ts +40 -0
- package/src/components/data-table/composables/useTableColumns.ts +7 -9
- package/src/components/navigation-menu/NavigationMenu.vue +84 -0
- package/src/components/navigation-menu/NavigationMenuContent.vue +25 -0
- package/src/components/navigation-menu/NavigationMenuItem.vue +13 -0
- package/src/components/navigation-menu/NavigationMenuLink.vue +82 -0
- package/src/components/navigation-menu/NavigationMenuTrigger.vue +44 -0
- package/src/components/navigation-menu/composables/useNavigationMenuKeyboard.ts +33 -0
- package/src/components/navigation-menu/composables/useNavigationMenuLayout.ts +72 -0
- package/src/components/navigation-menu/context.ts +19 -0
- package/src/components/navigation-menu/navigation-menu.variants.ts +82 -0
- package/src/components/navigation-menu/types.ts +17 -0
- package/src/components/rating/Rating.vue +22 -8
- package/src/components/rating/composables/useRatingScale.ts +24 -0
- package/src/components/sidebar/Sidebar.vue +1 -1
- package/src/components/stepper/Stepper.vue +95 -0
- package/src/components/stepper/StepperStep.vue +102 -0
- package/src/components/stepper/composables/useStepper.ts +112 -0
- package/src/components/stepper/stepper.variants.ts +39 -0
- package/src/components/stepper/types.ts +51 -0
- package/src/components/table/table.variants.ts +1 -2
- package/src/components/timeline/Timeline.vue +109 -0
- package/src/components/timeline/timeline.variants.ts +31 -0
- package/src/components/timeline/types.ts +20 -0
- package/src/components/toolbar/Toolbar.vue +45 -0
- package/src/components/toolbar/ToolbarButton.vue +26 -0
- package/src/components/toolbar/ToolbarControl.vue +46 -0
- package/src/components/toolbar/ToolbarLink.vue +40 -0
- package/src/components/toolbar/ToolbarSeparator.vue +20 -0
- package/src/components/toolbar/ToolbarToggleGroup.vue +42 -0
- package/src/components/toolbar/ToolbarToggleItem.vue +34 -0
- package/src/components/toolbar/context.ts +29 -0
- package/src/components/toolbar/toolbar.variants.ts +37 -0
- package/src/components/toolbar/types.ts +30 -0
- package/src/index.ts +45 -0
- package/src/locale/en-US.ts +7 -0
- package/src/locale/index.ts +1 -0
- package/src/locale/types.ts +7 -0
- package/src/locale/zh-CN.ts +7 -0
- package/src/styles/data-table.css +0 -1
- package/src/styles/interaction.css +1 -0
- package/src/styles/motion.css +66 -0
- package/src/styles/stepper.css +41 -0
- package/src/styles/timeline.css +144 -0
- package/src/styles/tokens.css +2 -0
- package/src/styles/typography.css +1 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TimelineVariants, TimelineMarkerVariants } from './timeline.variants'
|
|
2
|
+
|
|
3
|
+
export type TimelineTone = NonNullable<TimelineMarkerVariants['tone']>
|
|
4
|
+
export type TimelineSize = NonNullable<TimelineVariants['size']>
|
|
5
|
+
export type TimelineOrientation = 'vertical' | 'horizontal'
|
|
6
|
+
export type TimelineAlign = 'start' | 'end' | 'alternate'
|
|
7
|
+
|
|
8
|
+
export interface TimelineItem {
|
|
9
|
+
id?: string | number
|
|
10
|
+
title?: string
|
|
11
|
+
description?: string
|
|
12
|
+
time?: string
|
|
13
|
+
dateTime?: string
|
|
14
|
+
tone?: TimelineTone
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface TimelineSlotProps<T extends TimelineItem = TimelineItem> {
|
|
18
|
+
item: T
|
|
19
|
+
index: number
|
|
20
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { toRef } from 'vue'
|
|
3
|
+
import { ToolbarRoot } from 'reka-ui'
|
|
4
|
+
import { cn } from '../../lib/cn'
|
|
5
|
+
import { useAccessibleName } from '../../lib/a11y'
|
|
6
|
+
import { useDirection } from '../../lib/useDirection'
|
|
7
|
+
import { provideToolbar } from './context'
|
|
8
|
+
import { toolbar } from './toolbar.variants'
|
|
9
|
+
import type { ToolbarProps } from './types'
|
|
10
|
+
|
|
11
|
+
defineOptions({ name: 'HnToolbar' })
|
|
12
|
+
|
|
13
|
+
const props = withDefaults(defineProps<ToolbarProps>(), {
|
|
14
|
+
orientation: 'horizontal',
|
|
15
|
+
loop: true,
|
|
16
|
+
disabled: false,
|
|
17
|
+
size: 'md',
|
|
18
|
+
variant: 'primary',
|
|
19
|
+
})
|
|
20
|
+
const { root, direction, rootDirection } = useDirection(() => props.dir)
|
|
21
|
+
|
|
22
|
+
provideToolbar({
|
|
23
|
+
orientation: toRef(props, 'orientation'),
|
|
24
|
+
size: toRef(props, 'size'),
|
|
25
|
+
disabled: toRef(props, 'disabled'),
|
|
26
|
+
})
|
|
27
|
+
useAccessibleName('Toolbar', () => !props.label)
|
|
28
|
+
defineSlots<{ default(): unknown }>()
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<ToolbarRoot
|
|
33
|
+
as-child
|
|
34
|
+
:orientation="props.orientation"
|
|
35
|
+
:dir="direction"
|
|
36
|
+
:loop="props.loop"
|
|
37
|
+
:aria-label="props.label"
|
|
38
|
+
:aria-disabled="props.disabled || undefined"
|
|
39
|
+
:class="cn(toolbar({ orientation: props.orientation, variant: props.variant }), props.class)"
|
|
40
|
+
>
|
|
41
|
+
<div ref="root" :dir="rootDirection" data-hn-toolbar>
|
|
42
|
+
<slot />
|
|
43
|
+
</div>
|
|
44
|
+
</ToolbarRoot>
|
|
45
|
+
</template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { ToolbarButton as RekaToolbarButton } from 'reka-ui'
|
|
4
|
+
import ToolbarControl from './ToolbarControl.vue'
|
|
5
|
+
import { useToolbar } from './context'
|
|
6
|
+
import type { ToolbarControlProps } from './types'
|
|
7
|
+
|
|
8
|
+
defineOptions({ name: 'HnToolbarButton', inheritAttrs: false })
|
|
9
|
+
const props = withDefaults(defineProps<ToolbarControlProps>(), { tooltip: true, ripple: true })
|
|
10
|
+
const toolbar = useToolbar()
|
|
11
|
+
const disabled = computed(() => toolbar.disabled.value || props.disabled || props.loading)
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<RekaToolbarButton as-child :as="props.as" :disabled="disabled">
|
|
16
|
+
<ToolbarControl
|
|
17
|
+
v-bind="{ ...$attrs, ...props }"
|
|
18
|
+
:disabled="disabled"
|
|
19
|
+
:size="props.size ?? toolbar.size.value"
|
|
20
|
+
>
|
|
21
|
+
<template v-for="(_, name) in $slots" #[name]>
|
|
22
|
+
<slot :name="name" />
|
|
23
|
+
</template>
|
|
24
|
+
</ToolbarControl>
|
|
25
|
+
</RekaToolbarButton>
|
|
26
|
+
</template>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { injectTooltipProviderContext } from 'reka-ui'
|
|
3
|
+
import { Passthrough } from '../../lib/passthrough'
|
|
4
|
+
import Button from '../button/Button.vue'
|
|
5
|
+
import Tooltip from '../tooltip/Tooltip.vue'
|
|
6
|
+
import type { ToolbarControlProps } from './types'
|
|
7
|
+
|
|
8
|
+
defineOptions({ inheritAttrs: false })
|
|
9
|
+
|
|
10
|
+
const props = withDefaults(defineProps<ToolbarControlProps>(), {
|
|
11
|
+
as: 'button',
|
|
12
|
+
tooltip: true,
|
|
13
|
+
side: 'top',
|
|
14
|
+
variant: 'ghost',
|
|
15
|
+
tone: 'neutral',
|
|
16
|
+
ripple: true,
|
|
17
|
+
})
|
|
18
|
+
const Wrapper = injectTooltipProviderContext(null) ? Tooltip : Passthrough
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<Wrapper
|
|
23
|
+
:disabled="!props.tooltip || !props.label"
|
|
24
|
+
:content="props.label ?? ''"
|
|
25
|
+
:side="props.side"
|
|
26
|
+
>
|
|
27
|
+
<Button
|
|
28
|
+
v-bind="$attrs"
|
|
29
|
+
:as="props.as"
|
|
30
|
+
:as-child="props.asChild"
|
|
31
|
+
:aria-label="props.label"
|
|
32
|
+
:icon-only="!!props.label"
|
|
33
|
+
:size="props.size"
|
|
34
|
+
:variant="props.variant"
|
|
35
|
+
:tone="props.tone"
|
|
36
|
+
:disabled="props.disabled"
|
|
37
|
+
:loading="props.loading"
|
|
38
|
+
:ripple="props.ripple"
|
|
39
|
+
:class="props.class"
|
|
40
|
+
>
|
|
41
|
+
<template v-for="(_, name) in $slots" #[name]>
|
|
42
|
+
<slot :name="name" />
|
|
43
|
+
</template>
|
|
44
|
+
</Button>
|
|
45
|
+
</Wrapper>
|
|
46
|
+
</template>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { ToolbarButton as RekaToolbarButton } from 'reka-ui'
|
|
4
|
+
import ToolbarControl from './ToolbarControl.vue'
|
|
5
|
+
import { useToolbar } from './context'
|
|
6
|
+
import type { ToolbarControlProps } from './types'
|
|
7
|
+
|
|
8
|
+
defineOptions({ name: 'HnToolbarLink', inheritAttrs: false })
|
|
9
|
+
const props = withDefaults(
|
|
10
|
+
defineProps<
|
|
11
|
+
ToolbarControlProps & {
|
|
12
|
+
href?: string
|
|
13
|
+
target?: string
|
|
14
|
+
rel?: string
|
|
15
|
+
}
|
|
16
|
+
>(),
|
|
17
|
+
{ as: 'a', tooltip: true, ripple: true },
|
|
18
|
+
)
|
|
19
|
+
const toolbar = useToolbar()
|
|
20
|
+
const disabled = computed(() => toolbar.disabled.value || props.disabled || props.loading)
|
|
21
|
+
|
|
22
|
+
function activate(event: KeyboardEvent) {
|
|
23
|
+
if (!disabled.value) (event.currentTarget as HTMLElement).click()
|
|
24
|
+
}
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<template>
|
|
28
|
+
<RekaToolbarButton as-child :as="props.as" :disabled="disabled">
|
|
29
|
+
<ToolbarControl
|
|
30
|
+
v-bind="{ ...$attrs, ...props }"
|
|
31
|
+
:disabled="disabled"
|
|
32
|
+
:size="props.size ?? toolbar.size.value"
|
|
33
|
+
@keydown.space.prevent="activate"
|
|
34
|
+
>
|
|
35
|
+
<template v-for="(_, name) in $slots" #[name]>
|
|
36
|
+
<slot :name="name" />
|
|
37
|
+
</template>
|
|
38
|
+
</ToolbarControl>
|
|
39
|
+
</RekaToolbarButton>
|
|
40
|
+
</template>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Separator } from 'reka-ui'
|
|
3
|
+
import { cn } from '../../lib/cn'
|
|
4
|
+
import { useToolbar } from './context'
|
|
5
|
+
import { toolbarSeparator } from './toolbar.variants'
|
|
6
|
+
|
|
7
|
+
defineOptions({ name: 'HnToolbarSeparator' })
|
|
8
|
+
const props = withDefaults(defineProps<{ decorative?: boolean; class?: string }>(), {
|
|
9
|
+
decorative: true,
|
|
10
|
+
})
|
|
11
|
+
const toolbar = useToolbar()
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<template>
|
|
15
|
+
<Separator
|
|
16
|
+
:orientation="toolbar.orientation.value === 'horizontal' ? 'vertical' : 'horizontal'"
|
|
17
|
+
:decorative="props.decorative"
|
|
18
|
+
:class="cn(toolbarSeparator({ orientation: toolbar.orientation.value }), props.class)"
|
|
19
|
+
/>
|
|
20
|
+
</template>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script setup lang="ts" generic="T extends string | string[] = string | string[]">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { ToolbarToggleGroup as RekaToolbarToggleGroup, type AcceptableValue } from 'reka-ui'
|
|
4
|
+
import { cn } from '../../lib/cn'
|
|
5
|
+
import { useToolbar, provideToolbarGroup } from './context'
|
|
6
|
+
import { toolbarGroup } from './toolbar.variants'
|
|
7
|
+
|
|
8
|
+
defineOptions({ name: 'HnToolbarToggleGroup' })
|
|
9
|
+
const props = withDefaults(
|
|
10
|
+
defineProps<{
|
|
11
|
+
type?: 'single' | 'multiple'
|
|
12
|
+
defaultValue?: T
|
|
13
|
+
label?: string
|
|
14
|
+
disabled?: boolean
|
|
15
|
+
class?: string
|
|
16
|
+
}>(),
|
|
17
|
+
{ type: 'single' },
|
|
18
|
+
)
|
|
19
|
+
const model = defineModel<T>()
|
|
20
|
+
const toolbar = useToolbar()
|
|
21
|
+
const disabled = computed(() => toolbar.disabled.value || !!props.disabled)
|
|
22
|
+
provideToolbarGroup(disabled)
|
|
23
|
+
|
|
24
|
+
function update(value: AcceptableValue | AcceptableValue[]) {
|
|
25
|
+
model.value = value as T
|
|
26
|
+
}
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<RekaToolbarToggleGroup
|
|
31
|
+
:model-value="model"
|
|
32
|
+
:default-value="props.defaultValue"
|
|
33
|
+
:type="props.type"
|
|
34
|
+
:disabled="disabled"
|
|
35
|
+
:orientation="toolbar.orientation.value"
|
|
36
|
+
:aria-label="props.label"
|
|
37
|
+
:class="cn(toolbarGroup({ orientation: toolbar.orientation.value }), props.class)"
|
|
38
|
+
@update:model-value="update"
|
|
39
|
+
>
|
|
40
|
+
<slot />
|
|
41
|
+
</RekaToolbarToggleGroup>
|
|
42
|
+
</template>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { ToolbarToggleItem as RekaToolbarToggleItem } from 'reka-ui'
|
|
4
|
+
import { cn } from '../../lib/cn'
|
|
5
|
+
import ToolbarControl from './ToolbarControl.vue'
|
|
6
|
+
import { useToolbar, useToolbarGroup } from './context'
|
|
7
|
+
import type { ToolbarControlProps } from './types'
|
|
8
|
+
|
|
9
|
+
defineOptions({ name: 'HnToolbarToggleItem', inheritAttrs: false })
|
|
10
|
+
const props = withDefaults(defineProps<ToolbarControlProps & { value: string }>(), {
|
|
11
|
+
tooltip: true,
|
|
12
|
+
ripple: true,
|
|
13
|
+
})
|
|
14
|
+
const toolbar = useToolbar()
|
|
15
|
+
const groupDisabled = useToolbarGroup()
|
|
16
|
+
const disabled = computed(
|
|
17
|
+
() => toolbar.disabled.value || groupDisabled?.value || props.disabled || props.loading,
|
|
18
|
+
)
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<RekaToolbarToggleItem as-child :value="props.value" :disabled="disabled">
|
|
23
|
+
<ToolbarControl
|
|
24
|
+
v-bind="{ ...$attrs, ...props }"
|
|
25
|
+
:disabled="disabled"
|
|
26
|
+
:size="props.size ?? toolbar.size.value"
|
|
27
|
+
:class="cn('aria-pressed:text-accent-text', props.class)"
|
|
28
|
+
>
|
|
29
|
+
<template v-for="(_, name) in $slots" #[name]>
|
|
30
|
+
<slot :name="name" />
|
|
31
|
+
</template>
|
|
32
|
+
</ToolbarControl>
|
|
33
|
+
</RekaToolbarToggleItem>
|
|
34
|
+
</template>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { inject, provide, type InjectionKey, type Ref } from 'vue'
|
|
2
|
+
import type { ToolbarOrientation, ToolbarSize } from './types'
|
|
3
|
+
|
|
4
|
+
interface ToolbarContext {
|
|
5
|
+
orientation: Readonly<Ref<ToolbarOrientation>>
|
|
6
|
+
size: Readonly<Ref<ToolbarSize>>
|
|
7
|
+
disabled: Readonly<Ref<boolean>>
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const toolbarKey: InjectionKey<ToolbarContext> = Symbol('hn-toolbar')
|
|
11
|
+
const groupKey: InjectionKey<Readonly<Ref<boolean>>> = Symbol('hn-toolbar-group')
|
|
12
|
+
|
|
13
|
+
export function provideToolbar(context: ToolbarContext) {
|
|
14
|
+
provide(toolbarKey, context)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useToolbar() {
|
|
18
|
+
const context = inject(toolbarKey)
|
|
19
|
+
if (!context) throw new Error('[Hina UI] Toolbar controls must be inside Toolbar.')
|
|
20
|
+
return context
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function provideToolbarGroup(disabled: Readonly<Ref<boolean>>) {
|
|
24
|
+
provide(groupKey, disabled)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function useToolbarGroup() {
|
|
28
|
+
return inject(groupKey, null)
|
|
29
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { tv } from '../../lib/tv'
|
|
2
|
+
|
|
3
|
+
export const toolbar = tv({
|
|
4
|
+
base: 'inline-flex max-w-full gap-(--hn-control-gap) rounded-lg',
|
|
5
|
+
variants: {
|
|
6
|
+
orientation: {
|
|
7
|
+
horizontal: 'flex-row flex-wrap items-center',
|
|
8
|
+
vertical: 'flex-col items-stretch',
|
|
9
|
+
},
|
|
10
|
+
variant: {
|
|
11
|
+
primary: 'border-line bg-surface border p-1',
|
|
12
|
+
secondary: 'bg-inset p-1',
|
|
13
|
+
bare: '',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
defaultVariants: { orientation: 'horizontal', variant: 'primary' },
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
export const toolbarGroup = tv({
|
|
20
|
+
base: 'inline-flex gap-(--hn-control-gap)',
|
|
21
|
+
variants: {
|
|
22
|
+
orientation: {
|
|
23
|
+
horizontal: 'flex-wrap items-center',
|
|
24
|
+
vertical: 'flex-col items-stretch',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
export const toolbarSeparator = tv({
|
|
30
|
+
base: 'bg-line shrink-0 self-stretch',
|
|
31
|
+
variants: {
|
|
32
|
+
orientation: {
|
|
33
|
+
horizontal: 'mx-1 my-1 w-px',
|
|
34
|
+
vertical: 'mx-1 my-1 h-px',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
})
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PrimitiveProps } from 'reka-ui'
|
|
2
|
+
import type { ButtonVariants } from '../button/button.variants'
|
|
3
|
+
|
|
4
|
+
export type ToolbarOrientation = 'horizontal' | 'vertical'
|
|
5
|
+
export type ToolbarSize = 'sm' | 'md' | 'lg'
|
|
6
|
+
export type ToolbarVariant = 'primary' | 'secondary' | 'bare'
|
|
7
|
+
|
|
8
|
+
export interface ToolbarProps {
|
|
9
|
+
label?: string
|
|
10
|
+
orientation?: ToolbarOrientation
|
|
11
|
+
dir?: 'ltr' | 'rtl'
|
|
12
|
+
loop?: boolean
|
|
13
|
+
disabled?: boolean
|
|
14
|
+
size?: ToolbarSize
|
|
15
|
+
variant?: ToolbarVariant
|
|
16
|
+
class?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ToolbarControlProps extends PrimitiveProps {
|
|
20
|
+
label?: string
|
|
21
|
+
tooltip?: boolean
|
|
22
|
+
side?: 'top' | 'right' | 'bottom' | 'left'
|
|
23
|
+
variant?: ButtonVariants['variant']
|
|
24
|
+
tone?: ButtonVariants['tone']
|
|
25
|
+
size?: ToolbarSize
|
|
26
|
+
disabled?: boolean
|
|
27
|
+
loading?: boolean
|
|
28
|
+
ripple?: boolean
|
|
29
|
+
class?: string
|
|
30
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -78,6 +78,29 @@ export type { SliderVariants } from './components/slider/slider.variants'
|
|
|
78
78
|
export { default as RangeSlider } from './components/range-slider/RangeSlider.vue'
|
|
79
79
|
export { default as Toggle } from './components/toggle/Toggle.vue'
|
|
80
80
|
export type { ToggleVariants } from './components/toggle/toggle.variants'
|
|
81
|
+
export { default as Toolbar } from './components/toolbar/Toolbar.vue'
|
|
82
|
+
export { default as NavigationMenu } from './components/navigation-menu/NavigationMenu.vue'
|
|
83
|
+
export { default as NavigationMenuItem } from './components/navigation-menu/NavigationMenuItem.vue'
|
|
84
|
+
export { default as NavigationMenuTrigger } from './components/navigation-menu/NavigationMenuTrigger.vue'
|
|
85
|
+
export { default as NavigationMenuLink } from './components/navigation-menu/NavigationMenuLink.vue'
|
|
86
|
+
export { default as NavigationMenuContent } from './components/navigation-menu/NavigationMenuContent.vue'
|
|
87
|
+
export type {
|
|
88
|
+
NavigationMenuProps,
|
|
89
|
+
NavigationMenuSize,
|
|
90
|
+
NavigationMenuOrientation,
|
|
91
|
+
} from './components/navigation-menu/types'
|
|
92
|
+
export { default as ToolbarButton } from './components/toolbar/ToolbarButton.vue'
|
|
93
|
+
export { default as ToolbarLink } from './components/toolbar/ToolbarLink.vue'
|
|
94
|
+
export { default as ToolbarToggleGroup } from './components/toolbar/ToolbarToggleGroup.vue'
|
|
95
|
+
export { default as ToolbarToggleItem } from './components/toolbar/ToolbarToggleItem.vue'
|
|
96
|
+
export { default as ToolbarSeparator } from './components/toolbar/ToolbarSeparator.vue'
|
|
97
|
+
export type {
|
|
98
|
+
ToolbarProps,
|
|
99
|
+
ToolbarControlProps,
|
|
100
|
+
ToolbarOrientation,
|
|
101
|
+
ToolbarSize,
|
|
102
|
+
ToolbarVariant,
|
|
103
|
+
} from './components/toolbar/types'
|
|
81
104
|
export { default as TagsInput } from './components/tags-input/TagsInput.vue'
|
|
82
105
|
export { default as MultiCombobox } from './components/multi-combobox/MultiCombobox.vue'
|
|
83
106
|
export { default as Calendar } from './components/calendar/Calendar.vue'
|
|
@@ -290,3 +313,25 @@ export type {
|
|
|
290
313
|
DataTableProps,
|
|
291
314
|
DataTableSlots,
|
|
292
315
|
} from './components/data-table/types'
|
|
316
|
+
|
|
317
|
+
export { default as Timeline } from './components/timeline/Timeline.vue'
|
|
318
|
+
export type {
|
|
319
|
+
TimelineItem,
|
|
320
|
+
TimelineSlotProps,
|
|
321
|
+
TimelineAlign,
|
|
322
|
+
TimelineOrientation,
|
|
323
|
+
TimelineSize,
|
|
324
|
+
TimelineTone,
|
|
325
|
+
} from './components/timeline/types'
|
|
326
|
+
|
|
327
|
+
export { default as Stepper } from './components/stepper/Stepper.vue'
|
|
328
|
+
export type {
|
|
329
|
+
StepperItem,
|
|
330
|
+
StepperState,
|
|
331
|
+
StepperSize,
|
|
332
|
+
StepperOrientation,
|
|
333
|
+
StepperProps,
|
|
334
|
+
StepperSlotProps,
|
|
335
|
+
StepperNavigation,
|
|
336
|
+
StepperBeforeChange,
|
|
337
|
+
} from './components/stepper/types'
|
package/src/locale/en-US.ts
CHANGED
|
@@ -2,6 +2,12 @@ import type { UiMessages } from './types'
|
|
|
2
2
|
|
|
3
3
|
export const enUS: UiMessages = {
|
|
4
4
|
tag: 'en-US',
|
|
5
|
+
stepper: {
|
|
6
|
+
label: 'Steps',
|
|
7
|
+
progress: (step, total) => `Step ${step} of ${total}`,
|
|
8
|
+
completed: 'Completed',
|
|
9
|
+
error: 'This step has an error',
|
|
10
|
+
},
|
|
5
11
|
common: {
|
|
6
12
|
close: 'Close',
|
|
7
13
|
copy: 'Copy',
|
|
@@ -156,6 +162,7 @@ export const enUS: UiMessages = {
|
|
|
156
162
|
rating: {
|
|
157
163
|
star: value => `${value} ${value === 1 ? 'star' : 'stars'}`,
|
|
158
164
|
label: (value, max) => `${value} out of ${max} stars`,
|
|
165
|
+
score: (value, max) => `${value} out of ${max} points`,
|
|
159
166
|
},
|
|
160
167
|
form: {
|
|
161
168
|
required: 'Required',
|
package/src/locale/index.ts
CHANGED
|
@@ -18,6 +18,7 @@ function merge(base: UiMessages, patch: PartialUiMessages): UiMessages {
|
|
|
18
18
|
return {
|
|
19
19
|
tag: patch.tag ?? base.tag,
|
|
20
20
|
common: { ...base.common, ...patch.common },
|
|
21
|
+
stepper: { ...base.stepper, ...patch.stepper },
|
|
21
22
|
banner: { ...base.banner, ...patch.banner },
|
|
22
23
|
pagination: { ...base.pagination, ...patch.pagination },
|
|
23
24
|
table: { ...base.table, ...patch.table },
|
package/src/locale/types.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export interface UiMessages {
|
|
2
2
|
tag: string
|
|
3
|
+
stepper: {
|
|
4
|
+
label: string
|
|
5
|
+
progress: (step: number, total: number) => string
|
|
6
|
+
completed: string
|
|
7
|
+
error: string
|
|
8
|
+
}
|
|
3
9
|
common: {
|
|
4
10
|
close: string
|
|
5
11
|
copy: string
|
|
@@ -155,6 +161,7 @@ export interface UiMessages {
|
|
|
155
161
|
rating: {
|
|
156
162
|
star: (value: number) => string
|
|
157
163
|
label: (value: number, max: number) => string
|
|
164
|
+
score: (value: number, max: number) => string
|
|
158
165
|
}
|
|
159
166
|
form: {
|
|
160
167
|
required: string
|
package/src/locale/zh-CN.ts
CHANGED
|
@@ -2,6 +2,12 @@ import type { UiMessages } from './types'
|
|
|
2
2
|
|
|
3
3
|
export const zhCN: UiMessages = {
|
|
4
4
|
tag: 'zh-CN',
|
|
5
|
+
stepper: {
|
|
6
|
+
label: '步骤',
|
|
7
|
+
progress: (step, total) => `第 ${step} 步,共 ${total} 步`,
|
|
8
|
+
completed: '已完成',
|
|
9
|
+
error: '该步骤存在错误',
|
|
10
|
+
},
|
|
5
11
|
common: {
|
|
6
12
|
close: '关闭',
|
|
7
13
|
copy: '复制',
|
|
@@ -156,6 +162,7 @@ export const zhCN: UiMessages = {
|
|
|
156
162
|
rating: {
|
|
157
163
|
star: value => `${value} 星`,
|
|
158
164
|
label: (value, max) => `${value} 星,满分 ${max} 星`,
|
|
165
|
+
score: (value, max) => `${value} 分,满分 ${max} 分`,
|
|
159
166
|
},
|
|
160
167
|
form: {
|
|
161
168
|
required: '必填',
|
package/src/styles/motion.css
CHANGED
|
@@ -147,6 +147,72 @@
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
+
@utility hn-navigation-viewport {
|
|
151
|
+
box-sizing: content-box;
|
|
152
|
+
visibility: hidden;
|
|
153
|
+
transition:
|
|
154
|
+
width var(--hn-duration-base) var(--hn-ease-move),
|
|
155
|
+
height var(--hn-duration-base) var(--hn-ease-move),
|
|
156
|
+
left var(--hn-duration-base) var(--hn-ease-move),
|
|
157
|
+
top var(--hn-duration-base) var(--hn-ease-move);
|
|
158
|
+
|
|
159
|
+
&[style*='--reka-navigation-menu-viewport-width'] {
|
|
160
|
+
@apply hn-anim-pop;
|
|
161
|
+
|
|
162
|
+
visibility: visible;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
@keyframes hn-navigation-in {
|
|
167
|
+
from {
|
|
168
|
+
opacity: 0;
|
|
169
|
+
transform: translate(var(--hn-navigation-x, 0), var(--hn-navigation-y, 0));
|
|
170
|
+
}
|
|
171
|
+
to {
|
|
172
|
+
opacity: 1;
|
|
173
|
+
transform: none;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
@keyframes hn-navigation-out {
|
|
178
|
+
from {
|
|
179
|
+
opacity: 1;
|
|
180
|
+
transform: none;
|
|
181
|
+
}
|
|
182
|
+
to {
|
|
183
|
+
opacity: 0;
|
|
184
|
+
transform: translate(var(--hn-navigation-x, 0), var(--hn-navigation-y, 0));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@utility hn-anim-navigation-content {
|
|
189
|
+
--hn-navigation-x: var(--hn-navigation-travel, 0px);
|
|
190
|
+
|
|
191
|
+
&[data-orientation='vertical'] {
|
|
192
|
+
--hn-navigation-x: 0px;
|
|
193
|
+
--hn-navigation-y: var(--hn-navigation-travel, 0px);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
&[data-orientation='vertical']:dir(rtl) {
|
|
197
|
+
--hn-navigation-y: calc(var(--hn-navigation-travel, 0px) * -1);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
&[data-motion='from-start'],
|
|
201
|
+
&[data-motion='to-start'] {
|
|
202
|
+
--hn-navigation-travel: calc(var(--hn-travel-md) * -1);
|
|
203
|
+
}
|
|
204
|
+
&[data-motion='from-end'],
|
|
205
|
+
&[data-motion='to-end'] {
|
|
206
|
+
--hn-navigation-travel: var(--hn-travel-md);
|
|
207
|
+
}
|
|
208
|
+
&[data-motion^='from-'] {
|
|
209
|
+
animation: hn-navigation-in var(--hn-duration-base) var(--hn-ease-enter);
|
|
210
|
+
}
|
|
211
|
+
&[data-motion^='to-'] {
|
|
212
|
+
animation: hn-navigation-out var(--hn-duration-exit) var(--hn-ease-exit);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
150
216
|
@utility hn-scrim {
|
|
151
217
|
position: fixed;
|
|
152
218
|
inset: 0;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.hn-stepper-list[data-orientation='horizontal'] {
|
|
3
|
+
grid-auto-flow: column;
|
|
4
|
+
grid-auto-columns: minmax(0, 1fr);
|
|
5
|
+
|
|
6
|
+
> .hn-stepper-item {
|
|
7
|
+
position: relative;
|
|
8
|
+
|
|
9
|
+
> button {
|
|
10
|
+
padding-inline: var(--hn-inline-gap);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
> .hn-stepper-separator {
|
|
14
|
+
position: absolute;
|
|
15
|
+
pointer-events: none;
|
|
16
|
+
inset-block-start: calc(var(--hn-stepper-indicator) / 2 + --spacing(1));
|
|
17
|
+
inset-inline-start: calc(50% + var(--hn-stepper-indicator) / 2 + var(--hn-control-gap));
|
|
18
|
+
inline-size: calc(100% - var(--hn-stepper-indicator) - var(--hn-control-gap) * 2);
|
|
19
|
+
block-size: 1px;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.hn-stepper-list[data-orientation='vertical'] {
|
|
25
|
+
> .hn-stepper-item {
|
|
26
|
+
display: grid;
|
|
27
|
+
grid-template-columns: calc(var(--hn-stepper-indicator) + --spacing(2)) minmax(0, 1fr);
|
|
28
|
+
|
|
29
|
+
> button {
|
|
30
|
+
grid-column: 1 / -1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
> .hn-stepper-separator {
|
|
34
|
+
justify-self: center;
|
|
35
|
+
inline-size: 1px;
|
|
36
|
+
min-block-size: var(--hn-stack-gap);
|
|
37
|
+
margin-block: var(--hn-control-gap);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|