grist-widget-sdk 0.3.27 → 0.5.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/CHANGELOG.md +84 -0
- package/README.md +79 -208
- package/dist/app.cjs +1336 -4415
- package/dist/app.cjs.map +1 -1
- package/dist/app.d.cts +6 -103
- package/dist/app.d.ts +6 -103
- package/dist/app.js +5 -7
- package/dist/chunk-4ZGVKGDF.js +204 -0
- package/dist/chunk-4ZGVKGDF.js.map +1 -0
- package/dist/{chunk-6Y2IONGJ.js → chunk-LSALXIGM.js} +191 -20
- package/dist/chunk-LSALXIGM.js.map +1 -0
- package/dist/chunk-MAPAWVQC.js +1898 -0
- package/dist/chunk-MAPAWVQC.js.map +1 -0
- package/dist/{chunk-YQNMIL33.js → chunk-OXA2VITC.js} +532 -181
- package/dist/chunk-OXA2VITC.js.map +1 -0
- package/dist/define-widget-B1FIvI-h.d.cts +433 -0
- package/dist/define-widget-B9gEtJP0.d.ts +433 -0
- package/dist/emulator/testing.cjs +3341 -6512
- package/dist/emulator/testing.cjs.map +1 -1
- package/dist/emulator/testing.d.cts +29 -14
- package/dist/emulator/testing.d.ts +29 -14
- package/dist/emulator/testing.js +78 -72
- package/dist/emulator/testing.js.map +1 -1
- package/dist/emulator.cjs +63 -249
- package/dist/emulator.cjs.map +1 -1
- package/dist/emulator.d.cts +6 -8
- package/dist/emulator.d.ts +6 -8
- package/dist/emulator.js +5 -11
- package/dist/index.cjs +1442 -4862
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +81 -260
- package/dist/index.d.ts +81 -260
- package/dist/index.js +12 -158
- package/dist/mount-grist-widget-CkB-3iG_.d.ts +137 -0
- package/dist/mount-grist-widget-Dtelqao_.d.cts +137 -0
- package/dist/{inline-DpcT8tV9.d.ts → templates-CGmRIQBV.d.cts} +89 -35
- package/dist/{inline-C7DkvuET.d.cts → templates-Cq94qOcf.d.ts} +89 -35
- package/dist/{types-D3JxUCfL.d.cts → types-DBStn0Dk.d.cts} +2 -26
- package/dist/{types-D3JxUCfL.d.ts → types-DBStn0Dk.d.ts} +2 -26
- package/package.json +8 -37
- package/dist/advanced.cjs +0 -2799
- package/dist/advanced.cjs.map +0 -1
- package/dist/advanced.d.cts +0 -822
- package/dist/advanced.d.ts +0 -822
- package/dist/advanced.js +0 -872
- package/dist/advanced.js.map +0 -1
- package/dist/chunk-22U7WAY3.js +0 -463
- package/dist/chunk-22U7WAY3.js.map +0 -1
- package/dist/chunk-64SVRWW7.js +0 -758
- package/dist/chunk-64SVRWW7.js.map +0 -1
- package/dist/chunk-6Y2IONGJ.js.map +0 -1
- package/dist/chunk-B4AKVSWV.js +0 -2362
- package/dist/chunk-B4AKVSWV.js.map +0 -1
- package/dist/chunk-ELGVOHFD.js +0 -32
- package/dist/chunk-ELGVOHFD.js.map +0 -1
- package/dist/chunk-GTTD5HPO.js +0 -36
- package/dist/chunk-GTTD5HPO.js.map +0 -1
- package/dist/chunk-NO6FYX33.js +0 -2084
- package/dist/chunk-NO6FYX33.js.map +0 -1
- package/dist/chunk-OPTOYD2Y.js +0 -277
- package/dist/chunk-OPTOYD2Y.js.map +0 -1
- package/dist/chunk-PM3B4WYV.js +0 -12
- package/dist/chunk-PM3B4WYV.js.map +0 -1
- package/dist/chunk-REV5AUXD.js +0 -25
- package/dist/chunk-REV5AUXD.js.map +0 -1
- package/dist/chunk-YQNMIL33.js.map +0 -1
- package/dist/create-grist-emulator-BCqp1BF9.d.ts +0 -81
- package/dist/create-grist-emulator-DBM8OSIR.d.cts +0 -81
- package/dist/emulator/devtools.cjs +0 -1404
- package/dist/emulator/devtools.cjs.map +0 -1
- package/dist/emulator/devtools.d.cts +0 -48
- package/dist/emulator/devtools.d.ts +0 -48
- package/dist/emulator/devtools.js +0 -506
- package/dist/emulator/devtools.js.map +0 -1
- package/dist/emulator/transports.cjs +0 -1132
- package/dist/emulator/transports.cjs.map +0 -1
- package/dist/emulator/transports.d.cts +0 -38
- package/dist/emulator/transports.d.ts +0 -38
- package/dist/emulator/transports.js +0 -12
- package/dist/emulator/transports.js.map +0 -1
- package/dist/templates-8k2LKoO-.d.cts +0 -24
- package/dist/templates-DIwi_mvI.d.ts +0 -24
- package/dist/use-grist-reads-DUMvJgV7.d.ts +0 -480
- package/dist/use-grist-reads-DpjVuI0H.d.cts +0 -480
- package/dist/use-grist-types-DdOLEJXN.d.cts +0 -499
- package/dist/use-grist-types-kwxoFeub.d.ts +0 -499
- package/dist/use-grist-widget-options-from-context-CGOlQ5Vc.d.cts +0 -43
- package/dist/use-grist-widget-options-from-context-CGOlQ5Vc.d.ts +0 -43
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sdk/helpers/grist-value-codec.ts","../src/sdk/helpers/grist-widget-options.ts","../src/sdk/helpers/grist-safe-parse.ts","../src/sdk/helpers/grist-user-actions.ts"],"sourcesContent":["/**\n * Encoding helpers for Grist cell values.\n *\n * Grist sends some types as marshalled tuples or numeric epochs. This file\n * exposes pure decode/encode functions so widget code never has to spelunk\n * Grist's wire format.\n *\n * References: Grist `grist/RowRecord` and `grist/DocActions` typings.\n */\n\nimport type { GristReplicaColumn } from \"../types\"\n\n/** `[\"E\", \"ErrorClass\", \"message\", traceback?]` — Grist error sentinel. */\nexport type GristEncodedError = [\"E\", string, string?, string?]\n/** `[\"L\", ...items]` — list (used for ChoiceList, RefList, Attachments). */\nexport type GristEncodedList = [\"L\", ...unknown[]]\n/** `[\"D\", epochSeconds, \"tz/Name\"]` — DateTime with timezone. */\nexport type GristEncodedDateTime = [\"D\", number, string]\n/** `[\"d\", epochSeconds]` — Date (no time). */\nexport type GristEncodedDate = [\"d\", number]\n/** `[\"R\", tableId, rowId]` — explicit reference. */\nexport type GristEncodedRef = [\"R\", string, number]\n/** `[\"r\", rowId]` — bare reference (when table is contextual). */\nexport type GristEncodedBareRef = [\"r\", number]\n/** `[\"P\", encoded]` — pending marker. */\nexport type GristEncodedPending = [\"P\"]\n\nexport type GristDecodedValue =\n | null\n | string\n | number\n | boolean\n | Date\n | GristDecodedValue[]\n | { __error: true; type: string; message?: string; traceback?: string }\n | { __ref: true; tableId?: string; rowId: number }\n\nconst MARSHALLED_TAGS = new Set([\"E\", \"L\", \"D\", \"d\", \"R\", \"r\", \"P\"])\n\nfunction isMarshalledTuple(value: unknown): value is unknown[] {\n return (\n Array.isArray(value) &&\n typeof value[0] === \"string\" &&\n value[0].length <= 2 &&\n MARSHALLED_TAGS.has(value[0])\n )\n}\n\n/**\n * Normalises a Grist `fetchTable` cell that points at a row in another table.\n * Most payloads use a bare numeric row id, but `Ref:*` values may appear as\n * `[\"R\", tableId, rowId]` or `[\"r\", rowId]` (same shape as {@link decodeGristValue}).\n */\nexport function coerceGristDocApiRefRowId(value: unknown): number | undefined {\n if (typeof value === \"number\" && Number.isFinite(value)) return value\n if (!Array.isArray(value) || value.length < 2) return undefined\n const tag = value[0]\n if (tag === \"R\" && typeof value[2] === \"number\" && Number.isFinite(value[2])) return value[2]\n if (tag === \"r\" && typeof value[1] === \"number\" && Number.isFinite(value[1])) return value[1]\n return undefined\n}\n\nfunction looksLikeAttachmentColumn(column?: GristReplicaColumn): boolean {\n return column?.type === \"Attachments\"\n}\n\nfunction looksLikeChoiceListColumn(column?: GristReplicaColumn): boolean {\n return column?.type === \"ChoiceList\"\n}\n\nfunction looksLikeRefListColumn(column?: GristReplicaColumn): boolean {\n return typeof column?.type === \"string\" && column.type.startsWith(\"RefList:\")\n}\n\nfunction looksLikeRefColumn(column?: GristReplicaColumn): boolean {\n return typeof column?.type === \"string\" && column.type.startsWith(\"Ref:\")\n}\n\nfunction looksLikeDateColumn(column?: GristReplicaColumn): boolean {\n return column?.type === \"Date\"\n}\n\nfunction looksLikeDateTimeColumn(column?: GristReplicaColumn): boolean {\n return typeof column?.type === \"string\" && column.type.startsWith(\"DateTime\")\n}\n\n/**\n * Decodes a Grist cell value into an idiomatic JS value.\n *\n * Pass the column's metadata (from `useGristSchema` or `_grist_Tables_column`)\n * for type-aware decoding (e.g. `Date` columns return `Date` even when stored as a number).\n */\nexport function decodeGristValue(value: unknown, column?: GristReplicaColumn): GristDecodedValue {\n if (value === null || value === undefined) return null\n\n if (isMarshalledTuple(value)) {\n const tag = value[0] as string\n switch (tag) {\n case \"E\":\n return {\n __error: true,\n type: typeof value[1] === \"string\" ? value[1] : \"Error\",\n message: typeof value[2] === \"string\" ? value[2] : undefined,\n traceback: typeof value[3] === \"string\" ? value[3] : undefined,\n }\n case \"L\":\n return value.slice(1).map((v) => decodeGristValue(v, undefined)) as GristDecodedValue[]\n case \"D\":\n if (typeof value[1] === \"number\") return new Date(value[1] * 1000)\n return null\n case \"d\":\n if (typeof value[1] === \"number\") return new Date(value[1] * 1000)\n return null\n case \"R\":\n return {\n __ref: true,\n tableId: typeof value[1] === \"string\" ? value[1] : undefined,\n rowId: typeof value[2] === \"number\" ? value[2] : 0,\n }\n case \"r\":\n return { __ref: true, rowId: typeof value[1] === \"number\" ? value[1] : 0 }\n case \"P\":\n return null\n default:\n return null\n }\n }\n\n if (looksLikeDateColumn(column) || looksLikeDateTimeColumn(column)) {\n if (typeof value === \"number\" && Number.isFinite(value)) return new Date(value * 1000)\n }\n\n if (looksLikeRefColumn(column) && typeof value === \"number\") {\n return { __ref: true, rowId: value }\n }\n\n if ((looksLikeRefListColumn(column) || looksLikeChoiceListColumn(column) || looksLikeAttachmentColumn(column)) && Array.isArray(value)) {\n return value.map((v) => decodeGristValue(v, undefined)) as GristDecodedValue[]\n }\n\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") return value\n if (Array.isArray(value)) return value.map((v) => decodeGristValue(v, undefined)) as GristDecodedValue[]\n return null\n}\n\n/** Convenience: true when the cell is a Grist error sentinel. */\nexport function isGristCellError(value: unknown): value is GristEncodedError {\n return Array.isArray(value) && value[0] === \"E\"\n}\n\n/**\n * Encodes a JS value into Grist's expected wire form for a given column type.\n *\n * Use before passing values to `applyUserActions` or `TableOperations.update`\n * for `Date`, `DateTime`, `Ref`, `RefList`, and `ChoiceList` columns.\n */\nexport function encodeGristValue(value: unknown, column?: GristReplicaColumn): unknown {\n if (value === null || value === undefined) return null\n\n if (looksLikeDateColumn(column) || looksLikeDateTimeColumn(column)) {\n if (value instanceof Date) return Math.floor(value.getTime() / 1000)\n if (typeof value === \"string\") {\n const parsed = Date.parse(value)\n if (!Number.isNaN(parsed)) return Math.floor(parsed / 1000)\n }\n if (typeof value === \"number\") return Math.floor(value)\n }\n\n if (looksLikeRefColumn(column)) {\n if (typeof value === \"number\") return value\n if (value && typeof value === \"object\" && \"rowId\" in value) {\n return (value as { rowId: number }).rowId\n }\n }\n\n if (looksLikeRefListColumn(column) || looksLikeChoiceListColumn(column) || looksLikeAttachmentColumn(column)) {\n if (Array.isArray(value)) {\n const items = value.map((v) => {\n if (v && typeof v === \"object\" && \"rowId\" in v) return (v as { rowId: number }).rowId\n return v\n })\n return [\"L\", ...items]\n }\n }\n\n return value\n}\n","/**\n * Grist stores column widget configuration in `_grist_Tables_column.widgetOptions`\n * as a JSON string. Choice fields use `choices: string[]` plus optional\n * `choiceOptions: Record<string, Style>` (e.g. `fillColor`, `textColor`).\n *\n * @see https://github.com/gristlabs/grist-core/blob/main/app/client/widgets/ChoiceEditor.js\n */\n\n/** One selectable choice for UI (value stored in the cell is `value`). */\nexport type GristChoiceListEntry = {\n value: string\n label: string\n fillColor?: string\n textColor?: string\n}\n\n/**\n * Parse a cell value from `_grist_Tables_column.widgetOptions` into a plain object.\n */\nexport function parseGristWidgetOptionsCell(raw: unknown): Record<string, unknown> | undefined {\n if (raw == null || raw === \"\") return undefined\n if (typeof raw === \"string\") {\n try {\n const parsed: unknown = JSON.parse(raw)\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>\n }\n } catch {\n return undefined\n }\n return undefined\n }\n if (typeof raw === \"object\" && !Array.isArray(raw)) {\n return raw as Record<string, unknown>\n }\n return undefined\n}\n\nfunction readStyleColor(style: Record<string, unknown>, key: string): string | undefined {\n const v = style[key]\n return typeof v === \"string\" ? v : undefined\n}\n\n/**\n * Normalizes Grist Choice / ChoiceList widgetOptions into a flat list for dropdowns.\n * `choices` entries are string labels (the stored cell value). Per-choice styling\n * lives in `choiceOptions[label]`.\n */\nexport function normalizeGristChoiceListEntries(\n widgetOptions: Record<string, unknown> | undefined\n): GristChoiceListEntry[] {\n if (!widgetOptions) return []\n const rawChoices = widgetOptions.choices\n if (!Array.isArray(rawChoices)) return []\n\n const choiceOptionsRaw = widgetOptions.choiceOptions\n const choiceOptions: Record<string, Record<string, unknown>> =\n choiceOptionsRaw &&\n typeof choiceOptionsRaw === \"object\" &&\n !Array.isArray(choiceOptionsRaw)\n ? (choiceOptionsRaw as Record<string, Record<string, unknown>>)\n : {}\n\n const out: GristChoiceListEntry[] = []\n for (const c of rawChoices) {\n const value = typeof c === \"string\" ? c : c != null ? String(c) : \"\"\n if (!value) continue\n const style = choiceOptions[value] ?? {}\n out.push({\n value,\n label: value,\n fillColor: readStyleColor(style, \"fillColor\"),\n textColor: readStyleColor(style, \"textColor\"),\n })\n }\n return out\n}\n","import { z, type ZodType } from \"zod\"\n\nimport type { GristReplicaColumn, GristRowRecord } from \"../types\"\nimport type { GristColumnarTable } from \"./grist-table-data\"\nimport { normalizeGristChoiceListEntries, type GristChoiceListEntry } from \"./grist-widget-options\"\nimport { decodeGristValue, type GristDecodedValue } from \"./grist-value-codec\"\n\nexport type GristSafeParseIssueCode =\n | \"grist_error\"\n | \"invalid_format\"\n | \"type_mismatch\"\n | \"helper_mismatch\"\n | \"zod_error\"\n\nexport type GristSafeParseIssue = {\n code: GristSafeParseIssueCode\n message: string\n}\n\nexport type GristSafeRefValue = {\n rowId: number\n display?: string | null\n}\n\nexport type GristSafeRefListValue = {\n rowIds: number[]\n displays?: string[]\n}\n\nexport const gristSafeRefValueSchema = z.object({\n rowId: z.number(),\n display: z.string().nullable().optional(),\n})\n\nexport const gristSafeRefListValueSchema = z.object({\n rowIds: z.array(z.number()),\n displays: z.array(z.string()).optional(),\n})\n\nexport const gristCellValueSchema = z.union([\n z.null(),\n z.string(),\n z.number(),\n z.boolean(),\n z.date(),\n z.array(z.unknown()),\n gristSafeRefValueSchema,\n gristSafeRefListValueSchema,\n])\n\nexport type GristCellValue = z.infer<typeof gristCellValueSchema>\n\nexport type GristSafeParseCellResult<TValue = unknown> = {\n ok: boolean\n typedValue: TValue | null\n displayValue: unknown\n raw: unknown\n issues: GristSafeParseIssue[]\n}\n\ntype RefMode = \"id\" | \"detailed\"\n\nexport type SafeParseGristValuesOptions<TValue = unknown> = {\n values: readonly unknown[]\n column?: GristReplicaColumn\n helperValues?: readonly unknown[]\n schema?: ZodType<TValue>\n fallbackUntypedToString?: boolean\n refMode?: RefMode\n}\n\nexport type SafeParseGristTableDataOptions = {\n columns?: Record<string, GristReplicaColumn>\n displayHelpersByRef?: Record<string, string>\n order?: \"none\" | \"id\" | \"grist\"\n fallbackUntypedToString?: boolean\n refMode?: RefMode\n}\n\nexport type GristSafeTableCellIssue = GristSafeParseIssue & {\n rowIndex: number\n colId: string\n}\n\nexport type GristSafeChoiceTokenMeta = {\n value: string\n label: string\n fillColor?: string\n textColor?: string\n valid: boolean\n}\n\nexport type GristSafeTableCellMeta = {\n rowIndex: number\n colId: string\n ok: boolean\n issues: GristSafeParseIssue[]\n choiceTokens?: GristSafeChoiceTokenMeta[]\n}\n\nexport type SafeParseGristTableDataResult<TRow extends Record<string, unknown> = Record<string, unknown>> = {\n rows: GristRowRecord<TRow>[]\n cellIssues: GristSafeTableCellIssue[]\n cellMeta: GristSafeTableCellMeta[]\n cellMetaByKey: Record<string, GristSafeTableCellMeta>\n cellResultsByColumn: Record<string, GristSafeParseCellResult[]>\n}\n\n/** Maps `Ref:*` / `RefList:*` column ids to their paired `gristHelper_*` column id (same rules as safe-parse). */\nexport function inferDisplayHelpersByRef(\n columns: Record<string, GristReplicaColumn>\n): Record<string, string> {\n const out: Record<string, string> = {}\n const helperColumns = Object.entries(columns).filter(([colId]) =>\n colId.startsWith(\"gristHelper_\")\n )\n const usedHelpers = new Set<string>()\n const colRefToColId = new Map<number, string>()\n for (const [colId, col] of Object.entries(columns)) {\n if (typeof col?.colRef === \"number\" && Number.isFinite(col.colRef)) {\n colRefToColId.set(col.colRef, colId)\n }\n }\n for (const [colId, col] of Object.entries(columns)) {\n const type = col?.type\n if (typeof type !== \"string\" || (!type.startsWith(\"Ref:\") && !type.startsWith(\"RefList:\"))) {\n continue\n }\n if (typeof col.displayColRef === \"number\" && Number.isFinite(col.displayColRef)) {\n const helperColId = colRefToColId.get(col.displayColRef)\n if (helperColId) {\n out[colId] = helperColId\n usedHelpers.add(helperColId)\n continue\n }\n }\n const match = helperColumns.find(([, helper]) => {\n const formula = helper?.formula\n return typeof formula === \"string\" && (formula.includes(`$${colId}.`) || formula.includes(`$${colId}`))\n })\n if (match) {\n out[colId] = match[0]\n usedHelpers.add(match[0])\n }\n }\n\n // Secondary fallback for schemas where helper formulas are unavailable:\n // pair unresolved Ref/RefList columns with nearest following gristHelper_*.\n const unresolvedRefs = Object.entries(columns)\n .filter(([colId, col]) => {\n const type = col?.type\n return (\n !out[colId] &&\n typeof type === \"string\" &&\n (type.startsWith(\"Ref:\") || type.startsWith(\"RefList:\"))\n )\n })\n .sort((a, b) => (a[1]?.parentPos ?? Number.MAX_SAFE_INTEGER) - (b[1]?.parentPos ?? Number.MAX_SAFE_INTEGER))\n const helperByPos = helperColumns\n .filter(([helperId]) => !usedHelpers.has(helperId))\n .sort((a, b) => (a[1]?.parentPos ?? Number.MAX_SAFE_INTEGER) - (b[1]?.parentPos ?? Number.MAX_SAFE_INTEGER))\n for (const [refId, refCol] of unresolvedRefs) {\n const refPos = refCol?.parentPos ?? Number.MAX_SAFE_INTEGER\n const candidate = helperByPos.find(([, helperCol]) => {\n const helperPos = helperCol?.parentPos ?? Number.MAX_SAFE_INTEGER\n return helperPos > refPos\n })\n if (!candidate) continue\n out[refId] = candidate[0]\n usedHelpers.add(candidate[0])\n }\n // If multiple unresolved refs remain, greedily map by order.\n for (const [refId] of unresolvedRefs) {\n if (out[refId]) continue\n const candidate = helperByPos.find(([helperId]) => !usedHelpers.has(helperId))\n if (!candidate) continue\n out[refId] = candidate[0]\n usedHelpers.add(candidate[0])\n }\n return out\n}\n\nfunction computeRowCount(data: Record<string, unknown[]>): number {\n const idCol = data.id\n if (Array.isArray(idCol)) return idCol.length\n for (const key of Object.keys(data)) {\n const col = data[key]\n if (Array.isArray(col)) return col.length\n }\n return 0\n}\n\nfunction manualSortKey(row: Record<string, unknown>): number | null {\n const v = row.manualSort\n if (typeof v === \"number\" && !Number.isNaN(v)) return v\n if (typeof v === \"string\" && v.trim() !== \"\") {\n const n = Number(v)\n if (!Number.isNaN(n)) return n\n }\n return null\n}\n\nfunction sortRowsByGristOrder<T = Record<string, unknown>>(\n rows: readonly GristRowRecord<T>[]\n): GristRowRecord<T>[] {\n const hasManual = rows.some((r) => manualSortKey(r as Record<string, unknown>) !== null)\n if (!hasManual) {\n return [...rows].sort((a, b) => {\n const ida = typeof a.id === \"number\" ? a.id : 0\n const idb = typeof b.id === \"number\" ? b.id : 0\n return ida - idb\n })\n }\n return [...rows].sort((a, b) => {\n const ma = manualSortKey(a as Record<string, unknown>)\n const mb = manualSortKey(b as Record<string, unknown>)\n if (ma !== null && mb !== null && ma !== mb) return ma - mb\n if (ma !== null && mb === null) return -1\n if (ma === null && mb !== null) return 1\n const ida = typeof a.id === \"number\" ? a.id : 0\n const idb = typeof b.id === \"number\" ? b.id : 0\n return ida - idb\n })\n}\n\nfunction columnKind(column?: GristReplicaColumn):\n | \"text\"\n | \"numeric\"\n | \"int\"\n | \"bool\"\n | \"date\"\n | \"datetime\"\n | \"choice\"\n | \"choiceList\"\n | \"ref\"\n | \"refList\"\n | \"attachments\"\n | \"any\"\n | \"unknown\" {\n const type = column?.type\n if (!type) return \"unknown\"\n if (type === \"Text\") return \"text\"\n if (type === \"Numeric\") return \"numeric\"\n if (type === \"Int\") return \"int\"\n if (type === \"Bool\") return \"bool\"\n if (type === \"Date\") return \"date\"\n if (type === \"DateTime\" || type.startsWith(\"DateTime:\")) return \"datetime\"\n if (type === \"Choice\") return \"choice\"\n if (type === \"ChoiceList\") return \"choiceList\"\n if (type.startsWith(\"Ref:\")) return \"ref\"\n if (type.startsWith(\"RefList:\")) return \"refList\"\n if (type === \"Attachments\") return \"attachments\"\n if (type === \"Any\") return \"any\"\n return \"unknown\"\n}\n\nfunction primitiveToString(value: unknown): string | null {\n if (value === null || value === undefined) return null\n if (typeof value === \"string\") return value\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") {\n return String(value)\n }\n return null\n}\n\nfunction normalizeRefDisplay(value: unknown): { value?: string | null; issue?: GristSafeParseIssue } {\n if (value === null || value === undefined) return { value: null }\n if (typeof value === \"string\") return { value }\n if (typeof value === \"number\" || typeof value === \"boolean\") return { value: String(value) }\n return {\n issue: {\n code: \"helper_mismatch\",\n message: \"Ref display helper value should be a scalar value.\",\n },\n }\n}\n\nfunction normalizeRefListDisplays(value: unknown): { values?: string[]; issue?: GristSafeParseIssue } {\n if (value === null || value === undefined) return { values: [] }\n if (typeof value === \"string\") {\n const s = value.trim()\n if (s === \"\") return { values: [] }\n if (s.startsWith(\"[\")) {\n try {\n const parsed = JSON.parse(s)\n if (Array.isArray(parsed)) {\n return normalizeRefListDisplays(parsed)\n }\n } catch {\n // Keep existing error below for non-array/non-JSON helper strings.\n }\n }\n }\n if (!Array.isArray(value)) {\n return {\n issue: {\n code: \"helper_mismatch\",\n message: \"RefList display helper value should be an array.\",\n },\n }\n }\n // Grist list wire format may leak through as [\"L\", ...items].\n // Treat a leading \"L\" marker as metadata, not a display label.\n const items =\n value.length > 0 && value[0] === \"L\"\n ? value.slice(1)\n : value\n const out: string[] = []\n for (const item of items) {\n const s = primitiveToString(item)\n if (s === null) {\n return {\n issue: {\n code: \"helper_mismatch\",\n message: \"RefList helper items should be scalar values.\",\n },\n }\n }\n out.push(s)\n }\n return { values: out }\n}\n\nfunction normalizeRefValue(\n decoded: GristDecodedValue,\n helperValue: unknown,\n refMode: RefMode\n): { value: number | GristSafeRefValue | null; issues: GristSafeParseIssue[] } {\n const issues: GristSafeParseIssue[] = []\n if (decoded === null) return { value: null, issues }\n\n const rowId =\n typeof decoded === \"number\" && Number.isFinite(decoded)\n ? decoded\n : decoded && typeof decoded === \"object\" && \"__ref\" in decoded\n ? (decoded as { rowId: number }).rowId\n : null\n\n // Grist empty refs can surface as 0; treat as empty cell.\n if (rowId === 0) return { value: null, issues }\n if (rowId === null || !Number.isFinite(rowId)) {\n issues.push({\n code: \"type_mismatch\",\n message: \"Expected a Ref row id.\",\n })\n return { value: null, issues }\n }\n\n if (refMode === \"id\") return { value: rowId, issues }\n\n const helper = normalizeRefDisplay(helperValue)\n if (helper.issue) issues.push(helper.issue)\n return {\n value: { rowId, display: helper.value },\n issues,\n }\n}\n\nfunction normalizeRefListValue(\n decoded: GristDecodedValue,\n helperValue: unknown,\n refMode: RefMode\n): { value: number[] | GristSafeRefListValue | null; issues: GristSafeParseIssue[] } {\n const issues: GristSafeParseIssue[] = []\n if (decoded === null) return { value: null, issues }\n if (!Array.isArray(decoded)) {\n issues.push({\n code: \"type_mismatch\",\n message: \"Expected an array for RefList.\",\n })\n return { value: null, issues }\n }\n\n const rowIds: number[] = []\n for (const item of decoded) {\n if (typeof item === \"number\" && Number.isFinite(item) && item !== 0) {\n rowIds.push(item)\n continue\n }\n if (item && typeof item === \"object\" && \"__ref\" in item) {\n const rowId = (item as { rowId: number }).rowId\n if (typeof rowId === \"number\" && Number.isFinite(rowId) && rowId !== 0) {\n rowIds.push(rowId)\n continue\n }\n }\n issues.push({\n code: \"type_mismatch\",\n message: \"RefList items should be row ids.\",\n })\n return { value: null, issues }\n }\n\n if (refMode === \"id\") return { value: rowIds, issues }\n\n const helper = normalizeRefListDisplays(helperValue)\n if (helper.issue) {\n issues.push(helper.issue)\n } else if (helper.values && helper.values.length > 0 && helper.values.length !== rowIds.length) {\n issues.push({\n code: \"helper_mismatch\",\n message: \"RefList helper labels count does not match row ids count.\",\n })\n }\n return {\n value: { rowIds, displays: helper.values },\n issues,\n }\n}\n\nfunction normalizeByColumnKind(\n decoded: GristDecodedValue,\n kind: ReturnType<typeof columnKind>,\n helperValue: unknown,\n fallbackUntypedToString: boolean,\n refMode: RefMode\n): { value: unknown; issues: GristSafeParseIssue[] } {\n const issues: GristSafeParseIssue[] = []\n if (decoded && typeof decoded === \"object\" && \"__error\" in decoded) {\n issues.push({\n code: \"grist_error\",\n message: (decoded as { message?: string }).message ?? \"Grist returned a cell error.\",\n })\n return { value: null, issues }\n }\n\n switch (kind) {\n case \"ref\":\n return normalizeRefValue(decoded, helperValue, refMode)\n case \"refList\":\n return normalizeRefListValue(decoded, helperValue, refMode)\n case \"date\":\n case \"datetime\":\n if (decoded === null || decoded instanceof Date) return { value: decoded, issues }\n issues.push({ code: \"type_mismatch\", message: \"Expected a Date value.\" })\n return { value: null, issues }\n case \"bool\":\n if (decoded === null || typeof decoded === \"boolean\") return { value: decoded, issues }\n issues.push({ code: \"type_mismatch\", message: \"Expected a boolean value.\" })\n return { value: null, issues }\n case \"numeric\":\n if (decoded === null || (typeof decoded === \"number\" && Number.isFinite(decoded))) {\n return { value: decoded, issues }\n }\n issues.push({ code: \"type_mismatch\", message: \"Expected a numeric value.\" })\n return {\n value:\n typeof decoded === \"string\" ||\n typeof decoded === \"number\" ||\n typeof decoded === \"boolean\"\n ? decoded\n : null,\n issues,\n }\n case \"int\":\n if (decoded === null || (typeof decoded === \"number\" && Number.isInteger(decoded))) {\n return { value: decoded, issues }\n }\n issues.push({ code: \"type_mismatch\", message: \"Expected an integer value.\" })\n return {\n value:\n typeof decoded === \"string\" ||\n typeof decoded === \"number\" ||\n typeof decoded === \"boolean\"\n ? decoded\n : null,\n issues,\n }\n case \"choice\":\n case \"text\":\n if (decoded === null || typeof decoded === \"string\") return { value: decoded, issues }\n issues.push({ code: \"type_mismatch\", message: \"Expected a string value.\" })\n return { value: null, issues }\n case \"choiceList\":\n case \"attachments\":\n if (decoded === null || Array.isArray(decoded)) return { value: decoded, issues }\n issues.push({ code: \"type_mismatch\", message: \"Expected a list value.\" })\n return { value: null, issues }\n case \"any\":\n case \"unknown\":\n // Heuristic fallback: when schema typing is missing but a helper column is\n // attached, infer Ref/RefList from the decoded shape.\n if (helperValue !== undefined) {\n if (typeof decoded === \"number\" || (decoded && typeof decoded === \"object\" && \"__ref\" in decoded)) {\n return normalizeRefValue(decoded, helperValue, refMode)\n }\n if (Array.isArray(decoded)) {\n return normalizeRefListValue(decoded, helperValue, refMode)\n }\n }\n if (!fallbackUntypedToString) return { value: decoded, issues }\n if (decoded === null) return { value: null, issues }\n if (typeof decoded === \"string\") return { value: decoded, issues }\n if (\n typeof decoded === \"number\" ||\n typeof decoded === \"boolean\" ||\n decoded instanceof Date\n ) {\n return {\n value: decoded instanceof Date ? decoded.toISOString() : String(decoded),\n issues,\n }\n }\n if (Array.isArray(decoded)) {\n try {\n return { value: JSON.stringify(decoded), issues }\n } catch {\n issues.push({\n code: \"invalid_format\",\n message: \"Unable to stringify list value.\",\n })\n return { value: null, issues }\n }\n }\n issues.push({\n code: \"type_mismatch\",\n message: \"Untyped value could not be represented as a string.\",\n })\n return { value: null, issues }\n }\n}\n\nfunction buildChoiceTokens(\n col: GristReplicaColumn | undefined,\n value: unknown\n): GristSafeChoiceTokenMeta[] | undefined {\n const type = col?.type\n if (type !== \"Choice\" && type !== \"ChoiceList\") return undefined\n const entries = normalizeGristChoiceListEntries(col?.widgetOptions)\n const byValue = new Map<string, GristChoiceListEntry>(entries.map((entry) => [entry.value, entry]))\n\n if (type === \"Choice\") {\n if (value == null || typeof value !== \"string\" || value.trim() === \"\") return []\n const meta = byValue.get(value)\n if (!meta) return [{ value, label: value, valid: false }]\n return [\n {\n value,\n label: meta.label,\n fillColor: meta.fillColor,\n textColor: meta.textColor,\n valid: true,\n },\n ]\n }\n\n if (!Array.isArray(value)) return []\n const out: GristSafeChoiceTokenMeta[] = []\n for (const item of value) {\n const v = typeof item === \"string\" ? item : String(item)\n const meta = byValue.get(v)\n if (!meta) {\n out.push({ value: v, label: v, valid: false })\n continue\n }\n out.push({\n value: v,\n label: meta.label,\n fillColor: meta.fillColor,\n textColor: meta.textColor,\n valid: true,\n })\n }\n return out\n}\n\nexport function safeParseGristValues<TValue = unknown>(\n options: SafeParseGristValuesOptions<TValue>\n): GristSafeParseCellResult<TValue>[] {\n const fallbackUntypedToString = options.fallbackUntypedToString ?? true\n const refMode = options.refMode ?? \"id\"\n const kind = columnKind(options.column)\n return options.values.map((raw, index) => {\n const decoded = decodeGristValue(raw, options.column)\n const helperValue = options.helperValues?.[index]\n const normalized = normalizeByColumnKind(\n decoded,\n kind,\n helperValue,\n fallbackUntypedToString,\n refMode\n )\n const issues = [...normalized.issues]\n\n if (options.schema) {\n const result = options.schema.safeParse(normalized.value)\n if (!result.success) {\n issues.push({\n code: \"zod_error\",\n message: result.error.issues.map((issue) => issue.message).join(\"; \"),\n })\n }\n }\n\n return {\n ok: issues.length === 0,\n typedValue: normalized.value as TValue | null,\n displayValue: normalized.value,\n raw,\n issues,\n }\n })\n}\n\nexport function safeParseGristTableData<TRow extends Record<string, unknown> = Record<string, unknown>>(\n data: GristColumnarTable,\n options?: SafeParseGristTableDataOptions\n): SafeParseGristTableDataResult<TRow> {\n const columns = options?.columns ?? {}\n const inferredDisplayHelpersByRef = inferDisplayHelpersByRef(columns)\n const displayHelpersByRef: Record<string, string> = {\n ...inferredDisplayHelpersByRef,\n ...(options?.displayHelpersByRef ?? {}),\n }\n // Fallback convention: if `owner` exists and `gristHelper_owner` is fetched,\n // use it as display helper even when formula metadata is unavailable.\n for (const [colId, col] of Object.entries(columns)) {\n const type = col?.type\n if (typeof type !== \"string\" || (!type.startsWith(\"Ref:\") && !type.startsWith(\"RefList:\"))) {\n continue\n }\n if (displayHelpersByRef[colId]) continue\n const byName = `gristHelper_${colId}`\n if (Array.isArray(data[byName])) {\n displayHelpersByRef[colId] = byName\n }\n }\n const fallbackUntypedToString = options?.fallbackUntypedToString ?? true\n const refMode = options?.refMode ?? \"id\"\n const colIds = Object.keys(data)\n const parsedByColumn: Record<string, GristSafeParseCellResult[]> = {}\n\n for (const colId of colIds) {\n const rawValues = Array.isArray(data[colId]) ? data[colId] : []\n const helperColId = displayHelpersByRef[colId]\n const helperValues = helperColId && Array.isArray(data[helperColId]) ? data[helperColId] : undefined\n parsedByColumn[colId] =\n colId === \"id\"\n ? rawValues.map((raw) => ({\n ok: typeof raw === \"number\" && Number.isFinite(raw),\n typedValue: typeof raw === \"number\" && Number.isFinite(raw) ? raw : null,\n displayValue: raw,\n raw,\n issues:\n typeof raw === \"number\" && Number.isFinite(raw)\n ? []\n : [{ code: \"type_mismatch\", message: \"Row id should be numeric.\" }],\n }))\n : safeParseGristValues({\n values: rawValues,\n column: columns[colId],\n helperValues,\n fallbackUntypedToString,\n refMode,\n })\n }\n\n const rowCount = computeRowCount(data)\n const rows: GristRowRecord<TRow>[] = []\n const cellIssues: GristSafeTableCellIssue[] = []\n const cellMeta: GristSafeTableCellMeta[] = []\n for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {\n const row: Record<string, unknown> = {}\n for (const colId of colIds) {\n const parsed = parsedByColumn[colId]?.[rowIndex]\n row[colId] = parsed?.typedValue ?? null\n const choiceTokens = buildChoiceTokens(columns[colId], parsed?.displayValue)\n if (parsed) {\n if (parsed.issues.length > 0 || (choiceTokens && choiceTokens.length > 0)) {\n cellMeta.push({\n rowIndex,\n colId,\n ok: parsed.ok,\n issues: parsed.issues,\n choiceTokens,\n })\n }\n }\n if (!parsed || parsed.issues.length === 0) continue\n for (const issue of parsed.issues) {\n cellIssues.push({ ...issue, rowIndex, colId })\n }\n }\n rows.push(row as GristRowRecord<TRow>)\n }\n\n const cellMetaByKey: Record<string, GristSafeTableCellMeta> = {}\n for (const meta of cellMeta) {\n const rowId = rows[meta.rowIndex]?.id\n if (typeof rowId !== \"number\") continue\n cellMetaByKey[`${rowId}:${meta.colId}`] = meta\n }\n\n const order = options?.order ?? \"grist\"\n if (order === \"none\") {\n return { rows, cellIssues, cellMeta, cellMetaByKey, cellResultsByColumn: parsedByColumn }\n }\n if (order === \"id\") {\n return {\n rows: [...rows].sort((a, b) => {\n const ida = typeof a.id === \"number\" ? a.id : 0\n const idb = typeof b.id === \"number\" ? b.id : 0\n return ida - idb\n }),\n cellIssues,\n cellMeta,\n cellMetaByKey,\n cellResultsByColumn: parsedByColumn,\n }\n }\n return {\n rows: sortRowsByGristOrder(rows),\n cellIssues,\n cellMeta,\n cellMetaByKey,\n cellResultsByColumn: parsedByColumn,\n }\n}\n","/**\n * Grist `docApi.applyUserActions` payloads are arrays of user-action tuples.\n * @see https://support.getgrist.com/code/interfaces/grist_plugin_api.GristDocAPI/#applyuseractions\n */\n\nexport type GristUserActionTuple = unknown[]\n\n/** `[\"UpdateRecord\", tableId, rowId, { col: value, ... }]` */\nexport function gristUpdateRecordAction(\n tableId: string,\n rowId: number,\n patch: Record<string, unknown>\n): GristUserActionTuple {\n return [\"UpdateRecord\", tableId, rowId, patch]\n}\n\n/** `[\"AddRecord\", tableId, null, { col: value, ... }]` */\nexport function gristAddRecordAction(tableId: string, values: Record<string, unknown>): GristUserActionTuple {\n return [\"AddRecord\", tableId, null, values]\n}\n\n/** `[\"RemoveRecord\", tableId, rowId]` */\nexport function gristRemoveRecordAction(tableId: string, rowId: number): GristUserActionTuple {\n return [\"RemoveRecord\", tableId, rowId]\n}\n\n/** `[\"BulkUpdateRecord\", tableId, rowIds, { col: value[], ... }]` — column arrays must align with `rowIds`. */\nexport function gristBulkUpdateRecordAction(\n tableId: string,\n rowIds: number[],\n columnarPatch: Record<string, unknown[]>\n): GristUserActionTuple {\n return [\"BulkUpdateRecord\", tableId, rowIds, columnarPatch]\n}\n\n/**\n * `[\"BulkAddRecord\", tableId, rowIds | nullArray, { col: value[], ... }]`.\n * Pass `null` (or omit) for `rowIds` to let Grist allocate ids; in user-action\n * format Grist expects an array of nulls of the same length as the value arrays.\n */\nexport function gristBulkAddRecordAction(\n tableId: string,\n values: Record<string, unknown[]>,\n rowIds?: Array<number | null>\n): GristUserActionTuple {\n const length = inferBulkLength(values)\n const ids = rowIds ?? new Array<number | null>(length).fill(null)\n return [\"BulkAddRecord\", tableId, ids, values]\n}\n\n/** `[\"BulkRemoveRecord\", tableId, rowIds]` */\nexport function gristBulkRemoveRecordAction(tableId: string, rowIds: number[]): GristUserActionTuple {\n return [\"BulkRemoveRecord\", tableId, rowIds]\n}\n\n/** `[\"AddColumn\", tableId, colId, colInfo]` — `colInfo` shape depends on Grist version / column type. */\nexport function gristAddColumnAction(tableId: string, colId: string, colInfo: Record<string, unknown>): GristUserActionTuple {\n return [\"AddColumn\", tableId, colId, colInfo]\n}\n\n/** `[\"AddVisibleColumn\", tableId, colId, colInfo]` — like `AddColumn` but also adds the column to the current view section. */\nexport function gristAddVisibleColumnAction(tableId: string, colId: string, colInfo: Record<string, unknown>): GristUserActionTuple {\n return [\"AddVisibleColumn\", tableId, colId, colInfo]\n}\n\n/** `[\"RenameColumn\", tableId, colId, newColId]` */\nexport function gristRenameColumnAction(tableId: string, colId: string, newColId: string): GristUserActionTuple {\n return [\"RenameColumn\", tableId, colId, newColId]\n}\n\n/** `[\"ModifyColumn\", tableId, colId, colInfo]` */\nexport function gristModifyColumnAction(tableId: string, colId: string, colInfo: Record<string, unknown>): GristUserActionTuple {\n return [\"ModifyColumn\", tableId, colId, colInfo]\n}\n\n/** `[\"RemoveColumn\", tableId, colId]` */\nexport function gristRemoveColumnAction(tableId: string, colId: string): GristUserActionTuple {\n return [\"RemoveColumn\", tableId, colId]\n}\n\n/** `[\"AddTable\", tableId, tableInfo]` */\nexport function gristAddTableAction(tableId: string, tableInfo: Record<string, unknown>): GristUserActionTuple {\n return [\"AddTable\", tableId, tableInfo]\n}\n\n/** `[\"RenameTable\", tableId, newTableId]` */\nexport function gristRenameTableAction(tableId: string, newTableId: string): GristUserActionTuple {\n return [\"RenameTable\", tableId, newTableId]\n}\n\n/** `[\"RemoveTable\", tableId]` */\nexport function gristRemoveTableAction(tableId: string): GristUserActionTuple {\n return [\"RemoveTable\", tableId]\n}\n\n/** `[\"DuplicateTable\", tableId, newTableId, options?]` */\nexport function gristDuplicateTableAction(\n tableId: string,\n newTableId: string,\n options?: Record<string, unknown>\n): GristUserActionTuple {\n return options ? [\"DuplicateTable\", tableId, newTableId, options] : [\"DuplicateTable\", tableId, newTableId]\n}\n\n/** `[\"ReplaceTableData\", tableId, rowIds, columnarData]` */\nexport function gristReplaceTableDataAction(\n tableId: string,\n rowIds: Array<number | null>,\n columnarData: Record<string, unknown[]>\n): GristUserActionTuple {\n return [\"ReplaceTableData\", tableId, rowIds, columnarData]\n}\n\n/** `[\"SetDocumentInfo\", info]` */\nexport function gristSetDocumentInfoAction(info: Record<string, unknown>): GristUserActionTuple {\n return [\"SetDocumentInfo\", info]\n}\n\nfunction inferBulkLength(values: Record<string, unknown[]>): number {\n for (const arr of Object.values(values)) if (Array.isArray(arr)) return arr.length\n return 0\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/app/deploy-path.ts","../src/app/released-versions.ts","../src/app/widget-theme.tsx","../src/app/mount-grist-widget.tsx","../src/app/chrome/tokens.ts","../src/app/chrome/widget-title.ts","../src/app/chrome/local-dev-page.tsx","../src/app/chrome/release-page.tsx","../src/app/chrome/widget-alerts.tsx"],"sourcesContent":["/**\n * Where a deployed build is being served from.\n *\n * A widget's deploy pipeline publishes the same build at its root and at\n * `/latest/`, a preview at `/dev/`, and each release at `/v<version>/`, all\n * under one base path (e.g. `/my-widget/` on GitHub Pages). Opened outside\n * Grist, the page tells them apart from `window.location.pathname` alone.\n */\nexport type DeployChannel =\n | { kind: \"latest\" }\n | { kind: \"dev\" }\n | { kind: \"version\"; version: string }\n\nexport type DeployPath = {\n channel: DeployChannel\n /**\n * The path the channels live under, always ending in `/`: the current\n * path without its channel segment. `\"/my-widget/v1.2.0/\"` gives\n * `\"/my-widget/\"`.\n */\n basePath: string\n}\n\nconst VERSION_SEGMENT = /^v(\\d+\\.\\d+\\.\\d+(?:-[\\w.]+)?)$/\n\n/**\n * Parse a pathname into its deploy channel and base path. A path without a\n * channel segment (the deployed root, or a local dev server) is `latest`:\n * the deploy places the latest release at the root too.\n */\nexport function parseDeployPath(pathname: string): DeployPath {\n const segments = pathname.replace(/\\/+$/, \"\").split(\"/\")\n const last = segments[segments.length - 1] ?? \"\"\n\n let channel: DeployChannel | null = null\n if (last === \"latest\") channel = { kind: \"latest\" }\n else if (last === \"dev\") channel = { kind: \"dev\" }\n else {\n const match = VERSION_SEGMENT.exec(last)\n if (match) channel = { kind: \"version\", version: match[1] }\n }\n\n if (!channel) return { channel: { kind: \"latest\" }, basePath: withTrailingSlash(pathname) }\n return { channel, basePath: withTrailingSlash(segments.slice(0, -1).join(\"/\")) }\n}\n\n/** `\"latest\"`, `\"dev\"` or `\"v1.2.0\"`. */\nexport function deployChannelLabel(channel: DeployChannel): string {\n return channel.kind === \"version\" ? `v${channel.version}` : channel.kind\n}\n\nfunction withTrailingSlash(path: string): string {\n return path.endsWith(\"/\") ? path : `${path}/`\n}\n","import { useEffect, useState } from \"react\"\n\nimport { parseDeployPath } from \"./deploy-path\"\n\n/** One entry of the `versions.json` a widget's deploy pipeline maintains. */\nexport type ReleasedVersion = {\n version: string\n publishedAt: string\n}\n\nexport type UseReleasedVersionsResult = {\n /** Newest first, as the deploy writes them; `null` until loaded. */\n versions: ReleasedVersion[] | null\n /** `true` when `versions.json` couldn't be fetched or read. */\n error: boolean\n}\n\n/**\n * The widget's released versions, read from the `versions.json` next to its\n * channels (see {@link parseDeployPath}). For a page shown outside Grist,\n * such as a release page linking to each version.\n */\nexport function useReleasedVersions(\n pathname: string = typeof window === \"undefined\" ? \"/\" : window.location.pathname\n): UseReleasedVersionsResult {\n const url = `${parseDeployPath(pathname).basePath}versions.json`\n const [result, setResult] = useState<UseReleasedVersionsResult>({ versions: null, error: false })\n\n useEffect(() => {\n let cancelled = false\n fetch(url, { cache: \"no-store\" })\n .then((res) => (res.ok ? res.json() : Promise.reject(new Error(`HTTP ${res.status}`))))\n .then((data: unknown) => {\n if (cancelled) return\n if (!Array.isArray(data)) throw new Error(\"versions.json is not an array\")\n setResult({ versions: data as ReleasedVersion[], error: false })\n })\n .catch(() => {\n if (!cancelled) setResult({ versions: null, error: true })\n })\n return () => {\n cancelled = true\n }\n }, [url])\n\n return result\n}\n","import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode } from \"react\"\n\nimport { useGristTheme } from \"../sdk/use-grist\"\n\nexport type WidgetTheme = \"light\" | \"dark\" | \"system\"\nexport type ResolvedWidgetTheme = \"light\" | \"dark\"\n\nexport type UseThemeResult = {\n /**\n * Inside Grist: Grist's theme, or `\"system\"` until Grist has sent it.\n * Outside Grist: the saved choice, `\"system\"` by default.\n */\n theme: WidgetTheme\n /** The theme applied to `<html class>`: `\"system\"` resolved to light or dark. */\n resolvedTheme: ResolvedWidgetTheme\n /**\n * Choose a theme outside Grist; it is saved in `localStorage`. Inside Grist\n * this does nothing: the widget follows Grist's theme.\n */\n setTheme: (theme: WidgetTheme) => void\n}\n\nconst STORAGE_KEY = \"theme\"\nconst DARK_QUERY = \"(prefers-color-scheme: dark)\"\nconst THEMES: readonly WidgetTheme[] = [\"light\", \"dark\", \"system\"]\n\nconst ThemeContext = createContext<UseThemeResult | null>(null)\n\n/**\n * The widget's current theme, for components that need it in JavaScript\n * (a toaster, a chart). Same shape as shadcn's `useTheme()`. Styles should\n * rely on the `dark` class that {@link mountGristWidget} keeps on `<html>`.\n * Outside a mounted widget (a unit test, for instance) it reports the\n * system theme and `setTheme` does nothing.\n */\nexport function useTheme(): UseThemeResult {\n const value = useContext(ThemeContext)\n return value ?? { theme: \"system\", resolvedTheme: systemTheme(), setTheme: noop }\n}\n\n/** Inside Grist: follows Grist's theme, and the OS setting until Grist sends one. */\nexport function EmbeddedThemeProvider({ children }: { children: ReactNode }) {\n const { theme: gristTheme } = useGristTheme()\n const system = useSystemTheme(gristTheme === null)\n const resolvedTheme = gristTheme ?? system\n\n useApplyTheme(resolvedTheme)\n\n const value = useMemo<UseThemeResult>(\n () => ({ theme: gristTheme ?? \"system\", resolvedTheme, setTheme: noop }),\n [gristTheme, resolvedTheme]\n )\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>\n}\n\n/**\n * Outside Grist (`pnpm dev`, the deployed release page): the saved choice,\n * the OS setting by default, and the `d` key to switch between light and\n * dark, as shadcn's theme provider does.\n */\nexport function StandaloneThemeProvider({ children }: { children: ReactNode }) {\n const [theme, setThemeState] = useState<WidgetTheme>(() => readStoredTheme() ?? \"system\")\n const system = useSystemTheme(theme === \"system\")\n const resolvedTheme = theme === \"system\" ? system : theme\n\n useApplyTheme(resolvedTheme)\n\n const setTheme = useCallback((next: WidgetTheme) => {\n writeStoredTheme(next)\n setThemeState(next)\n }, [])\n\n // `d` switches between light and dark, unless typing or using a shortcut.\n useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.repeat || event.metaKey || event.ctrlKey || event.altKey) return\n if (event.key.toLowerCase() !== \"d\" || isEditableTarget(event.target)) return\n setThemeState((current) => {\n const currentResolved = current === \"system\" ? systemTheme() : current\n const next: WidgetTheme = currentResolved === \"dark\" ? \"light\" : \"dark\"\n writeStoredTheme(next)\n return next\n })\n }\n window.addEventListener(\"keydown\", onKeyDown)\n return () => window.removeEventListener(\"keydown\", onKeyDown)\n }, [])\n\n // Another tab saving a choice applies here too.\n useEffect(() => {\n const onStorage = (event: StorageEvent) => {\n if (event.key !== STORAGE_KEY) return\n setThemeState(isTheme(event.newValue) ? event.newValue : \"system\")\n }\n window.addEventListener(\"storage\", onStorage)\n return () => window.removeEventListener(\"storage\", onStorage)\n }, [])\n\n const value = useMemo<UseThemeResult>(\n () => ({ theme, resolvedTheme, setTheme }),\n [theme, resolvedTheme, setTheme]\n )\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>\n}\n\n/** The OS setting, kept current while `active`. */\nfunction useSystemTheme(active: boolean): ResolvedWidgetTheme {\n const [theme, setTheme] = useState<ResolvedWidgetTheme>(systemTheme)\n\n useEffect(() => {\n if (!active || typeof window.matchMedia !== \"function\") return\n const query = window.matchMedia(DARK_QUERY)\n const onChange = () => setTheme(query.matches ? \"dark\" : \"light\")\n onChange()\n query.addEventListener(\"change\", onChange)\n return () => query.removeEventListener(\"change\", onChange)\n }, [active])\n\n return theme\n}\n\n/** Keep `light` or `dark` on `<html class>`, which Tailwind's dark variant reads. */\nfunction useApplyTheme(theme: ResolvedWidgetTheme) {\n useEffect(() => {\n const root = document.documentElement\n if (root.classList.contains(theme) && !root.classList.contains(other(theme))) return\n const restoreTransitions = suspendTransitions()\n root.classList.remove(other(theme))\n root.classList.add(theme)\n restoreTransitions()\n }, [theme])\n}\n\nfunction systemTheme(): ResolvedWidgetTheme {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\") return \"light\"\n return window.matchMedia(DARK_QUERY).matches ? \"dark\" : \"light\"\n}\n\nfunction other(theme: ResolvedWidgetTheme): ResolvedWidgetTheme {\n return theme === \"dark\" ? \"light\" : \"dark\"\n}\n\n/** Switch themes without every color transition animating at once. */\nfunction suspendTransitions(): () => void {\n const style = document.createElement(\"style\")\n style.appendChild(\n document.createTextNode(\"*,*::before,*::after{-webkit-transition:none!important;transition:none!important}\")\n )\n document.head.appendChild(style)\n return () => {\n window.getComputedStyle(document.body)\n requestAnimationFrame(() => requestAnimationFrame(() => style.remove()))\n }\n}\n\nfunction isEditableTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false\n return target.isContentEditable || target.closest(\"input, textarea, select, [contenteditable='true']\") !== null\n}\n\nfunction isTheme(value: string | null): value is WidgetTheme {\n return value !== null && (THEMES as readonly string[]).includes(value)\n}\n\nfunction readStoredTheme(): WidgetTheme | null {\n try {\n const value = localStorage.getItem(STORAGE_KEY)\n return isTheme(value) ? value : null\n } catch {\n return null\n }\n}\n\nfunction writeStoredTheme(theme: WidgetTheme) {\n try {\n localStorage.setItem(STORAGE_KEY, theme)\n } catch {\n // Storage blocked (private mode, sandboxed iframe): the choice lasts for this page only.\n }\n}\n\nfunction noop() {}\n","import { StrictMode, Suspense, type ComponentType, type ReactNode } from \"react\"\nimport { createRoot } from \"react-dom/client\"\n\nimport { GristBoundary, GristWidgetProvider } from \"../sdk\"\nimport type { UseGristOptions } from \"../sdk\"\nimport { LocalDevPage as DefaultLocalDevPage } from \"./chrome/local-dev-page\"\nimport { ReleasePage as DefaultReleasePage } from \"./chrome/release-page\"\nimport { WidgetAlerts } from \"./chrome/widget-alerts\"\nimport { parseDeployPath, type DeployChannel } from \"./deploy-path\"\nimport { EmbeddedThemeProvider, StandaloneThemeProvider } from \"./widget-theme\"\n\nexport type GristWidgetAppProps = {\n /** The widget. A `React.lazy()` component works too: its code then loads only inside Grist. */\n App: ComponentType\n /** The widget's `GRIST_OPTIONS`: access level, columns, and so on. */\n options: UseGristOptions\n /**\n * Whether this is the local dev server. Pass `import.meta.env.DEV`.\n * Outside Grist it picks the local-dev page over the release page.\n */\n dev?: boolean\n /**\n * Wraps the widget inside Grist, under {@link GristBoundary}. The default\n * lists what needs the user's attention (column mapping, access level,\n * failed writes) above the widget; `null` renders the widget alone.\n */\n Alerts?: ComponentType<{ children: ReactNode }> | null\n /** Shown outside Grist on the local dev server. Defaults to a page pointing at `pnpm test` and the `dev` loop. */\n LocalDevPage?: ComponentType\n /**\n * Shown outside Grist on a deployed URL (`/latest/`, `/dev/`, `/v<version>/`).\n * Defaults to a page linking every channel and version, with the URL to\n * paste into Grist.\n */\n ReleasePage?: ComponentType<{ channel: DeployChannel }>\n}\n\nexport type MountGristWidgetConfig = GristWidgetAppProps & {\n /** The element to render into, or its CSS selector. Defaults to `#root`. */\n root?: Element | string\n}\n\nexport type MountedGristWidget = {\n unmount: () => void\n}\n\n/**\n * Render a widget into the page: everything `src/main.tsx` used to wire by\n * hand.\n *\n * ```tsx\n * import { mountGristWidget } from \"grist-widget-sdk/app\"\n * import \"./index.css\"\n * import App, { GRIST_OPTIONS } from \"./App\"\n *\n * mountGristWidget({ App, options: GRIST_OPTIONS, dev: import.meta.env.DEV })\n * ```\n *\n * Inside Grist, the widget renders in {@link GristWidgetProvider} and\n * {@link GristBoundary}, which gates on its mapped columns when it declares\n * any, and follows Grist's light/dark theme. Outside Grist, where there is\n * nothing to connect to, the page shows `LocalDevPage` on the dev server and\n * `ReleasePage` on a deployed URL.\n */\nexport function mountGristWidget(config: MountGristWidgetConfig): MountedGristWidget {\n const { root = \"#root\", ...props } = config\n const container = typeof root === \"string\" ? document.querySelector(root) : root\n if (!container) {\n throw new Error(`mountGristWidget: no element matches \"${String(root)}\" to render the widget into.`)\n }\n\n const reactRoot = createRoot(container)\n reactRoot.render(\n <StrictMode>\n <GristWidgetApp {...props} />\n </StrictMode>\n )\n return { unmount: () => reactRoot.unmount() }\n}\n\n/**\n * The tree {@link mountGristWidget} renders, as a component: for a test, or\n * for a page that manages its own React root.\n */\nexport function GristWidgetApp({\n App,\n options,\n dev = false,\n Alerts = WidgetAlerts,\n LocalDevPage = DefaultLocalDevPage,\n ReleasePage = DefaultReleasePage,\n}: GristWidgetAppProps) {\n const Wrap = Alerts ?? PassThrough\n if (isEmbedded()) {\n return (\n <GristWidgetProvider options={options}>\n <EmbeddedThemeProvider>\n <GristBoundary gate={options.columns?.length ? \"canRender\" : \"ready\"}>\n <div style={FILL}>\n <Wrap>\n <Suspense fallback={null}>\n <App />\n </Suspense>\n </Wrap>\n </div>\n </GristBoundary>\n </EmbeddedThemeProvider>\n </GristWidgetProvider>\n )\n }\n\n const channel = parseDeployPath(window.location.pathname).channel\n return (\n <StandaloneThemeProvider>\n <div style={FILL}>{dev ? <LocalDevPage /> : <ReleasePage channel={channel} />}</div>\n </StandaloneThemeProvider>\n )\n}\n\nconst FILL = { minHeight: \"100%\", width: \"100%\" } as const\n\n/** A Grist custom widget only ever runs in Grist's iframe. */\nfunction isEmbedded(): boolean {\n return typeof window !== \"undefined\" && window.self !== window.top\n}\n\nfunction PassThrough({ children }: { children: ReactNode }) {\n return <>{children}</>\n}\n","import type { CSSProperties } from \"react\"\n\n/**\n * The chrome's colours and radius: shadcn's CSS variables, so the pages\n * follow a widget's theme (light, dark, its own palette) without depending\n * on its Tailwind config, with neutral fallbacks for a widget without them.\n * Same approach as GristBoundaryScreen.\n */\nconst token = (name: string, fallback: string) => `var(--${name}, ${fallback})`\n\nexport const tokens = {\n background: token(\"background\", \"#ffffff\"),\n foreground: token(\"foreground\", \"#0a0a0a\"),\n card: token(\"card\", \"#ffffff\"),\n mutedForeground: token(\"muted-foreground\", \"#737373\"),\n border: token(\"border\", \"#e5e5e5\"),\n primary: token(\"primary\", \"#171717\"),\n primaryForeground: token(\"primary-foreground\", \"#fafafa\"),\n destructive: token(\"destructive\", \"#dc2626\"),\n radius: token(\"radius\", \"0.625rem\"),\n} as const\n\nexport const pageStyle: CSSProperties = {\n boxSizing: \"border-box\",\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n maxWidth: \"28rem\",\n minHeight: \"100%\",\n margin: \"0 auto\",\n padding: \"4rem 1.5rem\",\n color: tokens.foreground,\n font: \"inherit\",\n}\n\nexport const eyebrowStyle: CSSProperties = {\n margin: \"0 0 0.5rem\",\n textAlign: \"center\",\n fontSize: \"0.875rem\",\n fontWeight: 500,\n color: tokens.mutedForeground,\n}\n\nexport const headingStyle: CSSProperties = {\n margin: 0,\n textAlign: \"center\",\n fontSize: \"1.5rem\",\n fontWeight: 600,\n letterSpacing: \"-0.01em\",\n}\n\nexport const leadStyle: CSSProperties = {\n margin: \"0.75rem auto 2rem\",\n maxWidth: \"24rem\",\n textAlign: \"center\",\n fontSize: \"0.875rem\",\n lineHeight: 1.5,\n color: tokens.mutedForeground,\n}\n\nexport const cardStyle: CSSProperties = {\n boxSizing: \"border-box\",\n marginBottom: \"1rem\",\n padding: \"1.25rem\",\n border: `1px solid ${tokens.border}`,\n borderRadius: tokens.radius,\n background: tokens.card,\n}\n\nexport const cardTitleStyle: CSSProperties = {\n margin: \"0 0 0.375rem\",\n fontSize: \"1rem\",\n fontWeight: 600,\n}\n\nexport const cardTextStyle: CSSProperties = {\n margin: 0,\n fontSize: \"0.875rem\",\n lineHeight: 1.5,\n color: tokens.mutedForeground,\n}\n\nexport const codeStyle: CSSProperties = {\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n fontSize: \"0.8125rem\",\n color: tokens.foreground,\n}\n","/**\n * The widget's name for the pages shown outside Grist: the page title,\n * which `create-grist-widget` sets to the widget's title in `index.html`.\n */\nexport function widgetTitle(): string {\n const title = typeof document === \"undefined\" ? \"\" : document.title.trim()\n return title || \"Grist widget\"\n}\n","import {\n cardStyle,\n cardTextStyle,\n cardTitleStyle,\n codeStyle,\n eyebrowStyle,\n headingStyle,\n leadStyle,\n pageStyle,\n} from \"./tokens\"\nimport { widgetTitle } from \"./widget-title\"\n\n/**\n * Shown outside Grist on the dev server. Deliberately not a preview of the\n * widget: an emulator can't match real Grist, so it points at the two loops\n * worth trusting, `pnpm test` and the `dev` branch's preview inside Grist.\n */\nexport function LocalDevPage() {\n return (\n <main style={pageStyle}>\n <p style={eyebrowStyle}>{widgetTitle()} · local dev</p>\n <h1 style={headingStyle}>Not embedded in Grist</h1>\n <p style={leadStyle}>This is the local dev server: there's no Grist here to render the widget against.</p>\n\n <section style={cardStyle}>\n <h2 style={cardTitleStyle}>Check it against real Grist</h2>\n <p style={cardTextStyle}>\n Push to <code style={codeStyle}>dev</code>, then open its <code style={codeStyle}>/dev/</code> URL in a\n custom widget of a real Grist document: later pushes reload it there within seconds. Locally,{\" \"}\n <code style={codeStyle}>pnpm test</code> runs the widget against an emulated Grist.\n </p>\n </section>\n\n <section style={cardStyle}>\n <h2 style={cardTitleStyle}>Starting from another example?</h2>\n <p style={cardTextStyle}>\n <code style={codeStyle}>npx create-grist-widget list</code> shows the examples, and{\" \"}\n <code style={codeStyle}>npx create-grist-widget use <example></code> swaps this widget for one.\n </p>\n </section>\n </main>\n )\n}\n","import { useState, type CSSProperties } from \"react\"\n\nimport { deployChannelLabel, parseDeployPath, type DeployChannel } from \"../deploy-path\"\nimport { useReleasedVersions } from \"../released-versions\"\nimport {\n cardStyle,\n cardTextStyle,\n cardTitleStyle,\n codeStyle,\n eyebrowStyle,\n headingStyle,\n leadStyle,\n pageStyle,\n tokens,\n} from \"./tokens\"\nimport { widgetTitle } from \"./widget-title\"\n\n/**\n * Shown outside Grist on a deployed URL (`/latest/`, `/dev/`, `/v<version>/`\n * or the root): which build this is, links to the others, and the URL to\n * paste into a Grist custom widget.\n */\nexport function ReleasePage({ channel }: { channel: DeployChannel }) {\n const label = deployChannelLabel(channel)\n return (\n <main style={pageStyle}>\n <p style={eyebrowStyle}>\n {widgetTitle()} · {label}\n </p>\n <h1 style={headingStyle}>Grist isn't loaded here</h1>\n <p style={leadStyle}>\n This is the <code style={codeStyle}>{label}</code> build, opened outside Grist. Hover a version to see when it\n was released.\n </p>\n <ChannelLinks current={channel} />\n <InstallUrl />\n </main>\n )\n}\n\nfunction ChannelLinks({ current }: { current: DeployChannel }) {\n const { basePath } = parseDeployPath(window.location.pathname)\n const { versions } = useReleasedVersions()\n const isCurrent = (channel: DeployChannel) =>\n channel.kind === current.kind && (channel.kind !== \"version\" || (current.kind === \"version\" && channel.version === current.version))\n\n return (\n <nav aria-label=\"Versions\" style={{ display: \"flex\", flexWrap: \"wrap\", justifyContent: \"center\", gap: \"0.5rem\", marginBottom: \"2rem\" }}>\n <ChannelLink href={`${basePath}latest/`} active={isCurrent({ kind: \"latest\" })}>\n latest\n </ChannelLink>\n <ChannelLink href={`${basePath}dev/`} active={isCurrent({ kind: \"dev\" })}>\n dev\n </ChannelLink>\n {versions?.map((v) => (\n <ChannelLink\n key={v.version}\n href={`${basePath}v${v.version}/`}\n title={formatDate(v.publishedAt)}\n active={isCurrent({ kind: \"version\", version: v.version })}\n >\n {`v${v.version}`}\n </ChannelLink>\n ))}\n </nav>\n )\n}\n\nfunction ChannelLink({\n href,\n title,\n active,\n children,\n}: {\n href: string\n title?: string\n active: boolean\n children: string\n}) {\n const style: CSSProperties = {\n padding: \"0.25rem 0.75rem\",\n border: `1px solid ${active ? tokens.primary : tokens.border}`,\n borderRadius: \"9999px\",\n background: active ? tokens.primary : \"transparent\",\n color: active ? tokens.primaryForeground : tokens.mutedForeground,\n fontSize: \"0.75rem\",\n fontWeight: 500,\n textDecoration: \"none\",\n }\n return (\n <a href={href} title={title} aria-current={active ? \"page\" : undefined} style={style}>\n {children}\n </a>\n )\n}\n\nfunction InstallUrl() {\n const url = window.location.href\n const [copied, setCopied] = useState(false)\n\n function copy() {\n void navigator.clipboard?.writeText(url).then(() => {\n setCopied(true)\n setTimeout(() => setCopied(false), 1500)\n })\n }\n\n return (\n <section style={cardStyle}>\n <h2 style={cardTitleStyle}>Use it as a Grist custom widget</h2>\n <p style={{ ...cardTextStyle, marginBottom: \"1rem\" }}>Paste this URL into a custom widget's URL field in Grist.</p>\n <div style={{ display: \"flex\", gap: \"0.5rem\" }}>\n <input\n readOnly\n value={url}\n aria-label=\"Widget URL\"\n onFocus={(event) => event.target.select()}\n style={{\n flex: 1,\n minWidth: 0,\n padding: \"0.5rem 0.75rem\",\n border: `1px solid ${tokens.border}`,\n borderRadius: tokens.radius,\n background: \"transparent\",\n color: tokens.foreground,\n font: \"inherit\",\n fontSize: \"0.875rem\",\n }}\n />\n <button\n type=\"button\"\n onClick={copy}\n style={{\n padding: \"0.5rem 1rem\",\n border: \"none\",\n borderRadius: tokens.radius,\n background: tokens.primary,\n color: tokens.primaryForeground,\n font: \"inherit\",\n fontSize: \"0.875rem\",\n fontWeight: 500,\n cursor: \"pointer\",\n }}\n >\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n </div>\n </section>\n )\n}\n\nfunction formatDate(iso: string): string {\n const date = new Date(iso)\n return Number.isNaN(date.getTime())\n ? iso\n : date.toLocaleDateString(undefined, { year: \"numeric\", month: \"short\", day: \"numeric\" })\n}\n","import type { CSSProperties, ReactNode } from \"react\"\n\nimport { useGristSdkAlertDescriptors } from \"../../sdk\"\nimport type { GetGristSdkAlertDescriptorsOptions, GristSdkAlertDescriptor } from \"../../sdk\"\nimport { tokens } from \"./tokens\"\n\nconst ALERT_OPTIONS: GetGristSdkAlertDescriptorsOptions = {\n sectionNotLinkedHint:\n \"In Grist, select this widget section on the page, then use Link to connect a table, card, or chart view as the selector.\",\n}\n\n/**\n * The default `Alerts` of {@link mountGristWidget}: what needs the user's\n * attention (column mapping, access level, failed writes, an unlinked\n * section), above the widget. Renders nothing extra when all is well.\n */\nexport function WidgetAlerts({ children }: { children: ReactNode }) {\n const alerts = useGristSdkAlertDescriptors(undefined, ALERT_OPTIONS)\n if (alerts.length === 0) return <>{children}</>\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"0.75rem\" }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"0.75rem\", padding: \"0.75rem 0.75rem 0\" }}>\n {alerts.map((alert) => (\n <WidgetAlert key={alert.id} alert={alert} />\n ))}\n </div>\n {children}\n </div>\n )\n}\n\nfunction WidgetAlert({ alert }: { alert: GristSdkAlertDescriptor }) {\n const linkIcon = alert.kind === \"section-not-linked\" || alert.kind === \"source-not-wired\"\n return (\n <div role={alert.ariaRole} style={{ ...alertStyle, ...SEVERITY[alert.severity] }}>\n <span aria-hidden style={{ flexShrink: 0, marginTop: \"0.125rem\" }}>\n {linkIcon ? <LinkIcon /> : <WarningIcon />}\n </span>\n <div style={{ minWidth: 0 }}>\n <p style={{ margin: 0, fontWeight: 500 }}>{alert.title}</p>\n <p style={{ margin: \"0.25rem 0 0\", color: tokens.mutedForeground }}>{alert.message}</p>\n </div>\n </div>\n )\n}\n\nconst alertStyle: CSSProperties = {\n boxSizing: \"border-box\",\n display: \"flex\",\n gap: \"0.75rem\",\n padding: \"0.75rem 1rem\",\n border: `1px solid ${tokens.border}`,\n borderRadius: tokens.radius,\n color: tokens.foreground,\n fontSize: \"0.875rem\",\n lineHeight: 1.5,\n}\n\nconst SEVERITY: Record<GristSdkAlertDescriptor[\"severity\"], CSSProperties> = {\n error: { borderColor: tokens.destructive, color: tokens.destructive },\n warning: { borderColor: \"rgb(245 158 11 / 0.4)\", background: \"rgb(245 158 11 / 0.1)\" },\n info: { background: \"transparent\" },\n}\n\nconst ICON = {\n width: 16,\n height: 16,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n} as const\n\nfunction WarningIcon() {\n return (\n <svg {...ICON}>\n <path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\" />\n <path d=\"M12 9v4\" />\n <path d=\"M12 17h.01\" />\n </svg>\n )\n}\n\nfunction LinkIcon() {\n return (\n <svg {...ICON}>\n <path d=\"M9 17H7A5 5 0 0 1 7 7h2\" />\n <path d=\"M15 7h2a5 5 0 1 1 0 10h-2\" />\n <line x1=\"8\" x2=\"16\" y1=\"12\" y2=\"12\" />\n </svg>\n )\n}\n"],"mappings":"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","names":["useEffect","useState","useState","useEffect","jsx","useState","jsx","jsxs","useState","jsx","jsxs","Fragment","jsx","LocalDevPage","ReleasePage"]}
|