@aiquants/directory-tree 3.0.4 → 3.1.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 +25 -8
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/styles/directory-tree.css +1 -1
- package/dist/styles/directory-tree.standalone.css +3 -0
- package/package.json +10 -8
- package/src/DirectoryTree.spec.md +473 -0
- package/src/DirectoryTree.tsx +978 -0
- package/src/DirectoryTreeGrid.tsx +261 -0
- package/src/TreeLine.tsx +300 -0
- package/src/cli.server.ts +38 -0
- package/src/entryRendering.tsx +131 -0
- package/src/gridUtils.ts +88 -0
- package/src/index.ts +31 -0
- package/src/logger.ts +162 -0
- package/src/styles/components.entry.css +8 -0
- package/src/styles/directory-tree.css +89 -0
- package/src/styles/standalone.entry.css +12 -0
- package/src/types.ts +619 -0
- package/src/useDirectoryTreeState.ts +133 -0
- package/src/useEntryInteraction.ts +74 -0
- package/dist/directory-tree.css +0 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState, useTransition } from "react"
|
|
2
|
+
import type { DirectoryTreeState, UseDirectoryTreeStateProps } from "./types"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A React hook for managing the state of a directory tree.
|
|
6
|
+
* ディレクトリツリーの状態を管理するための React フック。
|
|
7
|
+
*
|
|
8
|
+
* This hook is designed to work with Server-Side Rendering (SSR) by allowing
|
|
9
|
+
* the initial expansion state to be passed in as a prop.
|
|
10
|
+
* このフックは、初期の展開状態をプロパティとして渡すことで、
|
|
11
|
+
* サーバーサイドレンダリング (SSR) と連携するように設計されています。
|
|
12
|
+
*
|
|
13
|
+
* @param props - The properties for the hook.
|
|
14
|
+
* @returns The state and actions for the directory tree.
|
|
15
|
+
*/
|
|
16
|
+
export const useDirectoryTreeState = ({ initialExpanded = new Set<string>(), storageKey }: UseDirectoryTreeStateProps = {}): DirectoryTreeState => {
|
|
17
|
+
const [isPending, startTransition] = useTransition()
|
|
18
|
+
const [expanded, setExpanded] = useState(() => {
|
|
19
|
+
if (typeof window !== "undefined" && storageKey) {
|
|
20
|
+
try {
|
|
21
|
+
const item = window.localStorage.getItem(storageKey)
|
|
22
|
+
if (item) {
|
|
23
|
+
const parsedItem = JSON.parse(item)
|
|
24
|
+
return new Set<string>(parsedItem)
|
|
25
|
+
}
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.error("[useDirectoryTreeState] Error reading from localStorage", error)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return initialExpanded
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
const runTransition = useCallback((update: (next: Set<string>) => void) => {
|
|
34
|
+
startTransition(() => {
|
|
35
|
+
setExpanded((prev) => {
|
|
36
|
+
const next = new Set(prev)
|
|
37
|
+
update(next)
|
|
38
|
+
return next
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
}, [])
|
|
42
|
+
|
|
43
|
+
const mutatePaths = useCallback(
|
|
44
|
+
(paths: Iterable<string>, modifier: (next: Set<string>, path: string) => void) => {
|
|
45
|
+
runTransition((next) => {
|
|
46
|
+
for (const path of paths) {
|
|
47
|
+
modifier(next, path)
|
|
48
|
+
}
|
|
49
|
+
})
|
|
50
|
+
},
|
|
51
|
+
[runTransition],
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
// 展開状態を localStorage に同期する副作用。expanded と storageKey の変化時に発火。
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (storageKey && typeof window !== "undefined") {
|
|
57
|
+
try {
|
|
58
|
+
window.localStorage.setItem(storageKey, JSON.stringify(Array.from(expanded)))
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.warn(`Error setting localStorage key "${storageKey}":`, error)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}, [expanded, storageKey])
|
|
64
|
+
|
|
65
|
+
const toggle = useCallback(
|
|
66
|
+
(path: string) => {
|
|
67
|
+
mutatePaths([path], (next, current) => {
|
|
68
|
+
if (next.has(current)) {
|
|
69
|
+
next.delete(current)
|
|
70
|
+
} else {
|
|
71
|
+
next.add(current)
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
},
|
|
75
|
+
[mutatePaths],
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
const expand = useCallback(
|
|
79
|
+
(path: string) => {
|
|
80
|
+
mutatePaths([path], (next, current) => {
|
|
81
|
+
next.add(current)
|
|
82
|
+
})
|
|
83
|
+
},
|
|
84
|
+
[mutatePaths],
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
const collapse = useCallback(
|
|
88
|
+
(path: string) => {
|
|
89
|
+
mutatePaths([path], (next, current) => {
|
|
90
|
+
next.delete(current)
|
|
91
|
+
})
|
|
92
|
+
},
|
|
93
|
+
[mutatePaths],
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
const collapseMultiple = useCallback(
|
|
97
|
+
(paths: string[]) => {
|
|
98
|
+
mutatePaths(paths, (next, current) => {
|
|
99
|
+
next.delete(current)
|
|
100
|
+
})
|
|
101
|
+
},
|
|
102
|
+
[mutatePaths],
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
const expandMultiple = useCallback(
|
|
106
|
+
(paths: string[]) => {
|
|
107
|
+
mutatePaths(paths, (next, current) => {
|
|
108
|
+
next.add(current)
|
|
109
|
+
})
|
|
110
|
+
},
|
|
111
|
+
[mutatePaths],
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
const collapseAll = useCallback(() => {
|
|
115
|
+
runTransition((next) => {
|
|
116
|
+
next.clear()
|
|
117
|
+
})
|
|
118
|
+
}, [runTransition])
|
|
119
|
+
|
|
120
|
+
const isExpanded = useCallback((path: string) => expanded.has(path), [expanded])
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
expanded,
|
|
124
|
+
toggle,
|
|
125
|
+
expand,
|
|
126
|
+
collapse,
|
|
127
|
+
collapseMultiple,
|
|
128
|
+
expandMultiple,
|
|
129
|
+
collapseAll,
|
|
130
|
+
isExpanded,
|
|
131
|
+
isPending,
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module useEntryInteraction
|
|
3
|
+
* @description Shared click / double-click / selection handling for a directory entry row.
|
|
4
|
+
* Used by both the classic label row (DirectoryEntryItem) and the TreeGrid row
|
|
5
|
+
* (DirectoryTreeGridRow) so the interaction semantics stay identical.
|
|
6
|
+
* 単一クリック/ダブルクリック/選択の共通ハンドラ。従来行と TreeGrid 行で共有する。
|
|
7
|
+
*/
|
|
8
|
+
import type { MouseEvent } from "react"
|
|
9
|
+
import { useCallback, useEffect, useRef } from "react"
|
|
10
|
+
import type { DirectoryEntry, DirectoryTreeClickEvent } from "./types.ts"
|
|
11
|
+
|
|
12
|
+
/** Delay (ms) distinguishing a single click (toggle) from a double click (recursive). / 単/ダブルクリック判定の遅延。 */
|
|
13
|
+
const DOUBLE_CLICK_DELAY_MS = 500
|
|
14
|
+
|
|
15
|
+
export type UseEntryInteractionArgs = {
|
|
16
|
+
entry: DirectoryEntry
|
|
17
|
+
isDirectory: boolean
|
|
18
|
+
isExpanded: boolean
|
|
19
|
+
isItemSelected: boolean
|
|
20
|
+
selectionMode: "none" | "single" | "multiple"
|
|
21
|
+
onSelectionChange?: (entry: DirectoryEntry, isSelected: boolean) => void
|
|
22
|
+
onEntryClick: (event: DirectoryTreeClickEvent) => void
|
|
23
|
+
toggleDirectory: (path: string) => void
|
|
24
|
+
onToggleDirectoryRecursive: (entry: DirectoryEntry) => void
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Returns a click handler implementing: fire onEntryClick immediately; for files toggle
|
|
29
|
+
* selection; for directories, single click toggles (after a delay) and double click expands
|
|
30
|
+
* recursively — unless the consumer calls preventDefault() on the click event.
|
|
31
|
+
*/
|
|
32
|
+
export const useEntryInteraction = ({ entry, isDirectory, isExpanded, isItemSelected, selectionMode, onSelectionChange, onEntryClick, toggleDirectory, onToggleDirectoryRecursive }: UseEntryInteractionArgs) => {
|
|
33
|
+
const clickTimer = useRef<number | null>(null)
|
|
34
|
+
|
|
35
|
+
useEffect(
|
|
36
|
+
() => () => {
|
|
37
|
+
if (clickTimer.current) window.clearTimeout(clickTimer.current)
|
|
38
|
+
},
|
|
39
|
+
[],
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
return useCallback(
|
|
43
|
+
(e: MouseEvent<HTMLDivElement>) => {
|
|
44
|
+
e.stopPropagation()
|
|
45
|
+
if (selectionMode !== "none" && !isDirectory && onSelectionChange) {
|
|
46
|
+
onSelectionChange(entry, !isItemSelected)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let defaultPrevented = false
|
|
50
|
+
onEntryClick({
|
|
51
|
+
entry,
|
|
52
|
+
isDirectory,
|
|
53
|
+
isExpanded,
|
|
54
|
+
preventDefault: () => {
|
|
55
|
+
defaultPrevented = true
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
if (!isDirectory || defaultPrevented) return
|
|
60
|
+
|
|
61
|
+
if (clickTimer.current) {
|
|
62
|
+
window.clearTimeout(clickTimer.current)
|
|
63
|
+
clickTimer.current = null
|
|
64
|
+
onToggleDirectoryRecursive(entry)
|
|
65
|
+
} else {
|
|
66
|
+
clickTimer.current = window.setTimeout(() => {
|
|
67
|
+
toggleDirectory(entry.absolutePath)
|
|
68
|
+
clickTimer.current = null
|
|
69
|
+
}, DOUBLE_CLICK_DELAY_MS)
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
[isDirectory, entry, isExpanded, onToggleDirectoryRecursive, toggleDirectory, onEntryClick, selectionMode, onSelectionChange, isItemSelected],
|
|
73
|
+
)
|
|
74
|
+
}
|
package/dist/directory-tree.css
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@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-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight: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-duration:initial}}}@layer theme{:root,:host{--color-amber-100:oklch(96.2% .059 95.617);--color-amber-900:oklch(41.4% .112 45.904);--color-yellow-50:oklch(98.7% .026 102.212);--color-yellow-400:oklch(85.2% .199 91.936);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-600:oklch(68.1% .162 75.834);--color-yellow-900:oklch(42.1% .095 57.708);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-900:oklch(37.8% .077 168.94);--color-cyan-400:oklch(78.9% .154 211.53);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-800:oklch(39.8% .195 277.366);--color-indigo-900:oklch(35.9% .144 278.697);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-800:oklch(27.9% .041 260.031);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-900:oklch(21% .034 264.665);--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-medium:500;--font-weight-bold:700;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer base;@layer components{@layer theme,base;@layer components.utilities{.aqvs-scroll-pane{display:flex;position:relative}.aqvs-scroll-pane-content{flex:1;height:100%;position:relative;overflow:hidden}.aqvs-tap-scroll-circle{touch-action:none;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;transition-property:transform;transition-duration:.1s;transition-timing-function:cubic-bezier(0,0,.2,1);display:flex;position:relative}.aqvs-tap-scroll-circle-visual-outer{border-radius:9999px;position:absolute;inset:0}.aqvs-tap-scroll-circle-gradient{background:linear-gradient(to bottom right,#1d4ed899,#60a5fa8c,#bfdbfe66);border-width:1px;border-color:#fff6;border-radius:9999px;position:absolute;inset:0;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}.aqvs-tap-scroll-circle-inner{border-radius:9999px;position:absolute;inset:18%}.aqvs-sample-visual-rod{background-color:#ffffffd9;border-width:1px;border-color:#ffffff80;border-radius:9999px;position:absolute;top:50%;left:50%}.aqvs-sample-visual-pupil{background-color:#fffc;border-radius:9999px;position:absolute;top:50%;left:50%}.aqvs-sample-visual-highlight{background-color:#ffffff80;border-radius:9999px;position:absolute;top:50%;left:50%}.aqvs-scrollbar{z-index:50;cursor:default;-webkit-user-select:none;user-select:none;touch-action:none;background-color:#fff;position:relative}.aqvs-scrollbar-horizontal{flex-direction:row;align-items:stretch;display:flex}.aqvs-scrollbar-vertical{flex-direction:column;align-items:stretch;display:flex}.aqvs-scrollbar-tap-circle-wrapper{pointer-events:auto;transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1);position:absolute}.aqvs-scrollbar-arrow-button{color:#313131;background-color:#e0e0e0;justify-content:center;align-items:center;font-size:.75rem;line-height:1rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1);display:flex}.aqvs-scrollbar-arrow-button:focus{outline-offset:2px;outline:2px solid #0000}.aqvs-scrollbar-arrow-button:focus-visible{outline-offset:1px;outline:2px solid #60a5fa}.aqvs-scrollbar-arrow-button:disabled{cursor:not-allowed;opacity:.5}.aqvs-scrollbar-arrow-button:enabled:hover{background-color:#d4d4d4}.aqvs-scrollbar-track{background-color:#f5f5f5;flex:1;position:relative}.aqvs-scrollbar-overlay{pointer-events:none;position:absolute;inset:0}.aqvs-scrollbar-thumb-wrapper{touch-action:none;position:absolute}.aqvs-scrollbar-thumb{transform-origin:50%;background-color:#7f7f7f;transition:transform 80ms ease-out;position:absolute}.aqvs-scrollbar-thumb[data-thumb-state=disabled]{transition:none;transform:none}.aqvs-scrollbar-thumb[data-thumb-state=hover]{background-color:#5f5f5f}.aqvs-scrollbar-thumb[data-thumb-state=dragging]{background-color:#4f4f4f;transition:transform 60ms ease-out}.aqvs-scrollbar-thumb-horizontal{inset:1.5px 0}.aqvs-scrollbar-thumb-horizontal[data-thumb-state=hover]{top:-.5px;bottom:-.5px;transform:scaleY(1.06)}.aqvs-scrollbar-thumb-horizontal[data-thumb-state=dragging]{top:-.5px;bottom:-.5px;transform:scaleY(1.12)}.aqvs-scrollbar-thumb-vertical{inset:0 1.5px}.aqvs-scrollbar-thumb-vertical[data-thumb-state=hover]{left:-.5px;right:-.5px;transform:scaleX(1.06)}.aqvs-scrollbar-thumb-vertical[data-thumb-state=dragging]{left:-.5px;right:-.5px;transform:scaleX(1.12)}.aqvs-scroll-to-edge-button{pointer-events:auto;color:#fff;text-transform:uppercase;letter-spacing:.05em;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background-color:#1f2937cc;border-radius:9999px;padding:.25rem 3rem;font-size:10px;font-weight:500;transition-property:transform,background-color;transition-duration:.15s;transform:none;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -1px #0000000f}.aqvs-scroll-to-edge-button:hover{background-color:#374151}.aqvs-scroll-to-edge-button:active{transform:scale(.95)}.aqvs-scroll-to-edge-overlay{pointer-events:none;z-index:10;transition-property:opacity;transition-duration:.5s;position:absolute;inset:0}.aqvs-scroll-to-edge-overlay[data-visible=true]{opacity:1}.aqvs-scroll-to-edge-overlay[data-visible=false]{opacity:0}.aqvs-scroll-to-edge-button-container{justify-content:center;display:flex;position:absolute;left:0;right:0}.aqvs-scroll-to-edge-button-container-top{top:.5rem}.aqvs-scroll-to-edge-button-container-bottom{bottom:.5rem}.aqvs-no-items-container{width:100%;position:absolute;top:0}.aqvs-no-items-text{text-align:center;color:#6b7280}.aqvs-item-container,.aqvs-bottom-inset,.aqvs-items-wrapper{width:100%;position:absolute}}@layer utilities{.dt-grid{flex-direction:column;display:flex;position:relative}.dt-grid-body{flex:1;min-height:0;position:relative}.dt-grid-header,.dt-grid-footer,.dt-grid-row,.dt-grid-hscrollbar-row{align-items:stretch;display:flex}.dt-grid-name-cell,.dt-grid-name-header,.dt-grid-name-footer{z-index:1;flex-shrink:0;align-items:center;display:flex;position:relative;overflow:hidden}.dt-grid-numeric-viewport{flex:1;position:relative;overflow:hidden}.dt-grid-numeric-track{transform:translate(calc(-1 * var(--dt-hscroll,0px)));will-change:transform;display:grid}.dt-grid-cell{white-space:nowrap;text-overflow:ellipsis;align-items:center;padding:0 8px;display:flex;overflow:hidden}.dt-grid-cell--right{text-align:right;justify-content:flex-end}.dt-grid-cell--center{text-align:center;justify-content:center}.dt-grid-name-label{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.dt-grid-scrollbar-spacer{flex-shrink:0}}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.top-0{top:calc(var(--spacing) * 0)}.left-0{left:calc(var(--spacing) * 0)}.z-0{z-index:0}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-2{margin-left:calc(var(--spacing) * 2)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.table{display:table}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-96{height:calc(var(--spacing) * 96)}.h-full{height:100%}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-full{width:100%}.flex-shrink{flex-shrink:1}.flex-shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.resize{resize:both}.items-center{align-items:center}.justify-center{justify-content:center}.overflow-hidden{overflow:hidden}.overflow-y-hidden{overflow-y:hidden}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.bg-amber-100{background-color:var(--color-amber-100)}.bg-blue-400\/10{background-color:#54a2ff1a}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/10{background-color:color-mix(in oklab,var(--color-blue-400) 10%,transparent)}}.bg-blue-400\/20{background-color:#54a2ff33}@supports (color:color-mix(in lab,red,red)){.bg-blue-400\/20{background-color:color-mix(in oklab,var(--color-blue-400) 20%,transparent)}}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-indigo-100{background-color:var(--color-indigo-100)}.bg-yellow-50{background-color:var(--color-yellow-50)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-2{padding-inline:calc(var(--spacing) * 2)}.py-1{padding-block:calc(var(--spacing) * 1)}.pr-\[3px\]{padding-right:3px}.pb-\[5px\]{padding-bottom:5px}.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))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.text-ellipsis{text-overflow:ellipsis}.whitespace-nowrap{white-space:nowrap}.text-blue-500{color:var(--color-blue-500)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-cyan-400{color:var(--color-cyan-400)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-indigo-800{color:var(--color-indigo-800)}.text-slate-600{color:var(--color-slate-600)}.text-slate-800{color:var(--color-slate-800)}.text-yellow-400{color:var(--color-yellow-400)}.text-yellow-500{color:var(--color-yellow-500)}.text-yellow-600{color:var(--color-yellow-600)}.opacity-70{opacity:.7}.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-\[0_0_0_1px_rgba\(59\,130\,246\,0\.3\)\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#3b82f64d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-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-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.hover\:bg-gray-400\/15:hover{background-color:#99a1af26}@supports (color:color-mix(in lab,red,red)){.hover\:bg-gray-400\/15:hover{background-color:color-mix(in oklab,var(--color-gray-400) 15%,transparent)}}.hover\:bg-slate-100\/50:hover{background-color:#f1f5f980}@supports (color:color-mix(in lab,red,red)){.hover\:bg-slate-100\/50:hover{background-color:color-mix(in oklab,var(--color-slate-100) 50%,transparent)}}}@media(prefers-color-scheme:dark){.dark\:bg-amber-900\/20{background-color:#7b330633}@supports (color:color-mix(in lab,red,red)){.dark\:bg-amber-900\/20{background-color:color-mix(in oklab,var(--color-amber-900) 20%,transparent)}}.dark\:bg-blue-400\/15{background-color:#54a2ff26}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-400\/15{background-color:color-mix(in oklab,var(--color-blue-400) 15%,transparent)}}.dark\:bg-blue-400\/25{background-color:#54a2ff40}@supports (color:color-mix(in lab,red,red)){.dark\:bg-blue-400\/25{background-color:color-mix(in oklab,var(--color-blue-400) 25%,transparent)}}.dark\:bg-emerald-900\/20{background-color:#004e3b33}@supports (color:color-mix(in lab,red,red)){.dark\:bg-emerald-900\/20{background-color:color-mix(in oklab,var(--color-emerald-900) 20%,transparent)}}.dark\:bg-gray-900{background-color:var(--color-gray-900)}.dark\:bg-indigo-900\/20{background-color:#312c8533}@supports (color:color-mix(in lab,red,red)){.dark\:bg-indigo-900\/20{background-color:color-mix(in oklab,var(--color-indigo-900) 20%,transparent)}}.dark\:bg-yellow-900\/20{background-color:#733e0a33}@supports (color:color-mix(in lab,red,red)){.dark\:bg-yellow-900\/20{background-color:color-mix(in oklab,var(--color-yellow-900) 20%,transparent)}}.dark\:text-blue-300{color:var(--color-blue-300)}.dark\:text-blue-400{color:var(--color-blue-400)}.dark\:text-gray-200{color:var(--color-gray-200)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-gray-400{color:var(--color-gray-400)}.dark\:text-slate-100{color:var(--color-slate-100)}.dark\:text-slate-300{color:var(--color-slate-300)}.dark\: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)}.dark\:shadow-\[0_0_0_1px_rgba\(96\,165\,250\,0\.4\)\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#60a5fa66);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@media(hover:hover){.dark\:hover\:bg-gray-200\/10:hover{background-color:#e5e7eb1a}@supports (color:color-mix(in lab,red,red)){.dark\:hover\:bg-gray-200\/10:hover{background-color:color-mix(in oklab,var(--color-gray-200) 10%,transparent)}}}}}@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-font-weight{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-duration{syntax:"*";inherits:false}
|