@flyanra/vue-core 0.1.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.
Files changed (76) hide show
  1. package/README.md +176 -0
  2. package/dist/types/components/AppButton/AppButton.types.d.ts +8 -0
  3. package/dist/types/components/AppButton/AppButton.vue.d.ts +20 -0
  4. package/dist/types/components/AppButton/index.d.ts +4 -0
  5. package/dist/types/components/AppCard/AppCard.types.d.ts +5 -0
  6. package/dist/types/components/AppCard/AppCard.vue.d.ts +17 -0
  7. package/dist/types/components/AppCard/index.d.ts +4 -0
  8. package/dist/types/components/basic/fly-button/FlyButton.types.d.ts +25 -0
  9. package/dist/types/components/basic/fly-button/FlyButton.vue.d.ts +26 -0
  10. package/dist/types/components/basic/fly-button/index.d.ts +4 -0
  11. package/dist/types/components/basic/index.d.ts +2 -0
  12. package/dist/types/components/feedback/index.d.ts +2 -0
  13. package/dist/types/components/feedback/tooltip/FlyTooltip.types.d.ts +4 -0
  14. package/dist/types/components/feedback/tooltip/FlyTooltip.vue.d.ts +16 -0
  15. package/dist/types/components/feedback/tooltip/index.d.ts +4 -0
  16. package/dist/types/components/general/fly-icon/FlyIcon.types.d.ts +7 -0
  17. package/dist/types/components/general/fly-icon/FlyIcon.vue.d.ts +6 -0
  18. package/dist/types/components/general/fly-icon/index.d.ts +4 -0
  19. package/dist/types/components/general/index.d.ts +2 -0
  20. package/dist/types/components/index.d.ts +9 -0
  21. package/dist/types/components/navigation/index.d.ts +1 -0
  22. package/dist/types/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.types.d.ts +7 -0
  23. package/dist/types/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.vue.d.ts +8 -0
  24. package/dist/types/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebarItem.vue.d.ts +7 -0
  25. package/dist/types/components/navigation/menu/fly-mini-sidebar/index.d.ts +4 -0
  26. package/dist/types/components/navigation/menu/fly-sidebar/FlySidebar.types.d.ts +29 -0
  27. package/dist/types/components/navigation/menu/fly-sidebar/FlySidebar.vue.d.ts +8 -0
  28. package/dist/types/components/navigation/menu/fly-sidebar/FlySidebarNode.vue.d.ts +7 -0
  29. package/dist/types/components/navigation/menu/fly-sidebar/index.d.ts +4 -0
  30. package/dist/types/components/navigation/menu/index.d.ts +4 -0
  31. package/dist/types/index.d.ts +1 -0
  32. package/package.json +123 -0
  33. package/src/components/AppButton/AppButton.element.scss +2 -0
  34. package/src/components/AppButton/AppButton.types.ts +10 -0
  35. package/src/components/AppButton/AppButton.vue +65 -0
  36. package/src/components/AppButton/index.ts +6 -0
  37. package/src/components/AppCard/AppCard.types.ts +5 -0
  38. package/src/components/AppCard/AppCard.vue +58 -0
  39. package/src/components/AppCard/index.ts +6 -0
  40. package/src/components/basic/fly-button/FlyButton.element.scss +3 -0
  41. package/src/components/basic/fly-button/FlyButton.mixins.scss +58 -0
  42. package/src/components/basic/fly-button/FlyButton.types.ts +29 -0
  43. package/src/components/basic/fly-button/FlyButton.vue +180 -0
  44. package/src/components/basic/fly-button/index.ts +11 -0
  45. package/src/components/basic/index.ts +2 -0
  46. package/src/components/feedback/index.ts +2 -0
  47. package/src/components/feedback/tooltip/FlyTooltip.element.scss +4 -0
  48. package/src/components/feedback/tooltip/FlyTooltip.types.ts +5 -0
  49. package/src/components/feedback/tooltip/FlyTooltip.vue +59 -0
  50. package/src/components/feedback/tooltip/index.ts +6 -0
  51. package/src/components/general/fly-icon/FlyIcon.types.ts +12 -0
  52. package/src/components/general/fly-icon/FlyIcon.vue +24 -0
  53. package/src/components/general/fly-icon/index.ts +6 -0
  54. package/src/components/general/index.ts +2 -0
  55. package/src/components/index.ts +12 -0
  56. package/src/components/navigation/index.ts +1 -0
  57. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.element.scss +2 -0
  58. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.types.ts +8 -0
  59. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebar.vue +46 -0
  60. package/src/components/navigation/menu/fly-mini-sidebar/FlyMiniSidebarItem.vue +55 -0
  61. package/src/components/navigation/menu/fly-mini-sidebar/index.ts +6 -0
  62. package/src/components/navigation/menu/fly-sidebar/FlySidebar.element.scss +9 -0
  63. package/src/components/navigation/menu/fly-sidebar/FlySidebar.types.ts +36 -0
  64. package/src/components/navigation/menu/fly-sidebar/FlySidebar.vue +150 -0
  65. package/src/components/navigation/menu/fly-sidebar/FlySidebarNode.vue +47 -0
  66. package/src/components/navigation/menu/fly-sidebar/index.ts +12 -0
  67. package/src/components/navigation/menu/index.ts +5 -0
  68. package/src/index.ts +1 -0
  69. package/src/styles/_scss-tokens.scss +76 -0
  70. package/src/styles/element/common.scss +57 -0
  71. package/src/styles/element/config.scss +3 -0
  72. package/src/styles/element/dark.scss +39 -0
  73. package/src/styles/index.d.ts +1 -0
  74. package/src/styles/index.scss +5 -0
  75. package/src/styles/mixins/shadows.scss +15 -0
  76. package/src/styles/tokens.scss +83 -0
