@graphenedata/cli 0.0.14 → 0.0.16

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 (121) hide show
  1. package/LICENSE.md +3 -3
  2. package/README.md +138 -0
  3. package/THIRD_PARTY_NOTICES.md +1 -0
  4. package/bin.js +2 -2
  5. package/dist/cli/bigQuery-I3F46SC6.js +75 -0
  6. package/dist/cli/bigQuery-I3F46SC6.js.map +7 -0
  7. package/dist/cli/chunk-OVWODUTJ.js +12849 -0
  8. package/dist/cli/chunk-OVWODUTJ.js.map +7 -0
  9. package/dist/cli/chunk-QAXEOZ43.js +53 -0
  10. package/dist/cli/chunk-QAXEOZ43.js.map +7 -0
  11. package/dist/cli/cli.js +245 -10290
  12. package/dist/cli/clickhouse-ZN5AN2UL.js +64 -0
  13. package/dist/cli/clickhouse-ZN5AN2UL.js.map +7 -0
  14. package/dist/cli/duckdb-IYBIO5KJ.js +87 -0
  15. package/dist/cli/duckdb-IYBIO5KJ.js.map +7 -0
  16. package/dist/cli/serve2-TNN5EROW.js +447 -0
  17. package/dist/cli/serve2-TNN5EROW.js.map +7 -0
  18. package/dist/cli/snowflake-MOQB5GA4.js +128 -0
  19. package/dist/cli/snowflake-MOQB5GA4.js.map +7 -0
  20. package/dist/index.d.ts +63 -0
  21. package/dist/lang/index.d.ts +63 -0
  22. package/dist/skills/graphene/SKILL.md +235 -0
  23. package/dist/skills/graphene/references/big-value.md +20 -0
  24. package/dist/skills/graphene/references/date-range.md +64 -0
  25. package/dist/skills/graphene/references/dropdown.md +62 -0
  26. package/dist/skills/graphene/references/echarts.md +162 -0
  27. package/dist/skills/graphene/references/gsql.md +393 -0
  28. package/dist/skills/graphene/references/model-gsql.md +72 -0
  29. package/dist/skills/graphene/references/table.md +143 -0
  30. package/dist/skills/graphene/references/text-input.md +29 -0
  31. package/dist/ui/app.css +263 -299
  32. package/dist/ui/component-utilities/dataShaping.ts +484 -0
  33. package/dist/ui/component-utilities/dataSummary.ts +57 -0
  34. package/dist/ui/component-utilities/enrich.ts +763 -0
  35. package/dist/ui/component-utilities/format.ts +177 -0
  36. package/dist/ui/component-utilities/inputUtils.ts +48 -9
  37. package/dist/ui/component-utilities/theme.ts +200 -0
  38. package/dist/ui/component-utilities/themeStores.ts +26 -21
  39. package/dist/ui/component-utilities/types.ts +70 -0
  40. package/dist/ui/components/AreaChart.svelte +57 -105
  41. package/dist/ui/components/BarChart.svelte +71 -129
  42. package/dist/ui/components/BigValue.svelte +24 -40
  43. package/dist/ui/components/Column.svelte +11 -19
  44. package/dist/ui/components/DateRange.svelte +71 -34
  45. package/dist/ui/components/Dropdown.svelte +82 -49
  46. package/dist/ui/components/DropdownOption.svelte +1 -2
  47. package/dist/ui/components/ECharts.svelte +179 -60
  48. package/dist/ui/components/InlineDelta.svelte +51 -32
  49. package/dist/ui/components/LineChart.svelte +54 -125
  50. package/dist/ui/components/PieChart.svelte +27 -37
  51. package/dist/ui/components/QueryLoad.svelte +78 -44
  52. package/dist/ui/components/Row.svelte +2 -1
  53. package/dist/ui/components/ScatterPlot.svelte +52 -0
  54. package/dist/ui/components/Skeleton.svelte +32 -0
  55. package/dist/ui/components/Table.svelte +3 -2
  56. package/dist/ui/components/TableGroupRow.svelte +28 -36
  57. package/dist/ui/components/TableHarness.svelte +32 -0
  58. package/dist/ui/components/TableHeader.svelte +34 -59
  59. package/dist/ui/components/TableRow.svelte +15 -39
  60. package/dist/ui/components/TableSubtotalRow.svelte +26 -21
  61. package/dist/ui/components/TableTotalRow.svelte +27 -37
  62. package/dist/ui/components/TextInput.svelte +17 -14
  63. package/dist/ui/components/Value.svelte +25 -0
  64. package/dist/ui/components/_Table.svelte +80 -76
  65. package/dist/ui/internal/ChartGallery.svelte +527 -0
  66. package/dist/ui/internal/ErrorDisplay.svelte +60 -0
  67. package/dist/ui/internal/LocalApp.svelte +87 -19
  68. package/dist/ui/internal/PageNavGroup.svelte +269 -0
  69. package/dist/ui/internal/Sidebar.svelte +178 -0
  70. package/dist/ui/internal/SidebarToggle.svelte +47 -0
  71. package/dist/ui/internal/StyleGallery.svelte +244 -0
  72. package/dist/ui/internal/clientCache.ts +15 -13
  73. package/dist/ui/internal/pageInputs.svelte.js +292 -0
  74. package/dist/ui/internal/queryEngine.ts +124 -132
  75. package/dist/ui/internal/runSocket.ts +59 -0
  76. package/dist/ui/internal/sidebar.svelte.js +18 -0
  77. package/dist/ui/internal/telemetry.ts +52 -17
  78. package/dist/ui/internal/types.d.ts +7 -0
  79. package/dist/ui/web.js +55 -13
  80. package/package.json +40 -41
  81. package/dist/docs/agent-instructions.md +0 -18
  82. package/dist/docs/base.md +0 -98
  83. package/dist/docs/cli.md +0 -22
  84. package/dist/docs/graphene.md +0 -1462
  85. package/dist/ui/component-utilities/autoFormatting.js +0 -301
  86. package/dist/ui/component-utilities/builtInFormats.js +0 -482
  87. package/dist/ui/component-utilities/chartContext.js +0 -12
  88. package/dist/ui/component-utilities/chartWindowDebug.js +0 -21
  89. package/dist/ui/component-utilities/checkInputs.js +0 -95
  90. package/dist/ui/component-utilities/convert.js +0 -15
  91. package/dist/ui/component-utilities/dateParsing.js +0 -57
  92. package/dist/ui/component-utilities/dropdownContext.ts +0 -1
  93. package/dist/ui/component-utilities/echarts.js +0 -272
  94. package/dist/ui/component-utilities/echartsThemes.js +0 -453
  95. package/dist/ui/component-utilities/formatTitle.js +0 -24
  96. package/dist/ui/component-utilities/formatting.js +0 -250
  97. package/dist/ui/component-utilities/getColumnExtents.js +0 -79
  98. package/dist/ui/component-utilities/getColumnSummary.js +0 -67
  99. package/dist/ui/component-utilities/getCompletedData.js +0 -114
  100. package/dist/ui/component-utilities/getDistinctCount.js +0 -7
  101. package/dist/ui/component-utilities/getDistinctValues.js +0 -15
  102. package/dist/ui/component-utilities/getSeriesConfig.js +0 -237
  103. package/dist/ui/component-utilities/getSortedData.js +0 -7
  104. package/dist/ui/component-utilities/getStackPercentages.js +0 -43
  105. package/dist/ui/component-utilities/getStackedData.js +0 -17
  106. package/dist/ui/component-utilities/getYAxisIndex.js +0 -15
  107. package/dist/ui/component-utilities/globalContexts.js +0 -1
  108. package/dist/ui/component-utilities/helpers/getCompletedData.helpers.js +0 -119
  109. package/dist/ui/component-utilities/replaceNulls.js +0 -14
  110. package/dist/ui/component-utilities/tableUtils.ts +0 -120
  111. package/dist/ui/components/Area.svelte +0 -214
  112. package/dist/ui/components/Bar.svelte +0 -350
  113. package/dist/ui/components/Chart.svelte +0 -989
  114. package/dist/ui/components/ErrorChart.svelte +0 -118
  115. package/dist/ui/components/Line.svelte +0 -227
  116. package/dist/ui/internal/NavSidebar.svelte +0 -396
  117. package/dist/ui/internal/PageError.svelte +0 -23
  118. package/dist/ui/internal/checkSocket.ts +0 -48
  119. package/dist/ui/internal/theme.ts +0 -88
  120. package/dist/ui/public/inter-latin-ext.woff2 +0 -0
  121. package/dist/ui/public/inter-latin.woff2 +0 -0
