Merge branch 'master' of github.com:Budibase/budibase into martin-more-bugfixes

This commit is contained in:
Martin McKeaveney 2020-10-15 09:29:59 +01:00
commit 6204a7c622
20 changed files with 325 additions and 196 deletions

View File

@ -27,6 +27,8 @@ context("Create a Table", () => {
cy.get(".actions input") cy.get(".actions input")
.first() .first()
.type("updated") .type("updated")
// Unset table display column
cy.contains("display column").click()
cy.contains("Save Column").click() cy.contains("Save Column").click()
cy.contains("nameupdated").should("have.text", "nameupdated") cy.contains("nameupdated").should("have.text", "nameupdated")
}) })

View File

@ -87,6 +87,8 @@ Cypress.Commands.add("addColumn", (tableName, columnName, type) => {
cy.get("input") cy.get("input")
.first() .first()
.type(columnName) .type(columnName)
// Unset table display column
cy.contains("display column").click()
cy.get("select").select(type) cy.get("select").select(type)
cy.contains("Save").click() cy.contains("Save").click()
}) })

View File

@ -91,10 +91,11 @@ export const getBackendUiStore = () => {
return state return state
}) })
}, },
saveField: ({ originalName, field }) => { saveField: ({ originalName, field, primaryDisplay = false }) => {
store.update(state => { store.update(state => {
// delete the original if renaming // delete the original if renaming
if (originalName) { // need to handle if the column had no name, empty string
if (originalName || originalName === "") {
delete state.draftTable.schema[originalName] delete state.draftTable.schema[originalName]
state.draftTable._rename = { state.draftTable._rename = {
old: originalName, old: originalName,
@ -102,8 +103,12 @@ export const getBackendUiStore = () => {
} }
} }
state.draftTable.schema[field.name] = cloneDeep(field) // Optionally set display column
if (primaryDisplay) {
state.draftTable.primaryDisplay = field.name
}
state.draftTable.schema[field.name] = cloneDeep(field)
store.actions.tables.save(state.draftTable) store.actions.tables.save(state.draftTable)
return state return state
}) })

View File

@ -33,7 +33,7 @@
function deleteColumn() { function deleteColumn() {
if (field.name === $backendUiStore.selectedTable.primaryDisplay) { if (field.name === $backendUiStore.selectedTable.primaryDisplay) {
notifier.danger("You cannot delete the primary display column") notifier.danger("You cannot delete the display column")
} else { } else {
backendUiStore.actions.tables.deleteField(field) backendUiStore.actions.tables.deleteField(field)
notifier.success("Column deleted") notifier.success("Column deleted")
@ -43,7 +43,11 @@
function sort(direction, column) { function sort(direction, column) {
backendUiStore.update(state => { backendUiStore.update(state => {
if (direction !== "none") {
state.sort = { direction, column } state.sort = { direction, column }
} else {
state.sort = undefined
}
return state return state
}) })
hideEditor() hideEditor()
@ -70,6 +74,12 @@
<Icon name="delete" /> <Icon name="delete" />
Delete Delete
</li> </li>
{#if sortDirection === 'desc' || sortDirection === 'asc'}
<li on:click={() => sort('none', field.name)}>
<Icon name="close" />
Remove sort
</li>
{/if}
{#if sortDirection === 'desc' || sortColumn !== field.name} {#if sortDirection === 'desc' || sortColumn !== field.name}
<li on:click={() => sort('asc', field.name)}> <li on:click={() => sort('asc', field.name)}>
<Icon name="sortascending" /> <Icon name="sortascending" />

View File

@ -28,9 +28,15 @@
export let field = { export let field = {
type: "string", type: "string",
constraints: fieldDefinitions.STRING.constraints, constraints: fieldDefinitions.STRING.constraints,
// Initial value for column name in other table for linked records
fieldName: $backendUiStore.selectedTable.name,
} }
let originalName = field.name let originalName = field.name
let primaryDisplay =
$backendUiStore.selectedTable.primaryDisplay == null ||
$backendUiStore.selectedTable.primaryDisplay === field.name
$: tableOptions = $backendUiStore.tables.filter( $: tableOptions = $backendUiStore.tables.filter(
table => table._id !== $backendUiStore.draftTable._id table => table._id !== $backendUiStore.draftTable._id
) )
@ -41,6 +47,7 @@
backendUiStore.actions.tables.saveField({ backendUiStore.actions.tables.saveField({
originalName, originalName,
field, field,
primaryDisplay,
}) })
return state return state
}) })
@ -85,6 +92,13 @@
text="Required" /> text="Required" />
{/if} {/if}
{#if field.type !== 'link'}
<Toggle
bind:checked={primaryDisplay}
thin
text="Use as table display column" />
{/if}
{#if field.type === 'string'} {#if field.type === 'string'}
<Input <Input
thin thin

View File

@ -78,16 +78,6 @@
bind:value={table.name} bind:value={table.name}
on:input={checkValid} on:input={checkValid}
{error} /> {error} />
<Select
label="Primary Display Column"
thin
secondary
bind:value={table.primaryDisplay}>
<option value="">Choose an option</option>
{#each fields as field}
<option value={field}>{field}</option>
{/each}
</Select>
<footer> <footer>
<Button secondary on:click={hideEditor}>Cancel</Button> <Button secondary on:click={hideEditor}>Cancel</Button>
<Button primary disabled={error} on:click={save}>Save</Button> <Button primary disabled={error} on:click={save}>Save</Button>

View File

@ -36,7 +36,7 @@
{#if linkedTable.primaryDisplay == null} {#if linkedTable.primaryDisplay == null}
<Label extraSmall grey>{label}</Label> <Label extraSmall grey>{label}</Label>
<Label small black> <Label small black>
Please choose a primary display column for the Please choose a display column for the
<b>{linkedTable.name}</b> <b>{linkedTable.name}</b>
table. table.
</Label> </Label>

View File

@ -20,7 +20,7 @@ export default `<html>
border-style: dashed !important; border-style: dashed !important;
border-width: 1px; border-width: 1px;
color: #000000; color: #000000;
background: #fafafa; background-color: rgba(0, 0, 0, 0.05);
flex: 1 1 auto; flex: 1 1 auto;
} }
.container-screenslot-placeholder span { .container-screenslot-placeholder span {

View File

@ -96,7 +96,6 @@
onChange={onScreenPropChange} onChange={onScreenPropChange}
props={{ ...excludeProps(def, ['control', 'label']) }} /> props={{ ...excludeProps(def, ['control', 'label']) }} />
{/each} {/each}
<hr />
{/if} {/if}
{#if displayNameField} {#if displayNameField}

View File

@ -523,6 +523,31 @@ export const background = [
label: "Plum Plate", label: "Plum Plate",
value: "linear-gradient(135deg, #667eea 0%, #764ba2 100%);", value: "linear-gradient(135deg, #667eea 0%, #764ba2 100%);",
}, },
{
label: "Peach Kiss",
value:
"radial-gradient(circle farthest-corner at 50% 100%,rgba(255,173,138,.50), rgba(255,248,247,1) 100%);",
},
{
label: "Flamingo Sunrise",
value:
"-webkit-radial-gradient(center top, rgb(255, 250, 245), rgb(255, 242, 242))",
},
{
label: "Budi Mist",
value:
"radial-gradient(circle, rgba(252,215,212,1) 0%, rgba(255,227,214,1) 50%, rgba(207,218,255,1) 100%);",
},
{
label: "Ballet Slipper",
value:
"linear-gradient(135deg, rgba(252,215,212,1) 20%, rgba(207,218,255,1) 100%);",
},
{
label: "Black Noir",
value:
"linear-gradient(312deg, rgba(60,60,60,1) 0%, rgba(42,42,42,1) 100%);",
},
], ],
}, },
{ {

View File

@ -1190,12 +1190,7 @@ export default {
children: [], children: [],
properties: { properties: {
design: { ...all }, design: { ...all },
settings: [ settings: [{ label: "Logo URL", key: "logoUrl", control: Input }],
{ label: "Logo URL", key: "logoUrl", control: Input },
{ label: "Title", key: "title", control: Input },
{ label: "Color", key: "color", control: Input },
{ label: "Background", key: "backgroundColor", control: Input },
],
}, },
}, },
{ {

View File

@ -4,10 +4,12 @@ import { parseAppIdFromCookie } from "./getAppId"
export const screenRouter = ({ screens, onScreenSelected, window }) => { export const screenRouter = ({ screens, onScreenSelected, window }) => {
const makeRootedPath = url => { const makeRootedPath = url => {
const hostname = window.location && window.location.hostname
if (hostname) {
if ( if (
window.location && hostname === "localhost" ||
(window.location.hostname === "localhost" || hostname === "127.0.0.1" ||
window.location.hostname === "127.0.0.1") hostname.startsWith("192.168")
) { ) {
const appId = parseAppIdFromCookie(window.document.cookie) const appId = parseAppIdFromCookie(window.document.cookie)
if (url) { if (url) {
@ -16,6 +18,7 @@ export const screenRouter = ({ screens, onScreenSelected, window }) => {
} }
return appId return appId
} }
}
return url return url
} }

View File

@ -36,14 +36,23 @@ exports.save = async function(ctx) {
let renameDocs = [] let renameDocs = []
// if the table obj had an _id then it will have been retrieved // if the table obj had an _id then it will have been retrieved
const oldTable = ctx.preExisting let oldTable
if (ctx.request.body && ctx.request.body._id) {
oldTable = await db.get(ctx.request.body._id)
}
// Don't rename if the name is the same
let { _rename } = tableToSave
if (_rename && _rename.old === _rename.updated) {
_rename = null
delete tableToSave._rename
}
// rename row fields when table column is renamed // rename row fields when table column is renamed
const { _rename } = tableToSave
if (_rename && tableToSave.schema[_rename.updated].type === "link") { if (_rename && tableToSave.schema[_rename.updated].type === "link") {
throw "Cannot rename a linked field." throw "Cannot rename a linked field."
} else if (_rename && tableToSave.primaryDisplay === _rename.old) { } else if (_rename && tableToSave.primaryDisplay === _rename.old) {
throw "Cannot rename the primary display field." throw "Cannot rename the display column."
} else if (_rename) { } else if (_rename) {
const rows = await db.allDocs( const rows = await db.allDocs(
getRowParams(tableToSave._id, null, { getRowParams(tableToSave._id, null, {

View File

@ -1,23 +1,57 @@
{ {
"componentLibraries": [
"@budibase/standard-components"
],
"title": "{{ name }}", "title": "{{ name }}",
"favicon": "./_shared/favicon.png", "favicon": "./_shared/favicon.png",
"stylesheets": [], "stylesheets": [],
"componentLibraries": ["@budibase/standard-components"],
"props": { "props": {
"_id": "private-master-root", "_id": "private-master-root",
"_component": "@budibase/standard-components/container", "_component": "@budibase/standard-components/container",
"_children": [ "_children": [
{ {
"_id": "49e0e519-9e5e-4127-885a-ee6a0a49e2c1", "_id": "c74f07266980c4b6eafc33e2a6caa783d",
"_component": "@budibase/standard-components/Navigation", "_component": "@budibase/standard-components/container",
"_styles": { "_styles": {
"normal": {}, "normal": {
"display": "flex",
"flex-direction": "row",
"justify-content": "flex-start",
"align-items": "flex-start",
"background": "#fff",
"width": "100%"
},
"hover": {}, "hover": {},
"active": {}, "active": {},
"selected": {} "selected": {}
}, },
"_code": "", "_code": "",
"logoUrl": "http://acmelogos.com/images/logo-8.svg", "className": "",
"onLoad": [],
"type": "div",
"_instanceId": "inst_app_80b_f158d4057d2c4bedb0042d42fda8abaf",
"_instanceName": "Header",
"_children": [
{
"_id": "49e0e519-9e5e-4127-885a-ee6a0a49e2c1",
"_component": "@budibase/standard-components/Navigation",
"_styles": {
"normal": {
"max-width": "1400px",
"margin-left": "auto",
"margin-right": "auto",
"padding": "20px",
"color": "#757575",
"font-weight": "400",
"font-size": "16px",
"flex": "1 1 auto"
},
"hover": {},
"active": {},
"selected": {}
},
"_code": "",
"logoUrl": "https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg",
"title": "", "title": "",
"backgroundColor": "", "backgroundColor": "",
"color": "", "color": "",
@ -38,7 +72,9 @@
"text-decoration-line": "none", "text-decoration-line": "none",
"font-size": "16px" "font-size": "16px"
}, },
"hover": {}, "hover": {
"color": "#4285f4"
},
"active": {}, "active": {},
"selected": {} "selected": {}
}, },
@ -56,6 +92,8 @@
"_children": [] "_children": []
} }
] ]
}
]
}, },
{ {
"_id": "7fcf11e4-6f5b-4085-8e0d-9f3d44c98967", "_id": "7fcf11e4-6f5b-4085-8e0d-9f3d44c98967",
@ -66,7 +104,12 @@
"display": "flex", "display": "flex",
"flex-direction": "column", "flex-direction": "column",
"justify-content": "flex-start", "justify-content": "flex-start",
"align-items": "stretch" "align-items": "stretch",
"max-width": "100%",
"margin-left": "20px",
"margin-right": "20px",
"width": "1400px",
"padding": "20px"
}, },
"hover": {}, "hover": {},
"active": {}, "active": {},
@ -83,11 +126,12 @@
"normal": { "normal": {
"display": "flex", "display": "flex",
"flex-direction": "column", "flex-direction": "column",
"align-items": "stretch", "align-items": "center",
"justify-content": "flex-start", "justify-content": "flex-start",
"margin-right": "auto", "margin-right": "auto",
"margin-left": "auto", "margin-left": "auto",
"min-height": "100%" "min-height": "100%",
"background-image": "linear-gradient(135deg, rgba(252,215,212,1) 20%, rgba(207,218,255,1) 100%);"
}, },
"selected": {} "selected": {}
}, },
@ -95,6 +139,5 @@
"className": "", "className": "",
"onLoad": [] "onLoad": []
}, },
"_css": "",
"uiFunctions": "" "uiFunctions": ""
} }

View File

@ -5,7 +5,13 @@
"_id": "d834fea2-1b3e-4320-ab34-f9009f5ecc59", "_id": "d834fea2-1b3e-4320-ab34-f9009f5ecc59",
"_component": "@budibase/standard-components/container", "_component": "@budibase/standard-components/container",
"_styles": { "_styles": {
"normal": {}, "normal": {
"flex": "1 1 auto",
"display": "flex",
"flex-direction": "column",
"justify-content": "flex-start",
"align-items": "stretch"
},
"hover": {}, "hover": {},
"active": {}, "active": {},
"selected": {} "selected": {}
@ -19,40 +25,75 @@
"_id": "ef60083f-4a02-4df3-80f3-a0d3d16847e7", "_id": "ef60083f-4a02-4df3-80f3-a0d3d16847e7",
"_component": "@budibase/standard-components/heading", "_component": "@budibase/standard-components/heading",
"_styles": { "_styles": {
"normal": {}, "normal": {
"text-align": "left"
},
"hover": {}, "hover": {},
"active": {}, "active": {},
"selected": {} "selected": {}
}, },
"_code": "", "_code": "",
"className": "", "className": "",
"text": "Home", "text": "Welcome to your Budibase App 👋",
"type": "h1", "type": "h2",
"_instanceId": "inst_cf8ace4_69efc0d72e6f443db2d4c902c14d9394", "_instanceId": "inst_cf8ace4_69efc0d72e6f443db2d4c902c14d9394",
"_instanceName": "Heading", "_instanceName": "Heading",
"_children": [] "_children": []
}, },
{ {
"_id": "6c256e06-784c-4ac0-a644-ed2f9b91d459", "_id": "cbbf41b27c2b44d1abba38bb694880c6a",
"_component": "@budibase/standard-components/image", "_component": "@budibase/standard-components/container",
"_styles": { "_styles": {
"normal": { "normal": {
"width": "100%" "display": "flex",
"flex-direction": "column",
"justify-content": "center",
"align-items": "stretch",
"flex": "1 1 auto",
"border-width": "4px",
"border-style": "Dashed",
"margin-bottom": "32px"
}, },
"hover": {}, "hover": {},
"active": {}, "active": {},
"selected": {} "selected": {}
}, },
"_code": "", "_code": "",
"url": "https://source.unsplash.com/Vun-71Vy2hc",
"className": "", "className": "",
"description": "", "onLoad": [],
"height": "", "type": "div",
"width": "", "_instanceId": "inst_app_2cc_ca3383f896034e9295345c05f7dfca0c",
"_instanceId": "inst_cf8ace4_69efc0d72e6f443db2d4c902c14d9394", "_instanceName": "Video Container",
"_instanceName": "Image", "_children": [
{
"_id": "c07d752cb3e544b418088fa9be84ba2e4",
"_component": "@budibase/standard-components/embed",
"_styles": {
"normal": {
"width": "100%",
"flex": "1 1 auto",
"opacity": "0",
"transition-property": "Opacity",
"transition-duration": "1s",
"transition-timing-function:": "ease-in"
},
"hover": {
"transition-property": "Opacity",
"transition-duration": "1s",
"transition-timing-function:": "ease-out",
"opacity": "1"
},
"active": {},
"selected": {}
},
"_code": "",
"embed": "<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/dQw4w9WgXcQ\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>",
"_instanceId": "inst_app_2cc_ca3383f896034e9295345c05f7dfca0c",
"_instanceName": "Rick Astley Video",
"_children": [] "_children": []
} }
]
}
], ],
"_instanceName": "Home" "_instanceName": "Home"
}, },

View File

@ -1,41 +0,0 @@
{
"description": "",
"url": "",
"_css": "",
"props": {
"_id": "f684460e-1f79-42b4-8ffd-1f708bca93ed",
"_component": "@budibase/standard-components/container",
"_styles": {
"normal": {},
"hover": {},
"active": {},
"selected": {}
},
"_code": "",
"className": "",
"onLoad": [],
"type": "div",
"_children": [
{
"_id": "7d1d6b43-b444-46a5-a75c-267fd6b5baf6",
"_component": "@budibase/standard-components/heading",
"_styles": {
"normal": {},
"hover": {},
"active": {},
"selected": {}
},
"_code": "",
"className": "",
"text": "Screen1",
"type": "h1",
"_instanceId": "inst_cf8ace4_69efc0d72e6f443db2d4c902c14d9394",
"_instanceName": "Heading",
"_children": []
}
],
"_instanceName": "Screen 1"
},
"route": "/screen1",
"name": "f684460e-1f79-42b4-8ffd-1f708bca93ed"
}

View File

@ -1,5 +1,7 @@
{ {
"componentLibraries": ["@budibase/standard-components"], "componentLibraries": [
"@budibase/standard-components"
],
"title": "{{ name }}", "title": "{{ name }}",
"favicon": "./_shared/favicon.png", "favicon": "./_shared/favicon.png",
"stylesheets": [], "stylesheets": [],
@ -11,7 +13,19 @@
"_id": "686c252d-dbf2-4e28-9078-414ba4719759", "_id": "686c252d-dbf2-4e28-9078-414ba4719759",
"_component": "@budibase/standard-components/login", "_component": "@budibase/standard-components/login",
"_styles": { "_styles": {
"normal": {}, "normal": {
"padding": "64px",
"background": "rgba(255, 255, 255, 0.4)",
"border-radius": "0.5rem",
"margin-top": "0px",
"margin": "0px",
"line-height": "1",
"box-shadow": "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
"font-size": "16px",
"font-family": "Inter",
"flex": "0 1 auto",
"transform": "0"
},
"hover": {}, "hover": {},
"active": {}, "active": {},
"selected": {} "selected": {}
@ -26,19 +40,29 @@
"inputClass": "", "inputClass": "",
"_children": [], "_children": [],
"title": "Log in to {{ name }}", "title": "Log in to {{ name }}",
"buttonText": "Login", "buttonText": "Log In",
"logo": "" "logo": "https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg"
} }
], ],
"type": "div", "type": "div",
"_styles": { "_styles": {
"layout": {}, "active": {},
"position": {} "hover": {},
"normal": {
"display": "flex",
"flex-direction": "column",
"align-items": "center",
"justify-content": "center",
"margin-right": "auto",
"margin-left": "auto",
"min-height": "100%",
"background-image": "linear-gradient(135deg, rgba(252,215,212,1) 20%, rgba(207,218,255,1) 100%);"
},
"selected": {}
}, },
"_code": "", "_code": "",
"className": "", "className": "",
"onLoad": [] "onLoad": []
}, },
"_css": "",
"uiFunctions": "" "uiFunctions": ""
} }

View File

@ -45,7 +45,7 @@
<Label extraSmall grey>{label}</Label> <Label extraSmall grey>{label}</Label>
{/if} {/if}
<Label small black> <Label small black>
Please choose a primary display column for the Please choose a display column for the
<b>{linkedTable.name}</b> <b>{linkedTable.name}</b>
table. table.
</Label> </Label>

View File

@ -1,7 +1,7 @@
<script> <script>
import Button from "./Button.svelte" import Button from "./Button.svelte"
export let buttonText = "Login" export let buttonText = "Log In"
export let logo = "" export let logo = ""
export let title = "" export let title = ""
export let buttonClass = "" export let buttonClass = ""
@ -46,7 +46,7 @@
{/if} {/if}
{#if title} {#if title}
<h1 class="header-content">{title}</h1> <h2 class="header-content">{title}</h2>
{/if} {/if}
<div class="form-root"> <div class="form-root">
@ -69,7 +69,7 @@
<div class="login-button-container"> <div class="login-button-container">
<button disabled={loading} on:click={login} class={_buttonClass}> <button disabled={loading} on:click={login} class={_buttonClass}>
{buttonText || 'Login'} {buttonText || 'Log In'}
</button> </button>
</div> </div>
@ -100,7 +100,9 @@
} }
.logo-container > img { .logo-container > img {
height: 80px;
max-width: 200px; max-width: 200px;
margin-bottom: 20px;
} }
.login-button-container { .login-button-container {
@ -112,24 +114,24 @@
font-family: Inter; font-family: Inter;
font-weight: 700; font-weight: 700;
color: #1f1f1f; color: #1f1f1f;
font-size: 48px; font-size: 32px;
line-height: 72px;
margin-bottom: 30px;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
font-feature-settings: "case" "rlig" "calt" 0; font-feature-settings: "case" "rlig" "calt" 0;
margin: 0 0 20px 0;
} }
.incorrect-details-panel { .incorrect-details-panel {
margin-top: 30px; margin-top: 26px;
padding: 10px; padding: 10px;
border-style: solid; border-style: solid;
border-width: 1px; border-width: 1px;
border-color: maroon; border-color: maroon;
border-radius: 1px; border-radius: 4px;
text-align: center; text-align: center;
color: maroon; color: maroon;
background-color: mistyrose; background-color: mistyrose;
align-self: stretch;
} }
.form-root { .form-root {

View File

@ -1,28 +1,11 @@
<script> <script>
import { cssVars, createClasses } from "./cssVars"
export let className = ""
export let onLoad export let onLoad
export let backgroundColor
export let color
export let borderWidth
export let borderColor
export let borderStyle
export let logoUrl export let logoUrl
export let title
export let _bb export let _bb
export let title
let itemContainer let itemContainer
let hasLoaded let hasLoaded
let currentChildren
$: cssVariables = {
backgroundColor,
color,
borderWidth,
borderColor,
borderStyle,
}
$: { $: {
if (itemContainer) { if (itemContainer) {
@ -33,46 +16,69 @@
} }
} }
} }
const logOut = () => {
document.cookie =
"budibase:token=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;"
location.reload()
}
</script> </script>
<nav use:cssVars={cssVariables}> <div class="nav">
{#if logoUrl} <div class="nav__top">
<a href="/"> <a href="/">
{#if logoUrl}
<img class="logo" alt="logo" src={logoUrl} height="48" /> <img class="logo" alt="logo" src={logoUrl} height="48" />
<span>{title}</span>
</a>
{:else}
<div />
{/if} {/if}
<div class="menu-items" bind:this={itemContainer} /> {#if title}<span>{title}</span>{/if}
</nav> </a>
<div class="nav__controls">
<div on:click={logOut}>Log out</div>
</div>
</div>
<div class="nav__menu" bind:this={itemContainer} />
</div>
<style> <style>
nav { .nav {
color: var(--color);
background-color: var(--backgroundColor);
align-items: center;
display: flex; display: flex;
font-weight: bold; flex-direction: column;
justify-content: flex-start;
align-items: stretch;
}
.nav__top {
display: flex;
flex-direction: row;
justify-content: space-between; justify-content: space-between;
padding: 20px 0px;
}
nav > a {
display: flex;
align-items: center; align-items: center;
font-size: 1.5em;
color: var(--color);
text-decoration: none;
} }
.nav__top img {
nav a img {
margin-right: 16px; margin-right: 16px;
} }
.menu-items {
.nav__controls {
display: flex; display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
gap: 16px;
} }
.menu-items > :global(*) { .nav__controls > div:hover {
margin: 0 10px; cursor: pointer;
color: #4285f4;
}
.nav__menu {
display: flex;
margin-top: 40px;
gap: 16px;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
.nav__menu > a {
font-size: 1.5em;
text-decoration: none;
} }
</style> </style>