@bagelink/vue 0.0.1084 → 0.0.1090
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/form/inputs/CodeEditor/Index.vue.d.ts +3 -1
- package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/components/EditorToolbar.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/ToggleInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/index.d.ts.map +1 -1
- package/dist/index.cjs +70 -55
- package/dist/index.mjs +70 -55
- package/dist/style.css +286 -281
- package/dist/utils/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/form/BglForm.vue +1 -1
- package/src/components/form/inputs/CodeEditor/Index.vue +28 -22
- package/src/components/form/inputs/DatePick.vue +459 -0
- package/src/components/form/inputs/RangeInput.vue +1 -1
- package/src/components/form/inputs/RichText/components/EditorToolbar.vue +1 -0
- package/src/components/form/inputs/ToggleInput.vue +2 -0
- package/src/components/form/inputs/index.ts +1 -0
- package/src/styles/theme.css +261 -259
- package/src/utils/index.ts +5 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAI/D,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,IAAI,GAAE,MAAY,QAO1D;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,UAMlC;AAED,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ3D;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,iBAGtE;AAED,wBAAgB,QAAQ,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,UAG3C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,QAIrE;AAED,wBAAgB,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,UAOpE;AAED,wBAAgB,SAAS,CAAC,CAAC,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EACnD,KAAK,CAAC,EAAE,UAAU,EAClB,QAAQ,CAAC,EAAE,GAAG,EACd,GAAG,CAAC,EAAE,CAAC,OAcP;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,OAO9C;AAED,wBAAgB,SAAS,CAAC,QAAQ,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAAE,OAAO,CAAC,EAAE,MAAM,OAG5E;AAED,eAAO,MAAM,MAAM,eAAgB,GAAG,YAA0C,CAAA;AAEhF,wBAAgB,iBAAiB,CAAC,CAAC,EAClC,IAAI,CAAC,EAAE,GAAG,EAAE,EACZ,UAAU,CAAC,EAAE,MAAM,EAAE,GACnB,cAAc,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAI/D,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,IAAI,GAAE,MAAY,QAO1D;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,UAMlC;AAED,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQ3D;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,iBAGtE;AAED,wBAAgB,QAAQ,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,UAG3C;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,IAAI,QAIrE;AAED,wBAAgB,QAAQ,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,UAOpE;AAED,wBAAgB,SAAS,CAAC,CAAC,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EACnD,KAAK,CAAC,EAAE,UAAU,EAClB,QAAQ,CAAC,EAAE,GAAG,EACd,GAAG,CAAC,EAAE,CAAC,OAcP;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,OAO9C;AAED,wBAAgB,SAAS,CAAC,QAAQ,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAAE,OAAO,CAAC,EAAE,MAAM,OAG5E;AAED,eAAO,MAAM,MAAM,eAAgB,GAAG,YAA0C,CAAA;AAEhF,wBAAgB,iBAAiB,CAAC,CAAC,EAClC,IAAI,CAAC,EAAE,GAAG,EAAE,EACZ,UAAU,CAAC,EAAE,MAAM,EAAE,GACnB,cAAc,CAAC,CAAC,CAAC,CAgBnB;AAED,wBAAgB,KAAK,CAAC,EAAE,GAAE,MAAY,oBAErC;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBlF;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAatD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,UAIvC;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EAAE,aAAa,SAAO,GAAG,MAAM,GAAG,SAAS,CAG/G;AAED,OAAO,KAAK,cAAc,MAAM,kBAAkB,CAAA;AAElD,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAEhC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { BglField, type BglFormSchemaFnT, Title, useBglSchema, useModal } from '@bagelink/vue'
|
|
3
|
-
import { inject,
|
|
3
|
+
import { inject, useSlots, watch } from 'vue'
|
|
4
4
|
import { FORM_STATE_KEY, provideBagelFormState, type BagelFormState } from './useBagelFormState'
|
|
5
5
|
|
|
6
6
|
export type FormStatus = 'idle' | 'loading' | 'success' | 'error'
|
|
@@ -10,22 +10,24 @@ import { appendStyle, appendScript } from '@bagelink/vue'
|
|
|
10
10
|
import { nextTick, onMounted, watch } from 'vue'
|
|
11
11
|
|
|
12
12
|
// Props
|
|
13
|
-
const { language, readonly = false, modelValue = '', autodetect, ignoreIllegals = true } = defineProps<{
|
|
13
|
+
const { language, readonly = false, modelValue = '', autodetect, ignoreIllegals = true, label, height = '300px' } = defineProps<{
|
|
14
14
|
language?: Language
|
|
15
15
|
readonly?: boolean
|
|
16
16
|
modelValue?: string
|
|
17
17
|
autodetect?: boolean
|
|
18
18
|
ignoreIllegals?: boolean
|
|
19
|
+
label?: string
|
|
20
|
+
height?: string
|
|
19
21
|
}>()
|
|
20
22
|
|
|
21
23
|
const emit = defineEmits(['update:modelValue'])
|
|
22
24
|
|
|
23
25
|
let hljs = $ref<HilightJS | null>(null)
|
|
24
26
|
|
|
27
|
+
let elHeight = $ref(height)
|
|
25
28
|
// State and refs
|
|
26
29
|
let code = $ref('')
|
|
27
30
|
const textarea = $ref<HTMLTextAreaElement>()
|
|
28
|
-
let height = $ref('300px')
|
|
29
31
|
let loaded = $ref(false)
|
|
30
32
|
|
|
31
33
|
// Computed properties
|
|
@@ -76,8 +78,8 @@ function handleTab(event: KeyboardEvent) {
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
function adjustHeight() {
|
|
79
|
-
if (textarea?.scrollHeight && textarea.scrollHeight >
|
|
80
|
-
|
|
81
|
+
if (textarea?.scrollHeight && textarea.scrollHeight > Number.parseInt(elHeight)) {
|
|
82
|
+
elHeight = `${textarea.scrollHeight}px`
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
85
|
|
|
@@ -105,30 +107,33 @@ watch(() => modelValue, (newVal) => {
|
|
|
105
107
|
</script>
|
|
106
108
|
|
|
107
109
|
<template>
|
|
108
|
-
<div
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
110
|
+
<div class="mb-05">
|
|
111
|
+
<label v-if="label" class="label txt-start">{{ label }}</label>
|
|
112
|
+
<div v-if="loaded" class="code-editor-wrap grid rounded p-1 overflow hm-300px ltr txt-start relative h-100p">
|
|
113
|
+
<div class="relative block h-100" :style="{ height: `calc(${elHeight} - 2rem)` }">
|
|
114
|
+
<pre class=" overflow-hidden absolute inset-0 p-0 m-0 h-100 codeText">
|
|
115
|
+
<code class="absolute inset-0" :class="className" v-html="highlightedCode" />
|
|
116
|
+
</pre>
|
|
117
|
+
<textarea
|
|
118
|
+
v-if="!readonly"
|
|
119
|
+
ref="textarea"
|
|
120
|
+
v-model="code"
|
|
121
|
+
class="code-editor absolute inset-0 bg-transparent overflow-hidden h-100 p-0 m-0 codeText border-none txt-start"
|
|
122
|
+
spellcheck="false"
|
|
123
|
+
placeholder="Write your code here"
|
|
124
|
+
aria-label="Code Editor"
|
|
125
|
+
data-gramm="false"
|
|
126
|
+
@keydown.tab.prevent="handleTab"
|
|
127
|
+
@input="emit('update:modelValue', code)"
|
|
128
|
+
/>
|
|
129
|
+
</div>
|
|
125
130
|
</div>
|
|
126
131
|
</div>
|
|
127
132
|
</template>
|
|
128
133
|
|
|
129
134
|
<style>
|
|
130
135
|
pre code.hljs{
|
|
131
|
-
|
|
136
|
+
padding: 0 !important;
|
|
132
137
|
inset: 0 !important;
|
|
133
138
|
position: absolute;
|
|
134
139
|
}
|
|
@@ -140,6 +145,7 @@ pre code.hljs{
|
|
|
140
145
|
white-space: pre-wrap;
|
|
141
146
|
word-wrap: break-word;
|
|
142
147
|
caret-color: var(--bgl-white);
|
|
148
|
+
color: var(--bgl-white);
|
|
143
149
|
}
|
|
144
150
|
.code-editor-wrap {
|
|
145
151
|
background: #282c34;
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { Btn, TextInput } from '@bagelink/vue'
|
|
3
|
+
import { computed, ref } from 'vue'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(
|
|
6
|
+
defineProps<{
|
|
7
|
+
required?: boolean
|
|
8
|
+
label?: string
|
|
9
|
+
editMode?: boolean
|
|
10
|
+
small?: boolean
|
|
11
|
+
enableTime?: boolean
|
|
12
|
+
modelValue?: string | Date
|
|
13
|
+
defaultValue?: string | Date
|
|
14
|
+
rtl?: boolean
|
|
15
|
+
min?: string | Date
|
|
16
|
+
max?: string | Date
|
|
17
|
+
showInput?: boolean
|
|
18
|
+
timezone?: string // e.g. 'America/New_York', 'Europe/London'
|
|
19
|
+
}>(),
|
|
20
|
+
{
|
|
21
|
+
enableTime: false,
|
|
22
|
+
editMode: true,
|
|
23
|
+
small: false,
|
|
24
|
+
rtl: false,
|
|
25
|
+
showInput: true,
|
|
26
|
+
timezone: 'UTC'
|
|
27
|
+
},
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
const emit = defineEmits(['update:modelValue'])
|
|
31
|
+
const isOpen = ref(false)
|
|
32
|
+
const currentMonth = ref(new Date())
|
|
33
|
+
|
|
34
|
+
const inputType = computed(() => props.enableTime ? 'datetime-local' : 'date')
|
|
35
|
+
|
|
36
|
+
function toLocalDate(date: Date): Date {
|
|
37
|
+
if (!date) return date
|
|
38
|
+
try {
|
|
39
|
+
return new Date(date.toLocaleString('en-US', { timeZone: props.timezone }))
|
|
40
|
+
} catch (e) {
|
|
41
|
+
console.warn(`Invalid timezone: ${props.timezone}, falling back to UTC`)
|
|
42
|
+
return date
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function fromLocalDate(date: Date): Date {
|
|
47
|
+
if (!date) return date
|
|
48
|
+
try {
|
|
49
|
+
const localDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }))
|
|
50
|
+
const tzDate = new Date(date.toLocaleString('en-US', { timeZone: props.timezone }))
|
|
51
|
+
const diff = localDate.getTime() - tzDate.getTime()
|
|
52
|
+
return new Date(date.getTime() + diff)
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.warn(`Invalid timezone: ${props.timezone}, falling back to UTC`)
|
|
55
|
+
return date
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const formattedValue = computed(() => {
|
|
60
|
+
if (!props.modelValue) return ''
|
|
61
|
+
const date = typeof props.modelValue === 'string' ? new Date(props.modelValue) : props.modelValue
|
|
62
|
+
const localDate = toLocalDate(date)
|
|
63
|
+
|
|
64
|
+
if (props.enableTime) {
|
|
65
|
+
return localDate.toISOString().slice(0, 16) // Format: YYYY-MM-DDTHH:mm
|
|
66
|
+
}
|
|
67
|
+
return localDate.toISOString().split('T')[0] // Format: YYYY-MM-DD
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
const formattedMin = computed(() => {
|
|
71
|
+
if (!props.min) return undefined
|
|
72
|
+
const date = typeof props.min === 'string' ? new Date(props.min) : props.min
|
|
73
|
+
const localDate = toLocalDate(date)
|
|
74
|
+
return props.enableTime ? localDate.toISOString().slice(0, 16) : localDate.toISOString().split('T')[0]
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const formattedMax = computed(() => {
|
|
78
|
+
if (!props.max) return undefined
|
|
79
|
+
const date = typeof props.max === 'string' ? new Date(props.max) : props.max
|
|
80
|
+
const localDate = toLocalDate(date)
|
|
81
|
+
return props.enableTime ? localDate.toISOString().slice(0, 16) : localDate.toISOString().split('T')[0]
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const selectedDate = computed(() => {
|
|
85
|
+
if (!props.modelValue) return null
|
|
86
|
+
const date = typeof props.modelValue === 'string' ? new Date(props.modelValue) : props.modelValue
|
|
87
|
+
return toLocalDate(date)
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const currentMonthDays = computed(() => {
|
|
91
|
+
const localCurrentMonth = toLocalDate(currentMonth.value)
|
|
92
|
+
const year = localCurrentMonth.getFullYear()
|
|
93
|
+
const month = localCurrentMonth.getMonth()
|
|
94
|
+
const firstDay = new Date(year, month, 1)
|
|
95
|
+
const lastDay = new Date(year, month + 1, 0)
|
|
96
|
+
const days = []
|
|
97
|
+
|
|
98
|
+
// Add empty slots for days before the first of the month
|
|
99
|
+
const firstDayOfWeek = firstDay.getDay()
|
|
100
|
+
for (let i = 0; i < firstDayOfWeek; i++) {
|
|
101
|
+
days.push(null)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Add all days of the month
|
|
105
|
+
for (let i = 1; i <= lastDay.getDate(); i++) {
|
|
106
|
+
days.push(new Date(year, month, i))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return days
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
const monthYear = computed(() => {
|
|
113
|
+
const localCurrentMonth = toLocalDate(currentMonth.value)
|
|
114
|
+
return localCurrentMonth.toLocaleString('default', {
|
|
115
|
+
month: 'long',
|
|
116
|
+
year: 'numeric',
|
|
117
|
+
timeZone: props.timezone
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
function handleInput(event: Event) {
|
|
122
|
+
const input = event.target as HTMLInputElement
|
|
123
|
+
if (!input.value) {
|
|
124
|
+
emit('update:modelValue', '')
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let date = new Date(input.value)
|
|
129
|
+
date = fromLocalDate(date)
|
|
130
|
+
|
|
131
|
+
if (props.enableTime) {
|
|
132
|
+
emit('update:modelValue', date.toISOString())
|
|
133
|
+
} else {
|
|
134
|
+
emit('update:modelValue', date.toISOString().split('T')[0])
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function previousMonth() {
|
|
139
|
+
const localCurrentMonth = toLocalDate(currentMonth.value)
|
|
140
|
+
currentMonth.value = new Date(
|
|
141
|
+
localCurrentMonth.getFullYear(),
|
|
142
|
+
localCurrentMonth.getMonth() - 1,
|
|
143
|
+
1
|
|
144
|
+
)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function nextMonth() {
|
|
148
|
+
const localCurrentMonth = toLocalDate(currentMonth.value)
|
|
149
|
+
currentMonth.value = new Date(
|
|
150
|
+
localCurrentMonth.getFullYear(),
|
|
151
|
+
localCurrentMonth.getMonth() + 1,
|
|
152
|
+
1
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function selectDate(date: Date | null) {
|
|
157
|
+
if (!date || !props.editMode) return
|
|
158
|
+
|
|
159
|
+
let selectedTime = { hours: 0, minutes: 0 }
|
|
160
|
+
if (props.enableTime && selectedDate.value) {
|
|
161
|
+
selectedTime = {
|
|
162
|
+
hours: selectedDate.value.getHours(),
|
|
163
|
+
minutes: selectedDate.value.getMinutes()
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const localDate = new Date(date)
|
|
168
|
+
localDate.setHours(selectedTime.hours)
|
|
169
|
+
localDate.setMinutes(selectedTime.minutes)
|
|
170
|
+
|
|
171
|
+
const utcDate = fromLocalDate(localDate)
|
|
172
|
+
|
|
173
|
+
emit('update:modelValue', props.enableTime ? utcDate.toISOString() : utcDate.toISOString().split('T')[0])
|
|
174
|
+
isOpen.value = false
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function isSelected(date: Date | null) {
|
|
178
|
+
if (!date || !selectedDate.value) return false
|
|
179
|
+
const localDate = toLocalDate(date)
|
|
180
|
+
return localDate.toISOString().split('T')[0] === selectedDate.value.toISOString().split('T')[0]
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function isToday(date: Date | null) {
|
|
184
|
+
if (!date) return false
|
|
185
|
+
const today = toLocalDate(new Date())
|
|
186
|
+
const localDate = toLocalDate(date)
|
|
187
|
+
return localDate.toISOString().split('T')[0] === today.toISOString().split('T')[0]
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function isDisabled(date: Date | null) {
|
|
191
|
+
if (!date) return true
|
|
192
|
+
const localDate = toLocalDate(date)
|
|
193
|
+
const minDate = props.min ? toLocalDate(new Date(props.min)) : null
|
|
194
|
+
const maxDate = props.max ? toLocalDate(new Date(props.max)) : null
|
|
195
|
+
|
|
196
|
+
if (minDate && localDate < minDate) return true
|
|
197
|
+
if (maxDate && localDate > maxDate) return true
|
|
198
|
+
return false
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Add timezone display if time is enabled
|
|
202
|
+
const timezoneDisplay = computed(() => {
|
|
203
|
+
if (!props.enableTime) return ''
|
|
204
|
+
try {
|
|
205
|
+
const date = new Date()
|
|
206
|
+
return date.toLocaleString('en-US', {
|
|
207
|
+
timeZoneName: 'short',
|
|
208
|
+
timeZone: props.timezone
|
|
209
|
+
}).split(' ').pop()
|
|
210
|
+
} catch (e) {
|
|
211
|
+
return 'UTC'
|
|
212
|
+
}
|
|
213
|
+
})
|
|
214
|
+
</script>
|
|
215
|
+
|
|
216
|
+
<template>
|
|
217
|
+
<div
|
|
218
|
+
class="bagel-input"
|
|
219
|
+
:class="{ small, 'rtl-date': rtl }"
|
|
220
|
+
:title="label"
|
|
221
|
+
>
|
|
222
|
+
<label v-if="label">
|
|
223
|
+
{{ label }}
|
|
224
|
+
<span v-if="required" class="required">*</span>
|
|
225
|
+
</label>
|
|
226
|
+
|
|
227
|
+
<div class="date-picker-container">
|
|
228
|
+
<TextInput @input="handleInput" @click="isOpen = true" />
|
|
229
|
+
<!-- <input
|
|
230
|
+
v-if="showInput"
|
|
231
|
+
:type="inputType"
|
|
232
|
+
:value="formattedValue"
|
|
233
|
+
:min="formattedMin"
|
|
234
|
+
:max="formattedMax"
|
|
235
|
+
:required="required"
|
|
236
|
+
:disabled="!editMode"
|
|
237
|
+
class="date-input"
|
|
238
|
+
> -->
|
|
239
|
+
|
|
240
|
+
<div
|
|
241
|
+
v-if="!showInput"
|
|
242
|
+
class="date-display"
|
|
243
|
+
:class="{ disabled: !editMode }"
|
|
244
|
+
@click="editMode && (isOpen = !isOpen)"
|
|
245
|
+
>
|
|
246
|
+
{{ formattedValue || 'Select date' }}
|
|
247
|
+
<span v-if="enableTime" class="timezone-display">{{ timezoneDisplay }}</span>
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
<div
|
|
251
|
+
v-if="isOpen"
|
|
252
|
+
class="calendar-popup"
|
|
253
|
+
@click.stop
|
|
254
|
+
>
|
|
255
|
+
<div class="calendar-header">
|
|
256
|
+
<Btn flat icon="chevron_left" @click="previousMonth" />
|
|
257
|
+
<span class="month-year">{{ monthYear }}</span>
|
|
258
|
+
<Btn flat icon="chevron_right" @click="nextMonth" />
|
|
259
|
+
</div>
|
|
260
|
+
|
|
261
|
+
<div class="calendar-grid">
|
|
262
|
+
<div
|
|
263
|
+
v-for="day in ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']"
|
|
264
|
+
:key="day"
|
|
265
|
+
class="weekday"
|
|
266
|
+
>
|
|
267
|
+
{{ day }}
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
<button
|
|
271
|
+
v-for="(date, index) in currentMonthDays"
|
|
272
|
+
:key="index"
|
|
273
|
+
type="button"
|
|
274
|
+
class="day"
|
|
275
|
+
:class="{
|
|
276
|
+
selected: isSelected(date),
|
|
277
|
+
today: isToday(date),
|
|
278
|
+
disabled: isDisabled(date),
|
|
279
|
+
}"
|
|
280
|
+
:disabled="isDisabled(date)"
|
|
281
|
+
@click="selectDate(date)"
|
|
282
|
+
>
|
|
283
|
+
{{ date?.getDate() }}
|
|
284
|
+
</button>
|
|
285
|
+
</div>
|
|
286
|
+
|
|
287
|
+
<div
|
|
288
|
+
v-if="enableTime && selectedDate"
|
|
289
|
+
class="time-picker"
|
|
290
|
+
>
|
|
291
|
+
<input
|
|
292
|
+
type="time"
|
|
293
|
+
:value="selectedDate.toISOString().slice(11, 16)"
|
|
294
|
+
@input="handleInput"
|
|
295
|
+
>
|
|
296
|
+
<span class="timezone-display">{{ timezoneDisplay }}</span>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
</template>
|
|
302
|
+
|
|
303
|
+
<style scoped>
|
|
304
|
+
.bagel-input {
|
|
305
|
+
display: flex;
|
|
306
|
+
flex-direction: column;
|
|
307
|
+
gap: 0.5rem;
|
|
308
|
+
position: relative;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.date-picker-container {
|
|
312
|
+
position: relative;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.date-input,
|
|
316
|
+
.date-display {
|
|
317
|
+
padding: 0.5rem;
|
|
318
|
+
border: 1px solid #ddd;
|
|
319
|
+
border-radius: 4px;
|
|
320
|
+
font-size: 1rem;
|
|
321
|
+
width: 100%;
|
|
322
|
+
background: white;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.date-display {
|
|
326
|
+
cursor: pointer;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.date-display.disabled {
|
|
330
|
+
background-color: #f5f5f5;
|
|
331
|
+
cursor: not-allowed;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.date-input:focus,
|
|
335
|
+
.date-display:focus {
|
|
336
|
+
outline: none;
|
|
337
|
+
border-color: #4a90e2;
|
|
338
|
+
box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.date-input:disabled {
|
|
342
|
+
background-color: #f5f5f5;
|
|
343
|
+
cursor: not-allowed;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.small .date-input,
|
|
347
|
+
.small .date-display {
|
|
348
|
+
padding: 0.25rem;
|
|
349
|
+
font-size: 0.875rem;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.rtl-date input {
|
|
353
|
+
direction: rtl;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.required {
|
|
357
|
+
color: #ff4d4f;
|
|
358
|
+
margin-left: 4px;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.calendar-popup {
|
|
362
|
+
position: absolute;
|
|
363
|
+
top: 100%;
|
|
364
|
+
left: 0;
|
|
365
|
+
z-index: 1000;
|
|
366
|
+
background: white;
|
|
367
|
+
border: 1px solid #ddd;
|
|
368
|
+
border-radius: 4px;
|
|
369
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
370
|
+
padding: 1rem;
|
|
371
|
+
margin-top: 0.5rem;
|
|
372
|
+
width: 300px;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.calendar-header {
|
|
376
|
+
display: flex;
|
|
377
|
+
align-items: center;
|
|
378
|
+
justify-content: space-between;
|
|
379
|
+
margin-bottom: 1rem;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
.nav-button {
|
|
383
|
+
background: none;
|
|
384
|
+
border: none;
|
|
385
|
+
font-size: 1.5rem;
|
|
386
|
+
cursor: pointer;
|
|
387
|
+
padding: 0 0.5rem;
|
|
388
|
+
color: #666;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.nav-button:hover {
|
|
392
|
+
color: #4a90e2;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
.month-year {
|
|
396
|
+
font-weight: 500;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.calendar-grid {
|
|
400
|
+
display: grid;
|
|
401
|
+
grid-template-columns: repeat(7, 1fr);
|
|
402
|
+
gap: 0.25rem;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.weekday {
|
|
406
|
+
text-align: center;
|
|
407
|
+
font-size: 0.875rem;
|
|
408
|
+
color: #666;
|
|
409
|
+
padding: 0.5rem 0;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.day {
|
|
413
|
+
aspect-ratio: 1;
|
|
414
|
+
display: flex;
|
|
415
|
+
align-items: center;
|
|
416
|
+
justify-content: center;
|
|
417
|
+
border: none;
|
|
418
|
+
background: none;
|
|
419
|
+
cursor: pointer;
|
|
420
|
+
border-radius: 50%;
|
|
421
|
+
font-size: 0.875rem;
|
|
422
|
+
color: #333;
|
|
423
|
+
padding: 0;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.day:hover:not(.disabled) {
|
|
427
|
+
background-color: #f5f5f5;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.day.selected {
|
|
431
|
+
background-color: #4a90e2;
|
|
432
|
+
color: white;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.day.today:not(.selected) {
|
|
436
|
+
border: 1px solid #4a90e2;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.day.disabled {
|
|
440
|
+
color: #ccc;
|
|
441
|
+
cursor: not-allowed;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.timezone-display {
|
|
445
|
+
margin-left: 0.5rem;
|
|
446
|
+
color: #666;
|
|
447
|
+
font-size: 0.875rem;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.time-picker {
|
|
451
|
+
display: flex;
|
|
452
|
+
align-items: center;
|
|
453
|
+
gap: 0.5rem;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
.time-picker input {
|
|
457
|
+
flex: 1;
|
|
458
|
+
}
|
|
459
|
+
</style>
|
|
@@ -183,7 +183,7 @@ input[type="range"]::-webkit-slider-thumb {
|
|
|
183
183
|
appearance: none;
|
|
184
184
|
width: var(--bgl-range-thumb-size);
|
|
185
185
|
height: var(--bgl-range-thumb-size);
|
|
186
|
-
background: var(--bgl-
|
|
186
|
+
background: var(--bgl-range-thumb-color);
|
|
187
187
|
border-radius: 50%;
|
|
188
188
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
189
189
|
position: relative;
|
|
@@ -34,6 +34,7 @@ function runAction(name: ToolbarConfigOption, value?: string) {
|
|
|
34
34
|
<Btn
|
|
35
35
|
v-else-if="action.name !== 'separator'" v-tooltip="action.label" :icon="action.icon" thin flat
|
|
36
36
|
:aria-label="action.name" :class="[action.class, { active: selectedStyles.has(action.name) }]"
|
|
37
|
+
class=""
|
|
37
38
|
@click="runAction(action.name)"
|
|
38
39
|
/>
|
|
39
40
|
<span v-else-if="action.name === 'separator'" :key="`separator-${index}`" class="opacity-2 mb-025">|</span>
|
|
@@ -54,6 +54,7 @@ onMounted(() => {
|
|
|
54
54
|
.bagel-input.bgl-toggle input{
|
|
55
55
|
padding: unset !important;
|
|
56
56
|
min-width: unset !important;
|
|
57
|
+
margin: 0 !important;
|
|
57
58
|
}
|
|
58
59
|
.bgl-toggle input {
|
|
59
60
|
appearance: none;
|
|
@@ -90,6 +91,7 @@ onMounted(() => {
|
|
|
90
91
|
user-select: none;
|
|
91
92
|
line-height: var(--input-height);
|
|
92
93
|
font-size: var(--input-font-size);
|
|
94
|
+
vertical-align: middle;
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
.bgl-toggle label:hover {
|
|
@@ -3,6 +3,7 @@ export { default as CheckInput } from './CheckInput.vue'
|
|
|
3
3
|
export { default as CodeEditor } from './CodeEditor/Index.vue'
|
|
4
4
|
export { default as ColorPicker } from './ColorPicker.vue'
|
|
5
5
|
export { default as DateInput } from './DateInput.vue'
|
|
6
|
+
// export { default as DatePick } from './DatePick.vue'
|
|
6
7
|
export { default as DatePicker } from './DatePicker.vue'
|
|
7
8
|
export { default as FileUpload } from './FileUpload.vue'
|
|
8
9
|
export { default as JSONInput } from './JSONInput.vue'
|