@rcarls/rc-textarea 0.3.1 → 0.4.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 CHANGED
@@ -18,7 +18,7 @@ Made with [Lit](https://lit.dev) and [Parchment](https://github.com/quilljs/parc
18
18
  - **Plugin API** - imperative decoration control + highlight.js / prism.js HTML compatibility bridge
19
19
  - **Line numbers, word wrap, auto-grow** - declarative features for common use cases
20
20
  - **Progressive enhancement** - wraps a native `<textarea>` for form submission, label association
21
- - **Undo/redo** - durable internally-tracked undo stack
21
+ - **Undo/redo** - durable internally tracked undo stack
22
22
 
23
23
  ---
24
24
 
@@ -242,23 +242,24 @@ The component reads inherited tokens where possible:
242
242
 
243
243
  ### Component Tokens
244
244
 
245
- | Token | Default | Use |
246
- | ----------------------------------------- | ------------------------------------- | ------------------------------------- |
247
- | `--rc-textarea-font-family` | `monospace` | Editor and gutter font family. |
248
- | `--rc-textarea-font-size` | `1em` | Editor and gutter font size. |
249
- | `--rc-textarea-line-height` | `1.5` | Editor and gutter line height. |
250
- | `--rc-textarea-padding` | `0.5em` | Editor and gutter padding. |
251
- | `--rc-textarea-background` | `Field` | Field background. |
252
- | `--rc-textarea-color` | `var(--rc-text, FieldText)` | Field text color. |
253
- | `--rc-textarea-caret-color` | `var(--rc-textarea-color, FieldText)` | Caret color. |
254
- | `--rc-textarea-border` | `1px solid ButtonBorder` | Field border. |
255
- | `--rc-textarea-border-radius` | `2px` | Field corner radius. |
256
- | `--rc-textarea-focus-outline` | `2px solid Highlight` | Focus ring. |
257
- | `--rc-textarea-active-line-bg` | `transparent` | Active line background. |
258
- | `--rc-textarea-gutter-bg` | `Canvas` | Gutter background. |
259
- | `--rc-textarea-gutter-color` | `GrayText` | Gutter text color. |
260
- | `--rc-textarea-gutter-border` | `1px solid ButtonBorder` | Gutter separator. |
261
- | `--rc-textarea-gutter-padding-inline-end` | `0.75em` | Space between gutter labels and text. |
245
+ | Token | Default | Use |
246
+ | ----------------------------------------- | ------------------------------------------- | ------------------------------------- |
247
+ | `--rc-textarea-font-family` | `monospace` | Editor font family. |
248
+ | `--rc-textarea-font-size` | `1em` | Editor and gutter font size. |
249
+ | `--rc-textarea-line-height` | `1.5` | Editor and gutter line height. |
250
+ | `--rc-textarea-padding` | `0.5em` | Editor and gutter padding. |
251
+ | `--rc-textarea-background` | `Field` | Field background. |
252
+ | `--rc-textarea-color` | `var(--rc-text, FieldText)` | Field text color. |
253
+ | `--rc-textarea-caret-color` | `var(--rc-textarea-color, FieldText)` | Caret color. |
254
+ | `--rc-textarea-border` | `1px solid ButtonBorder` | Field border. |
255
+ | `--rc-textarea-border-radius` | `2px` | Field corner radius. |
256
+ | `--rc-textarea-focus-outline` | `2px solid Highlight` | Focus ring. |
257
+ | `--rc-textarea-active-line-bg` | `transparent` | Active line background. |
258
+ | `--rc-textarea-gutter-bg` | `Canvas` | Gutter background. |
259
+ | `--rc-textarea-gutter-color` | `GrayText` | Gutter text color. |
260
+ | `--rc-textarea-gutter-border` | `1px solid ButtonBorder` | Gutter separator. |
261
+ | `--rc-textarea-gutter-font-family` | `var(--rc-textarea-font-family, monospace)` | Gutter font family. |
262
+ | `--rc-textarea-gutter-padding-inline-end` | `0.75em` | Space between gutter labels and text. |
262
263
 
263
264
  ```css
264
265
  rc-textarea {
@@ -912,6 +912,38 @@
912
912
  "description": "Gutter right border",
913
913
  "name": "--rc-textarea-gutter-border",
914
914
  "default": "1px solid ButtonBorder"
915
+ },
916
+ {
917
+ "description": "Gutter font family",
918
+ "name": "--rc-textarea-gutter-font-family",
919
+ "default": "var(--rc-textarea-font-family, monospace)"
920
+ },
921
+ {
922
+ "description": "Space between gutter labels and text",
923
+ "name": "--rc-textarea-gutter-padding-inline-end",
924
+ "default": "0.75em"
925
+ }
926
+ ],
927
+ "cssParts": [
928
+ {
929
+ "description": "The outer flex container wrapping the gutter and editor area.",
930
+ "name": "root"
931
+ },
932
+ {
933
+ "description": "The gutter column container.",
934
+ "name": "gutter"
935
+ },
936
+ {
937
+ "description": "The gutter's line-label list.",
938
+ "name": "gutter-cells"
939
+ },
940
+ {
941
+ "description": "The container positioning the editor over the slotted textarea.",
942
+ "name": "editor-area"
943
+ },
944
+ {
945
+ "description": "The contenteditable field surface.",
946
+ "name": "editor"
915
947
  }
916
948
  ],
917
949
  "slots": [
@@ -947,6 +979,7 @@
947
979
  "type": {
948
980
  "text": "boolean"
949
981
  },
982
+ "description": "Legacy alias for sparse (non-blank-line) list-style numbering.",
950
983
  "deprecated": "Use a plugin with `LineDecoration.gutterContent` to implement\nsparse line numbering. This property will be removed before v1.0.",
951
984
  "attribute": "list-numbers",
952
985
  "reflects": true
@@ -1010,6 +1043,7 @@
1010
1043
  "type": {
1011
1044
  "text": "string | null"
1012
1045
  },
1046
+ "description": "Accessible-name override, applied to the editor's `aria-label`.",
1013
1047
  "deprecated": "Set `aria-label` on the slotted `<textarea>` instead, or\nassociate a `<label>` element via its `for`/`id` pair. This property\nwill be removed before v1.0.",
1014
1048
  "attribute": "label"
1015
1049
  },
@@ -1103,7 +1137,7 @@
1103
1137
  "type": {
1104
1138
  "text": "RCDocument | null"
1105
1139
  },
1106
- "privacy": "private",
1140
+ "privacy": "protected",
1107
1141
  "default": "null"
1108
1142
  },
1109
1143
  {
@@ -1112,13 +1146,13 @@
1112
1146
  "type": {
1113
1147
  "text": "WeakRef<HTMLTextAreaElement> | null"
1114
1148
  },
1115
- "privacy": "private",
1149
+ "privacy": "protected",
1116
1150
  "default": "null"
1117
1151
  },
1118
1152
  {
1119
1153
  "kind": "field",
1120
1154
  "name": "_textareaController",
1121
- "privacy": "private",
1155
+ "privacy": "protected",
1122
1156
  "readonly": true,
1123
1157
  "default": "new NativeChildController<HTMLTextAreaElement>(this, { selector: ':scope > textarea', observe: true, onChange: ($textarea, $previousTextarea) => this._setupTextarea($textarea, $previousTextarea), onMissing: () => { if (import.meta.env.DEV && !this.readOnly) { warnMissingDirectChild(this, { selector: ':scope > textarea', message: '[rc-textarea] No direct child <textarea> found. Place a native <textarea> inside <rc-textarea>.', }); } }, })"
1124
1158
  },
@@ -1135,7 +1169,7 @@
1135
1169
  "type": {
1136
1170
  "text": "Decoration[]"
1137
1171
  },
1138
- "privacy": "private",
1172
+ "privacy": "protected",
1139
1173
  "default": "[]",
1140
1174
  "description": "Pattern-generated decorations (rebuilt on each value change)."
1141
1175
  },
@@ -1152,7 +1186,7 @@
1152
1186
  {
1153
1187
  "kind": "field",
1154
1188
  "name": "_patterns",
1155
- "privacy": "private",
1189
+ "privacy": "protected",
1156
1190
  "default": "new Map<string, TextPattern>()",
1157
1191
  "description": "Registered patterns."
1158
1192
  },
@@ -1189,14 +1223,14 @@
1189
1223
  "type": {
1190
1224
  "text": "number"
1191
1225
  },
1192
- "privacy": "private",
1226
+ "privacy": "protected",
1193
1227
  "default": "0",
1194
1228
  "description": "Sequence counter for async plugin safety (discard stale results)."
1195
1229
  },
1196
1230
  {
1197
1231
  "kind": "field",
1198
1232
  "name": "_pluginSheets",
1199
- "privacy": "private",
1233
+ "privacy": "protected",
1200
1234
  "default": "new Set<CSSStyleSheet>()",
1201
1235
  "description": "Stylesheets adopted into the shadow root by the active plugin."
1202
1236
  },
@@ -1215,7 +1249,7 @@
1215
1249
  "type": {
1216
1250
  "text": "number | null"
1217
1251
  },
1218
- "privacy": "private",
1252
+ "privacy": "protected",
1219
1253
  "default": "null"
1220
1254
  },
1221
1255
  {
@@ -1224,7 +1258,7 @@
1224
1258
  "type": {
1225
1259
  "text": "boolean"
1226
1260
  },
1227
- "privacy": "private",
1261
+ "privacy": "protected",
1228
1262
  "default": "false"
1229
1263
  },
1230
1264
  {
@@ -1233,7 +1267,7 @@
1233
1267
  "type": {
1234
1268
  "text": "boolean"
1235
1269
  },
1236
- "privacy": "private",
1270
+ "privacy": "protected",
1237
1271
  "default": "false"
1238
1272
  },
1239
1273
  {
@@ -1242,21 +1276,21 @@
1242
1276
  "type": {
1243
1277
  "text": "HTMLElement | null"
1244
1278
  },
1245
- "privacy": "private",
1279
+ "privacy": "protected",
1246
1280
  "default": "null",
1247
1281
  "description": "The currently highlighted `.line` element (active line)."
1248
1282
  },
1249
1283
  {
1250
1284
  "kind": "field",
1251
1285
  "name": "_cursorCallbacks",
1252
- "privacy": "private",
1286
+ "privacy": "protected",
1253
1287
  "default": "new Set<(start: number, end: number) => void>()",
1254
1288
  "description": "Callbacks registered via PluginAPI.onCursorMove()."
1255
1289
  },
1256
1290
  {
1257
1291
  "kind": "field",
1258
1292
  "name": "_docSelectionChangeHandler",
1259
- "privacy": "private"
1293
+ "privacy": "protected"
1260
1294
  },
1261
1295
  {
1262
1296
  "kind": "field",
@@ -1264,7 +1298,7 @@
1264
1298
  "type": {
1265
1299
  "text": "UndoEntry[]"
1266
1300
  },
1267
- "privacy": "private",
1301
+ "privacy": "protected",
1268
1302
  "default": "[]",
1269
1303
  "description": "Synthetic undo/redo stack (DOM rebuilds invalidate native undo)"
1270
1304
  },
@@ -1274,7 +1308,7 @@
1274
1308
  "type": {
1275
1309
  "text": "number"
1276
1310
  },
1277
- "privacy": "private",
1311
+ "privacy": "protected",
1278
1312
  "default": "-1"
1279
1313
  },
1280
1314
  {
@@ -1283,7 +1317,7 @@
1283
1317
  "type": {
1284
1318
  "text": "ResizeObserver | null"
1285
1319
  },
1286
- "privacy": "private",
1320
+ "privacy": "protected",
1287
1321
  "default": "null"
1288
1322
  },
1289
1323
  {
@@ -1292,7 +1326,7 @@
1292
1326
  "type": {
1293
1327
  "text": "(string | null)[]"
1294
1328
  },
1295
- "privacy": "private",
1329
+ "privacy": "protected",
1296
1330
  "default": "[]",
1297
1331
  "description": "Cached per-line gutter labels from the last render — reused by ResizeObserver."
1298
1332
  },
@@ -1312,12 +1346,12 @@
1312
1346
  "text": "string | undefined"
1313
1347
  },
1314
1348
  "description": "Initial uncontrolled value.",
1315
- "attribute": "defaultValue"
1349
+ "attribute": "default-value"
1316
1350
  },
1317
1351
  {
1318
1352
  "kind": "method",
1319
1353
  "name": "_onSlotChange",
1320
- "privacy": "private",
1354
+ "privacy": "protected",
1321
1355
  "return": {
1322
1356
  "type": {
1323
1357
  "text": "void"
@@ -1327,7 +1361,7 @@
1327
1361
  {
1328
1362
  "kind": "method",
1329
1363
  "name": "_setupTextarea",
1330
- "privacy": "private",
1364
+ "privacy": "protected",
1331
1365
  "return": {
1332
1366
  "type": {
1333
1367
  "text": "void"
@@ -1352,12 +1386,12 @@
1352
1386
  {
1353
1387
  "kind": "field",
1354
1388
  "name": "_onTextareaInvalid",
1355
- "privacy": "private"
1389
+ "privacy": "protected"
1356
1390
  },
1357
1391
  {
1358
1392
  "kind": "method",
1359
1393
  "name": "_bindEditorEvents",
1360
- "privacy": "private",
1394
+ "privacy": "protected",
1361
1395
  "return": {
1362
1396
  "type": {
1363
1397
  "text": "void"
@@ -1375,12 +1409,17 @@
1375
1409
  {
1376
1410
  "kind": "field",
1377
1411
  "name": "_onInputEvent",
1378
- "privacy": "private"
1412
+ "privacy": "protected"
1413
+ },
1414
+ {
1415
+ "kind": "field",
1416
+ "name": "_onBeforeInput",
1417
+ "privacy": "protected"
1379
1418
  },
1380
1419
  {
1381
1420
  "kind": "method",
1382
1421
  "name": "_onInput",
1383
- "privacy": "private",
1422
+ "privacy": "protected",
1384
1423
  "return": {
1385
1424
  "type": {
1386
1425
  "text": "void"
@@ -1390,12 +1429,12 @@
1390
1429
  {
1391
1430
  "kind": "field",
1392
1431
  "name": "_onSelectionChange",
1393
- "privacy": "private"
1432
+ "privacy": "protected"
1394
1433
  },
1395
1434
  {
1396
1435
  "kind": "method",
1397
1436
  "name": "_updateActiveLine",
1398
- "privacy": "private",
1437
+ "privacy": "protected",
1399
1438
  "return": {
1400
1439
  "type": {
1401
1440
  "text": "void"
@@ -1405,7 +1444,7 @@
1405
1444
  {
1406
1445
  "kind": "method",
1407
1446
  "name": "_updateActiveGutterCell",
1408
- "privacy": "private",
1447
+ "privacy": "protected",
1409
1448
  "return": {
1410
1449
  "type": {
1411
1450
  "text": "void"
@@ -1415,7 +1454,7 @@
1415
1454
  {
1416
1455
  "kind": "field",
1417
1456
  "name": "_onKeyDown",
1418
- "privacy": "private"
1457
+ "privacy": "protected"
1419
1458
  },
1420
1459
  {
1421
1460
  "kind": "method",
@@ -1480,7 +1519,7 @@
1480
1519
  {
1481
1520
  "kind": "field",
1482
1521
  "name": "_onPaste",
1483
- "privacy": "private"
1522
+ "privacy": "protected"
1484
1523
  },
1485
1524
  {
1486
1525
  "kind": "method",
@@ -1513,7 +1552,7 @@
1513
1552
  {
1514
1553
  "kind": "method",
1515
1554
  "name": "_undo",
1516
- "privacy": "private",
1555
+ "privacy": "protected",
1517
1556
  "return": {
1518
1557
  "type": {
1519
1558
  "text": "void"
@@ -1523,7 +1562,7 @@
1523
1562
  {
1524
1563
  "kind": "method",
1525
1564
  "name": "_redo",
1526
- "privacy": "private",
1565
+ "privacy": "protected",
1527
1566
  "return": {
1528
1567
  "type": {
1529
1568
  "text": "void"
@@ -1533,7 +1572,7 @@
1533
1572
  {
1534
1573
  "kind": "method",
1535
1574
  "name": "_applyUndoEntry",
1536
- "privacy": "private",
1575
+ "privacy": "protected",
1537
1576
  "return": {
1538
1577
  "type": {
1539
1578
  "text": "void"
@@ -1579,7 +1618,7 @@
1579
1618
  {
1580
1619
  "kind": "method",
1581
1620
  "name": "_buildPluginApi",
1582
- "privacy": "private",
1621
+ "privacy": "protected",
1583
1622
  "return": {
1584
1623
  "type": {
1585
1624
  "text": "RCTextareaPluginAPI"
@@ -1590,7 +1629,7 @@
1590
1629
  {
1591
1630
  "kind": "method",
1592
1631
  "name": "_clearPluginSheets",
1593
- "privacy": "private",
1632
+ "privacy": "protected",
1594
1633
  "return": {
1595
1634
  "type": {
1596
1635
  "text": "void"
@@ -1656,7 +1695,7 @@
1656
1695
  {
1657
1696
  "kind": "method",
1658
1697
  "name": "_performRender",
1659
- "privacy": "private",
1698
+ "privacy": "protected",
1660
1699
  "return": {
1661
1700
  "type": {
1662
1701
  "text": "Promise<void>"
@@ -1666,7 +1705,7 @@
1666
1705
  {
1667
1706
  "kind": "method",
1668
1707
  "name": "_computeGutterLabels",
1669
- "privacy": "private",
1708
+ "privacy": "protected",
1670
1709
  "return": {
1671
1710
  "type": {
1672
1711
  "text": "(string | null)[]"
@@ -1689,7 +1728,7 @@
1689
1728
  {
1690
1729
  "kind": "method",
1691
1730
  "name": "_syncGutterHeights",
1692
- "privacy": "private",
1731
+ "privacy": "protected",
1693
1732
  "return": {
1694
1733
  "type": {
1695
1734
  "text": "void"
@@ -1700,7 +1739,7 @@
1700
1739
  {
1701
1740
  "kind": "method",
1702
1741
  "name": "_syncGutter",
1703
- "privacy": "private",
1742
+ "privacy": "protected",
1704
1743
  "return": {
1705
1744
  "type": {
1706
1745
  "text": "void"
@@ -1720,7 +1759,7 @@
1720
1759
  {
1721
1760
  "kind": "method",
1722
1761
  "name": "_syncLabel",
1723
- "privacy": "private",
1762
+ "privacy": "protected",
1724
1763
  "return": {
1725
1764
  "type": {
1726
1765
  "text": "void"
@@ -1730,7 +1769,7 @@
1730
1769
  {
1731
1770
  "kind": "method",
1732
1771
  "name": "_syncTypography",
1733
- "privacy": "private",
1772
+ "privacy": "protected",
1734
1773
  "return": {
1735
1774
  "type": {
1736
1775
  "text": "void"
@@ -1804,15 +1843,16 @@
1804
1843
  ],
1805
1844
  "attributes": [
1806
1845
  {
1846
+ "description": "Show sequential line numbers in the gutter. Enables the gutter implicitly.",
1807
1847
  "name": "line-numbers",
1808
1848
  "type": {
1809
1849
  "text": "boolean"
1810
1850
  },
1811
1851
  "default": "false",
1812
- "description": "Show sequential line numbers in the gutter. Enables the gutter implicitly.",
1813
1852
  "fieldName": "lineNumbers"
1814
1853
  },
1815
1854
  {
1855
+ "description": "Legacy alias for sparse (non-blank-line) list-style numbering.",
1816
1856
  "name": "list-numbers",
1817
1857
  "type": {
1818
1858
  "text": "boolean"
@@ -1821,42 +1861,43 @@
1821
1861
  "fieldName": "listNumbers"
1822
1862
  },
1823
1863
  {
1864
+ "description": "Enable the gutter column without any built-in content.\n\nPlugins can populate individual cells via `LineDecoration.gutterContent`.\nFor sequential line numbers use `lineNumbers` / `line-numbers` instead.",
1824
1865
  "name": "gutter",
1825
1866
  "type": {
1826
1867
  "text": "boolean"
1827
1868
  },
1828
1869
  "default": "false",
1829
- "description": "Enable the gutter column without any built-in content.\n\nPlugins can populate individual cells via `LineDecoration.gutterContent`.\nFor sequential line numbers use `lineNumbers` / `line-numbers` instead.",
1830
1870
  "fieldName": "gutter"
1831
1871
  },
1832
1872
  {
1873
+ "description": "Wrap long lines within the field to prevent horizontal overflow.",
1833
1874
  "name": "word-wrap",
1834
1875
  "type": {
1835
1876
  "text": "boolean"
1836
1877
  },
1837
1878
  "default": "false",
1838
- "description": "Wrap long lines within the field to prevent horizontal overflow.",
1839
1879
  "fieldName": "wordWrap"
1840
1880
  },
1841
1881
  {
1882
+ "description": "Allow the field to grow vertically with content to prevent vertical overflow.",
1842
1883
  "name": "auto-grow",
1843
1884
  "type": {
1844
1885
  "text": "boolean"
1845
1886
  },
1846
1887
  "default": "false",
1847
- "description": "Allow the field to grow vertically with content to prevent vertical overflow.",
1848
1888
  "fieldName": "autoGrow"
1849
1889
  },
1850
1890
  {
1891
+ "description": "Disable editing. The field renders as a styled read-only display.",
1851
1892
  "name": "read-only",
1852
1893
  "type": {
1853
1894
  "text": "boolean"
1854
1895
  },
1855
1896
  "default": "false",
1856
- "description": "Disable editing. The field renders as a styled read-only display.",
1857
1897
  "fieldName": "readOnly"
1858
1898
  },
1859
1899
  {
1900
+ "description": "Accessible-name override, applied to the editor's `aria-label`.",
1860
1901
  "name": "label",
1861
1902
  "type": {
1862
1903
  "text": "string | null"
@@ -1865,19 +1906,19 @@
1865
1906
  "fieldName": "label"
1866
1907
  },
1867
1908
  {
1909
+ "description": "The current field value.\n\nSetting this property puts the component into\ncontrolled mode (host owns the value, changes are reflected\nimmediately, no change events dispatched)",
1868
1910
  "name": "value",
1869
1911
  "type": {
1870
1912
  "text": "string"
1871
1913
  },
1872
- "description": "The current field value.\n\nSetting this property puts the component into\ncontrolled mode (host owns the value, changes are reflected\nimmediately, no change events dispatched)",
1873
1914
  "fieldName": "value"
1874
1915
  },
1875
1916
  {
1876
- "name": "defaultValue",
1917
+ "description": "Initial uncontrolled value.",
1918
+ "name": "default-value",
1877
1919
  "type": {
1878
1920
  "text": "string | undefined"
1879
1921
  },
1880
- "description": "Initial uncontrolled value.",
1881
1922
  "fieldName": "defaultValue"
1882
1923
  }
1883
1924
  ],