@bagelink/vue 0.0.172 → 0.0.186

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.
@@ -9,25 +9,34 @@
9
9
  >
10
10
  {{ title }}
11
11
  </h3>
12
- <div
12
+ <template
13
13
  v-for="field in schema || []"
14
14
  :key="field.id"
15
- class="data-row"
16
15
  >
17
- <div class="key">
18
- {{ field?.label || keyToLabel(field.id) }}
16
+ <div class="data-row" v-if="field['v-if'] ? field['v-if'](itemData[field.id], itemData) : true">
17
+ <div class="key">
18
+ {{ field?.label || keyToLabel(field.id) }}
19
+ </div>
20
+ <component
21
+ :is="field.$el || 'div'"
22
+ class="vlue"
23
+ v-model="itemData[field.id]"
24
+ @update:modelValue="($event:any)=>field?.onUpdate?.($event, data[field.id], itemData)"
25
+ v-bind="bindAttrs(field.attrs, itemData[field.id], itemData)"
26
+ >
27
+ {{
28
+ field?.transform?.(itemData[field.id]
29
+ || field.defaultValue, itemData)
30
+ || itemData[field.id]
31
+ || ''
32
+ }}
33
+ </component>
19
34
  </div>
20
- <component
21
- :is="field.$el || 'div'"
22
- class="vlue"
23
- >
24
- {{ data[field.id] || field.defaultValue }}
25
- </component>
26
- </div>
35
+ </template>
27
36
  <div v-if="!schema?.length">
28
37
  <div
29
38
  class="data-row"
30
- v-for="[key, value] in Object.entries(data).filter(
39
+ v-for="[key, value] in Object.entries(itemData).filter(
31
40
  ([key]) => !keysToIgnore.includes(key),
32
41
  )"
33
42
  :key="key"
@@ -51,12 +60,22 @@ const i18nT = useI18nT();
51
60
 
52
61
  const keysToIgnore = ['id', 'person_id', 'person', 'created_at', 'updated_at'];
53
62
 
