@bagelink/vue 1.15.301 → 1.15.303
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/AccordionItem.vue.d.ts.map +1 -1
- package/dist/components/FilterQuery.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/IconPickerInput.vue.d.ts +209 -0
- package/dist/components/form/inputs/IconPickerInput.vue.d.ts.map +1 -0
- package/dist/components/form/inputs/index.d.ts +1 -0
- package/dist/components/form/inputs/index.d.ts.map +1 -1
- package/dist/components/layout/AppContent.vue.d.ts.map +1 -1
- package/dist/form-flow/FormFlow.vue.d.ts.map +1 -1
- package/dist/form-flow/form-flow.d.ts +1 -0
- package/dist/form-flow/form-flow.d.ts.map +1 -1
- package/dist/index.cjs +34 -34
- package/dist/index.mjs +7078 -6949
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/AccordionItem.vue +1 -0
- package/src/components/FilterQuery.vue +3 -2
- package/src/components/form/inputs/CodeEditor/Index.vue +7 -1
- package/src/components/form/inputs/IconPickerInput.vue +120 -0
- package/src/components/form/inputs/index.ts +1 -0
- package/src/components/layout/AppContent.vue +6 -0
- package/src/form-flow/FormFlow.vue +2 -0
- package/src/form-flow/form-flow.ts +7 -0
package/package.json
CHANGED
|
@@ -652,6 +652,7 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
|
|
|
652
652
|
.and-or-select {
|
|
653
653
|
--bgl-input-font-size: 12px !important;
|
|
654
654
|
--input-background-color: transparent !important;
|
|
655
|
+
min-width: 60px !important;
|
|
655
656
|
}
|
|
656
657
|
|
|
657
658
|
.between-inputs {
|
|
@@ -706,11 +707,11 @@ max-height: none;
|
|
|
706
707
|
}
|
|
707
708
|
|
|
708
709
|
.filter-query-inline .filter-row {
|
|
709
|
-
grid-template-columns:
|
|
710
|
+
grid-template-columns: 60px minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto;
|
|
710
711
|
}
|
|
711
712
|
|
|
712
713
|
.filter-query-inline .first-filter-row {
|
|
713
|
-
grid-template-columns:
|
|
714
|
+
grid-template-columns: 60px minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto;
|
|
714
715
|
}
|
|
715
716
|
|
|
716
717
|
.filter-query-inline .first-filter-field {
|
|
@@ -167,7 +167,7 @@ watch(() => props.modelValue, () => {
|
|
|
167
167
|
|
|
168
168
|
<template>
|
|
169
169
|
<div
|
|
170
|
-
class="bagel-input code-editor-container ltr" :class="[shellClass, { '
|
|
170
|
+
class="bagel-input code-editor-container ltr" :class="[shellClass, { '': label && !singleLine, 'has-value': hasCodeValue, 'single-line': singleLine }]"
|
|
171
171
|
:style="[{ height: maxHeight }, shellStyle]"
|
|
172
172
|
>
|
|
173
173
|
<label v-if="label" class="label">{{ label }}</label>
|
|
@@ -225,6 +225,12 @@ watch(() => props.modelValue, () => {
|
|
|
225
225
|
outline: solid 1px var(--bgl-border-color, #4f575f);
|
|
226
226
|
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.13);
|
|
227
227
|
}
|
|
228
|
+
.code-editor-grandpa textarea.code-input{
|
|
229
|
+
box-shadow: none !important;
|
|
230
|
+
background: transparent !important;
|
|
231
|
+
border-radius: 0 !important;
|
|
232
|
+
|
|
233
|
+
}
|
|
228
234
|
|
|
229
235
|
.editor-content-papa {
|
|
230
236
|
/* Stack pre + textarea in one cell so both share the content-sized box */
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, onBeforeUnmount, ref, watch } from 'vue'
|
|
3
|
+
import { Dropdown, EmptyState, Icon, TabsNav, TextInput } from '@bagelink/vue'
|
|
4
|
+
import { FONT_AWESOME_BRANDS_ICONS, FONT_AWESOME_ICONS, MATERIAL_ICONS } from '../../Icon/constants'
|
|
5
|
+
|
|
6
|
+
defineProps<{
|
|
7
|
+
modelValue?: string
|
|
8
|
+
label?: string
|
|
9
|
+
placeholder?: string
|
|
10
|
+
}>()
|
|
11
|
+
|
|
12
|
+
const emit = defineEmits<{
|
|
13
|
+
'update:modelValue': [value: string | undefined]
|
|
14
|
+
}>()
|
|
15
|
+
|
|
16
|
+
const dropdown = ref<InstanceType<typeof Dropdown> | null>(null)
|
|
17
|
+
const search = ref('')
|
|
18
|
+
const activeTab = ref<'material' | 'fa' | 'brands'>('material')
|
|
19
|
+
const visibleCount = ref(80)
|
|
20
|
+
const tabsGroup = `icon-picker-${Math.random().toString(36).slice(2)}`
|
|
21
|
+
let batchTimer: ReturnType<typeof setTimeout> | undefined
|
|
22
|
+
|
|
23
|
+
const tabs = [
|
|
24
|
+
{ label: 'Material', value: 'material' },
|
|
25
|
+
{ label: 'FA', value: 'fa' },
|
|
26
|
+
{ label: 'Brands', value: 'brands' },
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
const iconSets = {
|
|
30
|
+
material: MATERIAL_ICONS,
|
|
31
|
+
fa: FONT_AWESOME_ICONS,
|
|
32
|
+
brands: FONT_AWESOME_BRANDS_ICONS,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const filteredIcons = computed(() => {
|
|
36
|
+
const query = search.value.trim().toLowerCase()
|
|
37
|
+
const icons = iconSets[activeTab.value]
|
|
38
|
+
return query ? icons.filter(icon => icon.includes(query)) : icons
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const visibleIcons = computed(() => filteredIcons.value.slice(0, visibleCount.value))
|
|
42
|
+
|
|
43
|
+
function loadMore() {
|
|
44
|
+
if (visibleCount.value >= filteredIcons.value.length) return
|
|
45
|
+
batchTimer = setTimeout(() => {
|
|
46
|
+
visibleCount.value = Math.min(visibleCount.value + 80, filteredIcons.value.length)
|
|
47
|
+
loadMore()
|
|
48
|
+
}, 16)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function resetAndLoad() {
|
|
52
|
+
if (batchTimer) clearTimeout(batchTimer)
|
|
53
|
+
visibleCount.value = 80
|
|
54
|
+
loadMore()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function select(icon: string) {
|
|
58
|
+
emit('update:modelValue', icon)
|
|
59
|
+
dropdown.value?.hide()
|
|
60
|
+
search.value = ''
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function clear() {
|
|
64
|
+
emit('update:modelValue', undefined)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
watch([activeTab, search], resetAndLoad)
|
|
68
|
+
onBeforeUnmount(() => {
|
|
69
|
+
if (batchTimer) clearTimeout(batchTimer)
|
|
70
|
+
})
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<template>
|
|
74
|
+
<div class="bagel-input">
|
|
75
|
+
<label v-if="label" class="block txt12 medium pb-025">{{ label }}</label>
|
|
76
|
+
<Dropdown
|
|
77
|
+
ref="dropdown"
|
|
78
|
+
placement="bottom-start"
|
|
79
|
+
:auto-hide="true"
|
|
80
|
+
@show="resetAndLoad"
|
|
81
|
+
@hide="search = ''"
|
|
82
|
+
>
|
|
83
|
+
<template #trigger="{ shown, show, hide }">
|
|
84
|
+
<div class="icon-picker-trigger flex gap-05 w-100p bg-input px-075 rounded hover" @click="shown ? hide() : show()">
|
|
85
|
+
<span class="square-20 flex-center flex-shrink-0">
|
|
86
|
+
<Icon v-if="modelValue" :icon="modelValue" :size="1.1" />
|
|
87
|
+
<span v-else class="txt11 opacity-4">—</span>
|
|
88
|
+
</span>
|
|
89
|
+
<span class="txt12 flex-grow opacity-6 ellipsis-1">{{ modelValue || placeholder || 'Choose an icon' }}</span>
|
|
90
|
+
<Icon v-if="modelValue" icon="close" :size="0.9" class="opacity-5 hover-opacity-10" @click.stop="clear" />
|
|
91
|
+
<Icon :icon="shown ? 'expand_less' : 'expand_more'" :size="1" class="opacity-4" />
|
|
92
|
+
</div>
|
|
93
|
+
</template>
|
|
94
|
+
|
|
95
|
+
<div class="w-300px overflow-hidden">
|
|
96
|
+
<TabsNav v-model="activeTab" :tabs="tabs" :group="tabsGroup" flat class="round-none w-100p mx-0 txt-center" />
|
|
97
|
+
<TextInput v-model="search" icon-start="search" placeholder="Search icons" class="mb-0" />
|
|
98
|
+
<div class="grid grid-wrap-7 gap-025 p-05 overflow max-h-300px">
|
|
99
|
+
<div
|
|
100
|
+
v-for="icon in visibleIcons"
|
|
101
|
+
:key="icon"
|
|
102
|
+
class="square-40 flex-center hover rounded relative overflow-hidden"
|
|
103
|
+
:class="modelValue === icon ? 'bg-primary-light color-primary' : 'bg-box'"
|
|
104
|
+
:title="icon"
|
|
105
|
+
@click="select(icon)"
|
|
106
|
+
>
|
|
107
|
+
<Icon :icon="icon" :size="1.2" />
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
<EmptyState v-if="visibleIcons.length === 0" compact icon="none" description="No icons found" />
|
|
111
|
+
</div>
|
|
112
|
+
</Dropdown>
|
|
113
|
+
</div>
|
|
114
|
+
</template>
|
|
115
|
+
|
|
116
|
+
<style scoped>
|
|
117
|
+
.icon-picker-trigger {
|
|
118
|
+
height: var(--bgl-input-height);
|
|
119
|
+
}
|
|
120
|
+
</style>
|
|
@@ -7,6 +7,7 @@ export { default as ColorInput } from './ColorInput.vue'
|
|
|
7
7
|
export { default as DateInput } from './DateInput.vue'
|
|
8
8
|
export { default as DatePicker } from './DatePicker.vue'
|
|
9
9
|
export { default as EmailInput } from './EmailInput.vue'
|
|
10
|
+
export { default as IconPickerInput } from './IconPickerInput.vue'
|
|
10
11
|
export { default as MarkdownEditor } from './MarkdownEditor.vue'
|
|
11
12
|
export { default as NumberInput } from './NumberInput.vue'
|
|
12
13
|
export { default as OTP } from './OTP.vue'
|
|
@@ -434,6 +434,9 @@ padding-inline: 0.75rem;
|
|
|
434
434
|
.pageContent--border {
|
|
435
435
|
padding-top: 1rem;
|
|
436
436
|
}
|
|
437
|
+
.pageContent--border:has(.pageContentFull) {
|
|
438
|
+
padding: 0rem;
|
|
439
|
+
}
|
|
437
440
|
.pageContent--card {
|
|
438
441
|
padding-top: 0.25rem;
|
|
439
442
|
}
|
|
@@ -445,6 +448,9 @@ padding-top: 0;
|
|
|
445
448
|
.pageContent--m-border {
|
|
446
449
|
padding-top: 0.25rem;
|
|
447
450
|
}
|
|
451
|
+
.pageContent:has(.p-0) {
|
|
452
|
+
padding-block: 0rem !important;
|
|
453
|
+
}
|
|
448
454
|
.pageContent--m-card {
|
|
449
455
|
padding-top: 0.25rem;
|
|
450
456
|
}
|
|
@@ -7,6 +7,7 @@ import CodeEditor from '../components/form/inputs/CodeEditor/Index.vue'
|
|
|
7
7
|
import ColorInput from '../components/form/inputs/ColorInput.vue'
|
|
8
8
|
import DateInput from '../components/form/inputs/DateInput.vue'
|
|
9
9
|
import EmailInput from '../components/form/inputs/EmailInput.vue'
|
|
10
|
+
import IconPickerInput from '../components/form/inputs/IconPickerInput.vue'
|
|
10
11
|
import NumberInput from '../components/form/inputs/NumberInput.vue'
|
|
11
12
|
import PasswordInput from '../components/form/inputs/PasswordInput.vue'
|
|
12
13
|
import RadioGroup from '../components/form/inputs/RadioGroup.vue'
|
|
@@ -283,6 +284,7 @@ function getFieldComponent(fieldOrType: FieldBuilder | string) {
|
|
|
283
284
|
array: ArrayInput,
|
|
284
285
|
upload: UploadInput,
|
|
285
286
|
color: ColorInput,
|
|
287
|
+
icon: IconPickerInput,
|
|
286
288
|
range: RangeInput,
|
|
287
289
|
}
|
|
288
290
|
|
|
@@ -371,6 +371,10 @@ export const $ = {
|
|
|
371
371
|
return new Field('color', parseArgs(labelOrConfig, config))
|
|
372
372
|
},
|
|
373
373
|
|
|
374
|
+
icon(labelOrConfig?: string | BaseFieldConfig, config?: BaseFieldConfig): FieldBuilder<string> {
|
|
375
|
+
return new Field('icon', parseArgs(labelOrConfig, config))
|
|
376
|
+
},
|
|
377
|
+
|
|
374
378
|
range(
|
|
375
379
|
labelOrConfig?: string | (BaseFieldConfig & { min?: number, max?: number, step?: number, multiRange?: boolean }),
|
|
376
380
|
config?: BaseFieldConfig & { min?: number, max?: number, step?: number, multiRange?: boolean }
|
|
@@ -1031,6 +1035,9 @@ function createFieldFromProperty(
|
|
|
1031
1035
|
case 'multiselect':
|
|
1032
1036
|
field = $.multiselect(xOptions ?? resolvedProp.enum ?? [], config)
|
|
1033
1037
|
break
|
|
1038
|
+
case 'icon':
|
|
1039
|
+
field = $.icon(config)
|
|
1040
|
+
break
|
|
1034
1041
|
case 'file':
|
|
1035
1042
|
case 'upload':
|
|
1036
1043
|
field = $.upload(config)
|