@bagelink/vue 0.0.1100 → 0.0.1104

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.
package/dist/style.css CHANGED
@@ -755,6 +755,182 @@ pre code.hljs{
755
755
  direction: ltr;
756
756
  }
757
757
 
758
+ .bagel-input[data-v-e36ecd8c] {
759
+ display: flex;
760
+ flex-direction: column;
761
+ gap: 0.5rem;
762
+ position: relative;
763
+ }
764
+ .date-picker-container[data-v-e36ecd8c] {
765
+ position: relative;
766
+ }
767
+ .date-input[data-v-e36ecd8c] {
768
+ padding: 0.5rem;
769
+ border: 1px solid #ddd;
770
+ border-radius: 4px;
771
+ font-size: 1rem;
772
+ width: 100%;
773
+ background: white;
774
+ }
775
+ .date-input[data-v-e36ecd8c]:focus {
776
+ outline: none;
777
+ border-color: #4a90e2;
778
+ box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
779
+ }
780
+ .date-input[data-v-e36ecd8c]:disabled {
781
+ background-color: #f5f5f5;
782
+ cursor: not-allowed;
783
+ }
784
+ .small .date-input[data-v-e36ecd8c] {
785
+ padding: 0.25rem;
786
+ font-size: 0.875rem;
787
+ }
788
+ .required[data-v-e36ecd8c] {
789
+ color: #ff4d4f;
790
+ margin-left: 4px;
791
+ }
792
+ .calendar-popup[data-v-e36ecd8c] {
793
+ background: white;
794
+ border: 1px solid #ddd;
795
+ border-radius: 4px;
796
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
797
+ padding: 1rem;
798
+ }
799
+ .calendar-container[data-v-e36ecd8c] {
800
+ display: flex;
801
+ gap: 1rem;
802
+ }
803
+ .calendar-section[data-v-e36ecd8c] {
804
+ width: 300px;
805
+ }
806
+ .calendar-header[data-v-e36ecd8c] {
807
+ display: flex;
808
+ align-items: center;
809
+ justify-content: space-between;
810
+ margin-bottom: 1rem;
811
+ }
812
+ .month-year-selector[data-v-e36ecd8c] {
813
+ display: flex;
814
+ gap: 0.5rem;
815
+ align-items: center;
816
+ }
817
+ .month-btn[data-v-e36ecd8c],
818
+ .year-btn[data-v-e36ecd8c] {
819
+ background: none;
820
+ border: none;
821
+ font-weight: 500;
822
+ cursor: pointer;
823
+ padding: 0.25rem 0.5rem;
824
+ border-radius: 4px;
825
+ }
826
+ .month-btn[data-v-e36ecd8c]:hover,
827
+ .year-btn[data-v-e36ecd8c]:hover {
828
+ background-color: #f5f5f5;
829
+ }
830
+ .calendar-grid[data-v-e36ecd8c] {
831
+ display: grid;
832
+ grid-template-columns: repeat(7, 1fr);
833
+ gap: 0.25rem;
834
+ }
835
+ .month-grid[data-v-e36ecd8c] {
836
+ display: grid;
837
+ grid-template-columns: repeat(3, 1fr);
838
+ grid-template-rows: repeat(4, 1fr);
839
+ gap: 0.5rem;
840
+ padding: 0.5rem;
841
+ }
842
+ .year-grid[data-v-e36ecd8c] {
843
+ display: grid;
844
+ grid-template-columns: repeat(3, 1fr);
845
+ grid-template-rows: repeat(7, 1fr);
846
+ gap: 0.5rem;
847
+ padding: 0.5rem;
848
+ }
849
+ .month-item[data-v-e36ecd8c],
850
+ .year-item[data-v-e36ecd8c] {
851
+ display: flex;
852
+ align-items: center;
853
+ justify-content: center;
854
+ border: none;
855
+ background: none;
856
+ cursor: pointer;
857
+ border-radius: 4px;
858
+ font-size: 0.875rem;
859
+ color: #333;
860
+ padding: 0.5rem;
861
+ min-height: 2.5rem;
862
+ }
863
+ .month-item[data-v-e36ecd8c]:hover:not(.disabled),
864
+ .year-item[data-v-e36ecd8c]:hover:not(.disabled) {
865
+ background-color: #f5f5f5;
866
+ }
867
+ .month-item.selected[data-v-e36ecd8c],
868
+ .year-item.selected[data-v-e36ecd8c] {
869
+ background-color: #4a90e2;
870
+ color: white;
871
+ }
872
+ .month-item.disabled[data-v-e36ecd8c],
873
+ .year-item.disabled[data-v-e36ecd8c] {
874
+ color: #ccc;
875
+ cursor: not-allowed;
876
+ }
877
+ .weekday[data-v-e36ecd8c] {
878
+ text-align: center;
879
+ font-size: 0.875rem;
880
+ color: #666;
881
+ padding: 0.5rem 0;
882
+ }
883
+ .day[data-v-e36ecd8c] {
884
+ aspect-ratio: 1;
885
+ display: flex;
886
+ align-items: center;
887
+ justify-content: center;
888
+ border: none;
889
+ background: none;
890
+ cursor: pointer;
891
+ border-radius: 50%;
892
+ font-size: 0.875rem;
893
+ color: #333;
894
+ padding: 0;
895
+ }
896
+ .day[data-v-e36ecd8c]:hover:not(.disabled) {
897
+ background-color: #f5f5f5;
898
+ }
899
+ .day.selected[data-v-e36ecd8c] {
900
+ background-color: #4a90e2;
901
+ color: white;
902
+ }
903
+ .day.today[data-v-e36ecd8c]:not(.selected) {
904
+ border: 1px solid #4a90e2;
905
+ }
906
+ .day.disabled[data-v-e36ecd8c] {
907
+ color: #ccc;
908
+ cursor: not-allowed;
909
+ }
910
+ .timezone-display[data-v-e36ecd8c] {
911
+ color: #666;
912
+ font-size: 0.875rem;
913
+ text-align: center;
914
+ }
915
+ .time-picker[data-v-e36ecd8c] {
916
+ display: flex;
917
+ flex-direction: column;
918
+ gap: 1rem;
919
+ border-left: 1px solid #ddd;
920
+ width: 100px;
921
+ align-items: center;
922
+ }
923
+ .time-input-group[data-v-e36ecd8c] {
924
+ display: flex;
925
+ align-items: center;
926
+ gap: 0.25rem;
927
+ }
928
+ .time-input-group span[data-v-e36ecd8c] {
929
+ font-size: 1.25rem;
930
+ color: #666;
931
+ padding: 0 0.25rem;
932
+ }
933
+
758
934
  .datetime-wrap {
759
935
  display: flex;
760
936
  gap: 3rem;
@@ -1075,30 +1251,35 @@ pre code.hljs{
1075
1251
  direction: ltr;
1076
1252
  }
1077
1253
 
1078
- .txtInputIconStart .iconStart[data-v-a6e0446d] {
1254
+ .txtInputIconStart .iconStart[data-v-3a20cf4a] {
1079
1255
  color: var(--input-color);
1080
1256
  position: absolute;
1081
1257
  inset-inline-start:calc(var(--input-height) / 3 - 0.25rem);
1082
1258
  margin-top: calc(var(--input-height) / 2 );
1083
1259
  line-height: 0;
1084
1260
  }
1085
- .textInputSpinnerWrap .spinner[data-v-a6e0446d] {
1261
+ .textInputSpinnerWrap .spinner[data-v-3a20cf4a] {
1086
1262
  color: var(--input-color);
1087
1263
  position: absolute;
1088
1264
  inset-inline-end: 0;
1089
1265
  margin-top: calc(var(--input-height) / -1);
1090
1266
  line-height: 0;
1267
+ display: flex;
1268
+ flex-direction: column;
1269
+ gap: 0;
1091
1270
  }
1092
- .top-bgl-ctrl-num-btn[data-v-a6e0446d]{
1271
+ .top-bgl-ctrl-num-btn[data-v-3a20cf4a]{
1093
1272
  margin-top: calc(var(--input-height) / 10) !important;
1094
1273
  }
1095
- .bgl-ctrl-num-btn[data-v-a6e0446d]{
1274
+ .bgl-ctrl-num-btn[data-v-3a20cf4a]{
1096
1275
  height: calc(var(--input-height) / 2.5) !important;
1276
+ isolation: isolate;
1097
1277
  }
1098
- .bgl-big-ctrl-num-btn[data-v-a6e0446d]{
1278
+ .bgl-big-ctrl-num-btn[data-v-3a20cf4a]{
1099
1279
  width: 100% !important;
1280
+ isolation: isolate;
1100
1281
  }
1101
- .bgl-number-input[data-v-a6e0446d]{
1282
+ .bgl-number-input[data-v-3a20cf4a]{
1102
1283
  padding-inline-end: 1.75rem !important;
1103
1284
  }
1104
1285
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "0.0.1100",
4
+ "version": "0.0.1104",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Neveh Allon",
@@ -56,12 +56,18 @@ defineProps<{
56
56
  const emit = defineEmits(['show', 'hide'])
57
57
 
58
58
  const ddownRef = $ref<typeof DDown>()
59
+ const triggerRef = $ref<HTMLElement>()
59
60
  const shown = defineModel('shown', {
60
61
  type: Boolean,
61
62
  default: false,
62
63
  })
64
+
63
65
  const show = () => ddownRef?.show()
64
- const hide = () => ddownRef?.hide()
66
+ function hide() {
67
+ // Return focus to trigger element before hiding
68
+ triggerRef?.focus()
69
+ ddownRef?.hide()
70
+ }
65
71
 
66
72
  defineExpose({ show, hide, shown })
67
73
  </script>
@@ -75,8 +81,16 @@ defineExpose({ show, hide, shown })
75
81
  @hide="emit('hide')"
76
82
  @show="emit('show')"
77
83
  >
84
+ <div ref="triggerRef" />
78
85
  <slot name="trigger">
79
- <Btn :class="triggerClass" :iconEnd="iconEnd" :icon="icon" :value="value" :thin="thin" :flat="flat" />
86
+ <Btn
87
+ :class="triggerClass"
88
+ :iconEnd="iconEnd"
89
+ :icon="icon"
90
+ :value="value"
91
+ :thin="thin"
92
+ :flat="flat"
93
+ />
80
94
  </slot>
81
95
  <template #popper="{ hide, show }">
82
96
  <slot :hide="hide" :show="show" />
@@ -13,12 +13,10 @@ import {
13
13
  classify,
14
14
  NumberInput,
15
15
  UploadInput,
16
- type BagelFormState,
17
16
  BglForm
18
17
  } from '@bagelink/vue'
19
- import { inject } from 'vue'
18
+ import { useFormField } from '../../composables/useFormField'
20
19
  import TabsNav from '../layout/TabsNav.vue'
21
- import { FORM_STATE_KEY, provideBagelFormState } from './useBagelFormState'
22
20
 
23
21
  const props = defineProps<{
24
22
  field: Field<T>
@@ -31,7 +29,7 @@ const emit = defineEmits<{
31
29
  'update:modelValue': [value: any]
32
30
  }>()
33
31
 
34
- const formState = inject<BagelFormState<T>>(FORM_STATE_KEY) ?? provideBagelFormState(props.modelValue)
32
+ const { fieldData } = useFormField(props)
35
33
 
36
34
  const customAttrs = $ref<{ [key: string]: any }>({})
37
35
 
@@ -55,50 +53,17 @@ const is = $computed(() => {
55
53
  return props.field.$el ?? 'div'
56
54
  })
57
55
 
58
- const fieldData = $computed({
59
- get: () => {
60
- if (!props.fieldID) return props.field.defaultValue ?? (props.field.$el === 'form' ? {} : '')
61
- const value = formState.getFieldData(props.fieldID)
62
- if (props.field.$el === 'form' && !value) return {}
63
- return value ?? ''
64
- },
65
- set: (val: any) => {
66
- if (!props.fieldID) return
67
- const currentValue = formState.getFieldData(props.fieldID)
68
- if (JSON.stringify(val) === JSON.stringify(currentValue)) return
69
-
70
- emit('update:modelValue', val)
71
- if (props.field.onUpdate) {
72
- props.field.onUpdate(val, currentValue)
73
- }
74
- formState.updateField(props.fieldID, val)
75
- }
76
- })
77
-
78
- const vIf = $computed(() => {
79
- if (props.field['v-if'] === undefined && props.field.vIf === undefined) return true
80
- if (typeof props.field['v-if'] === 'boolean' || typeof props.field.vIf === 'boolean') return props.field['v-if']
81
- if (typeof props.field['v-if'] === 'string' || typeof props.field.vIf === 'string') return true
82
- if (typeof props.field['v-if'] === 'function') return props.field['v-if'](fieldData, formState.data.value as T)
83
- if (typeof props.field.vIf === 'function') return props.field.vIf(fieldData, formState.data.value as T)
84
- return true
85
- })
86
-
87
- // const computedFieldData = $computed(
88
- // () => props.field.transform?.(fieldData, formState.data.value as T) ?? fieldData
89
- // )
90
-
91
56
  const computedOptions = $computed(
92
- () => bindAttrs({ options: props.field.options }, fieldData, formState.data.value).options
57
+ () => bindAttrs({ options: props.field.options }, fieldData, props.modelValue).options
93
58
  )
94
59
 
95
60
  const computedAttrs = $computed(() => {
96
61
  const attrs = { ...customAttrs, ...props.field.attrs }
97
- return bindAttrs(attrs, fieldData, formState.data.value)
62
+ return bindAttrs(attrs, fieldData, props.modelValue)
98
63
  })
99
64
 
100
65
  const computedClass = $computed(
101
- () => classify(fieldData, formState.data.value, props.field.class, props.field.attrs?.class)
66
+ () => classify(fieldData, props.modelValue, props.field.class, props.field.attrs?.class)
102
67
  )
103
68
  </script>
104
69
 
@@ -106,7 +71,7 @@ const computedClass = $computed(
106
71
  <component
107
72
  v-bind="computedAttrs"
108
73
  :is="is"
109
- v-if="vIf"
74
+ v-if="field.vIf === undefined || field.vIf"
110
75
  v-model="fieldData"
111
76
  :fieldID="props.fieldID"
112
77
  :required="field.required"
@@ -47,7 +47,7 @@ if (!isNested) {
47
47
  data.value = newVal
48
48
  }, { deep: true, immediate: true })
49
49
 
50
- watch(() => data, (newVal) => {
50
+ watch(() => data.value, (newVal) => {
51
51
  if (emitDirty) return
52
52
  emitDirty = true
53
53
  emit('dirty')