@teammodlr/ui-kit 2.3.1 → 2.3.2

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 (29) hide show
  1. package/lib/components/cardcontextmenu/CardContextMenu.vue.d.ts +129 -0
  2. package/lib/components/cardcontextmenu/CardContextMenuItem.vue.d.ts +88 -0
  3. package/lib/components/cardcontextmenu/CardContextMenuList.vue.d.ts +5 -0
  4. package/lib/components/cardcontextmenu/CardContextMenuSeperator.vue.d.ts +4 -0
  5. package/lib/components/cardcontextmenu/CardContextMenuWrapper.vue.d.ts +2 -0
  6. package/lib/components/cardcontextmenu/hooks.d.ts +2 -0
  7. package/lib/components/cardcontextmenu/style/Dropdown.css.d.ts +9 -0
  8. package/lib/components/cardcontextmenu/style/index.d.ts +1 -0
  9. package/lib/components/cardcontextmenu/symbol.d.ts +6 -0
  10. package/lib/components/index.d.ts +4 -0
  11. package/lib/index.cjs.js +8 -8
  12. package/lib/index.es.js +4235 -3853
  13. package/lib/style.css +1 -1
  14. package/package.json +1 -1
  15. package/src/components/cardcontextmenu/CardContextMenu.vue +276 -0
  16. package/src/components/cardcontextmenu/CardContextMenuItem.vue +151 -0
  17. package/src/components/cardcontextmenu/CardContextMenuList.vue +20 -0
  18. package/src/components/cardcontextmenu/CardContextMenuSeperator.vue +23 -0
  19. package/src/components/cardcontextmenu/CardContextMenuWrapper.vue +18 -0
  20. package/src/components/cardcontextmenu/examples/basic.vue +71 -0
  21. package/src/components/cardcontextmenu/examples/index.stories.ts +22 -0
  22. package/src/components/cardcontextmenu/examples/index.ts +1 -0
  23. package/src/components/cardcontextmenu/hooks.ts +30 -0
  24. package/src/components/cardcontextmenu/style/Dropdown.css.ts +158 -0
  25. package/src/components/cardcontextmenu/style/index.ts +1 -0
  26. package/src/components/cardcontextmenu/symbol.ts +9 -0
  27. package/src/components/dropdown/Dropdown.vue +2 -2
  28. package/src/components/dropdown/examples/context.vue +3 -1
  29. package/src/components/index.ts +5 -0