@@ -2,8 +2,7 @@
2
2
  import chroma from 'chroma-js'
3
3
  import InlineDelta from './InlineDelta.svelte'
4
4
  import TableCell from './TableCell.svelte'
5
- import {safeExtractColumn} from '../component-utilities/tableUtils'
6
- import {formatValue, getFormatObjectFromString} from '../component-utilities/formatting.js'
5
+ import {formatFromField} from '../component-utilities/format.ts'
7
6
  import {getThemeStores} from '../component-utilities/themeStores'
8
7
 
9
8
  interface Props {
@@ -13,7 +12,7 @@
13
12
  rowNumbers?: boolean | string
14
13
  rowLines?: boolean | string
15
14
  index?: number
16
- columnSummary?: any[]
15
+ columnLookup?: Record<string, any>
17
16
  grouped?: boolean
18
17
  groupType?: 'accordion' | 'section'
19
18
  groupColumn?: string
@@ -26,7 +25,7 @@
26
25
  let {
27
26
  displayedData = [], rowShading: rowShadingProp = undefined, link = undefined,
28
27
  rowNumbers: rowNumbersProp = undefined, rowLines: rowLinesProp = undefined, index = 0,
29
- columnSummary = [], grouped = false, groupType = undefined, groupColumn = undefined,
28
+ columnLookup = {}, grouped = false, groupType = undefined, groupColumn = undefined,
30
29
  rowSpan = 1, groupNamePosition = 'middle', orderedColumns = [], compact: compactProp = undefined,
31
30
  }: Props = $props()
32
31
 
@@ -58,7 +57,7 @@
58
57
 
59
58
  try {
60
59
  return chroma.scale(column.colorScale).domain(domain)
61
- } catch (error) {
60
+ } catch(error) {
62
61
  console.warn('Unable to build color scale for column', column.id, error)
63
62
  return undefined
64
63
  }
@@ -124,10 +123,9 @@
124
123
  {/if}
125
124
 
126
125
  {#each orderedColumns as column, k (k)}
127
- {@const summary = safeExtractColumn(column, columnSummary)}
128
- {@const scaleSummary = column.scaleColumn ? columnSummary.find((d) => d.id === column.scaleColumn) : summary}
129
- {@const columnMin = column.colorMin ?? scaleSummary?.columnUnitSummary?.min}
130
- {@const columnMax = column.colorMax ?? scaleSummary?.columnUnitSummary?.max}
126
+ {@const scaleSummary = column.scaleColumn ? columnLookup[column.scaleColumn] : column}
127
+ {@const columnMin = column.colorMin ?? scaleSummary?.stats?.min}
128
+ {@const columnMax = column.colorMax ?? scaleSummary?.stats?.max}
131
129
  {@const colorScale = column.contentType === 'colorscale'
132
130
  ? computeColorScale(column, columnMin, columnMax)
133
131
  : undefined}
@@ -145,21 +143,15 @@
145
143
  if (contentContrast < backgroundContrast) return $theme.colors['base-100']
146
144
  return $theme.colors['base-content']
147
145
  })()}
