@johnhalazonetis/data-table 1.23.0

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/README.md ADDED
@@ -0,0 +1,391 @@
1
+ # DataTable
2
+
3
+ A feature-rich Vue 3 data table component built on [TanStack Table v8](https://tanstack.com/table/v8) with Tailwind CSS dark theme styling.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npm install
9
+ npm run dev
10
+ ```
11
+
12
+ ## Installation
13
+
14
+ **Dependencies:**
15
+
16
+ - Vue 3.5+
17
+ - @tanstack/vue-table ^8.21
18
+ - @vueuse/core ^14.2
19
+ - Tailwind CSS v4
20
+
21
+ ## Basic Usage
22
+
23
+ ```vue
24
+ <script setup>
25
+ import { ref } from 'vue'
26
+ import { DataTable } from './components/DataTable'
27
+ import { createColumnHelper } from '@tanstack/vue-table'
28
+
29
+ const col = createColumnHelper()
30
+
31
+ const columns = [
32
+ col.accessor('id', {
33
+ header: 'id',
34
+ meta: { type: 'int8', isPrimaryKey: true, isNullable: false },
35
+ size: 80,
36
+ enableSorting: true,
37
+ enableColumnFilter: true,
38
+ }),
39
+ col.accessor('name', {
40
+ header: 'name',
41
+ meta: { type: 'varchar', isNullable: false },
42
+ size: 200,
43
+ enableSorting: true,
44
+ enableColumnFilter: true,
45
+ }),
46
+ col.accessor('is_active', {
47
+ header: 'is_active',
48
+ meta: { type: 'boolean', isNullable: false },
49
+ size: 110,
50
+ enableSorting: true,
51
+ enableColumnFilter: true,
52
+ }),
53
+ ]
54
+
55
+ const rows = ref([
56
+ { id: 1, name: 'Acme Corp', is_active: true },
57
+ { id: 2, name: 'Globex', is_active: false },
58
+ ])
59
+ </script>
60
+
61
+ <template>
62
+ <DataTable
63
+ :columns="columns"
64
+ :rows="rows"
65
+ table-name="companies"
66
+ @insert-row="handleInsert"
67
+ @update-row="handleUpdate"
68
+ @delete-rows="handleDelete"
69
+ @refresh="handleRefresh"
70
+ />
71
+ </template>
72
+ ```
73
+
74
+ ## Props
75
+
76
+ | Prop | Type | Default | Description |
77
+ |------|------|---------|-------------|
78
+ | `columns` | `Array` | **required** | TanStack column definitions with `meta` for type info |
79
+ | `rows` | `Array` | **required** | Array of row data objects |
80
+ | `tableName` | `String` | `'table'` | Display name shown in the edit panel header |
81
+ | `loading` | `Boolean` | `false` | Spins the refresh button icon and disables it while true |
82
+ | `error` | `String` | `null` | Displays a dismissible error banner above the grid. Clears automatically when the prop value changes |
83
+ | `defaultColumnVisibility` | `Object` | `{}` | Initial column visibility. Keys are column IDs, values are booleans. `{ col_name: false }` hides `col_name` on load |
84
+ | `controlledColumnVisibility` | `Object` | `null` | When set, column visibility is driven from the parent (merged with internal state updates) |
85
+ | `showDataTypes` | `Boolean` | `true` | Show data type labels (e.g. `varchar`, `int8`) in column headers and panels |
86
+ | `editable` | `Boolean \| Object` | `true` | `true`/`false` enables or disables all mutations. Pass `{ insert, update, delete }` booleans to control each operation independently |
87
+ | `selectionActions` | `Array` | `[]` | Custom actions shown in the Actions dropdown when rows are selected. Each item: `{ key: string, label: string }` |
88
+ | `enableSelectAll` | `Boolean` | `true` | When `true`, shows **Select all N …** next to **Clear selection** (selects every filtered row across pages). The header checkbox only toggles the current page |
89
+ | `toolbarActions` | `Array` | `[]` | Custom dropdown next to Sort. Items: `{ key, label, icon? (SVG HTML), disabled?, divider? }`. Emits `toolbar-action` with `key`. Hidden when empty |
90
+ | `toolbarActionsLabel` | `String` | `'Actions'` | Label on the `toolbarActions` trigger |
91
+ | `defaultInsertLabel` | `String` | `null` | When `editable.insert` is true, sets the primary insert button label (e.g. `Import…`). Without `insertActions`, clicking fires `insert-row` only. With `insertActions`, the chevron opens the custom menu |
92
+ | `insertActions` | `Array` | `[]` | Extra insert/import menu entries: `{ key, label, icon? (SVG HTML) }`. Emits `insert-action` with `key`. See **Insert button** under Features |
93
+ | `showRowBorders` | `Boolean` | `true` | Show horizontal borders between rows |
94
+ | `showColumnBorders` | `Boolean` | `true` | Show vertical borders between columns |
95
+ | `cellButtonVisibility` | `String` | `'hover'` | `'hover'` \| `'always'` \| `'select'` — when to show `meta.cellButtons` |
96
+ | `cellOverflow` | `String` | `'truncate'` | Default text overflow for cells: `'truncate'` or `'wrap'`. Per-column `meta.overflow` overrides |
97
+ | `countLabelSingular` | `String` | `'record'` | Singular noun after the total in the footer (and in **Select all N …**): e.g. `ligand` → `1 ligand` |
98
+ | `countLabelPlural` | `String` | `'records'` | Plural form: e.g. `ligands` → `42 ligands` |
99
+ | `theme` | `String` | `'dark'` | `'dark'` or `'light'` |
100
+ | `accentColor` | `String` | `'#3ecf8e'` | Primary accent color (buttons, selections, progress bars) |
101
+ | `fontFamily` | `String` | `null` | Optional CSS `font-family` value; cascades into nested sub-tables |
102
+ | `showToolbar` | `Boolean` | `true` | Show filter/sort/columns/insert toolbar (and selection toolbar when rows are selected) |
103
+ | `showPagination` | `Boolean` | `true` | Show footer pagination bar |
104
+ | `emptyTitle` | `String` | `'No rows found'` | Empty-state heading |
105
+ | `emptyMessage` | `String` | `'Get started by inserting a new row.'` | Empty-state body |
106
+ | `totalCount` | `Number` | `null` | Total row count for server-side pagination. When set, switches to manual pagination and emits `page-change` |
107
+ | `hasRandomAccess` | `Boolean` | `true` | When `false`, hides the page number input in the footer (prev/next only) |
108
+ | `columnFilters` | `Array` | `null` | Optional `v-model:column-filters` — observe/sync filter state from the parent |
109
+ | `controlledSorting` | `Array` | `null` | External sort state for nested/controlled tables |
110
+ | `controlledColumnFilters` | `Array` | `null` | External filter state for nested tables |
111
+ | `getSubTable` | `Function` | `null` | `(row) => ({ columns, rows, ... }) \| null` — expandable rows with nested `DataTable` |
112
+ | `subTableColumns` | `Array` | `null` | Shared column defs for sub-tables when using expansion |
113
+ | `expandedRows` | `Object` | `null` | `v-model:expanded-rows` — controlled expanded row IDs |
114
+ | `stagedEdits` | `Boolean` | `false` | Queue mutations locally; footer shows **Commit** / **Clear edits**; emit `commit-edits` instead of immediate `insert-row` / `update-row` / `delete-rows` |
115
+
116
+ ## Events
117
+
118
+ | Event | Payload | Description |
119
+ |-------|---------|-------------|
120
+ | `insert-row` | `Object` (row data) | User submitted the insert form, or primary insert action when `defaultInsertLabel` is set without custom `insertActions` |
121
+ | `insert-action` | `actionKey: string` | User chose an item from `insertActions` (chevron menu or **Insert ▼** when no default label) |
122
+ | `update-row` | `{ id, changes }` | User edited a cell or saved the edit panel |
123
+ | `delete-rows` | `Array<string>` (row IDs) | User confirmed deletion of selected rows |
124
+ | `refresh` | — | User clicked the refresh button |
125
+ | `selection-action` | `(actionKey: string, rows: Object[])` | User triggered a custom selection action |
126
+ | `toolbar-action` | `actionKey: string` | User picked an item from `toolbarActions` |
127
+ | `page-change` | `{ pageIndex: number, pageSize: number }` | Page navigation while `totalCount` is set (server-side pagination) |
128
+ | `column-resize` | `Object<colId, number>` | User finished resizing a column; payload is the full column sizing map |
129
+ | `commit-edits` | `({ inserts, updates, deletes }, done)` | Staged-edits mode: parent must call `done(true)` or `done(false)` |
130
+ | `discard-edits` | — | User cleared staged edits after confirmation |
131
+ | `update:column-filters` | `Array` | Column filter state changed (when `columnFilters` is bound) |
132
+ | `update:expanded-rows` | `Object` | Expanded row map changed (when controlled) |
133
+
134
+ ## Column Definition
135
+
136
+ Columns use TanStack's `createColumnHelper()`. The `meta` object controls component behavior:
137
+
138
+ ```js
139
+ col.accessor('field_name', {
140
+ header: 'Display Name',
141
+ meta: {
142
+ type: 'varchar', // Data type: 'int8', 'int4', 'float8', 'varchar', 'text', 'boolean'
143
+ isPrimaryKey: false, // Disables editing in update mode
144
+ isNullable: true, // Separates required vs. optional in the edit panel
145
+ },
146
+ size: 180, // Column width in pixels
147
+ enableSorting: true,
148
+ enableColumnFilter: true,
149
+ })
150
+ ```
151
+
152
+ ### Supported `meta.type` Values
153
+
154
+ | Type | Behavior |
155
+ |------|----------|
156
+ | `int8`, `int4`, `float8` | Values converted to `Number` on save |
157
+ | `varchar`, `text` | Standard text input |
158
+ | `boolean` | Renders as a toggle switch |
159
+ | Any other string | Treated as text |
160
+
161
+ ### Additional column `meta` (presentation & cells)
162
+
163
+ | Property | Type | Description |
164
+ |----------|------|-------------|
165
+ | `overflow` | `'truncate' \| 'wrap'` | Text overflow for this column. Overrides the table-level `cellOverflow` prop. |
166
+ | `multiline` | `Boolean` | **Legacy:** `true` is equivalent to `overflow: 'wrap'`. |
167
+ | `progressBar` | `Boolean \| { min, max } \| (value, row) => number` | Renders a bar; value or mapped 0–100. Double-click edit disabled. |
168
+ | `cellButtons` | `Array` | Trailing buttons: `{ label, icon? (SVG HTML), onClick(row) }`. |
169
+ | `badge` | `Boolean \| { color? } \| (value, row) => { color? } \| null` | Renders the **cell value as a pill** for **any** column type (`varchar`, `text`, numbers, etc.). On **boolean** columns, `meta.badge` replaces the default toggle with a pill (double‑click to edit still works when `editable.update` is true). Set **`color`** to any CSS color (`#hex`, `rgb()`, `hsl()`, named colors, `var(--token)`). Omit `color` or use `badge: true` for neutral styling. |
170
+ | `suffixIcon` | `{ svg, color? } \| (value, row) => { svg, color? } \| null` | Small inline SVG **after** the cell text. `svg` is raw markup; `color` is an optional CSS color. |
171
+
172
+ ## Features
173
+
174
+ ### Toolbar
175
+ - **Filter bar** — Click to add column filters with operator support (equals, like, greater than, etc.)
176
+ - **Sort** — Multi-column sort with drag-and-drop reordering, ASC/DESC toggle
177
+ - **Columns** — Toggle column visibility with Show All / Default reset
178
+ - **Insert** — When `editable.insert` is true: if `defaultInsertLabel` is set, primary click emits `insert-row`; pairing with `insertActions` adds a chevron menu that emits `insert-action` per item. With no default label, an **Insert** dropdown lists `insertActions` or built-in items (insert row / column / CSV placeholder). Optional `toolbarActions` adds a separate **Actions** menu next to Sort.
179
+ - **Refresh** — Emits `refresh` event for parent to reload data
180
+
181
+ ### Grid
182
+ - **Sticky columns** — Row numbers and checkboxes stay pinned on horizontal scroll
183
+ - **Column resizing** — Drag column borders to resize
184
+ - **Inline editing** — Double-click a cell to edit (when `editable: true`)
185
+ - **Boolean toggles** — Click to flip boolean values
186
+ - **Row selection** — Click checkboxes, Shift+click for range selection
187
+ - **Context menu** — Right-click for copy, filter, edit, delete actions
188
+
189
+ ### Selection Toolbar
190
+ Appears when rows are selected:
191
+ - **Delete...** — Opens confirmation dialog before emitting `delete-rows`
192
+ - **Actions** — Dropdown with Copy as CSV/SQL/JSON plus any custom `selectionActions`
193
+ - **Clear selection** / **Select all N** — Uses `countLabelSingular` / `countLabelPlural` (e.g. *Select all 50 ligands*)
194
+
195
+ ### Row Edit Panel
196
+ Slide-in panel from the right for inserting or updating rows:
197
+ - Required and optional field sections based on `isNullable`
198
+ - Primary key fields are read-only in update mode
199
+ - Save with `Cmd+Enter`, close with `Escape`
200
+
201
+ ### Pagination
202
+ - Page navigation with direct page number input (unless `hasRandomAccess` is `false`)
203
+ - Configurable rows per page (100, 500, 1000)
204
+ - Total count line: `{{ n }} {{ countLabelSingular }}` or `{{ countLabelPlural }}` (defaults *record* / *records*)
205
+
206
+ ## Examples
207
+
208
+ ### Read-Only Table
209
+
210
+ ```vue
211
+ <DataTable
212
+ :columns="columns"
213
+ :rows="rows"
214
+ :editable="false"
215
+ />
216
+ ```
217
+
218
+ ### Minimal Chrome
219
+
220
+ ```vue
221
+ <DataTable
222
+ :columns="columns"
223
+ :rows="rows"
224
+ :show-data-types="false"
225
+ :show-row-borders="false"
226
+ :show-column-borders="false"
227
+ />
228
+ ```
229
+
230
+ ### Custom Selection Actions
231
+
232
+ ```vue
233
+ <script setup>
234
+ const actions = [
235
+ { key: 'export-pdf', label: 'Export to PDF' },
236
+ { key: 'send-email', label: 'Send via email' },
237
+ ]
238
+
239
+ function onAction(actionKey, selectedRows) {
240
+ if (actionKey === 'export-pdf') {
241
+ generatePdf(selectedRows)
242
+ }
243
+ }
244
+ </script>
245
+
246
+ <template>
247
+ <DataTable
248
+ :columns="columns"
249
+ :rows="rows"
250
+ :selection-actions="actions"
251
+ @selection-action="onAction"
252
+ />
253
+ </template>
254
+ ```
255
+
256
+ ### Default Hidden Columns
257
+
258
+ ```vue
259
+ <DataTable
260
+ :columns="columns"
261
+ :rows="rows"
262
+ :default-column-visibility="{ internal_id: false, metadata: false }"
263
+ />
264
+ ```
265
+
266
+ ### Granular Permissions
267
+
268
+ ```vue
269
+ <!-- Insert-only: allow inserts but block edits and deletes -->
270
+ <DataTable
271
+ :columns="columns"
272
+ :rows="rows"
273
+ :editable="{ insert: true, update: false, delete: false }"
274
+ @insert-row="handleInsert"
275
+ />
276
+ ```
277
+
278
+ ### Error Banner
279
+
280
+ ```vue
281
+ <script setup>
282
+ const error = ref(null)
283
+
284
+ async function handleRefresh() {
285
+ try {
286
+ rows.value = await fetchRows()
287
+ error.value = null
288
+ } catch (e) {
289
+ error.value = e.message
290
+ }
291
+ }
292
+ </script>
293
+
294
+ <template>
295
+ <DataTable
296
+ :columns="columns"
297
+ :rows="rows"
298
+ :loading="isLoading"
299
+ :error="error"
300
+ @refresh="handleRefresh"
301
+ />
302
+ </template>
303
+ ```
304
+
305
+ ### Custom footer count labels
306
+
307
+ Use domain nouns so the footer and **Select all** match your entity (e.g. stores, ligands).
308
+
309
+ ```vue
310
+ <DataTable
311
+ :columns="columns"
312
+ :rows="rows"
313
+ count-label-singular="store"
314
+ count-label-plural="stores"
315
+ />
316
+ ```
317
+
318
+ ### Custom insert / import menu
319
+
320
+ ```vue
321
+ <script setup>
322
+ const insertActions = [
323
+ { key: 'csv', label: 'Import CSV', icon: '<svg ...></svg>' },
324
+ { key: 'api', label: 'Sync from API' },
325
+ ]
326
+
327
+ function onInsertAction(key) {
328
+ if (key === 'csv') openCsvDialog()
329
+ }
330
+ </script>
331
+
332
+ <template>
333
+ <DataTable
334
+ :columns="columns"
335
+ :rows="rows"
336
+ default-insert-label="Import…"
337
+ :insert-actions="insertActions"
338
+ @insert-row="openDefaultImport"
339
+ @insert-action="onInsertAction"
340
+ />
341
+ </template>
342
+ ```
343
+
344
+ ### Server-Side Pagination
345
+
346
+ ```vue
347
+ <script setup>
348
+ const rows = ref([])
349
+ const totalCount = ref(0)
350
+ const isLoading = ref(false)
351
+
352
+ async function loadPage({ pageIndex, pageSize }) {
353
+ isLoading.value = true
354
+ const result = await api.getRows({ page: pageIndex, limit: pageSize })
355
+ rows.value = result.data
356
+ totalCount.value = result.total
357
+ isLoading.value = false
358
+ }
359
+
360
+ onMounted(() => loadPage({ pageIndex: 0, pageSize: 100 }))
361
+ </script>
362
+
363
+ <template>
364
+ <DataTable
365
+ :columns="columns"
366
+ :rows="rows"
367
+ :total-count="totalCount"
368
+ :loading="isLoading"
369
+ @page-change="loadPage"
370
+ @refresh="() => loadPage({ pageIndex: 0, pageSize: 100 })"
371
+ />
372
+ </template>
373
+ ```
374
+
375
+ ### Persisting Column Widths
376
+
377
+ ```vue
378
+ <DataTable
379
+ :columns="columns"
380
+ :rows="rows"
381
+ @column-resize="widths => localStorage.setItem('col-widths', JSON.stringify(widths))"
382
+ />
383
+ ```
384
+
385
+ ## Tech Stack
386
+
387
+ - **Vue 3** — Composition API with `<script setup>`
388
+ - **TanStack Table v8** — Headless table engine (sorting, filtering, pagination, column visibility, row selection, column resizing)
389
+ - **Tailwind CSS v4** — Dark theme styling
390
+ - **VueUse** — `onClickOutside` for dropdown/menu dismissal
391
+ - **Vite** — Build tooling
@@ -0,0 +1,3 @@
1
+ /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-blue-500:oklch(62.3% .214 259.815);--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--tracking-wider:.05em;--leading-tight:1.25;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-lg:.5rem;--radius-2xl:1rem;--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.top-0{top:calc(var(--spacing) * 0)}.top-0\.5{top:calc(var(--spacing) * .5)}.top-\[2px\]{top:2px}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.-bottom-7{bottom:calc(var(--spacing) * -7)}.left-0{left:calc(var(--spacing) * 0)}.left-0\.5{left:calc(var(--spacing) * .5)}.left-1\/2{left:50%}.left-3\.5{left:calc(var(--spacing) * 3.5)}.left-\[2px\]{left:2px}.left-\[17px\]{left:17px}.isolate{isolation:isolate}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.z-\[21\]{z-index:21}.z-\[26\]{z-index:26}.z-\[39\]{z-index:39}.z-\[40\]{z-index:40}.z-\[100\]{z-index:100}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-1{margin-inline:calc(var(--spacing) * 1)}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing) * 1)}.my-3{margin-block:calc(var(--spacing) * 3)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-14{height:calc(var(--spacing) * 14)}.h-\[14px\]{height:14px}.h-\[18px\]{height:18px}.h-full{height:100%}.h-screen{height:100vh}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-72{max-height:calc(var(--spacing) * 72)}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-\[36px\]{min-height:36px}.w-1{width:calc(var(--spacing) * 1)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-40{width:calc(var(--spacing) * 40)}.w-48{width:calc(var(--spacing) * 48)}.w-52{width:calc(var(--spacing) * 52)}.w-60{width:calc(var(--spacing) * 60)}.w-64{width:calc(var(--spacing) * 64)}.w-80{width:calc(var(--spacing) * 80)}.w-96{width:calc(var(--spacing) * 96)}.w-\[14px\]{width:14px}.w-\[68px\]{width:68px}.w-\[420px\]{width:420px}.w-full{width:100%}.w-max{width:max-content}.w-px{width:1px}.max-w-full{max-width:100%}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[11rem\]{min-width:11rem}.min-w-\[12rem\]{min-width:12rem}.min-w-\[200px\]{min-width:200px}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.border-separate{border-collapse:separate}.border-spacing-0{--tw-border-spacing-x:calc(var(--spacing) * 0);--tw-border-spacing-y:calc(var(--spacing) * 0);border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y)}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.resize-none{resize:none}.resize-y{resize:vertical}.\[appearance\:textfield\]{appearance:textfield}.flex-col{flex-direction:column}.flex-nowrap{flex-wrap:nowrap}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.self-start{align-self:flex-start}.self-stretch{align-self:stretch}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-l{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.bg-blue-500{background-color:var(--color-blue-500)}.bg-red-600{background-color:var(--color-red-600)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-3{padding:calc(var(--spacing) * 3)}.p-5{padding:calc(var(--spacing) * 5)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pr-1\.5{padding-right:calc(var(--spacing) * 1.5)}.pb-2\.5{padding-bottom:calc(var(--spacing) * 2.5)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-0\.5{padding-left:calc(var(--spacing) * .5)}.pl-1{padding-left:calc(var(--spacing) * 1)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.\!opacity-100{opacity:1!important}.opacity-0{opacity:0}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\/header\:opacity-100:is(:where(.group\/header):hover *){opacity:1}.group-hover\/row\:visible:is(:where(.group\/row):hover *){visibility:visible}.group-hover\/row\:opacity-100:is(:where(.group\/row):hover *){opacity:1}.hover\:bg-blue-500\/50:hover{background-color:#3080ff80}@supports (color:color-mix(in lab, red, red)){.hover\:bg-blue-500\/50:hover{background-color:color-mix(in oklab, var(--color-blue-500) 50%, transparent)}}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:opacity-100:hover{opacity:1}}.active\:cursor-grabbing:active{cursor:grabbing}.active\:bg-blue-500:active{background-color:var(--color-blue-500)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-60:disabled{opacity:.6}.\[\&_svg\]\:max-h-full svg{max-height:100%}.\[\&_svg\]\:max-w-full svg{max-width:100%}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{appearance:none}.\[\&\:\:-webkit-outer-spin-button\]\:appearance-none::-webkit-outer-spin-button{appearance:none}}.data-table-root{isolation:isolate;font-family:var(--dt-font-family);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;scrollbar-width:thin}.data-table-root *{scrollbar-width:inherit}.data-table-root[data-st-theme=dark],.data-table-root[data-st-theme=dark] *{scrollbar-color:#444 transparent}.data-table-root[data-st-theme=light],.data-table-root[data-st-theme=light] *{scrollbar-color:#a8a29e transparent}@property --tw-border-spacing-x{syntax:"<length>";inherits:false;initial-value:0}@property --tw-border-spacing-y{syntax:"<length>";inherits:false;initial-value:0}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}.sort-select[data-v-f1143526]{appearance:none;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23a1a1aa'><path fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/></svg>");background-position:right .5rem center;background-repeat:no-repeat;background-size:12px 12px;padding-left:.5rem;padding-right:1.75rem}.sort-select[data-v-f1143526]::-ms-expand{display:none}.filter-chip-close[data-v-d6671bc9]:hover{color:var(--st-text);background-color:var(--st-bg-menu-hover)}.hover-menu-item[data-v-c662bbfe]:hover,.hover-menu-item[data-v-7857cf96]:hover,.hover-menu-item[data-v-10f6e0bb]:hover,.hover-menu-item[data-v-d19d2667]:hover{background-color:var(--st-bg-menu-hover)}.st-row[data-v-1d48216e]{background-color:#0000}.st-row[data-v-1d48216e]:hover{background-color:var(--st-bg-row-hover)}.st-row--selected[data-v-1d48216e],.st-row--selected[data-v-1d48216e]:hover{background-color:var(--st-bg-selected)}.st-sticky-cell[data-v-1d48216e]{background-color:var(--st-bg)}.st-row--selected .st-sticky-cell[data-v-1d48216e]{background-color:var(--st-bg-selected-cell)}.st-row--active[data-v-1d48216e],.st-row--active[data-v-1d48216e]:hover{background-color:var(--st-bg-selected)}.st-row--active .st-sticky-cell[data-v-1d48216e]{background-color:var(--st-bg-selected-cell)}.st-row--pending-insert[data-v-1d48216e],.st-row--pending-insert[data-v-1d48216e]:hover,.st-row--pending-insert .st-sticky-cell[data-v-1d48216e]{background-color:var(--st-accent-bg)}.st-row--pending-delete[data-v-1d48216e]{background-color:#ef444414}.st-row--pending-delete[data-v-1d48216e]:hover{background-color:#ef44441f}.st-row--pending-delete .st-sticky-cell[data-v-1d48216e]{background-color:#ef444414}.hover-menu-item[data-v-c262480e]:hover,.hover-menu-item[data-v-3f2648fa]:hover{background-color:var(--st-bg-menu-hover)}.slide-panel-enter-active[data-v-3ec50e77],.slide-panel-leave-active[data-v-3ec50e77]{transition:width .25s,opacity .25s}.slide-panel-enter-from[data-v-3ec50e77],.slide-panel-leave-to[data-v-3ec50e77]{opacity:0;width:0!important}.slide-panel-enter-to[data-v-3ec50e77],.slide-panel-leave-from[data-v-3ec50e77]{opacity:1;width:420px}
3
+ /*$vite$:1*/