@stonecrop/aform 0.30.0 → 0.32.0

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 (92) hide show
  1. package/dist/aform.js +3024 -2256
  2. package/dist/aform.js.map +1 -1
  3. package/dist/assets/index.css +1170 -1
  4. package/dist/src/components/AForm.vue.d.ts +20 -0
  5. package/dist/src/components/AForm.vue.d.ts.map +1 -0
  6. package/dist/src/components/AFormLoading.vue.d.ts +14 -0
  7. package/dist/src/components/AFormLoading.vue.d.ts.map +1 -0
  8. package/dist/src/components/base/CollapseButton.vue.d.ts +7 -0
  9. package/dist/src/components/base/CollapseButton.vue.d.ts.map +1 -0
  10. package/dist/src/components/base/ExpandButton.vue.d.ts +7 -0
  11. package/dist/src/components/base/ExpandButton.vue.d.ts.map +1 -0
  12. package/dist/src/components/form/ABadge.vue.d.ts +14 -0
  13. package/dist/src/components/form/ABadge.vue.d.ts.map +1 -0
  14. package/dist/src/components/form/ACheckbox.vue.d.ts +15 -0
  15. package/dist/src/components/form/ACheckbox.vue.d.ts.map +1 -0
  16. package/dist/src/components/form/ACurrencyInput.vue.d.ts +20 -0
  17. package/dist/src/components/form/ACurrencyInput.vue.d.ts.map +1 -0
  18. package/dist/src/components/form/ADate.vue.d.ts +14 -0
  19. package/dist/src/components/form/ADate.vue.d.ts.map +1 -0
  20. package/dist/src/components/form/ADatePicker.vue.d.ts +28 -0
  21. package/dist/src/components/form/ADatePicker.vue.d.ts.map +1 -0
  22. package/dist/src/components/form/ADateRange.vue.d.ts +18 -0
  23. package/dist/src/components/form/ADateRange.vue.d.ts.map +1 -0
  24. package/dist/src/components/form/ADateSelection.vue.d.ts +52 -0
  25. package/dist/src/components/form/ADateSelection.vue.d.ts.map +1 -0
  26. package/dist/src/components/form/ADateTime.vue.d.ts +17 -0
  27. package/dist/src/components/form/ADateTime.vue.d.ts.map +1 -0
  28. package/dist/src/components/form/ADateTimeInput.vue.d.ts +30 -0
  29. package/dist/src/components/form/ADateTimeInput.vue.d.ts.map +1 -0
  30. package/dist/src/components/form/ADropdown.vue.d.ts +20 -0
  31. package/dist/src/components/form/ADropdown.vue.d.ts.map +1 -0
  32. package/dist/src/components/form/ADuration.vue.d.ts +18 -0
  33. package/dist/src/components/form/ADuration.vue.d.ts.map +1 -0
  34. package/dist/src/components/form/AFieldset.vue.d.ts +28 -0
  35. package/dist/src/components/form/AFieldset.vue.d.ts.map +1 -0
  36. package/dist/src/components/form/AFileAttach.vue.d.ts +5 -0
  37. package/dist/src/components/form/AFileAttach.vue.d.ts.map +1 -0
  38. package/dist/src/components/form/AFormLink.vue.d.ts +40 -0
  39. package/dist/src/components/form/AFormLink.vue.d.ts.map +1 -0
  40. package/dist/src/components/form/ANumericInput.vue.d.ts +14 -0
  41. package/dist/src/components/form/ANumericInput.vue.d.ts.map +1 -0
  42. package/dist/src/components/form/AQuantityInput.vue.d.ts +20 -0
  43. package/dist/src/components/form/AQuantityInput.vue.d.ts.map +1 -0
  44. package/dist/src/components/form/ASegmentedControl.vue.d.ts +23 -0
  45. package/dist/src/components/form/ASegmentedControl.vue.d.ts.map +1 -0
  46. package/dist/src/components/form/ATextInput.vue.d.ts +14 -0
  47. package/dist/src/components/form/ATextInput.vue.d.ts.map +1 -0
  48. package/dist/src/components/form/ATextboxInput.vue.d.ts +21 -0
  49. package/dist/src/components/form/ATextboxInput.vue.d.ts.map +1 -0
  50. package/dist/src/components/utilities/Login.vue.d.ts +14 -0
  51. package/dist/src/components/utilities/Login.vue.d.ts.map +1 -0
  52. package/dist/{tsdoc-metadata.json → src/tsdoc-metadata.json} +1 -1
  53. package/package.json +35 -30
  54. package/dist/aform.d.ts +0 -441
  55. package/dist/aform.tsbuildinfo +0 -1
  56. package/dist/src/directives/mask.js +0 -107
  57. package/dist/src/index.js +0 -58
  58. package/dist/src/types/index.js +0 -0
  59. package/dist/src/utils/badge.js +0 -71
  60. package/dist/src/utils/columns.js +0 -33
  61. package/dist/src/utils/deserialize.js +0 -20
  62. package/src/components/AForm.vue +0 -314
  63. package/src/components/AFormLoading.vue +0 -76
  64. package/src/components/base/CollapseButton.vue +0 -36
  65. package/src/components/base/ExpandButton.vue +0 -34
  66. package/src/components/form/ABadge.vue +0 -135
  67. package/src/components/form/ACheckbox.vue +0 -62
  68. package/src/components/form/ACurrencyInput.vue +0 -357
  69. package/src/components/form/ADate.vue +0 -93
  70. package/src/components/form/ADatePicker.vue +0 -470
  71. package/src/components/form/ADateRange.vue +0 -133
  72. package/src/components/form/ADateSelection.vue +0 -174
  73. package/src/components/form/ADateTime.vue +0 -149
  74. package/src/components/form/ADateTimeInput.vue +0 -299
  75. package/src/components/form/ADropdown.vue +0 -222
  76. package/src/components/form/ADuration.vue +0 -124
  77. package/src/components/form/AFieldset.vue +0 -72
  78. package/src/components/form/AFileAttach.vue +0 -97
  79. package/src/components/form/AFormLink.vue +0 -368
  80. package/src/components/form/ANumericInput.vue +0 -32
  81. package/src/components/form/AQuantityInput.vue +0 -349
  82. package/src/components/form/ASegmentedControl.vue +0 -342
  83. package/src/components/form/ATextInput.vue +0 -40
  84. package/src/components/form/ATextboxInput.vue +0 -66
  85. package/src/components/utilities/Login.vue +0 -189
  86. package/src/directives/mask.ts +0 -122
  87. package/src/index.ts +0 -92
  88. package/src/shims-vue.d.ts +0 -5
  89. package/src/types/index.ts +0 -333
  90. package/src/utils/badge.ts +0 -94
  91. package/src/utils/columns.ts +0 -38
  92. package/src/utils/deserialize.ts +0 -20
