@teammodlr/ui-kit 1.0.4 → 1.0.5

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 (147) hide show
  1. package/package.json +2 -1
  2. package/src/__storybook__/argTypes.ts +42 -0
  3. package/src/__storybook__/createStory.ts +15 -0
  4. package/src/__storybook__/index.ts +2 -0
  5. package/src/components/avatar/Avatar.css +69 -0
  6. package/src/components/avatar/Avatar.vue +102 -0
  7. package/src/components/avatar/examples/basic.vue +6 -0
  8. package/src/components/avatar/examples/custom-size.vue +7 -0
  9. package/src/components/avatar/examples/index.stories.ts +28 -0
  10. package/src/components/avatar/examples/index.ts +5 -0
  11. package/src/components/avatar/examples/sizes.vue +33 -0
  12. package/src/components/avatar/examples/slots.vue +7 -0
  13. package/src/components/avatar/examples/variants.vue +18 -0
  14. package/src/components/avatargroup/AvatarGroup.css +8 -0
  15. package/src/components/avatargroup/AvatarGroup.vue +32 -0
  16. package/src/components/avatargroup/examples/basic.vue +11 -0
  17. package/src/components/avatargroup/examples/index.stories.ts +28 -0
  18. package/src/components/avatargroup/examples/index.ts +1 -0
  19. package/src/components/breadcrumb/Breadcrumb.css +46 -0
  20. package/src/components/breadcrumb/Breadcrumb.vue +51 -0
  21. package/src/components/breadcrumb/examples/basic.vue +9 -0
  22. package/src/components/breadcrumb/examples/index.stories.ts +20 -0
  23. package/src/components/breadcrumb/examples/index.ts +1 -0
  24. package/src/components/breadcrumbitem/BreadcrumbItem.vue +66 -0
  25. package/src/components/breadcrumbitem/index.ts +1 -0
  26. package/src/components/button/Button.css +378 -0
  27. package/src/components/button/Button.vue +108 -0
  28. package/src/components/button/examples/basic.vue +3 -0
  29. package/src/components/button/examples/colors-secondary.vue +8 -0
  30. package/src/components/button/examples/colors.vue +8 -0
  31. package/src/components/button/examples/disabled.vue +3 -0
  32. package/src/components/button/examples/icon.vue +10 -0
  33. package/src/components/button/examples/index.stories.ts +33 -0
  34. package/src/components/button/examples/index.ts +7 -0
  35. package/src/components/button/examples/rounded.vue +7 -0
  36. package/src/components/button/examples/size.vue +7 -0
  37. package/src/components/buttongroup/ButtonGroup.vue +47 -0
  38. package/src/components/buttongroup/examples/basic.vue +9 -0
  39. package/src/components/buttongroup/examples/index.stories.ts +21 -0
  40. package/src/components/buttongroup/examples/index.ts +1 -0
  41. package/src/components/checkbox/Checkbox.css +185 -0
  42. package/src/components/checkbox/Checkbox.vue +140 -0
  43. package/src/components/checkbox/examples/basic.vue +9 -0
  44. package/src/components/checkbox/examples/index.stories.ts +21 -0
  45. package/src/components/checkbox/examples/index.ts +3 -0
  46. package/src/components/checkbox/examples/slot.vue +11 -0
  47. package/src/components/dropdown/Dropdown.css +68 -0
  48. package/src/components/dropdown/Dropdown.vue +237 -0
  49. package/src/components/dropdown/DropdownItem.vue +118 -0
  50. package/src/components/dropdown/DropdownList.vue +20 -0
  51. package/src/components/dropdown/DropdownWrapper.vue +17 -0
  52. package/src/components/dropdown/examples/basic.vue +73 -0
  53. package/src/components/dropdown/examples/context.vue +71 -0
  54. package/src/components/dropdown/examples/index.stories.ts +23 -0
  55. package/src/components/dropdown/examples/index.ts +2 -0
  56. package/src/components/dropdown/hooks.ts +30 -0
  57. package/src/components/form/Form.vue +141 -0
  58. package/src/components/form/examples/basic.vue +73 -0
  59. package/src/components/form/examples/index.stories.ts +23 -0
  60. package/src/components/form/examples/index.ts +1 -0
  61. package/src/components/image/Image.vue +71 -0
  62. package/src/components/image/examples/basic.vue +5 -0
  63. package/src/components/image/examples/index.stories.ts +12 -0
  64. package/src/components/image/examples/index.ts +1 -0
  65. package/src/components/index.ts +27 -0
  66. package/src/components/input/Input.css +173 -0
  67. package/src/components/input/Input.vue +176 -0
  68. package/src/components/input/examples/basic.vue +7 -0
  69. package/src/components/input/examples/index.stories.ts +24 -0
  70. package/src/components/input/examples/index.ts +4 -0
  71. package/src/components/input/examples/prefix.vue +7 -0
  72. package/src/components/input/examples/sizes.vue +9 -0
  73. package/src/components/input/examples/suffix.vue +7 -0
  74. package/src/components/link/Link.css +147 -0
  75. package/src/components/link/Link.vue +54 -0
  76. package/src/components/link/examples/basic.vue +3 -0
  77. package/src/components/link/examples/index.stories.ts +20 -0
  78. package/src/components/link/examples/index.ts +1 -0
  79. package/src/components/messageprovider/Message.vue +76 -0
  80. package/src/components/messageprovider/MessageProvider.css +36 -0
  81. package/src/components/messageprovider/MessageProvider.vue +142 -0
  82. package/src/components/messageprovider/examples/basic.vue +19 -0
  83. package/src/components/messageprovider/examples/index.stories.ts +30 -0
  84. package/src/components/messageprovider/examples/index.ts +1 -0
  85. package/src/components/messageprovider/examples/wrapper.vue +9 -0
  86. package/src/components/messageprovider/types.ts +39 -0
  87. package/src/components/messageprovider/useMessage.ts +12 -0
  88. package/src/components/select/Select.css +226 -0
  89. package/src/components/select/Select.vue +474 -0
  90. package/src/components/select/examples/basic.vue +20 -0
  91. package/src/components/select/examples/index.stories.ts +22 -0
  92. package/src/components/select/examples/index.ts +3 -0
  93. package/src/components/select/examples/multiple.vue +22 -0
  94. package/src/components/select/examples/searchable.vue +20 -0
  95. package/src/components/skeleton/Skeleton.css +73 -0
  96. package/src/components/skeleton/Skeleton.vue +47 -0
  97. package/src/components/skeleton/examples/basic.vue +3 -0
  98. package/src/components/skeleton/examples/index.stories.ts +24 -0
  99. package/src/components/skeleton/examples/index.ts +2 -0
  100. package/src/components/skeleton/examples/post.vue +8 -0
  101. package/src/components/tab/Tab.css +113 -0
  102. package/src/components/tab/Tab.vue +98 -0
  103. package/src/components/tab/TabGroup.vue +90 -0
  104. package/src/components/tab/examples/basic.vue +19 -0
  105. package/src/components/tab/examples/index.stories.ts +25 -0
  106. package/src/components/tab/examples/index.ts +2 -0
  107. package/src/components/tab/examples/vertical.vue +19 -0
  108. package/src/components/table/Table.css +45 -0
  109. package/src/components/table/Table.vue +108 -0
  110. package/src/components/table/TableBody.vue +13 -0
  111. package/src/components/table/TableCell.vue +13 -0
  112. package/src/components/table/TableHead.vue +22 -0
  113. package/src/components/table/TableHeadRow.vue +15 -0
  114. package/src/components/table/TableRow.vue +13 -0
  115. package/src/components/table/examples/basic.vue +46 -0
  116. package/src/components/table/examples/index.stories.ts +19 -0
  117. package/src/components/table/examples/index.ts +1 -0
  118. package/src/components/table/types/index.ts +5 -0
  119. package/src/components/tooltip/Tooltip.css +49 -0
  120. package/src/components/tooltip/Tooltip.vue +85 -0
  121. package/src/components/tooltip/examples/basic.vue +8 -0
  122. package/src/components/tooltip/examples/index.stories.ts +21 -0
  123. package/src/components/tooltip/examples/index.ts +1 -0
  124. package/src/components/virtualscroll/VirtualScroll.css +13 -0
  125. package/src/components/virtualscroll/VirtualScroll.vue +61 -0
  126. package/src/components/virtualscroll/examples/basic.vue +37 -0
  127. package/src/components/virtualscroll/examples/index.stories.ts +31 -0
  128. package/src/components/virtualscroll/examples/index.ts +1 -0
  129. package/src/composables/element.ts +13 -0
  130. package/src/composables/useCachedUid.ts +48 -0
  131. package/src/composables/useEventListener.ts +14 -0
  132. package/src/composables/useInput.ts +134 -0
  133. package/src/composables/useIsServer.ts +7 -0
  134. package/src/composables/useMount.ts +43 -0
  135. package/src/composables/usePopper.ts +194 -0
  136. package/src/create.ts +34 -0
  137. package/src/css/components.css +14 -0
  138. package/src/css/index.css +4 -0
  139. package/src/css/normalize.css +379 -0
  140. package/src/css/transitions.css +40 -0
  141. package/src/css/variables.css +80 -0
  142. package/src/exports/nuxt.js +33 -0
  143. package/src/exports/nuxt.plugin.js +8 -0
  144. package/src/index.ts +5 -0
  145. package/src/install.ts +8 -0
  146. package/src/shims-vue.d.ts +6 -0
  147. package/src/types/props.ts +3 -0
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@teammodlr/ui-kit",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "",
5
5
  "main": "lib/index.cjs.js",
