@hina-ui/vue 1.7.2 → 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.
Files changed (111) hide show
  1. package/dist/index.js +1899 -493
  2. package/dist/index.js.map +1 -1
  3. package/dist/types/components/navigation-menu/NavigationMenu.vue.d.ts +33 -0
  4. package/dist/types/components/navigation-menu/NavigationMenu.vue.d.ts.map +1 -0
  5. package/dist/types/components/navigation-menu/NavigationMenuContent.vue.d.ts +29 -0
  6. package/dist/types/components/navigation-menu/NavigationMenuContent.vue.d.ts.map +1 -0
  7. package/dist/types/components/navigation-menu/NavigationMenuItem.vue.d.ts +16 -0
  8. package/dist/types/components/navigation-menu/NavigationMenuItem.vue.d.ts.map +1 -0
  9. package/dist/types/components/navigation-menu/NavigationMenuLink.vue.d.ts +33 -0
  10. package/dist/types/components/navigation-menu/NavigationMenuLink.vue.d.ts.map +1 -0
  11. package/dist/types/components/navigation-menu/NavigationMenuTrigger.vue.d.ts +19 -0
  12. package/dist/types/components/navigation-menu/NavigationMenuTrigger.vue.d.ts.map +1 -0
  13. package/dist/types/components/navigation-menu/composables/useNavigationMenuKeyboard.d.ts +4 -0
  14. package/dist/types/components/navigation-menu/composables/useNavigationMenuKeyboard.d.ts.map +1 -0
  15. package/dist/types/components/navigation-menu/composables/useNavigationMenuLayout.d.ts +12 -0
  16. package/dist/types/components/navigation-menu/composables/useNavigationMenuLayout.d.ts.map +1 -0
  17. package/dist/types/components/navigation-menu/context.d.ts +10 -0
  18. package/dist/types/components/navigation-menu/context.d.ts.map +1 -0
  19. package/dist/types/components/navigation-menu/navigation-menu.variants.d.ts +112 -0
  20. package/dist/types/components/navigation-menu/navigation-menu.variants.d.ts.map +1 -0
  21. package/dist/types/components/navigation-menu/types.d.ts +17 -0
  22. package/dist/types/components/navigation-menu/types.d.ts.map +1 -0
  23. package/dist/types/components/rating/Rating.vue.d.ts +1 -0
  24. package/dist/types/components/rating/Rating.vue.d.ts.map +1 -1
  25. package/dist/types/components/rating/composables/useRatingScale.d.ts +8 -0
  26. package/dist/types/components/rating/composables/useRatingScale.d.ts.map +1 -0
  27. package/dist/types/components/stepper/Stepper.vue.d.ts +36 -0
  28. package/dist/types/components/stepper/Stepper.vue.d.ts.map +1 -0
  29. package/dist/types/components/stepper/StepperStep.vue.d.ts +33 -0
  30. package/dist/types/components/stepper/StepperStep.vue.d.ts.map +1 -0
  31. package/dist/types/components/stepper/composables/useStepper.d.ts +13 -0
  32. package/dist/types/components/stepper/composables/useStepper.d.ts.map +1 -0
  33. package/dist/types/components/stepper/stepper.variants.d.ts +58 -0
  34. package/dist/types/components/stepper/stepper.variants.d.ts.map +1 -0
  35. package/dist/types/components/stepper/types.d.ts +45 -0
  36. package/dist/types/components/stepper/types.d.ts.map +1 -0
  37. package/dist/types/components/timeline/Timeline.vue.d.ts +36 -0
  38. package/dist/types/components/timeline/Timeline.vue.d.ts.map +1 -0
  39. package/dist/types/components/timeline/timeline.variants.d.ts +51 -0
  40. package/dist/types/components/timeline/timeline.variants.d.ts.map +1 -0
  41. package/dist/types/components/timeline/types.d.ts +18 -0
  42. package/dist/types/components/timeline/types.d.ts.map +1 -0
  43. package/dist/types/components/toolbar/Toolbar.vue.d.ts +20 -0
  44. package/dist/types/components/toolbar/Toolbar.vue.d.ts.map +1 -0
  45. package/dist/types/components/toolbar/ToolbarButton.vue.d.ts +18 -0
  46. package/dist/types/components/toolbar/ToolbarButton.vue.d.ts.map +1 -0
  47. package/dist/types/components/toolbar/ToolbarControl.vue.d.ts +22 -0
  48. package/dist/types/components/toolbar/ToolbarControl.vue.d.ts.map +1 -0
  49. package/dist/types/components/toolbar/ToolbarLink.vue.d.ts +24 -0
  50. package/dist/types/components/toolbar/ToolbarLink.vue.d.ts.map +1 -0
  51. package/dist/types/components/toolbar/ToolbarSeparator.vue.d.ts +10 -0
  52. package/dist/types/components/toolbar/ToolbarSeparator.vue.d.ts.map +1 -0
  53. package/dist/types/components/toolbar/ToolbarToggleGroup.vue.d.ts +31 -0
  54. package/dist/types/components/toolbar/ToolbarToggleGroup.vue.d.ts.map +1 -0
  55. package/dist/types/components/toolbar/ToolbarToggleItem.vue.d.ts +21 -0
  56. package/dist/types/components/toolbar/ToolbarToggleItem.vue.d.ts.map +1 -0
  57. package/dist/types/components/toolbar/context.d.ts +13 -0
  58. package/dist/types/components/toolbar/context.d.ts.map +1 -0
  59. package/dist/types/components/toolbar/toolbar.variants.d.ts +64 -0
  60. package/dist/types/components/toolbar/toolbar.variants.d.ts.map +1 -0
  61. package/dist/types/components/toolbar/types.d.ts +28 -0
  62. package/dist/types/components/toolbar/types.d.ts.map +1 -0
  63. package/dist/types/index.d.ts +17 -0
  64. package/dist/types/index.d.ts.map +1 -1
  65. package/dist/types/locale/en-US.d.ts.map +1 -1
  66. package/dist/types/locale/index.d.ts.map +1 -1
  67. package/dist/types/locale/types.d.ts +7 -0
  68. package/dist/types/locale/types.d.ts.map +1 -1
  69. package/dist/types/locale/zh-CN.d.ts.map +1 -1
  70. package/package.json +1 -1
  71. package/src/components/navigation-menu/NavigationMenu.vue +84 -0
  72. package/src/components/navigation-menu/NavigationMenuContent.vue +25 -0
  73. package/src/components/navigation-menu/NavigationMenuItem.vue +13 -0
  74. package/src/components/navigation-menu/NavigationMenuLink.vue +82 -0
  75. package/src/components/navigation-menu/NavigationMenuTrigger.vue +44 -0
  76. package/src/components/navigation-menu/composables/useNavigationMenuKeyboard.ts +33 -0
  77. package/src/components/navigation-menu/composables/useNavigationMenuLayout.ts +72 -0
  78. package/src/components/navigation-menu/context.ts +19 -0
  79. package/src/components/navigation-menu/navigation-menu.variants.ts +82 -0
  80. package/src/components/navigation-menu/types.ts +17 -0
  81. package/src/components/rating/Rating.vue +22 -8
  82. package/src/components/rating/composables/useRatingScale.ts +24 -0
  83. package/src/components/sidebar/Sidebar.vue +1 -1
  84. package/src/components/stepper/Stepper.vue +95 -0
  85. package/src/components/stepper/StepperStep.vue +102 -0
  86. package/src/components/stepper/composables/useStepper.ts +112 -0
  87. package/src/components/stepper/stepper.variants.ts +39 -0
  88. package/src/components/stepper/types.ts +51 -0
  89. package/src/components/timeline/Timeline.vue +109 -0
  90. package/src/components/timeline/timeline.variants.ts +31 -0
  91. package/src/components/timeline/types.ts +20 -0
  92. package/src/components/toolbar/Toolbar.vue +45 -0
  93. package/src/components/toolbar/ToolbarButton.vue +26 -0
  94. package/src/components/toolbar/ToolbarControl.vue +46 -0
  95. package/src/components/toolbar/ToolbarLink.vue +40 -0
  96. package/src/components/toolbar/ToolbarSeparator.vue +20 -0
  97. package/src/components/toolbar/ToolbarToggleGroup.vue +42 -0
  98. package/src/components/toolbar/ToolbarToggleItem.vue +34 -0
  99. package/src/components/toolbar/context.ts +29 -0
  100. package/src/components/toolbar/toolbar.variants.ts +37 -0
  101. package/src/components/toolbar/types.ts +30 -0
  102. package/src/index.ts +45 -0
  103. package/src/locale/en-US.ts +7 -0
  104. package/src/locale/index.ts +1 -0
  105. package/src/locale/types.ts +7 -0
  106. package/src/locale/zh-CN.ts +7 -0
  107. package/src/styles/interaction.css +1 -0
  108. package/src/styles/motion.css +66 -0
  109. package/src/styles/stepper.css +41 -0
  110. package/src/styles/timeline.css +144 -0
  111. package/src/styles/tokens.css +2 -0
