@bagelink/vue 1.15.333 → 1.15.340

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,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "1.15.333",
4
+ "version": "1.15.340",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
@@ -404,13 +404,16 @@ defineExpose({ show, hide, shown })
404
404
  <div
405
405
  v-if="!referenceEl"
406
406
  ref="triggerWrapRef" v-bind="$attrs"
407
- aria-haspopup="menu"
408
- :aria-expanded="shown"
409
- :aria-controls="bglId"
410
407
  @mouseenter="onTriggerMouseenter" @mouseleave="onTriggerMouseleave" @focus="onTriggerMouseenter"
411
408
  @blur="onTriggerMouseleave" @keydown="onTriggerKeydown"
412
409
  >
413
- <slot name="trigger" :show :hide :shown>
410
+ <slot
411
+ name="trigger"
412
+ :show
413
+ :hide
414
+ :shown
415
+ :trigger-attrs="{ 'aria-haspopup': 'menu', 'aria-expanded': shown, 'aria-controls': bglId }"
416
+ >
414
417
  <Btn
415
418
  :class="triggerClass" :iconEnd :icon="iconSet" :value :thin :flat :outline :frame :round :color
416
419
  :disabled @click="onTriggerClick"
@@ -78,6 +78,23 @@ export function useDraggable(options: DraggableOptions = {}) {
78
78
  const UPDATE_THRESHOLD = 150 // ms between updates
79
79
  const POSITION_CACHE = new Map<number, { top: number, bottom: number }>()
80
80
 
81
+ function appendToTopLayer(element: HTMLElement) {
82
+ document.body.appendChild(element)
83
+ element.setAttribute('popover', 'manual')
84
+ // The browser's popover UA styles use `inset: 0; margin: auto`, which
85
+ // recentres fixed-position drag helpers and offsets them from the cursor.
86
+ element.style.inset = 'auto'
87
+ element.style.margin = '0'
88
+ element.style.padding = '0'
89
+ element.style.border = '0'
90
+ element.showPopover()
91
+ }
92
+
93
+ function removeFromTopLayer(element: HTMLElement) {
94
+ if (element.matches(':popover-open')) element.hidePopover()
95
+ element.parentNode?.removeChild(element)
96
+ }
97
+
81
98
  function createGhost(el: DraggableElement) {
82
99
  if (!isBrowser) { return null }
83
100
  const ghost = el.cloneNode(true) as HTMLElement
@@ -94,7 +111,7 @@ export function useDraggable(options: DraggableOptions = {}) {
94
111
  ghost.style.cursor = 'grabbing'
95
112
  ghost.style.willChange = 'transform'
96
113
  ghost.classList.add(defaultOptions.ghostClass!)
97
- document.body.appendChild(ghost)
114
+ appendToTopLayer(ghost)
98
115
  return ghost
99
116
  }
100
117
 
@@ -122,7 +139,7 @@ export function useDraggable(options: DraggableOptions = {}) {
122
139
  dot.style.background = 'var(--primary-color, #0066ff)'
123
140
 
124
141
  line.appendChild(dot)
125
- document.body.appendChild(line)
142
+ appendToTopLayer(line)
126
143
  return line
127
144
  }
128
145
 
@@ -249,7 +266,7 @@ export function useDraggable(options: DraggableOptions = {}) {
249
266
  ghostElement.value.style.opacity = '0'
250
267
  ghostElement.value.style.transform += ' scale(0.8)'
251
268
  setTimeout(() => {
252
- ghostElement.value?.parentNode?.removeChild(ghostElement.value)
269
+ if (ghostElement.value) removeFromTopLayer(ghostElement.value)
253
270
  ghostElement.value = null
254
271
  }, 150)
255
272
  }
@@ -257,7 +274,7 @@ export function useDraggable(options: DraggableOptions = {}) {
257
274
  if (dropIndicator.value) {
258
275
  dropIndicator.value.style.opacity = '0'
259
276
  setTimeout(() => {
260
- dropIndicator.value?.parentNode?.removeChild(dropIndicator.value)
277
+ if (dropIndicator.value) removeFromTopLayer(dropIndicator.value)
261
278
  dropIndicator.value = null
262
279
  }, 150)
263
280
  }
@@ -389,6 +389,13 @@ function getFieldProps(field: FieldBuilder, key: string) {
389
389
  return baseProps
390
390
  }
391
391
 
392
+ function getCustomFieldProps(field: FieldBuilder, key: string) {
393
+ return {
394
+ ...(field._component?.props ?? {}),
395
+ ...getFieldProps(field, key),
396
+ }
397
+ }
398
+
392
399
  function resolveComponent(componentRef: any): any {
393
400
  if (typeof componentRef === 'string') {
394
401
  if (props.components?.[componentRef] != null) {
@@ -556,9 +563,7 @@ defineExpose({
556
563
  <template v-else-if="usesCustomComponent(field)">
557
564
  <component
558
565
  :is="resolveComponent(field._component!.component)"
559
- :model-value="getFieldValue(key)"
560
- v-bind="field._component!.props"
561
- @update:model-value="(val: any) => updateField(key, val, field)"
566
+ v-bind="getCustomFieldProps(field, key)"
562
567
  />
563
568
  </template>
564
569
 
@@ -759,6 +759,7 @@ interface JSONSchemaProperty {
759
759
  'title'?: string
760
760
  'description'?: string
761
761
  'default'?: any
762
+ 'const'?: any
762
763
  'enum'?: any[]
763
764
  'format'?: string
764
765
  'minimum'?: number
@@ -1065,6 +1066,27 @@ function createFieldFromProperty(
1065
1066
  field = $.text(config)
1066
1067
  }
1067
1068
 
1069
+ // Rendering is orthogonal to semantics: a checkbox may use a branded
1070
+ // component while remaining a checkbox for validation and serialization.
1071
+ if (
1072
+ xUi.component
1073
+ && fieldType !== 'component'
1074
+ && fieldType !== 'display'
1075
+ ) {
1076
+ field._component = {
1077
+ component: xUi.component,
1078
+ props: xUi.componentProps || {},
1079
+ }
1080
+ }
1081
+
1082
+ if (resolvedProp.const !== undefined) {
1083
+ field.validate(value =>
1084
+ value === resolvedProp.const
1085
+ ? true
1086
+ : config.requiredMessage || 'form.required'
1087
+ )
1088
+ }
1089
+
1068
1090
  // Apply class
1069
1091
  if (xUi.class) {
1070
1092
  field.class(xUi.class)
@@ -101,6 +101,7 @@ export interface FormField {
101
101
  export interface JSONSchemaProperty {
102
102
  type?: string | string[]
103
103
  items?: JSONSchemaProperty
104
+ const?: any
104
105
  title?: string
105
106
  description?: string
106
107
  format?: string
@@ -354,7 +355,12 @@ export function fieldsToSchema(fields: FormField[]): JSONSchemaObject {
354
355
  if (field.validation?.pattern !== undefined) prop.pattern = field.validation.pattern
355
356
 
356
357
  // Required
357
- if (field.required) required.push(field.key)
358
+ if (field.required) {
359
+ required.push(field.key)
360
+ // Required checkboxes represent explicit acceptance, not merely
361
+ // presence of a boolean key.
362
+ if (field.type === 'checkbox') prop.const = true
363
+ }
358
364
  }
359
365
 
360
366
  // Placeholder