@sveltia/ui 0.24.0 → 0.24.2
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/components/listbox/listbox.svelte +1 -1
- package/dist/components/listbox/option.svelte +7 -2
- package/dist/components/text-editor/core.js +2 -1
- package/dist/components/text-editor/lexical-root.svelte +6 -0
- package/dist/components/text-editor/transformers/table.d.ts +4 -0
- package/dist/components/text-editor/transformers/table.js +209 -0
- package/package.json +23 -22
|
@@ -89,7 +89,6 @@
|
|
|
89
89
|
.option :global(button) {
|
|
90
90
|
flex: none;
|
|
91
91
|
display: flex;
|
|
92
|
-
justify-content: space-between;
|
|
93
92
|
gap: 4px;
|
|
94
93
|
margin: 0 !important;
|
|
95
94
|
border-radius: var(--sui-option-border-radius);
|
|
@@ -101,6 +100,12 @@
|
|
|
101
100
|
text-overflow: ellipsis;
|
|
102
101
|
white-space: nowrap;
|
|
103
102
|
}
|
|
103
|
+
.option :global(button) :global(*) {
|
|
104
|
+
flex: none;
|
|
105
|
+
}
|
|
106
|
+
.option :global(button) :global(.label) {
|
|
107
|
+
flex: auto;
|
|
108
|
+
}
|
|
104
109
|
.option.wrap :global(button) {
|
|
105
110
|
white-space: normal;
|
|
106
111
|
}
|
|
@@ -115,6 +120,6 @@
|
|
|
115
120
|
.option :global(.icon.check) {
|
|
116
121
|
margin: -2px;
|
|
117
122
|
}
|
|
118
|
-
.option :global(button[aria-selected="true"]) :global(.icon) {
|
|
123
|
+
.option :global(button[aria-selected="true"]) :global(.icon.check) {
|
|
119
124
|
color: var(--sui-primary-accent-color-text);
|
|
120
125
|
}</style>
|
|
@@ -52,8 +52,9 @@ import {
|
|
|
52
52
|
} from 'lexical';
|
|
53
53
|
import prismComponents from 'prismjs/components';
|
|
54
54
|
import { blockButtonTypes, textFormatButtonTypes } from '.';
|
|
55
|
+
import { TABLE } from './transformers/table';
|
|
55
56
|
|
|
56
|
-
const allTransformers = [...TRANSFORMERS];
|
|
57
|
+
const allTransformers = [...TRANSFORMERS, TABLE];
|
|
57
58
|
|
|
58
59
|
/**
|
|
59
60
|
* Lexical editor configuration.
|
|
@@ -195,6 +195,12 @@
|
|
|
195
195
|
.lexical-root :global([data-lexical-text=true]) {
|
|
196
196
|
cursor: text;
|
|
197
197
|
}
|
|
198
|
+
.lexical-root :global(th) > :global(p),
|
|
199
|
+
.lexical-root :global(td) > :global(p) {
|
|
200
|
+
margin: 0;
|
|
201
|
+
white-space: normal;
|
|
202
|
+
word-break: normal;
|
|
203
|
+
}
|
|
198
204
|
|
|
199
205
|
:root[data-theme=light] .lexical-root :global(.token.comment),
|
|
200
206
|
:root[data-theme=light] .lexical-root :global(.token.prolog),
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// Adopted from https://github.com/facebook/lexical/blob/main/packages/lexical-playground/src/plugins/MarkdownTransformers/index.ts
|
|
2
|
+
|
|
3
|
+
/* eslint-disable jsdoc/require-jsdoc */
|
|
4
|
+
/* eslint-disable jsdoc/require-returns-description */
|
|
5
|
+
/* eslint-disable jsdoc/require-param-description */
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
TRANSFORMERS,
|
|
9
|
+
$convertFromMarkdownString as convertFromMarkdownString,
|
|
10
|
+
$convertToMarkdownString as convertToMarkdownString,
|
|
11
|
+
} from '@lexical/markdown';
|
|
12
|
+
import {
|
|
13
|
+
TableCellHeaderStates,
|
|
14
|
+
TableCellNode,
|
|
15
|
+
TableNode,
|
|
16
|
+
TableRowNode,
|
|
17
|
+
$createTableCellNode as createTableCellNode,
|
|
18
|
+
$createTableNode as createTableNode,
|
|
19
|
+
$createTableRowNode as createTableRowNode,
|
|
20
|
+
$isTableCellNode as isTableCellNode,
|
|
21
|
+
$isTableNode as isTableNode,
|
|
22
|
+
$isTableRowNode as isTableRowNode,
|
|
23
|
+
} from '@lexical/table';
|
|
24
|
+
import { $isParagraphNode as isParagraphNode, $isTextNode as isTextNode } from 'lexical';
|
|
25
|
+
|
|
26
|
+
const TABLE_ROW_REG_EXP = /^(?:\|)(.+)(?:\|)\s?$/;
|
|
27
|
+
const TABLE_ROW_DIVIDER_REG_EXP = /^(\| ?:?-*:? ?)+\|\s?$/;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns the number of columns in the table.
|
|
31
|
+
* @param {TableNode} table
|
|
32
|
+
* @returns {number}
|
|
33
|
+
*/
|
|
34
|
+
function getTableColumnsSize(table) {
|
|
35
|
+
const row = table.getFirstChild();
|
|
36
|
+
|
|
37
|
+
return isTableRowNode(row) ? row.getChildrenSize() : 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Creates a table cell with the given text content.
|
|
42
|
+
* @param {string} textContent
|
|
43
|
+
* @returns {TableCellNode}
|
|
44
|
+
*/
|
|
45
|
+
const createTableCell = (textContent) => {
|
|
46
|
+
textContent = textContent.replace(/\\n/g, '\n');
|
|
47
|
+
|
|
48
|
+
const cell = createTableCellNode(TableCellHeaderStates.NO_STATUS);
|
|
49
|
+
|
|
50
|
+
convertFromMarkdownString(textContent, TRANSFORMERS, cell);
|
|
51
|
+
|
|
52
|
+
return cell;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Maps the given text content to an array of table cells.
|
|
57
|
+
* @param {string} textContent
|
|
58
|
+
* @returns {TableCellNode[] | null}
|
|
59
|
+
*/
|
|
60
|
+
const mapToTableCells = (textContent) => {
|
|
61
|
+
const [, match] = textContent.match(TABLE_ROW_REG_EXP) ?? [];
|
|
62
|
+
|
|
63
|
+
if (!match) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return match.split('|').map((text) => createTableCell(text));
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @type {import('@lexical/markdown').ElementTransformer}
|
|
72
|
+
*/
|
|
73
|
+
export const TABLE = {
|
|
74
|
+
dependencies: [TableNode, TableRowNode, TableCellNode],
|
|
75
|
+
export: (node) => {
|
|
76
|
+
if (!isTableNode(node)) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** @type {string[]} */
|
|
81
|
+
const output = [];
|
|
82
|
+
|
|
83
|
+
node.getChildren().forEach((row) => {
|
|
84
|
+
/** @type {string[]} */
|
|
85
|
+
const rowOutput = [];
|
|
86
|
+
|
|
87
|
+
if (!isTableRowNode(row)) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let isHeaderRow = false;
|
|
92
|
+
|
|
93
|
+
row.getChildren().forEach((cell) => {
|
|
94
|
+
// It’s TableCellNode so it’s just to make flow happy
|
|
95
|
+
if (isTableCellNode(cell)) {
|
|
96
|
+
rowOutput.push(convertToMarkdownString(TRANSFORMERS, cell).replace(/\n/g, '\\n').trim());
|
|
97
|
+
|
|
98
|
+
if (cell.__headerState === TableCellHeaderStates.ROW) {
|
|
99
|
+
isHeaderRow = true;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
output.push(`| ${rowOutput.join(' | ')} |`);
|
|
105
|
+
|
|
106
|
+
if (isHeaderRow) {
|
|
107
|
+
output.push(`| ${rowOutput.map(() => '---').join(' | ')} |`);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return output.join('\n');
|
|
112
|
+
},
|
|
113
|
+
regExp: TABLE_ROW_REG_EXP,
|
|
114
|
+
replace: (parentNode, _children, [textContent]) => {
|
|
115
|
+
// Header row
|
|
116
|
+
if (TABLE_ROW_DIVIDER_REG_EXP.test(textContent)) {
|
|
117
|
+
const table = parentNode.getPreviousSibling();
|
|
118
|
+
|
|
119
|
+
if (!table || !isTableNode(table)) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const rows = table.getChildren();
|
|
124
|
+
const lastRow = rows[rows.length - 1];
|
|
125
|
+
|
|
126
|
+
if (!lastRow || !isTableRowNode(lastRow)) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Add header state to row cells
|
|
131
|
+
lastRow.getChildren().forEach((cell) => {
|
|
132
|
+
if (!isTableCellNode(cell)) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
cell.setHeaderStyles(TableCellHeaderStates.ROW, TableCellHeaderStates.ROW);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Remove line
|
|
140
|
+
parentNode.remove();
|
|
141
|
+
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const matchCells = mapToTableCells(textContent);
|
|
146
|
+
|
|
147
|
+
if (!matchCells) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const rows = [matchCells];
|
|
152
|
+
let sibling = parentNode.getPreviousSibling();
|
|
153
|
+
let maxCells = matchCells.length;
|
|
154
|
+
|
|
155
|
+
while (sibling) {
|
|
156
|
+
if (!isParagraphNode(sibling)) {
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (sibling.getChildrenSize() !== 1) {
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const firstChild = sibling.getFirstChild();
|
|
165
|
+
|
|
166
|
+
if (!isTextNode(firstChild)) {
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const cells = mapToTableCells(firstChild.getTextContent());
|
|
171
|
+
|
|
172
|
+
if (!cells) {
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
maxCells = Math.max(maxCells, cells.length);
|
|
177
|
+
rows.unshift(cells);
|
|
178
|
+
|
|
179
|
+
const previousSibling = sibling.getPreviousSibling();
|
|
180
|
+
|
|
181
|
+
sibling.remove();
|
|
182
|
+
sibling = previousSibling;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const table = createTableNode();
|
|
186
|
+
|
|
187
|
+
rows.forEach((cells) => {
|
|
188
|
+
const tableRow = createTableRowNode();
|
|
189
|
+
|
|
190
|
+
table.append(tableRow);
|
|
191
|
+
|
|
192
|
+
for (let i = 0; i < maxCells; i += 1) {
|
|
193
|
+
tableRow.append(i < cells.length ? cells[i] : createTableCell(''));
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const previousSibling = parentNode.getPreviousSibling();
|
|
198
|
+
|
|
199
|
+
if (isTableNode(previousSibling) && getTableColumnsSize(previousSibling) === maxCells) {
|
|
200
|
+
previousSibling.append(...table.getChildren());
|
|
201
|
+
parentNode.remove();
|
|
202
|
+
} else {
|
|
203
|
+
parentNode.replace(table);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
table.selectEnd();
|
|
207
|
+
},
|
|
208
|
+
type: 'element',
|
|
209
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sveltia/ui",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -28,19 +28,19 @@
|
|
|
28
28
|
"test:unit": "vitest"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@lexical/code": "^0.
|
|
32
|
-
"@lexical/dragon": "^0.
|
|
33
|
-
"@lexical/history": "^0.
|
|
34
|
-
"@lexical/link": "^0.
|
|
35
|
-
"@lexical/list": "^0.
|
|
36
|
-
"@lexical/markdown": "^0.
|
|
37
|
-
"@lexical/rich-text": "^0.
|
|
38
|
-
"@lexical/selection": "^0.
|
|
39
|
-
"@lexical/table": "^0.
|
|
40
|
-
"@lexical/utils": "^0.
|
|
31
|
+
"@lexical/code": "^0.25.0",
|
|
32
|
+
"@lexical/dragon": "^0.25.0",
|
|
33
|
+
"@lexical/history": "^0.25.0",
|
|
34
|
+
"@lexical/link": "^0.25.0",
|
|
35
|
+
"@lexical/list": "^0.25.0",
|
|
36
|
+
"@lexical/markdown": "^0.25.0",
|
|
37
|
+
"@lexical/rich-text": "^0.25.0",
|
|
38
|
+
"@lexical/selection": "^0.25.0",
|
|
39
|
+
"@lexical/table": "^0.25.0",
|
|
40
|
+
"@lexical/utils": "^0.25.0",
|
|
41
41
|
"@sveltia/utils": "^0.6.3",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
42
|
+
"lexical": "^0.25.0",
|
|
43
|
+
"prismjs": "^1.29.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"svelte": "^5.0.0"
|
|
@@ -48,31 +48,31 @@
|
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@playwright/test": "^1.50.1",
|
|
50
50
|
"@sveltejs/adapter-auto": "^4.0.0",
|
|
51
|
-
"@sveltejs/kit": "^2.17.
|
|
51
|
+
"@sveltejs/kit": "^2.17.2",
|
|
52
52
|
"@sveltejs/package": "^2.3.10",
|
|
53
53
|
"@sveltejs/vite-plugin-svelte": "5.0.3",
|
|
54
|
-
"cspell": "^8.17.
|
|
54
|
+
"cspell": "^8.17.5",
|
|
55
55
|
"eslint": "^8.57.1",
|
|
56
56
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
57
57
|
"eslint-config-prettier": "^10.0.1",
|
|
58
58
|
"eslint-plugin-import": "^2.31.0",
|
|
59
59
|
"eslint-plugin-jsdoc": "^50.6.3",
|
|
60
60
|
"eslint-plugin-svelte": "^2.46.1",
|
|
61
|
-
"postcss": "^8.5.
|
|
61
|
+
"postcss": "^8.5.3",
|
|
62
62
|
"postcss-html": "^1.8.0",
|
|
63
|
-
"prettier": "^3.5.
|
|
63
|
+
"prettier": "^3.5.2",
|
|
64
64
|
"prettier-plugin-svelte": "^3.3.3",
|
|
65
65
|
"sass": "^1.85.0",
|
|
66
66
|
"stylelint": "^16.14.1",
|
|
67
67
|
"stylelint-config-recommended-scss": "^14.1.0",
|
|
68
|
-
"stylelint-scss": "^6.11.
|
|
69
|
-
"svelte": "5.20.
|
|
68
|
+
"stylelint-scss": "^6.11.1",
|
|
69
|
+
"svelte": "5.20.2",
|
|
70
70
|
"svelte-check": "^4.1.4",
|
|
71
71
|
"svelte-i18n": "^4.0.1",
|
|
72
72
|
"svelte-preprocess": "^6.0.3",
|
|
73
73
|
"tslib": "^2.8.1",
|
|
74
|
-
"vite": "^6.1.
|
|
75
|
-
"vitest": "^3.0.
|
|
74
|
+
"vite": "^6.1.1",
|
|
75
|
+
"vitest": "^3.0.6"
|
|
76
76
|
},
|
|
77
77
|
"exports": {
|
|
78
78
|
".": {
|
|
@@ -94,7 +94,8 @@
|
|
|
94
94
|
},
|
|
95
95
|
"pnpm": {
|
|
96
96
|
"overrides": {
|
|
97
|
-
"cookie@<0.7.0": ">=0.7.0"
|
|
97
|
+
"cookie@<0.7.0": ">=0.7.0",
|
|
98
|
+
"esbuild@<=0.24.2": ">=0.25.0"
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
}
|