148
- {@const columnFormat = (() => {
149
- if (column.fmt) return getFormatObjectFromString(column.fmt, summary.format?.valueType)
150
- if (column.fmtColumn && row[column.fmtColumn]) {
151
- return getFormatObjectFromString(row[column.fmtColumn], summary.format?.valueType)
152
- }
153
- return summary.format
154
- })()}
155
146
  {@const paddingLeft = k === 0 && grouped && groupType === 'accordion' && !rowNumbers ? '28px' : undefined}
156
- {@const shouldShow = !(groupType === 'section' && groupColumn === summary.id && i !== 0)}
147
+ {@const shouldShow = !(groupType === 'section' && groupColumn === column.id && i !== 0)}
157
148
  <TableCell
158
- class={summary?.type}
149
+ class={column?.type}
159
150
  {compact}
160
151
  verticalAlign={groupType === 'section' ? groupNamePosition : undefined}
161
- rowSpan={groupType === 'section' && groupColumn === summary.id && i === 0 ? rowSpan : 1}
152
+ rowSpan={groupType === 'section' && groupColumn === column.id && i === 0 ? rowSpan : 1}
162
153
  {paddingLeft}
154
+ align={column.align}
163
155
  wrap={column.wrap}
164
156
  cellColor={formattedColor}
