@a-vision-software/vue-input-components 1.3.19 → 1.3.21

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a-vision-software/vue-input-components",
3
- "version": "1.3.19",
3
+ "version": "1.3.21",
4
4
  "description": "A collection of reusable Vue 3 input components with TypeScript support",
5
5
  "author": "A-Vision Software",
6
6
  "license": "MIT",
@@ -0,0 +1,337 @@
1
+ <template>
2
+ <div class="checkbox" :class="{
3
+ 'checkbox--disabled': disabled,
4
+ 'checkbox--has-error': error,
5
+ 'checkbox--large-icon': iconSize === 'large',
6
+ [`label-${labelPosition}`]: label,
7
+ [`label-align-${labelAlign}`]: label,
8
+ [`checkbox--${presentation}`]: presentation,
9
+ }" :style="[
10
+ { width: width || '100%' },
11
+ labelStyle,
12
+ {
13
+ '--checkbox-color': error ? 'var(--danger-color)' : color,
14
+ '--checkbox-hover-color': hoverColor ? hoverColor : 'var(--checkbox-color)',
15
+ '--checkbox-active-color': activeColor ? activeColor : 'var(--checkbox-color)',
16
+ '--checkbox-disabled-color': disabledColor,
17
+ '--checkbox-background-color': backgroundColor,
18
+ '--checkbox-border-radius': borderRadius,
19
+ '--checkbox-padding': padding,
20
+ }
21
+ ]">
22
+ <label v-if="label" :for="id" class="label">
23
+ {{ label }}
24
+ </label>
25
+ <div class="checkbox__options" :style="{
26
+ 'grid-template-columns': `repeat(${columns || 1}, 1fr)`,
27
+ 'gap': presentation === 'minimal' ? '0' : '0.5rem'
28
+ }">
29
+ <div v-for="option in options" :key="option.id" class="checkbox__option" :class="{
30
+ 'checkbox__option--disabled': option.disabled || disabled,
31
+ 'checkbox__option--selected': isSelected(option),
32
+ 'checkbox__option--round': !multiple && options.length > 1
33
+ }" @click="() => toggleOption(option)">
34
+ <div class="checkbox__icon">
35
+ <font-awesome-icon v-if="isSelected(option)" :icon="multiple ? 'square-check' : 'circle-check'" />
36
+ <font-awesome-icon v-else :icon="multiple ? 'square' : 'circle'" />
37
+ </div>
38
+ <div class="checkbox__label">{{ option.label }}</div>
39
+ </div>
40
+ </div>
41
+ <span v-if="required && !showSaved && !showChanged && !error"
42
+ class="status-indicator required-indicator">required</span>
43
+ <transition name="fade">
44
+ <span v-if="showSaved && !error" class="status-indicator saved-indicator">saved</span>
45
+ </transition>
46
+ <transition name="fade">
47
+ <span v-if="showChanged && !error" class="status-indicator changed-indicator">changed</span>
48
+ </transition>
49
+ <transition name="fade">
50
+ <span v-if="error" class="status-indicator error-indicator" :data-error="error">error</span>
51
+ </transition>
52
+ </div>
53
+ </template>
54
+
55
+ <script setup lang="ts">
56
+ import { ref, computed, onMounted } from 'vue'
57
+ import type { CheckboxProps, CheckboxOption } from '../types/checkbox'
58
+
59
+ const props = withDefaults(defineProps<CheckboxProps>(), {
60
+ multiple: false,
61
+ disabled: false,
62
+ width: '100%',
63
+ color: 'var(--text-primary)',
64
+ hoverColor: '',
65
+ activeColor: '',
66
+ disabledColor: 'var(--text-disabled)',
67
+ backgroundColor: 'white',
68
+ borderRadius: '0.375rem',
69
+ padding: '0.5rem',
70
+ icon: '',
71
+ iconSize: 'normal',
72
+ required: false,
73
+ error: '',
74
+ label: '',
75
+ labelPosition: 'top',
76
+ labelAlign: 'left',
77
+ labelWidth: '',
78
+ columns: 1,
79
+ presentation: 'default',
80
+ })
81
+
82
+ const emit = defineEmits<{
83
+ (e: 'update:modelValue', value: string | string[]): void
84
+ (e: 'changed'): void
85
+ (e: 'saved'): void
86
+ }>()
87
+
88
+ const id = ref<string>('')
89
+ const showSaved = ref(false)
90
+ const showChanged = ref(false)
91
+ const isChanged = ref(false)
92
+ const debounceTimer = ref<number | null>(null)
93
+ const changedTimer = ref<number | null>(null)
94
+
95
+ const isSelected = (option: CheckboxOption) => {
96
+ if (Array.isArray(props.modelValue)) {
97
+ return props.modelValue.includes(option.id)
98
+ }
99
+ return option.id === props.modelValue
100
+ }
101
+
102
+ const toggleOption = (option: CheckboxOption) => {
103
+ if (option.disabled || props.disabled) return
104
+
105
+ if (props.multiple) {
106
+ const currentValue = Array.isArray(props.modelValue) ? props.modelValue : []
107
+ const newValue = currentValue.includes(option.id)
108
+ ? currentValue.filter((id) => id !== option.id)
109
+ : [...currentValue, option.id]
110
+ emit('update:modelValue', newValue)
111
+ debounceAutosave(newValue)
112
+ } else {
113
+ const newValue = option.id === props.modelValue ? '' : option.id
114
+ emit('update:modelValue', newValue)
115
+ debounceAutosave(newValue)
116
+ }
117
+ }
118
+
119
+ const handleAutosave = async (value: string | string[]) => {
120
+ if (props.autosave) {
121
+ try {
122
+ await props.autosave(value)
123
+ if (!props.error) {
124
+ emit('saved')
125
+ showSaved.value = true
126
+ showChanged.value = false
127
+ setTimeout(() => {
128
+ showSaved.value = false
129
+ }, 3000)
130
+ }
131
+ } catch (error) {
132
+ console.error('Autosave failed:', error)
133
+ }
134
+ }
135
+ }
136
+
137
+ const debounceAutosave = (value: string | string[]) => {
138
+ if (debounceTimer.value) {
139
+ clearTimeout(debounceTimer.value)
140
+ }
141
+ if (changedTimer.value) {
142
+ clearTimeout(changedTimer.value)
143
+ }
144
+
145
+ if (!props.error) {
146
+ showChanged.value = true
147
+ }
148
+
149
+ changedTimer.value = window.setTimeout(() => {
150
+ emit('changed')
151
+ isChanged.value = true
152
+ }, 500)
153
+
154
+ debounceTimer.value = window.setTimeout(() => {
155
+ handleAutosave(value)
156
+ }, 1500)
157
+ }
158
+
159
+ onMounted(() => {
160
+ id.value = `checkbox-${Math.random().toString(36).substring(2, 11)}`
161
+ })
162
+
163
+ const labelStyle = computed(() => {
164
+ if (!props.label) return {}
165
+ if (props.labelPosition === 'left' && props.labelWidth) {
166
+ return {
167
+ 'grid-template-columns': `${props.labelWidth} 1fr`,
168
+ }
169
+ }
170
+ return {}
171
+ })
172
+ </script>
173
+
174
+ <style scoped>
175
+ .checkbox {
176
+ position: relative;
177
+ width: var(--checkbox-width);
178
+ font-family: Arial, sans-serif;
179
+ cursor: pointer;
180
+ user-select: none;
181
+ outline: none;
182
+ display: grid;
183
+ gap: 0.5rem;
184
+ margin-top: 0.7rem;
185
+
186
+ .checkbox__options {
187
+ display: grid;
188
+ gap: 0.5rem;
189
+ }
190
+
191
+ &.checkbox--minimal .checkbox__options {
192
+ gap: 0;
193
+ margin: -0.5rem 0;
194
+ }
195
+ }
196
+
197
+ .checkbox--disabled {
198
+ opacity: 0.6;
199
+ cursor: not-allowed;
200
+ }
201
+
202
+ .checkbox--has-error {
203
+ border-color: var(--danger-color);
204
+ }
205
+
206
+
207
+ .checkbox__option {
208
+ display: flex;
209
+ align-items: center;
210
+ gap: 0.5rem;
211
+ padding: var(--checkbox-padding);
212
+ border: 1px solid var(--checkbox-color);
213
+ border-radius: var(--checkbox-border-radius);
214
+ background-color: var(--checkbox-background-color);
215
+ color: var(--checkbox-color);
216
+ transition: all 0.2s ease;
217
+ min-width: 0;
218
+ }
219
+
220
+ .checkbox--minimal .checkbox__option {
221
+ border: none;
222
+ border-radius: 0;
223
+ padding: 0.25rem 0.5rem;
224
+ margin: 0;
225
+ }
226
+
227
+ .checkbox__option:hover {
228
+ border-color: var(--checkbox-hover-color);
229
+ color: var(--checkbox-hover-color);
230
+ }
231
+
232
+ .checkbox--minimal .checkbox__option:hover {
233
+ background-color: rgba(0, 0, 0, 0.05);
234
+ }
235
+
236
+ .checkbox__option--selected {
237
+ border-color: var(--checkbox-active-color);
238
+ color: var(--checkbox-active-color);
239
+ background-color: rgba(from var(--checkbox-active-color) r g b / 0.1);
240
+ }
241
+
242
+ .checkbox--minimal .checkbox__option--selected {
243
+ background-color: rgba(from var(--checkbox-active-color) r g b / 0.1);
244
+ }
245
+
246
+ .checkbox__option--disabled {
247
+ opacity: 0.6;
248
+ cursor: not-allowed;
249
+ color: var(--checkbox-disabled-color);
250
+ }
251
+
252
+ .checkbox--minimal .checkbox__option--disabled {
253
+ background-color: transparent;
254
+ }
255
+
256
+ .checkbox__icon {
257
+ display: flex;
258
+ align-items: center;
259
+ justify-content: center;
260
+ font-size: 1.2em;
261
+ flex-shrink: 0;
262
+ }
263
+
264
+ .checkbox__label {
265
+ flex: 1;
266
+ min-width: 0;
267
+ overflow: hidden;
268
+ text-overflow: ellipsis;
269
+ white-space: nowrap;
270
+ }
271
+
272
+ .status-indicator {
273
+ position: absolute;
274
+ top: -1px;
275
+ line-height: 1px;
276
+ right: 0.5rem;
277
+ font-size: 0.75rem;
278
+ color: var(--text-muted);
279
+ background-color: var(--checkbox-background-color);
280
+ padding: 0 0.25rem;
281
+ }
282
+
283
+ .status-indicator.saved-indicator {
284
+ color: var(--success-color);
285
+ }
286
+
287
+ .status-indicator.changed-indicator {
288
+ color: var(--warning-color);
289
+ }
290
+
291
+ .status-indicator.error-indicator {
292
+ color: var(--danger-color);
293
+ }
294
+
295
+ .fade-enter-active,
296
+ .fade-leave-active {
297
+ transition: opacity 0.2s ease;
298
+ }
299
+
300
+ .fade-enter-from,
301
+ .fade-leave-to {
302
+ opacity: 0;
303
+ }
304
+
305
+ .checkbox.label-top {
306
+ grid-template-rows: auto 1fr;
307
+ }
308
+
309
+ .checkbox.label-left {
310
+ grid-template-columns: 30% 1fr;
311
+ align-items: start;
312
+ gap: 1rem;
313
+ }
314
+
315
+ .checkbox.label-left .label {
316
+ padding-top: 0.25rem;
317
+ width: 100%;
318
+ }
319
+
320
+ .label {
321
+ font-weight: 500;
322
+ color: var(--text-color);
323
+ text-align: left;
324
+ }
325
+
326
+ .label-align-left .label {
327
+ text-align: left;
328
+ }
329
+
330
+ .label-align-right .label {
331
+ text-align: right;
332
+ }
333
+
334
+ .label-align-center .label {
335
+ text-align: center;
336
+ }
337
+ </style>
@@ -177,7 +177,7 @@ const handleInput = (event: Event) => {
177
177
  const value = (event.target as HTMLTextAreaElement).value
178
178
  emit('update:modelValue', value)
179
179
  debounceAutosave(value)
180
- if (props.type === 'text' && (event.target as HTMLTextAreaElement).tagName === 'TEXTAREA') {
180
+ if (props.type === 'textarea' && (event.target as HTMLTextAreaElement).tagName === 'TEXTAREA') {
181
181
  adjustHeight(event.target as HTMLTextAreaElement)
182
182
  }
183
183
  }
package/src/index.ts CHANGED
@@ -3,7 +3,8 @@ import FileUpload from './components/FileUpload.vue'
3
3
  import Navigation from './components/Navigation.vue'
4
4
  import Action from './components/Action.vue'
5
5
  import Dropdown from './components/Dropdown.vue'
6
+ import Checkbox from './components/Checkbox.vue'
6
7
 
7
- export { TextInput, FileUpload, Navigation, Action, Dropdown }
8
+ export { TextInput, FileUpload, Navigation, Action, Dropdown, Checkbox }
8
9
 
9
10
  export * from './types'
@@ -5,6 +5,7 @@ import ActionTestView from '../views/ActionTestView.vue'
5
5
  import DashboardView from '../views/DashboardView.vue'
6
6
  import NavigationTestView from '../views/NavigationTestView.vue'
7
7
  import DropdownTestView from '../views/DropdownTestView.vue'
8
+ import CheckboxTestView from '../views/CheckboxTestView.vue'
8
9
 
9
10
  const router = createRouter({
10
11
  history: createWebHistory(import.meta.env.BASE_URL),
@@ -45,6 +46,12 @@ const router = createRouter({
45
46
  component: DropdownTestView,
46
47
  meta: { title: 'Dropdown Test' },
47
48
  },
49
+ {
50
+ path: '/checkbox',
51
+ name: 'checkbox',
52
+ component: CheckboxTestView,
53
+ meta: { title: 'Checkbox Test' },
54
+ },
48
55
  ],
49
56
  })
50
57
 
@@ -0,0 +1,31 @@
1
+ export interface CheckboxOption {
2
+ id: string
3
+ label: string
4
+ disabled?: boolean
5
+ }
6
+
7
+ export interface CheckboxProps {
8
+ options: CheckboxOption[]
9
+ modelValue: string | string[]
10
+ multiple?: boolean
11
+ disabled?: boolean
12
+ width?: string
13
+ color?: string
14
+ hoverColor?: string
15
+ activeColor?: string
16
+ disabledColor?: string
17
+ backgroundColor?: string
18
+ borderRadius?: string
19
+ padding?: string
20
+ icon?: string
21
+ iconSize?: 'normal' | 'large'
22
+ error?: string
23
+ required?: boolean
24
+ autosave?: (value: string | string[]) => Promise<void>
25
+ label?: string
26
+ labelPosition?: 'top' | 'left'
27
+ labelAlign?: 'left' | 'center' | 'right'
28
+ labelWidth?: string
29
+ columns?: number
30
+ presentation?: 'default' | 'minimal'
31
+ }
@@ -7,3 +7,4 @@ export * from './fileupload'
7
7
  export * from './action'
8
8
  export * from './navigation'
9
9
  export * from './dropdown'
10
+ export * from './checkbox'
@@ -1,24 +1,24 @@
1
1
  export interface TextInputProps {
2
2
  modelValue: string
3
+ required?: boolean
3
4
  type?: 'text' | 'textarea' | 'password' | 'email' | 'tel' | 'url' | 'date' | 'number'
4
5
  placeholder?: string
5
6
  label?: string
7
+ labelPosition?: 'top' | 'left'
8
+ labelAlign?: 'left' | 'center' | 'right'
9
+ labelWidth?: string
10
+ width?: string
6
11
  icon?: string
7
12
  disabled?: boolean
8
13
  readonly?: boolean
9
14
  maxlength?: number
10
- error?: string
11
15
  min?: Date | string
12
16
  max?: Date | string
13
- autosave?: (value: string) => Promise<void>
14
- labelPosition?: 'top' | 'left'
15
- labelAlign?: 'left' | 'center' | 'right'
16
- labelWidth?: string
17
17
  height?: string
18
18
  maxHeight?: string
19
19
  bgColor?: string
20
- width?: string
21
- required?: boolean
20
+ autosave?: (value: string) => Promise<void>
21
+ error?: string
22
22
  }
23
23
 
24
24
  export interface TextInputEmits {
@@ -0,0 +1,209 @@
1
+ <template>
2
+ <div class="checkbox-test">
3
+ <div class="checkbox-test__back">
4
+ <router-link to="/" class="back-link"> ← Back to Dashboard </router-link>
5
+ </div>
6
+
7
+ <div class="checkbox-test__section">
8
+ <h2>Single Select Checkbox</h2>
9
+ <Checkbox v-model="selectedSingle" :options="options" label="Select a Color" labelPosition="left"
10
+ labelWidth="100px" labelAlign="right" required @update:modelValue="handleSingleChange"
11
+ error="This is an error" />
12
+ <div v-if="selectedSingle.length" class="selection-info">
13
+ Selected: {{ Array.isArray(selectedSingle) ? getSelectedLabels(selectedSingle).join(', ') :
14
+ getOptionLabel(selectedSingle) }}
15
+ </div>
16
+ </div>
17
+
18
+ <div class="checkbox-test__section">
19
+ <h2>Multiple Select Checkbox</h2>
20
+ <Checkbox v-model="selectedMultiple" :options="options" label="Select Colors" :multiple="true" icon="paintbrush"
21
+ @update:modelValue="handleMultipleChange" color="#aa0000" />
22
+ <div v-if="selectedMultiple.length" class="selection-info">
23
+ Selected: {{ getSelectedLabels(selectedMultiple).join(', ') }}
24
+ </div>
25
+ </div>
26
+
27
+ <div class="checkbox-test__section">
28
+ <h2>Checkbox with Disabled Options</h2>
29
+ <Checkbox v-model="selectedWithDisabled" :options="optionsWithDisabled" label="Select with Disabled Options"
30
+ @update:modelValue="handleDisabledChange" />
31
+ <div v-if="selectedWithDisabled" class="selection-info">
32
+ Selected: {{ getOptionLabel(selectedWithDisabled) }}
33
+ </div>
34
+ </div>
35
+
36
+ <div class="checkbox-test__section">
37
+ <h2>Disabled Checkbox</h2>
38
+ <Checkbox v-model="selectedDisabled" :options="options" label="Disabled Checkbox" :disabled="true" />
39
+ </div>
40
+
41
+ <div class="checkbox-test__section">
42
+ <h2>Custom Styled Checkbox</h2>
43
+ <Checkbox v-model="selectedCustom" :options="options" label="Custom Style" color="#4a90e2" hoverColor="#357abd"
44
+ activeColor="#2c5a8c" borderRadius="1rem" padding="0.75rem 1rem" @update:modelValue="handleCustomChange" />
45
+ <div v-if="selectedCustom" class="selection-info">
46
+ Selected: {{ getOptionLabel(selectedCustom) }}
47
+ </div>
48
+ </div>
49
+
50
+ <div class="checkbox-test__section">
51
+ <h2>Checkbox with Autosave</h2>
52
+ <Checkbox v-model="selectedAutosave" :options="options" label="With Autosave" :autosave="handleAutosave"
53
+ @update:modelValue="handleAutosaveChange" />
54
+ <div v-if="selectedAutosave" class="selection-info">
55
+ Selected: {{ getOptionLabel(selectedAutosave) }}
56
+ </div>
57
+ </div>
58
+
59
+ <div class="checkbox-test__section">
60
+ <h2>Minimal Presentation</h2>
61
+ <Checkbox v-model="selectedMinimal" :options="options" label="Minimal Style" presentation="minimal"
62
+ @update:modelValue="handleMinimalChange" />
63
+ <div v-if="selectedMinimal" class="selection-info">
64
+ Selected: {{ getOptionLabel(selectedMinimal) }}
65
+ </div>
66
+ </div>
67
+
68
+ <div class="checkbox-test__section">
69
+ <h2>Multi-Column Checkbox</h2>
70
+ <Checkbox v-model="selectedMultiColumn" :options="options" label="Multi-Column Layout" :columns="3"
71
+ :multiple="true" presentation="minimal" @update:modelValue="handleMultiColumnChange" />
72
+ <div v-if="selectedMultiColumn" class="selection-info">
73
+ Selected: {{ getSelectedLabels(selectedMultiColumn).join(', ') }}
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </template>
78
+
79
+ <script setup lang="ts">
80
+ import { ref } from 'vue'
81
+ import type { CheckboxOption } from '../types/checkbox'
82
+ import Checkbox from '@/components/Checkbox.vue'
83
+
84
+ const options: CheckboxOption[] = [
85
+ { id: 'red', label: 'Red' },
86
+ { id: 'blue', label: 'Blue' },
87
+ { id: 'green', label: 'Green' },
88
+ { id: 'yellow', label: 'Yellow' },
89
+ { id: 'purple', label: 'Purple' },
90
+ ]
91
+
92
+ const optionsWithDisabled: CheckboxOption[] = [
93
+ { id: 'red', label: 'Red' },
94
+ { id: 'blue', label: 'Blue', disabled: true },
95
+ { id: 'green', label: 'Green' },
96
+ { id: 'yellow', label: 'Yellow', disabled: true },
97
+ { id: 'purple', label: 'Purple' },
98
+ ]
99
+
100
+ const selectedSingle = ref<string[]>(['red', 'yellow'])
101
+ const selectedMultiple = ref<string[]>(['red', 'yellow'])
102
+ const selectedCustom = ref('')
103
+ const selectedDisabled = ref('green')
104
+ const selectedWithDisabled = ref('')
105
+ const selectedAutosave = ref('')
106
+ const selectedMinimal = ref('')
107
+ const selectedMultiColumn = ref<string[]>(['red', 'yellow'])
108
+
109
+ const getOptionLabel = (id: string) => {
110
+ return options.find((option) => option.id === id)?.label || ''
111
+ }
112
+
113
+ const getSelectedLabels = (ids: string[]) => {
114
+ return ids.map((id) => getOptionLabel(id)).filter(Boolean)
115
+ }
116
+
117
+ const handleSingleChange = (value: string | string[]) => {
118
+ if (typeof value === 'string') {
119
+ console.log('Single selection changed:', value)
120
+ }
121
+ }
122
+
123
+ const handleMultipleChange = (value: string | string[]) => {
124
+ if (Array.isArray(value)) {
125
+ console.log('Multiple selection changed:', value)
126
+ }
127
+ }
128
+
129
+ const handleCustomChange = (value: string | string[]) => {
130
+ if (typeof value === 'string') {
131
+ console.log('Custom selection changed:', value)
132
+ }
133
+ }
134
+
135
+ const handleDisabledChange = (value: string | string[]) => {
136
+ if (typeof value === 'string') {
137
+ console.log('Selection with disabled options changed:', value)
138
+ }
139
+ }
140
+
141
+ const handleAutosaveChange = (value: string | string[]) => {
142
+ if (typeof value === 'string') {
143
+ console.log('Autosave selection changed:', value)
144
+ }
145
+ }
146
+
147
+ const handleAutosave = async (value: string | string[]) => {
148
+ console.log('Autosaving:', value)
149
+ // Simulate API call
150
+ await new Promise((resolve) => setTimeout(resolve, 1000))
151
+ }
152
+
153
+ const handleMinimalChange = (value: string | string[]) => {
154
+ if (typeof value === 'string') {
155
+ console.log('Minimal selection changed:', value)
156
+ }
157
+ }
158
+
159
+ const handleMultiColumnChange = (value: string | string[]) => {
160
+ if (typeof value === 'string') {
161
+ console.log('Multi-column selection changed:', value)
162
+ }
163
+ }
164
+ </script>
165
+
166
+ <style scoped>
167
+ .checkbox-test {
168
+ max-width: 800px;
169
+ margin: 0 auto;
170
+ padding: 2rem;
171
+ margin-bottom: 5rem;
172
+ }
173
+
174
+ .checkbox-test__back {
175
+ margin-bottom: 2rem;
176
+ }
177
+
178
+ .back-link {
179
+ display: inline-flex;
180
+ align-items: center;
181
+ gap: 0.5rem;
182
+ color: #4a90e2;
183
+ text-decoration: none;
184
+ font-weight: 500;
185
+ }
186
+
187
+ .back-link:hover {
188
+ color: #357abd;
189
+ }
190
+
191
+ .checkbox-test__section {
192
+ margin-bottom: 3rem;
193
+ }
194
+
195
+ .checkbox-test__section h2 {
196
+ margin-bottom: 1rem;
197
+ color: #333;
198
+ font-size: 1.5rem;
199
+ }
200
+
201
+ .selection-info {
202
+ margin-top: 1rem;
203
+ padding: 0.5rem;
204
+ background-color: #f7fafc;
205
+ border-radius: 4px;
206
+ font-size: 0.9rem;
207
+ color: #4a5568;
208
+ }
209
+ </style>