Make sheet gutter width customisable
This commit is contained in:
parent
09f4f210ee
commit
5640b2fa89
33 changed files with 120 additions and 88 deletions
|
@ -1,3 +1,3 @@
|
|||
export { default as SplitPage } from "./SplitPage.svelte"
|
||||
export { default as TestimonialPage } from "./TestimonialPage.svelte"
|
||||
export { default as Sheet } from "./sheet/Sheet.svelte"
|
||||
export { Sheet } from "./sheet"
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
<script>
|
||||
import SortButton from "./controls/SortButton.svelte"
|
||||
import HideColumnsButton from "./controls/HideColumnsButton.svelte"
|
||||
</script>
|
||||
|
||||
<HideColumnsButton />
|
||||
<SortButton />
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import SheetCell from "./SheetCell.svelte"
|
||||
import { getCellRenderer } from "../renderers"
|
||||
import { getCellRenderer } from "../lib/renderers"
|
||||
|
||||
const { rows, selectedCellId, menu, selectedCellAPI } = getContext("sheet")
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { getContext } from "svelte"
|
||||
import SheetCell from "./SheetCell.svelte"
|
||||
import { Icon, Popover, Menu, MenuItem } from "@budibase/bbui"
|
||||
import { getColumnIcon } from "../utils"
|
||||
import { getColumnIcon } from "../lib/utils"
|
||||
|
||||
export let column
|
||||
export let idx
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { Icon } from "@budibase/bbui"
|
||||
import { getColor } from "../utils"
|
||||
import { getColor } from "../lib/utils"
|
||||
import { onMount } from "svelte"
|
||||
|
||||
export let value
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { getColor } from "../utils"
|
||||
import { getColor } from "../lib/utils"
|
||||
import { onMount, getContext } from "svelte"
|
||||
import { Icon, Input } from "@budibase/bbui"
|
||||
import { debounce } from "../../../utils/utils"
|
||||
|
|
1
packages/frontend-core/src/components/sheet/index.js
Normal file
1
packages/frontend-core/src/components/sheet/index.js
Normal file
|
@ -0,0 +1 @@
|
|||
export { default as Sheet } from "./layout/Sheet.svelte"
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import SheetScrollWrapper from "./SheetScrollWrapper.svelte"
|
||||
import HeaderCell from "./cells/HeaderCell.svelte"
|
||||
import HeaderCell from "../cells/HeaderCell.svelte"
|
||||
import { Icon } from "@budibase/bbui"
|
||||
|
||||
const { renderedColumns, dispatch, config, ui } = getContext("sheet")
|
|
@ -1,9 +1,9 @@
|
|||
<script>
|
||||
import SheetCell from "./cells/SheetCell.svelte"
|
||||
import SheetCell from "../cells/SheetCell.svelte"
|
||||
import { getContext } from "svelte"
|
||||
import { Icon } from "@budibase/bbui"
|
||||
import SheetScrollWrapper from "./SheetScrollWrapper.svelte"
|
||||
import { getCellRenderer } from "./renderers"
|
||||
import { getCellRenderer } from "../lib/renderers"
|
||||
|
||||
const {
|
||||
renderedColumns,
|
||||
|
@ -12,13 +12,14 @@
|
|||
selectedCellId,
|
||||
reorder,
|
||||
stickyColumn,
|
||||
gutterWidth,
|
||||
} = getContext("sheet")
|
||||
|
||||
let isAdding = false
|
||||
let newRow = {}
|
||||
|
||||
$: rowHovered = $hoveredRowId === "new"
|
||||
$: width = 40 + ($stickyColumn?.width || 0)
|
||||
$: width = gutterWidth + ($stickyColumn?.width || 0)
|
||||
|
||||
const addRow = async field => {
|
||||
// const newRow = await rows.actions.addRow()
|
||||
|
@ -48,7 +49,7 @@
|
|||
</div>
|
||||
{:else}
|
||||
<div class="sticky" style="flex: 0 0 {width}px">
|
||||
<SheetCell width="40" center>
|
||||
<SheetCell width={gutterWidth} center>
|
||||
<Icon name="Add" size="S" />
|
||||
</SheetCell>
|
||||
{#if $stickyColumn}
|
||||
|
@ -116,7 +117,7 @@
|
|||
background: var(--cell-background-hover);
|
||||
}
|
||||
.add .icon {
|
||||
flex: 0 0 40px;
|
||||
flex: 0 0 var(--gutter-width);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
|
@ -1,33 +1,33 @@
|
|||
<script>
|
||||
import { setContext, onMount } from "svelte"
|
||||
import { setContext } from "svelte"
|
||||
import { writable } from "svelte/store"
|
||||
import { createEventManagers } from "./events"
|
||||
import { createAPIClient } from "../../api"
|
||||
import { createReorderStores } from "./stores/reorder"
|
||||
import { createViewportStores } from "./stores/viewport"
|
||||
import { createRowsStore } from "./stores/rows"
|
||||
import { createColumnsStores } from "./stores/columns"
|
||||
import { createScrollStores } from "./stores/scroll"
|
||||
import { createBoundsStores } from "./stores/bounds"
|
||||
import { createUIStores } from "./stores/ui"
|
||||
import { createUserStores } from "./stores/users"
|
||||
import { createWebsocket } from "./websocket"
|
||||
import { createResizeStores } from "./stores/resize"
|
||||
import { createMenuStores } from "./stores/menu"
|
||||
import { createMaxScrollStores } from "./stores/max-scroll"
|
||||
import { createPaginationStores } from "./stores/pagination"
|
||||
import DeleteButton from "./DeleteButton.svelte"
|
||||
import { createEventManagers } from "../lib/events"
|
||||
import { createAPIClient } from "../../../api"
|
||||
import { createReorderStores } from "../stores/reorder"
|
||||
import { createViewportStores } from "../stores/viewport"
|
||||
import { createRowsStore } from "../stores/rows"
|
||||
import { createColumnsStores } from "../stores/columns"
|
||||
import { createScrollStores } from "../stores/scroll"
|
||||
import { createBoundsStores } from "../stores/bounds"
|
||||
import { createUIStores } from "../stores/ui"
|
||||
import { createUserStores } from "../stores/users"
|
||||
import { createResizeStores } from "../stores/resize"
|
||||
import { createMenuStores } from "../stores/menu"
|
||||
import { createMaxScrollStores } from "../stores/max-scroll"
|
||||
import { createPaginationStores } from "../stores/pagination"
|
||||
import DeleteButton from "../controls/DeleteButton.svelte"
|
||||
import SheetBody from "./SheetBody.svelte"
|
||||
import ResizeOverlay from "./ResizeOverlay.svelte"
|
||||
import ResizeOverlay from "../overlays/ResizeOverlay.svelte"
|
||||
import HeaderRow from "./HeaderRow.svelte"
|
||||
import ScrollOverlay from "./ScrollOverlay.svelte"
|
||||
import MenuOverlay from "./MenuOverlay.svelte"
|
||||
import ScrollOverlay from "../overlays/ScrollOverlay.svelte"
|
||||
import MenuOverlay from "../overlays/MenuOverlay.svelte"
|
||||
import StickyColumn from "./StickyColumn.svelte"
|
||||
import UserAvatars from "./UserAvatars.svelte"
|
||||
import KeyboardManager from "./KeyboardManager.svelte"
|
||||
import KeyboardManager from "../overlays/KeyboardManager.svelte"
|
||||
import { clickOutside } from "@budibase/bbui"
|
||||
import AddRowButton from "./AddRowButton.svelte"
|
||||
import AddRowButton from "../controls/AddRowButton.svelte"
|
||||
import SheetControls from "./SheetControls.svelte"
|
||||
import SidePanel from "./SidePanel.svelte"
|
||||
|
||||
export let API
|
||||
export let tableId
|
||||
|
@ -38,6 +38,7 @@
|
|||
|
||||
// Sheet constants
|
||||
const cellHeight = 36
|
||||
const gutterWidth = 80
|
||||
const rand = Math.random()
|
||||
|
||||
// State stores
|
||||
|
@ -55,6 +56,7 @@
|
|||
API: API || createAPIClient(),
|
||||
rand,
|
||||
cellHeight,
|
||||
gutterWidth,
|
||||
config,
|
||||
}
|
||||
context = { ...context, ...createEventManagers() }
|
||||
|
@ -98,7 +100,7 @@
|
|||
id="sheet-{rand}"
|
||||
class:is-resizing={$isResizing}
|
||||
class:is-reordering={$isReordering}
|
||||
style="--cell-height:{cellHeight}px;"
|
||||
style="--cell-height:{cellHeight}px; --gutter-width:{gutterWidth}px;"
|
||||
>
|
||||
<div class="controls">
|
||||
<div class="controls-left">
|
||||
|
@ -125,6 +127,7 @@
|
|||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<SidePanel />
|
||||
<KeyboardManager />
|
||||
</div>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<script>
|
||||
import SortButton from "../controls/SortButton.svelte"
|
||||
import HideColumnsButton from "../controls/HideColumnsButton.svelte"
|
||||
</script>
|
||||
|
||||
<HideColumnsButton />
|
||||
<SortButton />
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import DataCell from "./cells/DataCell.svelte"
|
||||
import DataCell from "../cells/DataCell.svelte"
|
||||
|
||||
export let row
|
||||
export let idx
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { domDebounce } from "../../utils/utils"
|
||||
import { domDebounce } from "../../../utils/utils"
|
||||
|
||||
const {
|
||||
cellHeight,
|
|
@ -0,0 +1,20 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
|
||||
const { sidePanelRowId } = getContext("sheet")
|
||||
|
||||
$: visible = $sidePanelRowId != null
|
||||
</script>
|
||||
|
||||
<div class="side-panel" class:visible>some content</div>
|
||||
|
||||
<style>
|
||||
.side-panel {
|
||||
width: 320px;
|
||||
transform: translateX(100%);
|
||||
transition: transform 130ms ease-out;
|
||||
}
|
||||
.side-panel.visible {
|
||||
transform: translateX(0);
|
||||
}
|
||||
</style>
|
|
@ -1,10 +1,10 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { Checkbox } from "@budibase/bbui"
|
||||
import SheetCell from "./cells/SheetCell.svelte"
|
||||
import DataCell from "./cells/DataCell.svelte"
|
||||
import SheetCell from "../cells/SheetCell.svelte"
|
||||
import DataCell from "../cells/DataCell.svelte"
|
||||
import SheetScrollWrapper from "./SheetScrollWrapper.svelte"
|
||||
import HeaderCell from "./cells/HeaderCell.svelte"
|
||||
import HeaderCell from "../cells/HeaderCell.svelte"
|
||||
|
||||
const {
|
||||
rows,
|
||||
|
@ -18,12 +18,13 @@
|
|||
config,
|
||||
selectedCellMap,
|
||||
selectedCellRow,
|
||||
gutterWidth,
|
||||
} = getContext("sheet")
|
||||
|
||||
$: scrollLeft = $scroll.left
|
||||
$: rowCount = $rows.length
|
||||
$: selectedRowCount = Object.values($selectedRows).filter(x => !!x).length
|
||||
$: width = 40 + ($stickyColumn?.width || 0)
|
||||
$: width = gutterWidth + ($stickyColumn?.width || 0)
|
||||
|
||||
const selectAll = () => {
|
||||
const allSelected = selectedRowCount === rowCount
|
||||
|
@ -59,7 +60,7 @@
|
|||
>
|
||||
<div class="header row">
|
||||
<SheetCell
|
||||
width="40"
|
||||
width={gutterWidth}
|
||||
on:click={$config.allowSelectRows && selectAll}
|
||||
center
|
||||
>
|
||||
|
@ -90,7 +91,7 @@
|
|||
<SheetCell
|
||||
rowSelected={rowSelected || containsSelectedRow}
|
||||
{rowHovered}
|
||||
width="40"
|
||||
width={gutterWidth}
|
||||
center
|
||||
>
|
||||
<div
|
29
packages/frontend-core/src/components/sheet/lib/renderers.js
Normal file
29
packages/frontend-core/src/components/sheet/lib/renderers.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import OptionsCell from "../cells/OptionsCell.svelte"
|
||||
import DateCell from "../cells/DateCell.svelte"
|
||||
import MultiSelectCell from "../cells/MultiSelectCell.svelte"
|
||||
import NumberCell from "../cells/NumberCell.svelte"
|
||||
import RelationshipCell from "../cells/RelationshipCell.svelte"
|
||||
import TextCell from "../cells/TextCell.svelte"
|
||||
import LongFormCell from "../cells/LongFormCell.svelte"
|
||||
import BooleanCell from "../cells/BooleanCell.svelte"
|
||||
import FormulaCell from "../cells/FormulaCell.svelte"
|
||||
import JSONCell from "../cells/JSONCell.svelte"
|
||||
import AttachmentCell from "../cells/AttachmentCell.svelte"
|
||||
|
||||
const TypeComponentMap = {
|
||||
text: TextCell,
|
||||
options: OptionsCell,
|
||||
datetime: DateCell,
|
||||
barcodeqr: TextCell,
|
||||
longform: LongFormCell,
|
||||
array: MultiSelectCell,
|
||||
number: NumberCell,
|
||||
boolean: BooleanCell,
|
||||
attachment: AttachmentCell,
|
||||
link: RelationshipCell,
|
||||
formula: FormulaCell,
|
||||
json: JSONCell,
|
||||
}
|
||||
export const getCellRenderer = column => {
|
||||
return TypeComponentMap[column?.schema?.type] || TextCell
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { getContext, onMount } from "svelte"
|
||||
import { debounce } from "../../utils/utils"
|
||||
import { debounce } from "../../../utils/utils"
|
||||
|
||||
const {
|
||||
rows,
|
|
@ -8,11 +8,12 @@
|
|||
renderedColumns,
|
||||
stickyColumn,
|
||||
isReordering,
|
||||
gutterWidth,
|
||||
} = getContext("sheet")
|
||||
|
||||
$: scrollLeft = $scroll.left
|
||||
$: cutoff = scrollLeft + 40 + ($columns[0]?.width || 0)
|
||||
$: offset = 40 + ($stickyColumn?.width || 0)
|
||||
$: cutoff = scrollLeft + gutterWidth + ($columns[0]?.width || 0)
|
||||
$: offset = gutterWidth + ($stickyColumn?.width || 0)
|
||||
$: column = $resize.column
|
||||
|
||||
const getStyle = (column, offset, scrollLeft) => {
|
||||
|
@ -28,7 +29,7 @@
|
|||
class:visible={column === $stickyColumn.name}
|
||||
on:mousedown={e => resize.actions.startResizing($stickyColumn, e)}
|
||||
on:dblclick={() => resize.actions.resetSize($stickyColumn)}
|
||||
style="left:{40 + $stickyColumn.width}px;"
|
||||
style="left:{gutterWidth + $stickyColumn.width}px;"
|
||||
>
|
||||
<div class="resize-indicator" />
|
||||
</div>
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { getContext } from "svelte"
|
||||
import { domDebounce } from "../../utils/utils"
|
||||
import { domDebounce } from "../../../utils/utils"
|
||||
|
||||
const {
|
||||
scroll,
|
||||
|
@ -11,6 +11,7 @@
|
|||
maxScrollTop,
|
||||
contentWidth,
|
||||
maxScrollLeft,
|
||||
gutterWidth,
|
||||
} = getContext("sheet")
|
||||
|
||||
// Bar config
|
||||
|
@ -36,7 +37,7 @@
|
|||
$: barTop = barOffset + cellHeight + availHeight * (scrollTop / $maxScrollTop)
|
||||
|
||||
// Calculate H scrollbar size and offset
|
||||
$: totalWidth = width + 40 + ($stickyColumn?.width || 0)
|
||||
$: totalWidth = width + gutterWidth + ($stickyColumn?.width || 0)
|
||||
$: renderWidth = totalWidth - 2 * barOffset
|
||||
$: barWidth = Math.max(50, (totalWidth / $contentWidth) * renderWidth)
|
||||
$: availWidth = renderWidth - barWidth
|
|
@ -1,29 +0,0 @@
|
|||
import OptionsCell from "./cells/OptionsCell.svelte"
|
||||
import DateCell from "./cells/DateCell.svelte"
|
||||
import MultiSelectCell from "./cells/MultiSelectCell.svelte"
|
||||
import NumberCell from "./cells/NumberCell.svelte"
|
||||
import RelationshipCell from "./cells/RelationshipCell.svelte"
|
||||
import TextCell from "./cells/TextCell.svelte"
|
||||
import LongFormCell from "./cells/LongFormCell.svelte"
|
||||
import BooleanCell from "./cells/BooleanCell.svelte"
|
||||
import FormulaCell from "./cells/FormulaCell.svelte"
|
||||
import JSONCell from "./cells/JSONCell.svelte"
|
||||
import AttachmentCell from "./cells/AttachmentCell.svelte"
|
||||
|
||||
const TypeComponentMap = {
|
||||
text: TextCell,
|
||||
options: OptionsCell,
|
||||
datetime: DateCell,
|
||||
barcodeqr: TextCell,
|
||||
longform: LongFormCell,
|
||||
array: MultiSelectCell,
|
||||
number: NumberCell,
|
||||
boolean: BooleanCell,
|
||||
attachment: AttachmentCell,
|
||||
link: RelationshipCell,
|
||||
formula: FormulaCell,
|
||||
json: JSONCell,
|
||||
}
|
||||
export const getCellRenderer = column => {
|
||||
return TypeComponentMap[column?.schema?.type] || TextCell
|
||||
}
|
|
@ -3,7 +3,7 @@ import { derived, get, writable } from "svelte/store"
|
|||
export const DefaultColumnWidth = 200
|
||||
|
||||
export const createColumnsStores = context => {
|
||||
const { table } = context
|
||||
const { table, gutterWidth } = context
|
||||
const columns = writable([])
|
||||
const stickyColumn = writable(null)
|
||||
|
||||
|
@ -93,7 +93,7 @@ export const createColumnsStores = context => {
|
|||
stickyColumn.set({
|
||||
name: primaryDisplay,
|
||||
width: existing?.width || DefaultColumnWidth,
|
||||
left: 40,
|
||||
left: gutterWidth,
|
||||
schema: schema[primaryDisplay],
|
||||
idx: "sticky",
|
||||
})
|
||||
|
|
|
@ -10,6 +10,7 @@ export const createMaxScrollStores = context => {
|
|||
scroll,
|
||||
selectedCellRow,
|
||||
selectedCellId,
|
||||
gutterWidth,
|
||||
} = context
|
||||
const padding = 255
|
||||
|
||||
|
@ -35,7 +36,7 @@ export const createMaxScrollStores = context => {
|
|||
const contentWidth = derived(
|
||||
[visibleColumns, stickyColumn],
|
||||
([$visibleColumns, $stickyColumn]) => {
|
||||
let width = 40 + padding + ($stickyColumn?.width || 0)
|
||||
let width = gutterWidth + padding + ($stickyColumn?.width || 0)
|
||||
$visibleColumns.forEach(col => {
|
||||
width += col.width
|
||||
})
|
||||
|
@ -45,7 +46,8 @@ export const createMaxScrollStores = context => {
|
|||
)
|
||||
const screenWidth = derived(
|
||||
[width, stickyColumn],
|
||||
([$width, $stickyColumn]) => $width + 40 + ($stickyColumn?.width || 0),
|
||||
([$width, $stickyColumn]) =>
|
||||
$width + gutterWidth + ($stickyColumn?.width || 0),
|
||||
0
|
||||
)
|
||||
const maxScrollLeft = derived(
|
||||
|
|
|
@ -6,6 +6,7 @@ export const createUIStores = context => {
|
|||
const selectedRows = writable({})
|
||||
const hoveredRowId = writable(null)
|
||||
const selectedCellAPI = writable(null)
|
||||
const sidePanelRowId = writable(null)
|
||||
|
||||
// Derive the row that contains the selected cell.
|
||||
const selectedCellRow = derived(
|
||||
|
@ -92,6 +93,7 @@ export const createUIStores = context => {
|
|||
hoveredRowId,
|
||||
selectedCellRow,
|
||||
selectedCellAPI,
|
||||
sidePanelRowId,
|
||||
ui: {
|
||||
actions: {
|
||||
blur,
|
||||
|
|
Loading…
Reference in a new issue