@invopop/popui 0.1.13 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BaseButton.svelte +25 -103
- package/dist/BaseCard.svelte +35 -30
- package/dist/BaseCounter.svelte +11 -8
- package/dist/BaseTable.svelte +6 -8
- package/dist/BaseTableActions.svelte +2 -2
- package/dist/BaseTableCellContent.svelte +2 -2
- package/dist/BaseTableHeaderContent.svelte +2 -2
- package/dist/Breadcrumb.svelte +40 -0
- package/dist/Breadcrumb.svelte.d.ts +4 -0
- package/dist/Breadcrumbs.svelte +5 -30
- package/dist/ButtonFile.svelte +35 -30
- package/dist/ButtonUuidCopy.svelte +2 -2
- package/dist/CardCheckbox.svelte +25 -21
- package/dist/CardRelation.svelte +12 -16
- package/dist/CompanySelector.svelte +35 -7
- package/dist/DataListItem.svelte +14 -10
- package/dist/DatePicker.svelte +9 -9
- package/dist/DrawerContext.svelte +112 -10
- package/dist/DrawerContextItem.svelte +19 -29
- package/dist/DrawerContextSeparator.svelte +1 -1
- package/dist/DrawerContextWorkspace.svelte +7 -7
- package/dist/DropdownSelect.svelte +40 -14
- package/dist/EmptyState.svelte +40 -0
- package/dist/EmptyState.svelte.d.ts +4 -0
- package/dist/EmptyStateIllustration.svelte.d.ts +0 -1
- package/dist/FeedEvents.svelte +9 -5
- package/dist/FeedIconEvent.svelte +1 -1
- package/dist/FeedItem.svelte +8 -8
- package/dist/FeedItemDetail.svelte +23 -5
- package/dist/GlobalSearch.svelte +13 -12
- package/dist/InputCheckbox.svelte +2 -5
- package/dist/InputError.svelte +4 -9
- package/dist/InputLabel.svelte +3 -1
- package/dist/InputRadio.svelte +26 -11
- package/dist/InputSearch.svelte +8 -8
- package/dist/InputSelect.svelte +32 -31
- package/dist/InputText.svelte +32 -24
- package/dist/InputTextarea.svelte +25 -19
- package/dist/InputToggle.svelte +24 -18
- package/dist/Notification.svelte +55 -24
- package/dist/ProfileAvatar.svelte +41 -14
- package/dist/SeparatorHorizontal.svelte +2 -2
- package/dist/ShortcutWrapper.svelte +14 -5
- package/dist/StatusLabel.svelte +4 -5
- package/dist/StepIconList.svelte +7 -9
- package/dist/TagBeta.svelte +26 -14
- package/dist/TagStatus.svelte +33 -48
- package/dist/TitleMain.svelte +1 -1
- package/dist/TitleSection.svelte +1 -1
- package/dist/UuidCopy.svelte +4 -4
- package/dist/alert-dialog/alert-dialog-action.svelte +5 -3
- package/dist/alert-dialog/alert-dialog-cancel.svelte +4 -2
- package/dist/alert-dialog/alert-dialog-content.svelte +1 -1
- package/dist/alert-dialog/alert-dialog-description.svelte +1 -1
- package/dist/alert-dialog/alert-dialog-footer.svelte +1 -1
- package/dist/alert-dialog/alert-dialog-header.svelte +1 -1
- package/dist/alert-dialog/alert-dialog-title.svelte +1 -1
- package/dist/button/button.svelte +183 -24
- package/dist/button/button.svelte.d.ts +48 -26
- package/dist/index.d.ts +2 -7
- package/dist/index.js +2 -12
- package/dist/range-calendar/range-calendar-cell.svelte +1 -1
- package/dist/range-calendar/range-calendar-day.svelte +10 -8
- package/dist/range-calendar/range-calendar-head-cell.svelte +1 -1
- package/dist/range-calendar/range-calendar-next-button.svelte +3 -3
- package/dist/range-calendar/range-calendar-prev-button.svelte +3 -3
- package/dist/range-calendar/range-calendar.svelte +1 -1
- package/dist/svg/CheckBadge.svelte +18 -0
- package/dist/svg/CheckBadge.svelte.d.ts +26 -0
- package/dist/svg/IconEmpty.svelte +78 -106
- package/dist/table/table-body.svelte +1 -1
- package/dist/table/table-cell.svelte +1 -1
- package/dist/table/table-footer.svelte +1 -1
- package/dist/table/table-head.svelte +1 -1
- package/dist/table/table-header.svelte +1 -1
- package/dist/table/table-row.svelte +1 -1
- package/dist/tabs/tabs-list.svelte +1 -1
- package/dist/tailwind.theme.css +969 -0
- package/dist/tooltip/tooltip-content.svelte +2 -2
- package/dist/types.d.ts +36 -42
- package/package.json +2 -2
- package/dist/CounterWorkflow.svelte +0 -19
- package/dist/CounterWorkflow.svelte.d.ts +0 -4
- package/dist/EmptyStateIcon.svelte +0 -52
- package/dist/EmptyStateIcon.svelte.d.ts +0 -4
- package/dist/FormLayoutModal.svelte +0 -14
- package/dist/FormLayoutModal.svelte.d.ts +0 -4
- package/dist/ProfileSelector.svelte +0 -41
- package/dist/ProfileSelector.svelte.d.ts +0 -4
- package/dist/SectionLayout.svelte +0 -13
- package/dist/SectionLayout.svelte.d.ts +0 -4
- package/dist/tw.theme.d.ts +0 -171
- package/dist/tw.theme.js +0 -188
package/dist/CardRelation.svelte
CHANGED
|
@@ -2,31 +2,27 @@
|
|
|
2
2
|
import { Icon } from '@steeze-ui/svelte-icon'
|
|
3
3
|
import type { CardRelationProps } from './types.js'
|
|
4
4
|
import { ChevronRight } from '@invopop/ui-icons'
|
|
5
|
-
import SeparatorHorizontal from './SeparatorHorizontal.svelte'
|
|
6
5
|
|
|
7
6
|
let { title = '', icon = undefined, items = [], onclick }: CardRelationProps = $props()
|
|
8
7
|
</script>
|
|
9
8
|
|
|
10
|
-
<div class="border border-
|
|
11
|
-
<button
|
|
12
|
-
class="
|
|
13
|
-
{onclick}
|
|
14
|
-
>
|
|
15
|
-
<div class="flex items-center space-x-1.5">
|
|
9
|
+
<div class="border border-border-default-secondary rounded-2xl overflow-hidden">
|
|
10
|
+
<button class="flex items-center gap-3 px-3 py-2 w-full cursor-pointer" {onclick}>
|
|
11
|
+
<div class="flex grow items-center gap-1.5 min-w-0">
|
|
16
12
|
{#if icon}
|
|
17
|
-
<Icon src={icon} class="
|
|
13
|
+
<Icon src={icon} class="size-4 text-foreground shrink-0" />
|
|
18
14
|
{/if}
|
|
19
|
-
<span class="text-base font-medium text-
|
|
15
|
+
<span class="text-base font-medium text-foreground whitespace-nowrap">
|
|
16
|
+
{title}
|
|
17
|
+
</span>
|
|
20
18
|
</div>
|
|
21
|
-
|
|
22
|
-
<Icon src={ChevronRight} class="h-4 w-4 text-neutral-500" />
|
|
19
|
+
<Icon src={ChevronRight} class="size-3 text-foreground shrink-0" />
|
|
23
20
|
</button>
|
|
24
|
-
<
|
|
25
|
-
<div class="py-1.5 text-sm">
|
|
21
|
+
<div class="flex flex-col gap-2 px-3 pb-3 pt-2">
|
|
26
22
|
{#each items as item}
|
|
27
|
-
<div class="
|
|
28
|
-
<div class="min-w-[88px] text-
|
|
29
|
-
<div class="text-
|
|
23
|
+
<div class="flex items-center gap-3 text-sm">
|
|
24
|
+
<div class="min-w-[88px] text-foreground-default-secondary shrink-0">{item.label}</div>
|
|
25
|
+
<div class="grow text-foreground min-w-0">{item.value}</div>
|
|
30
26
|
</div>
|
|
31
27
|
{/each}
|
|
32
28
|
</div>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import ProfileAvatar from './ProfileAvatar.svelte'
|
|
3
|
-
import type { AnyProp, CompanySelectorProps, DrawerOption } from './types.js'
|
|
3
|
+
import type { AnyProp, CompanySelectorProps, DrawerOption, DrawerGroup } from './types.js'
|
|
4
4
|
import BaseDropdown from './BaseDropdown.svelte'
|
|
5
|
-
import
|
|
6
|
-
import { DoubleArrow } from '@invopop/ui-icons'
|
|
5
|
+
import DrawerContext from './DrawerContext.svelte'
|
|
6
|
+
import { DoubleArrow, Workspace, AddCircle, ExternalLink } from '@invopop/ui-icons'
|
|
7
7
|
import MenuItemCollapsible from './MenuItemCollapsible.svelte'
|
|
8
8
|
|
|
9
9
|
let companyDropdown: BaseDropdown | undefined = $state()
|
|
@@ -21,6 +21,24 @@
|
|
|
21
21
|
let country = $derived(selectedCompany?.country || '')
|
|
22
22
|
let picture = $derived(selectedCompany?.logo_url || '')
|
|
23
23
|
let isSandbox = $derived(selectedCompany?.sandbox)
|
|
24
|
+
|
|
25
|
+
let groups: DrawerGroup[] = [
|
|
26
|
+
{
|
|
27
|
+
label: 'Live',
|
|
28
|
+
slug: 'live',
|
|
29
|
+
emptyIcon: Workspace,
|
|
30
|
+
emptyTitle: 'No workspaces here',
|
|
31
|
+
emptyDescription: 'Create a workspace to start'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
label: 'Sandbox',
|
|
35
|
+
slug: 'sandbox',
|
|
36
|
+
emptyIcon: Workspace,
|
|
37
|
+
emptyTitle: 'No workspaces here',
|
|
38
|
+
emptyDescription: 'Create a workspace to start'
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
|
|
24
42
|
let items = $derived([
|
|
25
43
|
...companies.map((c) => ({
|
|
26
44
|
value: c.id,
|
|
@@ -28,8 +46,18 @@
|
|
|
28
46
|
selected: c.slug === selectedCompany?.slug && !!c.sandbox === !!selectedCompany?.sandbox,
|
|
29
47
|
country: c.country,
|
|
30
48
|
picture: c.logo_url,
|
|
31
|
-
sandbox: c.sandbox
|
|
32
|
-
|
|
49
|
+
sandbox: c.sandbox,
|
|
50
|
+
groupBy: c.sandbox ? 'sandbox' : 'live'
|
|
51
|
+
})),
|
|
52
|
+
{
|
|
53
|
+
separator: true
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
value: 'add',
|
|
57
|
+
label: 'Create workspace',
|
|
58
|
+
icon: AddCircle,
|
|
59
|
+
rightIcon: ExternalLink
|
|
60
|
+
}
|
|
33
61
|
] as DrawerOption[])
|
|
34
62
|
|
|
35
63
|
function selectCompany(value: AnyProp) {
|
|
@@ -60,8 +88,8 @@
|
|
|
60
88
|
active={isOpen}
|
|
61
89
|
bold
|
|
62
90
|
>
|
|
63
|
-
<ProfileAvatar {name} {picture} {country} dark
|
|
91
|
+
<ProfileAvatar {name} {picture} {country} dark variant="lg" />
|
|
64
92
|
</MenuItemCollapsible>
|
|
65
93
|
{/snippet}
|
|
66
|
-
<
|
|
94
|
+
<DrawerContext {items} {groups} onclick={selectCompany} widthClass="w-[300px]" />
|
|
67
95
|
</BaseDropdown>
|
package/dist/DataListItem.svelte
CHANGED
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
children
|
|
12
12
|
}: DataListItemProps = $props()
|
|
13
13
|
|
|
14
|
-
let
|
|
15
|
-
clsx({
|
|
14
|
+
let valueStyles = $derived(
|
|
15
|
+
clsx('text-foreground font-medium text-base', {
|
|
16
16
|
'font-mono': monospaced,
|
|
17
17
|
'slashed-zero tabular-nums lining-nums': monospacedNums,
|
|
18
18
|
'w-full': fullWidth
|
|
@@ -20,13 +20,17 @@
|
|
|
20
20
|
)
|
|
21
21
|
</script>
|
|
22
22
|
|
|
23
|
-
<div class="flex
|
|
24
|
-
<div class="text-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
{
|
|
29
|
-
{
|
|
30
|
-
|
|
23
|
+
<div class="flex gap-6 items-center px-3 py-1.5 rounded-lg hover:bg-background-default-secondary">
|
|
24
|
+
<div class="text-foreground-default-secondary text-base min-w-[125px]">
|
|
25
|
+
{label}
|
|
26
|
+
</div>
|
|
27
|
+
<div class="flex gap-1 items-center">
|
|
28
|
+
<div class={valueStyles}>
|
|
29
|
+
{#if children}
|
|
30
|
+
{@render children()}
|
|
31
|
+
{:else}
|
|
32
|
+
{value}
|
|
33
|
+
{/if}
|
|
34
|
+
</div>
|
|
31
35
|
</div>
|
|
32
36
|
</div>
|
package/dist/DatePicker.svelte
CHANGED
|
@@ -123,8 +123,8 @@
|
|
|
123
123
|
let isOpen = $state(false)
|
|
124
124
|
let styles = $derived(
|
|
125
125
|
clsx({
|
|
126
|
-
'border-
|
|
127
|
-
'border-
|
|
126
|
+
'border-border-selected-bold shadow-active': isOpen,
|
|
127
|
+
'border-border hover:border-border-default-secondary-hover': !isOpen
|
|
128
128
|
})
|
|
129
129
|
)
|
|
130
130
|
let selectedLabel = $state(label)
|
|
@@ -188,11 +188,11 @@
|
|
|
188
188
|
onclick={() => {
|
|
189
189
|
isOpen = !isOpen
|
|
190
190
|
}}
|
|
191
|
-
class="{styles} datepicker-trigger w-full py-1.25 pl-7 pr-8 border rounded-md text-
|
|
191
|
+
class="{styles} datepicker-trigger w-full py-1.25 pl-7 pr-8 border rounded-md text-foreground placeholder-foreground text-base cursor-pointer"
|
|
192
192
|
>
|
|
193
193
|
{selectedLabel}
|
|
194
194
|
</button>
|
|
195
|
-
<Icon src={Calendar} class="h-4 w-4 absolute top-2 left-2 text-
|
|
195
|
+
<Icon src={Calendar} class="h-4 w-4 absolute top-2 left-2 text-foreground-default-secondary" />
|
|
196
196
|
</div>
|
|
197
197
|
|
|
198
198
|
<div class="relative">
|
|
@@ -209,21 +209,21 @@
|
|
|
209
209
|
<div
|
|
210
210
|
class:left-0={position === 'left'}
|
|
211
211
|
class:right-0={position === 'right'}
|
|
212
|
-
class="bg-white inline-flex flex-col shadow rounded-lg absolute right-0 top-2 z-40"
|
|
212
|
+
class="bg-white inline-flex flex-col shadow-md rounded-lg absolute right-0 top-2 z-40"
|
|
213
213
|
use:clickOutside
|
|
214
214
|
onclick_outside={() => {
|
|
215
215
|
if (!isOpen) return
|
|
216
216
|
cancel()
|
|
217
217
|
}}
|
|
218
218
|
>
|
|
219
|
-
<div class="flex border-b border-
|
|
220
|
-
<div class="flex flex-col space-y-2 items-start p-3 border-r border-
|
|
219
|
+
<div class="flex border-b border-border min-h-[300px] rounded-lg shadow-calendar">
|
|
220
|
+
<div class="flex flex-col space-y-2 items-start p-3 border-r border-border">
|
|
221
221
|
{#each periods as period}
|
|
222
222
|
<button
|
|
223
223
|
onclick={period.action}
|
|
224
224
|
class="{selectedPeriod === period.slug
|
|
225
|
-
? 'selected-period text-
|
|
226
|
-
: 'text-
|
|
225
|
+
? 'selected-period text-foreground-accent bg-foreground-accent/10'
|
|
226
|
+
: 'text-foreground-default-secondary'} whitespace-nowrap text-base px-2 py-1 tracking-normal rounded cursor-pointer"
|
|
227
227
|
>
|
|
228
228
|
{period.label}
|
|
229
229
|
</button>
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
import type { DrawerContextProps, DrawerOption } from './types.ts'
|
|
3
3
|
import DrawerContextItem from './DrawerContextItem.svelte'
|
|
4
4
|
import DrawerContextSeparator from './DrawerContextSeparator.svelte'
|
|
5
|
+
import EmptyState from './EmptyState.svelte'
|
|
6
|
+
import BaseCounter from './BaseCounter.svelte'
|
|
7
|
+
import { Icon } from '@steeze-ui/svelte-icon'
|
|
8
|
+
import { ChevronRight } from '@steeze-ui/heroicons'
|
|
9
|
+
import { slide } from 'svelte/transition'
|
|
5
10
|
|
|
6
11
|
let {
|
|
7
12
|
items = $bindable([]),
|
|
@@ -9,10 +14,44 @@
|
|
|
9
14
|
widthClass = 'w-60',
|
|
10
15
|
onclick,
|
|
11
16
|
onselect,
|
|
12
|
-
children
|
|
17
|
+
children,
|
|
18
|
+
groups
|
|
13
19
|
}: DrawerContextProps = $props()
|
|
14
20
|
|
|
15
21
|
let selectedItems = $derived(items.filter((i) => i.selected))
|
|
22
|
+
let hasGroups = $derived(groups && groups.length > 0)
|
|
23
|
+
let { groupedItems, ungroupedItems } = $derived.by(() => {
|
|
24
|
+
if (!hasGroups) return { groupedItems: new Map(), ungroupedItems: items }
|
|
25
|
+
|
|
26
|
+
const grouped = new Map<string, DrawerOption[]>()
|
|
27
|
+
const ungrouped: DrawerOption[] = []
|
|
28
|
+
|
|
29
|
+
groups!.forEach((group) => {
|
|
30
|
+
grouped.set(group.slug, [])
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
items.forEach((item) => {
|
|
34
|
+
if (item.groupBy && grouped.has(item.groupBy)) {
|
|
35
|
+
grouped.get(item.groupBy)!.push(item)
|
|
36
|
+
} else {
|
|
37
|
+
ungrouped.push(item)
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
return { groupedItems: grouped, ungroupedItems: ungrouped }
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
let openGroups = $state<Record<string, boolean>>({})
|
|
45
|
+
|
|
46
|
+
$effect(() => {
|
|
47
|
+
if (hasGroups) {
|
|
48
|
+
const selectedItem = items.find((i) => i.selected)
|
|
49
|
+
if (selectedItem?.groupBy && Object.keys(openGroups).length === 0) {
|
|
50
|
+
openGroups = { [selectedItem.groupBy]: true }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
16
55
|
$effect(() => {
|
|
17
56
|
onselect?.(selectedItems)
|
|
18
57
|
})
|
|
@@ -23,19 +62,82 @@
|
|
|
23
62
|
return i
|
|
24
63
|
})
|
|
25
64
|
}
|
|
65
|
+
|
|
66
|
+
function toggleGroup(groupSlug: string) {
|
|
67
|
+
openGroups = openGroups[groupSlug] ? {} : { [groupSlug]: true }
|
|
68
|
+
}
|
|
26
69
|
</script>
|
|
27
70
|
|
|
28
71
|
<div
|
|
29
|
-
class="{widthClass} border border-
|
|
72
|
+
class="{widthClass} border border-border rounded-2xl shadow-lg bg-white overflow-hidden flex flex-col"
|
|
30
73
|
>
|
|
31
74
|
{@render children?.()}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
|
|
75
|
+
|
|
76
|
+
{#if hasGroups}
|
|
77
|
+
{#each groups as group, index}
|
|
78
|
+
{@const groupItems = groupedItems.get(group.slug) || []}
|
|
79
|
+
{@const isLastGroup = index === groups!.length - 1}
|
|
80
|
+
<div class="flex-shrink-0 {!isLastGroup ? 'border-b border-border' : ''}">
|
|
81
|
+
<button
|
|
82
|
+
class="cursor-pointer flex items-center justify-between h-9 pl-3 pr-2.5 py-2.5 text-sm font-medium text-foreground-default-secondary w-full hover:bg-background-default-secondary rounded-lg overflow-clip"
|
|
83
|
+
onclick={() => toggleGroup(group.slug)}
|
|
84
|
+
>
|
|
85
|
+
<div class="flex items-center gap-1.5">
|
|
86
|
+
<span>{group.label}</span>
|
|
87
|
+
<Icon
|
|
88
|
+
src={ChevronRight}
|
|
89
|
+
class="size-3 text-icon-default-secondary transition-all transform {openGroups[
|
|
90
|
+
group.slug
|
|
91
|
+
]
|
|
92
|
+
? 'rotate-90'
|
|
93
|
+
: ''}"
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
{#if groupItems.length}
|
|
97
|
+
<BaseCounter value={groupItems.length} />
|
|
98
|
+
{/if}
|
|
99
|
+
</button>
|
|
100
|
+
|
|
101
|
+
{#if openGroups[group.slug]}
|
|
102
|
+
<div transition:slide class="w-full">
|
|
103
|
+
{#if !groupItems.length}
|
|
104
|
+
<div class="px-1 pt-1 pb-5">
|
|
105
|
+
<EmptyState
|
|
106
|
+
iconSource={group.emptyIcon}
|
|
107
|
+
title={group.emptyTitle || 'No items here'}
|
|
108
|
+
description={group.emptyDescription || 'Add items to get started'}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
{:else}
|
|
112
|
+
<div class="max-h-[400px] overflow-y-auto">
|
|
113
|
+
{#each groupItems as item}
|
|
114
|
+
{#if item.separator}
|
|
115
|
+
<DrawerContextSeparator />
|
|
116
|
+
{:else}
|
|
117
|
+
<div class="px-1">
|
|
118
|
+
<DrawerContextItem {item} {multiple} {onclick} onchange={updateItem} />
|
|
119
|
+
</div>
|
|
120
|
+
{/if}
|
|
121
|
+
{/each}
|
|
122
|
+
</div>
|
|
123
|
+
{/if}
|
|
124
|
+
</div>
|
|
125
|
+
{/if}
|
|
126
|
+
</div>
|
|
39
127
|
{/each}
|
|
40
|
-
|
|
128
|
+
{/if}
|
|
129
|
+
|
|
130
|
+
{#if ungroupedItems.length}
|
|
131
|
+
<div class="flex-shrink-0 max-h-[400px] overflow-y-auto">
|
|
132
|
+
{#each ungroupedItems as item}
|
|
133
|
+
{#if item.separator}
|
|
134
|
+
<DrawerContextSeparator />
|
|
135
|
+
{:else}
|
|
136
|
+
<div class="px-1">
|
|
137
|
+
<DrawerContextItem {item} {multiple} {onclick} onchange={updateItem} />
|
|
138
|
+
</div>
|
|
139
|
+
{/if}
|
|
140
|
+
{/each}
|
|
141
|
+
</div>
|
|
142
|
+
{/if}
|
|
41
143
|
</div>
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
import InputCheckbox from './InputCheckbox.svelte'
|
|
4
4
|
import { Icon } from '@steeze-ui/svelte-icon'
|
|
5
5
|
import { onMount } from 'svelte'
|
|
6
|
-
import { Success
|
|
7
|
-
import ProfileAvatar from './ProfileAvatar.svelte'
|
|
6
|
+
import { Success } from '@invopop/ui-icons'
|
|
8
7
|
import clsx from 'clsx'
|
|
9
8
|
import BaseFlag from './BaseFlag.svelte'
|
|
10
9
|
import { getCountryName } from './helpers.js'
|
|
@@ -14,32 +13,26 @@
|
|
|
14
13
|
multiple = false,
|
|
15
14
|
item = $bindable(),
|
|
16
15
|
scrollIfSelected = false,
|
|
17
|
-
workspace = false,
|
|
18
16
|
onchange,
|
|
19
17
|
onclick
|
|
20
18
|
}: DrawerContextItemProps = $props()
|
|
21
19
|
|
|
22
20
|
let el: HTMLElement | undefined = $state()
|
|
23
21
|
|
|
24
|
-
let hasIcon = $derived(item.icon || workspace)
|
|
25
|
-
|
|
26
22
|
let styles = $derived(
|
|
27
23
|
clsx(
|
|
28
|
-
|
|
29
|
-
{ '
|
|
30
|
-
{ 'pl-
|
|
31
|
-
{ '
|
|
32
|
-
{
|
|
33
|
-
|
|
24
|
+
'py-1.5 space-x-1.5',
|
|
25
|
+
{ 'pl-1.5': !item.icon },
|
|
26
|
+
{ 'pl-2': item.icon },
|
|
27
|
+
{ 'bg-background-selected': item.selected && !multiple },
|
|
28
|
+
{
|
|
29
|
+
'group-hover:bg-background-default-secondary':
|
|
30
|
+
(!item.selected && !item.disabled) || multiple
|
|
31
|
+
}
|
|
34
32
|
)
|
|
35
33
|
)
|
|
36
34
|
let labelStyles = $derived(
|
|
37
|
-
clsx(
|
|
38
|
-
{ 'text-danger-500': item.destructive },
|
|
39
|
-
{ 'text-neutral-800': !item.destructive },
|
|
40
|
-
{ 'tracking-tight max-w-[200px]': workspace },
|
|
41
|
-
{ 'tracking-normal': !workspace }
|
|
42
|
-
)
|
|
35
|
+
clsx({ 'text-danger-500': item.destructive }, { 'text-neutral-800': !item.destructive })
|
|
43
36
|
)
|
|
44
37
|
let title = $derived(item.label.length > 25 ? item.label : undefined)
|
|
45
38
|
|
|
@@ -64,19 +57,15 @@
|
|
|
64
57
|
|
|
65
58
|
<button
|
|
66
59
|
bind:this={el}
|
|
67
|
-
class="cursor-pointer w-full
|
|
60
|
+
class="cursor-pointer w-full py-0.5 disabled:opacity-30 group"
|
|
68
61
|
disabled={item.disabled}
|
|
69
62
|
onclick={handleClick}
|
|
70
63
|
>
|
|
71
64
|
<div class="{styles} rounded pr-2 flex items-center justify-start w-full">
|
|
72
|
-
{#if
|
|
73
|
-
<ProfileAvatar name={item.label} picture={item.picture} large />
|
|
74
|
-
{:else if item.icon}
|
|
65
|
+
{#if item.icon}
|
|
75
66
|
<Icon
|
|
76
67
|
src={item.icon}
|
|
77
|
-
class="w-4 h-4 {item.destructive
|
|
78
|
-
? 'text-danger-500'
|
|
79
|
-
: item.iconClass || 'text-neutral-500'}"
|
|
68
|
+
class="w-4 h-4 {item.destructive ? 'text-icon-critical' : item.iconClass || 'text-icon'}"
|
|
80
69
|
/>
|
|
81
70
|
{/if}
|
|
82
71
|
<div class="whitespace-nowrap flex-1 text-left flex flex-col truncate" {title}>
|
|
@@ -90,7 +79,7 @@
|
|
|
90
79
|
{#if item.country}
|
|
91
80
|
<span class="flex space-x-1 items-center">
|
|
92
81
|
<BaseFlag country={item.country} width={10} />
|
|
93
|
-
<span class="text-sm text-
|
|
82
|
+
<span class="text-sm text-foreground-default-secondary">
|
|
94
83
|
{getCountryName(item.country)}
|
|
95
84
|
</span>
|
|
96
85
|
</span>
|
|
@@ -98,15 +87,16 @@
|
|
|
98
87
|
</div>
|
|
99
88
|
{#if multiple}
|
|
100
89
|
<InputCheckbox
|
|
101
|
-
|
|
102
|
-
onchange={() => {
|
|
90
|
+
checked={item.selected ?? false}
|
|
91
|
+
onchange={(value) => {
|
|
92
|
+
item.selected = value
|
|
103
93
|
onchange?.(item)
|
|
104
94
|
}}
|
|
105
95
|
/>
|
|
106
96
|
{:else if item.selected}
|
|
107
|
-
<Icon src={Success} class="
|
|
97
|
+
<Icon src={Success} class="size-4 text-icon-selected" />
|
|
108
98
|
{:else if item.rightIcon}
|
|
109
|
-
<Icon src={item.rightIcon} class="
|
|
99
|
+
<Icon src={item.rightIcon} class="size-4 text-icon-default-secondary" />
|
|
110
100
|
{/if}
|
|
111
101
|
</div>
|
|
112
102
|
</button>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<li class="bg-
|
|
1
|
+
<li class="bg-border h-px w-full"></li>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Icon } from '@steeze-ui/svelte-icon'
|
|
5
5
|
import { AddCircle, ExternalLink, Workspace } from '@invopop/ui-icons'
|
|
6
6
|
import BaseCounter from './BaseCounter.svelte'
|
|
7
|
-
import
|
|
7
|
+
import EmptyState from './EmptyState.svelte'
|
|
8
8
|
import { slide } from 'svelte/transition'
|
|
9
9
|
import { ChevronRight } from '@steeze-ui/heroicons'
|
|
10
10
|
|
|
@@ -44,15 +44,15 @@
|
|
|
44
44
|
<span>Live</span>
|
|
45
45
|
</div>
|
|
46
46
|
{#if liveItems.length}
|
|
47
|
-
<BaseCounter
|
|
47
|
+
<BaseCounter value={liveItems.length} />
|
|
48
48
|
{/if}
|
|
49
49
|
</button>
|
|
50
50
|
{#if liveOpen}
|
|
51
51
|
<div transition:slide class="max-h-[475px] overflow-auto">
|
|
52
52
|
{#if !liveItems.length}
|
|
53
53
|
<div class="h-[182px] overflow-x-hidden">
|
|
54
|
-
<
|
|
55
|
-
|
|
54
|
+
<EmptyState
|
|
55
|
+
iconSource={Workspace}
|
|
56
56
|
title="No workspaces here"
|
|
57
57
|
description="Create a workspace to start"
|
|
58
58
|
/>
|
|
@@ -82,15 +82,15 @@
|
|
|
82
82
|
<span>Sandbox</span>
|
|
83
83
|
</div>
|
|
84
84
|
{#if sandboxItems.length}
|
|
85
|
-
<BaseCounter
|
|
85
|
+
<BaseCounter value={sandboxItems.length} />
|
|
86
86
|
{/if}
|
|
87
87
|
</button>
|
|
88
88
|
{#if sandboxOpen}
|
|
89
89
|
<div transition:slide class="max-h-[475px] overflow-auto">
|
|
90
90
|
{#if !sandboxItems.length}
|
|
91
91
|
<div class="h-[182px] overflow-x-hidden">
|
|
92
|
-
<
|
|
93
|
-
|
|
92
|
+
<EmptyState
|
|
93
|
+
iconSource={Workspace}
|
|
94
94
|
title="No workspaces here"
|
|
95
95
|
description="Create a workspace to start"
|
|
96
96
|
/>
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
)
|
|
50
50
|
|
|
51
51
|
let styles = $derived(
|
|
52
|
-
clsx({
|
|
53
|
-
'
|
|
54
|
-
'border-
|
|
52
|
+
clsx('border backdrop-blur-sm backdrop-filter', {
|
|
53
|
+
'border-border-selected-bold shadow-active': isOpen,
|
|
54
|
+
'border-border hover:border-border-default-secondary-hover': !isOpen
|
|
55
55
|
})
|
|
56
56
|
)
|
|
57
57
|
|
|
@@ -78,19 +78,45 @@
|
|
|
78
78
|
<BaseDropdown bind:isOpen placement="bottom-start" {fullWidth} bind:this={selectDropdown}>
|
|
79
79
|
{#snippet trigger()}
|
|
80
80
|
<div
|
|
81
|
-
class="{styles} dropdown-select
|
|
81
|
+
class="{styles} dropdown-select flex items-center rounded-lg py-1.5 px-2 bg-background whitespace-nowrap {fullWidth
|
|
82
|
+
? 'w-full'
|
|
83
|
+
: widthClass}"
|
|
82
84
|
>
|
|
83
85
|
{#if selectedColor}
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
<div class="flex items-center gap-1 flex-1 min-w-0">
|
|
87
|
+
<TagStatus dot status={selectedColor} />
|
|
88
|
+
<span
|
|
89
|
+
class="flex-1 text-sm truncate {selectedItems.length
|
|
90
|
+
? 'text-foreground'
|
|
91
|
+
: 'text-foreground-default-secondary'}"
|
|
92
|
+
>
|
|
93
|
+
{selectedLabel}
|
|
94
|
+
</span>
|
|
95
|
+
</div>
|
|
96
|
+
{:else if selectedIcon || resolvedIcon}
|
|
97
|
+
<div class="flex items-center gap-1 flex-1 min-w-0">
|
|
98
|
+
{#if selectedIcon}
|
|
99
|
+
<Icon src={selectedIcon} {iconTheme} class="{selectedIconColor} size-4 flex-shrink-0" />
|
|
100
|
+
{:else if resolvedIcon}
|
|
101
|
+
<Icon src={resolvedIcon} {iconTheme} class="text-icon size-4 flex-shrink-0" />
|
|
102
|
+
{/if}
|
|
103
|
+
<span
|
|
104
|
+
class="flex-1 text-sm truncate {selectedItems.length
|
|
105
|
+
? 'text-foreground'
|
|
106
|
+
: 'text-foreground-default-secondary'}"
|
|
107
|
+
>
|
|
108
|
+
{selectedLabel}
|
|
109
|
+
</span>
|
|
110
|
+
</div>
|
|
111
|
+
{:else}
|
|
112
|
+
<span
|
|
113
|
+
class="flex-1 text-sm truncate {selectedItems.length
|
|
114
|
+
? 'text-foreground'
|
|
115
|
+
: 'text-foreground-default-secondary'}"
|
|
116
|
+
>
|
|
117
|
+
{selectedLabel}
|
|
118
|
+
</span>
|
|
89
119
|
{/if}
|
|
90
|
-
|
|
91
|
-
<span class="w-full pr-8 text-neutral-800 placeholder-neutral-800 text-base truncate">
|
|
92
|
-
{selectedLabel}
|
|
93
|
-
</span>
|
|
94
120
|
</div>
|
|
95
121
|
{/snippet}
|
|
96
122
|
<DrawerContext {widthClass} {multiple} {items} onclick={handleClick} onselect={handleSelected} />
|
|
@@ -98,7 +124,7 @@
|
|
|
98
124
|
|
|
99
125
|
<style>
|
|
100
126
|
.dropdown-select {
|
|
101
|
-
background-image: url('data:image/svg+xml;base64,
|
|
127
|
+
background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHJlY3Qgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiByeD0iNCIgZmlsbD0icmdiYSg1LCA1LCAzNiwgMC4wNikiLz4KPHBhdGggZD0iTTQuNSA2LjVMOCAxMEwxMS41IDYuNSIgc3Ryb2tlPSIjMGIwYjEwIiBzdHJva2Utd2lkdGg9IjEuMSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cjwvc3ZnPg==');
|
|
102
128
|
background-repeat: no-repeat;
|
|
103
129
|
background-position: center right 8px;
|
|
104
130
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import IconEmpty from './svg/IconEmpty.svelte'
|
|
3
|
+
import CheckBadge from './svg/CheckBadge.svelte'
|
|
4
|
+
import { Icon } from '@steeze-ui/svelte-icon'
|
|
5
|
+
import type { EmptyStateProps } from './types'
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
icon,
|
|
9
|
+
iconSource,
|
|
10
|
+
title = '',
|
|
11
|
+
description = '',
|
|
12
|
+
check = false,
|
|
13
|
+
children
|
|
14
|
+
}: EmptyStateProps = $props()
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<div class="flex flex-col items-center justify-center gap-4">
|
|
18
|
+
{#if icon}
|
|
19
|
+
<div class="relative h-[120px] w-[352px] max-w-sm flex items-center justify-center">
|
|
20
|
+
{@render icon()}
|
|
21
|
+
</div>
|
|
22
|
+
{:else if iconSource}
|
|
23
|
+
<div class="relative h-[120px] w-[352px] max-w-sm">
|
|
24
|
+
<IconEmpty />
|
|
25
|
+
<div class="absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2">
|
|
26
|
+
<Icon src={iconSource} class="h-12 w-12 text-foreground-accent" />
|
|
27
|
+
{#if check}
|
|
28
|
+
<CheckBadge />
|
|
29
|
+
{/if}
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
{/if}
|
|
33
|
+
<div class="flex flex-col items-center gap-0.5 text-center">
|
|
34
|
+
<h4 class="font-medium text-foreground text-base">{title}</h4>
|
|
35
|
+
<p class="text-foreground-default-secondary text-base">{description}</p>
|
|
36
|
+
</div>
|
|
37
|
+
{#if children}
|
|
38
|
+
{@render children()}
|
|
39
|
+
{/if}
|
|
40
|
+
</div>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { EmptyStateIllustrationProps } from './types.js';
|
|
2
1
|
declare const EmptyStateIllustration: import("svelte").Component<EmptyStateIllustrationProps, {}, "">;
|
|
3
2
|
type EmptyStateIllustration = ReturnType<typeof EmptyStateIllustration>;
|
|
4
3
|
export default EmptyStateIllustration;
|