@aglyn/shared-ui-jsx 1.0.0-beta.143
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/LICENSE +201 -0
- package/README.md +7 -0
- package/package.json +63 -0
- package/src/index.d.ts +48 -0
- package/src/index.js +179 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/aglyn-text.d.ts +86 -0
- package/src/lib/components/aglyn-text.js +44 -0
- package/src/lib/components/aglyn-text.js.map +1 -0
- package/src/lib/components/app-link.d.ts +74 -0
- package/src/lib/components/app-link.js +139 -0
- package/src/lib/components/app-link.js.map +1 -0
- package/src/lib/components/aspect-ratio.d.ts +59 -0
- package/src/lib/components/aspect-ratio.js +153 -0
- package/src/lib/components/aspect-ratio.js.map +1 -0
- package/src/lib/components/background-image.component.d.ts +30 -0
- package/src/lib/components/background-image.component.js +42 -0
- package/src/lib/components/background-image.component.js.map +1 -0
- package/src/lib/components/card-columns.d.ts +86 -0
- package/src/lib/components/card-columns.js +148 -0
- package/src/lib/components/card-columns.js.map +1 -0
- package/src/lib/components/card-display.d.ts +36 -0
- package/src/lib/components/card-display.js +158 -0
- package/src/lib/components/card-display.js.map +1 -0
- package/src/lib/components/card-list-item.d.ts +35 -0
- package/src/lib/components/card-list-item.js +137 -0
- package/src/lib/components/card-list-item.js.map +1 -0
- package/src/lib/components/children-function-prop.d.ts +25 -0
- package/src/lib/components/children-function-prop.js +29 -0
- package/src/lib/components/children-function-prop.js.map +1 -0
- package/src/lib/components/confirmation-provider.component.d.ts +19 -0
- package/src/lib/components/confirmation-provider.component.js +83 -0
- package/src/lib/components/confirmation-provider.component.js.map +1 -0
- package/src/lib/components/container.d.ts +25 -0
- package/src/lib/components/container.js +62 -0
- package/src/lib/components/container.js.map +1 -0
- package/src/lib/components/data-table.component.d.ts +54 -0
- package/src/lib/components/data-table.component.js +211 -0
- package/src/lib/components/data-table.component.js.map +1 -0
- package/src/lib/components/dialog-confirm.d.ts +36 -0
- package/src/lib/components/dialog-confirm.js +74 -0
- package/src/lib/components/dialog-confirm.js.map +1 -0
- package/src/lib/components/ellipsis-pulse.component.d.ts +22 -0
- package/src/lib/components/ellipsis-pulse.component.js +51 -0
- package/src/lib/components/ellipsis-pulse.component.js.map +1 -0
- package/src/lib/components/emotion-cache-provider.d.ts +31 -0
- package/src/lib/components/emotion-cache-provider.js +40 -0
- package/src/lib/components/emotion-cache-provider.js.map +1 -0
- package/src/lib/components/empty-state.component.d.ts +63 -0
- package/src/lib/components/empty-state.component.js +214 -0
- package/src/lib/components/empty-state.component.js.map +1 -0
- package/src/lib/components/error-boundary.component.d.ts +28 -0
- package/src/lib/components/error-boundary.component.js +86 -0
- package/src/lib/components/error-boundary.component.js.map +1 -0
- package/src/lib/components/grid-buttons.d.ts +26 -0
- package/src/lib/components/grid-buttons.js +45 -0
- package/src/lib/components/grid-buttons.js.map +1 -0
- package/src/lib/components/grid-items.d.ts +103 -0
- package/src/lib/components/grid-items.js +336 -0
- package/src/lib/components/grid-items.js.map +1 -0
- package/src/lib/components/grid-list.d.ts +37 -0
- package/src/lib/components/grid-list.js +156 -0
- package/src/lib/components/grid-list.js.map +1 -0
- package/src/lib/components/help-tip.component.d.ts +30 -0
- package/src/lib/components/help-tip.component.js +139 -0
- package/src/lib/components/help-tip.component.js.map +1 -0
- package/src/lib/components/link-navigation-reporter.d.ts +24 -0
- package/src/lib/components/link-navigation-reporter.js +64 -0
- package/src/lib/components/link-navigation-reporter.js.map +1 -0
- package/src/lib/components/list-pagination.component.d.ts +57 -0
- package/src/lib/components/list-pagination.component.js +90 -0
- package/src/lib/components/list-pagination.component.js.map +1 -0
- package/src/lib/components/list-table.component.d.ts +155 -0
- package/src/lib/components/list-table.component.js +369 -0
- package/src/lib/components/list-table.component.js.map +1 -0
- package/src/lib/components/loading-layout-app.component.d.ts +35 -0
- package/src/lib/components/loading-layout-app.component.js +42 -0
- package/src/lib/components/loading-layout-app.component.js.map +1 -0
- package/src/lib/components/loading-modal-overlay.d.ts +30 -0
- package/src/lib/components/loading-modal-overlay.js +156 -0
- package/src/lib/components/loading-modal-overlay.js.map +1 -0
- package/src/lib/components/loading-modal.d.ts +19 -0
- package/src/lib/components/loading-modal.js +113 -0
- package/src/lib/components/loading-modal.js.map +1 -0
- package/src/lib/components/loading-text.component.d.ts +21 -0
- package/src/lib/components/loading-text.component.js +40 -0
- package/src/lib/components/loading-text.component.js.map +1 -0
- package/src/lib/components/mdi-icon/index.d.ts +2 -0
- package/src/lib/components/mdi-icon/index.js +4 -0
- package/src/lib/components/mdi-icon/index.js.map +1 -0
- package/src/lib/components/mdi-icon/md-icon-stack.d.ts +31 -0
- package/src/lib/components/mdi-icon/md-icon-stack.js +101 -0
- package/src/lib/components/mdi-icon/md-icon-stack.js.map +1 -0
- package/src/lib/components/mdi-icon/md-icon.d.ts +32 -0
- package/src/lib/components/mdi-icon/md-icon.js +147 -0
- package/src/lib/components/mdi-icon/md-icon.js.map +1 -0
- package/src/lib/components/mdi-icon/mdi-icon-from-id.d.ts +23 -0
- package/src/lib/components/mdi-icon/mdi-icon-from-id.js +35 -0
- package/src/lib/components/mdi-icon/mdi-icon-from-id.js.map +1 -0
- package/src/lib/components/mdi-icon/mdi-icon.d.ts +24 -0
- package/src/lib/components/mdi-icon/mdi-icon.js +46 -0
- package/src/lib/components/mdi-icon/mdi-icon.js.map +1 -0
- package/src/lib/components/measured-figures.component.d.ts +64 -0
- package/src/lib/components/measured-figures.component.js +161 -0
- package/src/lib/components/measured-figures.component.js.map +1 -0
- package/src/lib/components/menu.d.ts +45 -0
- package/src/lib/components/menu.js +229 -0
- package/src/lib/components/menu.js.map +1 -0
- package/src/lib/components/mui-shadow-dom.d.ts +38 -0
- package/src/lib/components/mui-shadow-dom.js +161 -0
- package/src/lib/components/mui-shadow-dom.js.map +1 -0
- package/src/lib/components/navigation-drawer.component.d.ts +31 -0
- package/src/lib/components/navigation-drawer.component.js +76 -0
- package/src/lib/components/navigation-drawer.component.js.map +1 -0
- package/src/lib/components/navigation-intent.d.ts +18 -0
- package/src/lib/components/navigation-intent.js +56 -0
- package/src/lib/components/navigation-intent.js.map +1 -0
- package/src/lib/components/navigation-view/index.d.ts +18 -0
- package/src/lib/components/navigation-view/index.js +19 -0
- package/src/lib/components/navigation-view/index.js.map +1 -0
- package/src/lib/components/navigation-view/navigation-view.d.ts +35 -0
- package/src/lib/components/navigation-view/navigation-view.js +175 -0
- package/src/lib/components/navigation-view/navigation-view.js.map +1 -0
- package/src/lib/components/next-link.d.ts +27 -0
- package/src/lib/components/next-link.js +88 -0
- package/src/lib/components/next-link.js.map +1 -0
- package/src/lib/components/popper-styled.component.d.ts +25 -0
- package/src/lib/components/popper-styled.component.js +129 -0
- package/src/lib/components/popper-styled.component.js.map +1 -0
- package/src/lib/components/quota-readout.component.d.ts +69 -0
- package/src/lib/components/quota-readout.component.js +52 -0
- package/src/lib/components/quota-readout.component.js.map +1 -0
- package/src/lib/components/resizeable-stack.d.ts +4 -0
- package/src/lib/components/resizeable-stack.js +23 -0
- package/src/lib/components/resizeable-stack.js.map +1 -0
- package/src/lib/components/row-actions-menu.component.d.ts +53 -0
- package/src/lib/components/row-actions-menu.component.js +132 -0
- package/src/lib/components/row-actions-menu.component.js.map +1 -0
- package/src/lib/components/ruler-guides.component.d.ts +35 -0
- package/src/lib/components/ruler-guides.component.js +166 -0
- package/src/lib/components/ruler-guides.component.js.map +1 -0
- package/src/lib/components/sandbox-frame.d.ts +42 -0
- package/src/lib/components/sandbox-frame.js +122 -0
- package/src/lib/components/sandbox-frame.js.map +1 -0
- package/src/lib/components/scroll-reaction.d.ts +59 -0
- package/src/lib/components/scroll-reaction.js +43 -0
- package/src/lib/components/scroll-reaction.js.map +1 -0
- package/src/lib/components/scroll-table.component.d.ts +124 -0
- package/src/lib/components/scroll-table.component.js +103 -0
- package/src/lib/components/scroll-table.component.js.map +1 -0
- package/src/lib/components/shadow-dom/index.d.ts +18 -0
- package/src/lib/components/shadow-dom/index.js +19 -0
- package/src/lib/components/shadow-dom/index.js.map +1 -0
- package/src/lib/components/shadow-dom/shadow-dom.d.ts +42 -0
- package/src/lib/components/shadow-dom/shadow-dom.js +123 -0
- package/src/lib/components/shadow-dom/shadow-dom.js.map +1 -0
- package/src/lib/components/splash-screen.d.ts +33 -0
- package/src/lib/components/splash-screen.js +105 -0
- package/src/lib/components/splash-screen.js.map +1 -0
- package/src/lib/components/sr-only.d.ts +20 -0
- package/src/lib/components/sr-only.js +25 -0
- package/src/lib/components/sr-only.js.map +1 -0
- package/src/lib/components/status-screen-plain.component.d.ts +27 -0
- package/src/lib/components/status-screen-plain.component.js +178 -0
- package/src/lib/components/status-screen-plain.component.js.map +1 -0
- package/src/lib/components/usage-meter.component.d.ts +30 -0
- package/src/lib/components/usage-meter.component.js +92 -0
- package/src/lib/components/usage-meter.component.js.map +1 -0
- package/src/lib/components/variable-text-field.component.d.ts +50 -0
- package/src/lib/components/variable-text-field.component.js +188 -0
- package/src/lib/components/variable-text-field.component.js.map +1 -0
- package/src/lib/components/zoomable-panning-component/index.d.ts +1 -0
- package/src/lib/components/zoomable-panning-component/index.js +3 -0
- package/src/lib/components/zoomable-panning-component/index.js.map +1 -0
- package/src/lib/components/zoomable-panning-component/util.d.ts +58 -0
- package/src/lib/components/zoomable-panning-component/util.js +114 -0
- package/src/lib/components/zoomable-panning-component/util.js.map +1 -0
- package/src/lib/components/zoomable-panning-component/zoomable-panning-component.d.ts +132 -0
- package/src/lib/components/zoomable-panning-component/zoomable-panning-component.js +728 -0
- package/src/lib/components/zoomable-panning-component/zoomable-panning-component.js.map +1 -0
- package/src/lib/const/aglyn-besigner-logo-full.d.ts +39 -0
- package/src/lib/const/aglyn-besigner-logo-full.js +146 -0
- package/src/lib/const/aglyn-besigner-logo-full.js.map +1 -0
- package/src/lib/const/aglyn-console-logo-full.d.ts +34 -0
- package/src/lib/const/aglyn-console-logo-full.js +142 -0
- package/src/lib/const/aglyn-console-logo-full.js.map +1 -0
- package/src/lib/const/aglyn-logo-class-keys.d.ts +30 -0
- package/src/lib/const/aglyn-logo-class-keys.js +32 -0
- package/src/lib/const/aglyn-logo-class-keys.js.map +1 -0
- package/src/lib/const/aglyn-logo-full.d.ts +29 -0
- package/src/lib/const/aglyn-logo-full.js +111 -0
- package/src/lib/const/aglyn-logo-full.js.map +1 -0
- package/src/lib/const/list-filter.d.ts +260 -0
- package/src/lib/const/list-filter.js +409 -0
- package/src/lib/const/list-filter.js.map +1 -0
- package/src/lib/const/prebuilt-components.d.ts +17 -0
- package/src/lib/const/prebuilt-components.js +22 -0
- package/src/lib/const/prebuilt-components.js.map +1 -0
- package/src/lib/const/svg-icons.d.ts +75 -0
- package/src/lib/const/svg-icons.js +313 -0
- package/src/lib/const/svg-icons.js.map +1 -0
- package/src/lib/const/table-pagination.d.ts +106 -0
- package/src/lib/const/table-pagination.js +106 -0
- package/src/lib/const/table-pagination.js.map +1 -0
- package/src/lib/contexts/confirmation.context.d.ts +996 -0
- package/src/lib/contexts/confirmation.context.js +49 -0
- package/src/lib/contexts/confirmation.context.js.map +1 -0
- package/src/lib/contexts/loading.context.d.ts +93 -0
- package/src/lib/contexts/loading.context.js +126 -0
- package/src/lib/contexts/loading.context.js.map +1 -0
- package/src/lib/hocs/create-hoc-with-context-consumer.d.ts +36 -0
- package/src/lib/hocs/create-hoc-with-context-consumer.js +44 -0
- package/src/lib/hocs/create-hoc-with-context-consumer.js.map +1 -0
- package/src/lib/hocs/with-hoc.d.ts +32 -0
- package/src/lib/hocs/with-hoc.js +37 -0
- package/src/lib/hocs/with-hoc.js.map +1 -0
- package/src/lib/hooks/mdi-icon/use-mdi-icon.d.ts +20 -0
- package/src/lib/hooks/mdi-icon/use-mdi-icon.js +48 -0
- package/src/lib/hooks/mdi-icon/use-mdi-icon.js.map +1 -0
- package/src/lib/hooks/mdi-icon/use-mdi-icons-fuzzy.d.ts +26 -0
- package/src/lib/hooks/mdi-icon/use-mdi-icons-fuzzy.js +73 -0
- package/src/lib/hooks/mdi-icon/use-mdi-icons-fuzzy.js.map +1 -0
- package/src/lib/hooks/mdi-icon/use-mdi-icons.d.ts +19 -0
- package/src/lib/hooks/mdi-icon/use-mdi-icons.js +49 -0
- package/src/lib/hooks/mdi-icon/use-mdi-icons.js.map +1 -0
- package/src/lib/hooks/router-events.d.ts +56 -0
- package/src/lib/hooks/router-events.js +88 -0
- package/src/lib/hooks/router-events.js.map +1 -0
- package/src/lib/hooks/use-async-effect.d.ts +24 -0
- package/src/lib/hooks/use-async-effect.js +44 -0
- package/src/lib/hooks/use-async-effect.js.map +1 -0
- package/src/lib/hooks/use-callback-param-ref.d.ts +19 -0
- package/src/lib/hooks/use-callback-param-ref.js +29 -0
- package/src/lib/hooks/use-callback-param-ref.js.map +1 -0
- package/src/lib/hooks/use-id.d.ts +21 -0
- package/src/lib/hooks/use-id.js +28 -0
- package/src/lib/hooks/use-id.js.map +1 -0
- package/src/lib/hooks/use-isomorphic-layout-effect.d.ts +19 -0
- package/src/lib/hooks/use-isomorphic-layout-effect.js +20 -0
- package/src/lib/hooks/use-isomorphic-layout-effect.js.map +1 -0
- package/src/lib/hooks/use-merge-refs.d.ts +38 -0
- package/src/lib/hooks/use-merge-refs.js +52 -0
- package/src/lib/hooks/use-merge-refs.js.map +1 -0
- package/src/lib/hooks/use-subscribable.d.ts +29 -0
- package/src/lib/hooks/use-subscribable.js +50 -0
- package/src/lib/hooks/use-subscribable.js.map +1 -0
- package/src/lib/types.d.ts +18 -0
- package/src/lib/types.js +18 -0
- package/src/lib/types.js.map +1 -0
- package/src/lib/utils/make-link-elements.d.ts +24 -0
- package/src/lib/utils/make-link-elements.js +32 -0
- package/src/lib/utils/make-link-elements.js.map +1 -0
- package/src/lib/utils/make-meta-elements.d.ts +24 -0
- package/src/lib/utils/make-meta-elements.js +32 -0
- package/src/lib/utils/make-meta-elements.js.map +1 -0
- package/src/lib/utils/scroll-overflow.d.ts +120 -0
- package/src/lib/utils/scroll-overflow.js +115 -0
- package/src/lib/utils/scroll-overflow.js.map +1 -0
- package/src/lib/utils/vendor.d.ts +17 -0
- package/src/lib/utils/vendor.js +18 -0
- package/src/lib/utils/vendor.js.map +1 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ 'use client';
|
|
17
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
18
|
+
import { _ as _object_without_properties_loose } from "@swc/helpers/_/_object_without_properties_loose";
|
|
19
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
20
|
+
import { mdiPlus } from "@aglyn/shared-data-mdi";
|
|
21
|
+
import { IconButton, InputAdornment, ListItemText, Menu, MenuItem, TextField, Tooltip, Typography } from "@mui/material";
|
|
22
|
+
import { useCallback, useMemo, useRef, useState } from "react";
|
|
23
|
+
import { MdiIcon } from "./mdi-icon/mdi-icon.js";
|
|
24
|
+
/** `{{` plus the partial name after it, at the very end of what was typed. */ const OPEN_TOKEN = /\{\{([a-zA-Z][\w.]*)?$/;
|
|
25
|
+
export function VariableTextField(props) {
|
|
26
|
+
var _ref;
|
|
27
|
+
const { value, onChange, variables, insertLabel = 'Insert a variable', slotProps } = props, rest = _object_without_properties_loose(props, [
|
|
28
|
+
"value",
|
|
29
|
+
"onChange",
|
|
30
|
+
"variables",
|
|
31
|
+
"insertLabel",
|
|
32
|
+
"slotProps"
|
|
33
|
+
]);
|
|
34
|
+
const inputRef = useRef(null);
|
|
35
|
+
/**
|
|
36
|
+
* The two ways the list opens, held APART.
|
|
37
|
+
*
|
|
38
|
+
* They insert differently — the `+` adds a variable at the caret, while
|
|
39
|
+
* autocomplete REPLACES the `{{` and the partial name under it — and one
|
|
40
|
+
* state for both got that wrong in the direction that is easy to miss: a
|
|
41
|
+
* `+` insert also ate the two characters after the caret, which on a title
|
|
42
|
+
* being edited in the middle silently deleted whatever was there.
|
|
43
|
+
*
|
|
44
|
+
* Both carry the caret as it was when the list opened, because opening a
|
|
45
|
+
* menu moves focus off the input and a caret read afterwards is 0.
|
|
46
|
+
*/ const [picker, setPicker] = useState(null);
|
|
47
|
+
const [typing, setTyping] = useState(null);
|
|
48
|
+
const matches = useMemo(()=>{
|
|
49
|
+
var _ref;
|
|
50
|
+
var _typing_partial;
|
|
51
|
+
const partial = (_ref = typing == null ? void 0 : (_typing_partial = typing.partial) == null ? void 0 : _typing_partial.toLowerCase()) != null ? _ref : '';
|
|
52
|
+
if (!partial) return variables;
|
|
53
|
+
return variables.filter((variable)=>variable.name.toLowerCase().includes(partial) || variable.label.toLowerCase().includes(partial));
|
|
54
|
+
}, [
|
|
55
|
+
typing,
|
|
56
|
+
variables
|
|
57
|
+
]);
|
|
58
|
+
/** Where the caret is, or the end of the value when there is no input yet. */ const caret = useCallback(()=>{
|
|
59
|
+
var _ref;
|
|
60
|
+
var _inputRef_current;
|
|
61
|
+
return (_ref = (_inputRef_current = inputRef.current) == null ? void 0 : _inputRef_current.selectionStart) != null ? _ref : value.length;
|
|
62
|
+
}, [
|
|
63
|
+
value.length
|
|
64
|
+
]);
|
|
65
|
+
const insertAt = useCallback((name, from, to)=>{
|
|
66
|
+
const token = `{{${name}}}`;
|
|
67
|
+
onChange(`${value.slice(0, from)}${token}${value.slice(to)}`);
|
|
68
|
+
// After the paint that renders the new value, or the browser puts the
|
|
69
|
+
// caret back where the old value ended.
|
|
70
|
+
requestAnimationFrame(()=>{
|
|
71
|
+
const input = inputRef.current;
|
|
72
|
+
if (!input) return;
|
|
73
|
+
input.focus();
|
|
74
|
+
input.setSelectionRange(from + token.length, from + token.length);
|
|
75
|
+
});
|
|
76
|
+
}, [
|
|
77
|
+
onChange,
|
|
78
|
+
value
|
|
79
|
+
]);
|
|
80
|
+
const handleChange = useCallback((event)=>{
|
|
81
|
+
var _event_target_selectionStart, _open_;
|
|
82
|
+
const next = event.target.value;
|
|
83
|
+
onChange(next);
|
|
84
|
+
// `{{` at the caret opens the list; anything else closes it. Read from
|
|
85
|
+
// the text BEFORE the caret only, so typing `{{` in the middle of a
|
|
86
|
+
// title offers the list for that position rather than for the end.
|
|
87
|
+
const before = next.slice(0, (_event_target_selectionStart = event.target.selectionStart) != null ? _event_target_selectionStart : next.length);
|
|
88
|
+
const open = OPEN_TOKEN.exec(before);
|
|
89
|
+
setTyping(open ? {
|
|
90
|
+
at: before.length - open[0].length,
|
|
91
|
+
partial: (_open_ = open[1]) != null ? _open_ : ''
|
|
92
|
+
} : null);
|
|
93
|
+
}, [
|
|
94
|
+
onChange
|
|
95
|
+
]);
|
|
96
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
97
|
+
children: [
|
|
98
|
+
/*#__PURE__*/ _jsx(TextField, _extends({}, rest, {
|
|
99
|
+
value: value,
|
|
100
|
+
onChange: handleChange,
|
|
101
|
+
onBlur: (event)=>{
|
|
102
|
+
setTyping(null);
|
|
103
|
+
rest.onBlur == null ? void 0 : rest.onBlur.call(rest, event);
|
|
104
|
+
},
|
|
105
|
+
/*
|
|
106
|
+
* `inputRef`, not `slotProps.htmlInput.ref`. The slot's `ref` reaches
|
|
107
|
+
* the native input only on some of MUI's input variants, and a null
|
|
108
|
+
* ref here does not fail loudly — it silently makes `caret()` return
|
|
109
|
+
* the END of the value, so every insert lands after the title instead
|
|
110
|
+
* of where the author was typing. This is the prop `InputBase` forks
|
|
111
|
+
* into the input on every variant.
|
|
112
|
+
*/ inputRef: inputRef,
|
|
113
|
+
slotProps: _extends({}, slotProps, {
|
|
114
|
+
input: _extends({}, slotProps == null ? void 0 : slotProps.input, {
|
|
115
|
+
endAdornment: /*#__PURE__*/ _jsx(InputAdornment, {
|
|
116
|
+
position: "end",
|
|
117
|
+
children: /*#__PURE__*/ _jsx(Tooltip, {
|
|
118
|
+
title: insertLabel,
|
|
119
|
+
children: /*#__PURE__*/ _jsx(IconButton, {
|
|
120
|
+
size: "small",
|
|
121
|
+
"aria-label": insertLabel,
|
|
122
|
+
onClick: (event)=>{
|
|
123
|
+
// The caret is read HERE, while the input still has it.
|
|
124
|
+
setTyping(null);
|
|
125
|
+
setPicker({
|
|
126
|
+
anchor: event.currentTarget,
|
|
127
|
+
at: caret()
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
children: /*#__PURE__*/ _jsx(MdiIcon, {
|
|
131
|
+
fontSize: "small",
|
|
132
|
+
path: mdiPlus.path
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
})
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
})),
|
|
140
|
+
/*#__PURE__*/ _jsx(Menu, {
|
|
141
|
+
open: Boolean(picker) || Boolean(typing) && matches.length > 0,
|
|
142
|
+
anchorEl: (_ref = picker == null ? void 0 : picker.anchor) != null ? _ref : inputRef.current,
|
|
143
|
+
onClose: ()=>{
|
|
144
|
+
setPicker(null);
|
|
145
|
+
setTyping(null);
|
|
146
|
+
},
|
|
147
|
+
// The menu must not steal the caret while somebody is mid-word: an
|
|
148
|
+
// autocomplete that focused itself would end the typing run it exists
|
|
149
|
+
// to complete.
|
|
150
|
+
disableAutoFocus: !picker,
|
|
151
|
+
disableEnforceFocus: !picker,
|
|
152
|
+
anchorOrigin: {
|
|
153
|
+
vertical: 'bottom',
|
|
154
|
+
horizontal: 'left'
|
|
155
|
+
},
|
|
156
|
+
children: matches.map((variable)=>/*#__PURE__*/ _jsx(MenuItem, {
|
|
157
|
+
onClick: ()=>{
|
|
158
|
+
if (typing) {
|
|
159
|
+
// Autocomplete REPLACES the `{{` and the partial under it.
|
|
160
|
+
const to = Math.min(typing.at + 2 + typing.partial.length, value.length);
|
|
161
|
+
insertAt(variable.name, typing.at, to);
|
|
162
|
+
} else {
|
|
163
|
+
var _ref;
|
|
164
|
+
// The `+` INSERTS, replacing nothing.
|
|
165
|
+
const at = (_ref = picker == null ? void 0 : picker.at) != null ? _ref : caret();
|
|
166
|
+
insertAt(variable.name, at, at);
|
|
167
|
+
}
|
|
168
|
+
setPicker(null);
|
|
169
|
+
setTyping(null);
|
|
170
|
+
},
|
|
171
|
+
children: /*#__PURE__*/ _jsx(ListItemText, {
|
|
172
|
+
primary: variable.label,
|
|
173
|
+
secondary: /*#__PURE__*/ _jsx(Typography, {
|
|
174
|
+
variant: "caption",
|
|
175
|
+
color: "text.secondary",
|
|
176
|
+
component: "span",
|
|
177
|
+
children: `{{${variable.name}}}${variable.description ? ` — ${variable.description}` : ''}`
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
}, variable.name))
|
|
181
|
+
})
|
|
182
|
+
]
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
VariableTextField.displayName = 'VariableTextField';
|
|
186
|
+
export default VariableTextField;
|
|
187
|
+
|
|
188
|
+
//# sourceMappingURL=variable-text-field.component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../libs/shared/ui/jsx/src/lib/components/variable-text-field.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { mdiPlus } from '@aglyn/shared-data-mdi'\nimport {\n IconButton,\n InputAdornment,\n ListItemText,\n Menu,\n MenuItem,\n TextField,\n type TextFieldProps,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { useCallback, useMemo, useRef, useState } from 'react'\nimport { MdiIcon } from './mdi-icon/mdi-icon'\n\n/**\n * A text field whose value may name VARIABLES, with the two ways of reaching\n * them that the besigner's attribute fields already taught (AGL-3197).\n *\n * ## What it is, and what it deliberately is not\n *\n * It is a plain MUI `TextField`. The value in it is the value that is stored —\n * `{{site.name}}` reads as `{{site.name}}`, and what makes that legible is the\n * PREVIEW under the field, not a pill drawn over the text.\n *\n * The besigner's `TokenTextField` does draw pills, and this is not that on\n * purpose. That field is a contentEditable surface with its own selection\n * model, DOM/model sync contract, paste handling and undo trade-offs, wired to\n * react-final-form and to the canvas's binding and media pickers. It earns all\n * of that because a node attribute can hold a token referring to any record on\n * the page. Here there are three variables, the field is 60 characters long,\n * and the honest cost of a pill surface — an editor that fights the IME, an\n * undo stack that truncates, a value the author cannot select and retype — is\n * not worth paying for a title. A plain input, a menu and a live preview are.\n *\n * ## Two ways in, because people reach for different ones\n *\n * The `+` opens the list with a description under each name; typing `{{`\n * offers the same list inline, filtered by whatever follows. Either way the\n * insert lands at the caret, and the caret is left after it — not at the end\n * of the value, which is where an insert that rebuilt the string would leave\n * it, and which is wrong whenever somebody is editing the middle of a title.\n */\n\nexport interface VariableOption {\n /** Written between the braces. */\n name: string\n /** What the menu calls it. */\n label: string\n /** One line under the label. */\n description?: string\n}\n\nexport interface VariableTextFieldProps\n extends Omit<TextFieldProps, 'onChange' | 'value'> {\n value: string\n onChange: (value: string) => void\n /** Every variable this field offers. */\n variables: readonly VariableOption[]\n /** The tooltip on the insert control. */\n insertLabel?: string\n}\n\n/** `{{` plus the partial name after it, at the very end of what was typed. */\nconst OPEN_TOKEN = /\\{\\{([a-zA-Z][\\w.]*)?$/\n\nexport function VariableTextField(props: VariableTextFieldProps) {\n const {\n value,\n onChange,\n variables,\n insertLabel = 'Insert a variable',\n slotProps,\n ...rest\n } = props\n\n const inputRef = useRef<HTMLInputElement | null>(null)\n /**\n * The two ways the list opens, held APART.\n *\n * They insert differently — the `+` adds a variable at the caret, while\n * autocomplete REPLACES the `{{` and the partial name under it — and one\n * state for both got that wrong in the direction that is easy to miss: a\n * `+` insert also ate the two characters after the caret, which on a title\n * being edited in the middle silently deleted whatever was there.\n *\n * Both carry the caret as it was when the list opened, because opening a\n * menu moves focus off the input and a caret read afterwards is 0.\n */\n const [picker, setPicker] = useState<{ anchor: HTMLElement; at: number } | null>(null)\n const [typing, setTyping] = useState<{ at: number; partial: string } | null>(null)\n\n const matches = useMemo(() => {\n const partial = typing?.partial?.toLowerCase() ?? ''\n if (!partial) return variables\n return variables.filter(\n (variable) =>\n variable.name.toLowerCase().includes(partial) ||\n variable.label.toLowerCase().includes(partial),\n )\n }, [typing, variables])\n\n /** Where the caret is, or the end of the value when there is no input yet. */\n const caret = useCallback(\n () => inputRef.current?.selectionStart ?? value.length,\n [value.length],\n )\n\n const insertAt = useCallback(\n (name: string, from: number, to: number) => {\n const token = `{{${name}}}`\n onChange(`${value.slice(0, from)}${token}${value.slice(to)}`)\n // After the paint that renders the new value, or the browser puts the\n // caret back where the old value ended.\n requestAnimationFrame(() => {\n const input = inputRef.current\n if (!input) return\n input.focus()\n input.setSelectionRange(from + token.length, from + token.length)\n })\n },\n [onChange, value],\n )\n\n const handleChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n const next = event.target.value\n onChange(next)\n // `{{` at the caret opens the list; anything else closes it. Read from\n // the text BEFORE the caret only, so typing `{{` in the middle of a\n // title offers the list for that position rather than for the end.\n const before = next.slice(0, event.target.selectionStart ?? next.length)\n const open = OPEN_TOKEN.exec(before)\n setTyping(\n open\n ? { at: before.length - open[0].length, partial: open[1] ?? '' }\n : null,\n )\n },\n [onChange],\n )\n\n return (\n <>\n <TextField\n {...rest}\n value={value}\n onChange={handleChange}\n onBlur={(event) => {\n setTyping(null)\n rest.onBlur?.(event)\n }}\n /*\n * `inputRef`, not `slotProps.htmlInput.ref`. The slot's `ref` reaches\n * the native input only on some of MUI's input variants, and a null\n * ref here does not fail loudly — it silently makes `caret()` return\n * the END of the value, so every insert lands after the title instead\n * of where the author was typing. This is the prop `InputBase` forks\n * into the input on every variant.\n */\n inputRef={inputRef}\n slotProps={{\n ...slotProps,\n input: {\n ...(slotProps?.input as object),\n endAdornment: (\n <InputAdornment position=\"end\">\n <Tooltip title={insertLabel}>\n <IconButton\n size=\"small\"\n aria-label={insertLabel}\n onClick={(event) => {\n // The caret is read HERE, while the input still has it.\n setTyping(null)\n setPicker({ anchor: event.currentTarget, at: caret() })\n }}\n >\n <MdiIcon fontSize=\"small\" path={mdiPlus.path} />\n </IconButton>\n </Tooltip>\n </InputAdornment>\n ),\n },\n }}\n />\n <Menu\n open={Boolean(picker) || (Boolean(typing) && matches.length > 0)}\n anchorEl={picker?.anchor ?? inputRef.current}\n onClose={() => {\n setPicker(null)\n setTyping(null)\n }}\n // The menu must not steal the caret while somebody is mid-word: an\n // autocomplete that focused itself would end the typing run it exists\n // to complete.\n disableAutoFocus={!picker}\n disableEnforceFocus={!picker}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n >\n {matches.map((variable) => (\n <MenuItem\n key={variable.name}\n onClick={() => {\n if (typing) {\n // Autocomplete REPLACES the `{{` and the partial under it.\n const to = Math.min(typing.at + 2 + typing.partial.length, value.length)\n insertAt(variable.name, typing.at, to)\n } else {\n // The `+` INSERTS, replacing nothing.\n const at = picker?.at ?? caret()\n insertAt(variable.name, at, at)\n }\n setPicker(null)\n setTyping(null)\n }}\n >\n <ListItemText\n primary={variable.label}\n secondary={\n <Typography variant=\"caption\" color=\"text.secondary\" component=\"span\">\n {`{{${variable.name}}}${\n variable.description ? ` — ${variable.description}` : ''\n }`}\n </Typography>\n }\n />\n </MenuItem>\n ))}\n </Menu>\n </>\n )\n}\nVariableTextField.displayName = 'VariableTextField'\n\nexport default VariableTextField\n"],"names":["mdiPlus","IconButton","InputAdornment","ListItemText","Menu","MenuItem","TextField","Tooltip","Typography","useCallback","useMemo","useRef","useState","MdiIcon","OPEN_TOKEN","VariableTextField","props","value","onChange","variables","insertLabel","slotProps","rest","inputRef","picker","setPicker","typing","setTyping","matches","partial","toLowerCase","filter","variable","name","includes","label","caret","current","selectionStart","length","insertAt","from","to","token","slice","requestAnimationFrame","input","focus","setSelectionRange","handleChange","event","open","next","target","before","exec","at","onBlur","endAdornment","position","title","size","aria-label","onClick","anchor","currentTarget","fontSize","path","Boolean","anchorEl","onClose","disableAutoFocus","disableEnforceFocus","anchorOrigin","vertical","horizontal","map","Math","min","primary","secondary","variant","color","component","description","displayName"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './zoomable-panning-component';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../libs/shared/ui/jsx/src/lib/components/zoomable-panning-component/index.ts"],"sourcesContent":["export * from './zoomable-panning-component'\n"],"names":[],"mappings":"AAAA,cAAc,kCAA8B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
export type TransformationMatrix = {
|
|
18
|
+
a: number;
|
|
19
|
+
b: number;
|
|
20
|
+
c: number;
|
|
21
|
+
d: number;
|
|
22
|
+
x: number;
|
|
23
|
+
y: number;
|
|
24
|
+
};
|
|
25
|
+
export type BoundingBox = {
|
|
26
|
+
top: number;
|
|
27
|
+
left: number;
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
};
|
|
31
|
+
export type BoundaryRatio = {
|
|
32
|
+
vertical: number;
|
|
33
|
+
horizontal: number;
|
|
34
|
+
};
|
|
35
|
+
export type Coordinates = {
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
};
|
|
39
|
+
export type BoundCoordinates = {
|
|
40
|
+
boundX: number;
|
|
41
|
+
boundY: number;
|
|
42
|
+
offsetX: number;
|
|
43
|
+
offsetY: number;
|
|
44
|
+
};
|
|
45
|
+
export type TransformationParameters = {
|
|
46
|
+
angle: number;
|
|
47
|
+
scale: number;
|
|
48
|
+
offsetX: number;
|
|
49
|
+
offsetY: number;
|
|
50
|
+
};
|
|
51
|
+
export declare const ZOOM_SPEED_MULTIPLIER = 0.065;
|
|
52
|
+
export declare const TransformMatrix: (transformationParameters: TransformationParameters, centerCoordinates: Coordinates) => TransformationMatrix;
|
|
53
|
+
export declare const getTransformedBoundingBox: (transformationParameters: TransformationParameters, boundingBox: BoundingBox) => BoundingBox;
|
|
54
|
+
export declare const getScaleMultiplier: (delta: number, zoomSpeed?: number) => number;
|
|
55
|
+
export declare const boundCoordinates: (x: number, y: number, boundaryRatio: BoundaryRatio, boundingBox: BoundingBox, containerHeight: number, containerWidth: number, offsetX?: number, offsetY?: number) => BoundCoordinates;
|
|
56
|
+
export declare const preventDefault: (e: Event) => void;
|
|
57
|
+
export declare const captureTextSelection: () => void;
|
|
58
|
+
export declare const releaseTextSelection: () => void;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/ export const ZOOM_SPEED_MULTIPLIER = 0.065;
|
|
17
|
+
// Transform matrix use to rotate, zoom and pan
|
|
18
|
+
// Can be written as T(centerX, centerY) * R(theta) * T(-centerX, -centerY) * S(scale, scale) + T(offsetX, offsetY)
|
|
19
|
+
// ( a , c, x )
|
|
20
|
+
// ( b , d, y )
|
|
21
|
+
// ( 0 , 0, 1 )
|
|
22
|
+
export const TransformMatrix = (transformationParameters, centerCoordinates)=>{
|
|
23
|
+
const { angle, scale, offsetX, offsetY } = transformationParameters;
|
|
24
|
+
const { x: centerX, y: centerY } = centerCoordinates;
|
|
25
|
+
const theta = angle * Math.PI / 180;
|
|
26
|
+
const a = Math.cos(theta) * scale;
|
|
27
|
+
const b = Math.sin(theta) * scale;
|
|
28
|
+
const c = -b;
|
|
29
|
+
const d = a;
|
|
30
|
+
const transformX = -centerX * a + centerY * b + centerX * scale;
|
|
31
|
+
const transformY = centerX * c - centerY * d + centerY * scale;
|
|
32
|
+
return {
|
|
33
|
+
a,
|
|
34
|
+
b,
|
|
35
|
+
c,
|
|
36
|
+
d,
|
|
37
|
+
x: transformX + offsetX,
|
|
38
|
+
y: transformY + offsetY
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
const applyTransformMatrix = (transformationParameters, centerCoordinates)=>(x, y)=>{
|
|
42
|
+
const { a, b, c, d, x: transformX, y: transformY } = TransformMatrix(transformationParameters, centerCoordinates);
|
|
43
|
+
return [
|
|
44
|
+
x * a + y * c + transformX,
|
|
45
|
+
x * b + y * d + transformY
|
|
46
|
+
];
|
|
47
|
+
};
|
|
48
|
+
export const getTransformedBoundingBox = (transformationParameters, boundingBox)=>{
|
|
49
|
+
const { top, left, width, height } = boundingBox;
|
|
50
|
+
const center = {
|
|
51
|
+
x: width / 2,
|
|
52
|
+
y: height / 2
|
|
53
|
+
};
|
|
54
|
+
const getTransformedCoordinates = applyTransformMatrix(transformationParameters, center);
|
|
55
|
+
const [x1, y1] = getTransformedCoordinates(left, top);
|
|
56
|
+
const [x2, y2] = getTransformedCoordinates(left + width, top);
|
|
57
|
+
const [x3, y3] = getTransformedCoordinates(left + width, top + height);
|
|
58
|
+
const [x4, y4] = getTransformedCoordinates(left, top + height);
|
|
59
|
+
return {
|
|
60
|
+
top: Math.min(y1, y2, y3, y4),
|
|
61
|
+
left: Math.min(x1, x2, x3, x4),
|
|
62
|
+
width: Math.max(x1, x2, x3, x4) - Math.min(x1, x2, x3, x4),
|
|
63
|
+
height: Math.max(y1, y2, y3, y4) - Math.min(y1, y2, y3, y4)
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
export const getScaleMultiplier = (delta, zoomSpeed = 1)=>{
|
|
67
|
+
const speed = ZOOM_SPEED_MULTIPLIER * zoomSpeed;
|
|
68
|
+
let scaleMultiplier = 1;
|
|
69
|
+
if (delta > 0) {
|
|
70
|
+
scaleMultiplier = 1 - speed;
|
|
71
|
+
} else if (delta < 0) {
|
|
72
|
+
scaleMultiplier = 1 + speed;
|
|
73
|
+
}
|
|
74
|
+
return scaleMultiplier;
|
|
75
|
+
};
|
|
76
|
+
export const boundCoordinates = (x, y, boundaryRatio, boundingBox, containerHeight, containerWidth, offsetX = 0, offsetY = 0)=>{
|
|
77
|
+
const { top, left, width, height } = boundingBox;
|
|
78
|
+
// check that computed are inside boundaries otherwise set to the bounding box limits
|
|
79
|
+
let boundX = left;
|
|
80
|
+
let boundY = top;
|
|
81
|
+
if (boundY < -boundaryRatio.vertical * height) {
|
|
82
|
+
boundY = -boundaryRatio.vertical * height;
|
|
83
|
+
} else if (boundY > containerHeight - (1 - boundaryRatio.vertical) * height) {
|
|
84
|
+
boundY = containerHeight - (1 - boundaryRatio.vertical) * height;
|
|
85
|
+
}
|
|
86
|
+
if (boundX < -boundaryRatio.horizontal * width) {
|
|
87
|
+
boundX = -boundaryRatio.horizontal * width;
|
|
88
|
+
} else if (boundX > containerWidth - (1 - boundaryRatio.horizontal) * width) {
|
|
89
|
+
boundX = containerWidth - (1 - boundaryRatio.horizontal) * width;
|
|
90
|
+
}
|
|
91
|
+
// return new bounds coordinates for the transform matrix
|
|
92
|
+
// not the computed x/y coordinates
|
|
93
|
+
return {
|
|
94
|
+
boundX: x - (left - boundX),
|
|
95
|
+
boundY: y - (top - boundY),
|
|
96
|
+
offsetX: offsetX - (left - boundX),
|
|
97
|
+
offsetY: offsetY - (top - boundY)
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
export const preventDefault = (e)=>{
|
|
101
|
+
e.preventDefault();
|
|
102
|
+
};
|
|
103
|
+
export const captureTextSelection = ()=>{
|
|
104
|
+
if (typeof window !== 'undefined') {
|
|
105
|
+
window.addEventListener('selectstart', preventDefault);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
export const releaseTextSelection = ()=>{
|
|
109
|
+
if (typeof window !== 'undefined') {
|
|
110
|
+
window.removeEventListener('selectstart', preventDefault);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../../../libs/shared/ui/jsx/src/lib/components/zoomable-panning-component/util.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2022 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\nexport type TransformationMatrix = {\n a: number,\n b: number,\n c: number,\n d: number,\n x: number,\n y: number,\n}\n\nexport type BoundingBox = {\n top: number,\n left: number,\n width: number,\n height: number,\n}\n\nexport type BoundaryRatio = {\n vertical: number,\n horizontal: number,\n}\n\nexport type Coordinates = {\n x: number,\n y: number,\n}\n\nexport type BoundCoordinates = {boundX: number, boundY: number, offsetX: number, offsetY: number}\n\nexport type TransformationParameters = {\n angle: number,\n scale: number,\n offsetX: number,\n offsetY: number,\n}\n\nexport const ZOOM_SPEED_MULTIPLIER = 0.065\n\n// Transform matrix use to rotate, zoom and pan\n// Can be written as T(centerX, centerY) * R(theta) * T(-centerX, -centerY) * S(scale, scale) + T(offsetX, offsetY)\n// ( a , c, x )\n// ( b , d, y )\n// ( 0 , 0, 1 )\nexport const TransformMatrix = (transformationParameters: TransformationParameters, centerCoordinates: Coordinates, ): TransformationMatrix => {\n const {angle, scale, offsetX, offsetY} = transformationParameters\n const {x: centerX, y: centerY} = centerCoordinates\n const theta = angle * Math.PI / 180\n const a = Math.cos(theta) * scale\n const b = Math.sin(theta) * scale\n const c = -b\n const d = a\n const transformX = -centerX * a + centerY * b + centerX * scale\n const transformY = centerX * c - centerY * d + centerY * scale\n return {a, b, c, d, x: transformX + offsetX, y: transformY + offsetY}\n}\n\nconst applyTransformMatrix = (\n transformationParameters: TransformationParameters,\n centerCoordinates: Coordinates,\n) => (x: number, y: number): [number, number] => {\n const {a, b, c, d, x: transformX, y: transformY} = TransformMatrix(transformationParameters, centerCoordinates)\n return [\n x * a + y * c + transformX,\n x * b + y * d + transformY,\n ]\n}\n\nexport const getTransformedBoundingBox = (\n transformationParameters: TransformationParameters,\n boundingBox: BoundingBox,\n): BoundingBox => {\n const {top, left, width, height} = boundingBox\n const center = {\n x: width / 2,\n y: height / 2,\n }\n\n const getTransformedCoordinates = applyTransformMatrix(transformationParameters, center)\n\n const [x1, y1] = getTransformedCoordinates(left, top)\n const [x2, y2] = getTransformedCoordinates(left + width, top)\n const [x3, y3] = getTransformedCoordinates(left + width, top + height)\n const [x4, y4] = getTransformedCoordinates(left, top + height)\n\n return {\n top: Math.min(y1, y2, y3, y4),\n left: Math.min(x1, x2, x3, x4),\n width: Math.max(x1, x2, x3, x4) - Math.min(x1, x2, x3, x4),\n height: Math.max(y1, y2, y3, y4) - Math.min(y1, y2, y3, y4),\n }\n}\n\nexport const getScaleMultiplier = (\n delta: number,\n zoomSpeed = 1,\n): number => {\n const speed = ZOOM_SPEED_MULTIPLIER * zoomSpeed\n let scaleMultiplier = 1\n if (delta > 0) { // zoom out\n scaleMultiplier = (1 - speed)\n }\n else if (delta < 0) { // zoom in\n scaleMultiplier = (1 + speed)\n }\n\n return scaleMultiplier\n}\n\nexport const boundCoordinates = (\n x: number,\n y: number,\n boundaryRatio: BoundaryRatio,\n boundingBox: BoundingBox,\n containerHeight: number,\n containerWidth: number,\n offsetX = 0,\n offsetY = 0,\n): BoundCoordinates => {\n\n const {top, left, width, height} = boundingBox\n // check that computed are inside boundaries otherwise set to the bounding box limits\n let boundX = left\n let boundY = top\n\n if (boundY < -boundaryRatio.vertical * height) {\n boundY = -boundaryRatio.vertical * height\n }\n else if (boundY > containerHeight - (1 - boundaryRatio.vertical) * height) {\n boundY = containerHeight - (1 - boundaryRatio.vertical) * height\n }\n\n if (boundX < -boundaryRatio.horizontal * width) {\n boundX = -boundaryRatio.horizontal * width\n }\n else if (boundX > containerWidth - (1 - boundaryRatio.horizontal) * width) {\n boundX = containerWidth - (1 - boundaryRatio.horizontal) * width\n }\n\n // return new bounds coordinates for the transform matrix\n // not the computed x/y coordinates\n return {\n boundX: x - (left - boundX),\n boundY: y - (top - boundY),\n offsetX: offsetX - (left - boundX),\n offsetY: offsetY - (top - boundY),\n }\n}\n\n\nexport const preventDefault = (e: Event) => {\n e.preventDefault()\n}\n\nexport const captureTextSelection = () => {\n if (typeof window !== 'undefined') {\n window.addEventListener('selectstart', preventDefault)\n }\n}\n\nexport const releaseTextSelection = () => {\n if (typeof window !== 'undefined') {\n window.removeEventListener('selectstart', preventDefault)\n }\n}\n"],"names":["ZOOM_SPEED_MULTIPLIER","TransformMatrix","transformationParameters","centerCoordinates","angle","scale","offsetX","offsetY","x","centerX","y","centerY","theta","Math","PI","a","cos","b","sin","c","d","transformX","transformY","applyTransformMatrix","getTransformedBoundingBox","boundingBox","top","left","width","height","center","getTransformedCoordinates","x1","y1","x2","y2","x3","y3","x4","y4","min","max","getScaleMultiplier","delta","zoomSpeed","speed","scaleMultiplier","boundCoordinates","boundaryRatio","containerHeight","containerWidth","boundX","boundY","vertical","horizontal","preventDefault","e","captureTextSelection","window","addEventListener","releaseTextSelection","removeEventListener"],"mappings":"AAAA;;;;;;;;;;;;;;;CAeC,GAsCD,OAAO,MAAMA,wBAAwB,MAAK;AAE1C,+CAA+C;AAC/C,mHAAmH;AACnH,eAAe;AACf,eAAe;AACf,eAAe;AACf,OAAO,MAAMC,kBAAkB,CAACC,0BAAoDC;IAClF,MAAM,EAACC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,OAAO,EAAC,GAAGL;IACzC,MAAM,EAACM,GAAGC,OAAO,EAAEC,GAAGC,OAAO,EAAC,GAAGR;IACjC,MAAMS,QAAQR,QAAQS,KAAKC,EAAE,GAAG;IAChC,MAAMC,IAAIF,KAAKG,GAAG,CAACJ,SAASP;IAC5B,MAAMY,IAAIJ,KAAKK,GAAG,CAACN,SAASP;IAC5B,MAAMc,IAAI,CAACF;IACX,MAAMG,IAAIL;IACV,MAAMM,aAAa,CAACZ,UAAUM,IAAIJ,UAAUM,IAAIR,UAAUJ;IAC1D,MAAMiB,aAAab,UAAUU,IAAIR,UAAUS,IAAIT,UAAUN;IACzD,OAAO;QAACU;QAAGE;QAAGE;QAAGC;QAAGZ,GAAGa,aAAaf;QAASI,GAAGY,aAAaf;IAAO;AACtE,EAAC;AAED,MAAMgB,uBAAuB,CAC3BrB,0BACAC,oBACG,CAACK,GAAWE;QACf,MAAM,EAACK,CAAC,EAAEE,CAAC,EAAEE,CAAC,EAAEC,CAAC,EAAEZ,GAAGa,UAAU,EAAEX,GAAGY,UAAU,EAAC,GAAGrB,gBAAgBC,0BAA0BC;QAC7F,OAAO;YACLK,IAAIO,IAAIL,IAAIS,IAAIE;YAChBb,IAAIS,IAAIP,IAAIU,IAAIE;SACjB;IACH;AAEA,OAAO,MAAME,4BAA4B,CACvCtB,0BACAuB;IAEA,MAAM,EAACC,GAAG,EAAEC,IAAI,EAAEC,KAAK,EAAEC,MAAM,EAAC,GAAGJ;IACnC,MAAMK,SAAS;QACbtB,GAAGoB,QAAQ;QACXlB,GAAGmB,SAAS;IACd;IAEA,MAAME,4BAA4BR,qBAAqBrB,0BAA0B4B;IAEjF,MAAM,CAACE,IAAIC,GAAG,GAAGF,0BAA0BJ,MAAMD;IACjD,MAAM,CAACQ,IAAIC,GAAG,GAAGJ,0BAA0BJ,OAAOC,OAAOF;IACzD,MAAM,CAACU,IAAIC,GAAG,GAAGN,0BAA0BJ,OAAOC,OAAOF,MAAMG;IAC/D,MAAM,CAACS,IAAIC,GAAG,GAAGR,0BAA0BJ,MAAMD,MAAMG;IAEvD,OAAO;QACLH,KAAKb,KAAK2B,GAAG,CAACP,IAAIE,IAAIE,IAAIE;QAC1BZ,MAAMd,KAAK2B,GAAG,CAACR,IAAIE,IAAIE,IAAIE;QAC3BV,OAAOf,KAAK4B,GAAG,CAACT,IAAIE,IAAIE,IAAIE,MAAMzB,KAAK2B,GAAG,CAACR,IAAIE,IAAIE,IAAIE;QACvDT,QAAQhB,KAAK4B,GAAG,CAACR,IAAIE,IAAIE,IAAIE,MAAM1B,KAAK2B,GAAG,CAACP,IAAIE,IAAIE,IAAIE;IAC1D;AACF,EAAC;AAED,OAAO,MAAMG,qBAAqB,CAChCC,OACAC,YAAY,CAAC;IAEb,MAAMC,QAAQ7C,wBAAwB4C;IACtC,IAAIE,kBAAkB;IACtB,IAAIH,QAAQ,GAAG;QACbG,kBAAmB,IAAID;IACzB,OACK,IAAIF,QAAQ,GAAG;QAClBG,kBAAmB,IAAID;IACzB;IAEA,OAAOC;AACT,EAAC;AAED,OAAO,MAAMC,mBAAmB,CAC9BvC,GACAE,GACAsC,eACAvB,aACAwB,iBACAC,gBACA5C,UAAU,CAAC,EACXC,UAAU,CAAC;IAGX,MAAM,EAACmB,GAAG,EAAEC,IAAI,EAAEC,KAAK,EAAEC,MAAM,EAAC,GAAGJ;IACnC,qFAAqF;IACrF,IAAI0B,SAASxB;IACb,IAAIyB,SAAS1B;IAEb,IAAI0B,SAAS,CAACJ,cAAcK,QAAQ,GAAGxB,QAAQ;QAC7CuB,SAAS,CAACJ,cAAcK,QAAQ,GAAGxB;IACrC,OACK,IAAIuB,SAASH,kBAAkB,AAAC,CAAA,IAAID,cAAcK,QAAQ,AAAD,IAAKxB,QAAQ;QACzEuB,SAASH,kBAAkB,AAAC,CAAA,IAAID,cAAcK,QAAQ,AAAD,IAAKxB;IAC5D;IAEA,IAAIsB,SAAS,CAACH,cAAcM,UAAU,GAAG1B,OAAO;QAC9CuB,SAAS,CAACH,cAAcM,UAAU,GAAG1B;IACvC,OACK,IAAIuB,SAASD,iBAAiB,AAAC,CAAA,IAAIF,cAAcM,UAAU,AAAD,IAAK1B,OAAO;QACzEuB,SAASD,iBAAiB,AAAC,CAAA,IAAIF,cAAcM,UAAU,AAAD,IAAK1B;IAC7D;IAEA,yDAAyD;IACzD,mCAAmC;IACnC,OAAO;QACLuB,QAAQ3C,IAAKmB,CAAAA,OAAOwB,MAAK;QACzBC,QAAQ1C,IAAKgB,CAAAA,MAAM0B,MAAK;QACxB9C,SAASA,UAAWqB,CAAAA,OAAOwB,MAAK;QAChC5C,SAASA,UAAWmB,CAAAA,MAAM0B,MAAK;IACjC;AACF,EAAC;AAGD,OAAO,MAAMG,iBAAiB,CAACC;IAC7BA,EAAED,cAAc;AAClB,EAAC;AAED,OAAO,MAAME,uBAAuB;IAClC,IAAI,OAAOC,WAAW,aAAa;QACjCA,OAAOC,gBAAgB,CAAC,eAAeJ;IACzC;AACF,EAAC;AAED,OAAO,MAAMK,uBAAuB;IAClC,IAAI,OAAOF,WAAW,aAAa;QACjCA,OAAOG,mBAAmB,CAAC,eAAeN;IAC5C;AACF,EAAC"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2021 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { Component, PointerEvent, MouseEvent, KeyboardEvent, TouchEvent, WheelEvent, HTMLAttributes, PropsWithRef } from 'react';
|
|
18
|
+
import { BoundCoordinates, Coordinates, TransformationMatrix, TransformationParameters } from './util';
|
|
19
|
+
type OnStateChangeData = {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
scale: number;
|
|
23
|
+
angle: number;
|
|
24
|
+
};
|
|
25
|
+
export interface ZoomablePanningComponentProps extends PropsWithRef<HTMLAttributes<HTMLDivElement>> {
|
|
26
|
+
zoomSpeed: number;
|
|
27
|
+
doubleZoomSpeed: number;
|
|
28
|
+
disabled?: boolean;
|
|
29
|
+
autoCenter?: boolean;
|
|
30
|
+
autoCenterZoomLevel?: number;
|
|
31
|
+
disableKeyInteraction?: boolean;
|
|
32
|
+
disableDoubleClickZoom?: boolean;
|
|
33
|
+
disableScrollZoom?: boolean;
|
|
34
|
+
realPinch?: boolean;
|
|
35
|
+
keyMapping?: Record<string, {
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
z: number;
|
|
39
|
+
}>;
|
|
40
|
+
minZoom: number;
|
|
41
|
+
maxZoom: number;
|
|
42
|
+
preventPan: (event: PointerEvent<HTMLDivElement> | MouseEvent, x: number, y: number) => boolean;
|
|
43
|
+
noStateUpdate: boolean;
|
|
44
|
+
boundaryRatioVertical: number;
|
|
45
|
+
boundaryRatioHorizontal: number;
|
|
46
|
+
enableBoundingBox?: boolean;
|
|
47
|
+
onPanStart?: (event: MouseEvent<any> | TouchEvent<any>) => void;
|
|
48
|
+
onPan?: (event: MouseEvent<any> | TouchEvent<any>) => void;
|
|
49
|
+
onPanEnd?: (event: MouseEvent<any> | TouchEvent<any>) => void;
|
|
50
|
+
onStateChange?: (data: OnStateChangeData) => void;
|
|
51
|
+
}
|
|
52
|
+
type State = {
|
|
53
|
+
x: number;
|
|
54
|
+
y: number;
|
|
55
|
+
scale: number;
|
|
56
|
+
angle: number;
|
|
57
|
+
};
|
|
58
|
+
export declare class ZoomablePanningComponent extends Component<ZoomablePanningComponentProps, State> {
|
|
59
|
+
static defaultProps: {
|
|
60
|
+
zoomSpeed: number;
|
|
61
|
+
doubleZoomSpeed: number;
|
|
62
|
+
disabled: boolean;
|
|
63
|
+
minZoom: number;
|
|
64
|
+
maxZoom: number;
|
|
65
|
+
noStateUpdate: boolean;
|
|
66
|
+
boundaryRatioVertical: number;
|
|
67
|
+
boundaryRatioHorizontal: number;
|
|
68
|
+
disableDoubleClickZoom: boolean;
|
|
69
|
+
disableScrollZoom: boolean;
|
|
70
|
+
preventPan: () => boolean;
|
|
71
|
+
};
|
|
72
|
+
container: import("react").RefObject<HTMLDivElement>;
|
|
73
|
+
dragContainer: import("react").RefObject<HTMLDivElement>;
|
|
74
|
+
mousePos: {
|
|
75
|
+
x: number;
|
|
76
|
+
y: number;
|
|
77
|
+
};
|
|
78
|
+
panning: boolean;
|
|
79
|
+
touchInProgress: boolean;
|
|
80
|
+
panStartTriggered: boolean;
|
|
81
|
+
pinchZoomLength: number;
|
|
82
|
+
prevPanPosition: {
|
|
83
|
+
x: number;
|
|
84
|
+
y: number;
|
|
85
|
+
};
|
|
86
|
+
frameAnimation: number;
|
|
87
|
+
intermediateFrameAnimation: number;
|
|
88
|
+
transformMatrixString: string;
|
|
89
|
+
intermediateTransformMatrixString: string;
|
|
90
|
+
state: State;
|
|
91
|
+
componentDidMount(): void;
|
|
92
|
+
componentDidUpdate(prevProps: ZoomablePanningComponentProps, prevState: State): void;
|
|
93
|
+
componentWillUnmount(): void;
|
|
94
|
+
onDoubleClick: (e: MouseEvent<any>) => void;
|
|
95
|
+
onMouseDown: (e: MouseEvent<any>) => void;
|
|
96
|
+
onMouseMove: (e: MouseEvent<any>) => void;
|
|
97
|
+
onMouseUp: (e: MouseEvent<any>) => void;
|
|
98
|
+
onWheel: (e: WheelEvent<any>) => void;
|
|
99
|
+
onKeyDown: (e: KeyboardEvent<any>) => void;
|
|
100
|
+
onKeyUp: (e: KeyboardEvent<any>) => void;
|
|
101
|
+
onTouchStart: (e: TouchEvent<any>) => void;
|
|
102
|
+
onToucheMove: (e: TouchEvent<any>) => void;
|
|
103
|
+
onTouchEnd: (e: TouchEvent<any>) => void;
|
|
104
|
+
setMouseListeners: () => void;
|
|
105
|
+
cleanMouseListeners: () => void;
|
|
106
|
+
setTouchListeners: () => void;
|
|
107
|
+
cleanTouchListeners: () => void;
|
|
108
|
+
triggerOnPanStart: (e: MouseEvent<any> | TouchEvent<any>) => void;
|
|
109
|
+
triggerOnPan: (e: MouseEvent<any> | TouchEvent<any>) => void;
|
|
110
|
+
triggerOnPanEnd: (e: MouseEvent<any> | TouchEvent<any>) => void;
|
|
111
|
+
getPinchZoomLength: (finger1: Touch, finger2: Touch) => number;
|
|
112
|
+
getContainer: () => HTMLDivElement;
|
|
113
|
+
getDragContainer: () => HTMLDivElement;
|
|
114
|
+
autoCenter: (zoomLevel?: number, animate?: boolean) => void;
|
|
115
|
+
moveByRatio: (x: number, y: number, moveSpeedRatio?: number) => void;
|
|
116
|
+
moveBy: (dx: number, dy: number, noStateUpdate?: boolean) => void;
|
|
117
|
+
rotate: (value: number | ((prevAngle: number) => number)) => void;
|
|
118
|
+
zoomAbs: (x: number, y: number, zoomLevel: number) => void;
|
|
119
|
+
zoomTo: (x: number, y: number, ratio: number) => void;
|
|
120
|
+
centeredZoom: (delta: number, zoomSpeed?: number) => void;
|
|
121
|
+
zoomIn: (zoomSpeed?: number) => void;
|
|
122
|
+
zoomOut: (zoomSpeed?: number) => void;
|
|
123
|
+
reset: () => void;
|
|
124
|
+
getContainerBoundingRect: () => ClientRect;
|
|
125
|
+
getOffset: (e: MouseEvent<any> | Touch) => Coordinates;
|
|
126
|
+
getTransformMatrix: (x: number, y: number, scale: number, angle: number) => TransformationMatrix;
|
|
127
|
+
applyTransform: () => void;
|
|
128
|
+
applyIntermediateTransform: () => void;
|
|
129
|
+
getBoundCoordinates: (coordinates: Coordinates, transformationParameters: TransformationParameters) => BoundCoordinates;
|
|
130
|
+
render(): import("react").JSX.Element;
|
|
131
|
+
}
|
|
132
|
+
export default ZoomablePanningComponent;
|