Allow button groups to be collapsed

This commit is contained in:
Andrew Kingston 2024-09-02 09:31:19 +01:00
parent 2d52eff96f
commit fae897f468
No known key found for this signature in database
7 changed files with 129 additions and 44 deletions

View File

@ -246,7 +246,7 @@ export default function positionDropdown(element, opts) {
}
// Apply initial styles which don't need to change
element.style.position = "absolute"
element.style.position = "fixed"
element.style.zIndex = "9999"
// Set up a scroll listener

View File

@ -17,6 +17,7 @@
export let tooltip = undefined
export let newStyles = true
export let id
export let ref
const dispatch = createEventDispatcher()
</script>
@ -25,6 +26,7 @@
<button
{id}
{type}
bind:this={ref}
class:spectrum-Button--cta={cta}
class:spectrum-Button--primary={primary}
class:spectrum-Button--secondary={secondary}

View File

@ -60,7 +60,7 @@
$: darkMode = !currentTheme.includes("light")
$: buttons = [
{
text: "Actions",
text: "Action",
type: "cta",
icon: "ChevronDown",
onClick: async (e, row, refresh) => {

View File

@ -447,6 +447,18 @@
"section": true,
"name": "Layout",
"settings": [
{
"type": "boolean",
"label": "Collapse",
"key": "collapsed"
},
{
"type": "text",
"label": "Collapsed text",
"key": "collapsedText",
"dependsOn": "collapsed",
"placeholder": "Action"
},
{
"type": "select",
"label": "Direction",
@ -467,7 +479,11 @@
"barTitle": "Row layout"
}
],
"defaultValue": "row"
"defaultValue": "row",
"dependsOn": {
"setting": "collapsed",
"invert": true
}
},
{
"type": "select",
@ -501,7 +517,11 @@
"barTitle": "Align stretched horizontally"
}
],
"defaultValue": "left"
"defaultValue": "left",
"dependsOn": {
"setting": "collapsed",
"invert": true
}
},
{
"type": "select",
@ -535,7 +555,11 @@
"barTitle": "Align stretched vertically"
}
],
"defaultValue": "top"
"defaultValue": "top",
"dependsOn": {
"setting": "collapsed",
"invert": true
}
},
{
"type": "select",
@ -557,7 +581,11 @@
"barTitle": "Grow container"
}
],
"defaultValue": "shrink"
"defaultValue": "shrink",
"dependsOn": {
"setting": "collapsed",
"invert": true
}
},
{
"type": "select",
@ -583,7 +611,11 @@
"value": "L"
}
],
"defaultValue": "M"
"defaultValue": "M",
"dependsOn": {
"setting": "collapsed",
"invert": true
}
},
{
"type": "boolean",
@ -591,7 +623,11 @@
"key": "wrap",
"showInBar": true,
"barIcon": "ModernGridView",
"barTitle": "Wrap"
"barTitle": "Wrap",
"dependsOn": {
"setting": "collapsed",
"invert": true
}
}
]
}

View File

@ -1,44 +1,86 @@
<script>
import BlockComponent from "../BlockComponent.svelte"
import Block from "../Block.svelte"
import { Button, Popover, Menu, MenuItem } from "@budibase/bbui"
import { getContext } from "svelte"
export let buttons = []
export let direction = "row"
export let hAlign = "left"
export let vAlign = "top"
export let gap = "S"
export let collapsed = false
export let collapsedText = "Action"
const { styleable, enrichButtonActions } = getContext("sdk")
const component = getContext("component")
const context = getContext("context")
let popover
let anchor
const handleCollapsedClick = async button => {
const fn = enrichButtonActions(button.onClick, $context)
await fn?.()
popover.hide()
}
</script>
<Block>
<BlockComponent
type="container"
props={{
direction,
hAlign,
vAlign,
gap,
wrap: true,
}}
styles={{
normal: {
height: "100%",
},
}}
>
{#each buttons as { text, type, quiet, disabled, onClick, size, icon, gap }}
<BlockComponent
type="button"
props={{
text: text || "Button",
onClick,
type,
quiet,
disabled,
icon,
gap,
size: size || "M",
}}
/>
{/each}
</BlockComponent>
</Block>
{#if collapsed}
<div use:styleable={$component.styles}>
<Button
bind:ref={anchor}
on:click={() => popover?.show()}
icon="ChevronDown"
cta
>
{collapsedText || "Action"}
</Button>
</div>
<Popover bind:this={popover} align="left" {anchor}>
<Menu>
{#each buttons as button}
<MenuItem
on:click={() => handleCollapsedClick(button)}
disabled={button.disabled}
>
{button.text || "Button"}
</MenuItem>
{/each}
</Menu>
</Popover>
{:else}
<Block>
<BlockComponent
type="container"
props={{
direction,
hAlign,
vAlign,
gap,
wrap: true,
}}
styles={{
normal: {
height: "100%",
},
}}
>
{#each buttons as { text, type, quiet, disabled, onClick, size, icon, gap }}
<BlockComponent
type="button"
props={{
text: text || "Button",
onClick,
type,
quiet,
disabled,
icon,
gap,
size: size || "M",
}}
/>
{/each}
</BlockComponent>
</Block>
{/if}

View File

@ -16,7 +16,12 @@
$: style = getStyle(width, selectedUser, metadata)
const getStyle = (width, selectedUser, metadata) => {
let style = width === "auto" ? "width: auto;" : `flex: 0 0 ${width}px;`
let style
if (width === "auto" || width === "100%") {
style = `width: ${width};`
} else {
style = `flex: 0 0 ${width}px;`
}
if (selectedUser) {
style += `--user-color :${selectedUser.color};`
}

View File

@ -45,7 +45,7 @@
onMount(() => {
const observer = new ResizeObserver(entries => {
const width = entries?.[0]?.contentRect?.width ?? 0
buttonColumnWidth.set(Math.floor(width) - 1)
buttonColumnWidth.set(width)
})
observer.observe(container)
})
@ -113,7 +113,7 @@
on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
>
<GridCell
width={$buttonColumnWidth}
width="100%"
highlighted={$hoveredRowId === BlankRowID}
on:click={() => dispatch("add-row-inline")}
/>