@@ -0,0 +1,151 @@
1
+ <template>
2
+ <component
3
+ :is="computedType"
4
+ :href="href"
5
+ ref="wrapper"
6
+ :class="computedWrapperClasses"
7
+ role="menuitem"
8
+ tabindex="0"
9
+ @click="handleSelect"
10
+ v-bind="$attrs">
11
+ <div v-if="hasIconLeft" :class="style.menuItemIcon">
12
+ <slot name="icon-left" />
13
+ </div>
14
+ <div :class="style.menuItemTextContainer">
15
+ <span :class="style.menuItemText"><slot /></span>
16
+ </div>
17
+ <!-- <div v-if="hotkey" class="m-dropdown__hotkeys">
18
+ <template v-for="key in hotkey.split('+')">
19
+ <kbd>{{ key }}</kbd>
20
+ </template>
21
+ </div> -->
22
+ <div v-if="hasIconRight" :class="style.menuItemIcon">
23
+ <slot name="icon-right" />
24
+ </div>
25
+ </component>
26
+ </template>
27
+
28
+ <script lang="ts">
29
+ import {
30
+ computed,
31
+ defineComponent,
32
+ inject,
33
+ type PropType,
34
+ ref,
35
+ toRef
36
+ } from 'vue';
37
+ import { useLabel } from './hooks';
38
+ import * as style from './style';
39
+ import type { Variant } from '../../types/props';
40
+
41
+ export default defineComponent({
42
+ name: 'CardContextMenuItem',
43
+ props: {
44
+ label: {
45
+ type: [String, Number],
46
+ default: null
47
+ },
48
+ disabled: {
49
+ type: Boolean,
50
+ default: false
51
+ },
52
+ reference: {
53
+ type: Boolean,
54
+ default: false
55
+ },
56
+ onSelect: {
57
+ type: Function as PropType<(label: string | number) => void>,
58
+ default: () => {}
59
+ },
60
+ hotkey: {
61
+ type: String,
62
+ default: null
63
+ },
64
+ description: {
65
+ type: String,
66
+ default: null
67
+ },
68
+ href: {
69
+ type: String,
70
+ default: null
71
+ },
72
+ variant: {
73
+ type: String as PropType<Variant>,
74
+ default: 'default'
75
+ }
76
+ },
77
+ emits: [],
78
+ setup(props, { slots }) {
79
+ const parentSelect = inject('dropdown-select', null);
80
+ // const state = inject(DROPDOWN_STATE, null);
81
+ // const keys = useMagicKeys({
82
+ // passive: false,
83
+ // onEventFired: (event) => {
84
+
85
+ // // only fire when the dropdown is open
86
+ // if (state?.isOpen.value) {
87
+ // event.preventDefault();
88
+ // }
89
+ // }
90
+ // });
91
+
92
+ const hasIconLeft = computed(() => !!slots['icon-left']);
93
+ const hasIconRight = computed(() => !!slots['icon-right']);
94
+
95
+ const wrapper = ref(null);
96
+ const label = toRef(props, 'label');
97
+ const isReference = ref(props.reference);
98
+ const currentLabel = useLabel(label, wrapper);
99
+ function handleSelect() {
100
+ if (props.disabled || isReference.value) {
101
+ return;
102
+ }
103
+
104
+ if (typeof parentSelect === 'function') {
105
+ // @ts-ignore
106
+ parentSelect([currentLabel.value!]);
107
+ }
108
+
109
+ props.onSelect(currentLabel.value!);
110
+ }
111
+
112
+ // const isOpen = computed(() => {
113
+ // return state?.isOpen.value;
114
+ // });
115
+
116
+ const computedWrapperClasses = computed(() => {
117
+ return [style.menuItem, style.variant[props.variant]];
118
+ });
119
+
120
+ const computedType = computed(() => {
121
+ if (props.href) {
122
+ return 'a';
123
+ }
124
+
125
+ return 'li';
126
+ });
127
+
128
+ // onMounted(() => {
129
+ // if (props.hotkey) {
130
+ // const combination = keys[props.hotkey];
131
+
132
+ // whenever(combination, (v) => {
133
+ // if (v && isOpen.value) {
134
+ // handleSelect();
135
+ // }
136
+ // })
137
+ // }
138
+ // })
139
+
140
+ return {
141
+ wrapper,
142
+ hasIconLeft,
143
+ hasIconRight,
144
+ handleSelect,
145
+ computedWrapperClasses,
146
+ style,
147
+ computedType
148
+ };
149
+ }
150
+ });
151
+ </script>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <ul :class="style.menuItems">
3
+ <slot />
4
+ </ul>
5
+ </template>
6
+
7
+ <script lang="ts">
8
+ import { defineComponent } from 'vue';
9
+ import * as style from "./style";
10
+
11
+ export default defineComponent({
12
+ name: "CardContextMenuList",
13
+ setup() {
14
+
15
+ return {
16
+ style
17
+ }
18
+ }
19
+ })
20
+ </script>
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <li :class="computedClasses"></li>
3
+ </template>
4
+
5
+ <script lang="ts">
6
+ import {computed, defineComponent} from "vue";
7
+ import * as style from "./style";
8
+
9
+ export default defineComponent({
10
+ name: "CardContextMenuSeperator",
11
+ setup() {
12
+ const computedClasses = computed(() => {
13
+ return [
14
+ style.menuSeperator
15
+ ]
16
+ });
17
+
18
+ return {
19
+ computedClasses
20
+ }
21
+ }
22
+ })
23
+ </script>
@@ -0,0 +1,18 @@
1
+ <template>
2
+ <slot />
3
+ </template>
4
+
5
+ <script lang="ts">
6
+ import { defineComponent, inject, provide } from 'vue';
7
+ import {CARDCONTEXTMENU_STATE} from "./symbol";
8
+
9
+ export default defineComponent({
10
+ name: 'CardContextMenuWrapper',
11
+ setup() {
12
+ const state = inject(CARDCONTEXTMENU_STATE, null);
13
+
14
+ // @ts-ignore
15
+ provide('dropdown-select', state?.handleSelect);
16
+ }
17
+ })
18
+ </script>
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <div>
3
+ <div style="background: #eee; width: 500px; height: 500px;" @contextmenu="handleContextMenu">
4
+
5
+ </div>
6
+
7
+ <MCardContextMenu :virtual="position" :open="showing">
8
+ <template #menu>
9
+ <MCardContextMenuList>
10
+ <MCardContextMenuItem>
11
+ Item One
12
+ </MCardContextMenuItem>
13
+ <MCardContextMenuItem>
14
+ Item Two
15
+ </MCardContextMenuItem>
16
+
17
+ <MCardContextMenu>
18
+ <MCardContextMenuItem>
19
+ <template #icon-right>
20
+ <svg style="width: 16px; height: 16px;" xmlns="http://www.w3.org/2000/svg"
21
+ viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5">
22
+ <path fill-rule="evenodd"
23
+ d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
24
+ clip-rule="evenodd" />
25
+ </svg>
26
+
27
+ </template>
28
+ Item Three (Parent)
29
+ </MCardContextMenuItem>
30
+
31
+ <template #menu>
32
+ <MCardContextMenuList>
33
+ <MCardContextMenuItem @click="handleClick">
34
+ Child One
35
+ </MCardContextMenuItem>
36
+ <MCardContextMenuItem>
37
+ Child Two
38
+ </MCardContextMenuItem>
39
+ </MCardContextMenuList>
40
+ </template>
41
+ </MCardContextMenu>
42
+ </MCardContextMenuList>
43
+ </template>
44
+ </MCardContextMenu>
45
+ </div>
46
+ </template>
47
+
48
+ <script lang="ts" setup>
49
+ import { nextTick, ref, reactive } from 'vue';
50
+
51
+ const showing = ref(false);
52
+ const position = reactive({
53
+ x: 0,
54
+ y: 0
55
+ })
56
+
57
+ const handleContextMenu = (e: MouseEvent) => {
58
+ e.preventDefault();
59
+ showing.value = false;
60
+ nextTick().then(() => {
61
+ showing.value = true;
62
+
63
+ position.x = e.clientX;
64
+ position.y = e.clientY;
65
+ })
66
+ }
67
+
68
+ const handleClick = () => {
69
+ alert('hi');
70
+ }
71
+ </script>
@@ -0,0 +1,22 @@
1
+ import MCardContextMenu from '../CardContextMenu.vue';
2
+ import MCardContextMenuList from '../CardContextMenuList.vue';
3
+ import MCardContextMenuItem from '../CardContextMenuItem.vue';
4
+ import MButton from '../../button/Button.vue';
5
+
6
+ import { MCardContextMenuBasic } from './index';
7
+ import { createStory, popperPositionArgType } from '../../../__storybook__';
8
+
9
+ export default {
10
+ component: MCardContextMenu,
11
+ subcomponents: {
12
+ MCardContextMenuList,
13
+ MCardContextMenuItem,
14
+ MButton
15
+ },
16
+ title: 'Components/Card Context Menu',
17
+ argTypes: {
18
+ ...popperPositionArgType()
19
+ }
20
+ };
21
+
22
+ export const Basic = createStory(MCardContextMenuBasic);
@@ -0,0 +1 @@
1
+ export { default as MCardContextMenuBasic } from './basic.vue';
@@ -0,0 +1,30 @@
1
+ import { ref, watch, onMounted, nextTick } from 'vue';
2
+
3
+ import type { Ref } from 'vue';
4
+
5
+ export function useLabel(
6
+ rawLabel: Ref<string | number | null>,
7
+ element: Ref<HTMLElement | null | undefined>
8
+ ) {
9
+ const label = ref(rawLabel.value);
10
+
11
+ function setLabel(value: string | number | null) {
12
+ if (element.value) {
13
+ label.value = value ?? element.value.textContent?.trim() ?? null;
14
+ } else {
15
+ label.value = value;
16
+ }
17
+ }
18
+
19
+ watch(rawLabel, value => {
20
+ setLabel(value);
21
+ });
22
+
23
+ onMounted(() => {
24
+ nextTick(() => {
25
+ setLabel(rawLabel.value);
26
+ });
27
+ });
28
+
29
+ return label;
30
+ }
@@ -0,0 +1,158 @@
1
+ import { createVar, style, styleVariants } from '@vanilla-extract/css';
2
+ import { themeVars } from '../../../styles/theme.css';
3
+
4
+ export const menu = style({
5
+ backgroundColor: '#ffffff',
6
+ borderRadius: '5px',
7
+ padding: '5px',
8
+ zIndex: 4000,
9
+ boxSizing: 'border-box',
10
+ position: 'relative',
11
+ minWidth: '130px',
12
+ maxWidth: '350px',
13
+ border: `1px solid ${themeVars.color.gray[300]}`,
14
+ boxShadow: themeVars.shadow.md,
15
+ overflow: 'auto'
16
+ });
17
+
18
+ export const menuItems = style({
19
+ listStyle: 'none',
20
+ margin: 0,
21
+ padding: 0
22
+ });
23
+
24
+ const vars = {
25
+ backgroundColor: createVar(),
26
+ color: createVar()
27
+ };
28
+
29
+ export const menuItem = style({
30
+ vars: {
31
+ [vars.backgroundColor]: 'transparent',
32
+ [vars.color]: themeVars.color.font.text
33
+ },
34
+ display: 'grid',
35
+ alignItems: 'center',
36
+ gridTemplateAreas: '"icon name kbd decoration"',
37
+ gridTemplateColumns: '16px 1fr auto minmax(8px, auto)',
38
+ gridTemplateRows: '16px',
39
+ columnGap: themeVars.space['1.5'],
40
+ rowGap: themeVars.space['0.5'],
41
+ borderRadius: themeVars.rounded.default,
42
+ padding: `${themeVars.space['2']} ${themeVars.space['1.5']}`,
43
+ fontSize: themeVars.fontSize.base,
44
+ color: themeVars.color.font.text,
45
+ cursor: 'pointer',
46
+ transition: 'background-color 0.14s ease',
47
+ textDecoration: 'none',
48
+ ':hover': {
49
+ vars: {
50
+ [vars.backgroundColor]: themeVars.color.gray[100],
51
+ [vars.color]: themeVars.color.font.text
52
+ },
53
+ backgroundColor: vars.backgroundColor,
54
+ color: vars.color
55
+ }
56
+ });
57
+
58
+ export const variant = styleVariants({
59
+ primary: {
60
+ color: themeVars.color.blue[500],
61
+ ':hover': {
62
+ vars: {
63
+ [vars.backgroundColor]: themeVars.color.blue[50],
64
+ [vars.color]: themeVars.color.blue[500]
65
+ }
66
+ }
67
+ },
68
+ dark: {
69
+ ':hover': {
70
+ vars: {
71
+ [vars.backgroundColor]: themeVars.color.gray[100],
72
+ [vars.color]: themeVars.color.font.text
73
+ }
74
+ }
75
+ },
76
+ default: {
77
+ ':hover': {
78
+ vars: {
79
+ [vars.backgroundColor]: themeVars.color.gray[100],
80
+ [vars.color]: themeVars.color.font.text
81
+ }
82
+ }
83
+ },
84
+ tertiary: {
85
+ ':hover': {
86
+ vars: {
87
+ [vars.backgroundColor]: themeVars.color.gray[100],
88
+ [vars.color]: themeVars.color.font.text
89
+ }
90
+ }
91
+ },
92
+ success: {
93
+ color: themeVars.color.green[600],
94
+ ':hover': {
95
+ vars: {
96
+ [vars.backgroundColor]: themeVars.color.green[50],
97
+ [vars.color]: themeVars.color.green[600]
98
+ }
99
+ }
100
+ },
101
+ warning: {
102
+ color: themeVars.color.amber[600],
103
+ ':hover': {
104
+ vars: {
105
+ [vars.backgroundColor]: themeVars.color.amber[50],
106
+ [vars.color]: themeVars.color.amber[600]
107
+ }
108
+ }
109
+ },
110
+ error: {
111
+ color: themeVars.color.red[600],
112
+ ':hover': {
113
+ vars: {
114
+ [vars.backgroundColor]: themeVars.color.red[50],
115
+ [vars.color]: themeVars.color.red[500]
116
+ }
117
+ }
118
+ }
119
+ });
120
+
121
+ export const menuItemTextContainer = style({
122
+ margin: `0 ${themeVars.space[0.5]}`,
123
+ gridArea: 'name',
124
+ overflow: 'hidden',
125
+ display: 'flex',
126
+ alignItems: 'center',
127
+ gap: themeVars.space[2]
128
+ });
129
+
130
+ export const menuItemText = style({
131
+ flex: `0 1 auto`,
132
+ overflow: 'hidden',
133
+ whiteSpace: 'nowrap',
134
+ textOverflow: 'ellipsis'
135
+ });
136
+
137
+ export const menuItemIcon = style({
138
+ gridArea: 'icon',
139
+ flexShrink: 0,
140
+ display: 'flex',
141
+ position: 'relative',
142
+ top: '1px',
143
+ opacity: 0.8
144
+ });
145
+
146
+ export const menuSeperator = style({
147
+ height: '1px',
148
+ backgroundColor: themeVars.color.gray[200],
149
+ width: `calc(100% + 10px)`,
150
+ margin: `5px -5px`
151
+ });
152
+
153
+ export const heading = style({
154
+ padding: `${themeVars.space[2]} ${themeVars.space[2.5]}`,
155
+ fontWeight: 500,
156
+ fontSize: themeVars.fontSize.small,
157
+ color: themeVars.color.gray[600]
158
+ });
@@ -0,0 +1 @@
1
+ export * from './Dropdown.css';
@@ -0,0 +1,9 @@
1
+ import type { InjectionKey } from 'vue';
2
+
3
+ export interface CardContextMenuState {
4
+ handleSelect: (labels: string[]) => void;
5
+ isOpen: boolean;
6
+ }
7
+
8
+ export const CARDCONTEXTMENU_STATE: InjectionKey<CardContextMenuState> =
9
+ Symbol('CARDCONTEXTMENU_STATE');
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <ContextMenuRoot v-if="contextMenu">
2
+ <ContextMenuRoot v-model:open="isOpen" v-if="contextMenu" v-bind="$attrs">
3
3
  <ContextMenuTrigger as-child>
