react-markdown-table-ts 1.1.8 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -56
- package/dist/cellFormatter.d.ts +9 -0
- package/dist/index.cjs.js +51 -10
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +51 -10
- package/dist/index.esm.js.map +1 -1
- package/dist/types.d.ts +16 -4
- package/dist/utils.d.ts +4 -4
- package/package.json +1 -1
- package/dist/MarkdownTable.stories.d.ts +0 -156
- package/dist/jest.setup.d.ts +0 -2
- package/dist/jest.setup.js +0 -3
- package/dist/jest.setup.js.map +0 -1
- package/dist/src/MarkdownTable.stories.d.ts +0 -156
- package/dist/src/MarkdownTable.stories.js +0 -172
- package/dist/src/MarkdownTable.stories.js.map +0 -1
- package/dist/src/index.d.ts +0 -5
- package/dist/src/index.js +0 -78
- package/dist/src/index.js.map +0 -1
- package/dist/src/types.d.ts +0 -123
- package/dist/src/types.js +0 -3
- package/dist/src/types.js.map +0 -1
- package/dist/src/utils.d.ts +0 -8
- package/dist/src/utils.js +0 -176
- package/dist/src/utils.js.map +0 -1
- package/dist/src/validation.d.ts +0 -19
- package/dist/src/validation.js +0 -106
- package/dist/src/validation.js.map +0 -1
- package/dist/stories/Button.d.ts +0 -15
- package/dist/stories/Button.stories.d.ts +0 -23
- package/dist/stories/Header.d.ts +0 -12
- package/dist/stories/Header.stories.d.ts +0 -18
- package/dist/stories/Page.d.ts +0 -3
- package/dist/stories/Page.stories.d.ts +0 -13
- package/dist/test/MarkdownTable.test.d.ts +0 -1
- package/dist/test/MarkdownTable.test.js +0 -91
- package/dist/test/MarkdownTable.test.js.map +0 -1
- package/dist/test/utils.test.d.ts +0 -1
- package/dist/test/utils.test.js +0 -234
- package/dist/test/utils.test.js.map +0 -1
- package/dist/test/validation.test.d.ts +0 -1
- package/dist/test/validation.test.js +0 -86
- package/dist/test/validation.test.js.map +0 -1
package/README.md
CHANGED
@@ -7,16 +7,27 @@
|
|
7
7
|
[](https://github.com/keithwalsh/react-markdown-table-ts/commits/HEAD/)
|
8
8
|
|
9
9
|
|  |  |
|
10
|
-
|
11
|
-
| `'light'` theme | `'dark'` theme
|
10
|
+
|------------------------------------------|----------------------------------------|
|
11
|
+
| `'light'` theme | `'dark'` theme |
|
12
12
|
|
13
13
|
## Overview
|
14
|
-
|
14
|
+
|
15
|
+
This library provides a React component for generating and displaying formatted Markdown tables with syntax highlighting. The core component is `MarkdownTable` which converts structured data into properly formatted Markdown table syntax. Columns of variable width maintain consistent spacing across all rows, ensuring vertical alignment of delimiters. For syntax highlighting and line numbering, Prism.js is used within a `<pre>` HTML element.
|
15
16
|
|
16
17
|
## API
|
18
|
+
|
17
19
|
```typescript
|
20
|
+
interface CellData {
|
21
|
+
content: string; // The text content of the cell
|
22
|
+
alignment?: Alignment; // Text alignment ('left', 'center', 'right')
|
23
|
+
bold?: boolean; // Bold formatting
|
24
|
+
italic?: boolean; // Italic formatting
|
25
|
+
code?: boolean; // Code (monospace) formatting
|
26
|
+
link?: string; // Optional URL for cell content
|
27
|
+
}
|
28
|
+
|
18
29
|
interface MarkdownTableProps {
|
19
|
-
inputData?: string[][] | null;
|
30
|
+
inputData?: (string | CellData)[][] | null; // Table data as strings or CellData objects
|
20
31
|
columnAlignments?: readonly Alignment[];
|
21
32
|
isCompact?: boolean;
|
22
33
|
hasPadding?: boolean;
|
@@ -31,24 +42,26 @@ interface MarkdownTableProps {
|
|
31
42
|
onGenerate?: (markdownTableString: string) => void;
|
32
43
|
}
|
33
44
|
```
|
45
|
+
|
34
46
|
| Prop | Type | Default | Description |
|
35
|
-
|
36
|
-
| `inputData`
|
37
|
-
| `columnAlignments`
|
38
|
-
| `isCompact`
|
39
|
-
| `hasPadding`
|
40
|
-
| `hasTabs`
|
41
|
-
| `hasHeader`
|
42
|
-
| `convertLineBreaks`
|
43
|
-
| `topPadding`
|
44
|
-
| `theme`
|
45
|
-
| `className`
|
46
|
-
| `preStyle`
|
47
|
-
| `minWidth`
|
48
|
-
| `onGenerate`
|
47
|
+
|---------------------|----------------------------------------|-------------|------------------------------------------------------------------------------------|
|
48
|
+
| `inputData` | `(string \| CellData)[][] \| null` | `null` | Table data as strings or CellData objects for rich text formatting |
|
49
|
+
| `columnAlignments` | `readonly Alignment[]` | `[]` | Acceptable values are 'left', 'center', 'right', 'justify', or 'none' |
|
50
|
+
| `isCompact` | `boolean` | `false` | Disables column width alignment to provide a more compact markdown table string |
|
51
|
+
| `hasPadding` | `boolean` | `true` | One space added before and after the content in each cell |
|
52
|
+
| `hasTabs` | `boolean` | `false` | Adds a tab character after each \| and before the content |
|
53
|
+
| `hasHeader` | `boolean` | `true` | Indicates whether the first row of `data` is a header |
|
54
|
+
| `convertLineBreaks` | `boolean` | `false` | Replace newlines with <br> tags in table cells |
|
55
|
+
| `topPadding` | `number` | `16` | Controls the padding-top (in pixels) of the \<pre\> element display |
|
56
|
+
| `theme` | `'light' \| 'dark'` | `light` | Controls the color scheme of the \<pre\> element display |
|
57
|
+
| `className` | `string` | `undefined` | Class will be applied to the \<pre\> element display |
|
58
|
+
| `preStyle` | `React.CSSProperties` | `undefined` | Allows direct styling of the display with CSS properties |
|
59
|
+
| `minWidth` | `number` | `undefined` | Optional minimum width in pixels for the table container |
|
60
|
+
| `onGenerate` | `(markdownTableString: string) => void`| `undefined` | Callback to receive the generated Markdown table string |
|
61
|
+
|
49
62
|
## Usage Patterns
|
50
63
|
|
51
|
-
1. **Basic Table
|
64
|
+
1. **Basic String Table**:
|
52
65
|
```typescript
|
53
66
|
<MarkdownTable
|
54
67
|
inputData={[
|
@@ -57,20 +70,44 @@ interface MarkdownTableProps {
|
|
57
70
|
]}
|
58
71
|
/>
|
59
72
|
```
|
60
|
-
|
73
|
+
|
74
|
+
2. **Rich Text Formatting with CellData**:
|
61
75
|
```typescript
|
62
76
|
<MarkdownTable
|
63
|
-
inputData={
|
64
|
-
|
77
|
+
inputData={[
|
78
|
+
[
|
79
|
+
{ content: "Package ID", alignment: "left", bold: true },
|
80
|
+
{ content: "Status", alignment: "center", bold: true }
|
81
|
+
],
|
82
|
+
[
|
83
|
+
{ content: "PKG-001", code: true },
|
84
|
+
{ content: "In Transit", italic: true }
|
85
|
+
],
|
86
|
+
[
|
87
|
+
{ content: "PKG-002", code: true },
|
88
|
+
{ content: "Delivered", bold: true }
|
89
|
+
]
|
90
|
+
]}
|
91
|
+
columnAlignments={['left', 'center']}
|
65
92
|
/>
|
66
93
|
```
|
67
|
-
|
94
|
+
|
95
|
+
3. **Links and Mixed Formatting**:
|
68
96
|
```typescript
|
69
97
|
<MarkdownTable
|
70
|
-
inputData={
|
71
|
-
|
98
|
+
inputData={[
|
99
|
+
[
|
100
|
+
{ content: "Product", bold: true },
|
101
|
+
{ content: "Details", bold: true }
|
102
|
+
],
|
103
|
+
[
|
104
|
+
{ content: "Item 1", link: "https://example.com/item1" },
|
105
|
+
{ content: "New!", italic: true }
|
106
|
+
]
|
107
|
+
]}
|
72
108
|
/>
|
73
109
|
```
|
110
|
+
|
74
111
|
4. **Setting Minimum Width**:
|
75
112
|
```typescript
|
76
113
|
<MarkdownTable
|
@@ -82,34 +119,31 @@ interface MarkdownTableProps {
|
|
82
119
|
## Behaviors
|
83
120
|
|
84
121
|
1. **Input Validation**:
|
85
|
-
- Input must be non-null 2D
|
86
|
-
- All
|
87
|
-
- Empty arrays are not allowed
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
-
|
92
|
-
-
|
93
|
-
-
|
94
|
-
-
|
95
|
-
|
96
|
-
3. **
|
97
|
-
-
|
98
|
-
-
|
99
|
-
-
|
100
|
-
|
101
|
-
4. **
|
102
|
-
-
|
103
|
-
-
|
104
|
-
-
|
105
|
-
|
106
|
-
##
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
2. **Header Generation**:
|
114
|
-
- Auto-generates A, B, C... headers when `hasHeader={false}`
|
115
|
-
- Supports custom headers via first row when `hasHeader={true}`
|
122
|
+
- Input must be non-null 2D array of strings or CellData objects
|
123
|
+
- All cells must contain valid content
|
124
|
+
- Empty arrays are not allowed
|
125
|
+
|
126
|
+
2. **Markdown Formatting**:
|
127
|
+
- Bold text is wrapped in `**`
|
128
|
+
- Italic text is wrapped in `*`
|
129
|
+
- Code is wrapped in backticks (\`)
|
130
|
+
- Links are formatted as `[text](url)`
|
131
|
+
- Alignments are reflected in the table separator row
|
132
|
+
|
133
|
+
3. **Theme Support**:
|
134
|
+
- Light theme (default) for standard markdown appearance
|
135
|
+
- Dark theme for better visibility on dark backgrounds
|
136
|
+
- Custom styling through `className` and `preStyle` props
|
137
|
+
|
138
|
+
4. **Responsive Design**:
|
139
|
+
- Tables adjust to content width by default
|
140
|
+
- Minimum width can be enforced through `minWidth` prop
|
141
|
+
- Compact mode available for dense data presentation
|
142
|
+
|
143
|
+
## Contributing
|
144
|
+
|
145
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
146
|
+
|
147
|
+
## License
|
148
|
+
|
149
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import { CellData } from './types';
|
2
|
+
/**
|
3
|
+
* Formats cell content with markdown syntax based on CellData formatting options
|
4
|
+
*/
|
5
|
+
export declare function formatCellContent(cell: string | CellData): string;
|
6
|
+
/**
|
7
|
+
* Gets the alignment for a cell, prioritizing cell-specific alignment over column alignment
|
8
|
+
*/
|
9
|
+
export declare function getCellAlignment(cell: string | CellData, columnAlignment?: string): string;
|
package/dist/index.cjs.js
CHANGED
@@ -4068,14 +4068,53 @@ var Prism$1 = /*@__PURE__*/getDefaultExportFromCjs(prismExports);
|
|
4068
4068
|
|
4069
4069
|
}());
|
4070
4070
|
|
4071
|
+
/**
|
4072
|
+
* Formats cell content with markdown syntax based on CellData formatting options
|
4073
|
+
*/
|
4074
|
+
function formatCellContent(cell) {
|
4075
|
+
if (typeof cell === 'string') {
|
4076
|
+
return cell;
|
4077
|
+
}
|
4078
|
+
var content = cell.content;
|
4079
|
+
// Apply code formatting first (if present) as it should override other formatting
|
4080
|
+
if (cell.code) {
|
4081
|
+
content = "`".concat(content, "`");
|
4082
|
+
return content; // Code formatting should not be combined with other formatting
|
4083
|
+
}
|
4084
|
+
// Apply bold formatting
|
4085
|
+
if (cell.bold) {
|
4086
|
+
content = "**".concat(content, "**");
|
4087
|
+
}
|
4088
|
+
// Apply italic formatting
|
4089
|
+
if (cell.italic) {
|
4090
|
+
content = "*".concat(content, "*");
|
4091
|
+
}
|
4092
|
+
// Apply link formatting last
|
4093
|
+
if (cell.link) {
|
4094
|
+
content = "[".concat(content, "](").concat(cell.link, ")");
|
4095
|
+
}
|
4096
|
+
return content;
|
4097
|
+
}
|
4098
|
+
/**
|
4099
|
+
* Gets the alignment for a cell, prioritizing cell-specific alignment over column alignment
|
4100
|
+
*/
|
4101
|
+
function getCellAlignment(cell, columnAlignment) {
|
4102
|
+
if (typeof cell === 'string') {
|
4103
|
+
return columnAlignment || 'none';
|
4104
|
+
}
|
4105
|
+
return cell.alignment || columnAlignment || 'none';
|
4106
|
+
}
|
4107
|
+
|
4071
4108
|
var CellFormatter = /** @class */ (function () {
|
4072
4109
|
function CellFormatter(config) {
|
4073
4110
|
this.config = config;
|
4074
4111
|
this.padding = this.config.useTabs ? '\t' : (this.config.hasPadding ? ' ' : '');
|
4075
4112
|
}
|
4076
|
-
CellFormatter.prototype.formatCell = function (
|
4113
|
+
CellFormatter.prototype.formatCell = function (cell, alignment, width) {
|
4114
|
+
var content = formatCellContent(cell);
|
4115
|
+
var cellAlignment = getCellAlignment(cell, alignment);
|
4077
4116
|
var totalWidth = width;
|
4078
|
-
switch (
|
4117
|
+
switch (cellAlignment) {
|
4079
4118
|
case 'right':
|
4080
4119
|
return "".concat(this.padding).concat(content.padStart(totalWidth)).concat(this.padding);
|
4081
4120
|
case 'center': {
|
@@ -4128,7 +4167,7 @@ var TableFormatter = /** @class */ (function () {
|
|
4128
4167
|
cell = replaceNewlinesInCell(cell);
|
4129
4168
|
}
|
4130
4169
|
var alignment = _this.adjustedAlignments[i];
|
4131
|
-
var width = _this.config.columnWidths ? _this.config.columnWidths[i] : cell.length;
|
4170
|
+
var width = _this.config.columnWidths ? _this.config.columnWidths[i] : formatCellContent(cell).length;
|
4132
4171
|
return _this.cellFormatter.formatCell(cell, alignment, width);
|
4133
4172
|
});
|
4134
4173
|
return "|".concat(formattedCells.join('|'), "|");
|
@@ -4152,7 +4191,8 @@ function calculateColumnWidths(tableRows, maxColumnCount) {
|
|
4152
4191
|
var _a;
|
4153
4192
|
for (var i = 0; i < maxColumnCount; i++) {
|
4154
4193
|
var cell = (_a = row[i]) !== null && _a !== void 0 ? _a : '';
|
4155
|
-
|
4194
|
+
var content = formatCellContent(cell);
|
4195
|
+
widths[i] = Math.max(widths[i], content.length);
|
4156
4196
|
}
|
4157
4197
|
});
|
4158
4198
|
return widths;
|
@@ -4191,7 +4231,8 @@ function generateMarkdownTableString(inputData, columnAlignments, canAdjustColum
|
|
4191
4231
|
return "".concat(headerRow, "\n").concat(alignmentRow, "\n").concat(bodyRows).trimEnd();
|
4192
4232
|
}
|
4193
4233
|
function replaceNewlinesInCell(cell) {
|
4194
|
-
|
4234
|
+
var content = typeof cell === 'string' ? cell : cell.content;
|
4235
|
+
return content.replace(/\n/g, '<br>');
|
4195
4236
|
}
|
4196
4237
|
function getColumnName(index) {
|
4197
4238
|
var columnName = '';
|
@@ -4227,10 +4268,10 @@ var MarkdownTableError = /** @class */ (function (_super) {
|
|
4227
4268
|
*/
|
4228
4269
|
function validateInputData(inputData) {
|
4229
4270
|
if (inputData === null || !Array.isArray(inputData)) {
|
4230
|
-
throw new MarkdownTableError(
|
4271
|
+
throw new MarkdownTableError('The \'data\' prop must be a two-dimensional array.');
|
4231
4272
|
}
|
4232
4273
|
if (inputData.length === 0) {
|
4233
|
-
throw new MarkdownTableError(
|
4274
|
+
throw new MarkdownTableError('The \'data\' array must contain at least one row.');
|
4234
4275
|
}
|
4235
4276
|
}
|
4236
4277
|
|
@@ -4240,7 +4281,7 @@ var DARK_THEME_CSS = "\ncode[class*=language-],pre[class*=language-]{color:#f8f8
|
|
4240
4281
|
var getTableData = function (inputData, hasHeader) {
|
4241
4282
|
return hasHeader
|
4242
4283
|
? { inputDataHeader: inputData[0], inputDataBody: inputData.slice(1) }
|
4243
|
-
: { inputDataHeader: generateAlphabetHeaders(inputData[0].length), inputDataBody: inputData };
|
4284
|
+
: { inputDataHeader: generateAlphabetHeaders(inputData[0].length).map(function (header) { return ({ content: header }); }), inputDataBody: inputData };
|
4244
4285
|
};
|
4245
4286
|
var generateTableSyntax = function (inputData, hasHeader, columnAlignments, adjustColumnWidths, hasTabs, canReplaceNewlines, hasPadding) {
|
4246
4287
|
try {
|
@@ -4267,7 +4308,7 @@ var applySyntaxHighlighting = function (preElementRef, markdownTableSyntax) {
|
|
4267
4308
|
}, [markdownTableSyntax]);
|
4268
4309
|
};
|
4269
4310
|
var MarkdownTable = function (_a) {
|
4270
|
-
var _b = _a.inputData, inputData = _b === void 0 ? null : _b, _c = _a.hasHeader, hasHeader = _c === void 0 ? true : _c, _d = _a.columnAlignments, columnAlignments = _d === void 0 ? [] : _d, _e = _a.isCompact, isCompact = _e === void 0 ? false : _e, _f = _a.hasTabs, hasTabs = _f === void 0 ? false : _f, _g = _a.hasPadding, hasPadding = _g === void 0 ? true : _g, _h = _a.convertLineBreaks, convertLineBreaks = _h === void 0 ? false : _h, className = _a.className, onGenerate = _a.onGenerate, _j = _a.theme, theme = _j === void 0 ? 'light' : _j, preStyle = _a.preStyle
|
4311
|
+
var _b = _a.inputData, inputData = _b === void 0 ? null : _b, _c = _a.hasHeader, hasHeader = _c === void 0 ? true : _c, _d = _a.columnAlignments, columnAlignments = _d === void 0 ? [] : _d, _e = _a.isCompact, isCompact = _e === void 0 ? false : _e, _f = _a.hasTabs, hasTabs = _f === void 0 ? false : _f, _g = _a.hasPadding, hasPadding = _g === void 0 ? true : _g, _h = _a.convertLineBreaks, convertLineBreaks = _h === void 0 ? false : _h, className = _a.className, onGenerate = _a.onGenerate, _j = _a.theme, theme = _j === void 0 ? 'light' : _j, preStyle = _a.preStyle, _k = _a.topPadding, topPadding = _k === void 0 ? 16 : _k, minWidth = _a.minWidth;
|
4271
4312
|
var adjustColumnWidths = !isCompact;
|
4272
4313
|
var preElementRef = require$$0.useRef(null);
|
4273
4314
|
var markdownTableSyntax = require$$0.useMemo(function () { return generateTableSyntax(inputData, hasHeader, columnAlignments, adjustColumnWidths, hasTabs, convertLineBreaks, hasPadding); }, [
|
@@ -4285,7 +4326,7 @@ var MarkdownTable = function (_a) {
|
|
4285
4326
|
}
|
4286
4327
|
}, [markdownTableSyntax, onGenerate]);
|
4287
4328
|
applySyntaxHighlighting(preElementRef, markdownTableSyntax);
|
4288
|
-
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("style", { children: [theme === 'light' ? LIGHT_THEME_CSS : DARK_THEME_CSS, "\n pre {\n position: relative;\n }\n pre::before {\n position: absolute;\n top: 8px;\n left: 12px;\n color: ".concat(theme === 'light' ? '#666' : '#999', ";\n letter-spacing: 2px;\n font-size: 12px;\n }\n ")] }), jsxRuntimeExports.jsx("div", { id: "MarkdownTable", style: {
|
4329
|
+
return (jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("style", { children: [theme === 'light' ? LIGHT_THEME_CSS : DARK_THEME_CSS, "\n pre {\n position: relative;\n padding-top: ".concat(topPadding, "px !important;\n }\n pre::before {\n position: absolute;\n top: 8px;\n left: 12px;\n color: ").concat(theme === 'light' ? '#666' : '#999', ";\n letter-spacing: 2px;\n font-size: 12px;\n }\n ")] }), jsxRuntimeExports.jsx("div", { id: "MarkdownTable", style: {
|
4289
4330
|
position: 'relative',
|
4290
4331
|
isolation: 'isolate',
|
4291
4332
|
display: 'inline-block'
|