@invopop/popui 0.1.57 → 0.1.59

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.
@@ -2,6 +2,7 @@
2
2
  import { Duplicate } from '@invopop/ui-icons'
3
3
  import BaseButton from './BaseButton.svelte'
4
4
  import type { ButtonUuidCopyProps } from './types'
5
+ import { copyToClipboard } from './helpers'
5
6
 
6
7
  let {
7
8
  uuid = '',
@@ -35,7 +36,7 @@
35
36
  data-uuid-copy
36
37
  onclick={async (e) => {
37
38
  e.stopPropagation()
38
- await navigator.clipboard.writeText(uuid)
39
+ await copyToClipboard(uuid)
39
40
  oncopied?.(uuid)
40
41
  }}
41
42
  >
@@ -1,36 +1,80 @@
1
1
  <script lang="ts">
2
2
  import clsx from 'clsx'
3
3
  import type { DataListItemProps } from './types'
4
+ import BaseButton from './BaseButton.svelte'
5
+ import { Duplicate, ExternalLink } from '@invopop/ui-icons'
6
+ import { copyToClipboard } from './helpers'
4
7
 
5
8
  let {
6
9
  label = '',
7
10
  value = '',
8
11
  monospaced = false,
9
- monospacedNums = false,
10
- fullWidth = false,
11
- children
12
+ children,
13
+ onCopy,
14
+ onLink
12
15
  }: DataListItemProps = $props()
13
16
 
14
17
  let valueStyles = $derived(
15
- clsx('text-foreground font-medium text-base', {
16
- 'font-mono': monospaced,
17
- 'slashed-zero tabular-nums lining-nums': monospacedNums,
18
- 'w-full': fullWidth
18
+ clsx('text-foreground font-medium text-base truncate min-w-0', {
19
+ 'font-mono slashed-zero tabular-nums lining-nums': monospaced
19
20
  })
20
21
  )
22
+
23
+ let clickAction = $derived(onCopy || onLink)
24
+
25
+ const handleAreaClick = async (e: MouseEvent) => {
26
+ // Only handle click if not clicking on a button
27
+ if ((e.target as HTMLElement).closest('button')) return
28
+
29
+ if (onCopy) {
30
+ await copyToClipboard(value)
31
+ onCopy()
32
+ } else if (onLink) {
33
+ onLink()
34
+ }
35
+ }
21
36
  </script>
22
37
 
23
- <div class="flex gap-6 items-center px-3 py-1 rounded-lg hover:bg-background-default-secondary">
38
+ <div class="flex gap-6 items-center group">
24
39
  <div class="text-foreground-default-secondary text-base min-w-[125px]">
25
40
  {label}
26
41
  </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}
42
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
43
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
44
+ <div
45
+ class={clsx(
46
+ 'flex flex-1 gap-1 items-center group-hover:bg-background-default-secondary py-1 pl-2 pr-1 rounded-md min-w-0',
47
+ { 'cursor-pointer': clickAction }
48
+ )}
49
+ onclick={clickAction ? handleAreaClick : undefined}
50
+ >
51
+ <div class="flex-1 min-w-0 h-8">
52
+ <div class={valueStyles}>
53
+ {#if children}
54
+ {@render children()}
55
+ {:else}
56
+ {value}
57
+ {/if}
58
+ </div>
34
59
  </div>
60
+ {#if onCopy}
61
+ <BaseButton
62
+ variant="outline"
63
+ icon={Duplicate}
64
+ onclick={async () => {
65
+ await copyToClipboard(value)
66
+ onCopy()
67
+ }}
68
+ class="opacity-0 group-hover:opacity-100 transition-opacity"
69
+ />
70
+ {/if}
71
+ {#if onLink}
72
+ <BaseButton
73
+ variant="outline"
74
+ icon={ExternalLink}
75
+ onclick={onLink}
76
+ class="opacity-0 group-hover:opacity-100 transition-opacity"
77
+ />
78
+ {/if}
35
79
  </div>
36
80
  </div>
@@ -126,17 +126,17 @@
126
126
  {
127
127
  size: 'sm',
128
128
  iconOnly: true,
129
- class: 'w-6'
129
+ class: 'w-6 shrink-0'
130
130
  },
131
131
  {
132
132
  size: 'md',
133
133
  iconOnly: true,
134
- class: 'w-7'
134
+ class: 'w-7 shrink-0'
135
135
  },
136
136
  {
137
137
  size: 'lg',
138
138
  iconOnly: true,
139
- class: 'w-8'
139
+ class: 'w-8 shrink-0'
140
140
  },
141
141
  {
142
142
  stackedLeft: true,
@@ -201,15 +201,7 @@
201
201
  let iconOnly = $derived(!children)
202
202
  let hasIcon = $derived(!!icon && !iconOnly)
203
203
 
204
- let iconSize = $derived.by(() => {
205
- if (shortcut) return 'size-3'
206
-
207
- return {
208
- sm: 'size-3',
209
- md: 'size-4',
210
- lg: 'size-4'
211
- }[size]
212
- })
204
+ let iconSize = $derived(shortcut ? 'size-3' : 'size-4')
213
205
 
214
206
  // For icon-right, we need to reverse the padding
215
207
  let paddingClass = $derived(
@@ -240,7 +232,7 @@
240
232
 
241
233
  {#snippet buttonContent()}
242
234
  <div
243
- class={clsx('inline-flex items-center transition-transform group-active:translate-y-px', {
235
+ class={clsx('inline-flex items-center transition-transform group-active/button:translate-y-px', {
244
236
  'gap-1': !iconOnly && !shortcut,
245
237
  'gap-1.5': !iconOnly && shortcut
246
238
  })}
@@ -271,6 +263,7 @@
271
263
  data-slot="button"
272
264
  class={cn(
273
265
  buttonVariants({ variant, size, iconOnly, hasIcon, stackedLeft, stackedRight }),
266
+ 'group/button',
274
267
  iconPosition === 'right' && 'flex-row-reverse',
275
268
  paddingClass,
276
269
  className
@@ -289,7 +282,7 @@
289
282
  data-slot="button"
290
283
  class={cn(
291
284
  buttonVariants({ variant, size, iconOnly, hasIcon, stackedLeft, stackedRight }),
292
- 'group',
285
+ 'group/button',
293
286
  iconPosition === 'right' && 'flex-row-reverse',
294
287
  paddingClass,
295
288
  className
package/dist/helpers.d.ts CHANGED
@@ -11,3 +11,4 @@ export declare function scrollIntoTableView(element: HTMLElement): void;
11
11
  export declare function isInputFocused(): boolean;
12
12
  export declare function toCalendarDate(date: Date): DateValue;
13
13
  export declare function datesFromToday(): DatesFromToday;
14
+ export declare function copyToClipboard(text: string): Promise<void>;
package/dist/helpers.js CHANGED
@@ -120,3 +120,6 @@ export function datesFromToday() {
120
120
  endOfLastQuarter
121
121
  };
122
122
  }
123
+ export async function copyToClipboard(text) {
124
+ await navigator.clipboard.writeText(text);
125
+ }
package/dist/types.d.ts CHANGED
@@ -96,7 +96,6 @@ export type TableField = {
96
96
  helperIcons?: (data: TableDataRow) => TableIcon[];
97
97
  monospaced?: boolean;
98
98
  nowrap?: boolean;
99
- monospacedNums?: boolean;
100
99
  rightAlign?: boolean;
101
100
  isCountry?: boolean;
102
101
  copy?: boolean;
@@ -309,9 +308,10 @@ export interface DataListItemProps {
309
308
  label?: string;
310
309
  value?: string;
311
310
  monospaced?: boolean;
312
- monospacedNums?: boolean;
313
311
  fullWidth?: boolean;
314
312
  children?: Snippet;
313
+ onCopy?: () => void;
314
+ onLink?: () => void;
315
315
  }
316
316
  export interface DatePickerProps {
317
317
  label?: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@invopop/popui",
3
3
  "license": "MIT",
4
- "version": "0.1.57",
4
+ "version": "0.1.59",
5
5
  "repository": {
6
6
  "url": "https://github.com/invopop/popui"
7
7
  },