4
4
  <slot />
5
5
  </ContextMenuTrigger>
@@ -9,7 +9,7 @@
9
9
  </ContextMenuContent>
10
10
  </ContextMenuPortal>
11
11
  </ContextMenuRoot>
12
- <DropdownMenuRoot v-model:open="isOpen" v-else :modal="modal">
12
+ <DropdownMenuRoot v-model:open="isOpen" v-else :modal="modal" v-bind="$attrs">
13
13
  <DropdownMenuTrigger as-child>
14
14
  <slot />
15
15
  </DropdownMenuTrigger>
@@ -2,7 +2,7 @@
2
2
  <div>
3
3
 
4
4
 
5
- <MDropdown contextMenu>
5
+ <MDropdown v-model:open="isOpen" :style="{ top: `199px`, left: `9px` }">
6
6
  <div style="background: #eee; width: 500px; height: 500px;">
7
7
  </div>
8
8
  <template #menu>
@@ -46,6 +46,8 @@
46
46
  </template>
47
47
 
48
48
  <script lang="ts" setup>
49
+ import { ref } from 'vue';
50
+ const isOpen = ref(true);
49
51
  const handleClick = () => {
50
52
  alert('hi');
51
53
  }
@@ -19,6 +19,11 @@ export { default as MDropdownHeading } from './dropdown/DropdownHeading.vue';
19
19
  export { default as MDropdownSeperator } from './dropdown/DropdownSeperator.vue';
20
20
 
21
21
  // export { DropdownMenuSub as MDropdownMenuSub, DropdownMenuSubTrigger as MDropdownMenuSubTrigger, DropdownMenuSubContent as MDropdownMenuSubContent } from 'radix-vue';
22
+
23
+ export { default as MCardContextMenu } from './cardcontextmenu/CardContextMenu.vue';
24
+ export { default as MCardContextMenuItem } from './cardcontextmenu/CardContextMenuItem.vue';
25
+ export { default as MCardContextMenuList } from './cardcontextmenu/CardContextMenuList.vue';
26
+ export { default as MCardContextMenuSeperator } from './cardcontextmenu/CardContextMenuSeperator.vue';
22
27
  export { default as MForm } from './form/Form.vue';
23
28
  export { default as MImage } from './image/Image.vue';
24
29
  export { default as MInput } from './input/Input.vue';