165
157
  fontColor={fontColor}
@@ -185,21 +177,12 @@
185
177
  >
186
178
  {#if column.linkLabel != undefined}
187
179
  {#if row[column.linkLabel] != undefined}
188
- {@const labelSummary = safeExtractColumn({id: column.linkLabel}, columnSummary)}
189
- {formatValue(
190
- row[column.linkLabel],
191
- column.fmt ? getFormatObjectFromString(column.fmt, labelSummary.format?.valueType) : labelSummary.format,
192
- labelSummary.columnUnitSummary,
193
- )}
180
+ {formatFromField(columnLookup[column.linkLabel]?.field, row[column.linkLabel])}
194
181
  {:else}
195
182
  {column.linkLabel}
196
183
  {/if}
197
184
  {:else}
198
- {formatValue(
199
- row[column.id],
200
- column.fmt ? getFormatObjectFromString(column.fmt, summary.format?.valueType) : summary.format,
201
- summary.columnUnitSummary,
202
- )}
185
+ {formatFromField(column.field, row[column.id])}
203
186
  {/if}
204
187
  </a>
205
188
  {/if}
@@ -207,8 +190,7 @@
207
190
  <InlineDelta
208
191
  value={row[column.id]}
209
192
  downIsGood={column.downIsGood}
210
- formatObject={columnFormat}
211
- columnUnitSummary={summary.columnUnitSummary}
193
+ field={column.field}
212
194
  showValue={column.showValue}
213
195
  showSymbol={column.deltaSymbol}
214
196
  align={column.align}
@@ -217,13 +199,7 @@
217
199
  chip={column.chip}
218
200
  />
219
201
  {:else}
220
- {#if row[column.id] === null || row[column.id] === undefined}
221
-
222
- {:else if summary.type === 'number'}
223
- {formatValue(row[column.id], columnFormat, summary.columnUnitSummary)}
224
- {:else}
225
- {formatValue(row[column.id], columnFormat, summary.columnUnitSummary)}
226
- {/if}
202
+ {formatFromField(column.field, row[column.id])}
227
203
  {/if}
228
204
  </TableCell>
229
205
  {/each}
@@ -1,44 +1,53 @@
1
1
  <script lang="ts">
2
2
  import InlineDelta from './InlineDelta.svelte'
3
- import {aggregateColumn, safeExtractColumn} from '../component-utilities/tableUtils'
4
- import {formatValue, getFormatObjectFromString} from '../component-utilities/formatting.js'
3
+ import {summarizeColumn, type SummaryMetric} from '../component-utilities/dataSummary.ts'
4
+ import {formatFromField} from '../component-utilities/format.ts'
5
5
  import TableCell from './TableCell.svelte'
6
+ import {toBoolean} from '../component-utilities/inputUtils'
6
7
 
7
8
  interface Props {
8
9
  groupName?: string
9
10
  currentGroupData?: any[]
10
- columnSummary?: any[]
11
11
  rowColor?: string
12
12
  groupBy?: string
13
13
  groupType?: 'accordion' | 'section'
14
+ rowNumbers?: boolean | string
14
15
  fontColor?: string
15
16
  orderedColumns?: any[]
16
17
  compact?: boolean | string
17
18
  }
18
19
 
19
20
  let {
20
- groupName = undefined, currentGroupData = [], columnSummary = [], rowColor = undefined,
21
- groupBy = undefined, groupType = undefined, fontColor = undefined, orderedColumns = [], compact = undefined,
21
+ groupName = undefined, currentGroupData = [], rowColor = undefined,
22
+ groupBy = undefined, groupType = undefined, rowNumbers: rowNumbersProp = undefined,
23
+ fontColor = undefined, orderedColumns = [], compact = undefined,
22
24
  }: Props = $props()
25
+
26
+ let rowNumbers = $derived(toBoolean(rowNumbersProp) ?? false)
27
+
28
+ const SUPPORTED_METRICS: SummaryMetric[] = ['sum', 'mean', 'median', 'min', 'max', 'count', 'countDistinct']
29
+
30
+ const getAggregateValue = (rows: Record<string, unknown>[], column: any) => {
31
+ let metric = column?.totalAgg as SummaryMetric | undefined
32
+ if (!metric && String(column?.type || '').toLowerCase() === 'number') metric = 'sum'
33
+ if (!metric || !SUPPORTED_METRICS.includes(metric)) return '-'
34
+ let summary = summarizeColumn(rows, column.field ?? {name: column.id, type: column.type}, [metric])
35
+ return summary[metric] ?? null
36
+ }
23
37
  </script>
24
38
 
25
39
  <tr class="subtotal-row" style:background-color={rowColor} style:color={fontColor}>
40
+ {#if rowNumbers && groupType !== 'section'}
41
+ <TableCell class="index" {compact}></TableCell>
42
+ {/if}
26
43
  {#each orderedColumns as column (column.id)}
27
- {@const summary = safeExtractColumn(column, columnSummary)}
28
- {@const baseFormat = column.fmt ? getFormatObjectFromString(column.fmt, summary.format?.valueType) : summary.format}
29
- {@const format = (() => {
30
- if (column.subtotalFmt) return getFormatObjectFromString(column.subtotalFmt)
31
- if (column.totalFmt) return getFormatObjectFromString(column.totalFmt)
32
- return baseFormat
33
- })()}
34
- <TableCell class={summary.type} {compact} align={column.align}>
44
+ <TableCell class={column.type} {compact} align={column.align}>
35
45
  {#if column.id !== groupBy}
36
46
  {#if column.contentType === 'delta'}
37
47
  <InlineDelta
38
- value={aggregateColumn(currentGroupData, column.id, column.totalAgg, summary.type, column.weightCol)}
48
+ value={getAggregateValue(currentGroupData, column)}
39
49
  downIsGood={column.downIsGood}
40
- formatObject={baseFormat}
41
- columnUnitSummary={summary.columnUnitSummary}
50
+ field={column.field}
42
51
  showValue={column.showValue}
43
52
  showSymbol={column.deltaSymbol}
44
53
  align={column.align}
@@ -47,11 +56,7 @@
47
56
  chip={column.chip}
48
57
  />
49
58
  {:else}
50
- {formatValue(
51
- aggregateColumn(currentGroupData, column.id, column.totalAgg, summary.type, column.weightCol),
52
- format,
53
- summary.columnUnitSummary,
54
- )}
59
+ {formatFromField(column.field, getAggregateValue(currentGroupData, column))}
55
60
  {/if}
56
61
  {:else if groupType === 'section'}
57
62
  {groupName}
@@ -1,13 +1,12 @@
1
1
  <script lang="ts">
2
2
  import InlineDelta from './InlineDelta.svelte'
3
3
  import TableCell from './TableCell.svelte'
4
- import {safeExtractColumn, weightedMean} from '../component-utilities/tableUtils'
5
- import {formatValue, getFormatObjectFromString} from '../component-utilities/formatting.js'
4
+ import {summarizeColumn, type SummaryMetric} from '../component-utilities/dataSummary.ts'
5
+ import {formatFromField} from '../component-utilities/format.ts'
6
6
 
7
7
  interface Props {
8
8
  data?: any[]
9
9
  rowNumbers?: boolean | string
10
- columnSummary?: any[]
11
10
  rowColor?: string
12
11
  fontColor?: string
13
12
  groupType?: 'accordion' | 'section'
@@ -16,7 +15,7 @@
16
15
  }
17
16
 
18
17
  let {
19
- data = [], rowNumbers: rowNumbersProp = undefined, columnSummary = [], rowColor = undefined,
18
+ data = [], rowNumbers: rowNumbersProp = undefined, rowColor = undefined,
20
19
  fontColor = undefined, groupType = undefined, orderedColumns = [], compact: compactProp = undefined,
21
20
  }: Props = $props()
22
21
 
@@ -32,6 +31,16 @@
32
31
 
33
32
  let rowNumbers = $derived(toBool(rowNumbersProp))
34
33
  let compact = $derived(toBool(compactProp))
34
+
35
+ const SUPPORTED_METRICS: SummaryMetric[] = ['sum', 'mean', 'median', 'min', 'max', 'count', 'countDistinct']
36
+
37
+ const getAggregateValue = (rows: Record<string, unknown>[], column: any, aggType: string | undefined) => {
38
+ let metric = aggType as SummaryMetric | undefined
39
+ if (!metric && String(column?.type || '').toLowerCase() === 'number') metric = 'sum'
40
+ if (!metric || !SUPPORTED_METRICS.includes(metric)) return '-'
41
+ let summary = summarizeColumn(rows, column.field ?? {name: column.id, type: column.type}, [metric])
42
+ return summary[metric] ?? null
43
+ }
35
44
  </script>
36
45
 
37
46
  <tr class="total-row" style:background-color={rowColor} style:color={fontColor}>
@@ -40,49 +49,30 @@
40
49
  {/if}
41
50
 
42
51
  {#each orderedColumns as column (column.id)}
43
- {@const summary = safeExtractColumn(column, columnSummary)}
44
- {@const format = (() => {
45
- if (column.totalFmt) return getFormatObjectFromString(column.totalFmt)
46
- if (column.fmt) return getFormatObjectFromString(column.fmt, summary.format?.valueType)
47
- return summary.format
48
- })()}
49
52
  {@const totalAgg = column.totalAgg ?? 'sum'}
50
53
  <TableCell
51
54
  {compact}
52
- dataType={summary.type}
55
+ dataType={column.type}
53
56
  align={column.align}
54
57
  height={column.height}
55
58
  width={column.width}
56
59
  wrap={column.wrap}
57
60
  topBorder="1px solid rgba(107, 114, 128, 0.5)"
58
61
  >
59
- {#if ['sum', 'mean', 'weightedMean', 'median', 'min', 'max', 'count', 'countDistinct'].includes(totalAgg)}
60
- {#if column.contentType === 'delta'}
61
- <InlineDelta
62
- value={totalAgg === 'weightedMean' ? weightedMean(data, column.id, column.weightCol) : summary.columnUnitSummary?.[totalAgg]}
63
- downIsGood={column.downIsGood}
64
- formatObject={format}
65
- columnUnitSummary={summary.columnUnitSummary}
66
- showValue={column.showValue}
67
- showSymbol={column.deltaSymbol}
68
- align={column.align}
69
- neutralMin={column.neutralMin ?? 0}
70
- neutralMax={column.neutralMax ?? 0}
71
- chip={column.chip}
72
- />
73
- {:else}
74
- {formatValue(
75
- totalAgg === 'weightedMean' ? weightedMean(data, column.id, column.weightCol) : summary.columnUnitSummary?.[totalAgg],
76
- format,
77
- summary.columnUnitSummary,
78
- )}
79
- {/if}
62
+ {#if column.contentType === 'delta'}
63
+ <InlineDelta
64
+ value={getAggregateValue(data, column, totalAgg)}
65
+ downIsGood={column.downIsGood}
66
+ field={column.field}
67
+ showValue={column.showValue}
68
+ showSymbol={column.deltaSymbol}
69
+ align={column.align}
70
+ neutralMin={column.neutralMin ?? 0}
71
+ neutralMax={column.neutralMax ?? 0}
72
+ chip={column.chip}
73
+ />
80
74
  {:else}
81
- {#if column.totalFmt}
82
- {formatValue(totalAgg, format, summary.columnUnitSummary)}
83
- {:else}
84
- {totalAgg}
85
- {/if}
75
+ {formatFromField(column.field, getAggregateValue(data, column, totalAgg))}
86
76
  {/if}
87
77
  </TableCell>
88
78
  {/each}
@@ -1,5 +1,7 @@
1
1
  <script lang="ts">
2
+ import {onMount} from 'svelte'
2
3
  import {toBoolean} from '../component-utilities/inputUtils'
4
+ import {captureInitial, getPageInputs} from '../internal/pageInputs.svelte.js'
3
5
 
4
6
  interface Props {
5
7
  name: string
@@ -17,33 +19,31 @@
17
19
  placeholder = 'Type to search', defaultValue = undefined, hideDuringPrint = true, unsafe = false,
18
20
  }: Props = $props()
19
21
 
20
- // svelte-ignore state_referenced_locally - intentionally capturing initial value only
21
- let value = $state(defaultValue ?? '')
22
+ let pageInputs = getPageInputs()
23
+ let field = captureInitial(() => pageInputs.text(name))
22
24
 
23
25
  let hidePrint = $derived(toBoolean(hideDuringPrint))
24
26
  let allowUnsafe = $derived(toBoolean(unsafe))
25
27
  let displayLabel = $derived(title || label)
26
28
 
27
- // Push value changes to parent
28
- $effect(() => {
29
- pushValue(value)
29
+ onMount(() => {
30
+ if (!field.hasExternalValue) field.set(defaultValue ?? '')
31
+ return () => field.destroy()
30
32
  })
31
33
 
32
- function sanitize (input: string): string {
34
+ function sanitize(input: string): string {
33
35
  if (allowUnsafe) return input
34
36
  return input.replace(/'/g, "''")
35
37
  }
36
38
 
37
- function pushValue (input: string) {
39
+ function pushValue(input: string) {
38
40
  let trimmed = input ?? ''
39
- let _safe = sanitize(trimmed)
40
- let paramValue = trimmed === '' ? null : trimmed
41
- window.$GRAPHENE.updateParam(name, paramValue)
41
+ sanitize(trimmed)
42
+ field.set(trimmed)
42
43
  }
43
44
 
44
- function onInput (event: Event) {
45
- value = (event.currentTarget as HTMLInputElement).value
46
- pushValue(value)
45
+ function onInput(event: Event) {
46
+ pushValue((event.currentTarget as HTMLInputElement).value)
47
47
  }
48
48
  </script>
49
49
 
@@ -58,7 +58,7 @@
58
58
  id={`text-input-${name}`}
59
59
  class="text-input"
60
60
  type="text"
61
- value={value}
61
+ value={field.value}
62
62
  placeholder={placeholder}
63
63
  oninput={onInput}
64
64
  />
@@ -77,6 +77,7 @@
77
77
  }
78
78
  }
79
79
  .input-label {
80
+ font-family: var(--font-ui);
80
81
  font-size: 12px;
81
82
  font-weight: 600;
82
83
  color: var(--input-label-color, #374151);
@@ -91,5 +92,7 @@
91
92
  border-radius: 6px;
92
93
  border: 1px solid rgba(107, 114, 128, 0.4);
93
94
  font-size: 14px;
95
+ font-family: var(--font-ui);
96
+ font-synthesis: none;
94
97
  }
95
98
  </style>
@@ -0,0 +1,25 @@
1
+ <script lang="ts">
2
+ import QueryLoad from './QueryLoad.svelte'
3
+ import {formatFromField} from '../component-utilities/format.ts'
4
+ import type {QueryResult} from '../component-utilities/types.ts'
5
+
6
+ interface Props {
7
+ data: string | QueryResult
8
+ column: string
9
+ row?: number
10
+ }
11
+
12
+ let {data, column, row = 0}: Props = $props()
13
+
14
+ function formatValue(input: any, loaded: QueryResult) {
15
+ if (input === null || input === undefined) return '—'
16
+ let field = loaded?.fields?.find((entry: any) => entry?.name === column)
17
+ return formatFromField(field as any, input)
18
+ }
19
+ </script>
20
+
21
+ {#snippet valueContent(loaded: QueryResult)}
22
+ <span>{formatValue(loaded?.rows?.[row]?.[column], loaded)}</span>
23
+ {/snippet}
24
+
25
+ <QueryLoad {data} fields={{column}} inline children={valueContent} />