@dou-ui/dashboard 0.0.0-stage → 0.1.0-alpha.1

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 (188) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/chart/chart-settings.js +6 -0
  4. package/dist/chart/chart-settings.js.map +1 -0
  5. package/dist/chart/chart-settings.vue_vue_type_script_setup_true_lang.js +122 -0
  6. package/dist/chart/chart-settings.vue_vue_type_script_setup_true_lang.js.map +1 -0
  7. package/dist/chart/chart.js +6 -0
  8. package/dist/chart/chart.js.map +1 -0
  9. package/dist/chart/chart.vue_vue_type_script_setup_true_lang.js +99 -0
  10. package/dist/chart/chart.vue_vue_type_script_setup_true_lang.js.map +1 -0
  11. package/dist/chart/index.js +33 -0
  12. package/dist/chart/index.js.map +1 -0
  13. package/dist/collaboration/index.js +281 -0
  14. package/dist/collaboration/index.js.map +1 -0
  15. package/dist/collaboration/order.js +88 -0
  16. package/dist/collaboration/order.js.map +1 -0
  17. package/dist/core/document.js +128 -0
  18. package/dist/core/document.js.map +1 -0
  19. package/dist/core/history.js +66 -0
  20. package/dist/core/history.js.map +1 -0
  21. package/dist/core/transaction.js +218 -0
  22. package/dist/core/transaction.js.map +1 -0
  23. package/dist/dashboard/dashboard.js +6 -0
  24. package/dist/dashboard/dashboard.js.map +1 -0
  25. package/dist/dashboard/dashboard.vue_vue_type_script_setup_true_lang.js +1072 -0
  26. package/dist/dashboard/dashboard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  27. package/dist/dashboard/export.js +77 -0
  28. package/dist/dashboard/export.js.map +1 -0
  29. package/dist/dashboard/filter-bar.js +6 -0
  30. package/dist/dashboard/filter-bar.js.map +1 -0
  31. package/dist/dashboard/filter-bar.vue_vue_type_script_setup_true_lang.js +150 -0
  32. package/dist/dashboard/filter-bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  33. package/dist/dashboard/frame-context.js +5 -0
  34. package/dist/dashboard/frame-context.js.map +1 -0
  35. package/dist/dashboard/observers.js +48 -0
  36. package/dist/dashboard/observers.js.map +1 -0
  37. package/dist/dashboard/palette.js +6 -0
  38. package/dist/dashboard/palette.js.map +1 -0
  39. package/dist/dashboard/palette.vue_vue_type_script_setup_true_lang.js +54 -0
  40. package/dist/dashboard/palette.vue_vue_type_script_setup_true_lang.js.map +1 -0
  41. package/dist/dashboard/widget-body.js +6 -0
  42. package/dist/dashboard/widget-body.js.map +1 -0
  43. package/dist/dashboard/widget-body.vue_vue_type_script_setup_true_lang.js +96 -0
  44. package/dist/dashboard/widget-body.vue_vue_type_script_setup_true_lang.js.map +1 -0
  45. package/dist/dashboard/widget-frame.js +6 -0
  46. package/dist/dashboard/widget-frame.js.map +1 -0
  47. package/dist/dashboard/widget-frame.vue_vue_type_script_setup_true_lang.js +300 -0
  48. package/dist/dashboard/widget-frame.vue_vue_type_script_setup_true_lang.js.map +1 -0
  49. package/dist/dashboard/widget-settings.js +6 -0
  50. package/dist/dashboard/widget-settings.js.map +1 -0
  51. package/dist/dashboard/widget-settings.vue_vue_type_script_setup_true_lang.js +36 -0
  52. package/dist/dashboard/widget-settings.vue_vue_type_script_setup_true_lang.js.map +1 -0
  53. package/dist/data/context.js +5 -0
  54. package/dist/data/context.js.map +1 -0
  55. package/dist/data/filters.js +31 -0
  56. package/dist/data/filters.js.map +1 -0
  57. package/dist/data/store.js +214 -0
  58. package/dist/data/store.js.map +1 -0
  59. package/dist/grid/grid-handle.js +6 -0
  60. package/dist/grid/grid-handle.js.map +1 -0
  61. package/dist/grid/grid-handle.vue_vue_type_script_setup_true_lang.js +21 -0
  62. package/dist/grid/grid-handle.vue_vue_type_script_setup_true_lang.js.map +1 -0
  63. package/dist/grid/grid-item.js +80 -0
  64. package/dist/grid/grid-item.js.map +1 -0
  65. package/dist/grid/grid-layout.js +6 -0
  66. package/dist/grid/grid-layout.js.map +1 -0
  67. package/dist/grid/grid-layout.vue_vue_type_script_setup_true_lang.js +767 -0
  68. package/dist/grid/grid-layout.vue_vue_type_script_setup_true_lang.js.map +1 -0
  69. package/dist/grid/tiers.js +31 -0
  70. package/dist/grid/tiers.js.map +1 -0
  71. package/dist/index.js +23 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/layout/engine.js +284 -0
  74. package/dist/layout/engine.js.map +1 -0
  75. package/dist/layout/index.js +1 -0
  76. package/dist/locale.js +245 -0
  77. package/dist/locale.js.map +1 -0
  78. package/dist/pivot/index.js +47 -0
  79. package/dist/pivot/index.js.map +1 -0
  80. package/dist/pivot/pivot-settings.js +6 -0
  81. package/dist/pivot/pivot-settings.js.map +1 -0
  82. package/dist/pivot/pivot-settings.vue_vue_type_script_setup_true_lang.js +64 -0
  83. package/dist/pivot/pivot-settings.vue_vue_type_script_setup_true_lang.js.map +1 -0
  84. package/dist/pivot/pivot.js +6 -0
  85. package/dist/pivot/pivot.js.map +1 -0
  86. package/dist/pivot/pivot.vue_vue_type_script_setup_true_lang.js +76 -0
  87. package/dist/pivot/pivot.vue_vue_type_script_setup_true_lang.js.map +1 -0
  88. package/dist/style.css +1 -0
  89. package/dist/style.d.ts +1 -0
  90. package/dist/style.js +12 -0
  91. package/dist/types/chart/chart-settings.vue.d.ts +11 -0
  92. package/dist/types/chart/chart.vue.d.ts +3 -0
  93. package/dist/types/chart/index.d.ts +9 -0
  94. package/dist/types/chart/types.d.ts +23 -0
  95. package/dist/types/collaboration/index.d.ts +53 -0
  96. package/dist/types/collaboration/order.d.ts +20 -0
  97. package/dist/types/core/collaboration.d.ts +51 -0
  98. package/dist/types/core/document.d.ts +35 -0
  99. package/dist/types/core/history.d.ts +15 -0
  100. package/dist/types/core/transaction.d.ts +86 -0
  101. package/dist/types/core/types.d.ts +27 -0
  102. package/dist/types/dashboard/dashboard.vue.d.ts +33 -0
  103. package/dist/types/dashboard/export.d.ts +11 -0
  104. package/dist/types/dashboard/filter-bar.vue.d.ts +19 -0
  105. package/dist/types/dashboard/frame-context.d.ts +54 -0
  106. package/dist/types/dashboard/observers.d.ts +15 -0
  107. package/dist/types/dashboard/palette.vue.d.ts +20 -0
  108. package/dist/types/dashboard/types.d.ts +190 -0
  109. package/dist/types/dashboard/widget-body.vue.d.ts +19 -0
  110. package/dist/types/dashboard/widget-frame.vue.d.ts +6 -0
  111. package/dist/types/dashboard/widget-settings.vue.d.ts +16 -0
  112. package/dist/types/data/context.d.ts +18 -0
  113. package/dist/types/data/filters.d.ts +9 -0
  114. package/dist/types/data/store.d.ts +48 -0
  115. package/dist/types/data/types.d.ts +67 -0
  116. package/dist/types/grid/grid-handle.vue.d.ts +18 -0
  117. package/dist/types/grid/grid-item.d.ts +78 -0
  118. package/dist/types/grid/grid-layout.vue.d.ts +46 -0
  119. package/dist/types/grid/tiers.d.ts +12 -0
  120. package/dist/types/grid/types.d.ts +113 -0
  121. package/dist/types/index.d.ts +295 -0
  122. package/dist/types/layout/engine.d.ts +50 -0
  123. package/dist/types/layout/index.d.ts +2 -0
  124. package/dist/types/layout/types.d.ts +39 -0
  125. package/dist/types/locale.d.ts +117 -0
  126. package/dist/types/pivot/index.d.ts +14 -0
  127. package/dist/types/pivot/pivot-settings.vue.d.ts +16 -0
  128. package/dist/types/pivot/pivot.vue.d.ts +7 -0
  129. package/dist/types/pivot/types.d.ts +11 -0
  130. package/dist/types/widget/context.d.ts +91 -0
  131. package/dist/types/widget/define.d.ts +50 -0
  132. package/dist/types/widgets/field-select.vue.d.ts +18 -0
  133. package/dist/types/widgets/index.d.ts +15 -0
  134. package/dist/types/widgets/settings-field.vue.d.ts +17 -0
  135. package/dist/types/widgets/shared.d.ts +20 -0
  136. package/dist/types/widgets/source-field.vue.d.ts +15 -0
  137. package/dist/types/widgets/stat-settings.vue.d.ts +11 -0
  138. package/dist/types/widgets/stat.vue.d.ts +3 -0
  139. package/dist/types/widgets/table-settings.vue.d.ts +11 -0
  140. package/dist/types/widgets/table.vue.d.ts +3 -0
  141. package/dist/types/widgets/text-settings.vue.d.ts +11 -0
  142. package/dist/types/widgets/text.vue.d.ts +3 -0
  143. package/dist/types/widgets/types.d.ts +38 -0
  144. package/dist/widget/context.js +88 -0
  145. package/dist/widget/context.js.map +1 -0
  146. package/dist/widget/define.js +32 -0
  147. package/dist/widget/define.js.map +1 -0
  148. package/dist/widgets/field-select.js +6 -0
  149. package/dist/widgets/field-select.js.map +1 -0
  150. package/dist/widgets/field-select.vue_vue_type_script_setup_true_lang.js +54 -0
  151. package/dist/widgets/field-select.vue_vue_type_script_setup_true_lang.js.map +1 -0
  152. package/dist/widgets/index.js +74 -0
  153. package/dist/widgets/index.js.map +1 -0
  154. package/dist/widgets/settings-field.js +6 -0
  155. package/dist/widgets/settings-field.js.map +1 -0
  156. package/dist/widgets/settings-field.vue_vue_type_script_setup_true_lang.js +28 -0
  157. package/dist/widgets/settings-field.vue_vue_type_script_setup_true_lang.js.map +1 -0
  158. package/dist/widgets/shared.js +68 -0
  159. package/dist/widgets/shared.js.map +1 -0
  160. package/dist/widgets/source-field.js +6 -0
  161. package/dist/widgets/source-field.js.map +1 -0
  162. package/dist/widgets/source-field.vue_vue_type_script_setup_true_lang.js +47 -0
  163. package/dist/widgets/source-field.vue_vue_type_script_setup_true_lang.js.map +1 -0
  164. package/dist/widgets/stat-settings.js +6 -0
  165. package/dist/widgets/stat-settings.js.map +1 -0
  166. package/dist/widgets/stat-settings.vue_vue_type_script_setup_true_lang.js +107 -0
  167. package/dist/widgets/stat-settings.vue_vue_type_script_setup_true_lang.js.map +1 -0
  168. package/dist/widgets/stat.js +6 -0
  169. package/dist/widgets/stat.js.map +1 -0
  170. package/dist/widgets/stat.vue_vue_type_script_setup_true_lang.js +72 -0
  171. package/dist/widgets/stat.vue_vue_type_script_setup_true_lang.js.map +1 -0
  172. package/dist/widgets/table-settings.js +6 -0
  173. package/dist/widgets/table-settings.js.map +1 -0
  174. package/dist/widgets/table-settings.vue_vue_type_script_setup_true_lang.js +90 -0
  175. package/dist/widgets/table-settings.vue_vue_type_script_setup_true_lang.js.map +1 -0
  176. package/dist/widgets/table.js +6 -0
  177. package/dist/widgets/table.js.map +1 -0
  178. package/dist/widgets/table.vue_vue_type_script_setup_true_lang.js +91 -0
  179. package/dist/widgets/table.vue_vue_type_script_setup_true_lang.js.map +1 -0
  180. package/dist/widgets/text-settings.js +6 -0
  181. package/dist/widgets/text-settings.js.map +1 -0
  182. package/dist/widgets/text-settings.vue_vue_type_script_setup_true_lang.js +63 -0
  183. package/dist/widgets/text-settings.vue_vue_type_script_setup_true_lang.js.map +1 -0
  184. package/dist/widgets/text.js +6 -0
  185. package/dist/widgets/text.js.map +1 -0
  186. package/dist/widgets/text.vue_vue_type_script_setup_true_lang.js +16 -0
  187. package/dist/widgets/text.vue_vue_type_script_setup_true_lang.js.map +1 -0
  188. package/package.json +98 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-layout.vue_vue_type_script_setup_true_lang.js","names":["_useModel","_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_unref","_renderSlot","_createCommentVNode","_Fragment","_renderList","_createBlock","GridItemView","_toDisplayString"],"sources":["../../src/grid/grid-layout.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { holdPointer, useElementSize, type PointerHold } from 'dou-ui'\nimport { computed, onBeforeUnmount, provide, ref, shallowRef, useId, useSlots, watch } from 'vue'\nimport {\n deriveLayout,\n findPlace,\n fitItem,\n layoutHeight,\n moveItem,\n moveItemBy,\n normalizeLayout,\n resizeItem,\n resizeItemBy,\n} from '../layout/engine'\nimport type { GridItem, GridLayoutOptions } from '../layout/types'\nimport { format, useDashboardMessages } from '../locale'\nimport GridItemView, { gridItemKey } from './grid-item'\nimport { DEFAULT_BREAKPOINTS, DEFAULT_COLUMNS, gridTiers, type GridTier } from './tiers'\nimport type {\n GridChangeReason,\n GridDropItem,\n GridItemSlotProps,\n GridLayouts,\n GridLayoutEmits,\n GridLayoutExpose,\n GridLayoutProps,\n GridResizeHandle,\n} from './types'\n\ndefineOptions({ name: 'DouGridLayout' })\n\nconst props = withDefaults(defineProps<Omit<GridLayoutProps, 'modelValue' | 'layouts'>>(), {\n columns: () => DEFAULT_COLUMNS,\n breakpoints: () => DEFAULT_BREAKPOINTS,\n rowHeight: 80,\n gap: 16,\n compact: 'vertical',\n resize: true,\n})\nconst emit = defineEmits<Omit<GridLayoutEmits, 'update:modelValue' | 'update:layouts'>>()\ndefineSlots<{\n item?: (props: GridItemSlotProps) => unknown\n placeholder?: (props: { item: GridItem }) => unknown\n}>()\n\nconst model = defineModel<GridItem[]>({ default: () => [] })\nconst layouts = defineModel<GridLayouts>('layouts', { default: () => ({}) })\nconst messages = useDashboardMessages(() => props.messages)\nconst slots = useSlots()\nconst hintId = `${useId()}-hint`\nprovide(gridItemKey, { slots, hintId, resizeLabel: () => messages.value.resize })\n\n/** How far a mouse moves before a press becomes a move, in px. */\nconst DRAG_DISTANCE = 4\n/** How long a finger rests on an item before it is picked up, in ms. */\nconst HOLD_DELAY = 400\n/** How far a finger may move while resting, in px; further is a scroll. */\nconst HOLD_SLOP = 8\n/** The band along the top and bottom of the scrolling area that scrolls it during a drag, in px. */\nconst EDGE = 56\n/** The fastest that band scrolls, in px per frame. */\nconst EDGE_SPEED = 20\n/** How long items keep their transition after a drop, in ms (a little over the motion token). */\nconst SETTLE = 320\n\nconst root = ref<HTMLElement>()\n\n// ---------------------------------------------------------------------------\n// Breakpoints: the grid's own width picks how many columns it has\n\ntype Tier = GridTier\n\nconst tiers = computed(() => gridTiers(props.columns, props.breakpoints))\nconst { width: gridWidth } = useElementSize(root)\nconst tier = computed(() => {\n const list = tiers.value\n // not measured yet (or on the server): the widest\n if (!gridWidth.value) return list[0]!\n return list.find((t) => gridWidth.value >= t.min) ?? list.at(-1)!\n})\n/** The widest breakpoint: the one `v-model` holds. */\nconst isMain = computed(() => tier.value === tiers.value[0])\nconst optionsOf = (t: Tier): GridLayoutOptions => ({\n columns: Math.max(1, Math.round(t.columns)),\n compact: props.compact,\n})\nconst options = computed(() => optionsOf(tier.value))\nconst mainLayout = computed(() => normalizeLayout(model.value, optionsOf(tiers.value[0]!)))\nconst settledRaw = computed<readonly GridItem[]>(() => {\n if (isMain.value) return mainLayout.value\n const main = mainLayout.value\n const derived = deriveLayout(main, optionsOf(tiers.value[0]!).columns, options.value)\n const saved = layouts.value[tier.value.name]\n if (!saved?.length) return derived\n const places = new Map(saved.map((place) => [place.id, place]))\n return normalizeLayout(\n main.map((item, i) => {\n const place = places.get(item.id)\n return place ? { ...item, x: place.x, y: place.y, w: place.w, h: place.h } : derived[i]!\n }),\n options.value,\n )\n})\n/**\n * The items drawn last time are reused where nothing about them changed, so\n * a change to one item draws only that one again, even when the layout had\n * to be worked out anew (e.g. from a document that wasn't compacted).\n */\nlet drawnById = new Map<string, GridItem>()\nconst ITEM_KEYS = ['x', 'y', 'w', 'h', 'minW', 'maxW', 'minH', 'maxH', 'locked'] as const\nconst settled = computed<readonly GridItem[]>(() => {\n const next = new Map<string, GridItem>()\n const list = settledRaw.value.map((item) => {\n const old = drawnById.get(item.id)\n const keep = old && ITEM_KEYS.every((key) => old[key] === item[key]) ? old : item\n next.set(item.id, keep)\n return keep\n })\n drawnById = next\n return list\n})\nwatch(\n () => tier.value.name,\n (name, old) => old !== undefined && emit('breakpointChange', name),\n)\n/** The layout while a move or resize is under way; shown instead of `settled`. */\nconst preview = shallowRef<readonly GridItem[] | null>(null)\nconst layout = computed(() => preview.value ?? settled.value)\nconst gaps = computed<[number, number]>(() =>\n Array.isArray(props.gap) ? props.gap : [props.gap, props.gap],\n)\nconst handles = computed<GridResizeHandle[]>(() => {\n const list: GridResizeHandle[] =\n props.resize === false ? [] : props.resize === true ? ['e', 's', 'se'] : props.resize\n // one column: only the height can change\n return options.value.columns === 1 ? list.filter((edge) => edge !== 'e') : list\n})\n\ninterface Session {\n id: string\n kind: 'move' | 'resize' | 'drop'\n source: 'pointer' | 'keyboard'\n /** The layout when it started; pointer moves are always worked out from it. */\n base: readonly GridItem[]\n /** The item as it was. */\n item: GridItem\n}\n\ninterface PointerSession extends Session {\n source: 'pointer'\n edge: GridResizeHandle | null\n el: HTMLElement\n startX: number\n startY: number\n scroller: Element | null\n scrollLeft: number\n scrollTop: number\n /** The scroller's box on screen, measured once. */\n view: { top: number; bottom: number }\n col: number\n colStep: number\n rowStep: number\n /** The item's box when it started, in px from the grid's corner. */\n left: number\n top: number\n width: number\n height: number\n /** The cell or size last worked out, so pointer moves within one cell do nothing. */\n cell: string\n /** For a drop: what `startDrop` was given. */\n drop?: { item: GridDropItem; data: unknown }\n}\n\nconst session = shallowRef<Session | PointerSession | null>(null)\nconst settling = ref(false)\nlet settleTimer: ReturnType<typeof setTimeout> | undefined\n\nconst isPointer = (s: Session | null): s is PointerSession => s?.source === 'pointer'\n\n/**\n * Items as drawn: the one under the pointer keeps its old place, and\n * follows the pointer from there; one being dropped in shows only as the\n * place it would take.\n */\nconst drawn = computed(() => {\n const s = session.value\n if (!isPointer(s)) return layout.value\n if (s.kind === 'drop') return layout.value.filter((item) => item.id !== s.id)\n return layout.value.map((item) => (item.id === s.id ? s.item : item))\n})\n/** Where the item under the pointer would land. */\nconst ghost = computed(() => {\n const s = session.value\n return isPointer(s) ? layout.value.find((item) => item.id === s.id) : undefined\n})\n\nfunction stateOf(id: string) {\n const s = session.value\n if (s?.id !== id) return 'idle'\n return s.kind === 'resize' ? 'resizing' : 'dragging'\n}\n\nconst rootStyle = computed(() => ({\n '--dou-grid-columns': options.value.columns,\n '--dou-grid-row': `${props.rowHeight}px`,\n '--dou-grid-gap-x': `${gaps.value[0]}px`,\n '--dou-grid-gap-y': `${gaps.value[1]}px`,\n '--dou-grid-rows': layoutHeight(layout.value),\n}))\n\nconst cellStyle = (item: GridItem) => ({\n '--dou-grid-x': item.x,\n '--dou-grid-y': item.y,\n '--dou-grid-w': item.w,\n '--dou-grid-h': item.h,\n})\n\nconst labelOf = (item: GridItem) => props.itemLabel?.(item) ?? item.id\n/** Where an item is, read out: its cell and size, or with one column its place in the list. */\nfunction positionText(item: GridItem, items: readonly GridItem[]) {\n if (options.value.columns > 1)\n return format(messages.value.position, { x: item.x + 1, y: item.y + 1, w: item.w, h: item.h })\n let n = 1\n for (const other of items) if (other.y < item.y) n++\n return format(messages.value.order, { n, count: items.length })\n}\n\n// ---------------------------------------------------------------------------\n// Announcements\n\nconst live = ref('')\nfunction say(text: string) {\n // cleared first, so the same words twice are read twice\n live.value = ''\n requestAnimationFrame(() => (live.value = text))\n}\n\n// ---------------------------------------------------------------------------\n// Focus: one item is in the tab order, the arrow keys move between them\n\nconst focusId = ref<string>()\nconst firstId = computed(() => {\n let first: GridItem | undefined\n for (const item of settled.value)\n if (!first || item.y < first.y || (item.y === first.y && item.x < first.x)) first = item\n return first?.id\n})\nconst tabbableId = computed(() =>\n focusId.value && settled.value.some((item) => item.id === focusId.value)\n ? focusId.value\n : firstId.value,\n)\nconst tabindexOf = (item: GridItem) =>\n props.editable ? (item.id === tabbableId.value ? 0 : -1) : undefined\n\nfunction itemElement(id: string) {\n for (const child of root.value?.children ?? [])\n if (child instanceof HTMLElement && child.dataset.gridId === id) return child\n return undefined\n}\n\n/** The item element an event happened on: a direct child of this grid, not of a grid inside an item. */\nfunction ownItem(target: EventTarget | null) {\n const el = target instanceof Element ? target.closest<HTMLElement>('[data-grid-id]') : null\n return el && el.parentElement === root.value ? el : null\n}\n\nfunction onFocusIn(event: FocusEvent) {\n const el = ownItem(event.target)\n if (el) focusId.value = el.dataset.gridId\n}\n\n/** The nearest item in the direction of an arrow key. */\nfunction neighbour(from: GridItem, dx: number, dy: number) {\n const cx = from.x + from.w / 2\n const cy = from.y + from.h / 2\n let best: GridItem | undefined\n let bestScore = Infinity\n for (const item of settled.value) {\n if (item === from) continue\n const ix = item.x + item.w / 2 - cx\n const iy = item.y + item.h / 2 - cy\n const along = dx ? ix * dx : iy * dy\n if (along <= 0) continue\n const across = Math.abs(dx ? iy : ix)\n const score = along + across * 2\n if (score < bestScore) [best, bestScore] = [item, score]\n }\n return best\n}\n\n// ---------------------------------------------------------------------------\n// Ending a move or resize\n\nfunction commit(next: readonly GridItem[] | null, s: Session, reason: GridChangeReason) {\n if (!next || (next.length === s.base.length && next.every((item, i) => item === s.base[i])))\n return false\n const breakpoint = tier.value.name\n const drop = (s as PointerSession).drop\n let added: GridItem | undefined\n if (isMain.value) {\n const items = next.slice()\n added = drop && items.find((other) => other.id === s.id)\n model.value = items\n emit('change', { items, id: s.id, reason, breakpoint })\n } else {\n // a narrower breakpoint keeps its own places; a new item also joins the\n // widest layout, in the first spot there that fits its own size\n if (drop) {\n const main = mainLayout.value\n const wide = optionsOf(tiers.value[0]!)\n const fitted = fitItem({ ...drop.item, x: 0, y: 0 }, wide.columns)\n added = { ...fitted, ...findPlace(main, fitted, wide) }\n model.value = [...main, added]\n }\n layouts.value = {\n ...layouts.value,\n [breakpoint]: next.map(({ id, x, y, w, h }) => ({ id, x, y, w, h })),\n }\n emit('change', { items: next.slice(), id: s.id, reason, breakpoint })\n }\n if (drop && added) emit('drop', { item: added, data: drop.data, breakpoint })\n return true\n}\n\nfunction settle() {\n settling.value = true\n clearTimeout(settleTimer)\n settleTimer = setTimeout(() => (settling.value = false), SETTLE)\n}\n\nfunction finish(keep: boolean) {\n const s = session.value\n if (!s) return\n const next = preview.value\n if (isPointer(s)) stopPointer(s)\n session.value = null\n preview.value = null\n settle()\n const reason = s.source === 'keyboard' ? 'keyboard' : s.kind\n const changed = keep && commit(next, s, reason)\n emit('dragEnd', { id: s.id, kind: s.kind, cancelled: !keep || (s.kind === 'drop' && !changed) })\n // the keyboard hears every outcome; the pointer only a change, or a drag\n // undone (a new item that wasn't dropped has nowhere to go back to)\n if (s.source !== 'keyboard' && (keep || s.kind === 'drop') && !changed) return\n const items = (changed ? next : s.base) ?? s.base\n const item = items.find((other) => other.id === s.id) ?? s.item\n const label = labelOf(item)\n say(\n changed || (keep && s.source === 'keyboard')\n ? format(messages.value.dropped, { item: label, position: positionText(item, items) })\n : format(messages.value.cancelled, { item: label }),\n )\n}\n\n// ---------------------------------------------------------------------------\n// Pointer\n\ninterface Press {\n event: PointerEvent\n el: HTMLElement\n id: string\n kind: 'move' | 'resize' | 'drop'\n edge: GridResizeHandle | null\n hold: PointerHold\n timer?: ReturnType<typeof setTimeout>\n /** For a drop: the new item and its data. */\n drop?: { item: GridDropItem; data: unknown }\n}\n\nlet press: Press | null = null\nlet pointer = { x: 0, y: 0 }\nlet frame = 0\n\nconst NO_DRAG =\n 'input, textarea, select, [contenteditable=\"\"], [contenteditable=\"true\"], [data-dou-nodrag]'\n\nfunction onPointerDown(event: PointerEvent) {\n if (!props.editable || session.value || press || !event.isPrimary) return\n if (event.pointerType === 'mouse' && event.button !== 0) return\n const target = event.target as Element\n const el = ownItem(target)\n const id = el?.dataset.gridId\n const item = id === undefined ? undefined : settled.value.find((other) => other.id === id)\n if (!el || !id || !item || item.locked) return\n const handle = target.closest<HTMLElement>('[data-grid-resize]')\n let kind: Press['kind'] = 'move'\n let edge: GridResizeHandle | null = null\n if (handle && handle.parentElement === el) {\n kind = 'resize'\n edge = handle.dataset.gridResize as GridResizeHandle\n } else {\n if (props.handle) {\n const part = target.closest('[data-dou-grid-handle]')\n if (!part || part.closest('[data-grid-id]') !== el) return\n }\n if (target.closest(NO_DRAG)) return\n }\n listen({ event, el, id, kind, edge, hold: holdPointer(event, root.value) })\n}\n\n/** Follows a press until it becomes a drag (or a scroll, or nothing). */\nfunction listen(next: Press) {\n const { event } = next\n press = next\n pointer = { x: event.clientX, y: event.clientY }\n window.addEventListener('pointermove', onPointerMove)\n window.addEventListener('pointerup', onPointerUp)\n window.addEventListener('pointercancel', onPointerCancel)\n if (next.kind === 'resize') {\n // a handle does nothing else, so there is nothing to wait for\n event.preventDefault()\n begin()\n } else if (event.pointerType !== 'mouse') {\n next.timer = setTimeout(begin, HOLD_DELAY)\n }\n}\n\nfunction startDrop(event: PointerEvent, item: GridDropItem, data?: unknown) {\n if (!props.editable || session.value || press || !event.isPrimary || !root.value) return\n if (event.pointerType === 'mouse' && event.button !== 0) return\n // an id already on the grid would replace that item\n if (settled.value.some((other) => other.id === item.id)) return\n listen({\n event,\n el: root.value,\n id: item.id,\n kind: 'drop',\n edge: null,\n hold: holdPointer(event, root.value),\n drop: { item, data },\n })\n}\n\nfunction onPointerMove(event: PointerEvent) {\n if (!press || event.pointerId !== press.event.pointerId) return\n pointer = { x: event.clientX, y: event.clientY }\n if (!session.value) {\n const distance = Math.hypot(pointer.x - press.event.clientX, pointer.y - press.event.clientY)\n if (press.event.pointerType === 'mouse') {\n if (distance >= DRAG_DISTANCE) begin()\n } else if (distance > HOLD_SLOP) {\n // the finger is scrolling the page\n dropPress()\n }\n return\n }\n track()\n}\n\nfunction onPointerUp(event: PointerEvent) {\n if (!press || event.pointerId !== press.event.pointerId) return\n if (session.value) finish(true)\n else dropPress()\n}\n\nfunction onPointerCancel(event: PointerEvent) {\n if (!press || event.pointerId !== press.event.pointerId) return\n if (session.value) finish(false)\n else dropPress()\n}\n\nfunction onWindowKeydown(event: KeyboardEvent) {\n if (event.key !== 'Escape' || !isPointer(session.value)) return\n event.preventDefault()\n event.stopPropagation()\n finish(false)\n}\n\nfunction onScroll() {\n if (isPointer(session.value)) track()\n}\n\nfunction dropPress() {\n if (!press) return\n clearTimeout(press.timer)\n press.hold.release()\n press = null\n window.removeEventListener('pointermove', onPointerMove)\n window.removeEventListener('pointerup', onPointerUp)\n window.removeEventListener('pointercancel', onPointerCancel)\n}\n\nfunction scrollParent(el: Element): Element | null {\n for (let node = el.parentElement; node && node !== document.body; node = node.parentElement) {\n const { overflowY } = getComputedStyle(node)\n if (/(auto|scroll|overlay)/.test(overflowY) && node.scrollHeight > node.clientHeight)\n return node\n }\n return null\n}\n\nconst scrollOf = (scroller: Element | null) =>\n scroller\n ? { left: scroller.scrollLeft, top: scroller.scrollTop }\n : { left: window.scrollX, top: window.scrollY }\n\nfunction begin() {\n const p = press\n const el = root.value\n if (!p || !el || session.value) return\n clearTimeout(p.timer)\n const item = p.drop\n ? fitItem({ ...p.drop.item, x: 0, y: 0 }, options.value.columns)\n : settled.value.find((other) => other.id === p.id)\n if (!item) return dropPress()\n const rect = el.getBoundingClientRect()\n const [gx, gy] = gaps.value\n const columns = options.value.columns\n const col = (rect.width - gx * (columns - 1)) / columns\n const scroller = scrollParent(el)\n const scroll = scrollOf(scroller)\n const box = scroller?.getBoundingClientRect()\n session.value = {\n id: p.id,\n kind: p.kind,\n source: 'pointer',\n edge: p.edge,\n base: settled.value,\n item,\n el: p.el,\n // a drop measures from the grid's corner, a move from where the press was\n startX: p.drop ? rect.left : p.event.clientX,\n startY: p.drop ? rect.top : p.event.clientY,\n scroller,\n scrollLeft: scroll.left,\n scrollTop: scroll.top,\n view: box ? { top: box.top, bottom: box.bottom } : { top: 0, bottom: window.innerHeight },\n col,\n colStep: col + gx,\n rowStep: props.rowHeight + gy,\n left: item.x * (col + gx),\n top: item.y * (props.rowHeight + gy),\n width: item.w * col + (item.w - 1) * gx,\n height: item.h * props.rowHeight + (item.h - 1) * gy,\n cell: '',\n drop: p.drop,\n }\n preview.value = settled.value\n p.hold.grab()\n if (p.event.pointerType === 'mouse') {\n try {\n // the grabbing cursor follows the pointer outside the grid\n el.setPointerCapture(p.event.pointerId)\n } catch {\n // the pointer is already gone\n }\n }\n window.addEventListener('keydown', onWindowKeydown, true)\n window.addEventListener('scroll', onScroll, { capture: true, passive: true })\n emit('dragStart', { id: p.id, kind: p.kind })\n frame = requestAnimationFrame(autoscroll)\n track()\n}\n\nfunction stopPointer(s: PointerSession) {\n cancelAnimationFrame(frame)\n for (const name of ['dx', 'dy', 'dw', 'dh']) s.el.style.removeProperty(`--dou-grid-${name}`)\n window.removeEventListener('keydown', onWindowKeydown, true)\n window.removeEventListener('scroll', onScroll, true)\n const touch = press?.event.pointerType !== 'mouse'\n dropPress()\n // the click that ends a drag isn't a click on whatever is under the pointer\n window.addEventListener('click', swallow, { capture: true, once: true })\n setTimeout(() => window.removeEventListener('click', swallow, true), touch ? 400 : 0)\n}\n\nconst clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value))\n/** The length of `n` cells of `size` with `gap` between them. */\nconst span = (n: number, size: number, gap: number) => n * size + (n - 1) * gap\nfunction swallow(event: Event) {\n event.stopPropagation()\n event.preventDefault()\n}\n\n/** Follows the pointer: moves the item with it, and works out the layout when it reaches another cell. */\nfunction track() {\n const s = session.value\n if (!isPointer(s)) return\n const scroll = scrollOf(s.scroller)\n const dx = pointer.x - s.startX + scroll.left - s.scrollLeft\n const dy = pointer.y - s.startY + scroll.top - s.scrollTop\n const { columns } = options.value\n const [gx, gy] = gaps.value\n const item = s.item\n if (s.kind === 'drop') {\n // dx, dy: the pointer from the grid's corner; the item is held by its middle\n const height = layoutHeight(s.base) * s.rowStep\n const over =\n dx > -s.colStep / 2 &&\n dx < s.colStep * columns &&\n dy > -s.rowStep / 2 &&\n dy < height + s.rowStep * (item.h + 1)\n const x = clamp(Math.round((dx - s.width / 2) / s.colStep), 0, columns - item.w)\n const y = Math.max(0, Math.round((dy - s.height / 2) / s.rowStep))\n const cell = over ? `${x},${y}` : 'out'\n if (cell === s.cell) return\n s.cell = cell\n preview.value = over\n ? moveItem([...s.base, { ...item, x, y }], s.id, { x, y }, options.value)\n : s.base\n return\n }\n if (s.kind === 'move') {\n s.el.style.setProperty('--dou-grid-dx', `${dx}px`)\n s.el.style.setProperty('--dou-grid-dy', `${dy}px`)\n const x = clamp(Math.round((s.left + dx) / s.colStep), 0, columns - item.w)\n const y = Math.max(0, Math.round((s.top + dy) / s.rowStep))\n const cell = `${x},${y}`\n if (cell === s.cell) return\n s.cell = cell\n preview.value = moveItem(s.base, s.id, { x, y }, options.value)\n return\n }\n // resizing: the box follows the pointer within the item's limits, the size snaps to cells\n const maxW = Math.min(columns - item.x, item.maxW ?? Infinity)\n const minW = Math.min(maxW, Math.max(1, item.minW ?? 1))\n const maxH = item.maxH ?? Infinity\n const minH = Math.min(maxH, Math.max(1, item.minH ?? 1))\n const width =\n s.edge === 's' ? s.width : clamp(s.width + dx, span(minW, s.col, gx), span(maxW, s.col, gx))\n const height =\n s.edge === 'e'\n ? s.height\n : clamp(s.height + dy, span(minH, props.rowHeight, gy), span(maxH, props.rowHeight, gy))\n s.el.style.setProperty('--dou-grid-dw', `${width - s.width}px`)\n s.el.style.setProperty('--dou-grid-dh', `${height - s.height}px`)\n const w = Math.round((width + gx) / s.colStep)\n const h = Math.round((height + gy) / s.rowStep)\n const cell = `${w}x${h}`\n if (cell === s.cell) return\n s.cell = cell\n preview.value = resizeItem(s.base, s.id, { w, h }, options.value)\n}\n\nfunction autoscroll() {\n const s = session.value\n if (!isPointer(s)) return\n frame = requestAnimationFrame(autoscroll)\n const { top, bottom } = s.view\n let speed = 0\n if (pointer.y < top + EDGE) speed = -Math.min(1, (top + EDGE - pointer.y) / EDGE)\n else if (pointer.y > bottom - EDGE) speed = Math.min(1, (pointer.y - bottom + EDGE) / EDGE)\n if (!speed) return\n // the scroll event that follows moves the item along\n if (s.scroller) s.scroller.scrollTop += speed * EDGE_SPEED\n else window.scrollBy(0, speed * EDGE_SPEED)\n}\n\n// ---------------------------------------------------------------------------\n// Keyboard\n\nconst ARROWS: Record<string, [number, number]> = {\n ArrowLeft: [-1, 0],\n ArrowRight: [1, 0],\n ArrowUp: [0, -1],\n ArrowDown: [0, 1],\n}\n\nfunction onKeyDown(event: KeyboardEvent) {\n if (!props.editable || event.target !== ownItem(event.target)) return\n const id = (event.target as HTMLElement).dataset.gridId!\n const s = session.value\n const arrow = ARROWS[event.key]\n if (s?.source === 'keyboard' && s.id === id) {\n if (arrow && !event.altKey && !event.metaKey && !event.ctrlKey) {\n const current = preview.value ?? s.base\n const next = event.shiftKey\n ? resizeItemBy(current, id, arrow[0], arrow[1], options.value)\n : moveItemBy(current, id, arrow[0], arrow[1], options.value)\n preview.value = next\n const item = next.find((other) => other.id === id)\n if (item) say(positionText(item, next))\n } else if (event.key === 'Enter' || event.key === ' ') {\n finish(true)\n } else if (event.key === 'Escape') {\n finish(false)\n } else if (event.key !== 'Tab') {\n return\n }\n if (event.key !== 'Tab') {\n event.preventDefault()\n event.stopPropagation()\n }\n return\n }\n if (s) return\n const item = settled.value.find((other) => other.id === id)\n if (!item) return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n if (item.locked) return say(format(messages.value.locked, { item: labelOf(item) }))\n session.value = { id, kind: 'move', source: 'keyboard', base: settled.value, item }\n preview.value = settled.value\n emit('dragStart', { id, kind: 'move' })\n say(\n format(messages.value.grabbed, {\n item: labelOf(item),\n position: positionText(item, settled.value),\n }),\n )\n } else if (arrow && !event.shiftKey && !event.altKey && !event.metaKey && !event.ctrlKey) {\n const next = neighbour(item, arrow[0], arrow[1])\n if (!next) return\n event.preventDefault()\n itemElement(next.id)?.focus()\n }\n}\n\n/** Leaving a picked-up item puts it back. */\nfunction onFocusOut(event: FocusEvent) {\n const s = session.value\n if (s?.source !== 'keyboard') return\n const el = ownItem(event.target)\n if (el?.dataset.gridId === s.id && !el.contains(event.relatedTarget as Node | null)) finish(false)\n}\n\n// ---------------------------------------------------------------------------\n\nwatch(\n () => props.editable,\n (editable) => {\n if (!editable) {\n finish(false)\n dropPress()\n }\n },\n)\n\nonBeforeUnmount(() => {\n finish(false)\n dropPress()\n clearTimeout(settleTimer)\n})\n\ndefineExpose<GridLayoutExpose>({\n startDrop,\n get breakpoint() {\n return tier.value.name\n },\n focusItem(id) {\n const el = itemElement(id)\n if (!el) return\n if (props.editable) el.focus()\n else\n el.querySelector<HTMLElement>(\n 'a[href], button:not([disabled]), input:not([disabled]), select, textarea, [tabindex]:not([tabindex=\"-1\"])',\n )?.focus()\n },\n scrollToItem(id, scrollOptions) {\n itemElement(id)?.scrollIntoView({ block: 'nearest', inline: 'nearest', ...scrollOptions })\n },\n})\n</script>\n\n<template>\n <div\n ref=\"root\"\n class=\"dou-grid-layout\"\n :class=\"{\n 'is-editable': editable,\n 'has-handle': handle,\n 'is-arranging': !!session || settling,\n 'is-pointer-dragging': session?.source === 'pointer',\n 'is-resizing': session?.kind === 'resize' && session.source === 'pointer',\n }\"\n :style=\"rootStyle\"\n :role=\"editable ? 'group' : undefined\"\n :aria-label=\"label ?? (editable ? messages.layout : undefined)\"\n @pointerdown=\"onPointerDown\"\n @keydown=\"onKeyDown\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n >\n <div\n v-if=\"ghost\"\n class=\"dou-grid-layout__placeholder\"\n :style=\"cellStyle(ghost)\"\n aria-hidden=\"true\"\n >\n <slot name=\"placeholder\" :item=\"ghost\" />\n </div>\n <GridItemView\n v-for=\"item in drawn\"\n :key=\"item.id\"\n :item=\"item\"\n :state=\"stateOf(item.id)\"\n :editable=\"editable\"\n :tabindex=\"tabindexOf(item)\"\n :label=\"labelOf(item)\"\n :role-description=\"messages.item\"\n :handles=\"handles\"\n />\n <span v-if=\"editable\" :id=\"hintId\" hidden>{{ messages.itemHint }}</span>\n <div v-if=\"editable\" class=\"dou-grid-layout__live\" aria-live=\"assertive\" aria-atomic=\"true\">\n {{ live }}\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ // src/grid/tiers.ts