@@ -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'
@@ -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',
@@ -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 },
@@ -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
@@ -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: '必填',
@@ -227,6 +227,7 @@
227
227
  @utility hn-ripple-surface {
228
228
  position: absolute;
229
229
  inset: 0;
230
+ direction: ltr;
230
231
  border-radius: inherit;
231
232
  pointer-events: none;
232
233
 
@@ -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
+ }
@@ -0,0 +1,144 @@
1
+ @layer components {
2
+ .hn-timeline {
3
+ --hn-timeline-gap: calc(var(--hn-stack-gap) * 1.5);
4
+ }
5
+
6
+ .hn-timeline-item {
7
+ display: grid;
8
+ }
9
+
10
+ .hn-timeline-marker {
11
+ min-inline-size: 1lh;
12
+ min-block-size: 1lh;
13
+ }
14
+
15
+ .hn-timeline-separator {
16
+ display: flex;
17
+ align-items: center;
18
+ gap: var(--hn-control-gap);
19
+ }
20
+
21
+ .hn-timeline-connector {
22
+ flex: 1;
23
+ }
24
+
25
+ .hn-timeline[data-orientation='vertical'] {
26
+ grid-template-columns: 0 auto minmax(0, 1fr);
27
+
28
+ &[data-align='end'] {
29
+ grid-template-columns: minmax(0, 1fr) auto 0;
30
+ }
31
+
32
+ &[data-opposite],
33
+ &[data-align='alternate'] {
34
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
35
+ }
36
+
37
+ > .hn-timeline-item {
38
+ grid-column: 1 / -1;
39
+ grid-template-columns: subgrid;
40
+
41
+ > .hn-timeline-separator {
42
+ grid-area: 1 / 2;
43
+ flex-direction: column;
44
+ padding-block-end: var(--hn-control-gap);
45
+
46
+ > .hn-timeline-connector {
47
+ inline-size: 1px;
48
+ }
49
+ }
50
+
51
+ > .hn-timeline-content,
52
+ > .hn-timeline-opposite {
53
+ padding-block-end: var(--hn-timeline-gap);
54
+ }
55
+
56
+ > .hn-timeline-content {
57
+ grid-area: 1 / 3;
58
+ padding-inline-start: var(--hn-inline-gap);
59
+ }
60
+
61
+ > .hn-timeline-opposite {
62
+ grid-area: 1 / 1;
63
+ padding-inline-end: var(--hn-inline-gap);
64
+ text-align: end;
65
+ }
66
+
67
+ &[data-side='end'] {
68
+ > .hn-timeline-content {
69
+ grid-column: 1;
70
+ padding-inline: 0 var(--hn-inline-gap);
71
+ text-align: end;
72
+ }
73
+
74
+ > .hn-timeline-opposite {
75
+ grid-column: 3;
76
+ padding-inline: var(--hn-inline-gap) 0;
77
+ text-align: start;
78
+ }
79
+ }
80
+
81
+ &:last-child > .hn-timeline-content,
82
+ &:last-child > .hn-timeline-opposite,
83
+ &:last-child > .hn-timeline-separator {
84
+ padding-block-end: 0;
85
+ }
86
+ }
87
+ }
88
+
89
+ .hn-timeline[data-orientation='horizontal'] {
90
+ grid-auto-flow: column;
91
+ grid-auto-columns: minmax(0, 1fr);
92
+ grid-template-rows: auto auto auto;
93
+
94
+ > .hn-timeline-item {
95
+ grid-row: 1 / -1;
96
+ grid-template-rows: subgrid;
97
+
98
+ > .hn-timeline-separator {
99
+ grid-row: 2;
100
+ padding-inline-end: var(--hn-control-gap);
101
+
102
+ > .hn-timeline-connector {
103
+ block-size: 1px;
104
+ }
105
+ }
106
+
107
+ > .hn-timeline-content,
108
+ > .hn-timeline-opposite {
109
+ padding-inline-end: var(--hn-inline-gap);
110
+ }
111
+
112
+ > .hn-timeline-content {
113
+ grid-row: 3;
114
+ padding-block-start: var(--hn-inline-gap);
115
+ }
116
+
117
+ > .hn-timeline-opposite {
118
+ grid-row: 1;
119
+ padding-block-end: var(--hn-inline-gap);
120
+ align-self: end;
121
+ }
122
+
123
+ &[data-side='end'] {
124
+ > .hn-timeline-content {
125
+ grid-row: 1;
126
+ padding-block: 0 var(--hn-inline-gap);
127
+ align-self: end;
128
+ }
129
+
130
+ > .hn-timeline-opposite {
131
+ grid-row: 3;
132
+ padding-block: var(--hn-inline-gap) 0;
133
+ align-self: start;
134
+ }
135
+ }
136
+
137
+ &:last-child > .hn-timeline-content,
138
+ &:last-child > .hn-timeline-opposite,
139
+ &:last-child > .hn-timeline-separator {
140
+ padding-inline-end: 0;
141
+ }
142
+ }
143
+ }
144
+ }
@@ -9,6 +9,8 @@
9
9
  @import './spoiler.css';
10
10
  @import './scroll.css';
11
11
  @import './data-table.css';
12
+ @import './timeline.css';
13
+ @import './stepper.css';
12
14
  @import './base.css';
13
15
 
14
16
  @source '../components/**/*.vue';