@@ -0,0 +1,65 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue'
3
+
4
+ import { ElButton } from 'element-plus'
5
+
6
+ import './AppButton.element.scss'
7
+ import type { AppButtonProps } from './AppButton.types'
8
+
9
+ const props = withDefaults(defineProps<AppButtonProps>(), {
10
+ disabled: false,
11
+ label: 'Button',
12
+ size: 'md',
13
+ variant: 'primary'
14
+ })
15
+
16
+ const buttonType = computed(() => {
17
+ if (props.variant === 'primary') {
18
+ return 'primary'
19
+ }
20
+
21
+ return 'default'
22
+ })
23
+
24
+ const buttonSize = computed(() => {
25
+ if (props.size === 'sm') {
26
+ return 'small'
27
+ }
28
+
29
+ if (props.size === 'lg') {
30
+ return 'large'
31
+ }
32
+
33
+ return 'default'
34
+ })
35
+
36
+ const isPlain = computed(() => props.variant === 'secondary')
37
+ const isText = computed(() => props.variant === 'ghost')
38
+ </script>
39
+
40
+ <template>
41
+ <ElButton
42
+ :disabled="props.disabled"
43
+ :plain="isPlain"
44
+ :size="buttonSize"
45
+ :text="isText"
46
+ :type="buttonType"
47
+ >
48
+ <slot>{{ props.label }}</slot>
49
+ </ElButton>
50
+ </template>
51
+
52
+ <style scoped>
53
+ :deep(.el-button) {
54
+ font-weight: 600;
55
+ box-shadow: 0 10px 24px rgba(23, 32, 51, 0.12);
56
+ }
57
+
58
+ :deep(.el-button.is-text) {
59
+ padding-inline: 0.25rem;
60
+ }
61
+
62
+ :global(html.dark) :deep(.el-button:not(.is-text)) {
63
+ box-shadow: 0 12px 30px rgba(0, 0, 0, 0.28);
64
+ }
65
+ </style>
@@ -0,0 +1,6 @@
1
+ import AppButton from './AppButton.vue'
2
+
3
+ export default AppButton
4
+ export { AppButton }
5
+
6
+ export type { AppButtonProps, AppButtonSize, AppButtonVariant } from './AppButton.types'
@@ -0,0 +1,5 @@
1
+ export interface AppCardProps {
2
+ eyebrow?: string
3
+ title: string
4
+ body?: string
5
+ }
@@ -0,0 +1,58 @@
1
+ <script setup lang="ts">
2
+ import type { AppCardProps } from './AppCard.types'
3
+
4
+ const props = withDefaults(defineProps<AppCardProps>(), {
5
+ eyebrow: 'Featured',
6
+ body: ''
7
+ })
8
+ </script>
9
+
10
+ <template>
11
+ <article class="app-card">
12
+ <p v-if="props.eyebrow" class="app-card__eyebrow">{{ props.eyebrow }}</p>
13
+ <h2 class="app-card__title">{{ props.title }}</h2>
14
+ <p v-if="props.body" class="app-card__body">{{ props.body }}</p>
15
+ <div v-if="$slots.default" class="app-card__content">
16
+ <slot />
17
+ </div>
18
+ </article>
19
+ </template>
20
+
21
+ <style scoped>
22
+ .app-card {
23
+ display: grid;
24
+ gap: 0.75rem;
25
+ padding: 1.25rem;
26
+ background: #ffffff;
27
+ border: 1px solid #e5e7eb;
28
+ border-radius: 1rem;
29
+ box-shadow: 0 14px 30px rgba(17, 24, 39, 0.08);
30
+ color: #111827;
31
+ }
32
+
33
+ .app-card__eyebrow {
34
+ margin: 0;
35
+ font-size: 0.8rem;
36
+ font-weight: 700;
37
+ letter-spacing: 0.08em;
38
+ text-transform: uppercase;
39
+ color: #2563eb;
40
+ }
41
+
42
+ .app-card__title {
43
+ margin: 0;
44
+ font-size: 1.125rem;
45
+ line-height: 1.3;
46
+ }
47
+
48
+ .app-card__body {
49
+ margin: 0;
50
+ line-height: 1.6;
51
+ color: #4b5563;
52
+ }
53
+
54
+ .app-card__content {
55
+ display: grid;
56
+ gap: 0.75rem;
57
+ }
58
+ </style>
@@ -0,0 +1,6 @@
1
+ import AppCard from './AppCard.vue'
2
+
3
+ export default AppCard
4
+ export { AppCard }
5
+
6
+ export type { AppCardProps } from './AppCard.types'
@@ -0,0 +1,3 @@
1
+ @use '../../../styles/element/common.scss' as *;
2
+
3
+ @use 'element-plus/theme-chalk/src/button.scss' as *;
@@ -0,0 +1,58 @@
1
+ @use '././../../../styles/mixins/shadows.scss' as shadow;
2
+
3
+ $disabledOpacity: 0.5;
4
+
5
+ @mixin fly-button-overrides {
6
+ &.ep-button {
7
+ &.aspect-1 {
8
+ aspect-ratio: 1;
9
+ }
10
+
11
+ &.active {
12
+ border-color: var(--anra-primary);
13
+ @include shadow.shadow-lg;
14
+ }
15
+
16
+ &--primary {
17
+ &:not(.is-link) {
18
+ --ep-button-text-color: var(--anra-white);
19
+ --ep-button-hover-text-color: var(--anra-white);
20
+
21
+ &.is-plain {
22
+ --ep-button-text-color: var(--default-text-color);
23
+ }
24
+ }
25
+ }
26
+ &--success {
27
+ --ep-button-text-color: var(--dynamic-dark);
28
+ --ep-button-hover-text-color: var(--dynamic-dark);
29
+
30
+ &.is-plain {
31
+ --ep-button-text-color: var(--default-text-color);
32
+ }
33
+ }
34
+ &--warning {
35
+ --ep-button-text-color: var(--dynamic-dark);
36
+ --ep-button-hover-text-color: var(--dynamic-dark);
37
+
38
+ &.is-plain {
39
+ --ep-button-text-color: var(--default-text-color);
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ @mixin fly-button-overrides-dark {
46
+ &.ep-button {
47
+ &--primary {
48
+ &:not(.is-link) {
49
+ --ep-button-text-color: var(--anra-black);
50
+ --ep-button-hover-text-color: var(--anra-black);
51
+
52
+ &.is-plain {
53
+ --ep-button-text-color: var(--default-text-color);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,29 @@
1
+ import type { ButtonType, ElButton, UseTooltipProps } from 'element-plus'
2
+
3
+ import type { T_FlyIconTypes } from '../../general/fly-icon/FlyIcon.types'
4
+
5
+ export type FlyButtonIconPosition = 'left' | 'right'
6
+
7
+ export type FlyButtonSizes = InstanceType<typeof ElButton>['$props']['size']
8
+ export type FlyButtonTypes = ButtonType
9
+
10
+ export type FlyButtonProps = {
11
+ active?: boolean
12
+ appButtonClass?: string
13
+ aspect1?: boolean
14
+ /**
15
+ * Test
16
+ */
17
+ clipRound?: boolean
18
+ full?: boolean
19
+ icon?: string | object
20
+ iconPosition?: FlyButtonIconPosition
21
+ iconType?: T_FlyIconTypes
22
+ imageUrl?: string
23
+ label?: string
24
+ size?: FlyButtonSizes
25
+ stop?: boolean
26
+ title?: string
27
+ tooltip?: UseTooltipProps
28
+ type?: FlyButtonTypes
29
+ }
@@ -0,0 +1,180 @@
1
+ <template>
2
+ <div class="fly-button" :class="[{ full }, appButtonClass]">
3
+ <FlyTooltip
4
+ :tooltip="{
5
+ // effect: 'dark',
6
+ content: title,
7
+ placement: tooltip?.placement ?? 'bottom',
8
+ disabled: !!tooltip?.disabled || isEmpty(title)
9
+ }"
10
+ >
11
+ <el-button
12
+ v-bind="additionalButtonBindingValues"
13
+ :class="[{ active, 'aspect-1': aspect1 }]"
14
+ @click="handleClick"
15
+ >
16
+ <FlyIcon
17
+ v-if="icon && resolvedIconPosition === 'left'"
18
+ :type="iconType"
19
+ :icon="icon"
20
+ :class="[{ 'left-icon': slots.default }]"
21
+ />
22
+
23
+ <slot></slot>
24
+
25
+ <FlyIcon
26
+ v-if="icon && resolvedIconPosition === 'right'"
27
+ :type="iconType"
28
+ :icon="icon"
29
+ :class="[{ 'right-icon': slots.default }]"
30
+ />
31
+
32
+ <span v-if="imageUrl" class="btn-image" :class="[{ 'clip-round': clipRound }]">
33
+ <img :src="imageUrl" />
34
+ </span>
35
+ </el-button>
36
+ </FlyTooltip>
37
+ </div>
38
+ </template>
39
+
40
+ <script lang="ts" setup>
41
+ import { computed, useAttrs, useSlots } from 'vue'
42
+
43
+ import { ElButton } from 'element-plus'
44
+
45
+ import { isEmpty } from 'lodash'
46
+
47
+ import FlyTooltip from '../../feedback/tooltip/FlyTooltip.vue'
48
+ import FlyIcon from '../../general/fly-icon/FlyIcon.vue'
49
+
50
+ import './FlyButton.element.scss'
51
+ import type { FlyButtonIconPosition, FlyButtonProps } from './FlyButton.types'
52
+
53
+ const attrs = useAttrs()
54
+ const slots = useSlots()
55
+ const emit = defineEmits(['click'])
56
+
57
+ defineOptions({
58
+ inheritAttrs: false
59
+ })
60
+
61
+ const props = withDefaults(defineProps<FlyButtonProps>(), {
62
+ active: false,
63
+ aspect1: false,
64
+ clipRound: false,
65
+ full: false,
66
+ stop: false,
67
+ tooltip: () => ({
68
+ placement: 'bottom',
69
+ disabled: false
70
+ })
71
+ })
72
+
73
+ const additionalButtonBindingValues = computed(() => {
74
+ const { type, size } = props
75
+
76
+ return {
77
+ ...attrs,
78
+ size,
79
+ type
80
+ } as object
81
+ })
82
+
83
+ const resolvedIconPosition = computed<FlyButtonIconPosition>(() => props.iconPosition || 'left')
84
+
85
+ function handleClick(e: MouseEvent) {
86
+ /**
87
+ * Stop the event propagation if the stop prop is set to true
88
+ */
89
+ if (props.stop) {
90
+ e.stopPropagation()
91
+ }
92
+
93
+ emit('click', e)
94
+ }
95
+ </script>
96
+
97
+ <style lang="scss" scoped>
98
+ .fly-button {
99
+ pointer-events: auto;
100
+
101
+ &.full button {
102
+ width: 100%;
103
+ }
104
+
105
+ :deep(.ep-button) {
106
+ &.active {
107
+ /* 1px ring stile */
108
+ box-shadow: 0 0 0 1px var(--anra-white);
109
+ }
110
+
111
+ .fly-icon {
112
+ svg {
113
+ width: calc(1em + 2px);
114
+ }
115
+ }
116
+ }
117
+
118
+ :deep(.fly-icon.left-icon) {
119
+ padding-inline-end: 0.25rem;
120
+ }
121
+
122
+ :deep(.fly-icon.right-icon) {
123
+ padding-inline-start: 0.25rem;
124
+ }
125
+
126
+ .btn-image {
127
+ display: flex;
128
+ align-items: center;
129
+ justify-content: center;
130
+ position: absolute;
131
+ top: 0;
132
+ left: 0;
133
+ right: 0;
134
+ bottom: 0;
135
+
136
+ &.clip-round {
137
+ -webkit-box-align: stretch;
138
+ align-items: stretch;
139
+ border-radius: 50%;
140
+ box-sizing: content-box;
141
+ display: flex;
142
+ flex-direction: column;
143
+ -webkit-box-pack: center;
144
+ justify-content: center;
145
+ overflow: hidden;
146
+
147
+ img {
148
+ border: 5px solid transparent;
149
+ border-radius: 50%;
150
+ display: flex;
151
+ width: 100%;
152
+ height: 100%;
153
+ flex: 1 1 100%;
154
+ }
155
+ }
156
+ }
157
+ }
158
+ </style>
159
+
160
+ <style lang="scss">
161
+ @use './FlyButton.mixins.scss' as button;
162
+
163
+ .ep-button-group {
164
+ display: flex;
165
+ }
166
+
167
+ html.dark {
168
+ button.ep-button {
169
+ @include button.fly-button-overrides-dark;
170
+ }
171
+ }
172
+
173
+ button.ep-button {
174
+ position: relative;
175
+ overflow: hidden;
176
+ transition: 0.1s;
177
+ text-wrap: balance;
178
+ @include button.fly-button-overrides;
179
+ }
180
+ </style>
@@ -0,0 +1,11 @@
1
+ import FlyButton from './FlyButton.vue'
2
+
3
+ export default FlyButton
4
+ export { FlyButton }
5
+
6
+ export type {
7
+ FlyButtonProps,
8
+ FlyButtonSizes,
9
+ FlyButtonIconPosition,
10
+ FlyButtonTypes
11
+ } from './FlyButton.types'
@@ -0,0 +1,2 @@
1
+ export { default as FlyButton } from './fly-button'
2
+ export type * from './fly-button'
@@ -0,0 +1,2 @@
1
+ export { default as FlyTooltip } from './tooltip'
2
+ export type * from './tooltip'
@@ -0,0 +1,4 @@
1
+ @use '../../../../styles/element/common.scss' as *;
2
+
3
+ @use 'element-plus/theme-chalk/src/popper.scss' as *;
4
+ @use 'element-plus/theme-chalk/src/tooltip.scss' as *;
@@ -0,0 +1,5 @@
1
+ import type { UseTooltipProps } from 'element-plus'
2
+
3
+ export type T_FlyTooltipProps = {
4
+ tooltip?: UseTooltipProps
5
+ }
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <el-tooltip
3
+ v-bind="mergedElProps"
4
+ :popper-class="`fly-tooltip-popper ${popperClasses}`"
5
+ class="fly-tooltip"
6
+ >
7
+ <template v-if="$slots.default">
8
+ <slot></slot>
9
+ </template>
10
+
11
+ <template v-if="$slots.content" #content>
12
+ <slot name="content"></slot>
13
+ </template>
14
+ </el-tooltip>
15
+ </template>
16
+
17
+ <script lang="ts" setup>
18
+ import { computed } from 'vue'
19
+
20
+ import { ElTooltip, type UseTooltipProps } from 'element-plus'
21
+
22
+ import type { T_FlyTooltipProps } from './FlyTooltip.types'
23
+
24
+ const props = defineProps<T_FlyTooltipProps>()
25
+
26
+ const mergedElProps = computed<UseTooltipProps>(() => {
27
+ return {
28
+ enterable: false,
29
+ showAfter: 1000,
30
+ ...props.tooltip
31
+ }
32
+ })
33
+
34
+ const popperClasses = computed(() => {
35
+ const classes = []
36
+
37
+ if (!mergedElProps.value.enterable) {
38
+ classes.push('fly-tooltip-popper__no-enter')
39
+ }
40
+
41
+ return classes.join(' ')
42
+ })
43
+ </script>
44
+
45
+ <style lang="scss">
46
+ @use '../../../styles/mixins/shadows.scss' as shadow;
47
+
48
+ .fly-tooltip-popper {
49
+ @include shadow.shadow-lg;
50
+ max-width: 400px;
51
+
52
+ &__no-enter {
53
+ .fly-tooltip {
54
+ pointer-events: none;
55
+ max-width: 400px;
56
+ }
57
+ }
58
+ }
59
+ </style>
@@ -0,0 +1,6 @@
1
+ import FlyTooltip from './FlyTooltip.vue'
2
+
3
+ export default FlyTooltip
4
+ export { FlyTooltip }
5
+
6
+ export type { T_FlyTooltipProps } from './FlyTooltip.types'
@@ -0,0 +1,12 @@
1
+ import { type Component } from 'vue'
2
+
3
+ export type T_FlyIconTypes = 'mdi' | 'ri'
4
+
5
+ export type T_FlyIcon =
6
+ | string // mdi:home
7
+ | Component // RiHomeLine, EP icons, etc.
8
+
9
+ export type T_FlyIconProps = {
10
+ type?: T_FlyIconTypes
11
+ icon: T_FlyIcon
12
+ }
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <i class="fly-icon">
3
+ <svg-icon v-if="iconType === 'mdi'" :type="iconType" :path="icon as string" />
4
+ <component :is="icon" v-else-if="iconType === 'ri'" />
5
+ </i>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ import { computed } from 'vue'
10
+
11
+ import SvgIcon from '@jamescoyle/vue-icon'
12
+
13
+ import type { T_FlyIconProps } from './FlyIcon.types.ts'
14
+
15
+ type Props = T_FlyIconProps
16
+
17
+ const props = withDefaults(defineProps<Props>(), {
18
+ type: 'mdi'
19
+ })
20
+
21
+ const iconType = computed(() => props.type || 'mdi')
22
+ </script>
23
+
24
+ <style lang="scss" scoped></style>
@@ -0,0 +1,6 @@
1
+ import FlyIcon from './FlyIcon.vue'
2
+
3
+ export default FlyIcon
4
+ export { FlyIcon }
5
+
6
+ export type { T_FlyIconProps } from './FlyIcon.types.ts'
@@ -0,0 +1,2 @@
1
+ export { default as FlyIcon } from './fly-icon'
2
+ export type * from './fly-icon'
@@ -0,0 +1,12 @@
1
+ export { default as AppButton } from './AppButton'
2
+ export type * from './AppButton'
3
+
4
+ export { default as AppCard } from './AppCard'
5
+ export type * from './AppCard'
6
+
7
+ export * from './navigation'
8
+
9
+ export * from './basic'
10
+ export * from './feedback'
11
+ export * from './general'
12
+ export * from './navigation'
@@ -0,0 +1 @@
1
+ export * from './menu'
@@ -0,0 +1,2 @@
1
+ @use '../../../../styles/element/common.scss' as *;
2
+ @use 'element-plus/theme-chalk/src/scrollbar.scss' as *;
@@ -0,0 +1,8 @@
1
+ import type { T_FlyIconProps } from '../../../general/fly-icon'
2
+
3
+ export type T_FlyMiniSidebarItem = {
4
+ key: string | number
5
+ label: string
6
+ path: string
7
+ icon: T_FlyIconProps
8
+ }
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <aside class="anra-mini-sidebar">
3
+ <el-scrollbar>
4
+ <div class="anra-mini-sidebar__menu">
5
+ <FlyMiniSidebarItem v-for="item in menu" :key="item.key" :menu="item" />
6
+ </div>
7
+ </el-scrollbar>
8
+ </aside>
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import { ElScrollbar } from 'element-plus'
13
+
14
+ import './FlyMiniSidebar.element.scss'
15
+ import type { T_FlyMiniSidebarItem } from './FlyMiniSidebar.types'
16
+ import FlyMiniSidebarItem from './FlyMiniSidebarItem.vue'
17
+
18
+ defineProps<{
19
+ menu: T_FlyMiniSidebarItem[]
20
+ }>()
21
+ </script>
22
+
23
+ <style lang="scss">
24
+ .anra-mini-sidebar {
25
+ background-color: var(--anra-bg-20);
26
+ width: 5rem;
27
+ border-inline-end: 1px solid var(--anra-border-color);
28
+ flex-shrink: 0;
29
+ height: 100%;
30
+ padding-top: 0.5rem;
31
+ padding-bottom: 0.5rem;
32
+ overflow: hidden;
33
+
34
+ &wrapper {
35
+ flex-grow: 1;
36
+ padding-top: 0.5rem;
37
+ overflow-y: auto;
38
+ }
39
+
40
+ &__menu {
41
+ display: flex;
42
+ flex-direction: column;
43
+ gap: 0.5rem;
44
+ }
45
+ }
46
+ </style>