54
- // const props =
55
- defineProps<{
63
+ const props = defineProps<{
56
64
  data: Record<string, any>,
57
65
  schema?: Record<string, any>[],
58
66
  title?: string,
59
67
  }>();
68
+
69
+ const itemData = $ref<Record<string, any>>(props.data);
70
+
71
+ const bindAttrs = (attrs: Record<string, any>, field: any, row: any) => {
72
+ const arr = Object.entries(attrs || {}).map(([key, value]) => [
73
+ key,
74
+ typeof value === 'function' ? value(field, row) : value,
75
+ ]);
76
+ const resolvedAttrs = Object.fromEntries(arr);
77
+ return resolvedAttrs;
78
+ };
60
79
  </script>
61
80
 
62
81
  <style scoped>
@@ -71,7 +90,6 @@ defineProps<{
71
90
  justify-content: space-between;
72
91
  padding-bottom: 0.5rem;
73
92
  margin-bottom: 0.5rem;
74
- opacity: 0.8;
75
93
  border-bottom: 1px solid var(--border-color);
76
94
  }
77
95
 
@@ -1,43 +1,44 @@
1
1
  <template>
2
- <div class="dropdown" @click="toggleDropdown" :class="{ opendrop: isOpen }">
3
- <div class="dropdown-title">
4
- {{ selectedOption || placeholder }}
5
- <MaterialIcon icon="keyboard_arrow_down" />
6
- </div>
7
- <div class="dropdown-body">
8
- <p
9
- v-for="(option, index) in options"
10
- :key="index"
11
- @click.stop="selectOption(option as string, index as number)"
12
- >
13
- {{ option }}
14
- </p>
15
- </div>
16
- </div>
2
+ <div class="dropdown" @click="toggleDropdown" :class="{ opendrop: isOpen }">
3
+ <div class="dropdown-title">
4
+ {{ selectedOption || placeholder }}
5
+ <MaterialIcon icon="keyboard_arrow_down" />
6
+ </div>
7
+ <div
8
+ class="dropdown-body"
9
+ >
10
+ <p
11
+ v-for="(option, index) in options"
12
+ :key="index"
13
+ @click.stop="selectOption(option as string, index as number)"
14
+ >
15
+ {{ option }}
16
+ </p>
17
+ </div>
18
+ </div>
17
19
  </template>
18
20
 
19
21
  <script setup lang="ts">
20
- import { ref } from "vue";
21
- import { MaterialIcon } from "@bagelink/vue";
22
+ import { MaterialIcon } from '@bagelink/vue';
22
23
 
23
24
  const props = defineProps({
24
- modelValue: String,
25
- options: Array,
26
- placeholder: String,
25
+ modelValue: String,
26
+ options: Array,
27
+ placeholder: String,
27
28
  });
28
- const emit = defineEmits(["update:modelValue"]);
29
+ const emit = defineEmits(['update:modelValue']);
29
30
 
30
- const isOpen = ref(false);
31
- const selectedOption = ref(props.modelValue);
31
+ let isOpen = $ref(false);
32
+ let selectedOption = $ref(props.modelValue);
32
33
 
33
34
  function toggleDropdown() {
34
- isOpen.value = !isOpen.value;
35
+ isOpen = !isOpen;
35
36
  }
36
37
 
37
38
  function selectOption(option: string, index: number) {
38
- selectedOption.value = option;
39
- isOpen.value = false;
40
- emit("update:modelValue", { option, index }); // Emit the selected option value with v-model
39
+ selectedOption = option;
40
+ isOpen = false;
41
+ emit('update:modelValue', { option, index }); // Emit the selected option value with v-model
41
42
  }
42
43
  </script>
43
44
 
@@ -45,13 +46,14 @@ function selectOption(option: string, index: number) {
45
46
  .dropdown {
46
47
  position: relative;
47
48
  font-size: calc(var(--input-font-size) * 1.3);
48
- width: 50px;
49
- /* color: var(--bgl-primary); */
50
- z-index: 1;
49
+ /* width: 50px; */
50
+ z-index: 9;
51
+
51
52
  }
52
53
 
53
54
  .dropdown-title {
54
55
  white-space: nowrap;
56
+ color: var(--bgl-primary);
55
57
  border-radius: var(--input-border-radius);
56
58
  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 10%);
57
59
  padding-left: calc(var(--btn-padding) / 2);
@@ -90,7 +92,8 @@ function selectOption(option: string, index: number) {
90
92
  inset-inline-start: 0;
91
93
  inset-inline-end: 0;
92
94
  overflow: auto;
93
- box-shadow: 0 1px 2px 0 rgb(0 0 0 / 10%);
95
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.20);
96
+ z-index: 99999999;
94
97
  }
95
98
 
96
99
  .dropdown-body * {
@@ -99,12 +102,11 @@ function selectOption(option: string, index: number) {
99
102
  padding: calc(var(--btn-padding) / 2);
100
103
  padding-bottom: calc(var(--btn-padding) / 4);
101
104
  padding-top: calc(var(--btn-padding) / 4);
105
+ margin: 0;
102
106
  color: inherit;
103
107
  text-decoration: none;
104
108
  line-height: 1;
105
109
  transition: var(--bgl-transition);
106
- box-shadow: 0 -1px 0 0 rgb(0 0 0, 10%);
107
- z-index: 99999999;
108
110
  }
109
111
 
110
112
  .dropdown-body *:hover {
@@ -1,68 +1,70 @@
1
1
  <template>
2
- <div class="table-list-wrap h-100">
3
- <table class="infinite-wrapper">
4
- <thead class="row first-row">
5
- <th
6
- class="col"
7
- v-for="field in columns"
8
- :key="field.id"
9
- @click="sort(field.id)"
10
- >
11
- <div class="flex">
12
- {{ field?.label || field?.id }}
13
- <div
14
- class="list-arrows"
15
- :class="{ sorted: sortField === field.id }"
16
- >
17
- <MaterialIcon
18
- :class="{ desc: sortDirection === 'DESC' }"
19
- icon="keyboard_arrow_up"
20
- />
21
- </div>
22
- </div>
23
- </th>
24
- </thead>
25
- <tbody ref="infinite" class="rows infinite" :class="{ loading }">
26
- <tr
27
- @click="selectElement(row)"
28
- class="row row-item position-relative"
29
- v-for="row in data"
30
- :key="row.id"
31
- >
32
- <td
33
- class="col"
34
- v-for="field in columns"
35
- :key="`${field.id}-${row.id}`"
36
- >
37
- <slot
38
- v-if="slots[field.id]"
39
- :name="field.id"
40
- :row="row"
41
- :field="field"
42
- />
43
- <div v-else>
44
- <component
45
- :is="field.$el || field.$cmp || 'div'"
46
- v-if="field['v-if'] ? field['v-if'](row[field.id], row) : true"
47
- v-bind="bindAttrs(field.attrs, row[field.id], row)"
48
- :src="field.$el === 'img' ? row[field.id]?.url : ''"
49
- >
50
- {{
51
- field?.transform?.(row[field.id], row) || row[field.id] || ""
52
- }}
53
- </component>
54
- </div>
55
- </td>
56
- </tr>
57
- </tbody>
58
- </table>
59
- <!-- </Transition> -->
60
- </div>
2
+ <div class="table-list-wrap h-100">
3
+ <table class="infinite-wrapper">
4
+ <thead class="row first-row">
5
+ <th
6
+ class="col"
7
+ v-for="field in columns"
8
+ :key="field.id"
9
+ @click="sort(field.id)"
10
+ >
11
+ <div class="flex">
12
+ {{ field?.label || field?.id }}
13
+ <div
14
+ class="list-arrows"
15
+ :class="{ sorted: sortField === field.id }"
16
+ >
17
+ <MaterialIcon
18
+ :class="{ desc: sortDirection === 'DESC' }"
19
+ icon="keyboard_arrow_up"
20
+ />
21
+ </div>
22
+ </div>
23
+ </th>
24
+ </thead>
25
+ <tbody ref="infinite" class="rows infinite" :class="{ loading }">
26
+ <tr
27
+ @click="selectElement(row)"
28
+ class="row row-item position-relative"
29
+ v-for="row in data"
30
+ :key="row.id"
31
+ >
32
+ <td
33
+ class="col"
34
+ v-for="field in columns"
35
+ :key="`${field.id}-${row.id}`"
36
+ >
37
+ <slot
38
+ v-if="slots[field.id]"
39
+ :name="field.id"
40
+ :row="row"
41
+ :field="field"
42
+ />
43
+ <div v-else>
44
+ <component
45
+ :is="field.$el || field.$cmp || 'div'"
46
+ v-if="field['v-if'] ? field['v-if'](row[field.id], row) : true"
47
+ v-bind="bindAttrs(field.attrs, row[field.id], row)"
48
+ :src="field.$el === 'img' ? row[field.id]?.url : ''"
49
+ @update:modelValue="($event:any)=>field?.onUpdate?.($event, row[field.id], row)"
50
+ :modelValue="row[field.id]"
51
+ >
52
+ {{
53
+ field?.transform?.(row[field.id], row) || row[field.id] || ""
54
+ }}
55
+ </component>
56
+ </div>
57
+ </td>
58
+ </tr>
59
+ </tbody>
60
+ </table>
61
+ <!-- </Transition> -->
62
+ </div>
61
63
  </template>
62
64
 
63
65
  <script setup lang="ts">
64
- import { useSlots } from "vue";
65
- import { MaterialIcon } from "@bagelink/vue";
66
+ import { useSlots } from 'vue';
67
+ import { MaterialIcon } from '@bagelink/vue';
66
68
 
67
69
  const slots = useSlots();
68
70
  const loading = $ref(true);
@@ -72,42 +74,38 @@ const props = defineProps<{
72
74
  schema?: () => any[];
73
75
  }>();
74
76
 
75
- const emit = defineEmits(["select"]);
77
+ const emit = defineEmits(['select']);
76
78
 
77
79
  const selectElement = (data: Record<string, any>) => {
78
- emit("select", data);
80
+ emit('select', data);
79
81
  };
80
82
 
81
83
  const bindAttrs = (attrs: Record<string, any>, field: any, row: any) => {
82
- const arr = Object.entries(attrs || {}).map(([key, value]) => [
83
- key,
84
- typeof value === "function" ? value(field, row) : value,
85
- ]);
86
- const resolvedAttrs = Object.fromEntries(arr);
87
- return resolvedAttrs;
84
+ const arr = Object.entries(attrs || {}).map(([key, value]) => [
85
+ key,
86
+ typeof value === 'function' ? value(field, row) : value,
87
+ ]);
88
+ const resolvedAttrs = Object.fromEntries(arr);
89
+ return resolvedAttrs;
88
90
  };
89
91
 
90
92
  // const sortList = () => {};
91
- let sortDirection = $ref("");
92
- let sortField = $ref("");
93
+ let sortDirection = $ref('');
94
+ let sortField = $ref('');
93
95
 
94
96
  const sort = (fieldname: string) => {
95
- if (sortField === fieldname) {
96
- if (sortDirection === "ASC") sortDirection = "DESC";
97
- else sortField = "";
98
- } else {
99
- sortField = fieldname;
100
- sortDirection = "ASC";
101
- }
97
+ if (sortField === fieldname) {
98
+ if (sortDirection === 'ASC') sortDirection = 'DESC';
99
+ else sortField = '';
100
+ } else {
101
+ sortField = fieldname;
102
+ sortDirection = 'ASC';
103
+ }
102
104
  };
103
105
 
104
106
  const columns = $computed(
105
- () =>
106
- props.schema?.() ||
107
- Object.keys(props.data[0]).map((k: string) => ({
108
- id: k,
109
- inputType: "PlainText",
110
- }))
107
+ () => props.schema?.() ||
108
+ Object.keys(props.data[0]).map((k: string) => ({ id: k, inputType: 'PlainText' })),
111
109
  );
112
110
  </script>
113
111
 
@@ -1,36 +1,39 @@
1
1
  <template>
2
- <label class="primary-checkbox">
3
- <input type="checkbox" v-model="val" />
4
- <span>
5
- <MaterialIcon icon="check" />
6
- </span>
7
- </label>
2
+ <label class="primary-checkbox">
3
+ <input type="checkbox" v-model="val" >
4
+ <span>
5
+ <MaterialIcon icon="check" />
6
+ </span>
7
+ </label>
8
8
  </template>
9
9
 
10
10
  <script setup lang="ts">
11
- import { watch } from "vue";
12
- import { MaterialIcon } from "@bagelink/vue";
11
+ import { watch } from 'vue';
12
+ import { MaterialIcon } from '@bagelink/vue';
13
13
 
14
14
  const props = defineProps({
15
- modelValue: Boolean,
15
+ modelValue: Boolean,
16
16
  });
17
17
 
18
- const emits = defineEmits(["update:modelValue"]);
18
+ const emits = defineEmits(['update:modelValue']);
19
19
 
20
20
  let val = $ref<boolean>();
21
21
 
22
22
  watch(
23
- () => props.modelValue,
24
- (v: boolean) => {
25
- if (v === undefined || v === val) return;
26
- val = v;
27
- },
28
- { immediate: true }
23
+ () => props.modelValue,
24
+ (v: boolean) => {
25
+ if (v === undefined || v === val) return;
26
+ console.log('v', v);
27
+ val = v;
28
+ },
29
+ { immediate: true },
29
30
  );
30
31
 
31
32
  watch(
32
- () => val,
33
- (v) => emits("update:modelValue", v)
33
+ () => val,
34
+ (v) => {
35
+ if (v !== props.modelValue) emits('update:modelValue', v);
36
+ },
34
37
  );
35
38
  </script>
36
39
 
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div
3
3
  class="bagel-input"
4
- :class="{ small }"
4
+ :class="{ small, shrink, toggleEdit, editMode }"
5
5
  :title="title"
6
6
  >
7
7
  <label :for="id">
@@ -9,20 +9,28 @@
9
9
  <input
10
10
  :id="id"
11
11
  v-model="inputVal"
12
- type="text"
12
+ :type="type"
13
+ ref="input"
13
14
  :placeholder="placeholder || label"
14
- :class="{ 'no-edit': !editMode }"
15
+ :disabled="!editMode"
15
16
  :required="required"
16
17
  :pattern="pattern"
17
18
  v-bind="nativeInputAttrs"
19
+ @dblclick="toggleEditAction"
20
+ @keydown.enter="toggleEditAction"
18
21
  >
19
22
  </label>
23
+ <Btn
24
+ class="toggleEditBtn"
25
+ v-if="toggleEdit" thin @click="toggleEditAction" :icon="editMode?'check':'edit'"
26
+ flat
27
+ />
20
28
  </div>
21
29
  </template>
22
30
 
23
31
  <script setup lang="ts">
24
32
  import { watch } from 'vue';
25
- import { debounce } from '@bagelink/vue';
33
+ import { debounce, Btn } from '@bagelink/vue';
26
34
 
27
35
  const emit = defineEmits(['update:modelValue', 'debounce']);
28
36
  const props = withDefaults(
@@ -30,24 +38,43 @@ const props = withDefaults(
30
38
  id?: string;
31
39
  title?: string;
32
40
  placeholder?: string;
33
- modelValue?: string;
41
+ modelValue?: string | number;
34
42
  label?: string;
35
- editMode?: boolean;
36
43
  small?: boolean;
37
44
  required?: boolean;
38
45
  pattern?: string;
46
+ shrink?: boolean;
47
+ toggleEdit?: boolean;
48
+ type?: string;
39
49
  nativeInputAttrs?: Record<string, any>;
40
50
  }>(),
41
51
  {
42
- editMode: true,
52
+ type: 'text',
53
+ toggleEdit: false,
43
54
  modelValue: '',
44
55
  },
45
56
  );
46
- let inputVal = $ref<string>();
57
+ let inputVal = $ref<string|number>();
58
+ let editMode = $ref<boolean>(!props.toggleEdit);
59
+
60
+ const input = $ref<HTMLInputElement>();
61
+
62
+ const toggleEditAction = () => {
63
+ if (editMode) {
64
+ editMode = false;
65
+ emit('debounce', inputVal);
66
+ emit('update:modelValue', inputVal as string);
67
+ } else {
68
+ editMode = true;
69
+ setTimeout(() => input?.focus(), 10);
70
+ }
71
+ };
47
72
 
48
73
  watch(
49
74
  () => inputVal,
50
75
  (newVal) => {
76
+ if (props.toggleEdit) return;
77
+ if (newVal === props.modelValue) return;
51
78
  emit('update:modelValue', newVal as string);
52
79
  debounce(() => emit('debounce', newVal));
53
80
  },
@@ -61,3 +88,38 @@ watch(
61
88
  { immediate: true },
62
89
  );
63
90
  </script>
91
+
92
+ <style>
93
+ .bagel-input.shrink, .bagel-input.shrink input{
94
+ min-width: unset !important;
95
+ /* width: auto; */
96
+ }
97
+ </style>
98
+
99
+ <style scoped>
100
+ .bagel-input input[disabled]{
101
+ background: none;
102
+ }
103
+
104
+ .bagel-input.toggleEdit:hover {
105
+ background-color: var(--input-bg);
106
+ }
107
+ .bagel-input.small{
108
+ margin-bottom:0;
109
+ height: 30px;
110
+ }
111
+
112
+ .toggleEditBtn{
113
+ position: absolute;
114
+ right: -24px;
115
+ top: 4;
116
+ opacity: 0;
117
+ }
118
+ .bagel-input:hover .toggleEditBtn, .bagel-input.editMode .toggleEditBtn{
119
+ opacity: 1;
120
+ }
121
+
122
+ .bagel-input.small input{
123
+ height: 30px;
124
+ }
125
+ </style>
@@ -157,7 +157,7 @@ function uploadFiles() {
157
157
  if (file.uploaded || file.uploading || !file.file) return;
158
158
  file.uploading = true;
159
159
  file.serverFile = await bagel.uploadFile(file.file, {
160
- onUploadProgress: (e) => (file.progress = e.progress * 100 - 1),
160
+ onUploadProgress: (e: any) => (file.progress = e.progress * 100 - 1),
161
161
  });
162
162
  file.progress += 1;
163
163
  emitValue();
package/tsconfig.json CHANGED
@@ -35,36 +35,6 @@
35
35
  "@bagelink/vue/*": [
36
36
  "./vue/src/*"
37
37
  ],
38
- // "#": [
39
- // "./src/index.ts"
40
- // ],
41
- // "#/*": [
42
- // "./src/*"
43
- // ],
44
- // "#/components": [
45
- // "./src/components/index.ts"
46
- // ],
47
- // "#/components/*": [
48
- // "./src/components/*"
49
- // ],
50
- // "#/types": [
51
- // "./src/types/index.ts"
52
- // ],
53
- // "#/types/*": [
54
- // "./src/types/*"
55
- // ],
56
- // "#/utils": [
57
- // "./src/utils/index.ts"
58
- // ],
59
- // "#/utils/*": [
60
- // "./src/utils/*"
61
- // ],
62
- // "#/plugins": [
63
- // "./src/plugins/index.ts"
64
- // ],
65
- // "#/plugins/*": [
66
- // "./src/plugins/*"
67
- // ],
68
38
  },
69
39
  },
70
40
  "include": [