@react-x11/components 0.1.0 → 0.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 +979 -21
- package/dist/ansi/cast.d.ts +48 -0
- package/dist/ansi/cast.d.ts.map +1 -0
- package/dist/ansi/cast.js +135 -0
- package/dist/ansi/cast.js.map +1 -0
- package/dist/ansi/index.d.ts +10 -0
- package/dist/ansi/index.d.ts.map +1 -0
- package/dist/ansi/index.js +27 -0
- package/dist/ansi/index.js.map +1 -0
- package/dist/ansi/palette.d.ts +79 -0
- package/dist/ansi/palette.d.ts.map +1 -0
- package/dist/ansi/palette.js +155 -0
- package/dist/ansi/palette.js.map +1 -0
- package/dist/ansi/parse.d.ts +114 -0
- package/dist/ansi/parse.d.ts.map +1 -0
- package/dist/ansi/parse.js +687 -0
- package/dist/ansi/parse.js.map +1 -0
- package/dist/ansi/sgr.d.ts +87 -0
- package/dist/ansi/sgr.d.ts.map +1 -0
- package/dist/ansi/sgr.js +302 -0
- package/dist/ansi/sgr.js.map +1 -0
- package/dist/ansi/utf8.d.ts +15 -0
- package/dist/ansi/utf8.d.ts.map +1 -0
- package/dist/ansi/utf8.js +82 -0
- package/dist/ansi/utf8.js.map +1 -0
- package/dist/calendar/Calendar.d.ts +136 -0
- package/dist/calendar/Calendar.d.ts.map +1 -0
- package/dist/calendar/Calendar.js +460 -0
- package/dist/calendar/Calendar.js.map +1 -0
- package/dist/calendar/DatePicker.d.ts +52 -0
- package/dist/calendar/DatePicker.d.ts.map +1 -0
- package/dist/calendar/DatePicker.js +257 -0
- package/dist/calendar/DatePicker.js.map +1 -0
- package/dist/calendar/dates.d.ts +90 -0
- package/dist/calendar/dates.d.ts.map +1 -0
- package/dist/calendar/dates.js +236 -0
- package/dist/calendar/dates.js.map +1 -0
- package/dist/calendar/index.d.ts +8 -0
- package/dist/calendar/index.d.ts.map +1 -0
- package/dist/calendar/index.js +15 -0
- package/dist/calendar/index.js.map +1 -0
- package/dist/charts/components.d.ts +141 -0
- package/dist/charts/components.d.ts.map +1 -0
- package/dist/charts/components.js +580 -0
- package/dist/charts/components.js.map +1 -0
- package/dist/charts/data.d.ts +198 -0
- package/dist/charts/data.d.ts.map +1 -0
- package/dist/charts/data.js +616 -0
- package/dist/charts/data.js.map +1 -0
- package/dist/charts/hx.d.ts +21 -0
- package/dist/charts/hx.d.ts.map +1 -0
- package/dist/charts/hx.js +15 -0
- package/dist/charts/hx.js.map +1 -0
- package/dist/charts/index.d.ts +27 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +38 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/node.d.ts +96 -0
- package/dist/charts/node.d.ts.map +1 -0
- package/dist/charts/node.js +720 -0
- package/dist/charts/node.js.map +1 -0
- package/dist/charts/render.d.ts +153 -0
- package/dist/charts/render.d.ts.map +1 -0
- package/dist/charts/render.js +762 -0
- package/dist/charts/render.js.map +1 -0
- package/dist/charts/scale.d.ts +42 -0
- package/dist/charts/scale.d.ts.map +1 -0
- package/dist/charts/scale.js +173 -0
- package/dist/charts/scale.js.map +1 -0
- package/dist/charts/spec.d.ts +91 -0
- package/dist/charts/spec.d.ts.map +1 -0
- package/dist/charts/spec.js +33 -0
- package/dist/charts/spec.js.map +1 -0
- package/dist/charts/timers.d.ts +6 -0
- package/dist/charts/timers.d.ts.map +1 -0
- package/dist/charts/timers.js +14 -0
- package/dist/charts/timers.js.map +1 -0
- package/dist/code/hx.d.ts +24 -0
- package/dist/code/hx.d.ts.map +1 -0
- package/dist/code/hx.js +25 -0
- package/dist/code/hx.js.map +1 -0
- package/dist/code/index.d.ts +45 -0
- package/dist/code/index.d.ts.map +1 -0
- package/dist/code/index.js +93 -0
- package/dist/code/index.js.map +1 -0
- package/dist/code-editor/completion.d.ts +26 -0
- package/dist/code-editor/completion.d.ts.map +1 -0
- package/dist/code-editor/completion.js +129 -0
- package/dist/code-editor/completion.js.map +1 -0
- package/dist/code-editor/doc.d.ts +35 -0
- package/dist/code-editor/doc.d.ts.map +1 -0
- package/dist/code-editor/doc.js +162 -0
- package/dist/code-editor/doc.js.map +1 -0
- package/dist/code-editor/hx.d.ts +13 -0
- package/dist/code-editor/hx.d.ts.map +1 -0
- package/dist/code-editor/hx.js +10 -0
- package/dist/code-editor/hx.js.map +1 -0
- package/dist/code-editor/index.d.ts +88 -0
- package/dist/code-editor/index.d.ts.map +1 -0
- package/dist/code-editor/index.js +401 -0
- package/dist/code-editor/index.js.map +1 -0
- package/dist/code-editor/node.d.ts +343 -0
- package/dist/code-editor/node.d.ts.map +1 -0
- package/dist/code-editor/node.js +1521 -0
- package/dist/code-editor/node.js.map +1 -0
- package/dist/code-language/hljs.d.ts +47 -0
- package/dist/code-language/hljs.d.ts.map +1 -0
- package/dist/code-language/hljs.js +211 -0
- package/dist/code-language/hljs.js.map +1 -0
- package/dist/code-language/index.d.ts +22 -0
- package/dist/code-language/index.d.ts.map +1 -0
- package/dist/code-language/index.js +20 -0
- package/dist/code-language/index.js.map +1 -0
- package/dist/code-language/languages/glsl.d.ts +4 -0
- package/dist/code-language/languages/glsl.d.ts.map +1 -0
- package/dist/code-language/languages/glsl.js +99 -0
- package/dist/code-language/languages/glsl.js.map +1 -0
- package/dist/code-language/languages/javascript.d.ts +10 -0
- package/dist/code-language/languages/javascript.d.ts.map +1 -0
- package/dist/code-language/languages/javascript.js +360 -0
- package/dist/code-language/languages/javascript.js.map +1 -0
- package/dist/code-language/languages/json.d.ts +4 -0
- package/dist/code-language/languages/json.d.ts.map +1 -0
- package/dist/code-language/languages/json.js +68 -0
- package/dist/code-language/languages/json.js.map +1 -0
- package/dist/code-language/languages/shell.d.ts +4 -0
- package/dist/code-language/languages/shell.d.ts.map +1 -0
- package/dist/code-language/languages/shell.js +189 -0
- package/dist/code-language/languages/shell.js.map +1 -0
- package/dist/code-language/languages/sql.d.ts +11 -0
- package/dist/code-language/languages/sql.d.ts.map +1 -0
- package/dist/code-language/languages/sql.js +133 -0
- package/dist/code-language/languages/sql.js.map +1 -0
- package/dist/code-language/lezer.d.ts +24 -0
- package/dist/code-language/lezer.d.ts.map +1 -0
- package/dist/code-language/lezer.js +148 -0
- package/dist/code-language/lezer.js.map +1 -0
- package/dist/code-language/registry.d.ts +19 -0
- package/dist/code-language/registry.d.ts.map +1 -0
- package/dist/code-language/registry.js +56 -0
- package/dist/code-language/registry.js.map +1 -0
- package/dist/code-language/runs.d.ts +35 -0
- package/dist/code-language/runs.d.ts.map +1 -0
- package/dist/code-language/runs.js +88 -0
- package/dist/code-language/runs.js.map +1 -0
- package/dist/code-language/stream.d.ts +70 -0
- package/dist/code-language/stream.d.ts.map +1 -0
- package/dist/code-language/stream.js +243 -0
- package/dist/code-language/stream.js.map +1 -0
- package/dist/code-language/textmate.d.ts +27 -0
- package/dist/code-language/textmate.d.ts.map +1 -0
- package/dist/code-language/textmate.js +86 -0
- package/dist/code-language/textmate.js.map +1 -0
- package/dist/code-language/theme.d.ts +26 -0
- package/dist/code-language/theme.d.ts.map +1 -0
- package/dist/code-language/theme.js +108 -0
- package/dist/code-language/theme.js.map +1 -0
- package/dist/code-language/timers.d.ts +7 -0
- package/dist/code-language/timers.d.ts.map +1 -0
- package/dist/code-language/timers.js +22 -0
- package/dist/code-language/timers.js.map +1 -0
- package/dist/code-language/types.d.ts +173 -0
- package/dist/code-language/types.d.ts.map +1 -0
- package/dist/code-language/types.js +41 -0
- package/dist/code-language/types.js.map +1 -0
- package/dist/codeblock/index.d.ts +69 -0
- package/dist/codeblock/index.d.ts.map +1 -0
- package/dist/codeblock/index.js +85 -0
- package/dist/codeblock/index.js.map +1 -0
- package/dist/color-picker/ColorField.d.ts +39 -0
- package/dist/color-picker/ColorField.d.ts.map +1 -0
- package/dist/color-picker/ColorField.js +239 -0
- package/dist/color-picker/ColorField.js.map +1 -0
- package/dist/color-picker/ColorPicker.d.ts +109 -0
- package/dist/color-picker/ColorPicker.d.ts.map +1 -0
- package/dist/color-picker/ColorPicker.js +757 -0
- package/dist/color-picker/ColorPicker.js.map +1 -0
- package/dist/color-picker/color.d.ts +105 -0
- package/dist/color-picker/color.d.ts.map +1 -0
- package/dist/color-picker/color.js +313 -0
- package/dist/color-picker/color.js.map +1 -0
- package/dist/color-picker/index.d.ts +8 -0
- package/dist/color-picker/index.d.ts.map +1 -0
- package/dist/color-picker/index.js +19 -0
- package/dist/color-picker/index.js.map +1 -0
- package/dist/desktop-calendar/eds.d.ts +102 -0
- package/dist/desktop-calendar/eds.d.ts.map +1 -0
- package/dist/desktop-calendar/eds.js +356 -0
- package/dist/desktop-calendar/eds.js.map +1 -0
- package/dist/desktop-calendar/ical.d.ts +63 -0
- package/dist/desktop-calendar/ical.d.ts.map +1 -0
- package/dist/desktop-calendar/ical.js +57 -0
- package/dist/desktop-calendar/ical.js.map +1 -0
- package/dist/desktop-calendar/index.d.ts +72 -0
- package/dist/desktop-calendar/index.d.ts.map +1 -0
- package/dist/desktop-calendar/index.js +213 -0
- package/dist/desktop-calendar/index.js.map +1 -0
- package/dist/embed/client.d.ts +121 -0
- package/dist/embed/client.d.ts.map +1 -0
- package/dist/embed/client.js +203 -0
- package/dist/embed/client.js.map +1 -0
- package/dist/embed/host.d.ts +96 -0
- package/dist/embed/host.d.ts.map +1 -0
- package/dist/embed/host.js +266 -0
- package/dist/embed/host.js.map +1 -0
- package/dist/embed/index.d.ts +5 -0
- package/dist/embed/index.d.ts.map +1 -0
- package/dist/embed/index.js +13 -0
- package/dist/embed/index.js.map +1 -0
- package/dist/embed/timers.d.ts +6 -0
- package/dist/embed/timers.d.ts.map +1 -0
- package/dist/embed/timers.js +16 -0
- package/dist/embed/timers.js.map +1 -0
- package/dist/flow/draw.d.ts +45 -0
- package/dist/flow/draw.d.ts.map +1 -0
- package/dist/flow/draw.js +295 -0
- package/dist/flow/draw.js.map +1 -0
- package/dist/flow/index.d.ts +64 -0
- package/dist/flow/index.d.ts.map +1 -0
- package/dist/flow/index.js +306 -0
- package/dist/flow/index.js.map +1 -0
- package/dist/flow/model.d.ts +158 -0
- package/dist/flow/model.d.ts.map +1 -0
- package/dist/flow/model.js +566 -0
- package/dist/flow/model.js.map +1 -0
- package/dist/flow/node.d.ts +429 -0
- package/dist/flow/node.d.ts.map +1 -0
- package/dist/flow/node.js +3025 -0
- package/dist/flow/node.js.map +1 -0
- package/dist/flow/paths.d.ts +43 -0
- package/dist/flow/paths.d.ts.map +1 -0
- package/dist/flow/paths.js +327 -0
- package/dist/flow/paths.js.map +1 -0
- package/dist/flow/types.d.ts +561 -0
- package/dist/flow/types.d.ts.map +1 -0
- package/dist/flow/types.js +2 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/formula/hx.d.ts +24 -0
- package/dist/formula/hx.d.ts.map +1 -0
- package/dist/formula/hx.js +25 -0
- package/dist/formula/hx.js.map +1 -0
- package/dist/formula/index.d.ts +74 -0
- package/dist/formula/index.d.ts.map +1 -0
- package/dist/formula/index.js +155 -0
- package/dist/formula/index.js.map +1 -0
- package/dist/formula/katex.d.ts +78 -0
- package/dist/formula/katex.d.ts.map +1 -0
- package/dist/formula/katex.js +130 -0
- package/dist/formula/katex.js.map +1 -0
- package/dist/formula/layout.d.ts +103 -0
- package/dist/formula/layout.d.ts.map +1 -0
- package/dist/formula/layout.js +716 -0
- package/dist/formula/layout.js.map +1 -0
- package/dist/formula/node.d.ts +50 -0
- package/dist/formula/node.d.ts.map +1 -0
- package/dist/formula/node.js +351 -0
- package/dist/formula/node.js.map +1 -0
- package/dist/html/controls.d.ts +48 -0
- package/dist/html/controls.d.ts.map +1 -0
- package/dist/html/controls.js +195 -0
- package/dist/html/controls.js.map +1 -0
- package/dist/html/css/cascade.d.ts +51 -0
- package/dist/html/css/cascade.d.ts.map +1 -0
- package/dist/html/css/cascade.js +552 -0
- package/dist/html/css/cascade.js.map +1 -0
- package/dist/html/css/parse.d.ts +74 -0
- package/dist/html/css/parse.d.ts.map +1 -0
- package/dist/html/css/parse.js +464 -0
- package/dist/html/css/parse.js.map +1 -0
- package/dist/html/css/style.d.ts +142 -0
- package/dist/html/css/style.d.ts.map +1 -0
- package/dist/html/css/style.js +1145 -0
- package/dist/html/css/style.js.map +1 -0
- package/dist/html/css/ua.d.ts +5 -0
- package/dist/html/css/ua.d.ts.map +1 -0
- package/dist/html/css/ua.js +171 -0
- package/dist/html/css/ua.js.map +1 -0
- package/dist/html/css/values.d.ts +78 -0
- package/dist/html/css/values.d.ts.map +1 -0
- package/dist/html/css/values.js +330 -0
- package/dist/html/css/values.js.map +1 -0
- package/dist/html/dom.d.ts +112 -0
- package/dist/html/dom.d.ts.map +1 -0
- package/dist/html/dom.js +374 -0
- package/dist/html/dom.js.map +1 -0
- package/dist/html/hx.d.ts +24 -0
- package/dist/html/hx.d.ts.map +1 -0
- package/dist/html/hx.js +29 -0
- package/dist/html/hx.js.map +1 -0
- package/dist/html/index.d.ts +137 -0
- package/dist/html/index.d.ts.map +1 -0
- package/dist/html/index.js +339 -0
- package/dist/html/index.js.map +1 -0
- package/dist/html/layout/block.d.ts +58 -0
- package/dist/html/layout/block.d.ts.map +1 -0
- package/dist/html/layout/block.js +724 -0
- package/dist/html/layout/block.js.map +1 -0
- package/dist/html/layout/boxes.d.ts +261 -0
- package/dist/html/layout/boxes.d.ts.map +1 -0
- package/dist/html/layout/boxes.js +725 -0
- package/dist/html/layout/boxes.js.map +1 -0
- package/dist/html/layout/flex.d.ts +16 -0
- package/dist/html/layout/flex.d.ts.map +1 -0
- package/dist/html/layout/flex.js +242 -0
- package/dist/html/layout/flex.js.map +1 -0
- package/dist/html/layout/floats.d.ts +50 -0
- package/dist/html/layout/floats.d.ts.map +1 -0
- package/dist/html/layout/floats.js +110 -0
- package/dist/html/layout/floats.js.map +1 -0
- package/dist/html/layout/inline.d.ts +44 -0
- package/dist/html/layout/inline.d.ts.map +1 -0
- package/dist/html/layout/inline.js +700 -0
- package/dist/html/layout/inline.js.map +1 -0
- package/dist/html/layout/table.d.ts +5 -0
- package/dist/html/layout/table.d.ts.map +1 -0
- package/dist/html/layout/table.js +340 -0
- package/dist/html/layout/table.js.map +1 -0
- package/dist/html/node.d.ts +149 -0
- package/dist/html/node.d.ts.map +1 -0
- package/dist/html/node.js +861 -0
- package/dist/html/node.js.map +1 -0
- package/dist/html/paint.d.ts +48 -0
- package/dist/html/paint.d.ts.map +1 -0
- package/dist/html/paint.js +495 -0
- package/dist/html/paint.js.map +1 -0
- package/dist/html/resources.d.ts +48 -0
- package/dist/html/resources.d.ts.map +1 -0
- package/dist/html/resources.js +156 -0
- package/dist/html/resources.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/heights.d.ts +81 -0
- package/dist/internal/heights.d.ts.map +1 -0
- package/dist/internal/heights.js +193 -0
- package/dist/internal/heights.js.map +1 -0
- package/dist/internal/hx.d.ts +24 -0
- package/dist/internal/hx.d.ts.map +1 -0
- package/dist/internal/hx.js +27 -0
- package/dist/internal/hx.js.map +1 -0
- package/dist/internal/text.d.ts +6 -0
- package/dist/internal/text.d.ts.map +1 -0
- package/dist/internal/text.js +44 -0
- package/dist/internal/text.js.map +1 -0
- package/dist/internal/timers.d.ts +8 -0
- package/dist/internal/timers.d.ts.map +1 -0
- package/dist/internal/timers.js +22 -0
- package/dist/internal/timers.js.map +1 -0
- package/dist/internal/widget.d.ts +40 -0
- package/dist/internal/widget.d.ts.map +1 -0
- package/dist/internal/widget.js +44 -0
- package/dist/internal/widget.js.map +1 -0
- package/dist/markdown/ast.d.ts +126 -0
- package/dist/markdown/ast.d.ts.map +1 -0
- package/dist/markdown/ast.js +8 -0
- package/dist/markdown/ast.js.map +1 -0
- package/dist/markdown/hx.d.ts +24 -0
- package/dist/markdown/hx.d.ts.map +1 -0
- package/dist/markdown/hx.js +25 -0
- package/dist/markdown/hx.js.map +1 -0
- package/dist/markdown/index.d.ts +90 -0
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +413 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/parse.d.ts +8 -0
- package/dist/markdown/parse.d.ts.map +1 -0
- package/dist/markdown/parse.js +911 -0
- package/dist/markdown/parse.js.map +1 -0
- package/dist/markdown/spans.d.ts +20 -0
- package/dist/markdown/spans.d.ts.map +1 -0
- package/dist/markdown/spans.js +96 -0
- package/dist/markdown/spans.js.map +1 -0
- package/dist/media-player/backends.d.ts +64 -0
- package/dist/media-player/backends.d.ts.map +1 -0
- package/dist/media-player/backends.js +110 -0
- package/dist/media-player/backends.js.map +1 -0
- package/dist/media-player/control.d.ts +40 -0
- package/dist/media-player/control.d.ts.map +1 -0
- package/dist/media-player/control.js +44 -0
- package/dist/media-player/control.js.map +1 -0
- package/dist/media-player/hx.d.ts +24 -0
- package/dist/media-player/hx.d.ts.map +1 -0
- package/dist/media-player/hx.js +25 -0
- package/dist/media-player/hx.js.map +1 -0
- package/dist/media-player/index.d.ts +107 -0
- package/dist/media-player/index.d.ts.map +1 -0
- package/dist/media-player/index.js +219 -0
- package/dist/media-player/index.js.map +1 -0
- package/dist/media-player/mpv.d.ts +4 -0
- package/dist/media-player/mpv.d.ts.map +1 -0
- package/dist/media-player/mpv.js +120 -0
- package/dist/media-player/mpv.js.map +1 -0
- package/dist/media-player/vlc.d.ts +8 -0
- package/dist/media-player/vlc.d.ts.map +1 -0
- package/dist/media-player/vlc.js +83 -0
- package/dist/media-player/vlc.js.map +1 -0
- package/dist/richtext/index.d.ts +19 -0
- package/dist/richtext/index.d.ts.map +1 -0
- package/dist/richtext/index.js +4 -0
- package/dist/richtext/index.js.map +1 -0
- package/dist/richtext/links.d.ts +12 -0
- package/dist/richtext/links.d.ts.map +1 -0
- package/dist/richtext/links.js +64 -0
- package/dist/richtext/links.js.map +1 -0
- package/dist/richtext/menu.d.ts +11 -0
- package/dist/richtext/menu.d.ts.map +1 -0
- package/dist/richtext/menu.js +43 -0
- package/dist/richtext/menu.js.map +1 -0
- package/dist/richtext/node.d.ts +151 -0
- package/dist/richtext/node.d.ts.map +1 -0
- package/dist/richtext/node.js +255 -0
- package/dist/richtext/node.js.map +1 -0
- package/dist/richtext/runs.d.ts +92 -0
- package/dist/richtext/runs.d.ts.map +1 -0
- package/dist/richtext/runs.js +158 -0
- package/dist/richtext/runs.js.map +1 -0
- package/dist/table/hx.d.ts +24 -0
- package/dist/table/hx.d.ts.map +1 -0
- package/dist/table/hx.js +25 -0
- package/dist/table/hx.js.map +1 -0
- package/dist/table/index.d.ts +169 -0
- package/dist/table/index.d.ts.map +1 -0
- package/dist/table/index.js +844 -0
- package/dist/table/index.js.map +1 -0
- package/dist/table/rows.d.ts +136 -0
- package/dist/table/rows.d.ts.map +1 -0
- package/dist/table/rows.js +146 -0
- package/dist/table/rows.js.map +1 -0
- package/dist/terminal/backends.d.ts +105 -0
- package/dist/terminal/backends.d.ts.map +1 -0
- package/dist/terminal/backends.js +185 -0
- package/dist/terminal/backends.js.map +1 -0
- package/dist/terminal/hx.d.ts +24 -0
- package/dist/terminal/hx.d.ts.map +1 -0
- package/dist/terminal/hx.js +25 -0
- package/dist/terminal/hx.js.map +1 -0
- package/dist/terminal/index.d.ts +160 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +344 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/title.d.ts +24 -0
- package/dist/terminal/title.d.ts.map +1 -0
- package/dist/terminal/title.js +129 -0
- package/dist/terminal/title.js.map +1 -0
- package/dist/terminal/vt/colors.d.ts +63 -0
- package/dist/terminal/vt/colors.d.ts.map +1 -0
- package/dist/terminal/vt/colors.js +203 -0
- package/dist/terminal/vt/colors.js.map +1 -0
- package/dist/terminal/vt/diff.d.ts +117 -0
- package/dist/terminal/vt/diff.d.ts.map +1 -0
- package/dist/terminal/vt/diff.js +358 -0
- package/dist/terminal/vt/diff.js.map +1 -0
- package/dist/terminal/vt/fonts.d.ts +92 -0
- package/dist/terminal/vt/fonts.d.ts.map +1 -0
- package/dist/terminal/vt/fonts.js +178 -0
- package/dist/terminal/vt/fonts.js.map +1 -0
- package/dist/terminal/vt/index.d.ts +78 -0
- package/dist/terminal/vt/index.d.ts.map +1 -0
- package/dist/terminal/vt/index.js +312 -0
- package/dist/terminal/vt/index.js.map +1 -0
- package/dist/terminal/vt/keys.d.ts +74 -0
- package/dist/terminal/vt/keys.d.ts.map +1 -0
- package/dist/terminal/vt/keys.js +309 -0
- package/dist/terminal/vt/keys.js.map +1 -0
- package/dist/terminal/vt/mouse.d.ts +44 -0
- package/dist/terminal/vt/mouse.d.ts.map +1 -0
- package/dist/terminal/vt/mouse.js +106 -0
- package/dist/terminal/vt/mouse.js.map +1 -0
- package/dist/terminal/vt/node.d.ts +246 -0
- package/dist/terminal/vt/node.d.ts.map +1 -0
- package/dist/terminal/vt/node.js +1068 -0
- package/dist/terminal/vt/node.js.map +1 -0
- package/dist/terminal/vt/pty.d.ts +81 -0
- package/dist/terminal/vt/pty.d.ts.map +1 -0
- package/dist/terminal/vt/pty.js +201 -0
- package/dist/terminal/vt/pty.js.map +1 -0
- package/dist/terminal/vt/renderer.d.ts +179 -0
- package/dist/terminal/vt/renderer.d.ts.map +1 -0
- package/dist/terminal/vt/renderer.js +357 -0
- package/dist/terminal/vt/renderer.js.map +1 -0
- package/dist/terminal/vt/timers.d.ts +6 -0
- package/dist/terminal/vt/timers.d.ts.map +1 -0
- package/dist/terminal/vt/timers.js +16 -0
- package/dist/terminal/vt/timers.js.map +1 -0
- package/dist/terminal/vt/xterm.d.ts +142 -0
- package/dist/terminal/vt/xterm.d.ts.map +1 -0
- package/dist/terminal/vt/xterm.js +32 -0
- package/dist/terminal/vt/xterm.js.map +1 -0
- package/dist/terminal-output/hx.d.ts +24 -0
- package/dist/terminal-output/hx.d.ts.map +1 -0
- package/dist/terminal-output/hx.js +25 -0
- package/dist/terminal-output/hx.js.map +1 -0
- package/dist/terminal-output/index.d.ts +92 -0
- package/dist/terminal-output/index.d.ts.map +1 -0
- package/dist/terminal-output/index.js +179 -0
- package/dist/terminal-output/index.js.map +1 -0
- package/dist/terminal-output/runs.d.ts +27 -0
- package/dist/terminal-output/runs.d.ts.map +1 -0
- package/dist/terminal-output/runs.js +66 -0
- package/dist/terminal-output/runs.js.map +1 -0
- package/dist/three/canvas.d.ts +46 -0
- package/dist/three/canvas.d.ts.map +1 -0
- package/dist/three/canvas.js +305 -0
- package/dist/three/canvas.js.map +1 -0
- package/dist/three/events.d.ts +64 -0
- package/dist/three/events.d.ts.map +1 -0
- package/dist/three/events.js +146 -0
- package/dist/three/events.js.map +1 -0
- package/dist/three/geometries.d.ts +89 -0
- package/dist/three/geometries.d.ts.map +1 -0
- package/dist/three/geometries.js +345 -0
- package/dist/three/geometries.js.map +1 -0
- package/dist/three/globals.d.ts +7 -0
- package/dist/three/globals.d.ts.map +1 -0
- package/dist/three/globals.js +20 -0
- package/dist/three/globals.js.map +1 -0
- package/dist/three/hx.d.ts +9 -0
- package/dist/three/hx.d.ts.map +1 -0
- package/dist/three/hx.js +10 -0
- package/dist/three/hx.js.map +1 -0
- package/dist/three/index.d.ts +22 -0
- package/dist/three/index.d.ts.map +1 -0
- package/dist/three/index.js +24 -0
- package/dist/three/index.js.map +1 -0
- package/dist/three/jsx-dev-runtime.d.ts +19 -0
- package/dist/three/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/three/jsx-dev-runtime.js +2 -0
- package/dist/three/jsx-dev-runtime.js.map +1 -0
- package/dist/three/jsx-runtime.d.ts +19 -0
- package/dist/three/jsx-runtime.d.ts.map +1 -0
- package/dist/three/jsx-runtime.js +2 -0
- package/dist/three/jsx-runtime.js.map +1 -0
- package/dist/three/jsx.d.ts +198 -0
- package/dist/three/jsx.d.ts.map +1 -0
- package/dist/three/jsx.js +2 -0
- package/dist/three/jsx.js.map +1 -0
- package/dist/three/materials.d.ts +125 -0
- package/dist/three/materials.d.ts.map +1 -0
- package/dist/three/materials.js +229 -0
- package/dist/three/materials.js.map +1 -0
- package/dist/three/math.d.ts +146 -0
- package/dist/three/math.d.ts.map +1 -0
- package/dist/three/math.js +464 -0
- package/dist/three/math.js.map +1 -0
- package/dist/three/objects.d.ts +185 -0
- package/dist/three/objects.d.ts.map +1 -0
- package/dist/three/objects.js +309 -0
- package/dist/three/objects.js.map +1 -0
- package/dist/three/passes.d.ts +54 -0
- package/dist/three/passes.d.ts.map +1 -0
- package/dist/three/passes.js +78 -0
- package/dist/three/passes.js.map +1 -0
- package/dist/three/postprocess.d.ts +85 -0
- package/dist/three/postprocess.d.ts.map +1 -0
- package/dist/three/postprocess.js +503 -0
- package/dist/three/postprocess.js.map +1 -0
- package/dist/three/raycast.d.ts +24 -0
- package/dist/three/raycast.d.ts.map +1 -0
- package/dist/three/raycast.js +138 -0
- package/dist/three/raycast.js.map +1 -0
- package/dist/three/reconciler.d.ts +48 -0
- package/dist/three/reconciler.d.ts.map +1 -0
- package/dist/three/reconciler.js +416 -0
- package/dist/three/reconciler.js.map +1 -0
- package/dist/three/renderer-direct.d.ts +102 -0
- package/dist/three/renderer-direct.d.ts.map +1 -0
- package/dist/three/renderer-direct.js +782 -0
- package/dist/three/renderer-direct.js.map +1 -0
- package/dist/three/renderer-indirect.d.ts +68 -0
- package/dist/three/renderer-indirect.d.ts.map +1 -0
- package/dist/three/renderer-indirect.js +438 -0
- package/dist/three/renderer-indirect.js.map +1 -0
- package/dist/three/store.d.ts +81 -0
- package/dist/three/store.d.ts.map +1 -0
- package/dist/three/store.js +110 -0
- package/dist/three/store.js.map +1 -0
- package/dist/timeline/hx.d.ts +18 -0
- package/dist/timeline/hx.d.ts.map +1 -0
- package/dist/timeline/hx.js +10 -0
- package/dist/timeline/hx.js.map +1 -0
- package/dist/timeline/index.d.ts +152 -0
- package/dist/timeline/index.d.ts.map +1 -0
- package/dist/timeline/index.js +383 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/tray-host/hx.d.ts +24 -0
- package/dist/tray-host/hx.d.ts.map +1 -0
- package/dist/tray-host/hx.js +25 -0
- package/dist/tray-host/hx.js.map +1 -0
- package/dist/tray-host/index.d.ts +110 -0
- package/dist/tray-host/index.d.ts.map +1 -0
- package/dist/tray-host/index.js +191 -0
- package/dist/tray-host/index.js.map +1 -0
- package/dist/tray-host/manager.d.ts +137 -0
- package/dist/tray-host/manager.d.ts.map +1 -0
- package/dist/tray-host/manager.js +462 -0
- package/dist/tray-host/manager.js.map +1 -0
- package/dist/tray-host/notify.d.ts +22 -0
- package/dist/tray-host/notify.d.ts.map +1 -0
- package/dist/tray-host/notify.js +74 -0
- package/dist/tray-host/notify.js.map +1 -0
- package/dist/tray-host/protocol.d.ts +106 -0
- package/dist/tray-host/protocol.d.ts.map +1 -0
- package/dist/tray-host/protocol.js +191 -0
- package/dist/tray-host/protocol.js.map +1 -0
- package/dist/tree/hx.d.ts +24 -0
- package/dist/tree/hx.d.ts.map +1 -0
- package/dist/tree/hx.js +25 -0
- package/dist/tree/hx.js.map +1 -0
- package/dist/tree/index.d.ts +221 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/dist/tree/index.js +716 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree/internal.d.ts +18 -0
- package/dist/tree/internal.d.ts.map +1 -0
- package/dist/tree/internal.js +66 -0
- package/dist/tree/internal.js.map +1 -0
- package/dist/tree/rows.d.ts +177 -0
- package/dist/tree/rows.d.ts.map +1 -0
- package/dist/tree/rows.js +179 -0
- package/dist/tree/rows.js.map +1 -0
- package/package.json +166 -12
- package/src/ansi/cast.ts +159 -0
- package/src/ansi/index.ts +53 -0
- package/src/ansi/palette.ts +226 -0
- package/src/ansi/parse.ts +780 -0
- package/src/ansi/sgr.ts +380 -0
- package/src/ansi/utf8.ts +84 -0
- package/src/calendar/Calendar.ts +744 -0
- package/src/calendar/DatePicker.ts +368 -0
- package/src/calendar/dates.ts +307 -0
- package/src/calendar/index.ts +51 -0
- package/src/charts/components.ts +864 -0
- package/src/charts/data.ts +776 -0
- package/src/charts/hx.ts +39 -0
- package/src/charts/index.ts +99 -0
- package/src/charts/node.ts +932 -0
- package/src/charts/render.ts +982 -0
- package/src/charts/scale.ts +214 -0
- package/src/charts/spec.ts +122 -0
- package/src/charts/timers.ts +24 -0
- package/src/code/hx.ts +51 -0
- package/src/code/index.ts +174 -0
- package/src/code-editor/completion.ts +161 -0
- package/src/code-editor/doc.ts +198 -0
- package/src/code-editor/hx.ts +26 -0
- package/src/code-editor/index.ts +615 -0
- package/src/code-editor/node.ts +1926 -0
- package/src/code-language/hljs.ts +302 -0
- package/src/code-language/index.ts +51 -0
- package/src/code-language/languages/glsl.ts +120 -0
- package/src/code-language/languages/javascript.ts +419 -0
- package/src/code-language/languages/json.ts +72 -0
- package/src/code-language/languages/shell.ts +221 -0
- package/src/code-language/languages/sql.ts +165 -0
- package/src/code-language/lezer.ts +190 -0
- package/src/code-language/registry.ts +66 -0
- package/src/code-language/runs.ts +128 -0
- package/src/code-language/stream.ts +306 -0
- package/src/code-language/textmate.ts +134 -0
- package/src/code-language/theme.ts +124 -0
- package/src/code-language/timers.ts +36 -0
- package/src/code-language/types.ts +252 -0
- package/src/codeblock/index.ts +146 -0
- package/src/color-picker/ColorField.ts +333 -0
- package/src/color-picker/ColorPicker.ts +1069 -0
- package/src/color-picker/color.ts +399 -0
- package/src/color-picker/index.ts +50 -0
- package/src/desktop-calendar/eds.ts +484 -0
- package/src/desktop-calendar/ical.ts +119 -0
- package/src/desktop-calendar/index.ts +287 -0
- package/src/embed/client.ts +311 -0
- package/src/embed/host.ts +432 -0
- package/src/embed/index.ts +33 -0
- package/src/embed/timers.ts +32 -0
- package/src/flow/draw.ts +418 -0
- package/src/flow/index.ts +473 -0
- package/src/flow/model.ts +687 -0
- package/src/flow/node.ts +3694 -0
- package/src/flow/paths.ts +403 -0
- package/src/flow/types.ts +634 -0
- package/src/formula/hx.ts +51 -0
- package/src/formula/index.ts +243 -0
- package/src/formula/katex.ts +209 -0
- package/src/formula/layout.ts +876 -0
- package/src/formula/node.ts +467 -0
- package/src/html/controls.ts +244 -0
- package/src/html/css/cascade.ts +606 -0
- package/src/html/css/parse.ts +500 -0
- package/src/html/css/style.ts +1371 -0
- package/src/html/css/ua.ts +174 -0
- package/src/html/css/values.ts +358 -0
- package/src/html/dom.ts +410 -0
- package/src/html/hx.ts +55 -0
- package/src/html/index.ts +545 -0
- package/src/html/layout/block.ts +876 -0
- package/src/html/layout/boxes.ts +981 -0
- package/src/html/layout/flex.ts +297 -0
- package/src/html/layout/floats.ts +125 -0
- package/src/html/layout/inline.ts +870 -0
- package/src/html/layout/table.ts +380 -0
- package/src/html/node.ts +967 -0
- package/src/html/paint.ts +605 -0
- package/src/html/resources.ts +214 -0
- package/src/index.ts +638 -0
- package/src/internal/heights.ts +211 -0
- package/src/internal/hx.ts +53 -0
- package/src/internal/text.ts +44 -0
- package/src/internal/timers.ts +44 -0
- package/src/internal/widget.ts +92 -0
- package/src/markdown/ast.ts +163 -0
- package/src/markdown/hx.ts +51 -0
- package/src/markdown/index.ts +686 -0
- package/src/markdown/parse.ts +1037 -0
- package/src/markdown/spans.ts +143 -0
- package/src/media-player/backends.ts +155 -0
- package/src/media-player/control.ts +70 -0
- package/src/media-player/hx.ts +51 -0
- package/src/media-player/index.ts +378 -0
- package/src/media-player/mpv.ts +146 -0
- package/src/media-player/vlc.ts +97 -0
- package/src/richtext/index.ts +42 -0
- package/src/richtext/links.ts +78 -0
- package/src/richtext/menu.ts +49 -0
- package/src/richtext/node.ts +406 -0
- package/src/richtext/runs.ts +253 -0
- package/src/table/hx.ts +51 -0
- package/src/table/index.ts +1219 -0
- package/src/table/rows.ts +275 -0
- package/src/terminal/backends.ts +242 -0
- package/src/terminal/hx.ts +51 -0
- package/src/terminal/index.ts +574 -0
- package/src/terminal/title.ts +172 -0
- package/src/terminal/vt/colors.ts +247 -0
- package/src/terminal/vt/diff.ts +467 -0
- package/src/terminal/vt/fonts.ts +233 -0
- package/src/terminal/vt/index.ts +443 -0
- package/src/terminal/vt/keys.ts +369 -0
- package/src/terminal/vt/mouse.ts +144 -0
- package/src/terminal/vt/node.ts +1242 -0
- package/src/terminal/vt/pty.ts +334 -0
- package/src/terminal/vt/renderer.ts +555 -0
- package/src/terminal/vt/timers.ts +31 -0
- package/src/terminal/vt/xterm.ts +193 -0
- package/src/terminal-output/hx.ts +51 -0
- package/src/terminal-output/index.ts +340 -0
- package/src/terminal-output/runs.ts +79 -0
- package/src/three/canvas.ts +451 -0
- package/src/three/events.ts +197 -0
- package/src/three/geometries.ts +429 -0
- package/src/three/globals.ts +34 -0
- package/src/three/hx.ts +22 -0
- package/src/three/index.ts +98 -0
- package/src/three/jsx-dev-runtime.ts +27 -0
- package/src/three/jsx-runtime.ts +38 -0
- package/src/three/jsx.ts +275 -0
- package/src/three/materials.ts +270 -0
- package/src/three/math.ts +585 -0
- package/src/three/objects.ts +397 -0
- package/src/three/passes.ts +90 -0
- package/src/three/postprocess.ts +677 -0
- package/src/three/raycast.ts +189 -0
- package/src/three/react-reconciler.d.ts +50 -0
- package/src/three/reconciler.ts +624 -0
- package/src/three/renderer-direct.ts +1055 -0
- package/src/three/renderer-indirect.ts +570 -0
- package/src/three/store.ts +207 -0
- package/src/timeline/hx.ts +31 -0
- package/src/timeline/index.ts +603 -0
- package/src/tray-host/hx.ts +51 -0
- package/src/tray-host/index.ts +331 -0
- package/src/tray-host/manager.ts +639 -0
- package/src/tray-host/notify.ts +102 -0
- package/src/tray-host/protocol.ts +235 -0
- package/src/tree/hx.ts +51 -0
- package/src/tree/index.ts +1087 -0
- package/src/tree/internal.ts +87 -0
- package/src/tree/rows.ts +334 -0
- package/src/index.d.ts +0 -2
- package/src/index.js +0 -9
- package/src/sparkline/index.d.ts +0 -29
- package/src/sparkline/index.js +0 -50
- package/src/sparkline/node.js +0 -72
|
@@ -0,0 +1,864 @@
|
|
|
1
|
+
// The React layer: the shadcn-shaped composition over `<chartplot>`.
|
|
2
|
+
//
|
|
3
|
+
// The children of a chart wrapper are **config carriers, not renderers** —
|
|
4
|
+
// recharts' own model. `<LineSeries>`, `<XAxis>`, `<CartesianGrid>`,
|
|
5
|
+
// `<ChartTooltip>` and the rest render null; the wrapper walks its children
|
|
6
|
+
// with `React.Children`, folds their props into one `PlotSpec`, and renders
|
|
7
|
+
// the single element that paints everything. What stays real composition is
|
|
8
|
+
// what benefits from it: the legend row, and the hover machinery — a
|
|
9
|
+
// hit-transparent crosshair and marker dots inside the chart, and a value
|
|
10
|
+
// bubble whose home is a policy (`ChartTooltip mode`): a real anchored
|
|
11
|
+
// `<popup>` window by default, an in-chart box on request. See
|
|
12
|
+
// renderTooltipBubble for why.
|
|
13
|
+
//
|
|
14
|
+
// Two identity rules keep interaction cheap, and they are the point of
|
|
15
|
+
// this file's plumbing:
|
|
16
|
+
//
|
|
17
|
+
// - `spec` is memoized on a serialized key of everything JSON-able in the
|
|
18
|
+
// children, so re-renders (hover state!) hand the element the same
|
|
19
|
+
// object and the React commit contributes no damage of its own — what
|
|
20
|
+
// repaints on hover is only the overlays' damage strips, at the plot's
|
|
21
|
+
// usual pixel-bounded cost;
|
|
22
|
+
// - formatters live in ONE mutable object per chart whose identity never
|
|
23
|
+
// changes; paint reads the current fields. The trade, documented on
|
|
24
|
+
// `ChartFormatters`: changing a formatter's *meaning* alone does not
|
|
25
|
+
// repaint until something else does. Inline arrows stay free.
|
|
26
|
+
|
|
27
|
+
import React from 'react';
|
|
28
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
29
|
+
import { useTheme } from 'react-x11';
|
|
30
|
+
import type { Style } from 'react-x11/style';
|
|
31
|
+
|
|
32
|
+
/** What `style` props here accept — the `Style | Style[]` the rest of the
|
|
33
|
+
* package's components take. */
|
|
34
|
+
type StyleInput = Style | Style[];
|
|
35
|
+
|
|
36
|
+
import { hx } from './hx.js';
|
|
37
|
+
import type { ChartFormatters, ChartHit, ChartPlotNode } from './node.js';
|
|
38
|
+
import { ELEMENT } from './node.js';
|
|
39
|
+
import type { ChartDataLike, ChartSourceData } from './data.js';
|
|
40
|
+
import { isChartDataLike } from './data.js';
|
|
41
|
+
import { formatTimeTick } from './scale.js';
|
|
42
|
+
import type {
|
|
43
|
+
AxisSpec,
|
|
44
|
+
AxisType,
|
|
45
|
+
ChartConfig,
|
|
46
|
+
ChartFrameStats,
|
|
47
|
+
CurveKind,
|
|
48
|
+
GridSpec,
|
|
49
|
+
PlotSpec,
|
|
50
|
+
SeriesSpec,
|
|
51
|
+
SeriesType,
|
|
52
|
+
} from './spec.js';
|
|
53
|
+
import { DEFAULT_PALETTE, SPEC_DEFAULTS } from './spec.js';
|
|
54
|
+
|
|
55
|
+
const h = React.createElement;
|
|
56
|
+
|
|
57
|
+
// --- container -------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
const ConfigContext = React.createContext<ChartConfig>({});
|
|
60
|
+
|
|
61
|
+
export interface ChartContainerProps {
|
|
62
|
+
/** Series key → label and colour, the shadcn shape. */
|
|
63
|
+
config?: ChartConfig;
|
|
64
|
+
style?: StyleInput;
|
|
65
|
+
/** Names the root box for `react-x11/test`'s queries. */
|
|
66
|
+
'data-testname'?: string;
|
|
67
|
+
children?: ReactNode;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Carries the `ChartConfig` and the sizing box. Charts inside read their
|
|
72
|
+
* labels and colours from it by series key.
|
|
73
|
+
*/
|
|
74
|
+
export function ChartContainer(props: ChartContainerProps): ReactElement {
|
|
75
|
+
return h(
|
|
76
|
+
ConfigContext.Provider,
|
|
77
|
+
{ value: props.config ?? {} },
|
|
78
|
+
hx(
|
|
79
|
+
'box',
|
|
80
|
+
{
|
|
81
|
+
style: [{ flexDirection: 'column' }, props.style],
|
|
82
|
+
'data-testname': props['data-testname'],
|
|
83
|
+
},
|
|
84
|
+
props.children,
|
|
85
|
+
),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// --- config-carrier children ----------------------------------------------
|
|
90
|
+
|
|
91
|
+
export interface SeriesProps {
|
|
92
|
+
/** The column this series draws, and its config/legend key. */
|
|
93
|
+
dataKey: string;
|
|
94
|
+
/** Overrides the config/palette colour. `$token` allowed. */
|
|
95
|
+
color?: string;
|
|
96
|
+
label?: string;
|
|
97
|
+
strokeWidth?: number;
|
|
98
|
+
/** Area fill opacity (the stroke stays opaque). */
|
|
99
|
+
fillOpacity?: number;
|
|
100
|
+
curve?: CurveKind;
|
|
101
|
+
/** Marker dots on line points: a radius, or true for the default 3. */
|
|
102
|
+
dot?: boolean | number;
|
|
103
|
+
/** Series sharing a stackId stack in child order (bar/area). */
|
|
104
|
+
stackId?: string;
|
|
105
|
+
/** Rounded bar corners on the value end. */
|
|
106
|
+
radius?: number;
|
|
107
|
+
/** Scatter point size in px. */
|
|
108
|
+
size?: number;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* The series/axis/grid/tooltip/legend components render nothing: the chart
|
|
112
|
+
* wrapper introspects them by element type. Each keeps a display name so a
|
|
113
|
+
* child the wrapper does not recognise can be reported usefully. */
|
|
114
|
+
|
|
115
|
+
export function LineSeries(_props: SeriesProps): null {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
export function AreaSeries(_props: SeriesProps): null {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
export function BarSeries(_props: SeriesProps): null {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
export function ScatterSeries(_props: SeriesProps): null {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface XAxisProps {
|
|
129
|
+
/** The column holding x values. Absent means "the index". */
|
|
130
|
+
dataKey?: string;
|
|
131
|
+
type?: AxisType;
|
|
132
|
+
ticks?: number;
|
|
133
|
+
tickFormatter?: (value: number | string) => string;
|
|
134
|
+
domain?: [number | 'auto', number | 'auto'];
|
|
135
|
+
hide?: boolean;
|
|
136
|
+
/** Reserved gutter height under the plot. */
|
|
137
|
+
height?: number;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function XAxis(_props: XAxisProps): null {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface YAxisProps {
|
|
145
|
+
ticks?: number;
|
|
146
|
+
tickFormatter?: (value: number) => string;
|
|
147
|
+
domain?: [number | 'auto', number | 'auto'];
|
|
148
|
+
hide?: boolean;
|
|
149
|
+
/** Reserved gutter width; 'auto' measures the tick labels. */
|
|
150
|
+
width?: number | 'auto';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function YAxis(_props: YAxisProps): null {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface CartesianGridProps {
|
|
158
|
+
horizontal?: boolean;
|
|
159
|
+
vertical?: boolean;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function CartesianGrid(_props: CartesianGridProps): null {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface ChartTooltipProps {
|
|
167
|
+
/** Format one value row. Default: the y tick formatter's rendering. */
|
|
168
|
+
formatter?: (value: number, id: string) => string;
|
|
169
|
+
/** Format the header (the x value at the pointer). */
|
|
170
|
+
labelFormatter?: (value: number | string) => string;
|
|
171
|
+
/** Draw the vertical crosshair. Default true. */
|
|
172
|
+
cursor?: boolean;
|
|
173
|
+
/** Replace the bubble entirely. */
|
|
174
|
+
content?: (hit: TooltipData) => ReactNode;
|
|
175
|
+
/**
|
|
176
|
+
* Where the bubble lives.
|
|
177
|
+
*
|
|
178
|
+
* `'popup'` (the default) is a real override-redirect window anchored to
|
|
179
|
+
* the data point — it stacks above everything in the app (content that
|
|
180
|
+
* flows after the chart included), may extend past the window's edge,
|
|
181
|
+
* and never takes focus. `'overlay'` keeps the bubble as a box inside
|
|
182
|
+
* the chart, clamped to the plot: no extra window, one paint surface —
|
|
183
|
+
* for screenshots and tests, or an app that dislikes tooltip windows.
|
|
184
|
+
* The crosshair and the point markers are part of the plot and stay
|
|
185
|
+
* in-window in both modes.
|
|
186
|
+
*/
|
|
187
|
+
mode?: 'popup' | 'overlay';
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export function ChartTooltip(_props: ChartTooltipProps): null {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface ChartLegendProps {
|
|
195
|
+
verticalAlign?: 'top' | 'bottom';
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export function ChartLegend(_props: ChartLegendProps): null {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** What a custom tooltip `content` receives. */
|
|
203
|
+
export interface TooltipData {
|
|
204
|
+
xValue: number | string;
|
|
205
|
+
points: { id: string; label: string; color: string; value: number }[];
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The imperative handle `plotRef` exposes: the snap-to-nearest query the
|
|
210
|
+
* tooltip itself uses. It is also the primitive an app builds pan and zoom
|
|
211
|
+
* gestures on — the hit carries the plot rect (for pixels→domain-units)
|
|
212
|
+
* and the x value under any window x, so a drag handler needs nothing
|
|
213
|
+
* else from the chart's internals.
|
|
214
|
+
*/
|
|
215
|
+
export interface ChartPlotHandle {
|
|
216
|
+
hitAt(x: number): ChartHit | null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// --- child introspection ---------------------------------------------------
|
|
220
|
+
|
|
221
|
+
const SERIES_TYPES = new Map<unknown, SeriesType>([
|
|
222
|
+
[LineSeries, 'line'],
|
|
223
|
+
[AreaSeries, 'area'],
|
|
224
|
+
[BarSeries, 'bar'],
|
|
225
|
+
[ScatterSeries, 'scatter'],
|
|
226
|
+
]);
|
|
227
|
+
|
|
228
|
+
interface Introspected {
|
|
229
|
+
series: { type: SeriesType; props: SeriesProps }[];
|
|
230
|
+
xAxis: XAxisProps | null;
|
|
231
|
+
yAxis: YAxisProps | null;
|
|
232
|
+
grid: CartesianGridProps | null;
|
|
233
|
+
tooltip: ChartTooltipProps | null;
|
|
234
|
+
legend: ChartLegendProps | null;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function introspect(children: ReactNode): Introspected {
|
|
238
|
+
const out: Introspected = {
|
|
239
|
+
series: [],
|
|
240
|
+
xAxis: null,
|
|
241
|
+
yAxis: null,
|
|
242
|
+
grid: null,
|
|
243
|
+
tooltip: null,
|
|
244
|
+
legend: null,
|
|
245
|
+
};
|
|
246
|
+
React.Children.forEach(children, (child) => {
|
|
247
|
+
if (!React.isValidElement(child)) return;
|
|
248
|
+
const type = child.type;
|
|
249
|
+
const seriesType = SERIES_TYPES.get(type);
|
|
250
|
+
if (seriesType) {
|
|
251
|
+
out.series.push({
|
|
252
|
+
type: seriesType,
|
|
253
|
+
props: child.props as SeriesProps,
|
|
254
|
+
});
|
|
255
|
+
} else if (type === XAxis) out.xAxis = child.props as XAxisProps;
|
|
256
|
+
else if (type === YAxis) out.yAxis = child.props as YAxisProps;
|
|
257
|
+
else if (type === CartesianGrid)
|
|
258
|
+
out.grid = child.props as CartesianGridProps;
|
|
259
|
+
else if (type === ChartTooltip)
|
|
260
|
+
out.tooltip = child.props as ChartTooltipProps;
|
|
261
|
+
else if (type === ChartLegend) out.legend = child.props as ChartLegendProps;
|
|
262
|
+
// anything else is silently ignored, recharts-style: a chart's children
|
|
263
|
+
// are declarations, and there is nowhere sensible to render a stray box
|
|
264
|
+
});
|
|
265
|
+
return out;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function buildSpec(parts: Introspected, config: ChartConfig): PlotSpec {
|
|
269
|
+
const series: SeriesSpec[] = parts.series.map((s, i) => {
|
|
270
|
+
const conf = config[s.props.dataKey] ?? {};
|
|
271
|
+
return {
|
|
272
|
+
id: s.props.dataKey,
|
|
273
|
+
type: s.type,
|
|
274
|
+
color:
|
|
275
|
+
s.props.color ??
|
|
276
|
+
conf.color ??
|
|
277
|
+
DEFAULT_PALETTE[i % DEFAULT_PALETTE.length],
|
|
278
|
+
label: s.props.label ?? conf.label ?? s.props.dataKey,
|
|
279
|
+
strokeWidth: s.props.strokeWidth ?? SPEC_DEFAULTS.strokeWidth,
|
|
280
|
+
fillOpacity: s.props.fillOpacity ?? SPEC_DEFAULTS.fillOpacity,
|
|
281
|
+
curve: s.props.curve ?? 'linear',
|
|
282
|
+
dot:
|
|
283
|
+
s.props.dot === true
|
|
284
|
+
? 3
|
|
285
|
+
: s.props.dot === false || s.props.dot === undefined
|
|
286
|
+
? false
|
|
287
|
+
: s.props.dot,
|
|
288
|
+
stackId: s.props.stackId ?? null,
|
|
289
|
+
barRadius: s.props.radius ?? 0,
|
|
290
|
+
size: s.props.size ?? SPEC_DEFAULTS.scatterSize,
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
const x: AxisSpec = {
|
|
294
|
+
key: parts.xAxis?.dataKey ?? null,
|
|
295
|
+
type: parts.xAxis?.type ?? 'auto',
|
|
296
|
+
ticks: parts.xAxis?.ticks ?? SPEC_DEFAULTS.ticks,
|
|
297
|
+
domain: parts.xAxis?.domain ?? ['auto', 'auto'],
|
|
298
|
+
hide: parts.xAxis?.hide ?? false,
|
|
299
|
+
width: 'auto',
|
|
300
|
+
height: parts.xAxis?.height ?? SPEC_DEFAULTS.xAxisHeight,
|
|
301
|
+
};
|
|
302
|
+
const y: AxisSpec = {
|
|
303
|
+
key: null,
|
|
304
|
+
type: 'linear',
|
|
305
|
+
ticks: parts.yAxis?.ticks ?? SPEC_DEFAULTS.ticks,
|
|
306
|
+
domain: parts.yAxis?.domain ?? ['auto', 'auto'],
|
|
307
|
+
hide: parts.yAxis?.hide ?? false,
|
|
308
|
+
width: parts.yAxis?.width ?? 'auto',
|
|
309
|
+
height: 0,
|
|
310
|
+
};
|
|
311
|
+
const grid: GridSpec | null = parts.grid
|
|
312
|
+
? {
|
|
313
|
+
horizontal: parts.grid.horizontal ?? true,
|
|
314
|
+
vertical: parts.grid.vertical ?? false,
|
|
315
|
+
}
|
|
316
|
+
: null;
|
|
317
|
+
return { series, x, y, grid };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Everything JSON-able that shapes the spec — the memo key. Functions and
|
|
321
|
+
* the data stay out; they have their own channels. */
|
|
322
|
+
function specKey(parts: Introspected, config: ChartConfig): string {
|
|
323
|
+
return JSON.stringify([
|
|
324
|
+
parts.series.map((s) => [
|
|
325
|
+
s.type,
|
|
326
|
+
s.props.dataKey,
|
|
327
|
+
s.props.color,
|
|
328
|
+
s.props.label,
|
|
329
|
+
s.props.strokeWidth,
|
|
330
|
+
s.props.fillOpacity,
|
|
331
|
+
s.props.curve,
|
|
332
|
+
s.props.dot,
|
|
333
|
+
s.props.stackId,
|
|
334
|
+
s.props.radius,
|
|
335
|
+
s.props.size,
|
|
336
|
+
]),
|
|
337
|
+
parts.xAxis && [
|
|
338
|
+
parts.xAxis.dataKey,
|
|
339
|
+
parts.xAxis.type,
|
|
340
|
+
parts.xAxis.ticks,
|
|
341
|
+
parts.xAxis.domain,
|
|
342
|
+
parts.xAxis.hide,
|
|
343
|
+
parts.xAxis.height,
|
|
344
|
+
],
|
|
345
|
+
parts.yAxis && [
|
|
346
|
+
parts.yAxis.ticks,
|
|
347
|
+
parts.yAxis.domain,
|
|
348
|
+
parts.yAxis.hide,
|
|
349
|
+
parts.yAxis.width,
|
|
350
|
+
],
|
|
351
|
+
parts.grid && [parts.grid.horizontal, parts.grid.vertical],
|
|
352
|
+
config,
|
|
353
|
+
]);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// --- the chart wrappers ----------------------------------------------------
|
|
357
|
+
|
|
358
|
+
export interface CartesianChartProps {
|
|
359
|
+
/** Rows, columns, or a `ChartData` store. */
|
|
360
|
+
data: ChartSourceData;
|
|
361
|
+
/** Per painted frame: modes, command counts, wire bytes, timings. */
|
|
362
|
+
onFrameStats?: (stats: ChartFrameStats) => void;
|
|
363
|
+
/** The imperative snap query, for app gestures — pan, zoom, brushing. */
|
|
364
|
+
plotRef?: React.Ref<ChartPlotHandle | null>;
|
|
365
|
+
style?: StyleInput;
|
|
366
|
+
/** Names the chart's root box for `react-x11/test`'s queries. */
|
|
367
|
+
'data-testname'?: string;
|
|
368
|
+
children?: ReactNode;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
interface HoverState {
|
|
372
|
+
hit: ChartHit;
|
|
373
|
+
/** the element's window rect when the hit was taken — overlays are
|
|
374
|
+
* positioned relative to the plot wrapper, which the element fills */
|
|
375
|
+
originX: number;
|
|
376
|
+
originY: number;
|
|
377
|
+
width: number;
|
|
378
|
+
height: number;
|
|
379
|
+
pointerY: number;
|
|
380
|
+
/** which side of the crosshair the bubble hangs on — chosen with
|
|
381
|
+
* hysteresis so it sits opposite the pointer and never gets chased */
|
|
382
|
+
side: 'left' | 'right';
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/** How far past the snapped point the pointer travels before the bubble
|
|
386
|
+
* switches sides. The dead zone keeps the bubble still while the pointer
|
|
387
|
+
* sits on the point itself. */
|
|
388
|
+
const SIDE_HYSTERESIS = 8;
|
|
389
|
+
|
|
390
|
+
function makeCartesianChart(
|
|
391
|
+
displayName: string,
|
|
392
|
+
): (props: CartesianChartProps) => ReactElement {
|
|
393
|
+
function Chart(props: CartesianChartProps): ReactElement {
|
|
394
|
+
const config = React.useContext(ConfigContext);
|
|
395
|
+
const theme = useTheme();
|
|
396
|
+
const parts = introspect(props.children);
|
|
397
|
+
const key = specKey(parts, config);
|
|
398
|
+
// `key` serializes everything buildSpec reads, so it is the memo's
|
|
399
|
+
// whole dependency: same key, same spec object, no damage upstream.
|
|
400
|
+
const spec = React.useMemo(
|
|
401
|
+
() => buildSpec(parts, config),
|
|
402
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
403
|
+
[key],
|
|
404
|
+
);
|
|
405
|
+
|
|
406
|
+
// ONE mutable formatter object per chart: identity-stable on purpose,
|
|
407
|
+
// so inline arrow formatters never damage the plot (see file header)
|
|
408
|
+
const formatters = React.useRef<ChartFormatters>({}).current;
|
|
409
|
+
formatters.x = parts.xAxis?.tickFormatter;
|
|
410
|
+
formatters.y = parts.yAxis?.tickFormatter;
|
|
411
|
+
|
|
412
|
+
const nodeRef = React.useRef<ChartPlotNode | null>(null);
|
|
413
|
+
const [hover, setHover] = React.useState<HoverState | null>(null);
|
|
414
|
+
const sideRef = React.useRef<'left' | 'right'>('right');
|
|
415
|
+
const lastPointer = React.useRef<{ x: number; y: number } | null>(null);
|
|
416
|
+
|
|
417
|
+
// one callback ref feeds both the internal node ref and the public
|
|
418
|
+
// plotRef handle; memoized so React does not detach/attach per render
|
|
419
|
+
const plotRefProp = props.plotRef;
|
|
420
|
+
const setNode = React.useCallback(
|
|
421
|
+
(n: ChartPlotNode | null) => {
|
|
422
|
+
nodeRef.current = n;
|
|
423
|
+
if (typeof plotRefProp === 'function') plotRefProp(n);
|
|
424
|
+
else if (plotRefProp) {
|
|
425
|
+
(
|
|
426
|
+
plotRefProp as React.MutableRefObject<ChartPlotHandle | null>
|
|
427
|
+
).current = n;
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
[plotRefProp],
|
|
431
|
+
);
|
|
432
|
+
|
|
433
|
+
const wantHover = parts.tooltip !== null;
|
|
434
|
+
// Re-runnable for a pointer that has not moved: streaming data slides
|
|
435
|
+
// the chart under a parked pointer, and a hover snapshot taken at the
|
|
436
|
+
// last mousemove would keep showing the point that was there before.
|
|
437
|
+
const takeHover = (x: number, y: number) => {
|
|
438
|
+
const node = nodeRef.current;
|
|
439
|
+
const hit = node?.hitAt(x);
|
|
440
|
+
if (!hit || !node) {
|
|
441
|
+
setHover(null);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
// bubble side: opposite the pointer, with a dead zone around the
|
|
445
|
+
// snap so sitting on a point does not flip it back and forth
|
|
446
|
+
if (x > hit.px + SIDE_HYSTERESIS) sideRef.current = 'left';
|
|
447
|
+
else if (x < hit.px - SIDE_HYSTERESIS) sideRef.current = 'right';
|
|
448
|
+
setHover({
|
|
449
|
+
hit,
|
|
450
|
+
originX: node.abs.x,
|
|
451
|
+
originY: node.abs.y,
|
|
452
|
+
width: node.abs.width,
|
|
453
|
+
height: node.abs.height,
|
|
454
|
+
pointerY: y,
|
|
455
|
+
side: sideRef.current,
|
|
456
|
+
});
|
|
457
|
+
};
|
|
458
|
+
// effects re-take the hover through this ref, so they always run the
|
|
459
|
+
// render's latest closure without re-subscribing per render
|
|
460
|
+
const takeHoverRef = React.useRef(takeHover);
|
|
461
|
+
takeHoverRef.current = takeHover;
|
|
462
|
+
const hoverActive = hover !== null;
|
|
463
|
+
|
|
464
|
+
// a live store shifts under the pointer between mouse events: while
|
|
465
|
+
// hovered, every store notification re-snaps from the parked position
|
|
466
|
+
const data = props.data;
|
|
467
|
+
React.useEffect(() => {
|
|
468
|
+
if (!wantHover || !hoverActive) return;
|
|
469
|
+
if (!data || !isChartDataLike(data as never)) return;
|
|
470
|
+
return (data as ChartDataLike).subscribe(() => {
|
|
471
|
+
const p = lastPointer.current;
|
|
472
|
+
if (p) takeHoverRef.current(p.x, p.y);
|
|
473
|
+
});
|
|
474
|
+
}, [data, wantHover, hoverActive]);
|
|
475
|
+
|
|
476
|
+
// plain rows/columns move by prop identity instead — same re-snap
|
|
477
|
+
React.useEffect(() => {
|
|
478
|
+
const p = lastPointer.current;
|
|
479
|
+
if (p && hoverActive) takeHoverRef.current(p.x, p.y);
|
|
480
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
481
|
+
}, [data]);
|
|
482
|
+
|
|
483
|
+
// The bubble hides while a button is down — the toolkit convention
|
|
484
|
+
// (Qt and GTK dismiss tooltips on any press), and what makes a press
|
|
485
|
+
// that doubles as a gesture (pan, click-to-flip) never fight the
|
|
486
|
+
// window manager over stacking: a click-to-raise WM raises the owner
|
|
487
|
+
// window above the override-redirect popup, and no WM restacks
|
|
488
|
+
// unmanaged windows back (react-x11#299 is the standing fix). The
|
|
489
|
+
// crosshair and markers are in-window and keep tracking through the
|
|
490
|
+
// drag; on release the popup re-mounts, and a freshly created window
|
|
491
|
+
// starts above its siblings.
|
|
492
|
+
const [pressed, setPressed] = React.useState(false);
|
|
493
|
+
|
|
494
|
+
// The handlers ride the plot *wrapper*, not the element: the hover
|
|
495
|
+
// overlays live between the two, and tracking must survive the pointer
|
|
496
|
+
// passing over its own crosshair. (They are also hit-transparent — see
|
|
497
|
+
// renderPlotOverlays — this is the second layer of the same defence.)
|
|
498
|
+
const onMouseMove = wantHover
|
|
499
|
+
? (ev: { x: number; y: number }) => {
|
|
500
|
+
lastPointer.current = { x: ev.x, y: ev.y };
|
|
501
|
+
takeHover(ev.x, ev.y);
|
|
502
|
+
}
|
|
503
|
+
: undefined;
|
|
504
|
+
const onMouseLeave = wantHover
|
|
505
|
+
? () => {
|
|
506
|
+
lastPointer.current = null;
|
|
507
|
+
setPressed(false);
|
|
508
|
+
setHover(null);
|
|
509
|
+
}
|
|
510
|
+
: undefined;
|
|
511
|
+
const onMouseDown = wantHover ? () => setPressed(true) : undefined;
|
|
512
|
+
const onMouseUp = wantHover ? () => setPressed(false) : undefined;
|
|
513
|
+
|
|
514
|
+
const plotChildren: ReactNode[] = [
|
|
515
|
+
h(ELEMENT, {
|
|
516
|
+
key: 'plot',
|
|
517
|
+
ref: setNode,
|
|
518
|
+
spec,
|
|
519
|
+
data: props.data,
|
|
520
|
+
formatters,
|
|
521
|
+
onFrameStats: props.onFrameStats,
|
|
522
|
+
// minHeight/minWidth 0: yoga's `min* : auto` content floor would
|
|
523
|
+
// otherwise hold the element at its intrinsic measure, and a chart
|
|
524
|
+
// plus its legend then OVERFLOWS a fixed-height container — the
|
|
525
|
+
// x-gutter's tick labels land on whatever flows below the chart
|
|
526
|
+
style: { flexGrow: 1, alignSelf: 'stretch', minHeight: 0, minWidth: 0 },
|
|
527
|
+
} as never),
|
|
528
|
+
];
|
|
529
|
+
if (hover) {
|
|
530
|
+
plotChildren.push(...renderPlotOverlays(hover, parts.tooltip));
|
|
531
|
+
if (!pressed) {
|
|
532
|
+
const bubble = renderTooltipBubble(
|
|
533
|
+
hover,
|
|
534
|
+
parts.tooltip,
|
|
535
|
+
formatters,
|
|
536
|
+
theme,
|
|
537
|
+
nodeRef,
|
|
538
|
+
parts.xAxis?.type,
|
|
539
|
+
);
|
|
540
|
+
if (bubble) plotChildren.push(bubble);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
const legendRow = parts.legend
|
|
545
|
+
? renderLegend(spec, parts.legend.verticalAlign ?? 'bottom')
|
|
546
|
+
: null;
|
|
547
|
+
|
|
548
|
+
return hx(
|
|
549
|
+
'box',
|
|
550
|
+
// flexGrow so a chart FILLS the container's styled height instead of
|
|
551
|
+
// sitting at the element's intrinsic size and overflowing it; with no
|
|
552
|
+
// height anywhere the intrinsic size still decides, as before.
|
|
553
|
+
// minHeight/minWidth 0 at every level of the column (here, the plot
|
|
554
|
+
// wrapper, the element): yoga's `min*: auto` content floor at ANY of
|
|
555
|
+
// them re-inflates the chart past a fixed container, and the gutter's
|
|
556
|
+
// tick labels then print over whatever flows after the chart.
|
|
557
|
+
{
|
|
558
|
+
style: [
|
|
559
|
+
{ flexDirection: 'column', flexGrow: 1, minHeight: 0, minWidth: 0 },
|
|
560
|
+
props.style,
|
|
561
|
+
],
|
|
562
|
+
'data-testname': props['data-testname'],
|
|
563
|
+
},
|
|
564
|
+
parts.legend?.verticalAlign === 'top' ? legendRow : null,
|
|
565
|
+
hx(
|
|
566
|
+
'box',
|
|
567
|
+
{
|
|
568
|
+
style: {
|
|
569
|
+
flexGrow: 1,
|
|
570
|
+
flexDirection: 'column',
|
|
571
|
+
position: 'relative',
|
|
572
|
+
// the other half of the content-floor release: the wrapper
|
|
573
|
+
// itself must be allowed to shrink into the container's box
|
|
574
|
+
minHeight: 0,
|
|
575
|
+
minWidth: 0,
|
|
576
|
+
},
|
|
577
|
+
onMouseMove,
|
|
578
|
+
onMouseLeave,
|
|
579
|
+
onMouseDown,
|
|
580
|
+
onMouseUp,
|
|
581
|
+
},
|
|
582
|
+
...plotChildren,
|
|
583
|
+
),
|
|
584
|
+
parts.legend?.verticalAlign !== 'top' ? legendRow : null,
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
Chart.displayName = displayName;
|
|
588
|
+
return Chart;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/** The four chart types are one cartesian chart under four names, the way
|
|
592
|
+
* shadcn's all sit on one recharts: the series children say what is drawn,
|
|
593
|
+
* and mixing them — bars under a line — works in any of these. The names
|
|
594
|
+
* exist so a chart reads as what it is. */
|
|
595
|
+
export const LineChart = makeCartesianChart('LineChart');
|
|
596
|
+
export const AreaChart = makeCartesianChart('AreaChart');
|
|
597
|
+
export const BarChart = makeCartesianChart('BarChart');
|
|
598
|
+
export const ScatterChart = makeCartesianChart('ScatterChart');
|
|
599
|
+
|
|
600
|
+
// --- hover overlays --------------------------------------------------------
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* The crosshair and the point markers: part of the plot, always in-window,
|
|
604
|
+
* and **hit-transparent** — without `pointerEvents: 'none'` the pointer
|
|
605
|
+
* lands on its own crosshair, the wrapper's move events keep flowing but a
|
|
606
|
+
* box the hover conjured must never be the thing under the mouse.
|
|
607
|
+
*/
|
|
608
|
+
function renderPlotOverlays(
|
|
609
|
+
hover: HoverState,
|
|
610
|
+
tooltip: ChartTooltipProps | null,
|
|
611
|
+
): ReactNode[] {
|
|
612
|
+
const { hit, originX, originY } = hover;
|
|
613
|
+
const out: ReactNode[] = [];
|
|
614
|
+
const plotTop = hit.plot.y - originY;
|
|
615
|
+
const crosshairX = hit.px - originX;
|
|
616
|
+
|
|
617
|
+
if (tooltip?.cursor !== false) {
|
|
618
|
+
out.push(
|
|
619
|
+
hx('box', {
|
|
620
|
+
key: 'crosshair',
|
|
621
|
+
style: {
|
|
622
|
+
position: 'absolute',
|
|
623
|
+
pointerEvents: 'none',
|
|
624
|
+
left: Math.round(crosshairX),
|
|
625
|
+
top: Math.round(plotTop),
|
|
626
|
+
width: 1,
|
|
627
|
+
height: Math.round(hit.plot.height),
|
|
628
|
+
backgroundColor: '$border',
|
|
629
|
+
},
|
|
630
|
+
}),
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
for (const p of hit.points) {
|
|
635
|
+
out.push(
|
|
636
|
+
hx('box', {
|
|
637
|
+
key: `marker-${p.id}`,
|
|
638
|
+
style: {
|
|
639
|
+
position: 'absolute',
|
|
640
|
+
pointerEvents: 'none',
|
|
641
|
+
left: Math.round(crosshairX - 3),
|
|
642
|
+
top: Math.round(p.py - originY - 3),
|
|
643
|
+
width: 7,
|
|
644
|
+
height: 7,
|
|
645
|
+
borderRadius: 4,
|
|
646
|
+
borderWidth: 1,
|
|
647
|
+
borderColor: '$background',
|
|
648
|
+
backgroundColor: p.color,
|
|
649
|
+
},
|
|
650
|
+
}),
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
return out;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/** Rough bubble height, for clamping before anything is laid out. */
|
|
657
|
+
function bubbleEstimate(points: number): number {
|
|
658
|
+
return 34 + points * 18;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* The value bubble, in whichever home `ChartTooltip mode` chose.
|
|
663
|
+
*
|
|
664
|
+
* The default is a `<popup>` hung off the data point through the anchor
|
|
665
|
+
* system — a real override-redirect window, so it stacks above content
|
|
666
|
+
* that flows after the chart (an in-window overlay paints in tree order
|
|
667
|
+
* and loses to any later sibling it leans over), follows screen-edge
|
|
668
|
+
* flips, and never takes focus. The bubble hangs on the side of the
|
|
669
|
+
* crosshair *away* from the pointer (with hysteresis), so the pointer
|
|
670
|
+
* cannot wander onto the tooltip window and flicker the hover.
|
|
671
|
+
*
|
|
672
|
+
* `mode="overlay"` keeps it as an absolutely-positioned, hit-transparent
|
|
673
|
+
* box clamped inside the chart: one window, one paint surface — and the
|
|
674
|
+
* documented trade that later siblings can overdraw whatever part of it
|
|
675
|
+
* would have left the chart's box.
|
|
676
|
+
*/
|
|
677
|
+
function renderTooltipBubble(
|
|
678
|
+
hover: HoverState,
|
|
679
|
+
tooltip: ChartTooltipProps | null,
|
|
680
|
+
formatters: ChartFormatters,
|
|
681
|
+
theme: ReturnType<typeof useTheme>,
|
|
682
|
+
anchorRef: React.RefObject<ChartPlotNode | null>,
|
|
683
|
+
xType?: AxisType,
|
|
684
|
+
): ReactNode | null {
|
|
685
|
+
const { hit, originX, originY, width, height, side } = hover;
|
|
686
|
+
const crosshairX = hit.px - originX;
|
|
687
|
+
const data: TooltipData = { xValue: hit.xValue, points: hit.points };
|
|
688
|
+
const fmtLabel =
|
|
689
|
+
tooltip?.labelFormatter ??
|
|
690
|
+
((v: number | string) => {
|
|
691
|
+
if (typeof v !== 'number') return String(v);
|
|
692
|
+
if (formatters.x) return formatters.x(v);
|
|
693
|
+
// a time axis without a formatter of its own labels the header the
|
|
694
|
+
// way it labels its ticks — never as raw epoch milliseconds
|
|
695
|
+
if (xType === 'time') return formatTimeTick(v, Math.max(1, hit.xSpan));
|
|
696
|
+
return String(v);
|
|
697
|
+
});
|
|
698
|
+
const fmtValue =
|
|
699
|
+
tooltip?.formatter ??
|
|
700
|
+
((v: number) => (formatters.y ? formatters.y(v) : formatValue(v)));
|
|
701
|
+
const content = tooltip?.content
|
|
702
|
+
? [tooltip.content(data)]
|
|
703
|
+
: defaultTooltipContent(data, fmtLabel, fmtValue);
|
|
704
|
+
|
|
705
|
+
if (tooltip?.mode === 'overlay') {
|
|
706
|
+
const est = bubbleEstimate(hit.points.length);
|
|
707
|
+
const bubbleStyle: Style = {
|
|
708
|
+
position: 'absolute',
|
|
709
|
+
pointerEvents: 'none',
|
|
710
|
+
top: Math.max(
|
|
711
|
+
0,
|
|
712
|
+
Math.min(
|
|
713
|
+
Math.round(hover.pointerY - originY + 14),
|
|
714
|
+
Math.round(height - est),
|
|
715
|
+
),
|
|
716
|
+
),
|
|
717
|
+
flexDirection: 'column',
|
|
718
|
+
padding: 8,
|
|
719
|
+
gap: 4,
|
|
720
|
+
// Theme.radiusTooltip is not reachable as a style token (radius
|
|
721
|
+
// tokens resolve to numbers only), so it is read off the theme here.
|
|
722
|
+
borderRadius: theme.radiusTooltip,
|
|
723
|
+
borderWidth: 1,
|
|
724
|
+
borderColor: '$border',
|
|
725
|
+
backgroundColor: '$background',
|
|
726
|
+
};
|
|
727
|
+
if (side === 'left')
|
|
728
|
+
bubbleStyle.right = Math.round(width - crosshairX + 10);
|
|
729
|
+
else bubbleStyle.left = Math.round(crosshairX + 10);
|
|
730
|
+
return hx('box', { key: 'tooltip', style: bubbleStyle }, ...content);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
// the pointer's y, clamped into the plot band so tracking across the
|
|
734
|
+
// axis gutter does not drag the bubble out of the chart
|
|
735
|
+
const anchorY = Math.max(
|
|
736
|
+
hit.plot.y - originY,
|
|
737
|
+
Math.min(hover.pointerY - originY, hit.plot.y - originY + hit.plot.height),
|
|
738
|
+
);
|
|
739
|
+
return hx(
|
|
740
|
+
'popup',
|
|
741
|
+
{
|
|
742
|
+
key: 'tooltip-popup',
|
|
743
|
+
// the palette does not cross into a separate window on its own; the
|
|
744
|
+
// re-declared theme is what makes the $tokens below resolve (the
|
|
745
|
+
// calendar's DatePicker sets the precedent)
|
|
746
|
+
theme,
|
|
747
|
+
width: 'auto',
|
|
748
|
+
height: 'auto',
|
|
749
|
+
anchor: {
|
|
750
|
+
// the ref-facing DrawnNode view and the retained node are the same
|
|
751
|
+
// object; the anchor system wants the former's type
|
|
752
|
+
to: anchorRef as unknown as { current: null },
|
|
753
|
+
at: { x: crosshairX, y: anchorY },
|
|
754
|
+
placement: side,
|
|
755
|
+
align: 'start',
|
|
756
|
+
offset: 14,
|
|
757
|
+
},
|
|
758
|
+
transparent: true,
|
|
759
|
+
style: {
|
|
760
|
+
backgroundColor: theme.background,
|
|
761
|
+
'@supports transparency': {
|
|
762
|
+
backgroundColor: 'transparent',
|
|
763
|
+
},
|
|
764
|
+
} as Style,
|
|
765
|
+
},
|
|
766
|
+
hx(
|
|
767
|
+
'box',
|
|
768
|
+
{
|
|
769
|
+
style: {
|
|
770
|
+
flexDirection: 'column',
|
|
771
|
+
padding: 8,
|
|
772
|
+
gap: 4,
|
|
773
|
+
borderRadius: theme.radiusTooltip,
|
|
774
|
+
borderWidth: 1,
|
|
775
|
+
borderColor: '$border',
|
|
776
|
+
backgroundColor: '$background',
|
|
777
|
+
},
|
|
778
|
+
},
|
|
779
|
+
...content,
|
|
780
|
+
),
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
function formatValue(v: number): string {
|
|
785
|
+
if (Number.isInteger(v)) return String(v);
|
|
786
|
+
return Math.abs(v) >= 100 ? v.toFixed(0) : v.toFixed(2);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
function defaultTooltipContent(
|
|
790
|
+
data: TooltipData,
|
|
791
|
+
fmtLabel: (v: number | string) => string,
|
|
792
|
+
fmtValue: (v: number, id: string) => string,
|
|
793
|
+
): ReactNode[] {
|
|
794
|
+
const rows: ReactNode[] = [
|
|
795
|
+
hx(
|
|
796
|
+
'text',
|
|
797
|
+
{ key: 'label', style: { color: '$textMuted', fontSize: 12 } },
|
|
798
|
+
fmtLabel(data.xValue),
|
|
799
|
+
),
|
|
800
|
+
];
|
|
801
|
+
for (const p of data.points) {
|
|
802
|
+
rows.push(
|
|
803
|
+
hx(
|
|
804
|
+
'box',
|
|
805
|
+
{
|
|
806
|
+
key: p.id,
|
|
807
|
+
style: { flexDirection: 'row', alignItems: 'center', gap: 6 },
|
|
808
|
+
},
|
|
809
|
+
hx('box', {
|
|
810
|
+
style: {
|
|
811
|
+
width: 8,
|
|
812
|
+
height: 8,
|
|
813
|
+
borderRadius: 2,
|
|
814
|
+
backgroundColor: p.color,
|
|
815
|
+
},
|
|
816
|
+
}),
|
|
817
|
+
hx('text', { style: { color: '$textMuted', fontSize: 12 } }, p.label),
|
|
818
|
+
hx('box', { style: { flexGrow: 1, minWidth: 12 } }),
|
|
819
|
+
hx(
|
|
820
|
+
'text',
|
|
821
|
+
{ style: { color: '$text', fontSize: 12 } },
|
|
822
|
+
fmtValue(p.value, p.id),
|
|
823
|
+
),
|
|
824
|
+
),
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
return rows;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// --- legend ----------------------------------------------------------------
|
|
831
|
+
|
|
832
|
+
function renderLegend(spec: PlotSpec, align: 'top' | 'bottom'): ReactElement {
|
|
833
|
+
return hx(
|
|
834
|
+
'box',
|
|
835
|
+
{
|
|
836
|
+
key: `legend-${align}`,
|
|
837
|
+
style: {
|
|
838
|
+
flexDirection: 'row',
|
|
839
|
+
justifyContent: 'center',
|
|
840
|
+
gap: 16,
|
|
841
|
+
paddingTop: align === 'bottom' ? 8 : 0,
|
|
842
|
+
paddingBottom: align === 'top' ? 8 : 0,
|
|
843
|
+
},
|
|
844
|
+
},
|
|
845
|
+
...spec.series.map((s) =>
|
|
846
|
+
hx(
|
|
847
|
+
'box',
|
|
848
|
+
{
|
|
849
|
+
key: s.id,
|
|
850
|
+
style: { flexDirection: 'row', alignItems: 'center', gap: 6 },
|
|
851
|
+
},
|
|
852
|
+
hx('box', {
|
|
853
|
+
style: {
|
|
854
|
+
width: 10,
|
|
855
|
+
height: 10,
|
|
856
|
+
borderRadius: 3,
|
|
857
|
+
backgroundColor: s.color,
|
|
858
|
+
},
|
|
859
|
+
}),
|
|
860
|
+
hx('text', { style: { color: '$textMuted', fontSize: 12 } }, s.label),
|
|
861
|
+
),
|
|
862
|
+
),
|
|
863
|
+
);
|
|
864
|
+
}
|