@bagelink/vue 0.0.270 → 0.0.276

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 (35) hide show
  1. package/dist/components/Accordion.vue.d.ts +10 -0
  2. package/dist/components/Accordion.vue.d.ts.map +1 -0
  3. package/dist/components/AccordionItem.vue.d.ts +2 -0
  4. package/dist/components/AccordionItem.vue.d.ts.map +1 -1
  5. package/dist/components/Btn.vue.d.ts +3 -3
  6. package/dist/components/{Drop.vue.d.ts → ComboBox.vue.d.ts} +10 -12
  7. package/dist/components/ComboBox.vue.d.ts.map +1 -0
  8. package/dist/components/Popover.vue.d.ts +10 -0
  9. package/dist/components/Popover.vue.d.ts.map +1 -0
  10. package/dist/components/Title.vue.d.ts +1 -1
  11. package/dist/components/form/BglForm.vue.d.ts.map +1 -1
  12. package/dist/components/form/ItemRef.vue.d.ts +0 -1
  13. package/dist/components/form/ItemRef.vue.d.ts.map +1 -1
  14. package/dist/components/form/inputs/SelectField.vue.d.ts +4 -1
  15. package/dist/components/form/inputs/SelectField.vue.d.ts.map +1 -1
  16. package/dist/components/index.d.ts +3 -0
  17. package/dist/components/index.d.ts.map +1 -1
  18. package/dist/index.cjs +6752 -4031
  19. package/dist/index.mjs +6726 -4005
  20. package/dist/plugins/bagel.d.ts.map +1 -1
  21. package/dist/style.css +291 -238
  22. package/dist/utils/clickOutside.d.ts +7 -0
  23. package/dist/utils/clickOutside.d.ts.map +1 -0
  24. package/package.json +2 -1
  25. package/src/components/Accordion.vue +15 -0
  26. package/src/components/AccordionItem.vue +48 -24
  27. package/src/components/ComboBox.vue +132 -0
  28. package/src/components/index.ts +3 -0
  29. package/src/plugins/bagel.ts +14 -2
  30. package/src/styles/layout.css +191 -188
  31. package/src/styles/text.css +40 -43
  32. package/src/utils/clickOutside.ts +15 -0
  33. package/dist/components/Drop.vue.d.ts.map +0 -1
  34. package/dist/components/FileUploader.vue.d.ts +0 -60
  35. package/dist/components/FileUploader.vue.d.ts.map +0 -1
@@ -0,0 +1,7 @@
1
+ import type { DirectiveBinding } from 'vue';
2
+ declare const _default: {
3
+ beforeMount(el: any, binding: DirectiveBinding): void;
4
+ unmounted(el: any): void;
5
+ };
6
+ export default _default;
7
+ //# sourceMappingURL=clickOutside.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clickOutside.d.ts","sourceRoot":"","sources":["../../src/utils/clickOutside.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAC;;oBAG3B,GAAG,WAAW,gBAAgB;kBAQhC,GAAG;;AATlB,wBAYE"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "0.0.270",
4
+ "version": "0.0.276",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Neveh Allon",
@@ -113,6 +113,7 @@
113
113
  "access": "public"
114
114
  },
115
115
  "dependencies": {
116
+ "floating-vue": "^5.2.2",
116
117
  "type-fest": "^4.10.2",
117
118
  "vue-multiselect": "3.0.0-beta.3"
118
119
  },
@@ -0,0 +1,15 @@
1
+ <template>
2
+ <div>
3
+ <slot />
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { reactive, provide } from 'vue';
9
+
10
+ const state = reactive({
11
+ openItem: null as string | null,
12
+ });
13
+
14
+ provide('accordionState', state);
15
+ </script>
@@ -1,13 +1,14 @@
1
1
  <template>
2
2
  <div class="accordion-item">
3
- <div class="accordion-head" @click="toggle()">
4
- {{ label }}
5
- <div class="accordion-icon" :class="{open}" >
3
+ <button @click="toggle()" :aria-expanded="open ? 'true' : 'false'" class="accordion-head"
4
+ :aria-controls="`accordion-body-${id}`">
5
+ <span class="accordion-label">{{ label }}</span>
6
+ <div class="accordion-icon" :class="{ open }">
6
7
  <MaterialIcon icon="expand_more" />
7
8
  </div>
8
- </div>
9
+ </button>
9
10
  <Transition name="expand">
10
- <div v-if="open" class="accordion-body">
11
+ <div v-if="open" class="accordion-body" :id="`accordion-body-${id}`" :aria-hidden="open ? 'false' : 'true'">
11
12
  <slot />
12
13
  </div>
13
14
  </Transition>
@@ -16,57 +17,80 @@
16
17
 
17
18
  <script lang="ts" setup>
18
19
  import { MaterialIcon } from '@bagelink/vue';
20
+ import { watch, inject } from 'vue';
19
21
 
