Standardise sizing of all settings and design properties

This commit is contained in:
Andrew Kingston 2020-10-23 10:34:14 +01:00
parent 3b869d2ff4
commit 4e4aa5c525
11 changed files with 576 additions and 564 deletions

View File

@ -48,7 +48,7 @@
{/each} {/each}
{:else} {:else}
<div class="no-design"> <div class="no-design">
This component does not have any design properties. This component doesn't have any design properties.
</div> </div>
{/if} {/if}
</div> </div>
@ -61,13 +61,7 @@
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
height: 100%; height: 100%;
gap: var(--spacing-m); gap: var(--spacing-l);
}
.design-view-container :global(.property-group-name .name) {
font-size: var(--font-size-xs);
}
.design-view-container :global(.property-group-container) {
padding: 4px 0;
} }
.design-view-state-categories { .design-view-state-categories {
@ -85,10 +79,15 @@
min-height: 0; min-height: 0;
margin: 0 -20px; margin: 0 -20px;
padding: 0 20px; padding: 0 20px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
gap: var(--spacing-m);
} }
.no-design { .no-design {
font-size: var(--font-size-s); font-size: var(--font-size-xs);
color: var(--grey-6); color: var(--grey-5);
} }
</style> </style>

View File

@ -15,11 +15,11 @@
return [ return [
...$store.screens ...$store.screens
.filter( .filter(
screen => (screen) =>
screen.props._component.endsWith("/rowdetail") || screen.props._component.endsWith("/rowdetail") ||
screen.route.endsWith(":id") screen.route.endsWith(":id")
) )
.map(screen => ({ .map((screen) => ({
name: screen.props._instanceName, name: screen.props._instanceName,
url: screen.route, url: screen.route,
sort: screen.props._component, sort: screen.props._component,
@ -29,7 +29,13 @@
</script> </script>
<div> <div>
<DataList editable secondary thin on:blur={handleBlur} on:change bind:value> <DataList
editable
secondary
extraThin
on:blur={handleBlur}
on:change
bind:value>
<option value="" /> <option value="" />
{#each urls as url} {#each urls as url}
<option value={url.url}>{url.name}</option> <option value={url.url}>{url.name}</option>

View File

@ -1,291 +1,291 @@
<script> <script>
import { DropdownMenu, Button, Input } from "@budibase/bbui" import { DropdownMenu, Button, Input } from "@budibase/bbui"
import { createEventDispatcher, tick } from "svelte" import { createEventDispatcher, tick } from "svelte"
import icons from "./icons.js" import icons from "./icons.js"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
export let value = "" export let value = ""
export let maxIconsPerPage = 30 export let maxIconsPerPage = 30
let searchTerm = "" let searchTerm = ""
let selectedLetter = "A" let selectedLetter = "A"
let currentPage = 1 let currentPage = 1
let filteredIcons = findIconByTerm(selectedLetter) let filteredIcons = findIconByTerm(selectedLetter)
$: dispatch("change", value) $: dispatch("change", value)
const alphabet = [ const alphabet = [
"A", "A",
"B", "B",
"C", "C",
"D", "D",
"E", "E",
"F", "F",
"G", "G",
"H", "H",
"I", "I",
"J", "J",
"K", "K",
"L", "L",
"M", "M",
"N", "N",
"O", "O",
"P", "P",
"Q", "Q",
"R", "R",
"S", "S",
"T", "T",
"U", "U",
"V", "V",
"W", "W",
"X", "X",
"Y", "Y",
"Z", "Z",
] ]
let buttonAnchor, dropdown let buttonAnchor, dropdown
let loading = false let loading = false
function findIconByTerm(term) { function findIconByTerm(term) {
const r = new RegExp(`\^${term}`, "i") const r = new RegExp(`\^${term}`, "i")
return icons.filter(i => r.test(i.label)) return icons.filter((i) => r.test(i.label))
} }
async function switchLetter(letter) { async function switchLetter(letter) {
currentPage = 1 currentPage = 1
searchTerm = "" searchTerm = ""
loading = true loading = true
selectedLetter = letter selectedLetter = letter
filteredIcons = findIconByTerm(letter) filteredIcons = findIconByTerm(letter)
await tick() //svg icons do not update without tick await tick() //svg icons do not update without tick
loading = false loading = false
} }
async function findIconOnPage() { async function findIconOnPage() {
loading = true loading = true
const iconIdx = filteredIcons.findIndex(i => i.value === value) const iconIdx = filteredIcons.findIndex((i) => i.value === value)
if (iconIdx !== -1) { if (iconIdx !== -1) {
currentPage = Math.ceil(iconIdx / maxIconsPerPage) currentPage = Math.ceil(iconIdx / maxIconsPerPage)
} }
await tick() //svg icons do not update without tick await tick() //svg icons do not update without tick
loading = false loading = false
} }
async function setSelectedUI() { async function setSelectedUI() {
if (value) { if (value) {
const letter = displayValue.substring(0, 1) const letter = displayValue.substring(0, 1)
await switchLetter(letter) await switchLetter(letter)
await findIconOnPage() await findIconOnPage()
} }
} }
async function pageClick(next) { async function pageClick(next) {
loading = true loading = true
if (next && currentPage < totalPages) { if (next && currentPage < totalPages) {
currentPage++ currentPage++
} else if (!next && currentPage > 1) { } else if (!next && currentPage > 1) {
currentPage-- currentPage--
} }
await tick() //svg icons do not update without tick await tick() //svg icons do not update without tick
loading = false loading = false
} }
async function searchForIcon(e) { async function searchForIcon(e) {
currentPage = 1 currentPage = 1
loading = true loading = true
filteredIcons = findIconByTerm(searchTerm) filteredIcons = findIconByTerm(searchTerm)
await tick() //svg icons do not update without tick await tick() //svg icons do not update without tick
loading = false loading = false
} }
$: displayValue = value ? value.substring(7) : "Pick Icon" $: displayValue = value ? value.substring(7) : "Pick Icon"
$: totalPages = Math.ceil(filteredIcons.length / maxIconsPerPage) $: totalPages = Math.ceil(filteredIcons.length / maxIconsPerPage)
$: pageEndIdx = maxIconsPerPage * currentPage $: pageEndIdx = maxIconsPerPage * currentPage
$: pagedIcons = filteredIcons.slice(pageEndIdx - maxIconsPerPage, pageEndIdx) $: pagedIcons = filteredIcons.slice(pageEndIdx - maxIconsPerPage, pageEndIdx)
$: pagerText = `Page ${currentPage} of ${totalPages}` $: pagerText = `Page ${currentPage} of ${totalPages}`
</script> </script>
<div bind:this={buttonAnchor}> <div bind:this={buttonAnchor}>
<Button secondary on:click={dropdown.show}>{displayValue}</Button> <Button secondary small on:click={dropdown.show}>{displayValue}</Button>
</div> </div>
<DropdownMenu <DropdownMenu
bind:this={dropdown} bind:this={dropdown}
on:open={setSelectedUI} on:open={setSelectedUI}
anchor={buttonAnchor}> anchor={buttonAnchor}>
<div class="container"> <div class="container">
<div class="search-area"> <div class="search-area">
<div class="alphabet-area"> <div class="alphabet-area">
{#each alphabet as letter, idx} {#each alphabet as letter, idx}
<span <span
class="letter" class="letter"
class:letter-selected={letter === selectedLetter} class:letter-selected={letter === selectedLetter}
on:click={() => switchLetter(letter)}> on:click={() => switchLetter(letter)}>
{letter} {letter}
</span> </span>
{#if idx !== alphabet.length - 1}<span>-</span>{/if} {#if idx !== alphabet.length - 1}<span>-</span>{/if}
{/each} {/each}
</div> </div>
<div class="search-input"> <div class="search-input">
<div class="input-wrapper"> <div class="input-wrapper">
<Input bind:value={searchTerm} thin placeholder="Search Icon" /> <Input bind:value={searchTerm} thin placeholder="Search Icon" />
</div> </div>
<Button secondary on:click={searchForIcon}>Search</Button> <Button secondary on:click={searchForIcon}>Search</Button>
</div> </div>
<div class="page-area"> <div class="page-area">
<div class="pager"> <div class="pager">
<span on:click={() => pageClick(false)}> <span on:click={() => pageClick(false)}>
<i class="page-btn fas fa-chevron-left" /> <i class="page-btn fas fa-chevron-left" />
</span> </span>
<span>{pagerText}</span> <span>{pagerText}</span>
<span on:click={() => pageClick(true)}> <span on:click={() => pageClick(true)}>
<i class="page-btn fas fa-chevron-right" /> <i class="page-btn fas fa-chevron-right" />
</span> </span>
</div> </div>
</div> </div>
</div> </div>
{#if pagedIcons.length > 0} {#if pagedIcons.length > 0}
<div class="icon-area"> <div class="icon-area">
{#if !loading} {#if !loading}
{#each pagedIcons as icon} {#each pagedIcons as icon}
<div <div
class="icon-container" class="icon-container"
class:selected={value === icon.value} class:selected={value === icon.value}
on:click={() => (value = icon.value)}> on:click={() => (value = icon.value)}>
<div class="icon-preview"> <div class="icon-preview">
<i class={`${icon.value} fa-3x`} /> <i class={`${icon.value} fa-3x`} />
</div> </div>
<div class="icon-label">{icon.label}</div> <div class="icon-label">{icon.label}</div>
</div> </div>
{/each} {/each}
{/if} {/if}
</div> </div>
{:else} {:else}
<div class="no-icons"> <div class="no-icons">
<h5> <h5>
{`There is no icons for this ${searchTerm ? 'search' : 'page'}`} {`There is no icons for this ${searchTerm ? 'search' : 'page'}`}
</h5> </h5>
</div> </div>
{/if} {/if}
</div> </div>
</DropdownMenu> </DropdownMenu>
<style> <style>
.container { .container {
width: 610px; width: 610px;
height: 350px; height: 350px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 10px 0px 10px 15px; padding: 10px 0px 10px 15px;
overflow-x: hidden; overflow-x: hidden;
} }
.search-area { .search-area {
flex: 0 0 80px; flex: 0 0 80px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.icon-area { .icon-area {
flex: 1; flex: 1;
display: grid; display: grid;
grid-template-columns: repeat(5, 1fr); grid-template-columns: repeat(5, 1fr);
grid-gap: 5px; grid-gap: 5px;
justify-content: flex-start; justify-content: flex-start;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
padding-right: 10px; padding-right: 10px;
} }
.no-icons { .no-icons {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.alphabet-area { .alphabet-area {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;
padding-bottom: 10px; padding-bottom: 10px;
padding-right: 15px; padding-right: 15px;
justify-content: space-around; justify-content: space-around;
} }
.loading-container { .loading-container {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.search-input { .search-input {
display: flex; display: flex;
flex-flow: row nowrap; flex-flow: row nowrap;
width: 100%; width: 100%;
padding-right: 15px; padding-right: 15px;
} }
.input-wrapper { .input-wrapper {
width: 510px; width: 510px;
margin-right: 5px; margin-right: 5px;
} }
.page-area { .page-area {
padding: 10px; padding: 10px;
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.letter { .letter {
color: var(--blue); color: var(--blue);
} }
.letter:hover { .letter:hover {
cursor: pointer; cursor: pointer;
text-decoration: underline; text-decoration: underline;
} }
.letter-selected { .letter-selected {
text-decoration: underline; text-decoration: underline;
} }
.icon-container { .icon-container {
height: 100px; height: 100px;
display: flex; display: flex;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
border: var(--border-dark); border: var(--border-dark);
} }
.icon-container:hover { .icon-container:hover {
cursor: pointer; cursor: pointer;
background: var(--grey-2); background: var(--grey-2);
} }
.selected { .selected {
background: var(--grey-3); background: var(--grey-3);
} }
.icon-preview { .icon-preview {
flex: 1; flex: 1;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.icon-label { .icon-label {
flex: 0 0 20px; flex: 0 0 20px;
text-align: center; text-align: center;
font-size: 12px; font-size: 12px;
} }
.page-btn { .page-btn {
color: var(--blue); color: var(--blue);
} }
.page-btn:hover { .page-btn:hover {
cursor: pointer; cursor: pointer;
} }
</style> </style>

View File

@ -175,7 +175,7 @@
.bb-select-anchor { .bb-select-anchor {
cursor: pointer; cursor: pointer;
display: flex; display: flex;
padding: var(--spacing-m); padding: var(--spacing-s) var(--spacing-m);
background-color: var(--grey-2); background-color: var(--grey-2);
border-radius: var(--border-radius-m); border-radius: var(--border-radius-m);
align-items: center; align-items: center;

View File

@ -147,7 +147,7 @@
height: 90%; height: 90%;
width: 2rem; width: 2rem;
background: var(--grey-2); background: var(--grey-2);
right: 10px; right: 4px;
--spacing-s: 0; --spacing-s: 0;
border-left: 0.5px solid var(--grey-3); border-left: 0.5px solid var(--grey-3);
outline-color: var(--blue); outline-color: var(--blue);

View File

@ -13,7 +13,7 @@
$: style = componentInstance["_styles"][styleCategory] || {} $: style = componentInstance["_styles"][styleCategory] || {}
</script> </script>
<DetailSummary {name} on:open show={open}> <DetailSummary {name} on:open show={open} thin>
<div> <div>
{#each properties as props} {#each properties as props}
<PropertyControl <PropertyControl
@ -34,6 +34,5 @@
justify-content: flex-start; justify-content: flex-start;
align-items: stretch; align-items: stretch;
gap: var(--spacing-s); gap: var(--spacing-s);
margin-top: var(--spacing-m);
} }
</style> </style>

View File

@ -8,4 +8,4 @@
export let name, value, placeholder, type export let name, value, placeholder, type
</script> </script>
<Input {name} {value} {placeholder} {type} thin on:change /> <Input {name} {value} {placeholder} {type} extraThin on:change />

View File

@ -1,88 +1,94 @@
<script> <script>
import { DataList } from "@budibase/bbui" import { DataList } from "@budibase/bbui"
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
import { store, backendUiStore } from "builderStore" import { store, backendUiStore } from "builderStore"
import fetchBindableProperties from "builderStore/fetchBindableProperties" import fetchBindableProperties from "builderStore/fetchBindableProperties"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
export let value = "" export let value = ""
$: urls = getUrls() $: urls = getUrls()
const handleBlur = () => dispatch("change", value) const handleBlur = () => dispatch("change", value)
// this will get urls of all screens, but only // this will get urls of all screens, but only
// choose detail screens that are usable in the current context // choose detail screens that are usable in the current context
// and substitute the :id param for the actual {{ ._id }} binding // and substitute the :id param for the actual {{ ._id }} binding
const getUrls = () => { const getUrls = () => {
const urls = [ const urls = [
...$store.screens ...$store.screens
.filter(screen => !screen.props._component.endsWith("/rowdetail")) .filter((screen) => !screen.props._component.endsWith("/rowdetail"))
.map(screen => ({ .map((screen) => ({
name: screen.props._instanceName, name: screen.props._instanceName,
url: screen.route, url: screen.route,
sort: screen.props._component, sort: screen.props._component,
})), })),
] ]
const bindableProperties = fetchBindableProperties({ const bindableProperties = fetchBindableProperties({
componentInstanceId: $store.currentComponentInfo._id, componentInstanceId: $store.currentComponentInfo._id,
components: $store.components, components: $store.components,
screen: $store.currentPreviewItem, screen: $store.currentPreviewItem,
tables: $backendUiStore.tables, tables: $backendUiStore.tables,
}) })
const detailScreens = $store.screens.filter(screen => const detailScreens = $store.screens.filter((screen) =>
screen.props._component.endsWith("/rowdetail") screen.props._component.endsWith("/rowdetail")
) )
for (let detailScreen of detailScreens) { for (let detailScreen of detailScreens) {
const idBinding = bindableProperties.find(p => { const idBinding = bindableProperties.find((p) => {
if ( if (
p.type === "context" && p.type === "context" &&
p.runtimeBinding.endsWith("._id") && p.runtimeBinding.endsWith("._id") &&
p.table p.table
) { ) {
const tableId = const tableId =
typeof p.table === "string" ? p.table : p.table.tableId typeof p.table === "string" ? p.table : p.table.tableId
return tableId === detailScreen.props.table return tableId === detailScreen.props.table
} }
return false return false
}) })
if (idBinding) { if (idBinding) {
urls.push({ urls.push({
name: detailScreen.props._instanceName, name: detailScreen.props._instanceName,
url: detailScreen.route.replace( url: detailScreen.route.replace(
":id", ":id",
`{{ ${idBinding.runtimeBinding} }}` `{{ ${idBinding.runtimeBinding} }}`
), ),
sort: detailScreen.props._component, sort: detailScreen.props._component,
}) })
} }
} }
return urls return urls
} }
</script> </script>
<div> <div>
<DataList editable secondary thin on:blur={handleBlur} on:change bind:value> <DataList
<option value="" /> editable
{#each urls as url} secondary
<option value={url.url}>{url.name}</option> extraThin
{/each} on:blur={handleBlur}
</DataList> on:change
</div> bind:value>
<option value="" />
<style> {#each urls as url}
div { <option value={url.url}>{url.name}</option>
flex: 1 1 auto; {/each}
display: flex; </DataList>
flex-direction: row; </div>
}
div :global(> div) { <style>
flex: 1 1 auto; div {
} flex: 1 1 auto;
</style> display: flex;
flex-direction: row;
}
div :global(> div) {
flex: 1 1 auto;
}
</style>

View File

@ -125,7 +125,9 @@
{/if} {/if}
{/each} {/each}
{:else} {:else}
<div class="empty">This component does not have any settings.</div> <div class="empty">
This component doesn't have any additional settings.
</div>
{/if} {/if}
</div> </div>
@ -139,9 +141,9 @@
} }
.empty { .empty {
font-size: var(--font-size-s); font-size: var(--font-size-xs);
margin-top: var(--spacing-m); margin-top: var(--spacing-m);
color: var(--grey-6); color: var(--grey-5);
} }
.duplicate-name { .duplicate-name {

View File

@ -6,7 +6,7 @@
</script> </script>
<div> <div>
<Select thin secondary wide on:change {value}> <Select extraThin secondary wide on:change {value}>
<option value="">Choose a table</option> <option value="">Choose a table</option>
{#each $backendUiStore.tables as table} {#each $backendUiStore.tables as table}
<option value={table._id}>{table.name}</option> <option value={table._id}>{table.name}</option>

View File

@ -1,163 +1,163 @@
<script> <script>
import { Button, Icon, DropdownMenu, Spacer, Heading } from "@budibase/bbui" import { Button, Icon, DropdownMenu, Spacer, Heading } from "@budibase/bbui"
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
import { store, backendUiStore } from "builderStore" import { store, backendUiStore } from "builderStore"
import fetchBindableProperties from "../../builderStore/fetchBindableProperties" import fetchBindableProperties from "../../builderStore/fetchBindableProperties"
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let anchorRight, dropdownRight let anchorRight, dropdownRight
export let value = {} export let value = {}
function handleSelected(selected) { function handleSelected(selected) {
dispatch("change", selected) dispatch("change", selected)
dropdownRight.hide() dropdownRight.hide()
} }
$: tables = $backendUiStore.tables.map(m => ({ $: tables = $backendUiStore.tables.map((m) => ({
label: m.name, label: m.name,
name: `all_${m._id}`, name: `all_${m._id}`,
tableId: m._id, tableId: m._id,
type: "table", type: "table",
})) }))
$: views = $backendUiStore.tables.reduce((acc, cur) => { $: views = $backendUiStore.tables.reduce((acc, cur) => {
let viewsArr = Object.entries(cur.views).map(([key, value]) => ({ let viewsArr = Object.entries(cur.views).map(([key, value]) => ({
label: key, label: key,
name: key, name: key,
...value, ...value,
type: "view", type: "view",
})) }))
return [...acc, ...viewsArr] return [...acc, ...viewsArr]
}, []) }, [])
$: bindableProperties = fetchBindableProperties({ $: bindableProperties = fetchBindableProperties({
componentInstanceId: $store.currentComponentInfo._id, componentInstanceId: $store.currentComponentInfo._id,
components: $store.components, components: $store.components,
screen: $store.currentPreviewItem, screen: $store.currentPreviewItem,
tables: $backendUiStore.tables, tables: $backendUiStore.tables,
}) })
$: links = bindableProperties $: links = bindableProperties
.filter(x => x.fieldSchema.type === "link") .filter((x) => x.fieldSchema.type === "link")
.map(property => ({ .map((property) => ({
label: property.readableBinding, label: property.readableBinding,
fieldName: property.fieldSchema.name, fieldName: property.fieldSchema.name,
name: `all_${property.fieldSchema.tableId}`, name: `all_${property.fieldSchema.tableId}`,
tableId: property.fieldSchema.tableId, tableId: property.fieldSchema.tableId,
type: "link", type: "link",
})) }))
</script> </script>
<div <div
class="dropdownbutton" class="dropdownbutton"
bind:this={anchorRight} bind:this={anchorRight}
on:click={dropdownRight.show}> on:click={dropdownRight.show}>
<span>{value.label ? value.label : 'Table / View'}</span> <span>{value.label ? value.label : 'Table / View'}</span>
<Icon name="arrowdown" /> <Icon name="arrowdown" />
</div> </div>
<DropdownMenu bind:this={dropdownRight} anchor={anchorRight}> <DropdownMenu bind:this={dropdownRight} anchor={anchorRight}>
<div class="dropdown"> <div class="dropdown">
<div class="title"> <div class="title">
<Heading extraSmall>Tables</Heading> <Heading extraSmall>Tables</Heading>
</div> </div>
<ul> <ul>
{#each tables as table} {#each tables as table}
<li <li
class:selected={value === table} class:selected={value === table}
on:click={() => handleSelected(table)}> on:click={() => handleSelected(table)}>
{table.label} {table.label}
</li> </li>
{/each} {/each}
</ul> </ul>
<hr /> <hr />
<div class="title"> <div class="title">
<Heading extraSmall>Views</Heading> <Heading extraSmall>Views</Heading>
</div> </div>
<ul> <ul>
{#each views as view} {#each views as view}
<li <li
class:selected={value === view} class:selected={value === view}
on:click={() => handleSelected(view)}> on:click={() => handleSelected(view)}>
{view.label} {view.label}
</li> </li>
{/each} {/each}
</ul> </ul>
<hr /> <hr />
<div class="title"> <div class="title">
<Heading extraSmall>Relationships</Heading> <Heading extraSmall>Relationships</Heading>
</div> </div>
<ul> <ul>
{#each links as link} {#each links as link}
<li <li
class:selected={value === link} class:selected={value === link}
on:click={() => handleSelected(link)}> on:click={() => handleSelected(link)}>
{link.label} {link.label}
</li> </li>
{/each} {/each}
</ul> </ul>
</div> </div>
</DropdownMenu> </DropdownMenu>
<style> <style>
.dropdownbutton { .dropdownbutton {
background-color: var(--grey-2); background-color: var(--grey-2);
border: var(--border-transparent); border: var(--border-transparent);
padding: var(--spacing-m); padding: var(--spacing-s) var(--spacing-m);
border-radius: var(--border-radius-m); border-radius: var(--border-radius-m);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
overflow: hidden; overflow: hidden;
flex: 1 1 auto; flex: 1 1 auto;
} }
.dropdownbutton:hover { .dropdownbutton:hover {
cursor: pointer; cursor: pointer;
background-color: var(--grey-3); background-color: var(--grey-3);
} }
.dropdownbutton span { .dropdownbutton span {
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
flex: 1 1 auto; flex: 1 1 auto;
text-align: left; text-align: left;
font-size: var(--font-size-xs); font-size: var(--font-size-xs);
} }
.dropdownbutton :global(svg) { .dropdownbutton :global(svg) {
margin: -4px 0; margin: -4px 0;
} }
.dropdown { .dropdown {
padding: var(--spacing-m) 0; padding: var(--spacing-m) 0;
z-index: 99999999; z-index: 99999999;
} }
.title { .title {
padding: 0 var(--spacing-m) var(--spacing-xs) var(--spacing-m); padding: 0 var(--spacing-m) var(--spacing-xs) var(--spacing-m);
} }
hr { hr {
margin: var(--spacing-m) 0 var(--spacing-xl) 0; margin: var(--spacing-m) 0 var(--spacing-xl) 0;
} }
ul { ul {
list-style: none; list-style: none;
padding-left: 0px; padding-left: 0px;
margin: 0px; margin: 0px;
} }
li { li {
cursor: pointer; cursor: pointer;
margin: 0px; margin: 0px;
padding: var(--spacing-s) var(--spacing-m); padding: var(--spacing-s) var(--spacing-m);
font-size: var(--font-size-xs); font-size: var(--font-size-xs);
} }
.selected { .selected {
background-color: var(--grey-4); background-color: var(--grey-4);
} }
li:hover { li:hover {
background-color: var(--grey-4); background-color: var(--grey-4);
} }
</style> </style>