@bagelink/vue 1.9.81 → 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.
Files changed (40) hide show
  1. package/dist/components/Avatar.vue.d.ts +1 -0
  2. package/dist/components/Avatar.vue.d.ts.map +1 -1
  3. package/dist/components/Badge.vue.d.ts +0 -1
  4. package/dist/components/Badge.vue.d.ts.map +1 -1
  5. package/dist/components/Btn.vue.d.ts.map +1 -1
  6. package/dist/components/Dropdown.vue.d.ts.map +1 -1
  7. package/dist/components/Loading.vue.d.ts +2 -1
  8. package/dist/components/Loading.vue.d.ts.map +1 -1
  9. package/dist/components/form/inputs/RadioGroup.vue.d.ts +12 -3
  10. package/dist/components/form/inputs/RadioGroup.vue.d.ts.map +1 -1
  11. package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
  12. package/dist/form-flow/FormFlow.vue.d.ts.map +1 -1
  13. package/dist/form-flow/form-flow.d.ts +9 -9
  14. package/dist/form-flow/form-flow.d.ts.map +1 -1
  15. package/dist/index.cjs +165 -87
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.mjs +26221 -26015
  19. package/dist/plugins/useToast.d.ts.map +1 -1
  20. package/dist/style.css +1 -1
  21. package/dist/utils/filterRef.d.ts +15 -0
  22. package/dist/utils/filterRef.d.ts.map +1 -0
  23. package/package.json +1 -1
  24. package/src/components/Avatar.vue +6 -2
  25. package/src/components/Badge.vue +14 -1084
  26. package/src/components/Btn.vue +37 -37
  27. package/src/components/Dropdown.vue +1 -1
  28. package/src/components/Loading.vue +15 -7
  29. package/src/components/form/inputs/RadioGroup.vue +24 -13
  30. package/src/components/form/inputs/RichText/index.vue +325 -221
  31. package/src/form-flow/FormFlow.vue +9 -0
  32. package/src/form-flow/form-flow.ts +13 -3
  33. package/src/index.ts +1 -1
  34. package/src/plugins/useToast.ts +14 -0
  35. package/src/styles/bagel.css +1 -0
  36. package/src/styles/base-colors.css +1429 -46
  37. package/src/styles/text.css +1755 -1755
  38. package/src/styles/toast-overrides.css +10 -0
  39. package/src/utils/filterRef.ts +133 -0
  40. 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
+ ' ': /&nbsp;/g,
7
+ '"': /&quot;/g,
8
+ '\'': /&apos;/g,
9
+ '&': /&amp;/g,
10
+ '<': /&lt;/g,
11
+ '>': /&gt;/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
+ }