@react-x11/components 0.14.1 → 0.16.1

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.
Files changed (96) hide show
  1. package/dist/code-editor/node.d.ts +13 -0
  2. package/dist/code-editor/node.d.ts.map +1 -1
  3. package/dist/code-editor/node.js +23 -5
  4. package/dist/code-editor/node.js.map +1 -1
  5. package/dist/html/css/cascade.d.ts +171 -26
  6. package/dist/html/css/cascade.d.ts.map +1 -1
  7. package/dist/html/css/cascade.js +616 -216
  8. package/dist/html/css/cascade.js.map +1 -1
  9. package/dist/html/css/color.d.ts +25 -0
  10. package/dist/html/css/color.d.ts.map +1 -1
  11. package/dist/html/css/color.js +307 -19
  12. package/dist/html/css/color.js.map +1 -1
  13. package/dist/html/css/content.d.ts +11 -6
  14. package/dist/html/css/content.d.ts.map +1 -1
  15. package/dist/html/css/content.js +171 -12
  16. package/dist/html/css/content.js.map +1 -1
  17. package/dist/html/css/parse.d.ts.map +1 -1
  18. package/dist/html/css/parse.js +62 -9
  19. package/dist/html/css/parse.js.map +1 -1
  20. package/dist/html/css/shapes.d.ts +18 -0
  21. package/dist/html/css/shapes.d.ts.map +1 -1
  22. package/dist/html/css/shapes.js +21 -1
  23. package/dist/html/css/shapes.js.map +1 -1
  24. package/dist/html/css/style.d.ts +42 -5
  25. package/dist/html/css/style.d.ts.map +1 -1
  26. package/dist/html/css/style.js +74 -12
  27. package/dist/html/css/style.js.map +1 -1
  28. package/dist/html/css/ua.js +27 -8
  29. package/dist/html/css/ua.js.map +1 -1
  30. package/dist/html/css/values.d.ts +5 -0
  31. package/dist/html/css/values.d.ts.map +1 -1
  32. package/dist/html/css/values.js +18 -9
  33. package/dist/html/css/values.js.map +1 -1
  34. package/dist/html/index.d.ts.map +1 -1
  35. package/dist/html/index.js +7 -0
  36. package/dist/html/index.js.map +1 -1
  37. package/dist/html/layout/block.d.ts +29 -9
  38. package/dist/html/layout/block.d.ts.map +1 -1
  39. package/dist/html/layout/block.js +141 -52
  40. package/dist/html/layout/block.js.map +1 -1
  41. package/dist/html/layout/boxes.d.ts +29 -2
  42. package/dist/html/layout/boxes.d.ts.map +1 -1
  43. package/dist/html/layout/boxes.js +172 -23
  44. package/dist/html/layout/boxes.js.map +1 -1
  45. package/dist/html/layout/css-grid.d.ts.map +1 -1
  46. package/dist/html/layout/css-grid.js +11 -9
  47. package/dist/html/layout/css-grid.js.map +1 -1
  48. package/dist/html/layout/flex.d.ts.map +1 -1
  49. package/dist/html/layout/flex.js +1759 -238
  50. package/dist/html/layout/flex.js.map +1 -1
  51. package/dist/html/layout/inline.d.ts +15 -3
  52. package/dist/html/layout/inline.d.ts.map +1 -1
  53. package/dist/html/layout/inline.js +64 -19
  54. package/dist/html/layout/inline.js.map +1 -1
  55. package/dist/html/layout/table.d.ts +27 -1
  56. package/dist/html/layout/table.d.ts.map +1 -1
  57. package/dist/html/layout/table.js +886 -324
  58. package/dist/html/layout/table.js.map +1 -1
  59. package/dist/html/node.d.ts +35 -4
  60. package/dist/html/node.d.ts.map +1 -1
  61. package/dist/html/node.js +122 -26
  62. package/dist/html/node.js.map +1 -1
  63. package/dist/html/paint.d.ts.map +1 -1
  64. package/dist/html/paint.js +558 -178
  65. package/dist/html/paint.js.map +1 -1
  66. package/dist/html/resources.js +14 -1
  67. package/dist/html/resources.js.map +1 -1
  68. package/dist/html/svg.d.ts +23 -7
  69. package/dist/html/svg.d.ts.map +1 -1
  70. package/dist/html/svg.js +264 -59
  71. package/dist/html/svg.js.map +1 -1
  72. package/dist/html/widgets.d.ts.map +1 -1
  73. package/dist/html/widgets.js +57 -4
  74. package/dist/html/widgets.js.map +1 -1
  75. package/package.json +3 -3
  76. package/src/code-editor/node.ts +24 -5
  77. package/src/html/css/cascade.ts +697 -221
  78. package/src/html/css/color.ts +345 -18
  79. package/src/html/css/content.ts +173 -15
  80. package/src/html/css/parse.ts +60 -8
  81. package/src/html/css/shapes.ts +35 -1
  82. package/src/html/css/style.ts +122 -17
  83. package/src/html/css/ua.ts +27 -8
  84. package/src/html/css/values.ts +23 -9
  85. package/src/html/index.ts +7 -0
  86. package/src/html/layout/block.ts +149 -58
  87. package/src/html/layout/boxes.ts +211 -27
  88. package/src/html/layout/css-grid.ts +12 -9
  89. package/src/html/layout/flex.ts +1975 -231
  90. package/src/html/layout/inline.ts +70 -16
  91. package/src/html/layout/table.ts +961 -332
  92. package/src/html/node.ts +155 -27
  93. package/src/html/paint.ts +692 -234
  94. package/src/html/resources.ts +13 -1
  95. package/src/html/svg.ts +299 -56
  96. package/src/html/widgets.ts +61 -4
