@bagelink/vue 0.0.241 → 0.0.245

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 (47) hide show
  1. package/dist/components/Avatar.vue.d.ts +19 -3
  2. package/dist/components/Avatar.vue.d.ts.map +1 -1
  3. package/dist/components/ListItem.vue.d.ts +4 -0
  4. package/dist/components/ListItem.vue.d.ts.map +1 -1
  5. package/dist/components/ListView.vue.d.ts +1 -1
  6. package/dist/components/Modal.vue.d.ts.map +1 -1
  7. package/dist/components/ModalForm.vue.d.ts +6 -0
  8. package/dist/components/ModalForm.vue.d.ts.map +1 -1
  9. package/dist/components/form/BglField.vue.d.ts.map +1 -1
  10. package/dist/components/form/BglForm.vue.d.ts.map +1 -1
  11. package/dist/components/form/ItemRef.vue.d.ts +0 -1
  12. package/dist/components/form/ItemRef.vue.d.ts.map +1 -1
  13. package/dist/components/form/inputs/SelectField.vue.d.ts +4 -1
  14. package/dist/components/form/inputs/SelectField.vue.d.ts.map +1 -1
  15. package/dist/components/form/inputs/TextInput.vue.d.ts +2 -0
  16. package/dist/components/form/inputs/TextInput.vue.d.ts.map +1 -1
  17. package/dist/components/form/inputs/ToggleInput.vue.d.ts +7 -20
  18. package/dist/components/form/inputs/ToggleInput.vue.d.ts.map +1 -1
  19. package/dist/index.cjs +1876 -1868
  20. package/dist/index.mjs +1876 -1868
  21. package/dist/plugins/modal.d.ts +8 -6
  22. package/dist/plugins/modal.d.ts.map +1 -1
  23. package/dist/style.css +214 -74
  24. package/dist/types/BagelForm.d.ts +16 -12
  25. package/dist/types/BagelForm.d.ts.map +1 -1
  26. package/package.json +1 -1
  27. package/src/components/Avatar.vue +14 -17
  28. package/src/components/ListItem.vue +16 -9
  29. package/src/components/Modal.vue +2 -4
  30. package/src/components/ModalForm.vue +11 -34
  31. package/src/components/form/BglField.vue +18 -23
  32. package/src/components/form/BglForm.vue +21 -41
  33. package/src/components/form/inputs/TextInput.vue +27 -60
  34. package/src/components/form/inputs/ToggleInput.vue +29 -40
  35. package/src/plugins/modal.ts +12 -28
  36. package/src/styles/layout.css +197 -30
  37. package/src/styles/modal.css +15 -2
  38. package/src/styles/text.css +12 -0
  39. package/src/styles/theme.css +0 -10
  40. package/src/types/BagelForm.ts +16 -6
  41. package/src/utils/index.ts +2 -2
  42. package/dist/components/Drop.vue.d.ts +0 -34
  43. package/dist/components/Drop.vue.d.ts.map +0 -1
  44. package/dist/components/FileUploader.vue.d.ts +0 -60
  45. package/dist/components/FileUploader.vue.d.ts.map +0 -1
  46. package/src/types/BagelField.ts +0 -52
  47. package/src/utils/objects.ts +0 -81
@@ -1,39 +1,13 @@
1
1
  <template>
2
- <Modal
3
- :side="side"
4
- ref="modal"
5
- :dismissable="dismissable"
6
- :title="title"
7
- >
8
- <BagelForm
9
- v-model="formData"
10
- :schema="computedFormSchema"
11
- />
12
- <template
13
- #footer
14
- v-if="onDelete || onSubmit"
15
- >
2
+ <Modal @onUpdate:isModalVisible="props['onUpdate:isModalVisible']" :side="side" ref="modal" :dismissable="dismissable"
3
+ :title="title">
4
+ <BagelForm ref="form" v-model="formData" :schema="computedFormSchema" />
5
+ <template #footer v-if="onDelete || onSubmit">
16
6
  <div>
