@bagelink/vue 1.17.2 → 1.17.6
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/assetTransport.d.ts +9 -31
- package/dist/assetTransport.d.ts.map +1 -1
- package/dist/assets.d.ts +39 -20
- package/dist/assets.d.ts.map +1 -1
- package/dist/components/AddressSearch.vue.d.ts +40 -36
- package/dist/components/AddressSearch.vue.d.ts.map +1 -1
- package/dist/components/ContextMenu.vue.d.ts +518 -0
- package/dist/components/ContextMenu.vue.d.ts.map +1 -0
- package/dist/components/Dropdown.types.d.ts +25 -0
- package/dist/components/Dropdown.types.d.ts.map +1 -0
- package/dist/components/Dropdown.vue.d.ts +20 -15
- package/dist/components/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/FilterQuery.vue.d.ts +1 -1
- package/dist/components/FilterQuery.vue.d.ts.map +1 -1
- package/dist/components/Icon/Icon.vue.d.ts +0 -1
- package/dist/components/Icon/Icon.vue.d.ts.map +1 -1
- package/dist/components/Icon/constants.d.ts +0 -1
- package/dist/components/Icon/constants.d.ts.map +1 -1
- package/dist/components/Icon/types.d.ts +2 -3
- package/dist/components/Icon/types.d.ts.map +1 -1
- package/dist/components/Swiper.vue.d.ts +1 -1
- package/dist/components/draggable/useDraggable.d.ts.map +1 -1
- package/dist/components/form/inputs/IconPickerInput.vue.d.ts +48 -37
- package/dist/components/form/inputs/IconPickerInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/components/EditorToolbar.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/composables/useCommands.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/composables/useEditor.d.ts +3 -0
- package/dist/components/form/inputs/RichText/composables/useEditor.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/composables/useEditorKeyboard.d.ts +1 -1
- package/dist/components/form/inputs/RichText/composables/useEditorKeyboard.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/commands.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/selection.d.ts +2 -0
- package/dist/components/form/inputs/RichText/utils/selection.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/table.d.ts +34 -8
- package/dist/components/form/inputs/RichText/utils/table.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts +71 -63
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TelInput.vue.d.ts +2 -2
- package/dist/components/index.d.ts +3 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/composables/index.d.ts +1 -1
- package/dist/composables/index.d.ts.map +1 -1
- package/dist/composables/useBoundedRectDrag.d.ts.map +1 -1
- package/dist/composables/usePointerSession.d.ts +14 -3
- package/dist/composables/usePointerSession.d.ts.map +1 -1
- package/dist/core.css +3 -3
- package/dist/directives/vResize.d.ts.map +1 -1
- package/dist/form-flow/form-flow.d.ts +4 -2
- package/dist/form-flow/form-flow.d.ts.map +1 -1
- package/dist/form-flow/schema-fields.d.ts +4 -1
- package/dist/form-flow/schema-fields.d.ts.map +1 -1
- package/dist/index.cjs +240 -153
- package/dist/index.css +1 -1
- package/dist/index.mjs +18459 -18281
- package/dist/style.css +3 -3
- package/dist/types/BagelForm.d.ts +2 -0
- package/dist/types/BagelForm.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/assetTransport.test.ts +33 -83
- package/src/assetTransport.ts +24 -90
- package/src/assets.test.ts +58 -99
- package/src/assets.ts +78 -161
- package/src/components/ContextMenu.vue +113 -0
- package/src/components/Dropdown.types.ts +27 -0
- package/src/components/Dropdown.vue +129 -64
- package/src/components/FilterQuery.vue +1 -1
- package/src/components/Icon/Icon.vue +8 -30
- package/src/components/Icon/constants.ts +0 -166
- package/src/components/Icon/types.ts +2 -3
- package/src/components/draggable/useDraggable.ts +67 -100
- package/src/components/form/inputs/IconPickerInput.vue +14 -9
- package/src/components/form/inputs/RichText/components/EditorToolbar.vue +43 -111
- package/src/components/form/inputs/RichText/composables/useCommands.ts +32 -54
- package/src/components/form/inputs/RichText/composables/useEditor.ts +45 -171
- package/src/components/form/inputs/RichText/composables/useEditorKeyboard.ts +90 -14
- package/src/components/form/inputs/RichText/index.vue +1195 -1210
- package/src/components/form/inputs/RichText/utils/commands.ts +689 -1028
- package/src/components/form/inputs/RichText/utils/selection.ts +66 -41
- package/src/components/form/inputs/RichText/utils/table.ts +798 -136
- package/src/components/form/inputs/SelectInput.vue +1 -1
- package/src/components/form/inputs/Upload/AssetUploadInput.vue +2 -2
- package/src/components/index.ts +3 -1
- package/src/composables/index.ts +1 -1
- package/src/composables/useBoundedRectDrag.ts +9 -12
- package/src/composables/usePointerSession.ts +57 -12
- package/src/directives/vResize.ts +6 -7
- package/src/form-flow/form-flow.ts +8 -3
- package/src/form-flow/schema-fields.ts +9 -4
- package/src/styles/core.css +1 -18
- package/src/types/BagelForm.ts +2 -0
- package/dist/components/form/inputs/RichText/utils/formatting.d.ts +0 -10
- package/dist/components/form/inputs/RichText/utils/formatting.d.ts.map +0 -1
- package/src/components/form/inputs/RichText/components/gridBox.vue +0 -58
- package/src/components/form/inputs/RichText/utils/formatting.ts +0 -331
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import type { IconType, Option } from '../../../index'
|
|
3
|
-
import type { AlignedPlacement } from '../../Dropdown.
|
|
3
|
+
import type { AlignedPlacement } from '../../Dropdown.types'
|
|
4
4
|
import { Btn, Card, Skeleton, Dropdown, Icon, TextInput, useSearch, useI18n, resolveI18n } from '../../../index'
|
|
5
5
|
import { computed, onMounted, ref, useId, watch } from 'vue'
|
|
6
6
|
import { getOptionIcon, getOptionLabel, getOptionSubtitle, getOptionValue } from '../../../utils/options'
|
|
@@ -33,7 +33,7 @@ const { browse, addFile, fileQueue } = useFileUpload({
|
|
|
33
33
|
const next = props.multiple ? [...values.value] : []
|
|
34
34
|
try {
|
|
35
35
|
for (const item of props.multiple ? queued : queued.slice(0, 1)) {
|
|
36
|
-
next.push(await upload(item.file))
|
|
36
|
+
next.push(await upload(item.file, { visibility: props.assetVisibility }))
|
|
37
37
|
output([...next])
|
|
38
38
|
}
|
|
39
39
|
} catch (error) {
|
|
@@ -53,7 +53,7 @@ onScopeDispose(() => {
|
|
|
53
53
|
<template>
|
|
54
54
|
<Card outline class="flex column gap-1 p-1" v-on="handlers">
|
|
55
55
|
<label v-if="label">{{ label }}</label>
|
|
56
|
-
<div v-for="(value, index) in values" :key="
|
|
56
|
+
<div v-for="(value, index) in values" :key="value.asset_id" class="flex gap-1 align-items-center">
|
|
57
57
|
<Image v-if="accept?.startsWith('image/')" :src="value" width="80" height="80" />
|
|
58
58
|
<span class="ellipsis-1">{{ value.asset_id }}</span>
|
|
59
59
|
<Btn v-if="!readonly" flat icon="close" :disabled="disabled" aria-label="Remove attachment"
|
package/src/components/index.ts
CHANGED
|
@@ -19,6 +19,8 @@ export { default as DragOver } from './DragOver.vue'
|
|
|
19
19
|
export { useFileDropzone } from './file-drop/useFileDropzone'
|
|
20
20
|
export type { UseFileDropzoneOptions } from './file-drop/useFileDropzone'
|
|
21
21
|
export { default as Dropdown } from './Dropdown.vue'
|
|
22
|
+
export type { AlignedPlacement, AnchorPoint, DropdownItem } from './Dropdown.types'
|
|
23
|
+
export { default as ContextMenu } from './ContextMenu.vue'
|
|
22
24
|
export { default as EmptyState } from './EmptyState.vue'
|
|
23
25
|
export { default as FieldSetVue } from './FieldSetVue.vue'
|
|
24
26
|
export { default as KanbanBoard } from './kanban/KanbanBoard.vue'
|
|
@@ -30,7 +32,7 @@ export { default as FlipBook } from './FlipBook.vue'
|
|
|
30
32
|
export { default as FloatingPanel } from './FloatingPanel.vue'
|
|
31
33
|
export * from './form'
|
|
32
34
|
export { default as Icon } from './Icon/Icon.vue'
|
|
33
|
-
export {
|
|
35
|
+
export { FONT_AWESOME_BRANDS_ICONS, MATERIAL_ICONS } from './Icon/constants'
|
|
34
36
|
export { default as IframeVue } from './IframeVue.vue'
|
|
35
37
|
export { default as Image } from './Image.vue'
|
|
36
38
|
export * from './layout'
|
package/src/composables/index.ts
CHANGED
|
@@ -16,7 +16,7 @@ export { useImageSrc } from './useImageSrc'
|
|
|
16
16
|
export { useLocalStore } from './useLocalStore'
|
|
17
17
|
export { usePolling } from './usePolling'
|
|
18
18
|
export { createPointerSession, usePointerSession } from './usePointerSession'
|
|
19
|
-
export type { PointerSessionOptions } from './usePointerSession'
|
|
19
|
+
export type { PointerSessionMovePayload, PointerSessionOptions } from './usePointerSession'
|
|
20
20
|
export { resizeRect, snapGridDelta } from './resizeGeometry'
|
|
21
21
|
export type { ResizeRect } from './resizeGeometry'
|
|
22
22
|
export { usePrefersReducedMotion } from './usePrefersReducedMotion'
|
|
@@ -29,18 +29,14 @@ export function useBoundedRectDrag() {
|
|
|
29
29
|
if (!Number.isFinite(scale) || scale <= 0) return false
|
|
30
30
|
const initial = { ...options.rect }
|
|
31
31
|
const bounds = { ...options.bounds }
|
|
32
|
-
const startX = event.clientX
|
|
33
|
-
const startY = event.clientY
|
|
34
32
|
let moved = false
|
|
35
33
|
let previewed = false
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (!moved && Math.hypot(clientDx, clientDy) < (options.threshold ?? 0)) return
|
|
40
|
-
if (!moved && clientDx === 0 && clientDy === 0) return
|
|
34
|
+
function applyMove(dxClient: number, dyClient: number) {
|
|
35
|
+
if (!moved && Math.hypot(dxClient, dyClient) < (options.threshold ?? 0)) return
|
|
36
|
+
if (!moved && dxClient === 0 && dyClient === 0) return
|
|
41
37
|
moved = true
|
|
42
|
-
const dx =
|
|
43
|
-
const dy =
|
|
38
|
+
const dx = dxClient / scale
|
|
39
|
+
const dy = dyClient / scale
|
|
44
40
|
const rect = options.mode === 'resize'
|
|
45
41
|
? resizeRect(initial, { x: dx, y: dy }, 'se', bounds, { width: options.minWidth ?? 0, height: options.minHeight ?? 0 })
|
|
46
42
|
: {
|
|
@@ -52,9 +48,10 @@ export function useBoundedRectDrag() {
|
|
|
52
48
|
options.onUpdate(rect)
|
|
53
49
|
}
|
|
54
50
|
const started = session.start(event, {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
threshold: options.threshold,
|
|
52
|
+
onMove: (_next, { dx, dy }) => applyMove(dx, dy),
|
|
53
|
+
onEnd: (_next, { dx, dy }) => {
|
|
54
|
+
try { applyMove(dx, dy); options.onCommit?.(moved) } finally { active.value = false }
|
|
58
55
|
},
|
|
59
56
|
onCancel: () => {
|
|
60
57
|
active.value = false
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { getCurrentScope, onScopeDispose } from 'vue'
|
|
2
2
|
|
|
3
|
+
export interface PointerSessionMovePayload {
|
|
4
|
+
dx: number
|
|
5
|
+
dy: number
|
|
6
|
+
distance: number
|
|
7
|
+
exceededThreshold: boolean
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
export interface PointerSessionOptions {
|
|
4
11
|
cursor?: string
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
12
|
+
/** Optional distance in client pixels before `exceededThreshold` becomes true. */
|
|
13
|
+
threshold?: number
|
|
14
|
+
/** Override the target element or document when starting from a delegated listener. */
|
|
15
|
+
target?: Element | Document | null
|
|
16
|
+
onThreshold?: (event: PointerEvent, payload: PointerSessionMovePayload) => void
|
|
17
|
+
onMove: (event: PointerEvent, payload: PointerSessionMovePayload) => void
|
|
18
|
+
/** Commit receives the release coordinates and movement summary, even when no move event preceded it. */
|
|
19
|
+
onEnd?: (event: PointerEvent, payload: PointerSessionMovePayload) => void
|
|
8
20
|
onCancel?: () => void
|
|
9
21
|
}
|
|
10
22
|
|
|
@@ -14,17 +26,46 @@ export function createPointerSession() {
|
|
|
14
26
|
function cancel() { finish?.() }
|
|
15
27
|
function start(event: PointerEvent, options: PointerSessionOptions): boolean {
|
|
16
28
|
if (finish || event.button !== 0 || event.isPrimary === false) return false
|
|
17
|
-
const
|
|
18
|
-
const doc =
|
|
29
|
+
const rawTarget = (options.target ?? event.currentTarget ?? event.target) as Element | Document | null
|
|
30
|
+
const doc = rawTarget && 'ownerDocument' in rawTarget
|
|
31
|
+
? (rawTarget.ownerDocument ?? (rawTarget as unknown as Document))
|
|
32
|
+
: (rawTarget as Document | null)
|
|
33
|
+
const targetEl = rawTarget && 'ownerDocument' in rawTarget && rawTarget.ownerDocument
|
|
34
|
+
? (rawTarget as Element)
|
|
35
|
+
: null
|
|
19
36
|
const view = doc?.defaultView
|
|
20
37
|
if (!view) return false
|
|
38
|
+
|
|
21
39
|
const id = event.pointerId
|
|
40
|
+
const startX = event.clientX
|
|
41
|
+
const startY = event.clientY
|
|
42
|
+
const threshold = options.threshold ?? 0
|
|
43
|
+
let exceededThreshold = threshold <= 0
|
|
44
|
+
|
|
22
45
|
const style = doc.body?.style
|
|
23
46
|
const cursor = style?.cursor ?? ''
|
|
24
47
|
const selection = style?.userSelect ?? ''
|
|
48
|
+
|
|
49
|
+
function buildPayload(next: PointerEvent): PointerSessionMovePayload {
|
|
50
|
+
const dx = (next.clientX ?? startX) - startX
|
|
51
|
+
const dy = (next.clientY ?? startY) - startY
|
|
52
|
+
const distance = Math.hypot(dx, dy)
|
|
53
|
+
if (!exceededThreshold && distance > threshold) {
|
|
54
|
+
exceededThreshold = true
|
|
55
|
+
options.onThreshold?.(next, { dx, dy, distance, exceededThreshold: true })
|
|
56
|
+
}
|
|
57
|
+
return { dx, dy, distance, exceededThreshold }
|
|
58
|
+
}
|
|
59
|
+
|
|
25
60
|
function move(next: PointerEvent) {
|
|
26
61
|
if (next.pointerId !== id) return
|
|
27
|
-
try {
|
|
62
|
+
try {
|
|
63
|
+
const payload = buildPayload(next)
|
|
64
|
+
options.onMove(next, payload)
|
|
65
|
+
} catch (error) {
|
|
66
|
+
cancel()
|
|
67
|
+
throw error
|
|
68
|
+
}
|
|
28
69
|
}
|
|
29
70
|
function up(next: PointerEvent) { if (next.pointerId === id) finish?.(next) }
|
|
30
71
|
function interrupted(next: PointerEvent) { if (next.pointerId === id) cancel() }
|
|
@@ -38,13 +79,17 @@ export function createPointerSession() {
|
|
|
38
79
|
view!.removeEventListener('pointercancel', interrupted)
|
|
39
80
|
view!.removeEventListener('blur', cancel)
|
|
40
81
|
view!.removeEventListener('keydown', keydown)
|
|
41
|
-
|
|
82
|
+
targetEl?.removeEventListener('lostpointercapture', interrupted as EventListener)
|
|
42
83
|
try {
|
|
43
|
-
if (
|
|
84
|
+
if (targetEl?.hasPointerCapture?.(id)) targetEl.releasePointerCapture(id)
|
|
44
85
|
} catch { /* Detached targets may already have lost capture. */ }
|
|
45
86
|
if (style) { style.cursor = cursor; style.userSelect = selection }
|
|
46
|
-
if (next)
|
|
47
|
-
|
|
87
|
+
if (next) {
|
|
88
|
+
const payload = buildPayload(next)
|
|
89
|
+
options.onEnd?.(next, payload)
|
|
90
|
+
} else {
|
|
91
|
+
options.onCancel?.()
|
|
92
|
+
}
|
|
48
93
|
}
|
|
49
94
|
event.preventDefault()
|
|
50
95
|
if (style) {
|
|
@@ -56,8 +101,8 @@ export function createPointerSession() {
|
|
|
56
101
|
view.addEventListener('pointercancel', interrupted)
|
|
57
102
|
view.addEventListener('blur', cancel)
|
|
58
103
|
view.addEventListener('keydown', keydown)
|
|
59
|
-
|
|
60
|
-
try {
|
|
104
|
+
targetEl?.addEventListener('lostpointercapture', interrupted as EventListener)
|
|
105
|
+
try { targetEl?.setPointerCapture?.(id) } catch { /* Window listeners remain a capture fallback. */ }
|
|
61
106
|
return true
|
|
62
107
|
}
|
|
63
108
|
return { start, cancel }
|
|
@@ -47,8 +47,8 @@ function initResize(el: HTMLElement, binding: { value?: ResizeOptions }) {
|
|
|
47
47
|
if (options.maxHeight !== undefined) target.setAttribute('aria-valuemax', String(options.maxHeight))
|
|
48
48
|
target.setAttribute('aria-valuenow', String(el.offsetHeight))
|
|
49
49
|
|
|
50
|
-
function update(clientY: number,
|
|
51
|
-
const event = { clientY, deltaY
|
|
50
|
+
function update(clientY: number, deltaY: number, initialHeight: number): ResizeEvent {
|
|
51
|
+
const event = { clientY, deltaY, initialHeight }
|
|
52
52
|
const proposed = initialHeight + event.deltaY
|
|
53
53
|
const snapped = options.gridSize && options.gridSize > 0 ? Math.round(proposed / options.gridSize) * options.gridSize : proposed
|
|
54
54
|
const height = Math.min(options.maxHeight ?? Infinity, Math.max(options.minHeight ?? 0, snapped))
|
|
@@ -61,16 +61,15 @@ function initResize(el: HTMLElement, binding: { value?: ResizeOptions }) {
|
|
|
61
61
|
function handleStart(event: PointerEvent) {
|
|
62
62
|
if (event.button !== 0 || event.isPrimary === false) return
|
|
63
63
|
pointer.cancel()
|
|
64
|
-
const startY = event.clientY
|
|
65
64
|
const initialHeight = el.offsetHeight
|
|
66
65
|
const originalHeight = el.style.height
|
|
67
66
|
const originalValue = target.getAttribute('aria-valuenow')
|
|
68
67
|
options.onStart?.(event)
|
|
69
68
|
pointer.start(event, {
|
|
70
69
|
cursor: 'ns-resize',
|
|
71
|
-
onMove: e => update(e.clientY,
|
|
72
|
-
onEnd(e) {
|
|
73
|
-
const result = update(e.clientY,
|
|
70
|
+
onMove: (e, { dy }) => update(e.clientY, dy, initialHeight),
|
|
71
|
+
onEnd(e, { dy }) {
|
|
72
|
+
const result = update(e.clientY, dy, initialHeight)
|
|
74
73
|
options.onEnd?.(result)
|
|
75
74
|
},
|
|
76
75
|
onCancel() {
|
|
@@ -92,7 +91,7 @@ function initResize(el: HTMLElement, binding: { value?: ResizeOptions }) {
|
|
|
92
91
|
: event.key === 'End' ? options.maxHeight!
|
|
93
92
|
: initialHeight + (event.key === 'ArrowUp' ? -step : step)
|
|
94
93
|
options.onStart?.(event)
|
|
95
|
-
const result = update(height - initialHeight,
|
|
94
|
+
const result = update(height - initialHeight, height - initialHeight, initialHeight)
|
|
96
95
|
options.onEnd?.(result)
|
|
97
96
|
}
|
|
98
97
|
|
|
@@ -416,8 +416,9 @@ export const $ = {
|
|
|
416
416
|
noFilePlaceholder?: string
|
|
417
417
|
btnPlaceholder?: string
|
|
418
418
|
style?: string
|
|
419
|
-
/** Upload to the immutable assets catalog and persist a `{asset_id
|
|
419
|
+
/** Upload to the immutable assets catalog and persist a `{asset_id}` pin. */
|
|
420
420
|
assetMode?: boolean
|
|
421
|
+
assetVisibility?: import('../assets').AssetVisibility
|
|
421
422
|
}),
|
|
422
423
|
config?: BaseFieldConfig & {
|
|
423
424
|
multiple?: boolean
|
|
@@ -434,8 +435,9 @@ export const $ = {
|
|
|
434
435
|
noFilePlaceholder?: string
|
|
435
436
|
btnPlaceholder?: string
|
|
436
437
|
style?: string
|
|
437
|
-
/** Upload to the immutable assets catalog and persist a `{asset_id
|
|
438
|
+
/** Upload to the immutable assets catalog and persist a `{asset_id}` pin. */
|
|
438
439
|
assetMode?: boolean
|
|
440
|
+
assetVisibility?: import('../assets').AssetVisibility
|
|
439
441
|
}
|
|
440
442
|
): FieldBuilder<string | string[]> {
|
|
441
443
|
return new Field('upload', parseArgs(labelOrConfig, config))
|
|
@@ -1248,9 +1250,12 @@ function createFieldFromProperty(
|
|
|
1248
1250
|
case 'file':
|
|
1249
1251
|
case 'upload':
|
|
1250
1252
|
// `x-asset` marks a field as managed by the immutable assets catalog:
|
|
1251
|
-
// the widget uploads and persists a `{asset_id
|
|
1253
|
+
// the widget uploads and persists a `{asset_id}` pin, and
|
|
1252
1254
|
// the JSON-schema type is `object`, not `string`.
|
|
1253
1255
|
if (resolvedProp['x-asset'] === true) config.assetMode = true
|
|
1256
|
+
if (resolvedProp['x-asset-visibility']) {
|
|
1257
|
+
config.assetVisibility = resolvedProp['x-asset-visibility']
|
|
1258
|
+
}
|
|
1254
1259
|
field = $.upload(config)
|
|
1255
1260
|
break
|
|
1256
1261
|
case 'array': {
|
|
@@ -95,8 +95,10 @@ export interface FormField {
|
|
|
95
95
|
fileTheme?: 'dropzone' | 'basic'
|
|
96
96
|
fileShowIcon?: boolean
|
|
97
97
|
fileIcon?: string
|
|
98
|
-
/** Upload to the immutable assets catalog; persist a `{asset_id
|
|
98
|
+
/** Upload to the immutable assets catalog; persist a `{asset_id}` pin. */
|
|
99
99
|
assetMode?: boolean
|
|
100
|
+
/** Asset delivery policy. Omitted assets are protected. */
|
|
101
|
+
assetVisibility?: import('../assets').AssetVisibility
|
|
100
102
|
dateEnableTime?: boolean
|
|
101
103
|
dateMin?: string
|
|
102
104
|
dateMax?: string
|
|
@@ -166,6 +168,7 @@ export interface JSONSchemaProperty {
|
|
|
166
168
|
'x-file-show-icon'?: boolean
|
|
167
169
|
'x-file-icon'?: string
|
|
168
170
|
'x-asset'?: boolean
|
|
171
|
+
'x-asset-visibility'?: import('../assets').AssetVisibility
|
|
169
172
|
'x-date-enable-time'?: boolean
|
|
170
173
|
'x-date-min'?: string
|
|
171
174
|
'x-date-max'?: string
|
|
@@ -355,16 +358,15 @@ export function fieldsToSchema(
|
|
|
355
358
|
break
|
|
356
359
|
case 'file':
|
|
357
360
|
if (field.assetMode === true) {
|
|
358
|
-
//
|
|
361
|
+
// Public-by-default assets catalog: persist a `{asset_id}` pin.
|
|
359
362
|
// The JSON-schema type is `object` (the pin), and `x-asset` is the
|
|
360
363
|
// authoritative marker — never a `string` URL.
|
|
361
364
|
const assetRef = {
|
|
362
365
|
type: 'object',
|
|
363
366
|
properties: {
|
|
364
367
|
asset_id: { type: 'string', format: 'uuid' },
|
|
365
|
-
version_id: { type: 'string', format: 'uuid' },
|
|
366
368
|
},
|
|
367
|
-
required: ['asset_id'
|
|
369
|
+
required: ['asset_id'],
|
|
368
370
|
}
|
|
369
371
|
if (field.fileMultiple === true) {
|
|
370
372
|
prop.type = 'array'
|
|
@@ -373,6 +375,9 @@ export function fieldsToSchema(
|
|
|
373
375
|
Object.assign(prop, assetRef)
|
|
374
376
|
}
|
|
375
377
|
prop['x-asset'] = true
|
|
378
|
+
if (field.assetVisibility) {
|
|
379
|
+
prop['x-asset-visibility'] = field.assetVisibility
|
|
380
|
+
}
|
|
376
381
|
} else if (field.fileMultiple === true) {
|
|
377
382
|
prop.type = 'array'
|
|
378
383
|
prop.items = { type: 'string' }
|
package/src/styles/core.css
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* Font-neutral Bagel UI stylesheet for public/customer sites.
|
|
2
2
|
Apps choose their own typography and may import optional font packs. */
|
|
3
3
|
@import url('https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,100..700,0..1,0');
|
|
4
|
-
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/
|
|
4
|
+
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/brands.min.css');
|
|
5
5
|
|
|
6
6
|
@import "theme.css";
|
|
7
7
|
@import "dark.css";
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
@import "color-variants.css";
|
|
28
28
|
|
|
29
29
|
.bgl_icon-font { font-family: 'Material Symbols Outlined', serif !important; }
|
|
30
|
-
.bgl_icon-font.fa { font-family: 'Font Awesome 6 Free', serif !important; }
|
|
31
30
|
.bgl_icon-font.fa-brands { font-family: 'Font Awesome 6 Brands', serif !important; }
|
|
32
31
|
.bgl_icon-font.bgl_icon-round {
|
|
33
32
|
display: inline-flex;
|
|
@@ -94,19 +93,3 @@ button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
|
|
|
94
93
|
font-weight: 400;
|
|
95
94
|
src: url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/webfonts/fa-brands-400.woff2') format('woff2');
|
|
96
95
|
}
|
|
97
|
-
|
|
98
|
-
@font-face {
|
|
99
|
-
font-display: swap;
|
|
100
|
-
font-family: 'Font Awesome 6 Free';
|
|
101
|
-
font-style: normal;
|
|
102
|
-
font-weight: 400;
|
|
103
|
-
src: url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/webfonts/fa-regular-400.woff2') format('woff2');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
@font-face {
|
|
107
|
-
font-display: swap;
|
|
108
|
-
font-family: 'Font Awesome 6 Free';
|
|
109
|
-
font-style: normal;
|
|
110
|
-
font-weight: 900;
|
|
111
|
-
src: url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/webfonts/fa-solid-900.woff2') format('woff2');
|
|
112
|
-
}
|
package/src/types/BagelForm.ts
CHANGED
|
@@ -194,6 +194,8 @@ export interface UploadInputValueObject {
|
|
|
194
194
|
export interface UploadInputProps extends BagelInputShellProps {
|
|
195
195
|
/** Opt-in stable reference output; defaults to legacy path-key behavior. */
|
|
196
196
|
assetMode?: boolean
|
|
197
|
+
/** Asset delivery policy. Defaults to protected; website/media fields use public. */
|
|
198
|
+
assetVisibility?: import('../assets').AssetVisibility
|
|
197
199
|
id?: string
|
|
198
200
|
name?: string
|
|
199
201
|
label?: string
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { EditorState } from '../richTextTypes';
|
|
2
|
-
export declare function formatting(state: EditorState): {
|
|
3
|
-
text: (command: string) => void;
|
|
4
|
-
block: (command: string, tag: string) => void;
|
|
5
|
-
list: (command: string) => void;
|
|
6
|
-
clear: () => void;
|
|
7
|
-
};
|
|
8
|
-
export declare function getBlockElement(node: Node): HTMLElement | null;
|
|
9
|
-
export declare function adjustIndentation(state: EditorState, increase: boolean): void;
|
|
10
|
-
//# sourceMappingURL=formatting.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../../../../../src/components/form/inputs/RichText/utils/formatting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAGnD,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW;oBAIrB,MAAM;qBA4CL,MAAM,OAAO,MAAM;oBA6CpB,MAAM;;EAsN7B;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,GAAG,IAAI,CAI9D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,QAYtE"}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, ref } from 'vue'
|
|
3
|
-
|
|
4
|
-
const props = defineProps<{
|
|
5
|
-
gridSize?: number
|
|
6
|
-
}>()
|
|
7
|
-
const emit = defineEmits(['select'])
|
|
8
|
-
const fb = 1
|
|
9
|
-
const base = props.gridSize || 5
|
|
10
|
-
const hoveredRow = ref(fb)
|
|
11
|
-
const hoveredCol = ref(fb)
|
|
12
|
-
|
|
13
|
-
const rowSize = computed(() => {
|
|
14
|
-
const enlarge = Math.min(hoveredRow.value + 1, 20)
|
|
15
|
-
return hoveredRow.value > (base - 1) ? enlarge : base
|
|
16
|
-
})
|
|
17
|
-
const colSize = computed(() => {
|
|
18
|
-
const enlarge = Math.min(hoveredCol.value + 1, 20)
|
|
19
|
-
return hoveredCol.value > (base - 1) ? enlarge : base
|
|
20
|
-
})
|
|
21
|
-
</script>
|
|
22
|
-
|
|
23
|
-
<template>
|
|
24
|
-
<div class="grid grid-wrap p-05">
|
|
25
|
-
<div
|
|
26
|
-
v-for="row in rowSize" :key="`row-${row}`" class="flex" @mouseout="hoveredRow = fb; hoveredCol = fb"
|
|
27
|
-
@focusout="hoveredRow = fb; hoveredCol = fb"
|
|
28
|
-
>
|
|
29
|
-
<div
|
|
30
|
-
v-for="col in colSize" :key="`col-${col}`" role="button" tabindex="0" aria-label="Insert Table"
|
|
31
|
-
:style="{ width: '20px', height: '20px' }" class="flex pointer gap-025 tableBoxSelect"
|
|
32
|
-
:class="{ borderSelect: hoveredRow >= row && hoveredCol >= col }"
|
|
33
|
-
@mousemove="hoveredRow = row; hoveredCol = col" @click="emit('select', `${row}x${col}`)"
|
|
34
|
-
/>
|
|
35
|
-
</div>
|
|
36
|
-
<p class="txt-center txt-12 color-gray">
|
|
37
|
-
{{ hoveredRow }}x{{ hoveredCol }}
|
|
38
|
-
</p>
|
|
39
|
-
</div>
|
|
40
|
-
</template>
|
|
41
|
-
|
|
42
|
-
<style scoped>
|
|
43
|
-
|
|
44
|
-
.tableBoxSelect::after {
|
|
45
|
-
content: '';
|
|
46
|
-
display: block;
|
|
47
|
-
width: calc(100% - 4px);
|
|
48
|
-
height: calc(100% - 4px);
|
|
49
|
-
border: 1px solid var(--bgl-gray);
|
|
50
|
-
background: var(--bgl-gray-light);
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
.borderSelect::after {
|
|
54
|
-
border-color: var(--bgl-primary-tint);
|
|
55
|
-
background: var(--bgl-primary-light);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
</style>
|