20
- defineProps<{
21
- label: string,
22
+ const props = defineProps<{
23
+ label: string,
24
+ id?: string,
22
25
  }>();
23
-
24
26
  let open = $ref(false);
25
27
 
28
+ const accordionState = inject('accordionState') as { openItem: string | null };
29
+ const id = props.id || Math.random().toString(36).substring(7);
30
+
31
+ watch(() => accordionState.openItem, (currentOpenId) => {
32
+ if (currentOpenId !== id) {
33
+ open = false;
34
+ }
35
+ }, { immediate: true });
36
+
26
37
  function toggle() {
27
38
  open = !open;
28
- console.log('toggle', open);
39
+ if (open) accordionState.openItem = id;
40
+ else if (accordionState.openItem === id) accordionState.openItem = null;
29
41
  }
30
42
  </script>
31
43
 
32
44
  <style scoped>
33
45
  .accordion-item {
34
- border-bottom: 1px solid var(--border-color);
35
- transition: all 0.2s ease;
36
- cursor: pointer;
37
- overflow: hidden;
46
+ border-bottom: 1px solid var(--border-color);
47
+ transition: all 0.2s;
48
+ cursor: pointer;
49
+ overflow: hidden;
38
50
  }
39
51
 
40
52
  .accordion-head {
41
- height: var( --input-height);
42
- display: flex;
43
- align-items: center;
44
- justify-content: space-between;
53
+ height: var(--input-height);
54
+ background: transparent;
55
+ display: flex;
56
+ width: 100%;
57
+ align-items: center;
58
+ justify-content: space-between;
45
59
  }
46
60
 
47
61
  .accordion-icon {
48
- transition: all 0.2s ease;
62
+ transition: all 0.2s ease;
49
63
  }
64
+
50
65
  .accordion-icon.open {
51
- transform: rotate(180deg);
66
+ transform: rotate(180deg);
52
67
  }
68
+
69
+ .accordion-label {
70
+ font-weight: bold;
71
+ }
72
+
73
+ .accordion-head:hover .accordion-label {
74
+ text-decoration: underline;
75
+ }
76
+
77
+ .accordion-body {}
53
78
  </style>
54
79
 
55
80
  <style>
56
81
  .expand-enter-active,
57
82
  .expand-leave-active {
58
- transition: all 0.5s;
83
+ transition: all 0.5s;
84
+ transition-delay: 0ms;
59
85
  }
60
86
 
61
87
  .expand-enter-from,
62
88
  .expand-leave-to {
63
- max-height: 0;
64
- opacity: 0.5;
89
+ max-height: 0;
65
90
  }
66
91
 
67
92
  .expand-enter-to,
68
93
  .expand-leave-from {
69
- max-height: 100vh;
70
- opacity: 1;
94
+ max-height: 300px;
71
95
  }
72
96
  </style>
@@ -0,0 +1,132 @@
1
+ <template>
2
+ <Dropdown placement="auto-start" class="bagel-input combobox">
3
+ <Btn class="combobox-btn" border color="black" @click="toggle"
4
+ v-bind="{ 'icon.end': open ? 'unfold_less' : 'unfold_more' }">
5
+ {{
6
+ valueToLabel(selectedItem) ||
7
+ placeholder || 'Select' }}
8
+ </Btn>
9
+ <template #popper="{ hide }">
10
+ <Card border thin class="combobox-options">
11
+ <TextInput v-if="searchable" ref="searchInput" dense :placeholder="'Search'" icon="search" v-model="search" />
12
+ <div class="combobox-option" v-for="(option, i) in filteredOptions" :key="`${option}${i}`" @click="() => {
13
+ select(option)
14
+ hide();
15
+ }" :class="{ selected: option === selectedItem }">
16
+ <span>
17
+ {{ label(option) }}
18
+ </span>
19
+ <Icon v-if="isSelected(option)" icon="check" />
20
+ </div>
21
+ </Card>
22
+ </template>
23
+ </Dropdown>
24
+ </template>
25
+
26
+ <script lang="ts" setup>
27
+ import { Dropdown } from 'floating-vue';
28
+ import 'floating-vue/style.css';
29
+ import {
30
+ TextInput, Btn, Card, Icon,
31
+ } from '@bagelink/vue';
32
+
33
+ type Option = string | number | Record<string, any> | { label: string, value: string | number };
34
+ let open = $ref(false);
35
+ let selectedItem = $ref<Option>();
36
+
37
+ const searchInput = $ref<HTMLInputElement | null>(null);
38
+
39
+ const props = defineProps<{
40
+ options: Option[];
41
+ placeholder?: string;
42
+ disabled?: boolean;
43
+ modelValue?: Option;
44
+ searchable?: boolean;
45
+ }>();
46
+ let search = $ref('');
47
+
48
+ const toggle = () => {
49
+ open = !open;
50
+ if (!open) search = '';
51
+ if (open) setTimeout(() => (searchInput as any)?.$el?.querySelector('input')?.focus(), 100);
52
+ };
53
+
54
+ const valueToLabel = (value?: Option) => {
55
+ if (!value) return '';
56
+ const option = props.options.find((option) => {
57
+ if (typeof option === 'string' || typeof option === 'number') return option === value;
58
+ return option.value === value;
59
+ });
60
+ if (!option) return value;
61
+ return label(option);
62
+ };
63
+
64
+ const emit = defineEmits(['update:modelValue']);
65
+
66
+ const label = (option: Option) => {
67
+ if (typeof option === 'string') return option;
68
+ if (typeof option === 'number') return `${option}`;
69
+ return option.label;
70
+ };
71
+
72
+ const isSelected = (option: Option) => {
73
+ if (typeof option === 'string' || typeof option === 'number') return option === selectedItem;
74
+ return option.value === selectedItem;
75
+ };
76
+
77
+ const filteredOptions = $computed(() => props.options.filter((option) => {
78
+ const searchTerm = new RegExp(search, 'gi');
79
+ if (typeof option === 'string') return option.match(searchTerm);
80
+ if (typeof option === 'number') return `${option}`.match(searchTerm);
81
+ return option.label.match(searchTerm);
82
+ }));
83
+
84
+ const select = (option: Option) => {
85
+ if (typeof option === 'string') selectedItem = option;
86
+ else if (typeof option === 'number') selectedItem = option;
87
+ else selectedItem = option.value;
88
+ emit('update:modelValue', selectedItem);
89
+ open = false;
90
+ };
91
+ </script>
92
+
93
+ <style scoped>
94
+ .combobox {
95
+ width: 100%;
96
+ }
97
+
98
+ .combobox-option {
99
+ padding: 6px 12px;
100
+ cursor: pointer;
101
+ border-radius: 5px;
102
+ transition: all 0.2s;
103
+ display: flex;
104
+ justify-content: space-between;
105
+ width: 300px;
106
+ }
107
+
108
+ .combobox-options {
109
+ max-height: 300px;
110
+ overflow-y: auto;
111
+ }
112
+
113
+ .combobox-option:hover {
114
+ background: var(--bgl-gray-20);
115
+ }
116
+ </style>
117
+
118
+ <style>
119
+ .combobox-btn .bgl_btn-flex {
120
+ justify-content: space-between;
121
+ }
122
+
123
+ .v-popper__arrow-container {
124
+ display: none;
125
+ }
126
+
127
+ .v-popper--theme-dropdown .v-popper__inner {
128
+ border: none;
129
+ background: transparent;
130
+ border-radius: var(--card-border-radius);
131
+ }
132
+ </style>
@@ -1,6 +1,7 @@
1
1
  export { default as LangText } from './LangText.vue';
