@graphenedata/cli 0.0.15 → 0.0.17

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.
Files changed (117) hide show
  1. package/README.md +174 -0
  2. package/dist/cli/bigQuery-OQUNH3VT.js +75 -0
  3. package/dist/cli/bigQuery-OQUNH3VT.js.map +7 -0
  4. package/dist/cli/chunk-56K2FF57.js +53 -0
  5. package/dist/cli/chunk-56K2FF57.js.map +7 -0
  6. package/dist/cli/chunk-TZTTALAV.js +12868 -0
  7. package/dist/cli/chunk-TZTTALAV.js.map +7 -0
  8. package/dist/cli/cli.js +260 -11196
  9. package/dist/cli/clickhouse-S3BJSKND.js +65 -0
  10. package/dist/cli/clickhouse-S3BJSKND.js.map +7 -0
  11. package/dist/cli/duckdb-TKVMONRK.js +87 -0
  12. package/dist/cli/duckdb-TKVMONRK.js.map +7 -0
  13. package/dist/cli/serve2-S2LL4D4D.js +448 -0
  14. package/dist/cli/serve2-S2LL4D4D.js.map +7 -0
  15. package/dist/cli/snowflake-3VPDEYYP.js +128 -0
  16. package/dist/cli/snowflake-3VPDEYYP.js.map +7 -0
  17. package/dist/index.d.ts +63 -0
  18. package/dist/lang/index.d.ts +63 -0
  19. package/dist/skills/graphene/SKILL.md +156 -95
  20. package/dist/skills/graphene/references/big-value.md +6 -41
  21. package/dist/skills/graphene/references/date-range.md +64 -0
  22. package/dist/skills/graphene/references/dropdown.md +3 -4
  23. package/dist/skills/graphene/references/echarts.md +162 -0
  24. package/dist/skills/graphene/references/gsql.md +55 -25
  25. package/dist/skills/graphene/references/model-gsql.md +70 -0
  26. package/dist/skills/graphene/references/table.md +13 -14
  27. package/dist/skills/graphene/references/text-input.md +2 -1
  28. package/dist/ui/app.css +239 -340
  29. package/dist/ui/component-utilities/dataShaping.ts +484 -0
  30. package/dist/ui/component-utilities/dataSummary.ts +57 -0
  31. package/dist/ui/component-utilities/enrich.ts +793 -0
  32. package/dist/ui/component-utilities/format.ts +177 -0
  33. package/dist/ui/component-utilities/inputUtils.ts +44 -8
  34. package/dist/ui/component-utilities/theme.ts +200 -0
  35. package/dist/ui/component-utilities/themeStores.ts +21 -8
  36. package/dist/ui/component-utilities/types.ts +70 -0
  37. package/dist/ui/components/AreaChart.svelte +57 -105
  38. package/dist/ui/components/BarChart.svelte +71 -129
  39. package/dist/ui/components/BigValue.svelte +24 -40
  40. package/dist/ui/components/Column.svelte +10 -18
  41. package/dist/ui/components/DateRange.svelte +54 -21
  42. package/dist/ui/components/Dropdown.svelte +47 -26
  43. package/dist/ui/components/DropdownOption.svelte +1 -2
  44. package/dist/ui/components/ECharts.svelte +181 -67
  45. package/dist/ui/components/InlineDelta.svelte +50 -31
  46. package/dist/ui/components/LineChart.svelte +54 -125
  47. package/dist/ui/components/PieChart.svelte +27 -37
  48. package/dist/ui/components/QueryLoad.svelte +77 -45
  49. package/dist/ui/components/Row.svelte +2 -1
  50. package/dist/ui/components/ScatterPlot.svelte +52 -0
  51. package/dist/ui/components/Skeleton.svelte +32 -0
  52. package/dist/ui/components/Table.svelte +3 -2
  53. package/dist/ui/components/TableGroupRow.svelte +28 -36
  54. package/dist/ui/components/TableHarness.svelte +32 -0
  55. package/dist/ui/components/TableHeader.svelte +34 -59
  56. package/dist/ui/components/TableRow.svelte +14 -38
  57. package/dist/ui/components/TableSubtotalRow.svelte +18 -21
  58. package/dist/ui/components/TableTotalRow.svelte +27 -37
  59. package/dist/ui/components/TextInput.svelte +13 -12
  60. package/dist/ui/components/Value.svelte +25 -0
  61. package/dist/ui/components/_Table.svelte +72 -70
  62. package/dist/ui/internal/ChartGallery.svelte +527 -0
  63. package/dist/ui/internal/ErrorDisplay.svelte +22 -97
  64. package/dist/ui/internal/LocalApp.svelte +84 -19
  65. package/dist/ui/internal/PageNavGroup.svelte +269 -0
  66. package/dist/ui/internal/Sidebar.svelte +178 -0
  67. package/dist/ui/internal/SidebarToggle.svelte +47 -0
  68. package/dist/ui/internal/StyleGallery.svelte +244 -0
  69. package/dist/ui/internal/clientCache.ts +2 -2
  70. package/dist/ui/internal/pageInputs.svelte.js +292 -0
  71. package/dist/ui/internal/queryEngine.ts +112 -129
  72. package/dist/ui/internal/runSocket.ts +31 -14
  73. package/dist/ui/internal/sidebar.svelte.js +18 -0
  74. package/dist/ui/internal/telemetry.ts +51 -16
  75. package/dist/ui/internal/types.d.ts +7 -0
  76. package/dist/ui/web.js +30 -11
  77. package/package.json +40 -38
  78. package/dist/skills/graphene/references/area-chart.md +0 -95
  79. package/dist/skills/graphene/references/bar-chart.md +0 -112
  80. package/dist/skills/graphene/references/line-chart.md +0 -108
  81. package/dist/skills/graphene/references/pie-chart.md +0 -29
  82. package/dist/skills/graphene/references/value-formats.md +0 -104
  83. package/dist/ui/component-utilities/autoFormatting.js +0 -280
  84. package/dist/ui/component-utilities/builtInFormats.js +0 -481
  85. package/dist/ui/component-utilities/chartContext.js +0 -12
  86. package/dist/ui/component-utilities/chartWindowDebug.js +0 -21
  87. package/dist/ui/component-utilities/checkInputs.js +0 -84
  88. package/dist/ui/component-utilities/convert.js +0 -15
  89. package/dist/ui/component-utilities/dateParsing.js +0 -56
  90. package/dist/ui/component-utilities/dropdownContext.ts +0 -1
  91. package/dist/ui/component-utilities/echarts.js +0 -252
  92. package/dist/ui/component-utilities/echartsThemes.js +0 -443
  93. package/dist/ui/component-utilities/formatTitle.js +0 -24
  94. package/dist/ui/component-utilities/formatting.js +0 -241
  95. package/dist/ui/component-utilities/getColumnExtents.js +0 -79
  96. package/dist/ui/component-utilities/getColumnSummary.js +0 -62
  97. package/dist/ui/component-utilities/getCompletedData.js +0 -122
  98. package/dist/ui/component-utilities/getDistinctCount.js +0 -7
  99. package/dist/ui/component-utilities/getDistinctValues.js +0 -15
  100. package/dist/ui/component-utilities/getSeriesConfig.js +0 -231
  101. package/dist/ui/component-utilities/getSortedData.js +0 -9
  102. package/dist/ui/component-utilities/getStackPercentages.js +0 -45
  103. package/dist/ui/component-utilities/getStackedData.js +0 -19
  104. package/dist/ui/component-utilities/getYAxisIndex.js +0 -15
  105. package/dist/ui/component-utilities/globalContexts.js +0 -1
  106. package/dist/ui/component-utilities/helpers/getCompletedData.helpers.js +0 -119
  107. package/dist/ui/component-utilities/replaceNulls.js +0 -16
  108. package/dist/ui/component-utilities/tableUtils.ts +0 -107
  109. package/dist/ui/component-utilities/tidyWithTypes.js +0 -9
  110. package/dist/ui/components/Area.svelte +0 -214
  111. package/dist/ui/components/Bar.svelte +0 -347
  112. package/dist/ui/components/Chart.svelte +0 -995
  113. package/dist/ui/components/Line.svelte +0 -227
  114. package/dist/ui/internal/NavSidebar.svelte +0 -396
  115. package/dist/ui/internal/theme.ts +0 -60
  116. package/dist/ui/public/inter-latin-ext.woff2 +0 -0
  117. package/dist/ui/public/inter-latin.woff2 +0 -0