@@ -1,174 +0,0 @@
1
- <!-- This serves as a wrapper component for ADatePicker and ADateTimeInput in one component -->
2
-
3
- <template>
4
- <div class="adate-selection">
5
- <ADatePicker v-if="showDate" :select-range="selectRange" @get-date="handleDate" />
6
-
7
- <ADateTimeInput
8
- v-if="showTime"
9
- :allow-military-time="allowMilitaryTime"
10
- :default-hours="defaultHours"
11
- :default-minutes="defaultMinutes"
12
- :default-seconds="defaultSeconds"
13
- :default-meridiem="defaultMeridiem"
14
- :use-seconds="useSeconds"
15
- @get-time="handleStartTime" />
16
-
17
- <template v-if="selectRange && showTime && showEndTime">
18
- <div class="adate-selection__end-label">End time</div>
19
- <ADateTimeInput
20
- :allow-military-time="allowMilitaryTime"
21
- :default-hours="defaultHours"
22
- :default-minutes="defaultMinutes"
23
- :default-seconds="defaultSeconds"
24
- :default-meridiem="defaultMeridiem"
25
- :use-seconds="useSeconds"
26
- @get-time="handleEndTime" />
27
- </template>
28
-
29
- <p v-if="!showTime && !showDate" class="empty">empty</p>
30
- </div>
31
- </template>
32
-
33
- <script setup lang="ts">
34
- import { provide, ref } from 'vue'
35
- import ADatePicker from './ADatePicker.vue'
36
- import ADateTimeInput from './ADateTimeInput.vue'
37
-
38
- const {
39
- showDate = true,
40
- showTime = true,
41
- selectRange = true,
42
- showEndTime = false,
43
- allowMilitaryTime = false,
44
- defaultHours = 12,
45
- defaultMinutes = 0,
46
- defaultSeconds = 0,
47
- defaultMeridiem = 'AM',
48
- useSeconds = true,
49
- } = defineProps<{
50
- showDate?: boolean
51
- showTime?: boolean
52
- selectRange?: boolean
53
- showEndTime?: boolean
54
- allowMilitaryTime?: boolean
55
- defaultHours?: number
56
- defaultMinutes?: number
57
- defaultSeconds?: number
58
- defaultMeridiem?: string
59
- useSeconds?: boolean
60
- }>()
61
-
62
- // `source` is forwarded from ADateTimeInput, which declares it on every `get-time`. It is
63
- // optional here only because a host or a test may emit these events by hand, and doing so always
64
- // means a user action — `'init'` is the one case that has to be marked, because it is the widget
65
- // announcing its start value as it mounts rather than anything the user did.
66
- const emit = defineEmits<{
67
- 'get-date': [{ selected: Date; start?: Date | null; end?: Date | null }]
68
- 'get-time': [{ hours: number; minutes: number; seconds: number; meridiem: string; source?: 'init' | 'user' }]
69
- 'get-range': [{ start: Date; end: Date; source?: 'init' | 'user' }]
70
- }>()
71
-
72
- provide('select-range', selectRange)
73
-
74
- const today = new Date()
75
- const pickerStart = ref<Date>(today)
76
- const pickerEnd = ref<Date>(today)
77
- const startTimeMs = ref<number>(0)
78
- const endTimeMs = ref<number>(0)
79
-
80
- const mergeDateTime = (date: Date, timeMs: number): Date => {
81
- const d = new Date(date)
82
- d.setHours(0, 0, 0, 0)
83
- return new Date(d.getTime() + timeMs)
84
- }
85
-
86
- const timePayloadToMs = (payload: {
87
- hours: number
88
- minutes: number
89
- seconds: number
90
- meridiem: string
91
- militaryTime?: number
92
- }): number => {
93
- let h: number
94
- if (payload.militaryTime !== undefined) {
95
- h = payload.militaryTime
96
- } else {
97
- const hrs = payload.hours % 12
98
- h = payload.meridiem === 'PM' ? hrs + 12 : hrs
99
- }
100
- return (h * 3600 + payload.minutes * 60 + (payload.seconds ?? 0)) * 1000
101
- }
102
-
103
- const tryEmitRange = (source: 'init' | 'user') => {
104
- if (!selectRange || !showTime || !showEndTime) return
105
- emit('get-range', {
106
- start: mergeDateTime(pickerStart.value, startTimeMs.value),
107
- end: mergeDateTime(pickerEnd.value, endTimeMs.value),
108
- source,
109
- })
110
- }
111
-
112
- const handleDate = (data: { start: Date | null; end: Date | null; selected: Date }) => {
113
- emit('get-date', data)
114
- if (selectRange) {
115
- pickerStart.value = data.start ?? data.selected
116
- pickerEnd.value = data.end ?? data.selected
117
- // Picking a day on the calendar is unambiguously a user action.
118
- tryEmitRange('user')
119
- }
120
- }
121
-
122
- const handleStartTime = (data: {
123
- hours: number
124
- minutes: number
125
- seconds: number
126
- meridiem: string
127
- militaryTime?: number
128
- source?: 'init' | 'user'
129
- }) => {
130
- startTimeMs.value = timePayloadToMs(data)
131
- if (showEndTime) {
132
- tryEmitRange(data.source ?? 'user')
133
- } else {
134
- emit('get-time', data)
135
- }
136
- }
137
-
138
- const handleEndTime = (data: {
139
- hours: number
140
- minutes: number
141
- seconds: number
142
- meridiem: string
143
- militaryTime?: number
144
- source?: 'init' | 'user'
145
- }) => {
146
- endTimeMs.value = timePayloadToMs(data)
147
- tryEmitRange(data.source ?? 'user')
148
- }
149
- </script>
150
-
151
- <style scoped>
152
- .adate-selection {
153
- display: inline-block;
154
- border: 1px solid var(--sc-gray-80);
155
- padding: 10px;
156
- background: var(--sc-form-background);
157
- }
158
-
159
- .adate-selection__end-label {
160
- font-size: 0.8em;
161
- font-weight: bold;
162
- color: var(--sc-input-active-label-color);
163
- margin-top: 8px;
164
- margin-bottom: 2px;
165
- padding-left: 2px;
166
- }
167
-
168
- .empty {
169
- color: #ccc;
170
- padding: 10px;
171
- text-align: center;
172
- border: 1px solid #ccc;
173
- }
174
- </style>
@@ -1,149 +0,0 @@
1
- <template>
2
- <div class="aform_form-element">
3
- <template v-if="mode === 'display'">
4
- <span class="aform_display-value">{{ displayValue }}</span>
5
- <label class="aform_field-label">{{ label }}</label>
6
- </template>
7
-
8
- <template v-else>
9
- <input
10
- :id="uuid"
11
- class="aform_input-field"
12
- type="text"
13
- :value="datetimeDisplay"
14
- placeholder="Select date and time"
15
- :disabled="mode === 'read'"
16
- readonly
17
- @click="openPicker" />
18
- <label class="aform_field-label" :for="uuid">{{ label }}</label>
19
-
20
- <p v-show="errorText" class="aform_error" v-html="errorText"></p>
21
-
22
- <ADateSelection
23
- v-if="showPicker"
24
- ref="pickerRef"
25
- class="adatetime-picker"
26
- :select-range="false"
27
- :show-date="true"
28
- :show-time="true"
29
- :default-hours="pickerDefaults.hours"
30
- :default-minutes="pickerDefaults.minutes"
31
- :default-seconds="pickerDefaults.seconds"
32
- :default-meridiem="pickerDefaults.meridiem"
33
- :allow-military-time="allowMilitaryTime"
34
- :use-seconds="useSeconds"
35
- @get-date="handleDate"
36
- @get-time="handleTime" />
37
- </template>
38
- </div>
39
- </template>
40
-
41
- <script setup lang="ts">
42
- import { ref, computed, watch } from 'vue'
43
- import { onClickOutside } from '@vueuse/core'
44
- import ADateSelection from './ADateSelection.vue'
45
- import type { ComponentProps } from '../../types'
46
-
47
- const {
48
- label = 'Date & Time',
49
- mode,
50
- uuid,
51
- errors,
52
- validation = { errorMessage: '' },
53
- allowMilitaryTime = false,
54
- useSeconds = true,
55
- } = defineProps<
56
- ComponentProps & {
57
- allowMilitaryTime?: boolean
58
- useSeconds?: boolean
59
- }
60
- >()
61
-
62
- const errorText = computed(() => (errors?.length ? errors.join('; ') : (validation.errorMessage ?? '')))
63
-
64
- const modelValue = defineModel<string | Date>()
65
-
66
- const currentDateTime = ref<Date>(modelValue.value ? new Date(modelValue.value) : new Date())
67
-
68
- const showPicker = ref(false)
69
- const pickerRef = ref(null)
70
- onClickOutside(pickerRef, () => (showPicker.value = false))
71
-
72
- const openPicker = () => {
73
- if (mode !== 'read') showPicker.value = true
74
- }
75
-
76
- const displayValue = computed(() => {
77
- if (!modelValue.value) return ''
78
- return currentDateTime.value.toLocaleString()
79
- })
80
-
81
- const datetimeDisplay = computed(() => displayValue.value)
82
-
83
- const pickerDefaults = computed(() => {
84
- const d = currentDateTime.value
85
- const hours24 = d.getHours()
86
- const meridiem = hours24 >= 12 ? 'PM' : 'AM'
87
- const hours12 = hours24 % 12 || 12
88
- return {
89
- hours: allowMilitaryTime ? hours24 : hours12,
90
- minutes: d.getMinutes(),
91
- seconds: d.getSeconds(),
92
- meridiem,
93
- }
94
- })
95
-
96
- const emitModel = () => {
97
- modelValue.value = currentDateTime.value.toISOString()
98
- }
99
-
100
- const handleDate = (data: { selected: Date }) => {
101
- const next = new Date(currentDateTime.value)
102
- next.setFullYear(data.selected.getFullYear(), data.selected.getMonth(), data.selected.getDate())
103
- currentDateTime.value = next
104
- emitModel()
105
- }
106
-
107
- const handleTime = (data: {
108
- hours: number
109
- minutes: number
110
- seconds: number
111
- meridiem: string
112
- militaryTime?: number
113
- source?: 'init' | 'user'
114
- }) => {
115
- // The widget announces its own starting value as it mounts, and those defaults come from
116
- // `pickerDefaults` — i.e. straight back out of this component. Writing that echo to the model
117
- // meant one click on an empty field silently filled it with the current date and time.
118
- if (data.source === 'init') return
119
-
120
- const next = new Date(currentDateTime.value)
121
- const hours = data.militaryTime ?? data.hours
122
- next.setHours(hours, data.minutes, useSeconds ? data.seconds : 0, 0)
123
- currentDateTime.value = next
124
- emitModel()
125
- // Deliberately does NOT close the picker. `get-time` is the widget's current value, not a
126
- // commit — it fires on every blur, arrow key and meridiem change — so closing here shut the
127
- // picker as soon as the user tabbed out of the hours field. Dismissal is the click-outside
128
- // handler above; closing on `get-date` instead would strand the time half of a datetime.
129
- }
130
-
131
- watch(
132
- () => modelValue.value,
133
- newValue => {
134
- if (newValue) {
135
- currentDateTime.value = new Date(newValue)
136
- }
137
- }
138
- )
139
- </script>
140
-
141
- <style scoped>
142
- .adatetime-picker {
143
- position: absolute;
144
- top: 100%;
145
- left: 0;
146
- z-index: 1000;
147
- margin-top: 0.25rem;
148
- }
149
- </style>
@@ -1,299 +0,0 @@
1
- <template>
2
- <div class="adate_time">
3
- <div class="adate_time_fields">
4
- <input
5
- v-model="timeData.hours"
6
- type="text"
7
- inputmode="numeric"
8
- @paste="pasteInput($event, true)"
9
- @focus="focusInput"
10
- @blur="confirmTime"
11
- @keydown.enter.prevent="confirmTime"
12
- @keydown.up.prevent="tick('hours')"
13
- @keydown.down.prevent="tick('hours', -1)" />
14
- <span class="colon">:</span>
15
- <input
16
- v-model="timeData.minutes"
17
- type="text"
18
- inputmode="numeric"
19
- @paste="pasteInput"
20
- @focus="focusInput"
21
- @blur="confirmTime"
22
- @keydown.enter.prevent="confirmTime"
23
- @keydown.up.prevent="tick('minutes')"
24
- @keydown.down.prevent="tick('minutes', -1)" />
25
- <span v-if="useSeconds" class="colon">:</span>
26
- <input
27
- v-if="useSeconds"
28
- v-model="timeData.seconds"
29
- type="text"
30
- inputmode="numeric"
31
- @paste="pasteInput"
32
- @focus="focusInput"
33
- @blur="confirmTime"
34
- @keydown.enter.prevent="confirmTime"
35
- @keydown.up.prevent="tick('seconds')"
36
- @keydown.down.prevent="tick('seconds', -1)" />
37
- <select
38
- v-if="!allowMilitaryTime"
39
- ref="meridiem-selector"
40
- v-model="meridiem"
41
- class="aform-select meridiem-selector"
42
- @change="confirmTime">
43
- <option value="AM">AM</option>
44
- <option value="PM">PM</option>
45
- </select>
46
- </div>
47
- </div>
48
- </template>
49
-
50
- <script setup lang="ts">
51
- import { ref, reactive, useTemplateRef, watch, onMounted } from 'vue'
52
-
53
- const {
54
- allowMilitaryTime = false,
55
- defaultHours = 12,
56
- defaultMinutes = 0,
57
- defaultSeconds = 0,
58
- defaultMeridiem = 'AM',
59
- useSeconds = true,
60
- } = defineProps<{
61
- allowMilitaryTime?: boolean
62
- defaultHours?: number
63
- defaultMinutes?: number
64
- defaultSeconds?: number
65
- defaultMeridiem?: string
66
- useSeconds?: boolean
67
- }>()
68
-
69
- // `get-time` carries the widget's CURRENT VALUE, not a commit: it fires once as the widget
70
- // mounts and again on every blur, Enter, arrow key and meridiem change — five times during one
71
- // ordinary edit. `source` is what lets a parent tell the start-up announcement apart from a real
72
- // user edit; without it a parent has nothing to key on and must guess from the value alone.
73
- const emit = defineEmits<{
74
- 'get-time': [
75
- {
76
- hours: number
77
- minutes: number
78
- seconds: number
79
- meridiem: string
80
- militaryTime: number
81
- source: 'init' | 'user'
82
- },
83
- ]
84
- }>()
85
-
86
- const meridiemSelector = useTemplateRef<HTMLSelectElement>('meridiem-selector')
87
-
88
- const timeData = reactive({
89
- hours: String(defaultHours).padStart(2, '0'),
90
- minutes: String(defaultMinutes).padStart(2, '0'),
91
- seconds: String(defaultSeconds).padStart(2, '0'),
92
- })
93
-
94
- const meridiem = ref(defaultMeridiem == 'AM' ? 'AM' : 'PM')
95
-
96
- onMounted(() => {
97
- emitTime('init')
98
- })
99
-
100
- const confirmTime = () => {
101
- const maxHours = allowMilitaryTime ? 23 : 12
102
- const minHours = allowMilitaryTime ? 0 : 1
103
- let hours = Number(timeData.hours)
104
- let minutes = Number(timeData.minutes)
105
- let seconds = Number(timeData.seconds)
106
-
107
- if (isNaN(hours) || timeData.hours === '' || hours > maxHours) hours = maxHours
108
- if (!allowMilitaryTime && hours < minHours) hours = minHours
109
- if (isNaN(minutes) || timeData.minutes === '' || minutes > 59) minutes = 59
110
- if (isNaN(seconds) || timeData.seconds === '' || seconds > 59) seconds = 59
111
-
112
- timeData.hours = String(hours).padStart(2, '0')
113
- timeData.minutes = String(minutes).padStart(2, '0')
114
- timeData.seconds = String(seconds).padStart(2, '0')
115
-
116
- emitTime('user')
117
- }
118
-
119
- const emitTime = (source: 'init' | 'user') => {
120
- const hours = Number(timeData.hours)
121
- const minutes = Number(timeData.minutes)
122
- const seconds = Number(timeData.seconds)
123
- emit('get-time', {
124
- hours,
125
- minutes,
126
- seconds,
127
- source,
128
- meridiem: meridiem.value,
129
- militaryTime: allowMilitaryTime ? hours : meridiem.value === 'PM' ? (hours === 12 ? 12 : hours + 12) : hours % 12,
130
- })
131
- }
132
-
133
- const focusInput = (event: FocusEvent) => {
134
- const target = event.target
135
- if (target instanceof HTMLInputElement) {
136
- target.select()
137
- }
138
- }
139
-
140
- const tick = (target: 'hours' | 'minutes' | 'seconds', amount = 1) => {
141
- const maxHours = allowMilitaryTime ? 23 : 12
142
- const minHours = allowMilitaryTime ? 0 : 1
143
-
144
- if (target == 'hours') {
145
- const oldHours = Number(timeData.hours)
146
- timeData.hours = String(oldHours + amount)
147
- if ((oldHours == 11 && Number(timeData.hours) == 12) || (oldHours == 12 && Number(timeData.hours) == 11)) {
148
- changeMeridiem()
149
- }
150
- } else if (target == 'minutes') {
151
- timeData.minutes = String(Number(timeData.minutes) + amount)
152
- } else if (target == 'seconds') {
153
- timeData.seconds = String(Number(timeData.seconds) + amount)
154
- }
155
-
156
- const prevHours = Number(timeData.hours)
157
-
158
- if (Number(timeData.seconds) < 0) timeData.minutes = String(Number(timeData.minutes) - 1)
159
- else if (Number(timeData.seconds) > 59) timeData.minutes = String(Number(timeData.minutes) + 1)
160
-
161
- if (Number(timeData.minutes) < 0) timeData.hours = String(prevHours - 1)
162
- else if (Number(timeData.minutes) > 59) timeData.hours = String(prevHours + 1)
163
-
164
- const newRawHours = Number(timeData.hours)
165
- if (!allowMilitaryTime && newRawHours !== prevHours) {
166
- if ((prevHours === 11 && newRawHours === 12) || (prevHours === 12 && newRawHours === 11)) {
167
- changeMeridiem()
168
- }
169
- }
170
-
171
- timeData.hours = String(formatTime(Number(timeData.hours), minHours, maxHours)).padStart(2, '0')
172
- timeData.minutes = String(formatTime(Number(timeData.minutes), 0, 59)).padStart(2, '0')
173
- timeData.seconds = String(formatTime(Number(timeData.seconds), 0, 59)).padStart(2, '0')
174
- }
175
-
176
- watch(
177
- () => timeData.hours,
178
- (newVal, oldVal) => {
179
- timeData.hours = Number(newVal) > 99 ? oldVal : newVal
180
- }
181
- )
182
- watch(
183
- () => timeData.minutes,
184
- (newVal, oldVal) => {
185
- timeData.minutes = Number(newVal) > 99 ? oldVal : newVal
186
- }
187
- )
188
- watch(
189
- () => timeData.seconds,
190
- (newVal, oldVal) => {
191
- timeData.seconds = Number(newVal) > 99 ? oldVal : newVal
192
- }
193
- )
194
-
195
- const formatTime = (target: number, min: number, max: number): number => {
196
- if (target > max) return min
197
- else if (target < min) return max
198
- return target
199
- }
200
-
201
- const changeMeridiem = () => {
202
- meridiem.value = meridiem.value == 'PM' ? 'AM' : 'PM'
203
- emitTime('user')
204
- }
205
-
206
- const pasteInput = (event: ClipboardEvent, pasteAllFields = false) => {
207
- event.stopPropagation()
208
- event.preventDefault()
209
-
210
- const clipboardData = event.clipboardData
211
- if (!clipboardData) return
212
- let pastedData: string = clipboardData.getData('Text')
213
-
214
- pastedData = pastedData.replace(/[^0-9]/g, '')
215
-
216
- if (pasteAllFields) {
217
- if (pastedData.length % 2 != 0) pastedData = '0' + pastedData
218
- if (pastedData.length < 3) pastedData += '00'
219
- if (pastedData.length < 5) pastedData += '00'
220
-
221
- const timeUnits = pastedData.match(/(..?)/g)
222
- if (!timeUnits || timeUnits.length < 3) return
223
-
224
- timeData.seconds = timeUnits[2]
225
- timeData.minutes = timeUnits[1]
226
- timeData.hours = timeUnits[0]
227
- confirmTime()
228
- if (!allowMilitaryTime) meridiemSelector.value?.focus()
229
- } else {
230
- if (pastedData.length > 2) pastedData = pastedData.slice(0, 2)
231
- const target = event.target
232
- if (target instanceof HTMLInputElement) {
233
- target.value = pastedData
234
- target.dispatchEvent(new Event('input'))
235
- }
236
- }
237
- }
238
- </script>
239
-
240
- <style scoped>
241
- .adate_time {
242
- width: auto;
243
- padding: 10px;
244
- box-sizing: border-box;
245
- font-size: 1rem;
246
- background: var(--sc-gray-10);
247
- }
248
- .adate_time_fields {
249
- display: flex;
250
- align-items: stretch;
251
- gap: 5px;
252
- justify-content: flex-start;
253
- }
254
- .adate_time_fields > input {
255
- min-width: 30px;
256
- padding: 2px;
257
- text-align: center;
258
- display: inline-block;
259
- flex-basis: 0;
260
- }
261
- .meridiem-selector {
262
- cursor: pointer;
263
- display: inline-block;
264
- flex-basis: 0;
265
- padding: 5px;
266
- user-select: none;
267
- }
268
- .meridiem-selector:focus {
269
- outline: 2px solid black;
270
- outline-offset: -2px;
271
- }
272
- .adate_time_segment {
273
- display: flex;
274
- flex-direction: column;
275
- width: 40px;
276
- }
277
- .colon {
278
- display: flex;
279
- align-items: normal;
280
- }
281
- .aform_form-btn {
282
- cursor: pointer;
283
- }
284
- .aform-select {
285
- border-radius: 0px;
286
- border: 1px solid rgb(118, 118, 118);
287
- font-size: 1rem;
288
- padding: 0rem;
289
- margin: 0;
290
- border-radius: 0;
291
- box-sizing: border-box;
292
- min-height: auto;
293
- position: relative;
294
- color: var(--sc-cell-text-color);
295
- }
296
- .meridiem-selector {
297
- margin-left: 6px;
298
- }
299
- </style>