2
+ /** The breakpoint name used when `columns` is one number. */
3
+ var SINGLE_TIER = "default";
4
+ /** A grid's breakpoints, widest first. */
5
+ function gridTiers(columns, breakpoints) {
6
+ if (typeof columns === "number") return [{
7
+ name: SINGLE_TIER,
8
+ min: 0,
9
+ columns
10
+ }];
11
+ const list = Object.entries(columns).map(([name, count]) => ({
12
+ name,
13
+ min: breakpoints[name] ?? 0,
14
+ columns: count
15
+ }));
16
+ list.sort((a, b) => b.min - a.min);
17
+ return list;
18
+ }
19
+ var DEFAULT_COLUMNS = {
20
+ lg: 12,
21
+ md: 6,
22
+ sm: 1
23
+ };
24
+ var DEFAULT_BREAKPOINTS = {
25
+ lg: 1024,
26
+ md: 640,
27
+ sm: 0
28
+ };
29
+ export { DEFAULT_BREAKPOINTS, DEFAULT_COLUMNS, SINGLE_TIER, gridTiers };
30
+
31
+ //# sourceMappingURL=tiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tiers.js","names":[],"sources":["../../src/grid/tiers.ts"],"sourcesContent":["/** One breakpoint of a grid: its name, the narrowest width it applies at, and its columns. */\nexport interface GridTier {\n name: string\n min: number\n columns: number\n}\n\n/** The breakpoint name used when `columns` is one number. */\nexport const SINGLE_TIER = 'default'\n\n/** A grid's breakpoints, widest first. */\nexport function gridTiers(\n columns: number | Record<string, number>,\n breakpoints: Record<string, number>,\n): GridTier[] {\n if (typeof columns === 'number') return [{ name: SINGLE_TIER, min: 0, columns }]\n const list = Object.entries(columns).map(([name, count]) => ({\n name,\n min: breakpoints[name] ?? 0,\n columns: count,\n }))\n list.sort((a, b) => b.min - a.min)\n return list\n}\n\nexport const DEFAULT_COLUMNS: Record<string, number> = { lg: 12, md: 6, sm: 1 }\nexport const DEFAULT_BREAKPOINTS: Record<string, number> = { lg: 1024, md: 640, sm: 0 }\n"],"mappings":";;AAQA,IAAa,cAAc;;AAG3B,SAAgB,UACd,SACA,aACY;CACZ,IAAI,OAAO,YAAY,UAAU,OAAO,CAAC;EAAE,MAAM;EAAa,KAAK;EAAG;CAAQ,CAAC;CAC/E,MAAM,OAAO,OAAO,QAAQ,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,YAAY;EAC3D;EACA,KAAK,YAAY,SAAS;EAC1B,SAAS;CACX,EAAE;CACF,KAAK,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG;CACjC,OAAO;AACT;AAEA,IAAa,kBAA0C;CAAE,IAAI;CAAI,IAAI;CAAG,IAAI;AAAE;AAC9E,IAAa,sBAA8C;CAAE,IAAI;CAAM,IAAI;CAAK,IAAI;AAAE"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ import { compactLayout, deriveLayout, findPlace, fitItem, layoutHeight, moveItem, moveItemBy, normalizeLayout, overlaps, resizeItem, resizeItemBy } from "./layout/engine.js";
2
+ import { dashboardLocales, useDashboardMessages } from "./locale.js";
3
+ import grid_layout_default from "./grid/grid-layout.js";
4
+ import grid_handle_default from "./grid/grid-handle.js";
5
+ import { checkDocument, emptyDocument, isDashboardPlace, migrateDocument } from "./core/document.js";
6
+ import { DashboardTransaction, applySteps, replaceWidgets, sameValue } from "./core/transaction.js";
7
+ import { DashboardHistory } from "./core/history.js";
8
+ import { isEmptyFilter } from "./data/filters.js";
9
+ import { defineDashboardWidget } from "./widget/define.js";
10
+ import { useDashboardWidget } from "./widget/context.js";
11
+ import dashboard_default from "./dashboard/dashboard.js";
12
+ import palette_default from "./dashboard/palette.js";
13
+ import filter_bar_default from "./dashboard/filter-bar.js";
14
+ import { withInstall } from "dou-ui";
15
+ // src/index.ts
16
+ var DouGridLayout = withInstall(grid_layout_default);
17
+ var DouGridLayoutHandle = withInstall(grid_handle_default);
18
+ var DouDashboard = withInstall(dashboard_default);
19
+ var DouDashboardPalette = withInstall(palette_default);
20
+ var DouDashboardFilterBar = withInstall(filter_bar_default);
21
+ export { DashboardHistory, DashboardTransaction, DouDashboard, DouDashboardFilterBar, DouDashboardPalette, DouGridLayout, DouGridLayoutHandle, applySteps, checkDocument, compactLayout, dashboardLocales, defineDashboardWidget, deriveLayout, emptyDocument, findPlace, fitItem, isDashboardPlace, isEmptyFilter, layoutHeight, migrateDocument, moveItem, moveItemBy, normalizeLayout, overlaps, replaceWidgets, resizeItem, resizeItemBy, sameValue, useDashboardMessages, useDashboardWidget };
22
+
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["GridLayout","GridLayoutHandle","Dashboard","DashboardPalette","DashboardFilterBar"],"sources":["../src/index.ts"],"sourcesContent":["import { withInstall } from 'dou-ui'\nimport GridLayout from './grid/grid-layout.vue'\nimport GridLayoutHandle from './grid/grid-handle.vue'\nimport Dashboard from './dashboard/dashboard.vue'\nimport DashboardPalette from './dashboard/palette.vue'\nimport DashboardFilterBar from './dashboard/filter-bar.vue'\n\nexport const DouGridLayout = withInstall(GridLayout)\nexport const DouGridLayoutHandle = withInstall(GridLayoutHandle)\nexport const DouDashboard = withInstall(Dashboard)\nexport const DouDashboardPalette = withInstall(DashboardPalette)\nexport const DouDashboardFilterBar = withInstall(DashboardFilterBar)\n\nexport type {\n DashboardAddOptions,\n DashboardEmits,\n DashboardExportErrorEvent,\n DashboardExportOptions,\n DashboardSaveOptions,\n DashboardExpose,\n DashboardFilterBarProps,\n DashboardPaletteProps,\n DashboardProps,\n} from './dashboard/types'\nexport type { DashboardDocument, DashboardPlace, DashboardWidget } from './core/types'\nexport { checkDocument, emptyDocument, isDashboardPlace, migrateDocument } from './core/document'\nexport type { CheckDocumentOptions, DocumentProblem } from './core/document'\nexport { applySteps, DashboardTransaction, replaceWidgets, sameValue } from './core/transaction'\nexport type {\n DashboardCollaboration,\n DashboardCollaborationHost,\n DashboardPeer,\n DashboardPresence,\n DashboardPresenceAction,\n} from './core/collaboration'\nexport type {\n DashboardStep,\n DashboardTransactionMeta,\n DashboardWidgetPatch,\n} from './core/transaction'\nexport { DashboardHistory } from './core/history'\nexport { defineDashboardWidget } from './widget/define'\nexport type { DashboardWidgetSize, DashboardWidgetType } from './widget/define'\nexport { useDashboardWidget } from './widget/context'\nexport { isEmptyFilter } from './data/filters'\nexport type { DashboardImageOptions } from './dashboard/export'\nexport type {\n DashboardDateRangeFilterField,\n DashboardFilterField,\n DashboardFilters,\n DashboardLinkedFilter,\n DashboardSearchFilterField,\n DashboardSelectFilterField,\n DashboardSetFilterOptions,\n DashboardSourceContext,\n DashboardSourceLoad,\n DashboardSourceOptions,\n DashboardSources,\n} from './data/types'\nexport type {\n DashboardWidgetContext,\n DashboardWidgetState,\n DashboardWidgetStatus,\n} from './widget/context'\n\nexport type {\n GridChangeEvent,\n GridChangeReason,\n GridDragEndEvent,\n GridDragEvent,\n GridDropEvent,\n GridDropItem,\n GridItemSlotProps,\n GridLayoutEmits,\n GridLayoutExpose,\n GridLayoutProps,\n GridLayouts,\n GridPlace,\n GridResizeHandle,\n} from './grid/types'\nexport {\n compactLayout,\n deriveLayout,\n findPlace,\n fitItem,\n layoutHeight,\n moveItem,\n moveItemBy,\n normalizeLayout,\n overlaps,\n resizeItem,\n resizeItemBy,\n} from './layout'\nexport type { GridCompact, GridItem, GridLayoutOptions, GridPosition, GridSize } from './layout'\nexport { dashboardLocales, useDashboardMessages } from './locale'\nexport type { DashboardMessages, DashboardMessagesOverride } from './locale'\n\ndeclare module 'vue' {\n export interface GlobalComponents {\n DouGridLayout: typeof DouGridLayout\n DouGridLayoutHandle: typeof DouGridLayoutHandle\n DouDashboard: typeof DouDashboard\n DouDashboardPalette: typeof DouDashboardPalette\n DouDashboardFilterBar: typeof DouDashboardFilterBar\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAOA,IAAa,gBAAgB,YAAYA,mBAAU;AACnD,IAAa,sBAAsB,YAAYC,mBAAgB;AAC/D,IAAa,eAAe,YAAYC,iBAAS;AACjD,IAAa,sBAAsB,YAAYC,eAAgB;AAC/D,IAAa,wBAAwB,YAAYC,kBAAkB"}
@@ -0,0 +1,284 @@
1
+ // src/layout/engine.ts
2
+ /** Whether two boxes share at least one cell. */
3
+ function overlaps(a, b) {
4
+ return a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h;
5
+ }
6
+ /** The row just below the lowest item: how many rows the layout takes up. */
7
+ function layoutHeight(items) {
8
+ let bottom = 0;
9
+ for (const item of items) bottom = Math.max(bottom, item.y + item.h);
10
+ return bottom;
11
+ }
12
+ var int = (value, fallback) => Number.isFinite(value) ? Math.round(value) : fallback;
13
+ /** The width an item may have on a grid of `columns`. */
14
+ function clampW(item, w, columns) {
15
+ const max = Math.min(columns, item.maxW ?? columns);
16
+ const min = Math.min(max, Math.max(1, item.minW ?? 1));
17
+ return Math.min(max, Math.max(min, int(w, min)));
18
+ }
19
+ function clampH(item, h) {
20
+ const max = Math.max(1, item.maxH ?? Infinity);
21
+ const min = Math.min(max, Math.max(1, item.minH ?? 1));
22
+ return Math.min(max, Math.max(min, int(h, min)));
23
+ }
24
+ /**
25
+ * The item with its size inside its limits and the grid's width, and its
26
+ * position on the grid, in whole cells. Returns the item itself when it fits.
27
+ */
28
+ function fitItem(item, columns) {
29
+ const w = clampW(item, item.w, columns);
30
+ const h = clampH(item, item.h);
31
+ const x = Math.min(columns - w, Math.max(0, int(item.x, 0)));
32
+ const y = Math.max(0, int(item.y, 0));
33
+ return x === item.x && y === item.y && w === item.w && h === item.h ? item : {
34
+ ...item,
35
+ x,
36
+ y,
37
+ w,
38
+ h
39
+ };
40
+ }
41
+ var at = (item, x, y) => item.x === x && item.y === y ? item : {
42
+ ...item,
43
+ x,
44
+ y
45
+ };
46
+ /**
47
+ * Where an item the moved one landed on could step aside to: the same
48
+ * row, shifted into the columns the moved item left. This is what turns
49
+ * dropping an item onto its neighbour into a swap, instead of pushing the
50
+ * neighbour down. `undefined` when the item isn't in the way, or wouldn't
51
+ * fit in those columns.
52
+ */
53
+ function aside(item, fixed, origin) {
54
+ if (!fixed || !origin || !overlaps(item, fixed)) return void 0;
55
+ const hi = origin.x + origin.w - item.w;
56
+ if (hi < origin.x) return void 0;
57
+ const x = Math.min(hi, Math.max(origin.x, item.x));
58
+ return x === item.x ? void 0 : x;
59
+ }
60
+ /** The first of `boxes` that shares a cell with the box, if any. */
61
+ function hit(boxes, box) {
62
+ for (const other of boxes) if (overlaps(other, box)) return other;
63
+ }
64
+ /** Moves the box down until it is clear of every one of `boxes`; returns its row. */
65
+ function below(boxes, box) {
66
+ const probe = { ...box };
67
+ for (let other = hit(boxes, probe); other; other = hit(boxes, probe)) probe.y = other.y + other.h;
68
+ return probe.y;
69
+ }
70
+ /**
71
+ * Settles every item that isn't locked and isn't `fixed`; those stay where
72
+ * they are and the rest go around them. Items are settled from the top
73
+ * down (then left to right, then by their place in the array).
74
+ */
75
+ function settle(items, options, fixed, origin) {
76
+ const out = items.slice();
77
+ const obstacles = [];
78
+ const order = [];
79
+ items.forEach((item, i) => {
80
+ if (item.locked || item === fixed) obstacles.push(item);
81
+ else order.push(i);
82
+ });
83
+ order.sort((a, b) => items[a].y - items[b].y || items[a].x - items[b].x || a - b);
84
+ if (options.compact === false) {
85
+ const placed = obstacles.slice();
86
+ for (const i of order) {
87
+ const item = items[i];
88
+ let x = item.x;
89
+ let y = below(placed, item);
90
+ const side = aside(item, fixed, origin);
91
+ if (side !== void 0 && !hit(placed, {
92
+ ...item,
93
+ x: side
94
+ })) [x, y] = [side, item.y];
95
+ placed.push(out[i] = at(item, x, y));
96
+ }
97
+ return out;
98
+ }
99
+ const top = new Int32Array(options.columns);
100
+ for (const i of order) {
101
+ const item = items[i];
102
+ const rise = (x) => {
103
+ let y = 0;
104
+ for (let c = x; c < x + item.w; c++) y = Math.max(y, top[c] ?? 0);
105
+ return below(obstacles, {
106
+ x,
107
+ y,
108
+ w: item.w,
109
+ h: item.h
110
+ });
111
+ };
112
+ let x = item.x;
113
+ let y = rise(x);
114
+ const side = aside(item, fixed, origin);
115
+ if (side !== void 0) {
116
+ const y2 = rise(side);
117
+ if (y2 < y) [x, y] = [side, y2];
118
+ }
119
+ for (let c = x; c < x + item.w; c++) top[c] = y + item.h;
120
+ out[i] = at(item, x, y);
121
+ }
122
+ return out;
123
+ }
124
+ /**
125
+ * The layout fitted to the grid: sizes inside their limits, nothing past
126
+ * the last column, no two items on the same cell and, when compacting,
127
+ * no gaps above items. Returns `items` itself when it is already settled.
128
+ */
129
+ function normalizeLayout(items, options) {
130
+ const out = settle(items.map((item) => fitItem(item, options.columns)), options);
131
+ return out.every((item, i) => item === items[i]) ? items : out;
132
+ }
133
+ /** Floats every item up as far as it goes (ignores `compact`). */
134
+ function compactLayout(items, columns) {
135
+ return settle(items, {
136
+ columns,
137
+ compact: "vertical"
138
+ });
139
+ }
140
+ /** Puts `item` at the given place, moved down below any locked item it lands on. */
141
+ function place(items, index, next, options) {
142
+ const y = below(items.filter((other) => other.locked && other !== items[index]), next);
143
+ const out = items.slice();
144
+ const settled = settle(out, options, out[index] = at(next, next.x, y), items[index]);
145
+ return options.compact === false ? settled : settle(settled, options);
146
+ }
147
+ /**
148
+ * Moves an item to a cell; the items it lands on make way. Locked items
149
+ * and unknown ids leave the layout as it is.
150
+ */
151
+ function moveItem(items, id, to, options) {
152
+ const index = items.findIndex((item) => item.id === id);
153
+ const item = items[index];
154
+ if (!item || item.locked) return items;
155
+ const x = Math.min(options.columns - item.w, Math.max(0, int(to.x, item.x)));
156
+ const y = Math.max(0, int(to.y, item.y));
157
+ return place(items, index, {
158
+ ...item,
159
+ x,
160
+ y
161
+ }, options);
162
+ }
163
+ /**
164
+ * Gives an item a new size, keeping its top-left corner; the items it now
165
+ * covers make way. A size that would cover a locked item is refused.
166
+ */
167
+ function resizeItem(items, id, to, options) {
168
+ const index = items.findIndex((item) => item.id === id);
169
+ const item = items[index];
170
+ if (!item || item.locked) return items;
171
+ const w = Math.min(options.columns - item.x, clampW(item, to.w, options.columns));
172
+ const h = clampH(item, to.h);
173
+ const next = {
174
+ ...item,
175
+ w: Math.max(1, w),
176
+ h
177
+ };
178
+ if (items.some((other) => other.locked && other !== item && overlaps(other, next))) return items;
179
+ return place(items, index, next, options);
180
+ }
181
+ var sameSpot = (a, b) => !!a && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h;
182
+ /**
183
+ * Moves an item by whole cells, as the arrow keys do. Moving up or down
184
+ * goes on past rows where the item would only settle back where it was,
185
+ * so one press always moves it, to the next place it can take.
186
+ */
187
+ function moveItemBy(items, id, dx, dy, options) {
188
+ const item = items.find((other) => other.id === id);
189
+ if (!item || item.locked) return items;
190
+ if (!dy) return moveItem(items, id, {
191
+ x: item.x + dx,
192
+ y: item.y
193
+ }, options);
194
+ const step = Math.sign(dy);
195
+ const last = layoutHeight(items);
196
+ for (let y = item.y + dy; y >= 0 && y <= last; y += step) {
197
+ const out = moveItem(items, id, {
198
+ x: item.x + dx,
199
+ y
200
+ }, options);
201
+ if (!sameSpot(out.find((other) => other.id === id), item)) return out;
202
+ }
203
+ return items;
204
+ }
205
+ /** Resizes an item by whole cells, as Shift and the arrow keys do. */
206
+ function resizeItemBy(items, id, dw, dh, options) {
207
+ const item = items.find((other) => other.id === id);
208
+ if (!item) return items;
209
+ return resizeItem(items, id, {
210
+ w: item.w + dw,
211
+ h: item.h + dh
212
+ }, options);
213
+ }
214
+ /**
215
+ * Where a new item of `size` fits: the first free spot reading from the top
216
+ * left, or below everything when no row has room.
217
+ */
218
+ function findPlace(items, size, options) {
219
+ const w = Math.min(options.columns, Math.max(1, Math.round(size.w)));
220
+ const h = Math.max(1, Math.round(size.h));
221
+ const bottom = layoutHeight(items);
222
+ for (let y = 0; y < bottom; y++) for (let x = 0; x + w <= options.columns; x++) {
223
+ const other = hit(items, {
224
+ x,
225
+ y,
226
+ w,
227
+ h
228
+ });
229
+ if (!other) return {
230
+ x,
231
+ y
232
+ };
233
+ x = other.x + other.w - 1;
234
+ }
235
+ return {
236
+ x: 0,
237
+ y: bottom
238
+ };
239
+ }
240
+ /**
241
+ * The layout worked out for a grid of another width: positions and widths
242
+ * scaled by the ratio of the columns, then settled. On a single column the
243
+ * items are stacked in reading order (top to bottom, then left to right),
244
+ * each keeping its height.
245
+ */
246
+ function deriveLayout(items, from, options) {
247
+ const to = options.columns;
248
+ if (from === to) return normalizeLayout(items, options);
249
+ if (to === 1) {
250
+ const order = items.map((_, i) => i);
251
+ order.sort((a, b) => items[a].y - items[b].y || items[a].x - items[b].x || a - b);
252
+ const out = items.slice();
253
+ let y = 0;
254
+ for (const i of order) {
255
+ const item = fitItem({
256
+ ...items[i],
257
+ x: 0,
258
+ w: 1
259
+ }, 1);
260
+ out[i] = {
261
+ ...item,
262
+ y
263
+ };
264
+ y += item.h;
265
+ }
266
+ return out;
267
+ }
268
+ const scale = to / from;
269
+ const edge = (value) => Math.round(value * scale);
270
+ const limit = (value) => value === void 0 ? void 0 : Math.max(1, edge(value));
271
+ return normalizeLayout(items.map((item) => {
272
+ const x = edge(item.x);
273
+ return fitItem({
274
+ ...item,
275
+ x,
276
+ w: Math.max(1, edge(item.x + item.w) - x),
277
+ minW: limit(item.minW),
278
+ maxW: limit(item.maxW)
279
+ }, to);
280
+ }), options);
281
+ }
282
+ export { compactLayout, deriveLayout, findPlace, fitItem, layoutHeight, moveItem, moveItemBy, normalizeLayout, overlaps, resizeItem, resizeItemBy };
283
+
284
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","names":[],"sources":["../../src/layout/engine.ts"],"sourcesContent":["import type { GridItem, GridLayoutOptions, GridPosition, GridSize } from './types'\n\n/*\n * The layout engine: plain functions from a layout to a layout.\n *\n * Every function returns a new array in the same order as the one it was\n * given, and keeps the objects of the items that did not move, so a caller\n * can tell what changed by identity. The same input always gives the same\n * output: the order items are settled in depends only on their positions\n * and their places in the array, which is what lets several people editing\n * the same layout end up with the same result.\n */\n\ntype Box = Pick<GridItem, 'x' | 'y' | 'w' | 'h'>\n\n/** Whether two boxes share at least one cell. */\nexport function overlaps(a: Box, b: Box): boolean {\n return a.x < b.x + b.w && b.x < a.x + a.w && a.y < b.y + b.h && b.y < a.y + a.h\n}\n\n/** The row just below the lowest item: how many rows the layout takes up. */\nexport function layoutHeight(items: readonly Box[]): number {\n let bottom = 0\n for (const item of items) bottom = Math.max(bottom, item.y + item.h)\n return bottom\n}\n\nconst int = (value: number, fallback: number) =>\n Number.isFinite(value) ? Math.round(value) : fallback\n\n/** The width an item may have on a grid of `columns`. */\nfunction clampW(item: GridItem, w: number, columns: number) {\n const max = Math.min(columns, item.maxW ?? columns)\n const min = Math.min(max, Math.max(1, item.minW ?? 1))\n return Math.min(max, Math.max(min, int(w, min)))\n}\n\nfunction clampH(item: GridItem, h: number) {\n const max = Math.max(1, item.maxH ?? Infinity)\n const min = Math.min(max, Math.max(1, item.minH ?? 1))\n return Math.min(max, Math.max(min, int(h, min)))\n}\n\n/**\n * The item with its size inside its limits and the grid's width, and its\n * position on the grid, in whole cells. Returns the item itself when it fits.\n */\nexport function fitItem(item: GridItem, columns: number): GridItem {\n const w = clampW(item, item.w, columns)\n const h = clampH(item, item.h)\n const x = Math.min(columns - w, Math.max(0, int(item.x, 0)))\n const y = Math.max(0, int(item.y, 0))\n return x === item.x && y === item.y && w === item.w && h === item.h\n ? item\n : { ...item, x, y, w, h }\n}\n\nconst at = (item: GridItem, x: number, y: number): GridItem =>\n item.x === x && item.y === y ? item : { ...item, x, y }\n\n/**\n * Where an item the moved one landed on could step aside to: the same\n * row, shifted into the columns the moved item left. This is what turns\n * dropping an item onto its neighbour into a swap, instead of pushing the\n * neighbour down. `undefined` when the item isn't in the way, or wouldn't\n * fit in those columns.\n */\nfunction aside(item: GridItem, fixed?: GridItem, origin?: Box): number | undefined {\n if (!fixed || !origin || !overlaps(item, fixed)) return undefined\n const hi = origin.x + origin.w - item.w\n if (hi < origin.x) return undefined\n const x = Math.min(hi, Math.max(origin.x, item.x))\n return x === item.x ? undefined : x\n}\n\n/** The first of `boxes` that shares a cell with the box, if any. */\nfunction hit(boxes: readonly Box[], box: Box): Box | undefined {\n for (const other of boxes) if (overlaps(other, box)) return other\n return undefined\n}\n\n/** Moves the box down until it is clear of every one of `boxes`; returns its row. */\nfunction below(boxes: readonly Box[], box: Box): number {\n const probe = { ...box }\n for (let other = hit(boxes, probe); other; other = hit(boxes, probe)) probe.y = other.y + other.h\n return probe.y\n}\n\n/**\n * Settles every item that isn't locked and isn't `fixed`; those stay where\n * they are and the rest go around them. Items are settled from the top\n * down (then left to right, then by their place in the array).\n */\nfunction settle(\n items: readonly GridItem[],\n options: GridLayoutOptions,\n fixed?: GridItem,\n origin?: Box,\n): GridItem[] {\n const out = items.slice()\n const obstacles: GridItem[] = []\n const order: number[] = []\n items.forEach((item, i) => {\n if (item.locked || item === fixed) obstacles.push(item)\n else order.push(i)\n })\n order.sort((a, b) => items[a]!.y - items[b]!.y || items[a]!.x - items[b]!.x || a - b)\n\n if (options.compact === false) {\n // Each item keeps its row unless something settled before it is in the way.\n const placed = obstacles.slice()\n for (const i of order) {\n const item = items[i]!\n let x = item.x\n let y = below(placed, item)\n const side = aside(item, fixed, origin)\n if (side !== undefined && !hit(placed, { ...item, x: side })) [x, y] = [side, item.y]\n placed.push((out[i] = at(item, x, y)))\n }\n return out\n }\n\n // `top[c]` is the row below everything settled so far in column `c`: an\n // item can float up to the lowest of these across its columns, which is\n // as far as it can go without passing an item that was above it.\n const top = new Int32Array(options.columns)\n for (const i of order) {\n const item = items[i]!\n const rise = (x: number) => {\n let y = 0\n for (let c = x; c < x + item.w; c++) y = Math.max(y, top[c] ?? 0)\n return below(obstacles, { x, y, w: item.w, h: item.h })\n }\n let x = item.x\n let y = rise(x)\n const side = aside(item, fixed, origin)\n if (side !== undefined) {\n const y2 = rise(side)\n if (y2 < y) [x, y] = [side, y2]\n }\n for (let c = x; c < x + item.w; c++) top[c] = y + item.h\n out[i] = at(item, x, y)\n }\n return out\n}\n\n/**\n * The layout fitted to the grid: sizes inside their limits, nothing past\n * the last column, no two items on the same cell and, when compacting,\n * no gaps above items. Returns `items` itself when it is already settled.\n */\nexport function normalizeLayout(\n items: readonly GridItem[],\n options: GridLayoutOptions,\n): readonly GridItem[] {\n const fitted = items.map((item) => fitItem(item, options.columns))\n const out = settle(fitted, options)\n return out.every((item, i) => item === items[i]) ? items : out\n}\n\n/** Floats every item up as far as it goes (ignores `compact`). */\nexport function compactLayout(items: readonly GridItem[], columns: number): GridItem[] {\n return settle(items, { columns, compact: 'vertical' })\n}\n\n/** Puts `item` at the given place, moved down below any locked item it lands on. */\nfunction place(\n items: readonly GridItem[],\n index: number,\n next: GridItem,\n options: GridLayoutOptions,\n): GridItem[] {\n const locked = items.filter((other) => other.locked && other !== items[index])\n const y = below(locked, next)\n const out = items.slice()\n const moved = (out[index] = at(next, next.x, y))\n const settled = settle(out, options, moved, items[index])\n // Compacting a second time lets the item itself float up into the gap\n // it would otherwise leave, and puts it after the items it was dropped below.\n return options.compact === false ? settled : settle(settled, options)\n}\n\n/**\n * Moves an item to a cell; the items it lands on make way. Locked items\n * and unknown ids leave the layout as it is.\n */\nexport function moveItem(\n items: readonly GridItem[],\n id: string,\n to: GridPosition,\n options: GridLayoutOptions,\n): readonly GridItem[] {\n const index = items.findIndex((item) => item.id === id)\n const item = items[index]\n if (!item || item.locked) return items\n const x = Math.min(options.columns - item.w, Math.max(0, int(to.x, item.x)))\n const y = Math.max(0, int(to.y, item.y))\n return place(items, index, { ...item, x, y }, options)\n}\n\n/**\n * Gives an item a new size, keeping its top-left corner; the items it now\n * covers make way. A size that would cover a locked item is refused.\n */\nexport function resizeItem(\n items: readonly GridItem[],\n id: string,\n to: GridSize,\n options: GridLayoutOptions,\n): readonly GridItem[] {\n const index = items.findIndex((item) => item.id === id)\n const item = items[index]\n if (!item || item.locked) return items\n const w = Math.min(options.columns - item.x, clampW(item, to.w, options.columns))\n const h = clampH(item, to.h)\n const next = { ...item, w: Math.max(1, w), h }\n if (items.some((other) => other.locked && other !== item && overlaps(other, next))) return items\n return place(items, index, next, options)\n}\n\nconst sameSpot = (a: GridItem | undefined, b: GridItem) =>\n !!a && a.x === b.x && a.y === b.y && a.w === b.w && a.h === b.h\n\n/**\n * Moves an item by whole cells, as the arrow keys do. Moving up or down\n * goes on past rows where the item would only settle back where it was,\n * so one press always moves it, to the next place it can take.\n */\nexport function moveItemBy(\n items: readonly GridItem[],\n id: string,\n dx: number,\n dy: number,\n options: GridLayoutOptions,\n): readonly GridItem[] {\n const item = items.find((other) => other.id === id)\n if (!item || item.locked) return items\n if (!dy) return moveItem(items, id, { x: item.x + dx, y: item.y }, options)\n const step = Math.sign(dy)\n const last = layoutHeight(items)\n for (let y = item.y + dy; y >= 0 && y <= last; y += step) {\n const out = moveItem(items, id, { x: item.x + dx, y }, options)\n if (\n !sameSpot(\n out.find((other) => other.id === id),\n item,\n )\n )\n return out\n }\n return items\n}\n\n/** Resizes an item by whole cells, as Shift and the arrow keys do. */\nexport function resizeItemBy(\n items: readonly GridItem[],\n id: string,\n dw: number,\n dh: number,\n options: GridLayoutOptions,\n): readonly GridItem[] {\n const item = items.find((other) => other.id === id)\n if (!item) return items\n return resizeItem(items, id, { w: item.w + dw, h: item.h + dh }, options)\n}\n\n/**\n * Where a new item of `size` fits: the first free spot reading from the top\n * left, or below everything when no row has room.\n */\nexport function findPlace(\n items: readonly GridItem[],\n size: GridSize,\n options: GridLayoutOptions,\n): GridPosition {\n const w = Math.min(options.columns, Math.max(1, Math.round(size.w)))\n const h = Math.max(1, Math.round(size.h))\n const bottom = layoutHeight(items)\n for (let y = 0; y < bottom; y++)\n for (let x = 0; x + w <= options.columns; x++) {\n const other = hit(items, { x, y, w, h })\n if (!other) return { x, y }\n // skip to the column after the item in the way\n x = other.x + other.w - 1\n }\n return { x: 0, y: bottom }\n}\n\n/**\n * The layout worked out for a grid of another width: positions and widths\n * scaled by the ratio of the columns, then settled. On a single column the\n * items are stacked in reading order (top to bottom, then left to right),\n * each keeping its height.\n */\nexport function deriveLayout(\n items: readonly GridItem[],\n from: number,\n options: GridLayoutOptions,\n): readonly GridItem[] {\n const to = options.columns\n if (from === to) return normalizeLayout(items, options)\n if (to === 1) {\n const order = items.map((_, i) => i)\n order.sort((a, b) => items[a]!.y - items[b]!.y || items[a]!.x - items[b]!.x || a - b)\n const out = items.slice()\n let y = 0\n for (const i of order) {\n const item = fitItem({ ...items[i]!, x: 0, w: 1 }, 1)\n out[i] = { ...item, y }\n y += item.h\n }\n return out\n }\n const scale = to / from\n // both edges are scaled, so items side by side stay side by side\n const edge = (value: number) => Math.round(value * scale)\n const limit = (value: number | undefined) =>\n value === undefined ? undefined : Math.max(1, edge(value))\n const scaled = items.map((item) => {\n const x = edge(item.x)\n return fitItem(\n {\n ...item,\n x,\n w: Math.max(1, edge(item.x + item.w) - x),\n minW: limit(item.minW),\n maxW: limit(item.maxW),\n },\n to,\n )\n })\n return normalizeLayout(scaled, options)\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export { compactLayout, deriveLayout, findPlace, fitItem, layoutHeight, moveItem, moveItemBy, normalizeLayout, overlaps, resizeItem, resizeItemBy } from "./engine.js";