@@ -1,227 +0,0 @@
1
- <script lang="ts">
2
- import {getContext} from 'svelte'
3
- import type {Writable} from 'svelte/store'
4
- import {propKey, configKey} from '../component-utilities/chartContext.js'
5
- import getSeriesConfig from '../component-utilities/getSeriesConfig.js'
6
- import formatTitle from '../component-utilities/formatTitle.js'
7
- import getCompletedData from '../component-utilities/getCompletedData.js'
8
- import getYAxisIndex from '../component-utilities/getYAxisIndex.js'
9
- import {formatValue, getFormatObjectFromString} from '../component-utilities/formatting.js'
10
- import {getThemeStores} from '../component-utilities/themeStores'
11
- import {toBoolean} from '../component-utilities/convert'
12
- import {parseCommaList} from '../component-utilities/inputUtils.ts'
13
-
14
- interface Props {
15
- y?: any, y2?: any, series?: any, options?: any, name?: any, lineColor?: any, lineWidth?: number
16
- lineType?: string, lineOpacity?: any, markers?: boolean | string, markerShape?: string
17
- markerSize?: number, labels?: boolean | string, labelSize?: number, labelPosition?: string
18
- labelColor?: any, labelFmt?: any, yLabelFmt?: any, y2LabelFmt?: any, showAllLabels?: boolean | string
19
- y2SeriesType?: any, handleMissing?: string, step?: boolean | string, stepPosition?: string
20
- seriesOrder?: any, seriesLabelFmt?: any
21
- }
22
-
23
- const {resolveColor} = getThemeStores()
24
- const chartProps: Writable<any> = getContext(propKey)
25
- const config: Writable<any> = getContext(configKey)
26
-
27
- let {
28
- y = undefined, y2 = undefined, series = undefined, options = undefined, name = undefined,
29
- lineColor = undefined, lineWidth = 2, lineType = 'solid', lineOpacity = undefined, markers = false,
30
- markerShape = 'circle', markerSize = 8, labels = false, labelSize = 11, labelPosition = 'top',
31
- labelColor = undefined, labelFmt = undefined, yLabelFmt = undefined, y2LabelFmt = undefined,
32
- showAllLabels = false, y2SeriesType = undefined, handleMissing = 'gap', step = false,
33
- stepPosition = 'end', seriesOrder = undefined, seriesLabelFmt = undefined,
34
- }: Props = $props()
35
-
36
- // Use $derived for values that depend on props
37
- let ySet = $derived(y ? true : false)
38
- let y2Set = $derived(y2 ? true : false)
39
- let seriesSet = $derived(series ? true : false)
40
-
41
- let lineColorStore = $derived(resolveColor(lineColor))
42
- let labelColorStore = $derived(resolveColor(labelColor))
43
- let markersBool = $derived(toBoolean(markers))
44
- let labelsBool = $derived(toBoolean(labels))
45
- let showAllLabelsBool = $derived(toBoolean(showAllLabels))
46
- let stepBool = $derived(toBoolean(step))
47
-
48
- // Format objects derived from props
49
- let labelFormat = $derived(labelFmt ? getFormatObjectFromString(labelFmt) : undefined)
50
- let yLabelFormat = $derived(yLabelFmt ? getFormatObjectFromString(yLabelFmt) : undefined)
51
- let y2LabelFormat = $derived(y2LabelFmt ? getFormatObjectFromString(y2LabelFmt) : undefined)
52
-
53
- const labelPositions = {above: 'top', below: 'bottom', middle: 'inside'}
54
- const swapXYLabelPositions = {above: 'right', below: 'left', middle: 'inside'}
55
-
56
- // Derive values from chartProps store instead of using $effect to assign
57
- let data = $derived($chartProps.data)
58
- let x = $derived($chartProps.x)
59
- let swapXY = $derived($chartProps.swapXY)
60
- let yFormat = $derived($chartProps.yFormat)
61
- let y2Format = $derived($chartProps.y2Format)
62
- let yCount = $derived($chartProps.yCount)
63
- let y2Count = $derived($chartProps.y2Count)
64
- let xType = $derived($chartProps.xType)
65
- let xMismatch = $derived($chartProps.xMismatch)
66
- let columnSummary = $derived($chartProps.columnSummary)
67
- let resolvedSeries = $derived(seriesSet ? series : $chartProps.series)
68
- let resolvedY = $derived(ySet ? parseCommaList(y) : $chartProps.y)
69
- let resolvedY2 = $derived(y2Set ? parseCommaList(y2) : $chartProps.y2)
70
- let resolvedSeriesOrder = $derived(parseCommaList(seriesOrder))
71
-
72
- // Compute all the derived state in one $derived.by block to avoid read/write conflicts
73
- let computedState = $derived.by(() => {
74
- let isSingleSeries = !resolvedSeries && (!Array.isArray(resolvedY) || resolvedY.length === 1)
75
- let computedData = data
76
- let computedName = name
77
- let computedDefaultLabelPosition = swapXY ? 'right' : 'top'
78
-
79
- if (!data || !columnSummary) {
80
- return {
81
- data: computedData,
82
- name: computedName,
83
- defaultLabelPosition: computedDefaultLabelPosition,
84
- }
85
- }
86
-
87
- if (isSingleSeries) {
88
- // Single Series
89
- let col = Array.isArray(resolvedY) ? resolvedY[0] : resolvedY
90
- if (col && columnSummary[col]) {
91
- computedName = computedName ?? formatTitle(col, columnSummary[col].title)
92
- }
93
- } else {
94
- // Multi Series
95
- try {
96
- computedData = getCompletedData(computedData, x, resolvedY, resolvedSeries)
97
- } catch(error) {
98
- globalThis.console?.warn('Failed to complete data', {error})
99
- computedData = []
100
- }
101
- }
102
-
103
- // Handle missing values
104
- if (handleMissing === 'zero') {
105
- try {
106
- computedData = getCompletedData(computedData, x, resolvedY, resolvedSeries, true)
107
- } catch(error) {
108
- globalThis.console?.warn('Failed to complete data', {error})
109
- computedData = []
110
- }
111
- }
112
-
113
- return {
114
- data: computedData,
115
- name: computedName,
116
- defaultLabelPosition: computedDefaultLabelPosition,
117
- }
118
- })
119
-
120
- // Extract computed values for use in template and other derived values
121
- let processedData = $derived(computedState.data)
122
- let resolvedName = $derived(computedState.name)
123
- let defaultLabelPosition = $derived(computedState.defaultLabelPosition)
124
-
125
- let resolvedLabelPosition = $derived(
126
- (swapXY ? swapXYLabelPositions[labelPosition] : labelPositions[labelPosition]) ?? defaultLabelPosition,
127
- )
128
-
129
- let chartOverrides = $derived({
130
- yAxis: {boundaryGap: ['0%', '1%']},
131
- xAxis: {boundaryGap: [xType === 'time' ? '2%' : '0%', '2%']},
132
- })
133
-
134
- $effect(() => {
135
- // Don't run until we have data
136
- if (!processedData || !columnSummary) return
137
-
138
- let baseConfig = {
139
- type: 'line',
140
- label: {
141
- show: labelsBool,
142
- formatter: (params: any) =>
143
- params.value[swapXY ? 0 : 1] === 0
144
- ? ''
145
- : formatValue(
146
- params.value[swapXY ? 0 : 1],
147
- [yLabelFormat ?? labelFormat ?? yFormat, y2LabelFormat ?? labelFormat ?? y2Format][
148
- getYAxisIndex(params.componentIndex, yCount, y2Count)
149
- ],
150
- ),
151
- fontSize: labelSize,
152
- color: $labelColorStore,
153
- position: resolvedLabelPosition,
154
- padding: 3,
155
- },
156
- labelLayout: {hideOverlap: showAllLabelsBool ? false : true},
157
- connectNulls: handleMissing === 'connect',
158
- emphasis: {
159
- focus: 'series',
160
- endLabel: {show: false},
161
- lineStyle: {opacity: 1, width: 3},
162
- },
163
- lineStyle: {width: parseInt(lineWidth as string), type: lineType, opacity: lineOpacity},
164
- itemStyle: {color: $lineColorStore, opacity: lineOpacity},
165
- showSymbol: labelsBool || markersBool,
166
- symbol: markerShape,
167
- symbolSize: labelsBool && !markersBool ? 0 : markerSize,
168
- step: stepBool ? stepPosition : false,
169
- }
170
-
171
- let seriesConfig = getSeriesConfig(
172
- processedData,
173
- x,
174
- resolvedY,
175
- resolvedSeries,
176
- swapXY,
177
- baseConfig,
178
- resolvedName,
179
- xMismatch,
180
- columnSummary,
181
- resolvedSeriesOrder,
182
- undefined,
183
- undefined,
184
- resolvedY2,
185
- seriesLabelFmt,
186
- )
187
-
188
- config.update((d: any) => {
189
- // Guard against incomplete config state
190
- if (!d.series) d.series = []
191
- if (!d.legend) d.legend = {data: []}
192
- if (!d.legend.data) d.legend.data = []
193
-
194
- d.series.push(...seriesConfig)
195
- d.legend.data.push(...seriesConfig.map((entry: any) => entry.name.toString()))
196
- return d
197
- })
198
- })
199
-
200
- // Use $effect.pre() instead of beforeUpdate for runes mode
201
- $effect.pre(() => {
202
- if (options) {
203
- config.update((d: any) => ({...d, ...options}))
204
- }
205
-
206
- if (!chartOverrides) return
207
- config.update((d: any) => {
208
- if (!d.yAxis || !Array.isArray(d.yAxis)) return d
209
- if (swapXY) {
210
- d.yAxis = {...d.yAxis, ...chartOverrides.xAxis}
211
- d.xAxis = {...d.xAxis, ...chartOverrides.yAxis}
212
- if (labelsBool) d.axisPointer = {triggerEmphasis: false}
213
- return d
214
- }
215
- if (d.yAxis[0]) d.yAxis[0] = {...d.yAxis[0], ...chartOverrides.yAxis}
216
- d.xAxis = {...d.xAxis, ...chartOverrides.xAxis}
217
- if (y2Count > 0 && d.yAxis[1]) {
218
- let shouldSetY2Type = y2SeriesType && ['line', 'bar', 'scatter'].includes(y2SeriesType) && d.series
219
- for (let i = 0; shouldSetY2Type && i < y2Count; i++) {
220
- if (d.series[yCount + i]) d.series[yCount + i].type = y2SeriesType
221
- }
222
- }
223
- if (labelsBool) d.axisPointer = {triggerEmphasis: false}
224
- return d
225
- })
226
- })
227
- </script>
@@ -1,396 +0,0 @@
1
- <script>
2
- import {SvelteSet, SvelteMap} from 'svelte/reactivity'
3
-
4
- /** @type {string} */
5
- let {currentFile = '', files = [], onNavigate = undefined, baseRoute = ''} = $props()
6
-
7
- let tree = $state([])
8
- let flatNodes = $state([])
9
- // eslint-disable-next-line svelte/no-unnecessary-state-wrap -- openFolders is reassigned, needs $state
10
- let openFolders = $state(new SvelteSet())
11
- let treeSignature = $state('')
12
- let lastCurrent = $state('')
13
-
14
- let normalizedFiles = $derived((files || [])
15
- .map((file) => file.replace(/^\.\//, '').replace(/\\/g, '/')))
16
-
17
-
18
- let normalizedCurrent = $derived(deriveCurrentFile(currentFile, normalizedFiles, baseRoute))
19
- let currentRoute = $derived(normalizedCurrent ? pathToRoute(normalizedCurrent) : '/')
20
-
21
- function deriveCurrentFile(_currentFile, _normalizedFiles, _baseRoute) {
22
- let fromProp = normalizeFilePath(currentFile)
23
- let route = getLocationRoute()
24
- if (route && normalizedFiles) {
25
- let match = normalizedFiles.find((file) => pathToRoute(file) === route)
26
- if (match) return match
27
- }
28
- return fromProp
29
- }
30
-
31
- function normalizeFilePath(filePath) {
32
- return (filePath || '').replace(/^\.\//, '').replace(/\\/g, '/')
33
- }
34
-
35
- function getLocationRoute() {
36
- if (typeof window === 'undefined') return null
37
- let route = window.location.pathname || '/'
38
- route = route.replace(/\/+$/, '') || '/'
39
- return route
40
- }
41
-
42
- $effect(() => {
43
- let nextSignature = normalizedFiles.join('|')
44
- if (nextSignature !== treeSignature) {
45
- treeSignature = nextSignature
46
- tree = buildTree(normalizedFiles)
47
- flatNodes = flattenTree(tree)
48
- openFolders = createDefaultOpenFolders(tree, normalizedCurrent)
49
- }
50
- })
51
-
52
- $effect(() => {
53
- if (normalizedCurrent !== lastCurrent) {
54
- openFolders = mergeAncestorFolders(openFolders, normalizedCurrent)
55
- lastCurrent = normalizedCurrent
56
- }
57
- })
58
-
59
- function toggleFolder(path) {
60
- if (!path) return
61
- let next = new SvelteSet(openFolders)
62
- if (next.has(path)) next.delete(path)
63
- else next.add(path)
64
- openFolders = next
65
- }
66
-
67
- function handleFolderRowKey(event, path) {
68
- if (event.key !== 'Enter' && event.key !== ' ') return
69
- event.preventDefault()
70
- toggleFolder(path)
71
- }
72
-
73
- function isOpen(path, openSet = openFolders) {
74
- if (!path) return true
75
- return openSet.has(path)
76
- }
77
-
78
- function isVisible(node, openSet = openFolders) {
79
- return node.ancestors.every((path) => isOpen(path, openSet))
80
- }
81
-
82
- function buildTree(paths) {
83
- let root = []
84
- let folderMap = new SvelteMap()
85
-
86
- for (let filePath of paths) {
87
- let cleanPath = filePath.replace(/^\.\//, '').replace(/^\//, '')
88
- let segments = cleanPath.split('/')
89
- if (!segments.length) continue
90
- let fileName = segments.pop()
91
- let parentChildren = root
92
- let parentPath = ''
93
-
94
- for (let segment of segments) {
95
- parentPath = parentPath ? `${parentPath}/${segment}` : segment
96
- if (!folderMap.has(parentPath)) {
97
- let folderNode = {
98
- type: 'folder',
99
- name: segment,
100
- label: formatLabel(segment, 'folder'),
101
- path: parentPath,
102
- children: [],
103
- route: null,
104
- }
105
- folderMap.set(parentPath, folderNode)
106
- parentChildren.push(folderNode)
107
- }
108
- parentChildren = folderMap.get(parentPath).children
109
- }
110
-
111
- if (!fileName) continue
112
- let fullPath = parentPath ? `${parentPath}/${fileName}` : fileName
113
-
114
- if (fileName.toLowerCase() === 'index.md' && parentPath) {
115
- let folderNode = folderMap.get(parentPath)
116
- if (folderNode) folderNode.route = pathToRoute(fullPath)
117
- continue
118
- }
119
-
120
- let exists = parentChildren.find((node) => node.path === fullPath)
121
- if (exists) continue
122
- parentChildren.push({
123
- type: 'file',
124
- name: fileName,
125
- label: formatLabel(fileName, 'file'),
126
- path: fullPath,
127
- route: pathToRoute(fullPath),
128
- })
129
- }
130
-
131
- return sortNodes(root)
132
- }
133
-
134
- function sortNodes(nodes) {
135
- return nodes
136
- .map((node) => {
137
- if (node.type === 'folder' && node.children?.length) {
138
- return {...node, children: sortNodes(node.children)}
139
- }
140
- return node
141
- })
142
- .sort((a, b) => {
143
- if (a.label === 'Home') return -1
144
- if (b.label === 'Home') return 1
145
- if (a.type !== b.type) return a.type === 'folder' ? -1 : 1
146
- return a.label.localeCompare(b.label)
147
- })
148
- }
149
-
150
- function flattenTree(nodes, depth = 0, ancestors = []) {
151
- let list = []
152
- for (let node of nodes) {
153
- if (node.type === 'folder') {
154
- let entry = {...node, depth, ancestors}
155
- list.push(entry)
156
- if (node.children?.length) {
157
- list.push(...flattenTree(node.children, depth + 1, [...ancestors, node.path]))
158
- }
159
- continue
160
- }
161
- list.push({...node, depth, ancestors})
162
- }
163
- return list
164
- }
165
-
166
- function createDefaultOpenFolders(_treeNodes, currentPath) {
167
- let next = new SvelteSet()
168
- return mergeAncestorFolders(next, currentPath)
169
- }
170
-
171
- function mergeAncestorFolders(openSet, filePath) {
172
- if (!filePath) return new SvelteSet(openSet)
173
- let parts = filePath.split('/')
174
- parts.pop()
175
- let aggregate = []
176
- let next = new SvelteSet(openSet)
177
- for (let part of parts) {
178
- aggregate.push(part)
179
- next.add(aggregate.join('/'))
180
- }
181
- return next
182
- }
183
-
184
- function formatLabel(value, type) {
185
- let cleaned = type === 'file' ? value.replace(/\.md$/, '') : value
186
- if (cleaned.toLowerCase() === 'index') return 'Home'
187
- return cleaned
188
- .split(/[\s_-]+/)
189
- .filter(Boolean)
190
- .map((chunk) => chunk.charAt(0).toUpperCase() + chunk.slice(1))
191
- .join(' ')
192
- }
193
-
194
- function pathToRoute(path) {
195
- let clean = path.replace(/\.md$/, '')
196
- let prefix = baseRoute ? '/' + baseRoute : ''
197
- if (!clean || clean === 'index') return prefix || '/'
198
- return prefix + '/' + clean
199
- }
200
-
201
- function handleLinkClick(event, href) {
202
- if (!onNavigate) return
203
- if (href.startsWith('http') || href.startsWith('//')) return
204
- event.preventDefault()
205
- onNavigate(href)
206
- }
207
- </script>
208
-
209
- <ul>
210
- {#each flatNodes as node (node.path)}
211
- {#if node.type === 'folder'}
212
- <li class={isVisible(node, openFolders) ? '' : 'hidden'} style={`--depth:${node.depth}`} data-folder={node.path}>
213
- <div
214
- class={node.route ? 'folder-row' : 'folder-row clickable'}
215
- role={node.route ? undefined : 'button'}
216
- aria-expanded={node.route ? undefined : String(isOpen(node.path, openFolders))}
217
- onclick={node.route ? undefined : () => toggleFolder(node.path)}
218
- onkeydown={node.route ? undefined : (event) => handleFolderRowKey(event, node.path)}
219
- >
220
- <button
221
- class="toggle"
222
- type="button"
223
- data-folder-toggle={node.path}
224
- aria-expanded={isOpen(node.path, openFolders)}
225
- onclick={(event) => { event.stopPropagation(); toggleFolder(node.path) }}
226
- aria-label={(isOpen(node.path, openFolders) ? 'Collapse' : 'Expand') + ' ' + node.label}
227
- >
228
- <span class={isOpen(node.path, openFolders) ? 'chevron open' : 'chevron'}>▸</span>
229
- </button>
230
- {#if node.route}
231
- <a
232
- href={node.route}
233
- class={node.route === currentRoute ? 'active' : ''}
234
- aria-current={node.route === currentRoute ? 'page' : undefined}
235
- onclick={(e) => handleLinkClick(e, node.route)}
236
- >
237
- {node.label}
238
- </a>
239
- {:else}
240
- <span class="label">{node.label}</span>
241
- {/if}
242
- </div>
243
- </li>
244
- {:else}
245
- <li class={isVisible(node, openFolders) ? 'file' : 'file hidden'} style={`--depth:${node.depth}`}>
246
- <a
247
- href={node.route}
248
- class={node.path === normalizedCurrent ? 'active' : ''}
249
- aria-current={node.path === normalizedCurrent ? 'page' : undefined}
250
- onclick={(e) => handleLinkClick(e, node.route)}
251
- >
252
- <span>{node.label}</span>
253
- </a>
254
- </li>
255
- {/if}
256
- {/each}
257
- </ul>
258
-
259
- <style>
260
- ul {
261
- list-style: none;
262
- padding: 0 0.5rem 0 0;
263
- margin: 0;
264
- display: flex;
265
- flex-direction: column;
266
- gap: 0.1rem;
267
- overflow: hidden;
268
- }
269
-
270
- li {
271
- --indent: calc(var(--depth, 0) * 1rem);
272
- padding-left: var(--indent);
273
- width: 100%;
274
- box-sizing: border-box;
275
- }
276
-
277
- li.file {
278
- padding-left: calc(var(--indent) + 1.5rem);
279
- }
280
-
281
- li.hidden {
282
- display: none;
283
- }
284
-
285
- .folder-row {
286
- display: flex;
287
- align-items: center;
288
- padding: 0.1rem 0.15rem;
289
- border-radius: 4px;
290
- }
291
-
292
- .folder-row.clickable {
293
- cursor: pointer;
294
- }
295
-
296
- .folder-row.clickable:focus-visible {
297
- outline: 2px solid rgba(15, 23, 42, 0.2);
298
- outline-offset: 2px;
299
- }
300
-
301
- .toggle {
302
- display: inline-flex;
303
- align-items: center;
304
- justify-content: center;
305
- width: 1.5rem;
306
- height: 1.5rem;
307
- color: var(--base-heading);
308
- background: transparent;
309
- border: none;
310
- cursor: pointer;
311
- border-radius: 4px;
312
- opacity: 0;
313
- pointer-events: none;
314
- transition: opacity 120ms ease;
315
- visibility: hidden;
316
- }
317
-
318
- .folder-row:hover .toggle,
319
- .folder-row:focus-within .toggle,
320
- .toggle:focus-visible {
321
- opacity: 1;
322
- pointer-events: auto;
323
- visibility: visible;
324
- }
325
-
326
- .toggle:hover,
327
- .toggle:focus-visible {
328
- background: rgba(15, 23, 42, 0.1);
329
- outline: none;
330
- }
331
-
332
- .chevron {
333
- display: inline-block;
334
- transition: transform 150ms ease;
335
- font-size: 0.7rem;
336
- color: var(--base-content-muted);
337
- }
338
-
339
- .chevron.open {
340
- transform: rotate(90deg);
341
- }
342
-
343
- .label {
344
- font-size: 0.85rem;
345
- padding: 0.2rem 0.35rem;
346
- white-space: nowrap;
347
- overflow: hidden;
348
- text-overflow: ellipsis;
349
- color: var(--base-heading);
350
- }
351
-
352
- .folder-row a {
353
- flex: 1;
354
- display: block;
355
- font-size: 0.85rem;
356
- padding: 0.2rem 0.35rem;
357
- border-radius: 4px;
358
- color: var(--base-heading);
359
- text-decoration: none;
360
- white-space: nowrap;
361
- overflow: hidden;
362
- text-overflow: ellipsis;
363
- }
364
-
365
- .folder-row a:hover,
366
- .folder-row a:focus-visible {
367
- background: rgba(15, 23, 42, 0.05);
368
- outline: none;
369
- }
370
-
371
- li.file a {
372
- display: flex;
373
- align-items: center;
374
- font-size: 0.85rem;
375
- padding: 0.2rem 0.5rem;
376
- border-radius: 4px;
377
- color: var(--base-heading);
378
- text-decoration: none;
379
- }
380
-
381
- li.file a span {
382
- white-space: nowrap;
383
- overflow: hidden;
384
- text-overflow: ellipsis;
385
- }
386
-
387
- li.file a:hover,
388
- li.file a:focus-visible {
389
- background: rgba(15, 23, 42, 0.05);
390
- outline: none;
391
- }
392
-
393
- a.active {
394
- color: var(--base-900, #0f172a);
395
- }
396
- </style>
@@ -1,60 +0,0 @@
1
- // Evidence has a complex theme loading system that we don't really want to keep.
2
- // This was generated by copying the runtime export of $evidence/themes from the evidence sample app.
3
- export const themes = {
4
- light: {
5
- colors: {
6
- primary: '#2563eb',
7
- accent: '#c2410c',
8
- 'base-100': '#ffffff',
9
- info: '#0284c7',
10
- positive: '#16a34a',
11
- warning: '#f8c900',
12
- negative: '#dc2626',
13
- 'primary-content': '#f6f8fb',
14
- 'accent-content': '#fbf7f6',
15
- 'base-200': '#f7f7f7',
16
- 'base-300': '#d6d6d6',
17
- 'base-heading': '#060606',
18
- 'base-content': '#2c2c2c',
19
- 'base-content-muted': '#717171',
20
- 'info-content': '#030709',
21
- 'positive-content': '#040906',
22
- 'negative-content': '#fbf6f6',
23
- 'warning-content': '#0a0803',
24
- },
25
- colorPalettes: {
26
- default: ['#236aa4', '#45a1bf', '#a5cdee', '#8dacbf', '#85c7c6', '#d2c6ac', '#f4b548', '#8f3d56', '#71b9f4', '#46a485'],
27
- },
28
- colorScales: {
29
- default: ['#ADD8E6', '#00008B'],
30
- },
31
- },
32
- dark: {
33
- colors: {
34
- primary: '#3b82f6',
35
- accent: '#fdba74',
36
- 'base-100': '#09090b',
37
- info: '#38bdf8',
38
- positive: '#4ade80',
39
- warning: '#fbbf24',
40
- negative: '#f87171',
41
- 'primary-content': '#030609',
42
- 'accent-content': '#090603',
43
- 'base-200': '#111113',
44
- 'base-300': '#29292b',
45
- 'base-heading': '#f8f8f9',
46
- 'base-content': '#cacacb',
47
- 'base-content-muted': '#7b7b7c',
48
- 'info-content': '#030809',
49
- 'positive-content': '#040906',
50
- 'negative-content': '#090303',
51
- 'warning-content': '#090803',
52
- },
53
- colorPalettes: {
54
- default: ['#236aa4', '#45a1bf', '#a5cdee', '#8dacbf', '#85c7c6', '#d2c6ac', '#f4b548', '#8f3d56', '#71b9f4', '#46a485'],
55
- },
56
- colorScales: {
57
- default: ['#ADD8E6', '#00008B'],
58
- },
59
- },
60
- }
Binary file