@bagelink/vue 1.2.15 → 1.2.20
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/components/calendar/CalendarTypes.d.ts +13 -0
- package/dist/components/calendar/CalendarTypes.d.ts.map +1 -0
- package/dist/components/calendar/Index.vue.d.ts +39 -507
- package/dist/components/calendar/Index.vue.d.ts.map +1 -1
- package/dist/components/calendar/utils.d.ts +31 -0
- package/dist/components/calendar/utils.d.ts.map +1 -0
- package/dist/components/calendar/views/AgendaView.vue.d.ts +16 -0
- package/dist/components/calendar/views/AgendaView.vue.d.ts.map +1 -0
- package/dist/components/calendar/views/DayView.vue.d.ts +50 -0
- package/dist/components/calendar/views/DayView.vue.d.ts.map +1 -0
- package/dist/components/calendar/views/MonthView.vue.d.ts +20 -0
- package/dist/components/calendar/views/MonthView.vue.d.ts.map +1 -0
- package/dist/components/calendar/views/WeekView.vue.d.ts +33 -0
- package/dist/components/calendar/views/WeekView.vue.d.ts.map +1 -0
- package/dist/components/form/BglMultiStepForm.vue.d.ts +63 -0
- package/dist/components/form/BglMultiStepForm.vue.d.ts.map +1 -0
- package/dist/components/form/index.d.ts +1 -0
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/DateInput.vue.d.ts +3 -3
- package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/DatePicker.vue.d.ts +3 -3
- package/dist/components/form/inputs/DatePicker.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/index.cjs +2241 -3891
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +2242 -3892
- package/dist/style.css +567 -633
- package/dist/utils/BagelFormUtils.d.ts +4 -2
- package/dist/utils/BagelFormUtils.d.ts.map +1 -1
- package/dist/utils/calendar/EDate.d.ts +2 -0
- package/dist/utils/calendar/EDate.d.ts.map +1 -0
- package/dist/utils/calendar/Helpers.d.ts +19 -0
- package/dist/utils/calendar/Helpers.d.ts.map +1 -0
- package/dist/utils/calendar/constants.d.ts +3 -0
- package/dist/utils/calendar/constants.d.ts.map +1 -0
- package/dist/utils/calendar/dateUtils.d.ts +30 -0
- package/dist/utils/calendar/dateUtils.d.ts.map +1 -0
- package/dist/utils/calendar/event.interface.d.ts +32 -0
- package/dist/utils/calendar/event.interface.d.ts.map +1 -0
- package/dist/utils/calendar/time.d.ts +117 -0
- package/dist/utils/calendar/time.d.ts.map +1 -0
- package/dist/utils/calendar/types.d.ts +27 -0
- package/dist/utils/calendar/types.d.ts.map +1 -0
- package/dist/utils/calendar/typings.d.ts +87 -0
- package/dist/utils/calendar/typings.d.ts.map +1 -0
- package/dist/utils/calendar/week.d.ts +117 -0
- package/dist/utils/calendar/week.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/calendar/CalendarTypes.ts +13 -0
- package/src/components/calendar/Index.vue +124 -389
- package/src/components/calendar/utils.ts +70 -0
- package/src/components/calendar/views/AgendaView.vue +263 -0
- package/src/components/calendar/views/DayView.vue +373 -0
- package/src/components/calendar/views/MonthView.vue +313 -0
- package/src/components/calendar/views/WeekView.vue +431 -0
- package/src/components/form/BglMultiStepForm.vue +383 -69
- package/src/components/form/index.ts +1 -0
- package/src/components/form/inputs/CodeEditor/Index.vue +11 -0
- package/src/components/form/inputs/DateInput.vue +3 -3
- package/src/components/form/inputs/DatePicker.vue +35 -30
- package/src/components/form/inputs/SelectInput.vue +2 -0
- package/src/components/form/inputs/Upload/upload.types.d.ts +0 -1
- package/src/index.ts +2 -2
- package/src/styles/inputs.css +138 -137
- package/src/styles/layout.css +3 -2
- package/src/styles/mobilLayout.css +4 -2
- package/src/utils/BagelFormUtils.ts +6 -2
- package/src/utils/calendar/EDate.ts +0 -0
- package/src/{components/calendar/helpers → utils/calendar}/Helpers.ts +6 -6
- package/src/utils/calendar/constants.ts +2 -0
- package/src/utils/{timeAgo.ts → calendar/dateUtils.ts} +38 -1
- package/src/utils/calendar/event.interface.ts +33 -0
- package/src/{components/calendar/helpers/Time.ts → utils/calendar/time.ts} +15 -15
- package/src/utils/calendar/types.ts +27 -0
- package/src/{components/calendar/typings/config.interface.ts → utils/calendar/typings.ts} +13 -6
- package/src/utils/calendar/week.ts +588 -0
- package/src/components/calendar/assets/base.css +0 -60
- package/src/components/calendar/components/header/Header.vue +0 -153
- package/src/components/calendar/components/month/AgendaEventTile.vue +0 -135
- package/src/components/calendar/components/month/AgendaEvents.vue +0 -72
- package/src/components/calendar/components/month/Day.vue +0 -256
- package/src/components/calendar/components/month/Event.vue +0 -164
- package/src/components/calendar/components/month/Month.vue +0 -241
- package/src/components/calendar/components/month/WeekDay.vue +0 -15
- package/src/components/calendar/components/partials/EventFlyout.vue +0 -430
- package/src/components/calendar/components/week/Day.vue +0 -198
- package/src/components/calendar/components/week/DayEvent.vue +0 -584
- package/src/components/calendar/components/week/DayTimeline.vue +0 -80
- package/src/components/calendar/components/week/FullDayEvent.vue +0 -121
- package/src/components/calendar/components/week/Week.vue +0 -414
- package/src/components/calendar/components/week/WeekTimeline.vue +0 -101
- package/src/components/calendar/constants.ts +0 -13
- package/src/components/calendar/helpers/DayIntervals.ts +0 -48
- package/src/components/calendar/helpers/EDate.ts +0 -18
- package/src/components/calendar/helpers/Errors.ts +0 -69
- package/src/components/calendar/helpers/EventChange.ts +0 -88
- package/src/components/calendar/helpers/EventConcurrency.ts +0 -69
- package/src/components/calendar/helpers/EventFlyoutPosition.ts +0 -96
- package/src/components/calendar/helpers/EventPosition.ts +0 -154
- package/src/components/calendar/helpers/EventsFilter.ts +0 -50
- package/src/components/calendar/helpers/Week.ts +0 -37
- package/src/components/calendar/language/index.ts +0 -41
- package/src/components/calendar/language/keys.ts +0 -99
- package/src/components/calendar/models/Event.ts +0 -112
- package/src/components/calendar/styles/_mixins.css +0 -21
- package/src/components/calendar/styles/_variables.css +0 -47
- package/src/components/calendar/typings/interfaces/day.interface.ts +0 -10
- package/src/components/calendar/typings/interfaces/event.interface.ts +0 -32
- package/src/components/calendar/typings/interfaces/full-day-events-week.type.ts +0 -8
- package/src/components/calendar/typings/interfaces/period.interface.ts +0 -5
- package/src/components/calendar/typings/interfaces/time-modes.ts +0 -11
- package/src/components/calendar/typings/types.ts +0 -27
|
@@ -3,7 +3,7 @@ import type { BglFormSchemaFnT } from '@bagelink/vue'
|
|
|
3
3
|
|
|
4
4
|
import type { ComponentExposed, ComponentProps } from 'vue-component-type-helpers'
|
|
5
5
|
import { BagelForm, Btn, useBglSchema } from '@bagelink/vue'
|
|
6
|
-
import { watch } from 'vue'
|
|
6
|
+
import { ref, watch, computed } from 'vue'
|
|
7
7
|
|
|
8
8
|
const props = withDefaults(
|
|
9
9
|
defineProps<{
|
|
@@ -14,56 +14,176 @@ const props = withDefaults(
|
|
|
14
14
|
)
|
|
15
15
|
>
|
|
16
16
|
schema: BglFormSchemaFnT<T>
|
|
17
|
+
showProgress?: boolean
|
|
18
|
+
rtl?: boolean
|
|
19
|
+
stepLabels?: string[]
|
|
20
|
+
allowStepNavigation?: boolean
|
|
21
|
+
validateOnSteps?: boolean
|
|
22
|
+
/** Animation direction - auto detects based on step change or can be forced */
|
|
23
|
+
direction?: 'auto' | 'left' | 'right'
|
|
17
24
|
}>(),
|
|
18
25
|
{
|
|
19
|
-
bagelFormProps: () => ({})
|
|
26
|
+
bagelFormProps: () => ({}),
|
|
27
|
+
showProgress: false,
|
|
28
|
+
rtl: false,
|
|
29
|
+
allowStepNavigation: false,
|
|
30
|
+
validateOnSteps: true,
|
|
31
|
+
direction: 'auto'
|
|
20
32
|
}
|
|
21
33
|
)
|
|
22
34
|
|
|
23
|
-
const emits = defineEmits(['submit'])
|
|
35
|
+
const emits = defineEmits(['submit', 'stepChange'])
|
|
24
36
|
|
|
25
37
|
type BagelFormT = ComponentExposed<typeof BagelForm<T, P>>
|
|
26
38
|
|
|
27
|
-
const formRef =
|
|
39
|
+
const formRef = ref<BagelFormT>()
|
|
28
40
|
|
|
29
|
-
const formData = defineModel<T>(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
)
|
|
41
|
+
const formData = defineModel<T>('modelValue', {
|
|
42
|
+
default: () => ({}),
|
|
43
|
+
required: true
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const currentStep = ref(0)
|
|
47
|
+
const previousStep = ref(0)
|
|
48
|
+
const validatedSteps = ref<number[]>([])
|
|
33
49
|
|
|
34
50
|
function reportValidity() {
|
|
35
|
-
if (!formRef) return false
|
|
36
|
-
|
|
51
|
+
if (!formRef.value) return false
|
|
52
|
+
const isValid = formRef.value.validateForm()
|
|
53
|
+
|
|
54
|
+
if (isValid && !validatedSteps.value.includes(currentStep.value)) {
|
|
55
|
+
validatedSteps.value.push(currentStep.value)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return isValid
|
|
37
59
|
}
|
|
38
60
|
|
|
39
|
-
const computedSchema =
|
|
61
|
+
const computedSchema = computed(
|
|
40
62
|
() => useBglSchema({ schema: props.schema })
|
|
41
63
|
)
|
|
42
64
|
|
|
43
|
-
|
|
65
|
+
// Filter out steps with vIf conditions that evaluate to false
|
|
66
|
+
const filteredSchema = computed(() => {
|
|
67
|
+
const schema = computedSchema.value
|
|
68
|
+
return schema.filter((step, index) => {
|
|
69
|
+
// Skip steps that have vIf or v-if returning false
|
|
70
|
+
if (step.vIf !== undefined || step['v-if'] !== undefined) {
|
|
71
|
+
const condition = step.vIf ?? step['v-if']
|
|
72
|
+
// If condition is a function, evaluate it with current form data
|
|
73
|
+
if (typeof condition === 'function') {
|
|
74
|
+
return condition(undefined, formData.value)
|
|
75
|
+
}
|
|
76
|
+
// If condition is a boolean, use it directly
|
|
77
|
+
if (typeof condition === 'boolean') {
|
|
78
|
+
return condition
|
|
79
|
+
}
|
|
80
|
+
// If condition is a string, evaluate it (treat non-empty as true)
|
|
81
|
+
if (typeof condition === 'string') {
|
|
82
|
+
return !!condition
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// Include steps with no vIf condition or ones that evaluate to true
|
|
86
|
+
return true
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const numberOfSteps = computed(() => filteredSchema.value.length)
|
|
91
|
+
|
|
92
|
+
// Map the filtered step index to the actual schema index
|
|
93
|
+
const schemaIndexMap = computed(() => {
|
|
94
|
+
const map: number[] = []
|
|
95
|
+
computedSchema.value.forEach((step, index) => {
|
|
96
|
+
const vIfCondition = step.vIf ?? step['v-if']
|
|
97
|
+
let shouldInclude = true
|
|
98
|
+
|
|
99
|
+
if (vIfCondition !== undefined) {
|
|
100
|
+
if (typeof vIfCondition === 'function') {
|
|
101
|
+
shouldInclude = vIfCondition(undefined, formData.value)
|
|
102
|
+
} else if (typeof vIfCondition === 'boolean') {
|
|
103
|
+
shouldInclude = vIfCondition
|
|
104
|
+
} else if (typeof vIfCondition === 'string') {
|
|
105
|
+
shouldInclude = !!vIfCondition
|
|
106
|
+
}
|
|
107
|
+
}
|
|
44
108
|
|
|
45
|
-
|
|
109
|
+
if (shouldInclude) {
|
|
110
|
+
map.push(index)
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
return map
|
|
114
|
+
})
|
|
46
115
|
|
|
47
|
-
|
|
116
|
+
// Get current step schema using the mapping
|
|
117
|
+
const currentStepSchema = computed(() => {
|
|
118
|
+
const actualIndex = schemaIndexMap.value[currentStep.value]
|
|
119
|
+
return [computedSchema.value[actualIndex]]
|
|
120
|
+
})
|
|
48
121
|
|
|
49
|
-
|
|
122
|
+
const isStepping = ref(false)
|
|
50
123
|
let isSteppingTO: NodeJS.Timeout
|
|
124
|
+
|
|
125
|
+
// Tracks which way we're sliding (left or right)
|
|
126
|
+
const slideDirection = ref(props.rtl ? 'right' : 'left')
|
|
127
|
+
|
|
51
128
|
watch(
|
|
52
|
-
() => currentStep,
|
|
53
|
-
() => {
|
|
129
|
+
() => currentStep.value,
|
|
130
|
+
(newStep, oldStep) => {
|
|
131
|
+
// Set direction based on step change
|
|
132
|
+
if (props.direction === 'auto') {
|
|
133
|
+
slideDirection.value = props.rtl
|
|
134
|
+
? (newStep > oldStep ? 'right' : 'left')
|
|
135
|
+
: (newStep > oldStep ? 'left' : 'right')
|
|
136
|
+
} else {
|
|
137
|
+
slideDirection.value = props.direction
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
previousStep.value = oldStep
|
|
54
141
|
clearTimeout(isSteppingTO)
|
|
55
|
-
isStepping = true
|
|
56
|
-
isSteppingTO = setTimeout(() => (isStepping = false),
|
|
142
|
+
isStepping.value = true
|
|
143
|
+
isSteppingTO = setTimeout(() => (isStepping.value = false), 200)
|
|
144
|
+
emits('stepChange', {
|
|
145
|
+
newStep,
|
|
146
|
+
oldStep,
|
|
147
|
+
totalSteps: numberOfSteps.value,
|
|
148
|
+
direction: slideDirection.value
|
|
149
|
+
})
|
|
57
150
|
}
|
|
58
151
|
)
|
|
59
152
|
|
|
60
|
-
const canDoNext =
|
|
153
|
+
const canDoNext = computed(() => currentStep.value < numberOfSteps.value - 1)
|
|
61
154
|
|
|
62
|
-
|
|
155
|
+
const isStepValidated = computed(() => (stepIndex: number) => validatedSteps.value.includes(stepIndex))
|
|
156
|
+
|
|
157
|
+
function prevStep() {
|
|
158
|
+
if (currentStep.value > 0) currentStep.value--
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const formContainer = ref<HTMLElement>()
|
|
63
162
|
|
|
64
163
|
function nextStep() {
|
|
65
|
-
if (reportValidity() === false) return
|
|
66
|
-
if (canDoNext) currentStep++
|
|
164
|
+
if (props.validateOnSteps && reportValidity() === false) return
|
|
165
|
+
if (canDoNext.value) currentStep.value++
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function goToStep(stepIndex: number) {
|
|
169
|
+
// Can always go back, or to already validated steps
|
|
170
|
+
if (stepIndex < currentStep.value || validatedSteps.value.includes(stepIndex)) {
|
|
171
|
+
currentStep.value = stepIndex
|
|
172
|
+
return true
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// For forward navigation to non-validated steps, validate current step first if needed
|
|
176
|
+
if (props.validateOnSteps && reportValidity() === false) {
|
|
177
|
+
return false
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Can only move one step forward at a time (prevent skipping)
|
|
181
|
+
if (stepIndex === currentStep.value + 1) {
|
|
182
|
+
currentStep.value = stepIndex
|
|
183
|
+
return true
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return false
|
|
67
187
|
}
|
|
68
188
|
|
|
69
189
|
function handleSubmit() {
|
|
@@ -71,56 +191,250 @@ function handleSubmit() {
|
|
|
71
191
|
emits('submit', formData.value)
|
|
72
192
|
}
|
|
73
193
|
|
|
194
|
+
function reset() {
|
|
195
|
+
validatedSteps.value = []
|
|
196
|
+
currentStep.value = 0
|
|
197
|
+
// Clear form if BagelForm supports it
|
|
198
|
+
// if (formRef.value && typeof formRef.value.clearForm === 'function') {
|
|
199
|
+
// formRef.value.clearForm()
|
|
200
|
+
// }
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Re-evaluate filtered steps when formData changes
|
|
204
|
+
watch(() => formData.value, () => {
|
|
205
|
+
// If current step index is now invalid after filtering, reset to first valid step
|
|
206
|
+
if (currentStep.value >= numberOfSteps.value && numberOfSteps.value > 0) {
|
|
207
|
+
currentStep.value = 0
|
|
208
|
+
}
|
|
209
|
+
}, { deep: true })
|
|
210
|
+
|
|
74
211
|
defineExpose({
|
|
75
212
|
submit: handleSubmit,
|
|
76
|
-
validateForm:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
213
|
+
validateForm: reportValidity,
|
|
214
|
+
isDirty: computed(() => formRef.value?.isDirty),
|
|
215
|
+
reset,
|
|
216
|
+
goToStep,
|
|
217
|
+
currentStep: computed(() => currentStep.value),
|
|
218
|
+
totalSteps: computed(() => numberOfSteps.value),
|
|
219
|
+
nextStep,
|
|
220
|
+
prevStep,
|
|
80
221
|
})
|
|
81
222
|
</script>
|
|
82
223
|
|
|
83
224
|
<template>
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
225
|
+
<div class="bgl-multi-step-form">
|
|
226
|
+
<!-- Progress indicator -->
|
|
227
|
+
<div v-if="showProgress" class="bgl-step-progress">
|
|
228
|
+
<slot
|
|
229
|
+
name="progress" v-bind="{
|
|
230
|
+
currentStep,
|
|
231
|
+
totalSteps: numberOfSteps,
|
|
232
|
+
goToStep,
|
|
233
|
+
stepLabels: props.stepLabels,
|
|
234
|
+
allowStepNavigation: props.allowStepNavigation,
|
|
235
|
+
isStepValidated,
|
|
236
|
+
}"
|
|
237
|
+
>
|
|
238
|
+
<div class="bgl-steps-indicator">
|
|
239
|
+
<div
|
|
240
|
+
v-for="(_, index) in numberOfSteps"
|
|
241
|
+
:key="index"
|
|
242
|
+
class="bgl-step-indicator" :class="[
|
|
243
|
+
{ active: index === currentStep },
|
|
244
|
+
{ completed: index < currentStep || isStepValidated(index) },
|
|
245
|
+
{ clickable: props.allowStepNavigation },
|
|
246
|
+
]"
|
|
247
|
+
@click="props.allowStepNavigation && goToStep(index)"
|
|
248
|
+
>
|
|
249
|
+
<span>{{ index + 1 }}</span>
|
|
250
|
+
<span v-if="props.stepLabels && props.stepLabels[index]" class="bgl-step-label">
|
|
251
|
+
{{ props.stepLabels[index] }}
|
|
252
|
+
</span>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
</slot>
|
|
256
|
+
</div>
|
|
257
|
+
|
|
258
|
+
<div class="bgl-form-wrapper">
|
|
259
|
+
<transition
|
|
260
|
+
:name="slideDirection === 'right' ? 'slide-right' : 'slide-left'"
|
|
261
|
+
mode="out-in"
|
|
262
|
+
>
|
|
263
|
+
<div v-if="!isStepping" :key="currentStep" ref="formContainer" class="bgl-form-container">
|
|
264
|
+
<BagelForm
|
|
265
|
+
ref="formRef"
|
|
266
|
+
v-model="formData"
|
|
267
|
+
:schema="currentStepSchema"
|
|
268
|
+
v-bind="bagelFormProps"
|
|
269
|
+
>
|
|
270
|
+
<template v-if="$slots.success" #success>
|
|
271
|
+
<slot name="success" />
|
|
272
|
+
</template>
|
|
273
|
+
<template v-if="$slots.error" #error>
|
|
274
|
+
<slot name="error" />
|
|
275
|
+
</template>
|
|
276
|
+
</BagelForm>
|
|
277
|
+
|
|
278
|
+
<!-- Navigation buttons inside the form container to animate together -->
|
|
279
|
+
<div class="bgl-step-controls">
|
|
280
|
+
<slot
|
|
281
|
+
name="steppers" v-bind="{
|
|
282
|
+
prevStep,
|
|
283
|
+
nextStep,
|
|
284
|
+
submit: handleSubmit,
|
|
285
|
+
currentStep,
|
|
286
|
+
totalSteps: numberOfSteps,
|
|
287
|
+
canDoNext,
|
|
288
|
+
}"
|
|
289
|
+
>
|
|
290
|
+
<Btn :disabled="currentStep === 0" flat value="Back" class="px-3" @click="prevStep" />
|
|
291
|
+
<Btn v-if="canDoNext" value="Next" class="px-3" @click="nextStep" />
|
|
292
|
+
<Btn v-else value="Submit" @click="handleSubmit" />
|
|
293
|
+
</slot>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
</transition>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
126
299
|
</template>
|
|
300
|
+
|
|
301
|
+
<style scoped>
|
|
302
|
+
.bgl-multi-step-form {
|
|
303
|
+
display: flex;
|
|
304
|
+
flex-direction: column;
|
|
305
|
+
gap: 1rem;
|
|
306
|
+
/* Default transition duration */
|
|
307
|
+
--transition-duration: 200ms;
|
|
308
|
+
--move-distance: 35%;
|
|
309
|
+
--ease-in: ease-in-out;
|
|
310
|
+
--ease-out: ease-in-out;
|
|
311
|
+
/* --ease-in: cubic-bezier(0.42, 0, 0.58, 1); */
|
|
312
|
+
/* --ease-out: cubic-bezier(0.5, 0, 0.75, 0); */
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.bgl-steps-indicator {
|
|
316
|
+
display: flex;
|
|
317
|
+
justify-content: space-between;
|
|
318
|
+
align-items: center;
|
|
319
|
+
margin-bottom: 1rem;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.bgl-step-indicator {
|
|
323
|
+
display: flex;
|
|
324
|
+
flex-direction: column;
|
|
325
|
+
align-items: center;
|
|
326
|
+
position: relative;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.bgl-step-indicator::before {
|
|
330
|
+
content: '';
|
|
331
|
+
position: absolute;
|
|
332
|
+
top: 50%;
|
|
333
|
+
right: 50%;
|
|
334
|
+
height: 2px;
|
|
335
|
+
width: 100%;
|
|
336
|
+
background: #e0e0e0;
|
|
337
|
+
z-index: -1;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.bgl-step-indicator:first-child::before {
|
|
341
|
+
display: none;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.bgl-step-indicator > span:first-child {
|
|
345
|
+
width: 30px;
|
|
346
|
+
height: 30px;
|
|
347
|
+
border-radius: 50%;
|
|
348
|
+
background: #e0e0e0;
|
|
349
|
+
color: #555;
|
|
350
|
+
display: flex;
|
|
351
|
+
align-items: center;
|
|
352
|
+
justify-content: center;
|
|
353
|
+
margin-bottom: 0.5rem;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.bgl-step-indicator.active > span:first-child {
|
|
357
|
+
background: var(--primary-color, #4CAF50);
|
|
358
|
+
color: white;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.bgl-step-indicator.completed > span:first-child {
|
|
362
|
+
background: var(--success-color, #8BC34A);
|
|
363
|
+
color: white;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.bgl-step-indicator.clickable {
|
|
367
|
+
cursor: pointer;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
.bgl-step-label {
|
|
371
|
+
font-size: 0.8rem;
|
|
372
|
+
max-width: 100px;
|
|
373
|
+
text-align: center;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.bgl-form-wrapper {
|
|
377
|
+
display: grid;
|
|
378
|
+
overflow: clip;
|
|
379
|
+
height: auto;
|
|
380
|
+
min-height: 300px;
|
|
381
|
+
transition: height var(--transition-duration) ease;
|
|
382
|
+
interpolate-size: allow-keywords;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.bgl-form-wrapper > div {
|
|
386
|
+
grid-area: 1 / 1;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.bgl-form-container {
|
|
390
|
+
width: 100%;
|
|
391
|
+
display: flex;
|
|
392
|
+
flex-direction: column;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.bgl-step-controls {
|
|
396
|
+
display: flex;
|
|
397
|
+
justify-content: center;
|
|
398
|
+
gap: 1rem;
|
|
399
|
+
margin-top: 1.5rem;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* Slide Left Animation (going forward) */
|
|
403
|
+
.slide-left-enter-active {
|
|
404
|
+
transition: opacity, transform calc(var(--transition-duration) * 1.2) var(--ease-in);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.slide-left-leave-active {
|
|
408
|
+
transition: opacity, transform var(--transition-duration) var(--ease-out);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.slide-left-enter-from {
|
|
412
|
+
opacity: 0;
|
|
413
|
+
transform: translateX(var(--move-distance));
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.slide-left-leave-to {
|
|
417
|
+
opacity: 0;
|
|
418
|
+
transform: translateX(-30%);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/* Slide Right Animation (going back) */
|
|
422
|
+
.slide-right-enter-active {
|
|
423
|
+
transition: all calc(var(--transition-duration) * 1.2) var(--ease-in);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.slide-right-leave-active {
|
|
427
|
+
transition: all var(--transition-duration) var(--ease-out);
|
|
428
|
+
transition-property: opacity, transform;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.slide-right-enter-from {
|
|
432
|
+
opacity: 0;
|
|
433
|
+
transform: translateX(-30%);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.slide-right-leave-to {
|
|
437
|
+
opacity: 0;
|
|
438
|
+
transform: translateX(var(--move-distance));
|
|
439
|
+
}
|
|
440
|
+
</style>
|
|
@@ -151,6 +151,17 @@ pre code.hljs{
|
|
|
151
151
|
background: #282c34;
|
|
152
152
|
height: max-content;
|
|
153
153
|
}
|
|
154
|
+
.code-editor-wrap:focus-within, .code-editor-wrap:focus-visible, .code-editor-wrap:focus {
|
|
155
|
+
box-shadow: inset 0 0 10px #00000021;
|
|
156
|
+
outline: solid 1px var(--border-color);
|
|
157
|
+
/* outline: -webkit-focus-ring-color auto 1px; */
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.code-editor-wrap:focus-within:has(textarea:focus) + .label,
|
|
162
|
+
.label:has(+ .code-editor-wrap:focus-within) {
|
|
163
|
+
color: var(--bgl-primary) !important;
|
|
164
|
+
}
|
|
154
165
|
|
|
155
166
|
.code-editor {
|
|
156
167
|
color: transparent;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type { ModeType } from '
|
|
2
|
+
import type { ModeType } from '../../../utils/calendar/typings'
|
|
3
3
|
import { TextInput, Dropdown, formatDate } from '@bagelink/vue'
|
|
4
4
|
import { onClickOutside } from '@vueuse/core'
|
|
5
5
|
import { ref, onMounted } from 'vue'
|
|
6
|
-
import { WEEK_START_DAY } from '
|
|
6
|
+
import { WEEK_START_DAY } from '../../../utils/calendar/time'
|
|
7
7
|
import DatePicker from './DatePicker.vue'
|
|
8
8
|
|
|
9
9
|
const props = withDefaults(
|
|
@@ -30,7 +30,7 @@ const props = withDefaults(
|
|
|
30
30
|
enableTime: false,
|
|
31
31
|
editMode: true,
|
|
32
32
|
small: false,
|
|
33
|
-
mode: 'day',
|
|
33
|
+
mode: () => ({ mode: 'day' }),
|
|
34
34
|
firstDayOfWeek: WEEK_START_DAY.SUNDAY,
|
|
35
35
|
locale: ''
|
|
36
36
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type {
|
|
2
|
+
import type { ModeType } from '../../../utils/calendar/typings'
|
|
3
3
|
import { Btn, NumberInput } from '@bagelink/vue'
|
|
4
4
|
import { computed, ref } from 'vue'
|
|
5
|
-
import Time, { WEEK_START_DAY } from '
|
|
5
|
+
import Time, { WEEK_START_DAY } from '../../../utils/calendar/time'
|
|
6
6
|
|
|
7
7
|
const props = withDefaults(
|
|
8
8
|
defineProps<{
|
|
@@ -15,7 +15,7 @@ const props = withDefaults(
|
|
|
15
15
|
enableTime?: boolean
|
|
16
16
|
}>(),
|
|
17
17
|
{
|
|
18
|
-
mode: 'day',
|
|
18
|
+
mode: () => ({ mode: 'day' }),
|
|
19
19
|
firstDayOfWeek: WEEK_START_DAY.SUNDAY,
|
|
20
20
|
locale: '',
|
|
21
21
|
enableTime: false
|
|
@@ -26,7 +26,7 @@ const emit = defineEmits(['update:modelValue'])
|
|
|
26
26
|
|
|
27
27
|
// State
|
|
28
28
|
const currentMonth = ref(new Date())
|
|
29
|
-
const currentView = ref
|
|
29
|
+
const currentView = ref('days')
|
|
30
30
|
|
|
31
31
|
// Time helper instance
|
|
32
32
|
const time = new Time(props.firstDayOfWeek, props.locale)
|
|
@@ -85,7 +85,21 @@ function useCalendarView() {
|
|
|
85
85
|
const currentMonthDays = computed(() => {
|
|
86
86
|
const year = currentMonth.value.getFullYear()
|
|
87
87
|
const month = currentMonth.value.getMonth()
|
|
88
|
-
|
|
88
|
+
|
|
89
|
+
// Get the weeks for the current month
|
|
90
|
+
const weeksInMonth = time.getCalendarMonthSplitInWeeks(year, month)
|
|
91
|
+
|
|
92
|
+
// Always ensure we have 6 rows (42 days) in our calendar
|
|
93
|
+
// If we have less than 6 weeks, add extra week(s) from the next month
|
|
94
|
+
while (weeksInMonth.length < 6) {
|
|
95
|
+
const lastWeek = weeksInMonth[weeksInMonth.length - 1]
|
|
96
|
+
const lastDay = lastWeek[lastWeek.length - 1]
|
|
97
|
+
const nextDay = new Date(lastDay.getFullYear(), lastDay.getMonth(), lastDay.getDate() + 1)
|
|
98
|
+
const nextWeek = time.getCalendarWeekDateObjects(nextDay)
|
|
99
|
+
weeksInMonth.push(nextWeek)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return weeksInMonth.flat()
|
|
89
103
|
})
|
|
90
104
|
|
|
91
105
|
const currentMonthValue = computed(() => ({
|
|
@@ -263,21 +277,21 @@ function selectDate(date: Date | null) {
|
|
|
263
277
|
<div class="calendar-section m_border-none pe-05 m_p-0">
|
|
264
278
|
<div class="flex space-between pb-1">
|
|
265
279
|
<template v-if="currentView === 'days'">
|
|
266
|
-
<Btn flat icon="chevron_left" @click="previousMonth" />
|
|
280
|
+
<Btn flat thin icon="chevron_left" @click="previousMonth" />
|
|
267
281
|
<div class="flex gap-05">
|
|
268
|
-
<Btn flat class="month-btn" @click="currentView = 'months'">
|
|
282
|
+
<Btn flat thin class="month-btn" @click="currentView = 'months'">
|
|
269
283
|
{{ currentMonthValue.formatted.month }}
|
|
270
284
|
</Btn>
|
|
271
|
-
<Btn flat class="year-btn" @click="currentView = 'years'">
|
|
285
|
+
<Btn flat thin class="year-btn" @click="currentView = 'years'">
|
|
272
286
|
{{ currentMonthValue.formatted.year }}
|
|
273
287
|
</Btn>
|
|
274
288
|
</div>
|
|
275
|
-
<Btn flat icon="chevron_right" @click="nextMonth" />
|
|
289
|
+
<Btn flat thin icon="chevron_right" @click="nextMonth" />
|
|
276
290
|
</template>
|
|
277
291
|
<template v-else>
|
|
278
|
-
<Btn flat icon="chevron_left" @click="previousYear" />
|
|
292
|
+
<Btn flat thin icon="chevron_left" @click="previousYear" />
|
|
279
293
|
<span class="month-year">{{ currentMonthValue.formatted.year }}</span>
|
|
280
|
-
<Btn flat icon="chevron_right" @click="nextYear" />
|
|
294
|
+
<Btn flat thin icon="chevron_right" @click="nextYear" />
|
|
281
295
|
</template>
|
|
282
296
|
</div>
|
|
283
297
|
|
|
@@ -309,35 +323,26 @@ function selectDate(date: Date | null) {
|
|
|
309
323
|
</div>
|
|
310
324
|
|
|
311
325
|
<div v-else-if="currentView === 'months'" class="month-grid grid gap-05 p-05">
|
|
312
|
-
<
|
|
326
|
+
<Btn
|
|
313
327
|
v-for="month in months"
|
|
314
328
|
:key="month.value"
|
|
315
|
-
|
|
316
|
-
:
|
|
317
|
-
selected: month.value === currentMonthValue.month,
|
|
318
|
-
disabled: month.disabled,
|
|
319
|
-
}"
|
|
329
|
+
thin
|
|
330
|
+
:flat="month.value !== currentMonthValue.month"
|
|
320
331
|
:disabled="month.disabled"
|
|
332
|
+
:value="month.name"
|
|
321
333
|
@click="selectMonth(month.value)"
|
|
322
|
-
|
|
323
|
-
{{ month.name }}
|
|
324
|
-
</button>
|
|
334
|
+
/>
|
|
325
335
|
</div>
|
|
326
336
|
|
|
327
337
|
<div v-else class="year-grid grid gap-05 p-0">
|
|
328
|
-
<
|
|
338
|
+
<Btn
|
|
329
339
|
v-for="year in years"
|
|
330
|
-
:key="year.value"
|
|
331
|
-
|
|
332
|
-
:class="{
|
|
333
|
-
selected: year.value === currentMonthValue.year,
|
|
334
|
-
disabled: year.disabled,
|
|
335
|
-
}"
|
|
340
|
+
:key="year.value" thin
|
|
341
|
+
:flat="year.value !== currentMonthValue.year"
|
|
336
342
|
:disabled="year.disabled"
|
|
343
|
+
:value="year.value.toString()"
|
|
337
344
|
@click="selectYear(year.value)"
|
|
338
|
-
|
|
339
|
-
{{ year.value }}
|
|
340
|
-
</button>
|
|
345
|
+
/>
|
|
341
346
|
</div>
|
|
342
347
|
</div>
|
|
343
348
|
|
|
@@ -237,6 +237,7 @@ onMounted(() => {
|
|
|
237
237
|
:placement="placement"
|
|
238
238
|
class="bagel-input selectinput"
|
|
239
239
|
no-auto-focus
|
|
240
|
+
@click.stop
|
|
240
241
|
>
|
|
241
242
|
<template #trigger>
|
|
242
243
|
<label>
|
|
@@ -298,6 +299,7 @@ onMounted(() => {
|
|
|
298
299
|
<Card
|
|
299
300
|
class="p-05"
|
|
300
301
|
:style="{ width: fullWidth ? '100%' : 'auto' }"
|
|
302
|
+
@click.stop
|
|
301
303
|
>
|
|
302
304
|
<div ref="selectOptions" class="selectinput-options" :class="{ multiselect }">
|
|
303
305
|
<div
|