@teammodlr/ui-kit 2.3.0 → 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 (33) 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/dropdown/Dropdown.vue.d.ts +9 -0
  11. package/lib/components/dropdown/DropdownSeperator.vue.d.ts +4 -0
  12. package/lib/components/index.d.ts +5 -1
  13. package/lib/index.cjs.js +8 -8
  14. package/lib/index.es.js +4264 -3862
  15. package/lib/style.css +1 -1
  16. package/package.json +1 -1
  17. package/src/components/cardcontextmenu/CardContextMenu.vue +276 -0
  18. package/src/components/cardcontextmenu/CardContextMenuItem.vue +151 -0
  19. package/src/components/cardcontextmenu/CardContextMenuList.vue +20 -0
  20. package/src/components/cardcontextmenu/CardContextMenuSeperator.vue +23 -0
  21. package/src/components/cardcontextmenu/CardContextMenuWrapper.vue +18 -0
  22. package/src/components/cardcontextmenu/examples/basic.vue +71 -0
  23. package/src/components/cardcontextmenu/examples/index.stories.ts +22 -0
  24. package/src/components/cardcontextmenu/examples/index.ts +1 -0
  25. package/src/components/cardcontextmenu/hooks.ts +30 -0
  26. package/src/components/cardcontextmenu/style/Dropdown.css.ts +158 -0
  27. package/src/components/cardcontextmenu/style/index.ts +1 -0
  28. package/src/components/cardcontextmenu/symbol.ts +9 -0
  29. package/src/components/dropdown/Dropdown.vue +6 -2
  30. package/src/components/dropdown/DropdownSeperator.vue +26 -0
  31. package/src/components/dropdown/examples/basic.vue +120 -0
  32. package/src/components/dropdown/examples/context.vue +3 -1
  33. package/src/components/index.ts +8 -1
@@ -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>
12
+ <DropdownMenuRoot v-model:open="isOpen" v-else :modal="modal" v-bind="$attrs">
13
13
  <DropdownMenuTrigger as-child>
14
14
  <slot />
15
15
  </DropdownMenuTrigger>
@@ -105,6 +105,10 @@ export default defineComponent({
105
105
  type: Boolean,
106
106
  default: false
107
107
  },
108
+ modal: {
109
+ type: Boolean,
110
+ default: false
111
+ },
108
112
  placement: {
109
113
  type: String as PropType<"start" | "center" | "end">,
110
114
  default: 'start'
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <DropdownMenuSeparator :class="computedClasses" />
3
+ </template>
4
+
5
+ <script lang="ts">
6
+ import {computed, defineComponent} from "vue";
7
+ import * as style from "./style";
8
+ import { DropdownMenuSeparator } from 'radix-vue';
9
+ export default defineComponent({
10
+ name: "DropdownSeperator",
11
+ components: {
12
+ DropdownMenuSeparator
13
+ },
14
+ setup() {
15
+ const computedClasses = computed(() => {
16
+ return [
17
+ style.menuSeperator
18
+ ]
19
+ });
20
+
21
+ return {
22
+ computedClasses
23
+ }
24
+ }
25
+ })
26
+ </script>