@bagelink/vue 1.9.83 → 1.9.86
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/Avatar.vue.d.ts +1 -0
- package/dist/components/Avatar.vue.d.ts.map +1 -1
- package/dist/components/Badge.vue.d.ts +0 -1
- package/dist/components/Badge.vue.d.ts.map +1 -1
- package/dist/components/Btn.vue.d.ts.map +1 -1
- package/dist/components/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/Loading.vue.d.ts +2 -1
- package/dist/components/Loading.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/index.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 +9 -9
- package/dist/form-flow/form-flow.d.ts.map +1 -1
- package/dist/index.cjs +163 -85
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +25737 -25545
- package/dist/plugins/useToast.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/dist/utils/filterRef.d.ts +15 -0
- package/dist/utils/filterRef.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/Avatar.vue +6 -2
- package/src/components/Badge.vue +14 -1084
- package/src/components/Btn.vue +37 -37
- package/src/components/Dropdown.vue +1 -1
- package/src/components/Loading.vue +15 -6
- package/src/components/form/inputs/RichText/index.vue +325 -221
- package/src/form-flow/FormFlow.vue +9 -0
- package/src/form-flow/form-flow.ts +13 -3
- package/src/index.ts +1 -1
- package/src/plugins/useToast.ts +14 -0
- package/src/styles/bagel.css +1 -0
- package/src/styles/base-colors.css +1429 -46
- package/src/styles/text.css +1755 -1755
- package/src/styles/toast-overrides.css +10 -0
- package/src/utils/filterRef.ts +133 -0
- package/src/styles/btnColors.css +0 -847
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/* Reset popover container used to promote toasts above showModal() dialogs */
|
|
2
|
+
#bgl-toast-container {
|
|
3
|
+
all: unset;
|
|
4
|
+
pointer-events: none;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
#bgl-toast-container > * {
|
|
8
|
+
pointer-events: auto;
|
|
9
|
+
}
|
|
10
|
+
|
|
1
11
|
/* Override vue-toastification default styles */
|
|
2
12
|
.custom-toast-wrapper {
|
|
3
13
|
padding: 0 !important;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { Ref } from 'vue'
|
|
2
|
+
import { computed, isRef, shallowReactive } from 'vue'
|
|
3
|
+
|
|
4
|
+
const htmlReplacers = {
|
|
5
|
+
'': /<[^>]*>?/g,
|
|
6
|
+
' ': / /g,
|
|
7
|
+
'"': /"/g,
|
|
8
|
+
'\'': /'/g,
|
|
9
|
+
'&': /&/g,
|
|
10
|
+
'<': /</g,
|
|
11
|
+
'>': />/g,
|
|
12
|
+
} as const
|
|
13
|
+
|
|
14
|
+
function clearHtml(value?: string): string {
|
|
15
|
+
if (!value) { return '' }
|
|
16
|
+
return Object.entries(htmlReplacers).reduce(
|
|
17
|
+
(text, [replacement, regex]) => text.replace(regex, replacement),
|
|
18
|
+
value
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const normalizeSearchChars = /[\p{N}\p{L}\s]/gu
|
|
23
|
+
function normalizeText(text: string): string {
|
|
24
|
+
return text.match(normalizeSearchChars)?.join('').toLowerCase() ?? ''
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function getValueByPath(obj: any, path: string): any {
|
|
28
|
+
let result = obj
|
|
29
|
+
for (const key of path.split('.')) {
|
|
30
|
+
if (result === null || result === undefined || typeof result !== 'object') { return undefined }
|
|
31
|
+
result = result[key]
|
|
32
|
+
}
|
|
33
|
+
return result
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function collectAllLeafPaths(obj: any, prefix = ''): string[] {
|
|
37
|
+
if (!obj || typeof obj !== 'object') { return [] }
|
|
38
|
+
return Object.keys(obj).flatMap((key) => {
|
|
39
|
+
const value = obj[key]
|
|
40
|
+
const path = prefix ? `${prefix}.${key}` : key
|
|
41
|
+
if (value && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)) {
|
|
42
|
+
return collectAllLeafPaths(value, path)
|
|
43
|
+
}
|
|
44
|
+
return [path]
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function toSearchableString(value: unknown): string {
|
|
49
|
+
if (value === null || value === undefined) { return '' }
|
|
50
|
+
if (typeof value === 'string') { return clearHtml(value) }
|
|
51
|
+
if (typeof value === 'number' || typeof value === 'boolean') { return String(value) }
|
|
52
|
+
if (value instanceof Date) { return value.toISOString() }
|
|
53
|
+
return ''
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface FilterRefOptions<Item extends Record<string, any>> {
|
|
57
|
+
filter?: Ref<(item: Item) => boolean> | ((item: Item) => boolean)
|
|
58
|
+
/** Dot-path keys to index (e.g. 'user.address.city'). Defaults to all leaf fields. */
|
|
59
|
+
keys?: string[]
|
|
60
|
+
minChars?: number
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function filterRef<T extends Record<string, any>[]>(
|
|
64
|
+
initialValue: T = [] as unknown as T,
|
|
65
|
+
options: FilterRefOptions<T[number]> = {}
|
|
66
|
+
) {
|
|
67
|
+
type Item = T[number]
|
|
68
|
+
const { minChars = 1 } = options
|
|
69
|
+
const state = shallowReactive({ _list: initialValue as Item[], searchTerm: '' })
|
|
70
|
+
|
|
71
|
+
let searchIndex: string[] = []
|
|
72
|
+
|
|
73
|
+
function buildIndexEntry(item: Item, seen = new WeakSet()): string {
|
|
74
|
+
if (seen.has(item as object)) { return '' }
|
|
75
|
+
seen.add(item as object)
|
|
76
|
+
|
|
77
|
+
const paths = options.keys ?? collectAllLeafPaths(item)
|
|
78
|
+
const parts: string[] = []
|
|
79
|
+
for (const path of paths) {
|
|
80
|
+
const value = getValueByPath(item, path)
|
|
81
|
+
if (Array.isArray(value)) {
|
|
82
|
+
for (const el of value) {
|
|
83
|
+
if (el && typeof el === 'object' && !(el instanceof Date)) {
|
|
84
|
+
parts.push(buildIndexEntry(el as Item, seen))
|
|
85
|
+
} else {
|
|
86
|
+
const s = toSearchableString(el)
|
|
87
|
+
if (s) { parts.push(normalizeText(s)) }
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
const s = toSearchableString(value)
|
|
92
|
+
if (s) { parts.push(normalizeText(s)) }
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return parts.join(' ')
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function buildIndex(list: Item[]) {
|
|
99
|
+
searchIndex = list.map(item => buildIndexEntry(item))
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
buildIndex(initialValue as Item[])
|
|
103
|
+
|
|
104
|
+
const filtered = computed(() => {
|
|
105
|
+
let result = state._list
|
|
106
|
+
|
|
107
|
+
if (state.searchTerm.length >= minChars) {
|
|
108
|
+
const terms = normalizeText(state.searchTerm).split(/\s+/).filter(t => t.length > 0)
|
|
109
|
+
if (terms.length > 0) {
|
|
110
|
+
result = result.filter((_, i) => {
|
|
111
|
+
const entry = searchIndex[i] ?? ''
|
|
112
|
+
return terms.every(term => entry.includes(term))
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (options.filter) {
|
|
118
|
+
const fn = isRef(options.filter) ? options.filter.value : options.filter
|
|
119
|
+
result = result.filter(fn)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return result
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
get searchTerm() { return state.searchTerm },
|
|
127
|
+
set searchTerm(v: string) { state.searchTerm = v },
|
|
128
|
+
get value() { return filtered.value },
|
|
129
|
+
set value(v: Item[]) { state._list = v; buildIndex(v) },
|
|
130
|
+
get length() { return filtered.value.length },
|
|
131
|
+
[Symbol.iterator](): IterableIterator<Item> { return filtered.value[Symbol.iterator]() },
|
|
132
|
+
}
|
|
133
|
+
}
|