mirror of https://github.com/Budibase/budibase.git
11 changed files with 576 additions and 564 deletions
@ -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> |
||||
|
|||||
@ -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> |
||||
|
|||||
@ -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> |
||||
|
|||||
Loading…
Reference in new issue