Add generic list and list item spectrum components for simple table style UI
This commit is contained in:
parent
31502eceee
commit
0ee58bdea8
|
@ -4,7 +4,7 @@
|
||||||
["XXS", "--spectrum-alias-avatar-size-50"],
|
["XXS", "--spectrum-alias-avatar-size-50"],
|
||||||
["XS", "--spectrum-alias-avatar-size-75"],
|
["XS", "--spectrum-alias-avatar-size-75"],
|
||||||
["S", "--spectrum-alias-avatar-size-200"],
|
["S", "--spectrum-alias-avatar-size-200"],
|
||||||
["M", "--spectrum-alias-avatar-size-300"],
|
["M", "--spectrum-alias-avatar-size-400"],
|
||||||
["L", "--spectrum-alias-avatar-size-500"],
|
["L", "--spectrum-alias-avatar-size-500"],
|
||||||
["XL", "--spectrum-alias-avatar-size-600"],
|
["XL", "--spectrum-alias-avatar-size-600"],
|
||||||
["XXL", "--spectrum-alias-avatar-size-700"],
|
["XXL", "--spectrum-alias-avatar-size-700"],
|
||||||
|
@ -13,6 +13,19 @@
|
||||||
export let url = ""
|
export let url = ""
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
export let initials = "JD"
|
export let initials = "JD"
|
||||||
|
|
||||||
|
const DefaultColor = "#3aab87"
|
||||||
|
|
||||||
|
$: color = getColor(initials)
|
||||||
|
|
||||||
|
const getColor = initials => {
|
||||||
|
if (!initials?.length) {
|
||||||
|
return DefaultColor
|
||||||
|
}
|
||||||
|
const code = initials[0].toLowerCase().charCodeAt(0)
|
||||||
|
const hue = ((code % 26) / 26) * 360
|
||||||
|
return `hsl(${hue}, 50%, 50%)`
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if url}
|
{#if url}
|
||||||
|
@ -25,10 +38,11 @@
|
||||||
/>
|
/>
|
||||||
{:else}
|
{:else}
|
||||||
<div
|
<div
|
||||||
|
class="spectrum-Avatar"
|
||||||
class:is-disabled={disabled}
|
class:is-disabled={disabled}
|
||||||
style="width: var({sizes.get(size)}); height: var({sizes.get(
|
style="width: var({sizes.get(size)}); height: var({sizes.get(
|
||||||
size
|
size
|
||||||
)}); font-size: calc(var({sizes.get(size)}) / 2)"
|
)}); font-size: calc(var({sizes.get(size)}) / 2); background: {color};"
|
||||||
>
|
>
|
||||||
{initials || ""}
|
{initials || ""}
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,7 +54,6 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
background: #3aab87;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
|
@ -91,7 +91,7 @@
|
||||||
</span>
|
</span>
|
||||||
{:else if fieldColour}
|
{:else if fieldColour}
|
||||||
<span class="option-left">
|
<span class="option-left">
|
||||||
<StatusLight custom color={fieldColour} />
|
<StatusLight color={fieldColour} />
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
<span
|
<span
|
||||||
|
@ -113,7 +113,7 @@
|
||||||
{/if}
|
{/if}
|
||||||
{#if fieldIcon && fieldColour}
|
{#if fieldIcon && fieldColour}
|
||||||
<span class="option-right">
|
<span class="option-right">
|
||||||
<StatusLight custom color={fieldColour} />
|
<StatusLight color={fieldColour} />
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
<svg
|
<svg
|
||||||
|
@ -175,7 +175,7 @@
|
||||||
</span>
|
</span>
|
||||||
{:else if getOptionColour(option, idx)}
|
{:else if getOptionColour(option, idx)}
|
||||||
<span class="option-left">
|
<span class="option-left">
|
||||||
<StatusLight custom color={getOptionColour(option, idx)} />
|
<StatusLight color={getOptionColour(option, idx)} />
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
<span class="spectrum-Menu-itemLabel">
|
<span class="spectrum-Menu-itemLabel">
|
||||||
|
@ -190,7 +190,7 @@
|
||||||
</svg>
|
</svg>
|
||||||
{#if getOptionIcon(option, idx) && getOptionColour(option, idx)}
|
{#if getOptionIcon(option, idx) && getOptionColour(option, idx)}
|
||||||
<span class="option-right">
|
<span class="option-right">
|
||||||
<StatusLight custom color={getOptionColour(option, idx)} />
|
<StatusLight color={getOptionColour(option, idx)} />
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
<script>
|
|
||||||
import { View } from "svench";
|
|
||||||
import DetailSummary from "./DetailSummary.svelte";
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
div {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: stretch;
|
|
||||||
gap: var(--spacing-m);
|
|
||||||
width: 120px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<View name="default">
|
|
||||||
<div>
|
|
||||||
<DetailSummary name="Category 1">
|
|
||||||
<span>1</span>
|
|
||||||
<span>2</span>
|
|
||||||
<span>3</span>
|
|
||||||
<span>4</span>
|
|
||||||
</DetailSummary>
|
|
||||||
<DetailSummary name="Category 2">
|
|
||||||
<span>1</span>
|
|
||||||
<span>2</span>
|
|
||||||
<span>3</span>
|
|
||||||
<span>4</span>
|
|
||||||
</DetailSummary>
|
|
||||||
</div>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View name="thin">
|
|
||||||
<div>
|
|
||||||
<DetailSummary thin name="Category 1">
|
|
||||||
<span>1</span>
|
|
||||||
<span>2</span>
|
|
||||||
<span>3</span>
|
|
||||||
<span>4</span>
|
|
||||||
</DetailSummary>
|
|
||||||
<DetailSummary thin name="Category 2">
|
|
||||||
<span>1</span>
|
|
||||||
<span>2</span>
|
|
||||||
<span>3</span>
|
|
||||||
<span>4</span>
|
|
||||||
</DetailSummary>
|
|
||||||
</div>
|
|
||||||
</View>
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<script>
|
||||||
|
import Detail from "../Typography/Detail.svelte"
|
||||||
|
|
||||||
|
export let title = null
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{#if title}
|
||||||
|
<div class="title">
|
||||||
|
<Detail>{title}</Detail>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<div class="list-items">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.title {
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
.list-items {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,92 @@
|
||||||
|
<script>
|
||||||
|
import Body from "../Typography/Body.svelte"
|
||||||
|
import Icon from "../Icon/Icon.svelte"
|
||||||
|
import Label from "../Label/Label.svelte"
|
||||||
|
import Avatar from "../Avatar/Avatar.svelte"
|
||||||
|
|
||||||
|
export let icon = null
|
||||||
|
export let iconBackground = null
|
||||||
|
export let avatar = false
|
||||||
|
export let title = null
|
||||||
|
export let subtitle = null
|
||||||
|
|
||||||
|
$: initials = avatar ? title?.[0] : null
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="list-item">
|
||||||
|
<div class="left">
|
||||||
|
{#if icon}
|
||||||
|
<div class="icon" style="background: {iconBackground || `transparent`};">
|
||||||
|
<Icon name={icon} size="S" color={iconBackground ? "white" : null} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if avatar}
|
||||||
|
<Avatar {initials} />
|
||||||
|
{/if}
|
||||||
|
{#if title}
|
||||||
|
<Body>{title}</Body>
|
||||||
|
{/if}
|
||||||
|
{#if subtitle}
|
||||||
|
<Label>{subtitle}</Label>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.list-item {
|
||||||
|
padding: 0 16px;
|
||||||
|
height: 56px;
|
||||||
|
background: var(--spectrum-alias-background-color-tertiary);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
border: 1px solid var(--spectrum-global-color-gray-300);
|
||||||
|
}
|
||||||
|
.list-item:not(:first-child) {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
.list-item:first-child {
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
}
|
||||||
|
.list-item:last-child {
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
}
|
||||||
|
.left,
|
||||||
|
.right {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--spacing-xl);
|
||||||
|
}
|
||||||
|
.left {
|
||||||
|
width: 0;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
.list-item :global(.spectrum-Icon),
|
||||||
|
.list-item :global(.spectrum-Avatar) {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
.list-item :global(.spectrum-Body) {
|
||||||
|
color: var(--spectrum-global-color-gray-900);
|
||||||
|
}
|
||||||
|
.list-item :global(.spectrum-Body) {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
width: var(--spectrum-alias-avatar-size-400);
|
||||||
|
height: var(--spectrum-alias-avatar-size-400);
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -65,6 +65,8 @@ export { default as BannerDisplay } from "./Banner/BannerDisplay.svelte"
|
||||||
export { default as MarkdownEditor } from "./Markdown/MarkdownEditor.svelte"
|
export { default as MarkdownEditor } from "./Markdown/MarkdownEditor.svelte"
|
||||||
export { default as MarkdownViewer } from "./Markdown/MarkdownViewer.svelte"
|
export { default as MarkdownViewer } from "./Markdown/MarkdownViewer.svelte"
|
||||||
export { default as RichTextField } from "./Form/RichTextField.svelte"
|
export { default as RichTextField } from "./Form/RichTextField.svelte"
|
||||||
|
export { default as List } from "./List/List.svelte"
|
||||||
|
export { default as ListItem } from "./List/ListItem.svelte"
|
||||||
|
|
||||||
// Renderers
|
// Renderers
|
||||||
export { default as BoldRenderer } from "./Table/BoldRenderer.svelte"
|
export { default as BoldRenderer } from "./Table/BoldRenderer.svelte"
|
||||||
|
|
Loading…
Reference in New Issue