17
- <Btn
18
- thin
19
- flat
20
- value="Cancel"
21
- @click="closeModal()"
22
- />
23
- <Btn
24
- thin
25
- icon="delete"
26
- v-if="onDelete"
27
- flat
28
- value="Delete"
29
- @click="runDelete()"
30
- color="red"
31
- />
7
+ <Btn thin flat value="Cancel" @click="closeModal()" />
8
+ <Btn thin icon="delete" v-if="onDelete" flat value="Delete" @click="runDelete()" color="red" />
32
9
  </div>
33
- <Btn
34
- value="Submit"
35
- @click="runSubmit()"
36
- />
10
+ <Btn value="Submit" @click="runSubmit()" />
37
11
  </template>
38
12
  </Modal>
39
13
  </template>
@@ -55,6 +29,8 @@ const props = defineProps<{
55
29
  onSubmit?: ((formData: any) => Promise<void>);
56
30
  // eslint-disable-next-line no-unused-vars
57
31
  onDelete?: ((id: string) => void);
32
+ // eslint-disable-next-line no-unused-vars
33
+ 'onUpdate:isModalVisible'?: ((visible: boolean) => void);
58
34
  }>();
59
35
 
60
36
  const modal = $ref<InstanceType<typeof Modal>>();
@@ -65,10 +41,11 @@ const computedFormSchema = $computed(() => {
65
41
  });
66
42
 
67
43
  const formData = defineModel<Record<string, any>>('modelValue', { default: {} });
68
-
44
+ const form = $ref<InstanceType<typeof BagelForm>>();
69
45
  const closeModal = () => modal?.closeModal();
70
46
 