6
6
  "module": "lib/index.es.js",
7
7
  "typings": "lib/index.d.ts",
8
8
  "files": [
9
9
  "lib",
10
+ "src",
10
11
  "*.d.ts"
11
12
  ],
12
13
  "exports": {
@@ -0,0 +1,42 @@
1
+ import { placementWhileList } from "@/composables/usePopper";
2
+
3
+ export const sizeArgType = () => ({
4
+ size: {
5
+ options: ['xs', 'sm', 'md', 'lg', 'xl'],
6
+ control: {
7
+ type: 'select',
8
+ labels: {
9
+ ['Extra Small']: 'xs',
10
+ ['Small']: 'sm',
11
+ ['Medium']: 'md',
12
+ ['Large']: 'lg',
13
+ ['Extra Large']: 'xl'
14
+ }
15
+ }
16
+ }
17
+ });
18
+
19
+ export const colorArgType = () => ({
20
+ color: {
21
+ options: [
22
+ 'white',
23
+ 'black',
24
+ 'green',
25
+ 'red',
26
+ 'yellow',
27
+ 'blue',
28
+ ],
29
+ control: {
30
+ type: 'select',
31
+ }
32
+ }
33
+ });
34
+
35
+ export const popperPositionArgType = () => ({
36
+ placement: {
37
+ options: placementWhileList,
38
+ control: {
39
+ type: 'select',
40
+ }
41
+ }
42
+ })
@@ -0,0 +1,15 @@
1
+ import { h } from 'vue';
2
+ import type { Component } from 'vue';
3
+
4
+ export const createStory =
5
+ (component: Component, storyArgs: { classes?: string } = {}) =>
6
+ (args: any) => ({
7
+ setup: () => () =>
8
+ h(
9
+ 'div',
10
+ {
11
+ class: `storybook-example ${storyArgs.classes || ''}`
12
+ },
13
+ [h(component, args)]
14
+ )
15
+ });
@@ -0,0 +1,2 @@
1
+ export * from './createStory';
2
+ export * from './argTypes';
@@ -0,0 +1,69 @@
1
+ .m-avatar {
2
+ --avatar-height: 40px;
3
+ --avatar-width: 40px;
4
+ --avatar-font-size: 13px;
5
+ --avatar-border-radius: 4px;
6
+ width: var(--avatar-width);
7
+ height: var(--avatar-height);
8
+ font-size: var(--avatar-font-size);
9
+ position: relative;
10
+ display: inline-flex;
11
+ background-color: var(--gray-200);
12
+ color: var(--gray-400);
13
+ overflow: hidden;
14
+ white-space: nowrap;
15
+ vertical-align: middle;
16
+ justify-content: center;
17
+ align-items: center;
18
+ box-sizing: content-box;
19
+ border-radius: var(--avatar-border-radius);
20
+ font-weight: 600;
21
+ user-select: none;
22
+ }
23
+
24
+ .m-avatar img {
25
+ width: 100%;
26
+ height: 100%;
27
+ }
28
+
29
+ .m-avatar--circle {
30
+ --avatar-border-radius: 50%;
31
+ }
32
+
33
+ .m-avatar--rounded {
34
+ --avatar-border-radius: 4px;
35
+ }
36
+
37
+ .m-avatar--square {
38
+ --avatar-border-radius: 0;
39
+ }
40
+
41
+ .m-avatar--xs {
42
+ --avatar-height: 24px;
43
+ --avatar-width: 24px;
44
+ --avatar-font-size: 11px;
45
+ }
46
+
47
+ .m-avatar--sm {
48
+ --avatar-height: 32px;
49
+ --avatar-width: 32px;
50
+ --avatar-font-size: 12px;
51
+ }
52
+
53
+ .m-avatar--md {
54
+ --avatar-height: 40px;
55
+ --avatar-width: 40px;
56
+ --avatar-font-size: 13px;
57
+ }
58
+
59
+ .m-avatar--lg {
60
+ --avatar-height: 48px;
61
+ --avatar-width: 48px;
62
+ --avatar-font-size: 16px;
63
+ }
64
+
65
+ .m-avatar--xl {
66
+ --avatar-height: 56px;
67
+ --avatar-width: 56px;
68
+ --avatar-font-size: 17px;
69
+ }
@@ -0,0 +1,102 @@
1
+ <template>
2
+ <span
3
+ :class="classes"
4
+ :style="customSize"
5
+ ref="avatar"
6
+ >
7
+ <MImage
8
+ v-if="(src || srcSet) && imageExists"
9
+ :src="src"
10
+ :alt="src"
11
+ :srcset="srcSet"
12
+ @error="handleImageLoadError"
13
+ />
14
+ <slot v-else />
15
+ </span>
16
+ </template>
17
+
18
+ <script lang="ts">
19
+ import { defineComponent, ref, computed, inject, onMounted } from 'vue';
20
+ import MImage from '../image/Image.vue';
21
+
22
+ export default defineComponent({
23
+ name: "MAvatar",
24
+ components: {
25
+ MImage,
26
+ },
27
+ props: {
28
+ src: {
29
+ type: String,
30
+ default: ""
31
+ },
32
+ srcSet: {
33
+ type: String,
34
+ default: ""
35
+ },
36
+ size: {
37
+ type: [Number, String],
38
+ default: 'md'
39
+ },
40
+ fit: {
41
+ type: String,
42
+ default: "cover"
43
+ },
44
+ variant: {
45
+ type: String,
46
+ default: "circle"
47
+ }
48
+ },
49
+ emits: {
50
+ error: (e: Event) => true
51
+ },
52
+ setup(props, { emit }) {
53
+ const avatarGroup = inject('avatarGroup', undefined);
54
+ const avatar = ref<HTMLElement | null>(null);
55
+ const imageExists = ref(true);
56
+ const sizeValue = ref('');
57
+
58
+ const groupSize = computed(() => {
59
+ // @ts-ignore
60
+ return avatarGroup?.size
61
+ });
62
+
63
+ const isCustomSize = computed(() => {
64
+ return typeof props.size === 'number' || props.size.includes('px')
65
+ });
66
+
67
+ const customSize = computed(() => {
68
+ return isCustomSize.value ? {
69
+ width: props.size,
70
+ height: props.size
71
+ } : {}
72
+ });
73
+
74
+ const classes = computed(() => {
75
+ return {
76
+ 'm-avatar': true,
77
+ [`m-avatar--${sizeValue.value}`]: !isCustomSize.value,
78
+ [`m-avatar--${props.variant}`]: true
79
+ }
80
+ });
81
+
82
+ const handleImageLoadError = (e: Event) => {
83
+ imageExists.value = false;
84
+ emit('error', e);
85
+ };
86
+
87
+ onMounted(() => {
88
+ sizeValue.value = groupSize.value || props.size;
89
+ });
90
+
91
+ return {
92
+ avatar,
93
+ avatarGroup,
94
+ classes,
95
+ customSize,
96
+ imageExists,
97
+
98
+ handleImageLoadError
99
+ }
100
+ }
101
+ })
102
+ </script>
@@ -0,0 +1,6 @@
1
+ <template>
2
+ <MAvatar
3
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
4
+ variant="rounded"
5
+ />
6
+ </template>
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <MAvatar
3
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
4
+ variant="rounded"
5
+ size="100px"
6
+ />
7
+ </template>
@@ -0,0 +1,28 @@
1
+ import MAvatar from "../Avatar.vue";
2
+
3
+ import {
4
+ MAvatarBasic,
5
+ MAvatarSize,
6
+ MAvatarCustomSize,
7
+ MAvatarVariant,
8
+ MAvatarSlot
9
+ } from "./index";
10
+
11
+ import {
12
+ colorArgType,
13
+ createStory, sizeArgType
14
+ } from "@/__storybook__";
15
+
16
+ export default {
17
+ component: MAvatar,
18
+ title: 'Components/Avatar',
19
+ argTypes: {
20
+ ...sizeArgType()
21
+ }
22
+ }
23
+
24
+ export const Basic = createStory(MAvatarBasic);
25
+ export const Sizes = createStory(MAvatarSize);
26
+ export const CustomSize = createStory(MAvatarCustomSize);
27
+ export const Variants = createStory(MAvatarVariant);
28
+ export const Slots = createStory(MAvatarSlot);
@@ -0,0 +1,5 @@
1
+ export { default as MAvatarBasic } from './basic.vue';
2
+ export { default as MAvatarSize } from './sizes.vue';
3
+ export { default as MAvatarCustomSize } from './custom-size.vue';
4
+ export { default as MAvatarVariant } from './variants.vue';
5
+ export { default as MAvatarSlot } from './slots.vue';
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div>
3
+ <MAvatar
4
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
5
+ variant="rounded"
6
+ size="xs"
7
+ /><br /><br />
8
+
9
+ <MAvatar
10
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
11
+ variant="rounded"
12
+ size="sm"
13
+ /><br /><br />
14
+
15
+ <MAvatar
16
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
17
+ variant="rounded"
18
+ size="md"
19
+ /><br /><br />
20
+
21
+ <MAvatar
22
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
23
+ variant="rounded"
24
+ size="lg"
25
+ /><br /><br />
26
+
27
+ <MAvatar
28
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
29
+ variant="rounded"
30
+ size="xl"
31
+ /><br /><br />
32
+ </div>
33
+ </template>
@@ -0,0 +1,7 @@
1
+ <template>
2
+ <MAvatar
3
+ variant="rounded"
4
+ >
5
+ BV
6
+ </MAvatar>
7
+ </template>
@@ -0,0 +1,18 @@
1
+ <template>
2
+ <div>
3
+ <MAvatar
4
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
5
+ variant="square"
6
+ /><br /><br />
7
+
8
+ <MAvatar
9
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
10
+ variant="rounded"
11
+ /><br /><br />
12
+
13
+ <MAvatar
14
+ src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp"
15
+ variant="circle"
16
+ /><br /><br />
17
+ </div>
18
+ </template>
@@ -0,0 +1,8 @@
1
+ .m-avatar-group .m-avatar:not(:last-child) {
2
+ margin-right: calc(0px - 10px);
3
+ }
4
+
5
+
6
+ .m-avatar-group .m-avatar {
7
+ border: 2px solid var(--white);
8
+ }
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <div class="m-avatar-group">
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script lang="ts">
8
+ import { defineComponent, provide } from 'vue';
9
+
10
+
11
+ export default defineComponent({
12
+ name: "MAvatarGroup",
13
+ props: {
14
+ max: {
15
+ type: Number,
16
+ default: 5
17
+ },
18
+ size: {
19
+ type: [Number, String],
20
+ default: 'md'
21
+ }
22
+ },
23
+ setup(props) {
24
+
25
+ provide('avatarGroup', props);
26
+
27
+ return {
28
+ props
29
+ }
30
+ }
31
+ })
32
+ </script>
@@ -0,0 +1,11 @@
1
+
2
+
3
+ <template>
4
+ <MAvatarGroup>
5
+ <MAvatar src="https://cdn.discordapp.com/avatars/314170125915783180/9f71af5f78d3188a0c92800c94112496.webp" variant="circle" />
6
+ <MAvatar src="https://cdn.vuetifyjs.com/images/lists/2.jpg" variant="circle" />
7
+ <MAvatar src="https://cdn.vuetifyjs.com/images/lists/3.jpg" variant="circle" />
8
+ <MAvatar src="https://cdn.vuetifyjs.com/images/lists/4.jpg" variant="circle" />
9
+ <MAvatar src="https://cdn.vuetifyjs.com/images/lists/5.jpg" variant="circle" />
10
+ </MAvatarGroup>
11
+ </template>
@@ -0,0 +1,28 @@
1
+ import MAvatarGroup from "../AvatarGroup.vue";
2
+ import MAvatar from "../../avatar/Avatar.vue";
3
+
4
+ import {
5
+ MAvatarGroupBasic
6
+ } from "./index";
7
+
8
+ import {
9
+ createStory
10
+ } from "@/__storybook__";
11
+
12
+ export default {
13
+ component: MAvatarGroup,
14
+ subcomponents: {
15
+ MAvatar
16
+ },
17
+ title: 'Components/Avatar Group',
18
+ argTypes: {
19
+ size: {
20
+ control: {
21
+ type: 'select',
22
+ options: ['xs', 'sm', 'md', 'lg', 'xl']
23
+ }
24
+ },
25
+ }
26
+ }
27
+
28
+ export const Basic = createStory(MAvatarGroupBasic);
@@ -0,0 +1 @@
1
+ export { default as MAvatarGroupBasic } from './basic.vue';
@@ -0,0 +1,46 @@
1
+ .m-breadcrumbs {
2
+ display: flex;
3
+ list-style: none;
4
+ margin: 0;
5
+ padding: 4px;
6
+ font-variant-numeric: tabular-nums;
7
+ align-items: center;
8
+ position: relative;
9
+ }
10
+
11
+ .m-breadcrumbs__item:last-child .m-breadcrumbs__item-separator {
12
+ display: none;
13
+ }
14
+
15
+ .m-breadcrumbs__item {
16
+ display: flex;
17
+ align-items: center;
18
+ outline: none;
19
+ cursor: pointer;
20
+ color: var(--gray-600);
21
+ }
22
+
23
+ .m-breadcrumbs__link {
24
+ padding: 4px 10px;
25
+ font-size: 14px;
26
+ border-radius: 4px;
27
+ background-color: transparent;
28
+ text-decoration: none;
29
+ outline: none;
30
+ transition: color .3s cubic-bezier(0.4, 0, 0.2, 1), background-color .3s cubic-bezier(0.4, 0, 0.2, 1), border-color .3s cubic-bezier(0.4, 0, 0.2, 1), box-shadow .3s cubic-bezier(0.4, 0, 0.2, 1);
31
+ }
32
+
33
+ .m-breadcrumbs__link:hover {
34
+ color: var(--blue-dark);
35
+ background-color: var(--gray-100);
36
+ }
37
+
38
+ .m-breadcrumbs__item-separator {
39
+ display: inline-flex;
40
+ padding: 0 6px;
41
+ cursor: default;
42
+ user-select: none;
43
+ color: var(--gray-300);
44
+ /*font-style: italic;*/
45
+ /*border-right: 2px solid transparent;*/
46
+ }
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <ol :class="classes">
3
+ <slot />
4
+ </ol>
5
+ </template>
6
+
7
+ <script lang="ts">
8
+ import {
9
+ defineComponent, reactive, computed, provide, toRef
10
+ } from "vue";
11
+
12
+ interface BreadcrumbState {
13
+ separator: string,
14
+ refreshItems: () => void
15
+ }
16
+
17
+ export default defineComponent({
18
+ name: "Breadcrumb",
19
+ components: {
20
+ BreadcrumbItem: () => import("../breadcrumbitem/BreadcrumbItem.vue")
21
+ },
22
+ props: {
23
+ seperator: {
24
+ type: String,
25
+ default: "/"
26
+ }
27
+ },
28
+ setup(props) {
29
+ const refreshItems = () => { };
30
+
31
+ const state: BreadcrumbState = reactive({
32
+ separator: toRef(props, 'seperator'),
33
+ refreshItems
34
+ });
35
+
36
+ const classes = computed(() => {
37
+ return {
38
+ 'm-breadcrumbs': true
39
+ }
40
+ });
41
+
42
+ provide('breadcrumb', state);
43
+
44
+ return {
45
+ props,
46
+ refreshItems,
47
+ classes
48
+ }
49
+ }
50
+ })
51
+ </script>
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <div>
3
+ <MBreadcrumb>
4
+ <MBreadcrumbItem>Home</MBreadcrumbItem>
5
+ <MBreadcrumbItem>Category One</MBreadcrumbItem>
6
+ <MBreadcrumbItem>Category Two</MBreadcrumbItem>
7
+ </MBreadcrumb>
8
+ </div>
9
+ </template>
@@ -0,0 +1,20 @@
1
+ import MBreadcrumb from "../Breadcrumb.vue";
2
+ import MBreadcrumbItem from "../../breadcrumbitem/BreadcrumbItem.vue";
3
+
4
+ import {
5
+ MBreadcrumbBasic
6
+ } from "./index";
7
+
8
+ import {
9
+ createStory
10
+ } from "@/__storybook__";
11
+
12
+ export default {
13
+ component: MBreadcrumb,
14
+ subcomponents: {
15
+ MBreadcrumbItem
16
+ },
17
+ title: 'Components/Breadcrumb',
18
+ }
19
+
20
+ export const Basic = createStory(MBreadcrumbBasic);
@@ -0,0 +1 @@
1
+ export { default as MBreadcrumbBasic } from './basic.vue';
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <li class="m-breadcrumbs__item">
3
+ <a tabindex="0" @click="handleClick" class="m-breadcrumbs__link">
4
+ <slot>{{ label }}</slot>
5
+ </a>
6
+ <span class="m-breadcrumbs__item-separator" role="separator">
7
+ {{ separator }}
8
+ </span>
9
+ </li>
10
+ </template>
11
+
12
+ <script lang="ts">
13
+ import {
14
+ defineComponent, ref, reactive, watch, inject, onBeforeUnmount
15
+ } from "vue";
16
+
17
+ interface BreadcrumbItemState {
18
+ label: string | number;
19
+ }
20
+
21
+ export default defineComponent({
22
+ name: 'BreadcrumbItem',
23
+ props: {
24
+ label: {
25
+ type: [String, Number],
26
+ default: null
27
+ }
28
+ },
29
+ setup(props) {
30
+ const breadcrumbState = inject("breadcrumb");
31
+
32
+ const label = ref(props.label);
33
+ const separator = ref("/");
34
+
35
+ watch(
36
+ () => props.label,
37
+ value => {
38
+ label.value = value;
39
+ // @ts-ignore
40
+ breadcrumbState?.refreshItems()
41
+ }
42
+ )
43
+
44
+ if (breadcrumbState) {
45
+ const state: BreadcrumbItemState = reactive({
46
+ label: label
47
+ })
48
+
49
+ // @ts-ignore
50
+ watch(() => breadcrumbState.separator, value => separator.value = value, { immediate: true });
51
+
52
+ onBeforeUnmount(() => { });
53
+ }
54
+
55
+ const handleClick = () => { };
56
+
57
+ return {
58
+ label,
59
+ separator,
60
+
61
+ handleClick
62
+ }
63
+ }
64
+ })
65
+ </script>
66
+
@@ -0,0 +1 @@
1
+ export { default as MBreadcrumbItem } from './MBreadcrumbItem.vue';