poe-svelte-ui-lib 1.6.2 → 1.6.3

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.
@@ -1,21 +1,22 @@
1
1
  <!-- $lib/ElementsUI/Table.svelte -->
2
2
  <script lang="ts">
3
- import { get } from 'svelte/store'
4
- import type { ITableHeader, ITableProps } from '../types'
5
- import { fade, fly } from 'svelte/transition'
6
- import { twMerge } from 'tailwind-merge'
7
- import { onMount } from 'svelte'
8
- import ButtonClear from '../libIcons/ButtonClear.svelte'
3
+ import { get } from "svelte/store"
4
+ import type { ISelectOption, ITableHeader, ITableProps } from "../types"
5
+ import { fade, fly, slide } from "svelte/transition"
6
+ import { twMerge } from "tailwind-merge"
7
+ import { onMount } from "svelte"
8
+ import ButtonClear from "../libIcons/ButtonClear.svelte"
9
+ import { t } from "../locales/i18n"
9
10
 
10
11
  let {
11
12
  id = crypto.randomUUID(),
12
- wrapperClass = '',
13
- label = { name: '', class: '' },
13
+ wrapperClass = "",
14
+ label = { name: "", class: "" },
14
15
  body = $bindable(),
15
16
  header = [],
16
- footer = '',
17
- dataBuffer = { stashData: false, rowsAmmount: 10, clearButton: false, clearClass: '' },
18
- type = 'table',
17
+ footer = "",
18
+ dataBuffer = { stashData: false, rowsAmmount: 10, clearButton: false, clearClass: "" },
19
+ type = "table",
19
20
  outline = false,
20
21
  cursor = null,
21
22
  loader,
@@ -33,7 +34,7 @@
33
34
  /* Сортировка */
34
35
  let sortState: {
35
36
  key: string | null
36
- direction: 'asc' | 'desc' | null
37
+ direction: "asc" | "desc" | null
37
38
  } = {
38
39
  key: null,
39
40
  direction: null,
@@ -42,42 +43,42 @@
42
43
  let isAutoscroll = $state(false)
43
44
 
44
45
  const logTypeOptions = [
45
- { id: crypto.randomUUID(), name: 'Error', value: 'error', color: 'bg-(--red-color)' },
46
- { id: crypto.randomUUID(), name: 'Warning', value: 'warning', color: 'bg-(--yellow-color)' },
47
- { id: crypto.randomUUID(), name: 'Info', value: 'info', color: 'bg-(--gray-color)' },
46
+ { id: crypto.randomUUID(), name: "Error", value: "error", color: "bg-(--red-color)" },
47
+ { id: crypto.randomUUID(), name: "Warning", value: "warning", color: "bg-(--yellow-color)" },
48
+ { id: crypto.randomUUID(), name: "Info", value: "info", color: "bg-(--gray-color)" },
48
49
  ]
49
- let logType = $state(['error', 'warning'])
50
+ let logType = $state(["error", "warning"])
50
51
 
51
52
  /* Сортировка столбцов */
52
53
  const sortRows = (key: string) => {
53
54
  if (sortState.key === key) {
54
- sortState.direction = sortState.direction === 'asc' ? 'desc' : 'asc'
55
+ sortState.direction = sortState.direction === "asc" ? "desc" : "asc"
55
56
  } else {
56
57
  sortState.key = key
57
- sortState.direction = 'asc'
58
+ sortState.direction = "asc"
58
59
  }
59
60
 
60
61
  body = [...body].sort((a, b) => {
61
62
  const aValue = a[key]
62
63
  const bValue = b[key]
63
- if (typeof aValue === 'number' && typeof bValue === 'number') {
64
- return sortState.direction === 'asc' ? aValue - bValue : bValue - aValue
64
+ if (typeof aValue === "number" && typeof bValue === "number") {
65
+ return sortState.direction === "asc" ? aValue - bValue : bValue - aValue
65
66
  }
66
67
  if (aValue instanceof Date && bValue instanceof Date) {
67
- return sortState.direction === 'asc' ? aValue.getTime() - bValue.getTime() : bValue.getTime() - aValue.getTime()
68
+ return sortState.direction === "asc" ? aValue.getTime() - bValue.getTime() : bValue.getTime() - aValue.getTime()
68
69
  }
69
70
  const strA = String(aValue).toLowerCase()
70
71
  const strB = String(bValue).toLowerCase()
71
- const numA = strA.match(/\d+/g)?.[0] || ''
72
- const numB = strB.match(/\d+/g)?.[0] || ''
72
+ const numA = strA.match(/\d+/g)?.[0] || ""
73
+ const numB = strB.match(/\d+/g)?.[0] || ""
73
74
  if (numA && numB) {
74
75
  const numCompare = parseInt(numA, 10) - parseInt(numB, 10)
75
76
  if (numCompare !== 0) {
76
- return sortState.direction === 'asc' ? numCompare : -numCompare
77
+ return sortState.direction === "asc" ? numCompare : -numCompare
77
78
  }
78
79
  }
79
80
  const stringCompare = strA.localeCompare(strB)
80
- return sortState.direction === 'asc' ? stringCompare : -stringCompare
81
+ return sortState.direction === "asc" ? stringCompare : -stringCompare
81
82
  })
82
83
  }
83
84
 
@@ -113,18 +114,33 @@
113
114
  if (button.onClick) button.onClick(row)
114
115
  else if (button.eventHandler && onClick) {
115
116
  let value: Record<string, boolean | string | number | number[] | object | null> = {}
116
- button.eventHandler.Variables.forEach((v: string) => {
117
- value[v] = row[v]
118
- })
117
+ button.eventHandler.Variables.forEach((v: string) => (value[v] = row[v]))
119
118
  button.eventHandler.Value = JSON.stringify(value)
120
119
  onClick(button.eventHandler)
121
120
  }
122
121
  }
123
122
 
124
- let copiedCell = $state({ x: '', y: -1 })
123
+ let isDropdownOpen: number | null = $state(null)
124
+ let changedOptions: { index: number; options: ISelectOption<string | number>[] | null }[] = $state([])
125
+
126
+ const selectOption = (index: number, options: ISelectOption<string | number>[], option: ISelectOption<string | number>, event: MouseEvent) => {
127
+ event.stopPropagation()
128
+
129
+ const existingItem = changedOptions.find(item => item.index === index)
130
+
131
+ if (existingItem) {
132
+ existingItem.options = [option, ...options.filter(opt => opt.id !== option.id)]
133
+ } else {
134
+ changedOptions = [...changedOptions, { index, options: [option, ...options.filter(opt => opt.id !== option.id)] }]
135
+ }
136
+
137
+ isDropdownOpen = null
138
+ }
139
+
140
+ let copiedCell = $state({ x: "", y: -1 })
125
141
  let tooltip = $state({
126
142
  show: false,
127
- text: '',
143
+ text: "",
128
144
  x: 0,
129
145
  y: 0,
130
146
  })
@@ -133,14 +149,14 @@
133
149
  modalData = {
134
150
  isOpen: true,
135
151
  rawData: text,
136
- formattedData: formatting ? formatting(text) : (text ?? ''),
152
+ formattedData: formatting ? formatting(text) : (text ?? ""),
137
153
  }
138
154
  }
139
155
 
140
156
  const showTooltip = (event: MouseEvent, text: string, formatting?: (text: string) => string) => {
141
157
  tooltip = {
142
158
  show: true,
143
- text: formatting ? formatting(text) : (text ?? ''),
159
+ text: formatting ? formatting(text) : (text ?? ""),
144
160
  x: event.clientX,
145
161
  y: event.clientY,
146
162
  }
@@ -153,23 +169,23 @@
153
169
  /* Для работы этой проверки в описании столбцов таблицы нужно явно указать что строка будет пустая при отсутствии иконки в БД -
154
170
  src: (row) => (row.icon ? `data:image/png;base64,${row.icon}` : '') */
155
171
  const hasImage = (column: ITableHeader<any>, row: any): boolean => {
156
- const src = typeof column.image?.src === 'function' ? column.image.src(row) : column.image?.src
172
+ const src = typeof column.image?.src === "function" ? column.image.src(row) : column.image?.src
157
173
  return !!src
158
174
  }
159
175
 
160
176
  $effect(() => {
161
177
  const currentType = type
162
- if (currentType === 'logger') {
178
+ if (currentType === "logger") {
163
179
  header = [
164
180
  {
165
- key: 'color',
166
- label: { name: 'Type' },
167
- width: '3rem',
181
+ key: "color",
182
+ label: { name: "Type" },
183
+ width: "3rem",
168
184
  } as ITableHeader<any>,
169
185
  {
170
- key: 'data',
171
- label: { name: 'Data' },
172
- width: 'calc(100% - 3rem)',
186
+ key: "data",
187
+ label: { name: "Data" },
188
+ width: "calc(100% - 3rem)",
173
189
  } as ITableHeader<any>,
174
190
  ]
175
191
  }
@@ -179,14 +195,14 @@
179
195
  })
180
196
 
181
197
  $effect(() => {
182
- if (body && type == 'logger') {
198
+ if (body && type == "logger") {
183
199
  if (Array.isArray(body)) {
184
200
  for (let i = 0; i < body.length; i++) {
185
201
  buffer = [
186
202
  ...buffer,
187
203
  {
188
204
  type: Object.entries(body[i])[0][1] as string,
189
- color: `<div class='size-6 rounded-full ${logTypeOptions.find((o) => o.value == Object.entries(body[i])[0][1])?.color}'></div>`,
205
+ color: `<div class='size-6 rounded-full ${logTypeOptions.find(o => o.value == Object.entries(body[i])[0][1])?.color}'></div>`,
190
206
  data: Object.entries(body[i])[1][1] as string,
191
207
  },
192
208
  ]
@@ -196,7 +212,7 @@
196
212
  ...buffer,
197
213
  {
198
214
  type: Object.entries(body)[0][1] as string,
199
- color: `<div class='size-6 rounded-full ${logTypeOptions.find((o) => o.value == Object.entries(body)[0][1])?.color}'></div>`,
215
+ color: `<div class='size-6 rounded-full ${logTypeOptions.find(o => o.value == Object.entries(body)[0][1])?.color}'></div>`,
200
216
  data: Object.entries(body)[1][1] as string,
201
217
  },
202
218
  ]
@@ -211,7 +227,7 @@
211
227
  })
212
228
 
213
229
  $effect(() => {
214
- if (body && dataBuffer.stashData && type == 'table') {
230
+ if (body && dataBuffer.stashData && type == "table") {
215
231
  if (Array.isArray(body)) {
216
232
  for (let i = 0; i < body.length; i++) {
217
233
  buffer = [...buffer, body[i]]
@@ -227,28 +243,28 @@
227
243
 
228
244
  onMount(() => {
229
245
  if (autoscroll) {
230
- container?.addEventListener('scroll', handleAutoScroll)
246
+ container?.addEventListener("scroll", handleAutoScroll)
231
247
  scrollToBottom()
232
248
  }
233
249
 
234
- if (type === 'logger') {
250
+ if (type === "logger") {
235
251
  header = [
236
252
  {
237
- key: 'color',
238
- label: { name: 'Type' },
239
- width: '3rem',
253
+ key: "color",
254
+ label: { name: "Type" },
255
+ width: "3rem",
240
256
  } as ITableHeader<any>,
241
257
  {
242
- key: 'data',
243
- label: { name: 'Data' },
244
- width: 'calc(100% - 3rem)',
258
+ key: "data",
259
+ label: { name: "Data" },
260
+ width: "calc(100% - 3rem)",
245
261
  } as ITableHeader<any>,
246
262
  ]
247
263
  }
248
264
 
249
265
  return () => {
250
266
  if (autoscroll) {
251
- container?.removeEventListener('scroll', handleAutoScroll)
267
+ container?.removeEventListener("scroll", handleAutoScroll)
252
268
  }
253
269
  }
254
270
  })
@@ -256,13 +272,12 @@
256
272
 
257
273
  <div
258
274
  id={`${id}-${crypto.randomUUID().slice(0, 6)}`}
259
- class={twMerge(`bg-blue flex h-full w-full items-center ${type == 'logger' ? 'gap-2' : ''} flex-col overflow-hidden`, wrapperClass)}
260
- >
275
+ class={twMerge(`bg-blue flex h-full w-full items-center ${type == "logger" ? "gap-2" : ""} flex-col overflow-hidden`, wrapperClass)}>
261
276
  {#if label.name}
262
277
  <h5 class={twMerge(`w-full px-4 text-center`, label.class)}>{label.name}</h5>
263
278
  {/if}
264
279
 
265
- {#if type == 'logger'}
280
+ {#if type == "logger"}
266
281
  <div id={`${id}-${crypto.randomUUID().slice(0, 6)}`} class="flex w-[50%] justify-center rounded-full">
267
282
  {#each logTypeOptions as option, index}
268
283
  <button
@@ -271,20 +286,17 @@
271
286
  select-none hover:shadow-md
272
287
  ${
273
288
  logType.includes(option.value) && logType !== null
274
- ? 'z-10 py-1 shadow-[0_0_10px_var(--shadow-color)] hover:shadow-[0_0_15px_var(--shadow-color)]'
275
- : ''
289
+ ? "z-10 py-1 shadow-[0_0_10px_var(--shadow-color)] hover:shadow-[0_0_15px_var(--shadow-color)]"
290
+ : ""
276
291
  }
277
- ${logTypeOptions.length > 0 && index === 0 ? 'rounded-l-2xl' : ''} ${
278
- index === logTypeOptions.length - 1 ? 'rounded-r-2xl' : ''
279
- } ${option.color}`)}
292
+ ${logTypeOptions.length > 0 && index === 0 ? "rounded-l-2xl" : ""} ${index === logTypeOptions.length - 1 ? "rounded-r-2xl" : ""} ${option.color}`)}
280
293
  onclick={() => {
281
294
  if (logType.includes(option.value)) {
282
- logType = logType.filter((type) => type !== option.value)
295
+ logType = logType.filter(type => type !== option.value)
283
296
  } else {
284
297
  logType.push(option.value)
285
298
  }
286
- }}
287
- >
299
+ }}>
288
300
  <span class="flex flex-row items-center justify-center gap-4">
289
301
  {#if option}
290
302
  <div class="flex-1">
@@ -300,29 +312,26 @@
300
312
  <div
301
313
  class="relative flex h-full w-full flex-col overflow-hidden rounded-xl border shadow-sm transition duration-200 hover:shadow-md {outline
302
314
  ? ' border-(--border-color)'
303
- : 'border-transparent'} "
304
- >
315
+ : 'border-transparent'} ">
305
316
  <!-- Table Header -->
306
- <div class="grid font-semibold" style={`grid-template-columns: ${header.map((c) => c.width || 'minmax(0, 1fr)').join(' ')};`}>
317
+ <div class="grid font-semibold" style={`grid-template-columns: ${header.map(c => c.width || "minmax(0, 1fr)").join(" ")};`}>
307
318
  {#each header as column, index (column)}
308
319
  <div
309
320
  class={twMerge(
310
- `items-center justify-center border-l ${outline && index !== 0 ? ' border-(--border-color)' : 'border-transparent'} ${
311
- column.align === 'center'
312
- ? 'flex justify-center text-center'
313
- : column.align === 'right'
314
- ? 'flex justify-end text-right'
315
- : 'flex justify-start text-left'
321
+ `items-center justify-center border-l ${outline && index !== 0 ? " border-(--border-color)" : "border-transparent"} ${
322
+ column.align === "center"
323
+ ? "flex justify-center text-center"
324
+ : column.align === "right"
325
+ ? "flex justify-end text-right"
326
+ : "flex justify-start text-left"
316
327
  } gap-1 bg-(--bg-color) p-2 text-left`,
317
328
  column.label?.class,
318
- )}
319
- >
329
+ )}>
320
330
  <span>{column.label?.name}</span>
321
331
  {#if column.sortable}
322
332
  <button
323
333
  class="inline-block cursor-pointer font-bold transition-transform duration-75 hover:scale-110 active:scale-95"
324
- onclick={() => sortRows(column.key as string)}
325
- >
334
+ onclick={() => sortRows(column.key as string)}>
326
335
  ↑↓
327
336
  </button>
328
337
  {/if}
@@ -332,11 +341,10 @@
332
341
  {#if dataBuffer.clearButton}
333
342
  <button
334
343
  class={twMerge(
335
- 'absolute right-2 bg-(--back-color) rounded-full p-1 cursor-pointer [&_svg]:h-full [&_svg]:max-h-full [&_svg]:w-full [&_svg]:max-w-full',
344
+ "absolute right-2 bg-(--back-color) rounded-full p-1 cursor-pointer [&_svg]:h-full [&_svg]:max-h-full [&_svg]:w-full [&_svg]:max-w-full",
336
345
  dataBuffer.clearClass,
337
346
  )}
338
- onclick={clearBuffer}
339
- >
347
+ onclick={clearBuffer}>
340
348
  <ButtonClear />
341
349
  </button>
342
350
  {/if}
@@ -344,14 +352,14 @@
344
352
  {#if body || buffer}
345
353
  {@const isSliced = buffer.length - (dataBuffer.rowsAmmount ?? 10) > 0 ? buffer.length - ((dataBuffer.rowsAmmount ?? 10) % 2) !== 0 : false}
346
354
  {@const rows =
347
- type == 'logger'
348
- ? buffer.filter((str) => logType.includes(str.type)).slice(-(dataBuffer.rowsAmmount ?? 10))
355
+ type == "logger"
356
+ ? buffer.filter(str => logType.includes(str.type)).slice(-(dataBuffer.rowsAmmount ?? 10))
349
357
  : dataBuffer.stashData
350
358
  ? buffer.slice(-(dataBuffer.rowsAmmount ?? 10))
351
359
  : body}
352
360
  <!-- Table Body с прокруткой -->
353
361
  <div class="flex-1 overflow-y-auto bg-(--container-color)/50" bind:this={container} onscroll={handleScroll}>
354
- <div class="grid min-w-0" style={`grid-template-columns: ${header.map((c) => c.width || 'minmax(0, 1fr)').join(' ')};`}>
362
+ <div class="grid min-w-0" style={`grid-template-columns: ${header.map(c => c.width || "minmax(0, 1fr)").join(" ")};`}>
355
363
  {#each rows as row, index (row)}
356
364
  {#each header as column, j (column)}
357
365
  <div
@@ -364,35 +372,70 @@
364
372
  : 'flex justify-start text-left'}
365
373
  border-t
366
374
  {j !== 0 ? ' border-l ' : ''}
367
- {outline ? 'border-(--border-color)' : 'border-transparent'} "
368
- >
369
- {#if column.buttons}
375
+ {outline ? 'border-(--border-color)' : 'border-transparent'} ">
376
+ {#if column.action?.type == "buttons" && column.action?.buttons}
370
377
  <div class="flex w-full flex-col gap-1">
371
- {#each column.buttons as button (button)}
378
+ {#each column.action?.buttons as button (button)}
372
379
  <button
373
380
  class="{twMerge(`cursor-pointer rounded-full
374
381
  px-4 py-1 font-semibold shadow-sm transition-shadow duration-200 outline-none select-none hover:shadow-md
375
382
  ${typeof button.class === 'function' ? button.class(row) : button.class}`)} bg-(--bg-color)"
376
- onclick={() => buttonClick(row, button)}
377
- >
378
- {typeof button.name === 'function' ? button.name(row) : button.name}
383
+ onclick={() => buttonClick(row, button)}>
384
+ {typeof button.name === "function" ? button.name(row) : button.name}
379
385
  </button>
380
386
  {/each}
381
387
  </div>
388
+ {:else if column.action?.type == "select" && column.action?.select}
389
+ {@const currentOptions = changedOptions.find(item => item.index === index)?.options}
390
+ {@const defaultOptions = Array.isArray(row[column.key])
391
+ ? row[column.key].map((option: string | number) => ({
392
+ id: crypto.randomUUID(),
393
+ value: option,
394
+ name: option,
395
+ class: "",
396
+ disabled: false,
397
+ }))
398
+ : []}
399
+ {@const options = currentOptions || defaultOptions}
400
+ <div class="relative w-full">
401
+ <button
402
+ class={`w-full rounded-2xl border border-(--blue-color) bg-(--back-color) p-1 text-center shadow-[0_0_3px_rgb(0_0_0_/0.25)] transition duration-200
403
+ cursor-pointer hover:shadow-[0_0_6px_rgb(0_0_0_/0.25)]`}
404
+ onclick={() => (isDropdownOpen = isDropdownOpen === index ? null : index)}>
405
+ {options[0]?.name || $t("common.select_tag")}
406
+ </button>
407
+
408
+ {#if isDropdownOpen === index}
409
+ <div
410
+ class="absolute top-full left-1/2 z-50 -translate-x-1/2 rounded-b-2xl shadow-[0_0_3px_rgb(0_0_0_/0.25)]"
411
+ style="width: calc(100% - 1.8rem);"
412
+ transition:slide={{ duration: 250 }}>
413
+ {#each options as option, option_index (option.id)}
414
+ <button
415
+ id={option.id}
416
+ value={option?.value ? String(option.value) : ""}
417
+ class={twMerge(
418
+ `flex h-full w-full cursor-pointer items-center justify-center p-1 inset-shadow-[0_10px_10px_-15px_rgb(0_0_0_/0.5)] duration-250 hover:bg-(--field-color)! bg-(--back-color)
419
+ ${option_index === options.length - 1 ? "rounded-b-2xl" : ""} `,
420
+ option.class,
421
+ )}
422
+ onclick={e => selectOption(index, options, option, e)}>
423
+ {option.name}
424
+ </button>
425
+ {/each}
426
+ </div>
427
+ {/if}
428
+ </div>
382
429
  {:else if column.image?.src || column.image?.defaultIcon}
383
- <div
384
- class="flex items-center justify-center"
385
- style={`width: ${column.image.width || '5rem'}; height: ${column.image.height || '5rem'};`}
386
- >
430
+ <div class="flex items-center justify-center" style={`width: ${column.image.width || "5rem"}; height: ${column.image.height || "5rem"};`}>
387
431
  {#if hasImage(column, row)}
388
432
  <img
389
- src={typeof column.image?.src === 'function' ? column.image.src(row) : column.image?.src || ''}
390
- alt={column.image.alt ?? 'Image'}
391
- class={twMerge(`h-full w-full object-cover ${column.image.class || ''}`)}
392
- loading="lazy"
393
- />
433
+ src={typeof column.image?.src === "function" ? column.image.src(row) : column.image?.src || ""}
434
+ alt={column.image.alt ?? "Image"}
435
+ class={twMerge(`h-full w-full object-cover ${column.image.class || ""}`)}
436
+ loading="lazy" />
394
437
  {:else if column.image.defaultIcon}
395
- {#if typeof column.image.defaultIcon === 'string'}
438
+ {#if typeof column.image.defaultIcon === "string"}
396
439
  {@html column.image.defaultIcon}
397
440
  {:else}
398
441
  <column.image.defaultIcon />
@@ -402,25 +445,23 @@
402
445
  {:else}
403
446
  <div
404
447
  class=" w-full max-w-full wrap-break-word {column.overflow?.truncated ? 'truncate' : ' whitespace-normal'}"
405
- onmouseenter={column.overflow?.truncated ? (e) => showTooltip(e, row[column.key], column.overflow?.formatting) : undefined}
448
+ onmouseenter={column.overflow?.truncated ? e => showTooltip(e, row[column.key], column.overflow?.formatting) : undefined}
406
449
  onmouseleave={column.overflow?.truncated ? hideTooltip : undefined}
407
450
  onmousemove={column.overflow?.truncated
408
- ? (e) => {
451
+ ? e => {
409
452
  tooltip.x = e.clientX
410
453
  tooltip.y = e.clientY
411
454
  }
412
455
  : undefined}
413
456
  role="columnheader"
414
- tabindex={null}
415
- >
457
+ tabindex={null}>
416
458
  {#if column.overflow?.modal}
417
459
  <button
418
460
  class="w-full cursor-pointer overflow-hidden text-left text-ellipsis whitespace-nowrap"
419
- onclick={(e) => {
461
+ onclick={e => {
420
462
  e.stopPropagation()
421
463
  showModal(row[column.key], column.overflow?.formatting)
422
- }}
423
- >
464
+ }}>
424
465
  {@html row[column.key]}
425
466
  </button>
426
467
  {:else}
@@ -434,28 +475,25 @@
434
475
  {#if column.overflow?.copy}
435
476
  <button
436
477
  class="mx-2 flex cursor-pointer border-none bg-transparent text-2xl"
437
- onclick={(e) => {
478
+ onclick={e => {
438
479
  e.preventDefault()
439
480
  navigator.clipboard.writeText(row[column.key])
440
481
  copiedCell = { x: column.key as string, y: index }
441
- setTimeout(() => (copiedCell = { x: '', y: -1 }), 1000)
482
+ setTimeout(() => (copiedCell = { x: "", y: -1 }), 1000)
442
483
  }}
443
- aria-label="Копировать текст"
444
- >
484
+ aria-label="Копировать текст">
445
485
  <div class=" size-5 text-sm [&_svg]:h-full [&_svg]:max-h-full [&_svg]:w-full [&_svg]:max-w-full">
446
486
  {#if copiedCell.y === index && copiedCell.x === column.key}
447
487
  <div
448
488
  class="absolute top-1/2 right-3.5 -translate-y-1/2 transform rounded-md bg-(--green-color) px-1.5 py-1 shadow-lg"
449
- transition:fade={{ duration: 200 }}
450
- >
489
+ transition:fade={{ duration: 200 }}>
451
490
 
452
491
  </div>
453
492
  {:else}
454
493
  <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
455
494
  <g fill="none" stroke="currentColor" stroke-width="1.5">
456
495
  <path
457
- d="M6 11c0-2.828 0-4.243.879-5.121C7.757 5 9.172 5 12 5h3c2.828 0 4.243 0 5.121.879C21 6.757 21 8.172 21 11v5c0 2.828 0 4.243-.879 5.121C19.243 22 17.828 22 15 22h-3c-2.828 0-4.243 0-5.121-.879C6 20.243 6 18.828 6 16z"
458
- />
496
+ d="M6 11c0-2.828 0-4.243.879-5.121C7.757 5 9.172 5 12 5h3c2.828 0 4.243 0 5.121.879C21 6.757 21 8.172 21 11v5c0 2.828 0 4.243-.879 5.121C19.243 22 17.828 22 15 22h-3c-2.828 0-4.243 0-5.121-.879C6 20.243 6 18.828 6 16z" />
459
497
  <path d="M6 19a3 3 0 0 1-3-3v-6c0-3.771 0-5.657 1.172-6.828S7.229 2 11 2h4a3 3 0 0 1 3 3" />
460
498
  </g>
461
499
  </svg>
@@ -477,8 +515,7 @@
477
515
  style="background: color-mix(in srgb, var(--yellow-color) 30%, var(--back-color)); transform: translateX(-50%); left: {tooltip.x +
478
516
  10}px; top: {tooltip.y + 10}px;"
479
517
  transition:fly={{ y: 10, duration: 200 }}
480
- role="tooltip"
481
- >
518
+ role="tooltip">
482
519
  {@html tooltip.text}
483
520
  </div>
484
521
  {/if}
@@ -1,4 +1,4 @@
1
- import type { ITableProps } from '../types';
1
+ import type { ITableProps } from "../types";
2
2
  declare const Table: import("svelte").Component<ITableProps<any>, {
3
3
  clearBuffer: () => void;
4
4
  }, "body" | "modalData">;