2
2
  export { default as RTXEditor } from './RTXEditor.vue';
3
3
  export { default as MaterialIcon } from './MaterialIcon.vue';
4
+ export { default as Icon } from './MaterialIcon.vue';
4
5
  export { default as NavBar } from './NavBar.vue';
5
6
  export { default as Btn } from './Btn.vue';
6
7
  export { default as Modal } from './Modal.vue';
@@ -18,6 +19,8 @@ export { default as DataPreview } from './DataPreview.vue';
18
19
  export { default as Card } from './Card.vue';
19
20
  export { default as Avatar } from './Avatar.vue';
20
21
  export { default as Title } from './Title.vue';
22
+ export { default as Accordion } from './Accordion.vue';
23
+ export { default as ComboBox } from './ComboBox.vue';
21
24
 
22
25
  export * from './charts';
23
26
  export * from './form';
@@ -1,6 +1,9 @@
1
+ // import { vTooltip } from 'floating-vue';
2
+ import FloatingVue from 'floating-vue';
1
3
  import { inject } from 'vue';
2
4
  import type { InjectionKey, Plugin } from 'vue';
3
5
  import { Bagel } from '@bagelink/sdk';
6
+ import clickOutside from '../utils/clickOutside';
4
7
 
5
8
  export const bagelInjectionKey = Symbol('bagel') as InjectionKey<Bagel>;
6
9
  export const i18nTInjectionKey = Symbol('bagel') as InjectionKey<
@@ -29,11 +32,20 @@ export interface BagelOptions {
29
32
  // eslint-disable-next-line no-unused-vars
30
33
  i18nT?: (key: string) => string
31
34
  }
32
-
33
35
  export const BagelVue: Plugin = {
34
36
  install: (app, options: BagelOptions) => {
35
37
  const bagel = new Bagel({ host: options.host, onError: options.onError });
36
-
38
+ app.directive('click-outside', clickOutside);
39
+
40
+ app.use(FloatingVue, {
41
+ themes: {
42
+ 'bgl-theme': {
43
+ triggers: ['click'],
44
+ autoHide: true,
45
+ placement: 'bottom',
46
+ },
47
+ },
48
+ });
37
49
  app.config.globalProperties.$bagel = bagel;
38
50
  app.provide(bagelInjectionKey, bagel);
39
51
  app.config.globalProperties.$i18T = options?.i18nT || ((key?: string) => key);