@@ -101,7 +101,37 @@ export function useForms(options: FormsOptions): Forms {
101
101
  // and its undo. Keyed by position, each move mounted a new one, and a
102
102
  // page whose stylesheet landed while someone was typing lost the field
103
103
  // from under them.
104
- const widgets = React.useMemo(() => new WidgetBoxes(), []);
104
+ const widgets = React.useMemo(
105
+ () =>
106
+ new WidgetBoxes((el) => {
107
+ // a field that unmounts with the focus is forgotten rather than
108
+ // blurred, and the document is told it went
109
+ const node = view.current;
110
+ if (node?.focusedElement === el) node.setFocus(null);
111
+ }),
112
+ [view],
113
+ );
114
+
115
+ // Which element's field holds the focus, for `:focus` and its kin
116
+ // (`HtmlViewNode.setFocus`). A blur is told a microtask later, and only
117
+ // where no field took the focus in the meantime: core blurs one field
118
+ // and then focuses the next, and a move from one to the other is one
119
+ // change to the document, not two.
120
+ const blurred = React.useRef<Element | null>(null);
121
+ const focused = (el: Element, on: boolean) => {
122
+ if (on) {
123
+ blurred.current = null;
124
+ view.current?.setFocus(el, true);
125
+ return;
126
+ }
127
+ blurred.current = el;
128
+ void Promise.resolve().then(() => {
129
+ if (blurred.current !== el) return;
130
+ blurred.current = null;
131
+ const node = view.current;
132
+ if (node?.focusedElement === el) node.setFocus(null);
133
+ });
134
+ };
105
135
 
106
136
  React.useEffect(() => {
107
137
  if (!invalid) return;
@@ -271,6 +301,7 @@ export function useForms(options: FormsOptions): Forms {
271
301
  setChecked,
272
302
  checkRadio,
273
303
  press,
304
+ focused,
274
305
  submitFrom: (field) => {
275
306
  const plan = implicitSubmission(field);
276
307
  if (plan) submit(plan.form, plan.submitter);
@@ -346,6 +377,9 @@ class WidgetBoxes {
346
377
  private _boxes = new Map<Element, DrawnNode>();
347
378
  private _refs = new WeakMap<Element, (node: DrawnNode | null) => void>();
348
379
 
380
+ /** `gone` hears of each element whose widget's box unmounted. */
381
+ constructor(private readonly _gone: (el: Element) => void) {}
382
+
349
383
  idOf(el: Element): number {
350
384
  let id = this._ids.get(el);
351
385
  if (id === undefined) this._ids.set(el, (id = ++this._next));
@@ -358,7 +392,10 @@ class WidgetBoxes {
358
392
  if (!ref) {
359
393
  ref = (node) => {
360
394
  if (node) this._boxes.set(el, node);
361
- else if (this._boxes.get(el)) this._boxes.delete(el);
395
+ else if (this._boxes.get(el)) {
396
+ this._boxes.delete(el);
397
+ this._gone(el);
398
+ }
362
399
  };
363
400
  this._refs.set(el, ref);
364
401
  }
@@ -415,6 +452,8 @@ interface ControlContext {
415
452
  checkRadio: (el: Element) => void;
416
453
  /** A button was pressed: what it does to its form. */
417
454
  press: (button: Element) => void;
455
+ /** A field's widget took the focus, or gave it up. */
456
+ focused: (el: Element, on: boolean) => void;
418
457
  /** Enter in a text field: its form's implicit submission. */
419
458
  submitFrom: (field: Element) => void;
420
459
  }
@@ -574,8 +613,10 @@ function renderControl(
574
613
  defaultValue: forms.value(el),
575
614
  maxLength: maxLength(el),
576
615
  ...order,
577
- style: [field, { width: '100%', height: '100%' }],
616
+ style: [field, FIELD_BOX],
578
617
  onChange: readOnly ? undefined : (ev) => typed(ev.value),
618
+ onFocus: () => ctx.focused(el, true),
619
+ onBlur: () => ctx.focused(el, false),
579
620
  });
580
621
  break;
581
622
  case 'input': {
@@ -588,7 +629,11 @@ function renderControl(
588
629
  // Core's word for a password field: nothing in it reaches a
589
630
  // selection, PRIMARY included.
590
631
  sensitive: type === 'password',
591
- style: [field, { width: '100%', height: '100%' }],
632
+ // a browser's caret is the field's text colour (`caret-color:
633
+ // auto`), which is the page's where the page drew the field — the
634
+ // palette's own field keeps the palette's caret
635
+ ...(rect.bare && { caretColor: rect.bare.color }),
636
+ style: [field, FIELD_BOX],
592
637
  onChange: readOnly
593
638
  ? undefined
594
639
  : (ev) => {
@@ -600,6 +645,8 @@ function renderControl(
600
645
  },
601
646
  // Enter submits the field's form, as it does in a browser
602
647
  onSubmit: () => ctx.submitFrom(el),
648
+ onFocus: () => ctx.focused(el, true),
649
+ onBlur: () => ctx.focused(el, false),
603
650
  });
604
651
  break;
605
652
  }
@@ -676,6 +723,16 @@ function ariaHidden(el: Element): boolean {
676
723
  /** How far past its box a widget's focus ring is drawn, and then some. */
677
724
  const RING_REACH = 8;
678
725
 
726
+ /**
727
+ * A text field's box: all of its frame, and no focus ring of its own. Its
728
+ * ring is its element's `outline`, which the document draws round the
729
+ * border box (the UA sheet's `:focus-visible`), so a page's
730
+ * `outline: none` takes it away and a ring of the page's own replaces it,
731
+ * as they do in a browser. Core's, drawn round the widget, stood inside the
732
+ * border of a field the page drew, where the widget is only the content box.
733
+ */
734
+ const FIELD_BOX: Style = { width: '100%', height: '100%', outlineWidth: 0 };
735
+
679
736
  /** A field's `maxlength`, which the widget enforces as it is typed into. */
680
737
  function maxLength(el: Element): number | undefined {
681
738
  const raw = attr(el, 'maxlength')?.trim();