@extable/core 0.3.3 → 0.3.4
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/dist/core.css +1 -0
- package/dist/index +5328 -0
- package/dist/index.css +1 -1
- package/dist/index.js +1696 -2643
- package/dist/index.js.map +1 -1
- package/dist/index.map +1 -0
- package/dist/numberIO-CmW6eOR7.js +978 -0
- package/dist/numberIO-CmW6eOR7.js.map +1 -0
- package/dist/ssr/htmlBuilder.d.ts +11 -0
- package/dist/ssr/index +338 -0
- package/dist/ssr/index.d.ts +2 -0
- package/dist/ssr/index.js +480 -0
- package/dist/ssr/index.js.map +1 -0
- package/dist/ssr/index.map +1 -0
- package/dist/ssr/nodeShims.d.ts +14 -0
- package/dist/ssr/renderer.d.ts +27 -0
- package/dist/ssr/styleSerializer.d.ts +10 -0
- package/package.json +10 -4
- package/src/styles.css +885 -0
- package/style.css +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index","sources":["../../src/ssr/htmlBuilder.ts","../../src/ssr/styleSerializer.ts","../../src/ssr/renderer.ts"],"sourcesContent":["export type HTMLAttributeValue = string | number | boolean | null | undefined;\n\nexport class HTMLBuilder {\n private parts: string[] = [];\n\n openTag(tag: string, attrs?: Record<string, HTMLAttributeValue>): this {\n let html = `<${tag}`;\n if (attrs) {\n for (const [key, value] of Object.entries(attrs)) {\n if (value === true) {\n html += ` ${key}`;\n } else if (value !== false && value !== null && value !== undefined) {\n html += ` ${key}=\"${escapeHtml(String(value))}\"`;\n }\n }\n }\n html += \">\";\n this.parts.push(html);\n return this;\n }\n\n closeTag(tag: string): this {\n this.parts.push(`</${tag}>`);\n return this;\n }\n\n text(content: string): this {\n this.parts.push(escapeHtml(content));\n return this;\n }\n\n html(content: string): this {\n this.parts.push(content);\n return this;\n }\n\n build(): string {\n return this.parts.join(\"\");\n }\n}\n\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\\\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","export type CSSValue = string | number | null | undefined | false;\nexport type CSSStyleMap = Record<string, CSSValue>;\n\nexport function serializeStyle(style: CSSStyleMap): string {\n const parts: string[] = [];\n for (const [key, value] of Object.entries(style)) {\n if (value === null || value === undefined || value === false) continue;\n const prop = toKebabCase(key);\n parts.push(`${prop}:${String(value)};`);\n }\n return parts.join(\"\");\n}\n\nexport class CSSBuilder {\n private rules = new Map<string, CSSStyleMap>();\n\n addRule(selector: string, style: CSSStyleMap) {\n const prev = this.rules.get(selector) ?? {};\n this.rules.set(selector, { ...prev, ...style });\n }\n\n build(options?: { minify?: boolean }): string {\n const minify = options?.minify ?? false;\n const lines: string[] = [];\n for (const [selector, style] of this.rules.entries()) {\n const body = serializeStyle(style);\n if (!body) continue;\n if (minify) {\n lines.push(`${selector}{${body}}`);\n } else {\n lines.push(`${selector} { ${body} }`);\n }\n }\n return lines.join(minify ? \"\" : \"\\n\");\n }\n}\n\nfunction toKebabCase(input: string): string {\n if (input.startsWith(\"--\")) return input;\n if (input.includes(\"-\")) return input.toLowerCase();\n return input.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);\n}\n","import { DataModel } from \"../dataModel\";\nimport { columnFormatToStyle, mergeStyle } from \"../styleResolver\";\nimport type {\n ColumnSchema,\n InternalRow,\n NumberFormat,\n IntegerFormat,\n Schema,\n View,\n ViewFilterValues,\n RowObject,\n ResolvedCellStyle,\n} from \"../types\";\nimport { coerceDatePattern, formatDateLite, parseIsoDate } from \"../dateUtils\";\nimport { formatIntegerWithPrefix, formatNumberForEdit } from \"../numberIO\";\nimport { toRawValue } from \"../cellValueCodec\";\nimport { getButtonLabel, getLinkLabel, resolveButtonAction, resolveLinkAction } from \"../actionValue\";\nimport { DEFAULT_ROW_HEIGHT_PX, HEADER_HEIGHT_PX, ROW_HEADER_WIDTH_PX, getColumnWidths } from \"../geometry\";\nimport { HTMLBuilder } from \"./htmlBuilder\";\nimport { CSSBuilder, type CSSStyleMap, serializeStyle } from \"./styleSerializer\";\n\nexport type SSRView = View & {\n columnOrder?: string[];\n columnVisibility?: Record<string, boolean>;\n};\n\nexport interface SSROptions<T extends object = Record<string, unknown>> {\n data: T[] | null | undefined;\n schema: Schema<any>;\n view?: Partial<SSRView>;\n tableAttributes?: Record<string, string | number | boolean>;\n cssMode?: \"inline\" | \"external\" | \"both\";\n cssClassName?: string;\n includeDataAttributes?: boolean;\n includeAccessibilityAttributes?: boolean;\n onFormulaError?: (error: Error, row: number, col: string) => string | void;\n onValidationError?: (error: Error, row: number, col: string) => void;\n}\n\nexport interface SSRResult {\n html: string;\n css?: string;\n metadata: {\n rowCount: number;\n columnCount: number;\n hasFormulas: boolean;\n hasConditionalStyles: boolean;\n errors: Array<{ row: number; col: string; message: string }>;\n };\n}\n\nexport function renderTableHTML<T extends object = Record<string, unknown>>(\n options: SSROptions<T>,\n): SSRResult {\n const cssMode = options.cssMode ?? \"inline\";\n const cssClassName = options.cssClassName ?? \"extable\";\n const includeDataAttributes = options.includeDataAttributes ?? true;\n const includeAccessibilityAttributes = options.includeAccessibilityAttributes ?? false;\n const view = options.view ?? {};\n const data = (options.data ?? []) as RowObject[];\n\n const baseView: View = {\n hiddenColumns: view.hiddenColumns,\n filters: view.filters,\n sorts: view.sorts,\n columnDiagnostics: view.columnDiagnostics,\n userId: view.userId,\n columnWidths: view.columnWidths,\n rowHeights: view.rowHeights,\n wrapText: view.wrapText,\n };\n\n const dataModel = new DataModel(data, options.schema, baseView);\n const schema = dataModel.getSchema();\n const effectiveView = dataModel.getView();\n const rows = dataModel.listRows();\n const columns = resolveVisibleColumns(schema, view);\n const colWidths = getColumnWidths(schema, effectiveView);\n\n const html = new HTMLBuilder();\n const cssBuilder = cssMode === \"inline\" ? null : new CSSBuilder();\n const errors: Array<{ row: number; col: string; message: string }> = [];\n\n const rootSelector = `.${cssClassName.split(/\\s+/)[0] ?? \"extable\"}`;\n if (cssBuilder && cssMode !== \"inline\") {\n for (const col of columns) {\n const baseStyle = resolvedStyleToMap(columnFormatToStyle(col));\n if (Object.keys(baseStyle).length === 0) continue;\n cssBuilder.addRule(`${rootSelector} tbody td[data-col-key=\\\"${String(col.key)}\\\"]`, baseStyle);\n }\n }\n\n const totalWidth = ROW_HEADER_WIDTH_PX + colWidths.reduce((acc, w) => acc + (w ?? 0), 0);\n const tableAttrs: Record<string, string | number | boolean> = {\n class: cssClassName,\n \"data-extable-renderer\": \"html\",\n \"data-extable-ssr\": true,\n style: `width:${totalWidth}px;`,\n ...options.tableAttributes,\n };\n if (includeAccessibilityAttributes) {\n tableAttrs.role = \"grid\";\n }\n\n html.openTag(\"table\", tableAttrs);\n html.openTag(\"thead\");\n html.openTag(\"tr\", { style: `height:${HEADER_HEIGHT_PX}px;` });\n\n const rowHeaderAttrs: Record<string, string | number | boolean> = {\n class: \"extable-row-header extable-corner\",\n \"data-col-key\": \"\",\n style: `width:${ROW_HEADER_WIDTH_PX}px;`,\n };\n html.openTag(\"th\", rowHeaderAttrs).text(\"\").closeTag(\"th\");\n\n for (const col of columns) {\n const thAttrs: Record<string, string | number | boolean> = {\n \"data-col-key\": col.key,\n };\n if (includeDataAttributes) thAttrs[\"data-col-type\"] = col.type;\n const sortDir = getColumnSortDir(effectiveView, col.key);\n const hasFilter = hasActiveColumnFilter(effectiveView, col.key);\n if (sortDir) thAttrs[\"data-extable-sort-dir\"] = sortDir;\n if (hasFilter) thAttrs[\"data-extable-fs-active\"] = \"1\";\n const width = colWidths[schema.columns.findIndex((c) => c.key === col.key)] ?? col.width;\n if (width) thAttrs.style = `width:${width}px;`;\n if (includeAccessibilityAttributes) thAttrs.scope = \"col\";\n\n html.openTag(\"th\", thAttrs);\n html.openTag(\"div\", { class: \"extable-col-header\" });\n html.openTag(\"span\", { class: \"extable-col-header-text\" }).text(col.header ?? col.key);\n html.closeTag(\"span\");\n html.openTag(\"button\", {\n type: \"button\",\n class: \"extable-filter-sort-trigger\",\n \"data-extable-fs-open\": \"1\",\n \"data-extable-col-key\": col.key,\n title: \"Filter / Sort\",\n });\n html.html(sortDir ? svgArrow(sortDir) : svgFunnel());\n html.closeTag(\"button\");\n html.closeTag(\"div\");\n html.closeTag(\"th\");\n }\n\n html.closeTag(\"tr\");\n html.closeTag(\"thead\");\n html.openTag(\"tbody\");\n\n const hasFormulas = schema.columns.some((c) => Boolean(c.formula));\n const hasConditionalStyles = schema.columns.some((c) => Boolean(c.conditionalStyle)) ||\n Boolean(schema.row?.conditionalStyle);\n\n rows.forEach((row, rowIndex) => {\n const trAttrs: Record<string, string | number | boolean> = {\n \"data-row-id\": row.id,\n style: `height:${DEFAULT_ROW_HEIGHT_PX}px;`,\n };\n if (includeDataAttributes) trAttrs[\"data-row-index\"] = rowIndex;\n html.openTag(\"tr\", trAttrs);\n\n const rowHeader: Record<string, string | number | boolean> = {\n class: \"extable-row-header\",\n };\n if (includeAccessibilityAttributes) rowHeader.scope = \"row\";\n const displayIndex = dataModel.getDisplayIndex(row.id) ?? \"\";\n html.openTag(\"th\", rowHeader).text(String(displayIndex)).closeTag(\"th\");\n\n for (const col of columns) {\n renderCell({\n html,\n row,\n rowIndex,\n col,\n dataModel,\n view: effectiveView,\n includeDataAttributes,\n cssMode,\n cssBuilder,\n rootSelector,\n errors,\n onFormulaError: options.onFormulaError,\n onValidationError: options.onValidationError,\n });\n }\n\n html.closeTag(\"tr\");\n });\n\n html.closeTag(\"tbody\");\n html.closeTag(\"table\");\n\n return {\n html: html.build(),\n css: cssBuilder?.build({ minify: true }),\n metadata: {\n rowCount: rows.length,\n columnCount: columns.length,\n hasFormulas,\n hasConditionalStyles,\n errors,\n },\n };\n}\n\nfunction resolveVisibleColumns(schema: Schema, view: Partial<SSRView>): ColumnSchema[] {\n const visibility = view.columnVisibility ?? {};\n const hidden = new Set((view.hiddenColumns ?? []).map((k) => String(k)));\n const colMap = new Map<string, ColumnSchema>();\n for (const col of schema.columns) {\n colMap.set(String(col.key), col);\n }\n const ordered: ColumnSchema[] = [];\n const seen = new Set<string>();\n\n const order = (view.columnOrder ?? []).map((k) => String(k));\n for (const key of order) {\n const col = colMap.get(key);\n if (!col) continue;\n if (!isVisibleColumn(col, visibility, hidden)) continue;\n ordered.push(col);\n seen.add(key);\n }\n\n for (const col of schema.columns) {\n const key = String(col.key);\n if (seen.has(key)) continue;\n if (!isVisibleColumn(col, visibility, hidden)) continue;\n ordered.push(col);\n }\n return ordered;\n}\n\nfunction isVisibleColumn(\n col: ColumnSchema,\n visibility: Record<string, boolean>,\n hidden: Set<string>,\n): boolean {\n const key = String(col.key);\n if (visibility[key] === false) return false;\n if (visibility[key] === true) return true;\n if (hidden.has(key)) return false;\n return true;\n}\n\nfunction renderCell(options: {\n html: HTMLBuilder;\n row: InternalRow;\n rowIndex: number;\n col: ColumnSchema;\n dataModel: DataModel;\n view: View;\n includeDataAttributes: boolean;\n cssMode: \"inline\" | \"external\" | \"both\";\n cssBuilder: CSSBuilder | null;\n rootSelector: string;\n errors: Array<{ row: number; col: string; message: string }>;\n onFormulaError?: (error: Error, row: number, col: string) => string | void;\n onValidationError?: (error: Error, row: number, col: string) => void;\n}) {\n const {\n html,\n row,\n rowIndex,\n col,\n dataModel,\n view,\n includeDataAttributes,\n cssMode,\n cssBuilder,\n rootSelector,\n errors,\n onFormulaError,\n onValidationError,\n } = options;\n\n const tdClasses = [\"extable-cell\"];\n if (col.type === \"boolean\") tdClasses.push(\"extable-boolean\");\n\n const interaction = dataModel.getCellInteraction(row.id, col.key);\n if (interaction.readonly) tdClasses.push(\"extable-readonly\");\n else tdClasses.push(\"extable-editable\");\n if (interaction.muted) tdClasses.push(\"extable-readonly-muted\");\n if (interaction.disabled) tdClasses.push(\"extable-disabled\");\n\n const wrap = view.wrapText?.[col.key] ?? col.wrapText;\n tdClasses.push(wrap ? \"cell-wrap\" : \"cell-nowrap\");\n\n const align =\n col.style?.align ??\n (col.type === \"number\" || col.type === \"int\" || col.type === \"uint\" ? \"right\" : \"left\");\n tdClasses.push(align === \"right\" ? \"align-right\" : \"align-left\");\n\n const condRes = dataModel.resolveConditionalStyle(row.id, col);\n const cellStyle = dataModel.getCellStyle(row.id, col.key);\n const baseStyle = columnFormatToStyle(col);\n const withCond = condRes.delta ? mergeStyle(baseStyle, condRes.delta) : baseStyle;\n const resolved = cellStyle ? mergeStyle(withCond, cellStyle) : withCond;\n\n const marker = dataModel.getCellMarker(row.id, col.key);\n if (marker) {\n tdClasses.push(marker.level === \"warning\" ? \"extable-diag-warning\" : \"extable-diag-error\");\n }\n\n const raw = dataModel.getRawCell(row.id, col.key);\n const valueRes = dataModel.resolveCellValue(row.id, col);\n let textOverride = valueRes.textOverride ?? (condRes.forceErrorText ? \"#ERROR\" : undefined);\n\n if (valueRes.diagnostic?.source === \"formula\") {\n const err = new Error(valueRes.diagnostic.message);\n const replacement = onFormulaError?.(err, rowIndex, String(col.key));\n errors.push({ row: rowIndex, col: String(col.key), message: err.message });\n if (typeof replacement === \"string\") textOverride = replacement;\n }\n\n const validationMsg = dataModel.getCellValidationMessage(row.id, col.key);\n if (validationMsg) {\n const err = new Error(validationMsg);\n errors.push({ row: rowIndex, col: String(col.key), message: err.message });\n onValidationError?.(err, rowIndex, String(col.key));\n }\n\n const formatted = textOverride\n ? { text: textOverride }\n : formatValue(valueRes.value, col);\n const resolvedWithFormat =\n formatted.color && formatted.color !== resolved.textColor\n ? { ...resolved, textColor: formatted.color }\n : resolved;\n\n const tagValues = col.type === \"tags\" && !textOverride ? resolveTagValues(valueRes.value) : null;\n const isActionType = col.type === \"button\" || col.type === \"link\";\n const actionValue = isActionType\n ? col.type === \"button\"\n ? resolveButtonAction(valueRes.value)\n : resolveLinkAction(valueRes.value)\n : null;\n const actionLabel = isActionType\n ? col.type === \"button\"\n ? getButtonLabel(valueRes.value)\n : getLinkLabel(valueRes.value)\n : \"\";\n\n const tdAttrs: Record<string, string | number | boolean> = {\n class: tdClasses.join(\" \"),\n \"data-col-key\": col.key,\n };\n\n if (includeDataAttributes) {\n tdAttrs[\"data-row-id\"] = row.id;\n tdAttrs[\"data-col-type\"] = col.type;\n tdAttrs[\"data-cell\"] = `${rowIndex}:${String(col.key)}`;\n if (col.formula) tdAttrs[\"data-computed\"] = true;\n if (interaction.readonly) tdAttrs[\"data-readonly\"] = true;\n if (marker?.level === \"error\") tdAttrs[\"data-invalid\"] = true;\n if (marker) tdAttrs[\"data-extable-diag-message\"] = marker.message;\n } else if (marker) {\n tdAttrs[\"data-extable-diag-message\"] = marker.message;\n }\n\n const rawNumbered = toRawValue(raw, valueRes.value, col);\n if (rawNumbered !== null) {\n tdAttrs[\"data-raw\"] = rawNumbered;\n } else {\n const rawStr = raw === null || raw === undefined ? \"\" : String(raw);\n tdAttrs[\"data-raw\"] = rawStr;\n }\n\n if (cssMode === \"inline\" || cssMode === \"both\") {\n const needsInline = cssMode === \"inline\" || Boolean(condRes.delta || cellStyle || formatted.color);\n const inlineStyle = needsInline ? serializeStyle(resolvedStyleToMap(resolvedWithFormat)) : \"\";\n if (inlineStyle) tdAttrs.style = inlineStyle;\n } else if (cssMode === \"external\" && cssBuilder) {\n const selector = `${rootSelector} tbody tr[data-row-id=\\\"${row.id}\\\"] td[data-col-key=\\\"${String(col.key)}\\\"]`;\n cssBuilder.addRule(selector, resolvedStyleToMap(resolvedWithFormat));\n }\n\n html.openTag(\"td\", tdAttrs);\n\n if (tagValues && tagValues.length) {\n html.openTag(\"div\", { class: \"extable-tag-list\" });\n tagValues.forEach((tag, index) => {\n html.openTag(\"span\", { class: \"extable-tag\" });\n html.openTag(\"span\", { class: \"extable-tag-label\" }).text(tag).closeTag(\"span\");\n html.openTag(\"button\", {\n type: \"button\",\n class: \"extable-tag-remove\",\n \"data-extable-tag-remove\": \"1\",\n \"data-extable-tag-index\": String(index),\n disabled: interaction.readonly || interaction.disabled,\n });\n html.text(\"×\");\n html.closeTag(\"button\");\n html.closeTag(\"span\");\n });\n html.closeTag(\"div\");\n } else if (isActionType && !textOverride && actionValue && actionLabel) {\n const actionAttrs: Record<string, string | number | boolean> = {\n class: col.type === \"button\" ? \"extable-action-button\" : \"extable-action-link\",\n \"data-extable-action\": col.type,\n };\n if (interaction.disabled) {\n actionAttrs.class = `${actionAttrs.class} extable-action-disabled`;\n }\n if (col.type === \"button\") {\n actionAttrs.type = \"button\";\n html.openTag(\"button\", actionAttrs);\n html.text(actionLabel);\n html.closeTag(\"button\");\n } else {\n html.openTag(\"span\", actionAttrs);\n html.text(actionLabel);\n html.closeTag(\"span\");\n }\n } else {\n html.text(actionLabel || formatted.text);\n }\n\n html.closeTag(\"td\");\n}\n\nfunction formatValue(value: unknown, col: ColumnSchema): { text: string; color?: string } {\n if (value === null || value === undefined) return { text: \"\" };\n if (col.type === \"button\") {\n const label = getButtonLabel(value);\n return { text: label || String(value) };\n }\n if (col.type === \"link\") {\n const label = getLinkLabel(value);\n return { text: label || String(value) };\n }\n if (col.type === \"tags\") {\n const tags = resolveTagValues(value);\n if (tags) return { text: tags.join(\", \") };\n }\n if (col.type === \"enum\") {\n if (value && typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n if (obj.kind === \"enum\" && typeof obj.value === \"string\") {\n return { text: obj.value };\n }\n }\n }\n if (col.type === \"boolean\") {\n if (col.format === \"checkbox\" || !col.format) {\n return { text: value ? \"☑\" : \"☐\" };\n }\n if (Array.isArray(col.format) && col.format.length >= 2) {\n return { text: value ? String(col.format[0]) : String(col.format[1]) };\n }\n return { text: value ? String(col.format) : \"\" };\n }\n if (col.type === \"number\" && typeof value === \"number\") {\n const num = value;\n const fmt = col.format as NumberFormat | undefined;\n const token = fmt?.format ?? \"decimal\";\n if (token === \"scientific\") {\n const text = formatNumberForEdit(num, { format: \"scientific\", precision: fmt?.precision });\n const color = fmt?.negativeRed && num < 0 ? \"#b91c1c\" : undefined;\n return { text, color };\n }\n\n const opts: Intl.NumberFormatOptions = {};\n if (fmt?.scale !== undefined) {\n opts.minimumFractionDigits = fmt.scale;\n opts.maximumFractionDigits = fmt.scale;\n }\n opts.useGrouping = Boolean(fmt?.thousandSeparator);\n const text = new Intl.NumberFormat(\"en-US\", opts).format(num);\n const color = fmt?.negativeRed && num < 0 ? \"#b91c1c\" : undefined;\n return { text, color };\n }\n\n if ((col.type === \"int\" || col.type === \"uint\") && typeof value === \"number\") {\n const num = value;\n const fmt = col.format as IntegerFormat | undefined;\n const token = fmt?.format ?? \"decimal\";\n if (token === \"binary\" || token === \"octal\" || token === \"hex\") {\n const text = formatIntegerWithPrefix(num, token);\n const color = fmt?.negativeRed && num < 0 ? \"#b91c1c\" : undefined;\n return { text, color };\n }\n\n const opts: Intl.NumberFormatOptions = {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n useGrouping: Boolean(fmt?.thousandSeparator),\n };\n const text = new Intl.NumberFormat(\"en-US\", opts).format(num);\n const color = fmt?.negativeRed && num < 0 ? \"#b91c1c\" : undefined;\n return { text, color };\n }\n\n if (\n (col.type === \"date\" || col.type === \"time\" || col.type === \"datetime\") &&\n (value instanceof Date || typeof value === \"string\")\n ) {\n const fmtValue = col.format as string | undefined;\n const fmt =\n col.type === \"date\"\n ? coerceDatePattern(fmtValue, \"date\")\n : col.type === \"time\"\n ? coerceDatePattern(fmtValue, \"time\")\n : coerceDatePattern(fmtValue, \"datetime\");\n let d: Date | null = null;\n if (value instanceof Date) d = value;\n else {\n d = parseIsoDate(value);\n }\n if (!d) return { text: String(value) };\n return { text: formatDateLite(d, fmt) };\n }\n return { text: String(value) };\n}\n\nfunction resolveTagValues(value: unknown): string[] | null {\n if (Array.isArray(value) && value.every((v) => typeof v === \"string\")) {\n return value as string[];\n }\n if (value && typeof value === \"object\") {\n const obj = value as Record<string, unknown>;\n if (obj.kind === \"tags\") {\n const values = obj.values;\n if (Array.isArray(values)) {\n return values.filter((v): v is string => typeof v === \"string\");\n }\n }\n }\n return null;\n}\n\nfunction resolvedStyleToMap(style: ResolvedCellStyle): CSSStyleMap {\n const css: CSSStyleMap = {};\n if (style.backgroundColor) css.backgroundColor = style.backgroundColor;\n if (style.textColor) css.color = style.textColor;\n if (style.bold) css.fontWeight = \"600\";\n if (style.italic) css.fontStyle = \"italic\";\n const dec: string[] = [];\n if (style.underline) dec.push(\"underline\");\n if (style.strike) dec.push(\"line-through\");\n if (dec.length) css.textDecorationLine = dec.join(\" \");\n return css;\n}\n\nfunction getColumnSortDir(view: View, colKey: string): \"asc\" | \"desc\" | null {\n const s = view.sorts?.[0];\n if (!s) return null;\n return s.key === colKey ? s.dir : null;\n}\n\nfunction hasActiveColumnFilter(view: View, colKey: string): boolean {\n const hasValues = (view.filters ?? []).some((f) => {\n const vf = f as ViewFilterValues;\n return vf?.kind === \"values\" && vf.key === colKey;\n });\n if (hasValues) return true;\n const diag = view.columnDiagnostics?.[colKey];\n return Boolean(diag?.errors || diag?.warnings);\n}\n\nfunction svgFunnel() {\n return `\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M3 5h18l-7 8v6l-4 2v-8L3 5z\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linejoin=\"round\"/>\n </svg>\n `.trim();\n}\n\nfunction svgArrow(dir: \"asc\" | \"desc\") {\n const d = dir === \"asc\" ? \"M12 6l6 8H6l6-8z\" : \"M12 18l-6-8h12l-6 8z\";\n return `\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"${d}\" fill=\"currentColor\"/>\n </svg>\n `.trim();\n}\n"],"names":["HTMLBuilder","tag","attrs","html","key","value","escapeHtml","content","text","serializeStyle","style","parts","prop","toKebabCase","CSSBuilder","selector","prev","options","minify","lines","body","input","m","renderTableHTML","cssMode","cssClassName","includeDataAttributes","includeAccessibilityAttributes","view","data","baseView","dataModel","DataModel","schema","effectiveView","rows","columns","resolveVisibleColumns","colWidths","getColumnWidths","cssBuilder","errors","rootSelector","col","baseStyle","resolvedStyleToMap","columnFormatToStyle","totalWidth","ROW_HEADER_WIDTH_PX","acc","w","tableAttrs","HEADER_HEIGHT_PX","rowHeaderAttrs","thAttrs","sortDir","getColumnSortDir","hasFilter","hasActiveColumnFilter","width","c","svgArrow","svgFunnel","hasFormulas","hasConditionalStyles","row","rowIndex","trAttrs","DEFAULT_ROW_HEIGHT_PX","rowHeader","displayIndex","renderCell","visibility","hidden","k","colMap","ordered","seen","order","isVisibleColumn","onFormulaError","onValidationError","tdClasses","interaction","wrap","align","condRes","cellStyle","withCond","mergeStyle","resolved","marker","raw","valueRes","textOverride","err","replacement","validationMsg","formatted","formatValue","resolvedWithFormat","tagValues","resolveTagValues","isActionType","actionValue","resolveButtonAction","resolveLinkAction","actionLabel","getButtonLabel","getLinkLabel","tdAttrs","rawNumbered","toRawValue","rawStr","inlineStyle","index","actionAttrs","tags","obj","num","fmt","formatNumberForEdit","color","opts","token","formatIntegerWithPrefix","fmtValue","coerceDatePattern","d","parseIsoDate","formatDateLite","v","values","css","dec","colKey","s","f","vf","diag","dir"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const isBrowser: boolean;
|
|
2
|
+
export declare function getDefaultLocale(): string;
|
|
3
|
+
export declare function getNavigator(): Navigator | {
|
|
4
|
+
language?: string;
|
|
5
|
+
userAgent?: string;
|
|
6
|
+
platform?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const ResizeObserverShim: typeof ResizeObserver | (new () => {
|
|
9
|
+
observe: () => void;
|
|
10
|
+
unobserve: () => void;
|
|
11
|
+
disconnect: () => void;
|
|
12
|
+
});
|
|
13
|
+
export declare function getRequestAnimationFrame(): (cb: FrameRequestCallback) => number;
|
|
14
|
+
export declare function getCancelAnimationFrame(): (id: number | ReturnType<typeof setTimeout>) => void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Schema } from "../types";
|
|
2
|
+
export interface SSROptions<T extends object = Record<string, unknown>> {
|
|
3
|
+
data: T[] | null | undefined;
|
|
4
|
+
schema: Schema<any>;
|
|
5
|
+
cssMode?: "inline" | "external" | "both";
|
|
6
|
+
wrapWithRoot?: boolean;
|
|
7
|
+
defaultClass?: string | string[];
|
|
8
|
+
defaultStyle?: Partial<CSSStyleDeclaration>;
|
|
9
|
+
includeStyles?: boolean;
|
|
10
|
+
includeRawAttributes?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface SSRResult {
|
|
13
|
+
html: string;
|
|
14
|
+
css?: string;
|
|
15
|
+
metadata: {
|
|
16
|
+
rowCount: number;
|
|
17
|
+
columnCount: number;
|
|
18
|
+
hasFormulas: boolean;
|
|
19
|
+
hasConditionalStyles: boolean;
|
|
20
|
+
errors: Array<{
|
|
21
|
+
row: number;
|
|
22
|
+
col: string;
|
|
23
|
+
message: string;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare function renderTableHTML<T extends object = Record<string, unknown>>(options: SSROptions<T>): SSRResult;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type CSSValue = string | number | null | undefined | false;
|
|
2
|
+
export type CSSStyleMap = Record<string, CSSValue>;
|
|
3
|
+
export declare function serializeStyle(style: CSSStyleMap): string;
|
|
4
|
+
export declare class CSSBuilder {
|
|
5
|
+
private rules;
|
|
6
|
+
addRule(selector: string, style: CSSStyleMap): void;
|
|
7
|
+
build(options?: {
|
|
8
|
+
minify?: boolean;
|
|
9
|
+
}): string;
|
|
10
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@extable/core",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -10,11 +10,17 @@
|
|
|
10
10
|
"import": "./dist/index.js",
|
|
11
11
|
"types": "./dist/index.d.ts"
|
|
12
12
|
},
|
|
13
|
-
"./
|
|
13
|
+
"./ssr": {
|
|
14
|
+
"import": "./dist/ssr/index.js",
|
|
15
|
+
"types": "./dist/ssr/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./style.css": "./style.css",
|
|
14
18
|
"./index.css": "./dist/index.css"
|
|
15
19
|
},
|
|
16
20
|
"files": [
|
|
17
|
-
"dist"
|
|
21
|
+
"dist",
|
|
22
|
+
"style.css",
|
|
23
|
+
"src/styles.css"
|
|
18
24
|
],
|
|
19
25
|
"publishConfig": {
|
|
20
26
|
"access": "public"
|
|
@@ -31,7 +37,7 @@
|
|
|
31
37
|
"format": "biome format --write ."
|
|
32
38
|
},
|
|
33
39
|
"dependencies": {
|
|
34
|
-
"@extable/sequence": "0.3.
|
|
40
|
+
"@extable/sequence": "0.3.4"
|
|
35
41
|
},
|
|
36
42
|
"devDependencies": {
|
|
37
43
|
"typescript": "^5.6.3"
|