71
47
  const runSubmit = async () => {
48
+ if (form?.validateForm?.() === false) return;
72
49
  try {
73
50
  await props.onSubmit?.(formData.value);
74
51
  closeModal();
@@ -1,32 +1,17 @@
1
1
  <template>
2
- <component
3
- :required="field.required"
4
- v-bind="bindAttrs(field?.attrs || {}, fieldData, modelValue)"
5
- :class="classify(fieldData, modelValue, field.class, field.attrs?.class)"
6
- v-if="iffer(field, fieldData)"
7
- :is="is"
8
- :label="field.label"
9
- :id="field.id"
10
- :placeholder="field.placeholder || field.label"
11
- v-model="fieldData"
12
- :defaultValue="field.defaultValue"
13
- :options="field.options"
14
- :hint="field.hint"
15
- @update:modelValue="($event: any) => field?.onUpdate?.($event, denullify(fieldData, field.id), formData)"
16
- >
2
+ <component :required="field.required" v-bind="bindAttrs(field?.attrs || {}, fieldData, modelValue)"
3
+ :class="classify(fieldData, modelValue, field.class, field.attrs?.class)" v-if="vIf" :is="is" :label="field.label"
4
+ :id="field.id" :placeholder="field.placeholder || field.label" v-model="fieldData"
5
+ :defaultValue="field.defaultValue" :options="field.options" :helptext="field.helptext"
6
+ @update:modelValue="($event: any) => field?.onUpdate?.($event, denullify(fieldData, field.id), formData)">
17
7
  {{ field.transform?.(fieldData, modelValue) || fieldData || '' }}
18
- <BglField
19
- v-model="formData"
20
- v-for="(child, ii) in field.children"
21
- :key="child.id || ii"
22
- :field="child"
23
- />
8
+ <BglField v-model="formData" v-for="(child, ii) in field.children" :key="child.id || ii" :field="child" />
24
9
  </component>
25
10
  </template>
26
11
 
27
12
  <script lang="ts" setup>
28
13
  import {
29
- type Field, bindAttrs, classify, SelectInput, TextInput, ToggleInput, CheckInput, iffer, denullify,
14
+ type Field, bindAttrs, classify, SelectInput, TextInput, ToggleInput, CheckInput, denullify,
30
15
  } from '@bagelink/vue';
31
16
 
32
17
  const props = withDefaults(defineProps<{
@@ -58,6 +43,16 @@ const fieldData = $computed({
58
43
  data[props.field.id] = val;
59
44
  emit('update:modelValue', data);
60
45
  },
61
- get: () => (props.field.id ? props.modelValue[props.field.id] : ''),
46
+ get: () => (props.field.id ? props.modelValue[props.field.id] : props.field.defaultValue || ''),
47
+ });
48
+
49
+ const vIf = $computed(() => {
50
+ if (props.field['v-if'] === undefined) return true;
51
+ if (typeof props.field['v-if'] === 'boolean') return props.field['v-if'];
52
+ if (typeof props.field['v-if'] === 'string') return true;
53
+ if (typeof props.field['v-if'] === 'function') {
54
+ return props.field['v-if']?.(fieldData, formData);
55
+ }
56
+ return true;
62
57
  });
63
58
  </script>
@@ -1,46 +1,19 @@
1
1
  <template>
2
- <component
3
- :is="id?'div':'form'"
4
- ref="form"
5
- @submit.prevent="runSubmit"
6
- >
7
- <Title
8
- tag="h4"
9
- :label="label"
10
- v-if="label"
11
- />
12
- <BglField
13
- v-for="(field, i) in schema"
14
- :key="field.id || `${i}p`"
15
- :field="field"
16
- v-model="data"
17
- />
18
- <Btn
19
- class="del-top"
20
- v-if="data?.id && onDelete"
21
- @click="runDelete"
22
- value="Delete"
23
- flat
24
- icon="delete"
25
- color="red"
26
- thin
27
- />
28
- <Btn
29
- v-if="!$slots.submit && onSubmit"
30
- value="Submit"
31
- type="submit"
32
- thin
33
- />
34
- <div v-else>
35
- <slot name="submit" />
36
- </div>
37
- </component>
2
+ <template v-if="id">
3
+ <BglField v-for="(field, i) in schema" :key="field.id || `${i}p`" :field="field" v-model="data" />
4
+ </template>
5
+ <form v-else ref="form" @submit.prevent="runSubmit">
6
+ <Title tag="h4" :label="label" v-if="label" />
7
+ <BglField v-for="(field, i) in schema" :key="field.id || `${i}p`" :field="field" v-model="data" />
8
+ <slot name="submit" />
9
+ </form>
38
10
  </template>
39
11
 
40
12
  <script lang="ts" setup>
41
13
  import {
42
- Btn, useModal, BglField, Title,
14
+ useModal, BglField, Title,
43
15
  } from '@bagelink/vue';
16
+
44
17
  import { type BglFormSchemaT } from '@bagelink/vue';
45
18
 
46
19
  const { showModal } = useModal();
@@ -59,10 +32,17 @@ const props = withDefaults(
59
32
  },
60
33
  );
61
34
 
62
- const emit = defineEmits(['update:modelValue', 'submit']);
35
+ const timeSinceInst = () => new Date().getTime() - instAt.getTime();
63
36
 
37
+ const emit = defineEmits(['update:modelValue', 'submit', 'dirty']);
38
+ const instAt = new Date();
39
+ let isDirty = $ref(false);
64
40
  const data = $computed({
65
41
  set: (val: any) => {
42
+ if (timeSinceInst() > 100) {
43
+ emit('dirty');
44
+ isDirty = true;
45
+ }
66
46
  emit('update:modelValue', val);
67
47
  },
68
48
  get: () => props.modelValue || {},
@@ -71,8 +51,6 @@ const form = $ref<HTMLFormElement>();
71
51
 
72
52
  const validateForm = () => form?.reportValidity?.();
73
53
 
74
- defineExpose({ validateForm });
75
-
76
54
  const clearForm = () => Object.assign(data, {});
77
55
 
78
56
  const runSubmit = () => {
@@ -83,7 +61,7 @@ const runSubmit = () => {
83
61
 
84
62
  const i18nT = (val: string) => val;
85
63
 
86
- const runDelete = () => {
64
+ const deleteItem = () => {
87
65
  showModal(
88
66
  {
89
67
  class: 'small-modal',
@@ -100,6 +78,8 @@ const runDelete = () => {
100
78
  { default: i18nT('form.deleteMessage') },
101
79
  );
102
80
  };
81
+
82
+ defineExpose({ validateForm, deleteItem, isDirty });
103
83
  </script>
104
84
 
105
85
  <style>
@@ -1,59 +1,22 @@
1
1
  <template>
2
- <div
3
- class="bagel-input text-input"
2
+ <div class="bagel-input text-input"
4
3
  :class="{ small, shrink, toggleEdit, editMode, textInputIconWrap: icon, txtInputIconStart: iconStart, code }"
5
- :title="title"
6
- >
4
+ :title="title">
7
5
  <label :for="id">
8
6
  {{ label }}
9
- <input
10
- :autocomplete="autocomplete"
11
- v-if="!multiline && !autoheight && !code"
12
- :id="id"
13
- v-model="inputVal"
14
- :type="type"
15
- :rows="1"
16
- ref="input"
17
- :placeholder="placeholder || label"
18
- :disabled="!editMode"
19
- :required="required"
20
- :pattern="pattern"
21
- v-bind="nativeInputAttrs"
22
- @dblclick="toggleEditAction"
23
- >
24
- <textarea
25
- v-else
26
- :id="id"
27
- v-model="inputVal"
28
- :type="type"
29
- :rows="rows"
30
- ref="input"
31
- :placeholder="placeholder || label"
32
- :disabled="!editMode"
33
- :required="required"
34
- :pattern="pattern"
35
- v-bind="nativeInputAttrs"
36
- @dblclick="toggleEditAction"
37
- />
7
+ <input :autocomplete="autocomplete" v-if="!multiline && !autoheight && !code" :id="id" v-model="inputVal"
8
+ :type="type" :rows="1" ref="input" :placeholder="placeholder || label" :disabled="!editMode"
9
+ :required="required" :pattern="pattern" v-bind="nativeInputAttrs" @dblclick="toggleEditAction">
10
+ <textarea v-else :id="id" v-model="inputVal" :type="type" :rows="rows" ref="input"
11
+ :placeholder="placeholder || label" :disabled="!editMode" :required="required" :pattern="pattern"
12
+ v-bind="nativeInputAttrs" @dblclick="toggleEditAction" />
13
+ <p v-if="helptext">{{ helptext }}</p>
38
14
  </label>
39
15
 
40
- <MaterialIcon
41
- class="iconStart"
42
- v-if="iconStart"
43
- :icon="iconStart"
44
- />
45
- <MaterialIcon
46
- v-if="icon"
47
- :icon="icon"
48
- />
49
- <Btn
50
- class="toggleEditBtn"
51
- v-if="toggleEdit"
52
- thin
53
- @click="toggleEditAction"
54
- :icon="editMode ? 'check' : 'edit'"
55
- flat
56
- />
16
+ <MaterialIcon class="iconStart" v-if="iconStart" :icon="iconStart" />
17
+ <MaterialIcon v-if="icon" :icon="icon" />
18
+ <Btn class="toggleEditBtn" v-if="toggleEdit" thin @click="toggleEditAction" :icon="editMode ? 'check' : 'edit'"
19
+ flat />
57
20
  </div>
58
21
  </template>
59
22
 
@@ -68,6 +31,7 @@ const props = withDefaults(
68
31
  defineProps<{
69
32
  id?: string;
70
33
  title?: string;
34
+ helptext?: string;
71
35
  placeholder?: string;
72
36
  modelValue?: string | number;
73
37
  label?: string;
@@ -80,8 +44,8 @@ const props = withDefaults(
80
44
  nativeInputAttrs?: Record<string, any>;
81
45
  icon?: MaterialIcons;
82
46
  iconStart?: MaterialIcons;
83
- multiline?: boolean;
84
- autoheight?: boolean;
47
+ multiline?: boolean;
48
+ autoheight?: boolean;
85
49
  code?: boolean;
86
50
  lines?: number;
87
51
  autocomplete?: string;
@@ -144,17 +108,20 @@ watch(
144
108
  </style>
145
109
 
146
110
  <style scoped>
147
- .bagel-input textarea{
148
- min-height: unset;
111
+ .bagel-input textarea {
112
+ min-height: unset;
149
113
  }
150
- .bagel-input.text-input textarea{
151
- resize: none;
114
+
115
+ .bagel-input.text-input textarea {
116
+ resize: none;
152
117
  }
153
- .code textarea{
154
- font-family: 'Inconsolata', monospace;
155
- background: var(--bgl-black) !important;
156
- color: var(--bgl-white) !important;
118
+
119
+ .code textarea {
120
+ font-family: 'Inconsolata', monospace;
121
+ background: var(--bgl-black) !important;
122
+ color: var(--bgl-white) !important;
157
123
  }
124
+
158
125
  .bagel-input.toggleEdit:hover {
159
126
  background-color: var(--input-bg);
160
127
  }
@@ -1,59 +1,48 @@
1
1
  <template>
2
- <div
3
- class="bagel-input bgl-checkbox"
4
- :title="title"
5
- :class="{ small: small, 'no-edit': !editMode }"
6
- >
7
- <div class="switch">
8
- <input
9
- :id="id"
10
- type="checkbox"
11
- v-model="inputVal"
12
- :class="{ 'no-edit': !editMode }"
13
- >
14
- <span class="slider round" />
15
- </div>
16
- <label :for="id">
17
- {{ label }}
18
- </label>
19
- </div>
2
+ <div class="bagel-input bgl-checkbox justify-content-center gap-3" :title="title" :class="{ small: small }">
3
+ <div class="switch" :class="{ checked }">
4
+ <span class="slider round" />
5
+ </div>
6
+ <label>
7
+ {{ label }}
8
+ <input :id="id" type="checkbox" v-model="checked">
9
+ </label>
10
+ </div>
20
11
  </template>
21
12
 
22
13
  <script setup lang="ts">
23
- withDefaults(
24
- defineProps<{
25
- label: string;
26
- id?: string;
27
- title?: string;
28
- editMode?: boolean;
29
- small?: boolean;
30
- }>(),
31
- {
32
- editMode: true,
33
- id: Math.random().toString(36).substring(7),
34
- },
35
- );
14
+ defineProps<{
15
+ label: string;
16
+ id?: string;
17
+ title?: string;
18
+ small?: boolean;
19
+ }>();
36
20
 
37
- const inputVal = defineModel<boolean>('modelValue', { default: false });
21
+ const checked = defineModel<boolean>('modelValue', { default: false });
38
22
  </script>
39
23
 
40
24
  <style scoped>
41
- .bgl-checkbox{
25
+ .bgl-checkbox {
42
26
  position: relative;
43
27
  }
44
- .bgl-checkbox input[type=checkbox]{
28
+
29
+ .bgl-checkbox input[type=checkbox] {
45
30
  display: none;
46
31
  }
47
- .bgl-checkbox label{
32
+
33
+ .bgl-checkbox label {
48
34
  padding-inline-start: calc(var(--input-height) + 0.25rem);
49
35
  transition: var(--bgl-transition);
50
36
  cursor: pointer;
51
37
  user-select: none;
38
+ line-height: var(--input-height);
52
39
  }
53
- .bgl-checkbox:hover{
40
+
41
+ .bgl-checkbox:hover {
54
42
  filter: brightness(90%);
55
43
  }
56
- .bgl-checkbox:active{
44
+
45
+ .bgl-checkbox:active {
57
46
  filter: var(--bgl-active-filter);
58
47
  }
59
48
 
@@ -64,7 +53,7 @@ const inputVal = defineModel<boolean>('modelValue', { default: false });
64
53
  width: var(--input-height);
65
54
  border-radius: var(--input-height);
66
55
  background: var(--bgl-gray);
67
- outline: 1px solid var(--bgl-black);
56
+ outline: 1px solid var(--border-color);
68
57
  margin-top: 0.15rem;
69
58
  pointer-events: none;
70
59
  }
@@ -102,11 +91,11 @@ const inputVal = defineModel<boolean>('modelValue', { default: false });
102
91
  transition: 0.4s;
103
92
  }
104
93
 
105
- input:checked + .slider {
94
+ .checked .slider {
106
95
  background: var(--bgl-primary);
107
96
  }
108
97
 
109
- input:checked + .slider:before {
98
+ .checked .slider:before {
110
99
  transform: translateX(calc(var(--input-height) / 2));
111
100
  }
112
101
  </style>
@@ -13,26 +13,20 @@ interface ModalOptions {
13
13
  class?: string;
14
14
  }
15
15
 
16
- interface ModalFormOptions extends ModalOptions {
17
- modelValue?: any;
18
- // eslint-disable-next-line no-unused-vars
19
- 'onUpdate:modelValue'?: (val: any) => void;
20
- // eslint-disable-next-line no-unused-vars
21
- onSubmit: (val: any) => void;
22
- // eslint-disable-next-line no-unused-vars
23
- onDelete?: (id: string) => void;
24
- schema: BglFormSchemaT<any> | (() => BglFormSchemaT<any>);
25
-
16
+ interface ModalFormOptions {
17
+ side?: boolean;
18
+ title?: string;
19
+ dismissable?: boolean;
20
+ schema: BglFormSchemaT<any> | (() => BglFormSchemaT);
21
+ modelValue?: Record<string, any>;
22
+ onSubmit?: (formData: any) => Promise<any>;
23
+ onDelete?: (id: string) => Promise<void>;
26
24
  }
27
25
 
28
26
  interface ModalApi {
29
- // eslint-disable-next-line no-unused-vars
30
27
  showModal: (options: ModalOptions, slots?: Record<string, any>) => void;
31
- // eslint-disable-next-line no-unused-vars
32
28
  showModalForm: (options: ModalFormOptions, slots?: Record<string, any>) => void;
33
- // eslint-disable-next-line no-unused-vars
34
29
  hideModal: (index?: number) => void;
35
- // modalOptions: Ref<ModalOptions | ModalFormOptions>;
36
30
  }
37
31
 
38
32
  export const ModalSymbol: InjectionKey<ModalApi> = Symbol('modal');
@@ -77,22 +71,12 @@ export const ModalPlugin: Plugin = {
77
71
  });
78
72
 
79
73
  const ModalComponent = defineComponent({
80
- data() {
81
- return {
82
- modalStack,
83
- };
84
- },
74
+ data: () => ({ modalStack }),
85
75
  render() {
86
76
  return modalStack.map((modal, index) => {
87
- const renderComponent = modal.modalType === 'modalForm' ? ModalForm : Modal;
88
- return h(
89
- renderComponent,
90
- {
91
- ...modal.modalOptions,
92
- 'onUpdate:isModalVisible': () => hideModal(index),
93
- },
94
- modal.componentSlots,
95
- );
77
+ const props = { ...modal.modalOptions, 'onUpdate:isModalVisible': () => hideModal(index) };
78
+ if (modal.modalType === 'modalForm') return h(ModalForm, props as ModalFormOptions, modal.componentSlots);
79
+ return h(Modal, props, modal.componentSlots);
96
80
  });
97
81
  },
98
82
  });