@invopop/popui 0.1.30 → 0.1.32

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.
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import type { CounterWidgetProps } from './types'
3
+ import { Icon } from '@steeze-ui/svelte-icon'
4
+ import { Warning, Failure } from '@invopop/ui-icons'
5
+ import ProgressBar from './ProgressBar.svelte'
6
+
7
+ let {
8
+ label,
9
+ current,
10
+ total,
11
+ resetDate = '',
12
+ icon,
13
+ allowOverage = true
14
+ }: CounterWidgetProps = $props()
15
+
16
+ let percentage = $derived(total > 0 ? (current / total) * 100 : 0)
17
+ let isOverage = $derived(current > total && allowOverage)
18
+ let isCritical = $derived(percentage >= 100 || (current > total && !allowOverage))
19
+ let isWarning = $derived(percentage >= 80 && percentage < 100)
20
+ </script>
21
+
22
+ <div class="border border-border-inverse rounded-xl w-full py-[5px] pl-2 pr-1.5 flex flex-col">
23
+ <div class="flex items-center justify-between text-base font-medium">
24
+ <div class="flex items-center gap-1.5">
25
+ {#if icon}
26
+ <Icon src={icon} class="size-3 text-icon-inverse rounded-xs" />
27
+ {/if}
28
+ <span class="font-medium text-foreground-inverse">
29
+ {label}
30
+ </span>
31
+ </div>
32
+ <div class="flex items-center gap-1.5">
33
+ {#if isCritical && !isOverage}
34
+ <Icon src={Failure} class="size-4 text-icon-critical-inverse" />
35
+ {:else if isWarning && !isOverage}
36
+ <Icon src={Warning} class="size-4 text-icon-warning-inverse" />
37
+ {/if}
38
+ <span class="font-mono text-foreground-inverse">
39
+ {current}<span class="text-white/70">/{total}</span>
40
+ </span>
41
+ </div>
42
+ </div>
43
+ <div class="py-2">
44
+ <ProgressBar {percentage} {current} {total} {allowOverage} />
45
+ </div>
46
+
47
+ {#if resetDate}
48
+ <span class="text-sm font-normal text-foreground-inverse-secondary">
49
+ {label} reset {resetDate}
50
+ </span>
51
+ {/if}
52
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { CounterWidgetProps } from './types';
2
+ declare const CounterWidget: import("svelte").Component<CounterWidgetProps, {}, "">;
3
+ type CounterWidget = ReturnType<typeof CounterWidget>;
4
+ export default CounterWidget;
@@ -79,7 +79,7 @@
79
79
  {/snippet}
80
80
 
81
81
  <div
82
- class="{widthClass} border border-border rounded-2xl shadow-lg bg-background flex flex-col py-1 max-h-[440px] list-none"
82
+ class="{widthClass} border border-border rounded-2xl shadow-lg bg-background flex flex-col py-1 max-h-[568px] list-none"
83
83
  >
84
84
  {@render children?.()}
85
85
 
@@ -140,7 +140,7 @@
140
140
  {/if}
141
141
 
142
142
  {#if ungroupedItems.length}
143
- <div class="flex-shrink-0 overflow-y-auto max-h-[436px]">
143
+ <div class="flex-shrink-0 overflow-y-auto max-h-[564px]">
144
144
  {#each ungroupedItems as item}
145
145
  {@render drawerItem(item)}
146
146
  {/each}
@@ -31,7 +31,11 @@
31
31
  )
32
32
  )
33
33
  let labelStyles = $derived(
34
- clsx({ 'text-foreground-critical': item.destructive }, { 'text-foreground': !item.destructive })
34
+ clsx(
35
+ { 'text-foreground-critical': item.destructive },
36
+ { 'text-foreground': !item.destructive },
37
+ { 'opacity-30': item.locked }
38
+ )
35
39
  )
36
40
  let title = $derived(item.label.length > 25 ? item.label : undefined)
37
41
 
@@ -68,7 +72,9 @@
68
72
  {:else if item.icon}
69
73
  <Icon
70
74
  src={item.icon}
71
- class="w-4 h-4 {item.destructive ? 'text-icon-critical' : item.iconClass || 'text-icon'}"
75
+ class="w-4 h-4 {item.destructive
76
+ ? 'text-icon-critical'
77
+ : item.iconClass || 'text-icon'} {item.locked ? 'opacity-30' : ''}"
72
78
  />
73
79
  {/if}
74
80
  <div class="whitespace-nowrap flex-1 text-left flex items-center space-x-1.5 truncate" {title}>
@@ -84,7 +90,9 @@
84
90
  </span>
85
91
  {/if}
86
92
  </div>
87
- {#if multiple}
93
+ {#if item.action}
94
+ {@render item.action()}
95
+ {:else if multiple}
88
96
  <InputCheckbox
89
97
  checked={item.selected ?? false}
90
98
  onchange={(value) => {
@@ -1,7 +1,36 @@
1
1
  <script lang="ts">
2
- let { percentage = 0 }: { percentage?: number } = $props()
2
+ import clsx from 'clsx'
3
+ import type { ProgressBarProps } from './types'
4
+
5
+ let { percentage = 0, current = 0, total = 0, allowOverage = true }: ProgressBarProps = $props()
6
+
7
+ let isOverage = $derived(current > total && allowOverage)
8
+ let overagePercentage = $derived(isOverage && total > 0 ? ((current - total) / current) * 100 : 0)
9
+ let usedPercentage = $derived(isOverage ? 100 - overagePercentage : percentage)
10
+ let isCritical = $derived(percentage >= 100 || (current > total && !allowOverage))
11
+ let isWarning = $derived(percentage >= 80 && percentage < 100)
12
+
13
+ let barColor = $derived(
14
+ clsx({
15
+ 'bg-background-critical-inverse': isCritical,
16
+ 'bg-background-warning-inverse': isWarning || isOverage,
17
+ 'bg-icon-inverse-bold': !isCritical && !isWarning && !isOverage
18
+ })
19
+ )
20
+
21
+ let barWidth = $derived(isOverage ? usedPercentage : Math.min(percentage, 100))
3
22
  </script>
4
23
 
5
- <div class="w-full h-1 shrink-0 rounded-full bg-background-default-secondary">
6
- <div class="rounded-full h-1 bg-foreground-accent" style="width: {percentage}%;"></div>
24
+ <div class="flex gap-0.5 w-full h-1">
25
+ {#if isOverage}
26
+ <div class="h-1 rounded-full bg-icon-inverse-bold" style="width: {barWidth}%"></div>
27
+ <div class="h-1 rounded-full bg-background-warning-inverse flex-1"></div>
28
+ {:else if percentage >= 100}
29
+ <div class="h-1 rounded-full {barColor} w-full"></div>
30
+ {:else}
31
+ {#if barWidth > 0}
32
+ <div class="h-1 rounded-full {barColor}" style="width: {barWidth}%"></div>
33
+ {/if}
34
+ <div class="h-1 rounded-full bg-background-selected-inverse flex-1"></div>
35
+ {/if}
7
36
  </div>
@@ -1,6 +1,4 @@
1
- type $$ComponentProps = {
2
- percentage?: number;
3
- };
4
- declare const ProgressBar: import("svelte").Component<$$ComponentProps, {}, "">;
1
+ import type { ProgressBarProps } from './types';
2
+ declare const ProgressBar: import("svelte").Component<ProgressBarProps, {}, "">;
5
3
  type ProgressBar = ReturnType<typeof ProgressBar>;
6
4
  export default ProgressBar;
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ import ButtonUuidCopy from './ButtonUuidCopy.svelte';
13
13
  import CardCheckbox from './CardCheckbox.svelte';
14
14
  import CardRelation from './CardRelation.svelte';
15
15
  import CompanySelector from './CompanySelector.svelte';
16
+ import CounterWidget from './CounterWidget.svelte';
16
17
  import DataListItem from './DataListItem.svelte';
17
18
  import DatePicker from './DatePicker.svelte';
18
19
  import DrawerContext from './DrawerContext.svelte';
@@ -71,4 +72,4 @@ import { resolveIcon } from './helpers.js';
71
72
  import { getCountryName } from './helpers.js';
72
73
  import { getStatusType } from './helpers.js';
73
74
  import { buttonVariants } from './button/button.svelte';
74
- export { AlertDialog, BaseButton, BaseCard, BaseCounter, BaseDropdown, BaseFlag, BaseTable, BaseTableActions, BaseTableHeaderContent, Breadcrumbs, ButtonFile, ButtonUuidCopy, CardCheckbox, CardRelation, CompanySelector, DataListItem, DatePicker, DrawerContext, DrawerContextItem, DrawerContextSeparator, DropdownSelect, EmptyState, FeedEvents, FeedIconEvent, FeedIconStatus, FeedItem, FeedItemDetail, FeedViewer, GlobalSearch, InputCheckbox, InputError, InputLabel, InputRadio, InputSearch, InputSelect, InputText, InputTextarea, InputToggle, MenuItem, MenuItemCollapsible, Notification, ProfileAvatar, ProgressBar, SeparatorHorizontal, ShortcutWrapper, StatusLabel, StepIconList, Table, TableBody, TableCaption, TableFooter, TableHeader, TableRow, TableHead, TableCell, Tabs, TabsContent, TabsList, TabsTrigger, TagBeta, TagSearch, TagStatus, TitleMain, TitleSection, Toaster, Tooltip, TooltipContent, TooltipTrigger, UuidCopy, resolveIcon, getCountryName, getStatusType, buttonVariants };
75
+ export { AlertDialog, BaseButton, BaseCard, BaseCounter, BaseDropdown, BaseFlag, BaseTable, BaseTableActions, BaseTableHeaderContent, Breadcrumbs, ButtonFile, ButtonUuidCopy, CardCheckbox, CardRelation, CompanySelector, CounterWidget, DataListItem, DatePicker, DrawerContext, DrawerContextItem, DrawerContextSeparator, DropdownSelect, EmptyState, FeedEvents, FeedIconEvent, FeedIconStatus, FeedItem, FeedItemDetail, FeedViewer, GlobalSearch, InputCheckbox, InputError, InputLabel, InputRadio, InputSearch, InputSelect, InputText, InputTextarea, InputToggle, MenuItem, MenuItemCollapsible, Notification, ProfileAvatar, ProgressBar, SeparatorHorizontal, ShortcutWrapper, StatusLabel, StepIconList, Table, TableBody, TableCaption, TableFooter, TableHeader, TableRow, TableHead, TableCell, Tabs, TabsContent, TabsList, TabsTrigger, TagBeta, TagSearch, TagStatus, TitleMain, TitleSection, Toaster, Tooltip, TooltipContent, TooltipTrigger, UuidCopy, resolveIcon, getCountryName, getStatusType, buttonVariants };
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ import ButtonUuidCopy from './ButtonUuidCopy.svelte'
13
13
  import CardCheckbox from './CardCheckbox.svelte'
14
14
  import CardRelation from './CardRelation.svelte'
15
15
  import CompanySelector from './CompanySelector.svelte'
16
+ import CounterWidget from './CounterWidget.svelte'
16
17
  import DataListItem from './DataListItem.svelte'
17
18
  import DatePicker from './DatePicker.svelte'
18
19
  import DrawerContext from './DrawerContext.svelte'
@@ -83,6 +84,7 @@ export {
83
84
  CardCheckbox,
84
85
  CardRelation,
85
86
  CompanySelector,
87
+ CounterWidget,
86
88
  DataListItem,
87
89
  DatePicker,
88
90
  DrawerContext,
package/dist/types.d.ts CHANGED
@@ -36,8 +36,10 @@ export type DrawerOption = SelectOption & {
36
36
  sandbox?: boolean;
37
37
  iconClass?: string;
38
38
  disabled?: boolean;
39
+ locked?: boolean;
39
40
  groupBy?: string;
40
41
  useAvatar?: boolean;
42
+ action?: Snippet;
41
43
  };
42
44
  export type Company = {
43
45
  id: string;
@@ -184,6 +186,20 @@ export interface BaseCounterProps {
184
186
  value: number;
185
187
  theme?: 'light' | 'navigation' | 'accent';
186
188
  }
189
+ export interface CounterWidgetProps {
190
+ label: string;
191
+ current: number;
192
+ total: number;
193
+ resetDate?: string;
194
+ icon?: IconSource;
195
+ allowOverage?: boolean;
196
+ }
197
+ export interface ProgressBarProps {
198
+ percentage?: number;
199
+ current?: number;
200
+ total?: number;
201
+ allowOverage?: boolean;
202
+ }
187
203
  export interface BaseDropdownProps {
188
204
  isOpen?: boolean;
189
205
  fullWidth?: boolean;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@invopop/popui",
3
3
  "license": "MIT",
4
- "version": "0.1.30",
4
+ "version": "0.1.32",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
7
7
  "dev:clean": "npm run clean && vite dev",
@@ -82,7 +82,7 @@
82
82
  "type": "module",
83
83
  "dependencies": {
84
84
  "@floating-ui/core": "^1.5.1",
85
- "@invopop/ui-icons": "0.0.72",
85
+ "@invopop/ui-icons": "0.0.74",
86
86
  "@steeze-ui/heroicons": "^2.2.3",
87
87
  "@steeze-ui/svelte-icon": "^1.6.2",
88
88
  "@tailwindcss/vite": "^4.1.12",