tyrell-react 1.0.0-RC10
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 +21 -0
- package/README.md +410 -0
- package/dist/components/TyButton.d.ts +52 -0
- package/dist/components/TyButton.d.ts.map +1 -0
- package/dist/components/TyButton.js +76 -0
- package/dist/components/TyButton.js.map +1 -0
- package/dist/components/TyCalendar.d.ts +63 -0
- package/dist/components/TyCalendar.d.ts.map +1 -0
- package/dist/components/TyCalendar.js +128 -0
- package/dist/components/TyCalendar.js.map +1 -0
- package/dist/components/TyCalendarMonth.d.ts +32 -0
- package/dist/components/TyCalendarMonth.d.ts.map +1 -0
- package/dist/components/TyCalendarMonth.js +54 -0
- package/dist/components/TyCalendarMonth.js.map +1 -0
- package/dist/components/TyCalendarNavigation.d.ts +21 -0
- package/dist/components/TyCalendarNavigation.d.ts.map +1 -0
- package/dist/components/TyCalendarNavigation.js +50 -0
- package/dist/components/TyCalendarNavigation.js.map +1 -0
- package/dist/components/TyCheckbox.d.ts +39 -0
- package/dist/components/TyCheckbox.d.ts.map +1 -0
- package/dist/components/TyCheckbox.js +76 -0
- package/dist/components/TyCheckbox.js.map +1 -0
- package/dist/components/TyCopy.d.ts +21 -0
- package/dist/components/TyCopy.d.ts.map +1 -0
- package/dist/components/TyCopy.js +46 -0
- package/dist/components/TyCopy.js.map +1 -0
- package/dist/components/TyDatePicker.d.ts +45 -0
- package/dist/components/TyDatePicker.d.ts.map +1 -0
- package/dist/components/TyDatePicker.js +122 -0
- package/dist/components/TyDatePicker.js.map +1 -0
- package/dist/components/TyDropdown.d.ts +62 -0
- package/dist/components/TyDropdown.d.ts.map +1 -0
- package/dist/components/TyDropdown.js +124 -0
- package/dist/components/TyDropdown.js.map +1 -0
- package/dist/components/TyFileUpload.d.ts +31 -0
- package/dist/components/TyFileUpload.d.ts.map +1 -0
- package/dist/components/TyFileUpload.js +56 -0
- package/dist/components/TyFileUpload.js.map +1 -0
- package/dist/components/TyIcon.d.ts +17 -0
- package/dist/components/TyIcon.d.ts.map +1 -0
- package/dist/components/TyIcon.js +42 -0
- package/dist/components/TyIcon.js.map +1 -0
- package/dist/components/TyInput.d.ts +65 -0
- package/dist/components/TyInput.d.ts.map +1 -0
- package/dist/components/TyInput.js +134 -0
- package/dist/components/TyInput.js.map +1 -0
- package/dist/components/TyModal.d.ts +48 -0
- package/dist/components/TyModal.d.ts.map +1 -0
- package/dist/components/TyModal.js +120 -0
- package/dist/components/TyModal.js.map +1 -0
- package/dist/components/TyMultiselect.d.ts +57 -0
- package/dist/components/TyMultiselect.d.ts.map +1 -0
- package/dist/components/TyMultiselect.js +111 -0
- package/dist/components/TyMultiselect.js.map +1 -0
- package/dist/components/TyOption.d.ts +10 -0
- package/dist/components/TyOption.d.ts.map +1 -0
- package/dist/components/TyOption.js +29 -0
- package/dist/components/TyOption.js.map +1 -0
- package/dist/components/TyPopup.d.ts +24 -0
- package/dist/components/TyPopup.d.ts.map +1 -0
- package/dist/components/TyPopup.js +70 -0
- package/dist/components/TyPopup.js.map +1 -0
- package/dist/components/TyRadio.d.ts +20 -0
- package/dist/components/TyRadio.d.ts.map +1 -0
- package/dist/components/TyRadio.js +35 -0
- package/dist/components/TyRadio.js.map +1 -0
- package/dist/components/TyRadioGroup.d.ts +40 -0
- package/dist/components/TyRadioGroup.d.ts.map +1 -0
- package/dist/components/TyRadioGroup.js +61 -0
- package/dist/components/TyRadioGroup.js.map +1 -0
- package/dist/components/TyResizeObserver.d.ts +11 -0
- package/dist/components/TyResizeObserver.d.ts.map +1 -0
- package/dist/components/TyResizeObserver.js +28 -0
- package/dist/components/TyResizeObserver.js.map +1 -0
- package/dist/components/TyScrollContainer.d.ts +25 -0
- package/dist/components/TyScrollContainer.d.ts.map +1 -0
- package/dist/components/TyScrollContainer.js +61 -0
- package/dist/components/TyScrollContainer.js.map +1 -0
- package/dist/components/TyStep.d.ts +17 -0
- package/dist/components/TyStep.d.ts.map +1 -0
- package/dist/components/TyStep.js +35 -0
- package/dist/components/TyStep.js.map +1 -0
- package/dist/components/TySwitch.d.ts +35 -0
- package/dist/components/TySwitch.d.ts.map +1 -0
- package/dist/components/TySwitch.js +59 -0
- package/dist/components/TySwitch.js.map +1 -0
- package/dist/components/TyTab.d.ts +13 -0
- package/dist/components/TyTab.d.ts.map +1 -0
- package/dist/components/TyTab.js +34 -0
- package/dist/components/TyTab.js.map +1 -0
- package/dist/components/TyTabs.d.ts +23 -0
- package/dist/components/TyTabs.d.ts.map +1 -0
- package/dist/components/TyTabs.js +48 -0
- package/dist/components/TyTabs.js.map +1 -0
- package/dist/components/TyTag.d.ts +22 -0
- package/dist/components/TyTag.d.ts.map +1 -0
- package/dist/components/TyTag.js +51 -0
- package/dist/components/TyTag.js.map +1 -0
- package/dist/components/TyTextarea.d.ts +37 -0
- package/dist/components/TyTextarea.d.ts.map +1 -0
- package/dist/components/TyTextarea.js +116 -0
- package/dist/components/TyTextarea.js.map +1 -0
- package/dist/components/TyTooltip.d.ts +17 -0
- package/dist/components/TyTooltip.d.ts.map +1 -0
- package/dist/components/TyTooltip.js +41 -0
- package/dist/components/TyTooltip.js.map +1 -0
- package/dist/components/TyWizard.d.ts +26 -0
- package/dist/components/TyWizard.d.ts.map +1 -0
- package/dist/components/TyWizard.js +50 -0
- package/dist/components/TyWizard.js.map +1 -0
- package/dist/components/index.d.ts +112 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +127 -0
- package/dist/components/index.js.map +1 -0
- package/dist/utils/react-version.d.ts +2 -0
- package/dist/utils/react-version.d.ts.map +1 -0
- package/dist/utils/react-version.js +8 -0
- package/dist/utils/react-version.js.map +1 -0
- package/dist/utils/use-boolean-prop.d.ts +36 -0
- package/dist/utils/use-boolean-prop.d.ts.map +1 -0
- package/dist/utils/use-boolean-prop.js +62 -0
- package/dist/utils/use-boolean-prop.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +47 -0
- package/src/components/EventConventionTest.tsx +155 -0
- package/src/components/TyButton.tsx +157 -0
- package/src/components/TyCalendar.tsx +247 -0
- package/src/components/TyCalendarMonth.tsx +108 -0
- package/src/components/TyCalendarNavigation.tsx +91 -0
- package/src/components/TyCheckbox.tsx +147 -0
- package/src/components/TyCopy.tsx +83 -0
- package/src/components/TyDatePicker.tsx +215 -0
- package/src/components/TyDropdown.tsx +240 -0
- package/src/components/TyFileUpload.tsx +108 -0
- package/src/components/TyIcon.tsx +71 -0
- package/src/components/TyInput.tsx +239 -0
- package/src/components/TyModal.tsx +195 -0
- package/src/components/TyMultiselect.tsx +208 -0
- package/src/components/TyOption.tsx +47 -0
- package/src/components/TyPopup.tsx +116 -0
- package/src/components/TyRadio.tsx +61 -0
- package/src/components/TyRadioGroup.tsx +125 -0
- package/src/components/TyResizeObserver.tsx +54 -0
- package/src/components/TyScrollContainer.tsx +102 -0
- package/src/components/TyStep.tsx +71 -0
- package/src/components/TySwitch.tsx +114 -0
- package/src/components/TyTab.tsx +65 -0
- package/src/components/TyTabs.tsx +93 -0
- package/src/components/TyTag.tsx +86 -0
- package/src/components/TyTextarea.tsx +181 -0
- package/src/components/TyTooltip.tsx +83 -0
- package/src/components/TyWizard.tsx +99 -0
- package/src/components/index.ts +279 -0
- package/src/utils/react-version.ts +8 -0
- package/src/utils/use-boolean-prop.ts +62 -0
- package/src/version.ts +6 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { needsPropertyBridge } from '../utils/react-version';
|
|
3
|
+
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
|
+
// One-time global warning flags so we don't spam the console.
|
|
5
|
+
let _warnedOnInputProp = false;
|
|
6
|
+
// React wrapper for ty-input web component
|
|
7
|
+
export const TyInput = React.forwardRef(({ onChange, onChangeCommit, onFocus, onBlur, disabled, required, name, checked, debounce, ...props }, ref) => {
|
|
8
|
+
const elementRef = useRef(null);
|
|
9
|
+
// Catch the most common mistake: passing `onInput` (React's prop) instead
|
|
10
|
+
// of `onChange` (our wrapper's prop). React's synthetic-event system
|
|
11
|
+
// strips event.detail, so the user's handler crashes on `e.detail.value`.
|
|
12
|
+
// Forward to onChange and log a one-shot warning.
|
|
13
|
+
const onInputProp = props.onInput;
|
|
14
|
+
if (onInputProp && !onChange) {
|
|
15
|
+
if (!_warnedOnInputProp) {
|
|
16
|
+
_warnedOnInputProp = true;
|
|
17
|
+
console.warn('[tyrell-react] <TyInput> received `onInput`. ' +
|
|
18
|
+
'React strips event.detail; use `onChange` instead — it receives the raw CustomEvent. ' +
|
|
19
|
+
'Forwarding for now, but please rename the prop.');
|
|
20
|
+
}
|
|
21
|
+
onChange = onInputProp;
|
|
22
|
+
}
|
|
23
|
+
// Either way, drop onInput from spread so React doesn't double-wire it.
|
|
24
|
+
delete props.onInput;
|
|
25
|
+
// Map onChange to input event (React convention)
|
|
26
|
+
const handleInput = useCallback((event) => {
|
|
27
|
+
if (onChange) {
|
|
28
|
+
onChange(event);
|
|
29
|
+
}
|
|
30
|
+
}, [onChange]);
|
|
31
|
+
// Map onChangeCommit to change event (blur behavior)
|
|
32
|
+
const handleChangeCommit = useCallback((event) => {
|
|
33
|
+
if (onChangeCommit) {
|
|
34
|
+
onChangeCommit(event);
|
|
35
|
+
}
|
|
36
|
+
}, [onChangeCommit]);
|
|
37
|
+
const handleFocus = useCallback((event) => {
|
|
38
|
+
if (onFocus) {
|
|
39
|
+
onFocus(event);
|
|
40
|
+
}
|
|
41
|
+
}, [onFocus]);
|
|
42
|
+
const handleBlur = useCallback((event) => {
|
|
43
|
+
if (onBlur) {
|
|
44
|
+
onBlur(event);
|
|
45
|
+
}
|
|
46
|
+
}, [onBlur]);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
const element = elementRef.current;
|
|
49
|
+
if (!element)
|
|
50
|
+
return;
|
|
51
|
+
// Listen for custom input/change events from ty-input
|
|
52
|
+
// Map onChange → input event (React convention)
|
|
53
|
+
if (onChange) {
|
|
54
|
+
element.addEventListener('input', handleInput);
|
|
55
|
+
}
|
|
56
|
+
// Map onChangeCommit → change event (blur behavior)
|
|
57
|
+
if (onChangeCommit) {
|
|
58
|
+
element.addEventListener('change', handleChangeCommit);
|
|
59
|
+
}
|
|
60
|
+
// Listen for standard focus/blur events
|
|
61
|
+
if (onFocus) {
|
|
62
|
+
element.addEventListener('focus', handleFocus);
|
|
63
|
+
}
|
|
64
|
+
if (onBlur) {
|
|
65
|
+
element.addEventListener('blur', handleBlur);
|
|
66
|
+
}
|
|
67
|
+
return () => {
|
|
68
|
+
if (onChange) {
|
|
69
|
+
element.removeEventListener('input', handleInput);
|
|
70
|
+
}
|
|
71
|
+
if (onChangeCommit) {
|
|
72
|
+
element.removeEventListener('change', handleChangeCommit);
|
|
73
|
+
}
|
|
74
|
+
if (onFocus) {
|
|
75
|
+
element.removeEventListener('focus', handleFocus);
|
|
76
|
+
}
|
|
77
|
+
if (onBlur) {
|
|
78
|
+
element.removeEventListener('blur', handleBlur);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}, [handleInput, handleChangeCommit, handleFocus, handleBlur, onChange, onChangeCommit, onFocus, onBlur]);
|
|
82
|
+
// Handle ref forwarding
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (ref && elementRef.current) {
|
|
85
|
+
if (typeof ref === 'function') {
|
|
86
|
+
ref(elementRef.current);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
ref.current = elementRef.current;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}, [ref]);
|
|
93
|
+
// Imperatively sync `value` to the underlying element's property whenever
|
|
94
|
+
// the React prop changes. React 18's prop-to-property bridging for custom
|
|
95
|
+
// elements is unreliable for empty strings, so we set the property directly
|
|
96
|
+
// to guarantee resets (`value=""`) clear the visible content. React 19+
|
|
97
|
+
// handles this natively, so the effect short-circuits there.
|
|
98
|
+
useEffect(() => {
|
|
99
|
+
if (!needsPropertyBridge)
|
|
100
|
+
return;
|
|
101
|
+
const element = elementRef.current;
|
|
102
|
+
if (!element)
|
|
103
|
+
return;
|
|
104
|
+
const next = props.value ?? '';
|
|
105
|
+
if (element.value !== next) {
|
|
106
|
+
element.value = next;
|
|
107
|
+
}
|
|
108
|
+
}, [props.value]);
|
|
109
|
+
// Imperative property sync for boolean props (see use-boolean-prop.ts).
|
|
110
|
+
const isDisabled = useBooleanProperty(elementRef, 'disabled', disabled);
|
|
111
|
+
const isRequired = useBooleanProperty(elementRef, 'required', required);
|
|
112
|
+
const isChecked = useBooleanProperty(elementRef, 'checked', checked);
|
|
113
|
+
// Convert React props to web component attributes
|
|
114
|
+
const webComponentProps = {
|
|
115
|
+
...props,
|
|
116
|
+
ref: elementRef,
|
|
117
|
+
};
|
|
118
|
+
// Add conditional attributes
|
|
119
|
+
if (isDisabled)
|
|
120
|
+
webComponentProps.disabled = '';
|
|
121
|
+
if (isRequired)
|
|
122
|
+
webComponentProps.required = '';
|
|
123
|
+
if (isChecked)
|
|
124
|
+
webComponentProps.checked = '';
|
|
125
|
+
// Add string attributes
|
|
126
|
+
if (name)
|
|
127
|
+
webComponentProps.name = name;
|
|
128
|
+
// Add debounce attribute
|
|
129
|
+
if (debounce !== undefined)
|
|
130
|
+
webComponentProps.debounce = debounce;
|
|
131
|
+
return React.createElement('ty-input', webComponentProps);
|
|
132
|
+
});
|
|
133
|
+
TyInput.displayName = 'TyInput';
|
|
134
|
+
//# sourceMappingURL=TyInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TyInput.js","sourceRoot":"","sources":["../../src/components/TyInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface TyModalEventDetail {
|
|
3
|
+
reason?: 'programmatic' | 'native' | 'backdrop' | 'escape' | 'close-button';
|
|
4
|
+
returnValue?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Detail for the `beforeclose` event — fired *before* the modal closes,
|
|
8
|
+
* cancellable. Call `event.preventDefault()` to abort the close and render
|
|
9
|
+
* your own confirm UI; once the user consents, call `ref.current?.hide({ force: true })`
|
|
10
|
+
* to actually close (or just toggle your controlled `open` state to `false`).
|
|
11
|
+
*/
|
|
12
|
+
export interface TyModalBeforeCloseDetail {
|
|
13
|
+
reason: 'programmatic' | 'backdrop' | 'escape' | 'close-button' | 'native';
|
|
14
|
+
}
|
|
15
|
+
export interface TyModalProps extends React.HTMLAttributes<HTMLElement> {
|
|
16
|
+
/** Controls modal visibility */
|
|
17
|
+
open?: boolean;
|
|
18
|
+
/** Show backdrop behind modal (default: true) */
|
|
19
|
+
backdrop?: boolean;
|
|
20
|
+
/** Allow closing modal by clicking backdrop (default: true) */
|
|
21
|
+
closeOnOutsideClick?: boolean;
|
|
22
|
+
/** Allow closing modal with Escape key (default: true) */
|
|
23
|
+
closeOnEscape?: boolean;
|
|
24
|
+
/** React event handlers */
|
|
25
|
+
onOpen?: (event: CustomEvent<TyModalEventDetail>) => void;
|
|
26
|
+
onClose?: (event: CustomEvent<TyModalEventDetail>) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Fires before the modal closes. Cancellable — call `event.preventDefault()`
|
|
29
|
+
* to abort. Use this for "discard changes?" flows with custom UI.
|
|
30
|
+
*/
|
|
31
|
+
onBeforeClose?: (event: CustomEvent<TyModalBeforeCloseDetail>) => void;
|
|
32
|
+
/** Modal content */
|
|
33
|
+
children?: React.ReactNode;
|
|
34
|
+
}
|
|
35
|
+
export interface TyModalRef {
|
|
36
|
+
show: () => void;
|
|
37
|
+
/**
|
|
38
|
+
* Close the modal. Without `force`, fires `beforeclose` first (consumer can
|
|
39
|
+
* cancel). With `force: true`, bypasses `beforeclose` — call this once your
|
|
40
|
+
* custom confirm UI has captured user consent.
|
|
41
|
+
*/
|
|
42
|
+
hide: (opts?: {
|
|
43
|
+
force?: boolean;
|
|
44
|
+
}) => void;
|
|
45
|
+
element: HTMLElement | null;
|
|
46
|
+
}
|
|
47
|
+
export declare const TyModal: React.ForwardRefExoticComponent<TyModalProps & React.RefAttributes<TyModalRef>>;
|
|
48
|
+
//# sourceMappingURL=TyModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TyModal.d.ts","sourceRoot":"","sources":["../../src/components/TyModal.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAKtE,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,cAAc,CAAC;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,cAAc,GAAG,UAAU,GAAG,QAAQ,GAAG,cAAc,GAAG,QAAQ,CAAC;CAC5E;AAGD,MAAM,WAAW,YAAa,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACrE,gCAAgC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B,0DAA0D;IAC1D,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;IAC1D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;IAC3D;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,wBAAwB,CAAC,KAAK,IAAI,CAAC;IAEvE,oBAAoB;IACpB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAGD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB;;;;OAIG;IACH,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3C,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;CAC7B;AAGD,eAAO,MAAM,OAAO,iFAoInB,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useImperativeHandle } from 'react';
|
|
2
|
+
import { useBooleanProperty, coerceBool } from '../utils/use-boolean-prop';
|
|
3
|
+
import { needsPropertyBridge } from '../utils/react-version';
|
|
4
|
+
// React wrapper for ty-modal web component
|
|
5
|
+
export const TyModal = React.forwardRef(({ open, backdrop, closeOnOutsideClick, closeOnEscape, onOpen, onClose, onBeforeClose, children, ...props }, ref) => {
|
|
6
|
+
const elementRef = useRef(null);
|
|
7
|
+
// Expose imperative methods through ref
|
|
8
|
+
useImperativeHandle(ref, () => ({
|
|
9
|
+
show: () => {
|
|
10
|
+
if (elementRef.current && typeof elementRef.current.show === 'function') {
|
|
11
|
+
elementRef.current.show();
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
hide: (opts) => {
|
|
15
|
+
if (elementRef.current && typeof elementRef.current.hide === 'function') {
|
|
16
|
+
elementRef.current.hide(opts);
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
element: elementRef.current,
|
|
20
|
+
}), []);
|
|
21
|
+
// Handle modal events.
|
|
22
|
+
//
|
|
23
|
+
// ty-dropdown, ty-multiselect, ty-date-picker etc. dispatch their own
|
|
24
|
+
// `open`/`close` custom events with `bubbles: true, composed: true` when
|
|
25
|
+
// their internal popups toggle. Those events bubble up through the
|
|
26
|
+
// modal's slotted content and land on the ty-modal host — same event
|
|
27
|
+
// type, same listener. Without the `event.target === element` guard, an
|
|
28
|
+
// `onClose={() => setIsOpen(false)}` callback would fire every time the
|
|
29
|
+
// user closes a dropdown inside the modal, and the React state flip
|
|
30
|
+
// would close the modal. Core's modal.ts already applies the same guard
|
|
31
|
+
// on its internal <dialog>.onclose; this is the React-layer mirror.
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const element = elementRef.current;
|
|
34
|
+
if (!element)
|
|
35
|
+
return;
|
|
36
|
+
const handleOpen = (event) => {
|
|
37
|
+
if (event.target !== element)
|
|
38
|
+
return;
|
|
39
|
+
if (onOpen)
|
|
40
|
+
onOpen(event);
|
|
41
|
+
};
|
|
42
|
+
const handleClose = (event) => {
|
|
43
|
+
if (event.target !== element)
|
|
44
|
+
return;
|
|
45
|
+
if (onClose)
|
|
46
|
+
onClose(event);
|
|
47
|
+
};
|
|
48
|
+
const handleBeforeClose = (event) => {
|
|
49
|
+
if (event.target !== element)
|
|
50
|
+
return;
|
|
51
|
+
if (onBeforeClose)
|
|
52
|
+
onBeforeClose(event);
|
|
53
|
+
};
|
|
54
|
+
// Listen for custom modal events
|
|
55
|
+
if (onOpen) {
|
|
56
|
+
element.addEventListener('open', handleOpen);
|
|
57
|
+
}
|
|
58
|
+
if (onClose) {
|
|
59
|
+
element.addEventListener('close', handleClose);
|
|
60
|
+
}
|
|
61
|
+
if (onBeforeClose) {
|
|
62
|
+
element.addEventListener('beforeclose', handleBeforeClose);
|
|
63
|
+
}
|
|
64
|
+
return () => {
|
|
65
|
+
if (onOpen) {
|
|
66
|
+
element.removeEventListener('open', handleOpen);
|
|
67
|
+
}
|
|
68
|
+
if (onClose) {
|
|
69
|
+
element.removeEventListener('close', handleClose);
|
|
70
|
+
}
|
|
71
|
+
if (onBeforeClose) {
|
|
72
|
+
element.removeEventListener('beforeclose', handleBeforeClose);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}, [onOpen, onClose, onBeforeClose]);
|
|
76
|
+
// Imperative property sync for boolean props (see use-boolean-prop.ts).
|
|
77
|
+
// Without this, flipping `open` from `true` to `false` on React 18 leaves
|
|
78
|
+
// the `open` attribute on the element and the modal stays open.
|
|
79
|
+
const isOpen = useBooleanProperty(elementRef, 'open', open);
|
|
80
|
+
// For default-true booleans (backdrop, closeOn*), only the explicit-false
|
|
81
|
+
// case is interesting — bridge it imperatively too so it propagates.
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (!needsPropertyBridge)
|
|
84
|
+
return;
|
|
85
|
+
const el = elementRef.current;
|
|
86
|
+
if (!el)
|
|
87
|
+
return;
|
|
88
|
+
const setIf = (prop, raw) => {
|
|
89
|
+
if (raw === undefined)
|
|
90
|
+
return;
|
|
91
|
+
const next = coerceBool(raw);
|
|
92
|
+
if (Boolean(el[prop]) !== next)
|
|
93
|
+
el[prop] = next;
|
|
94
|
+
};
|
|
95
|
+
setIf('backdrop', backdrop);
|
|
96
|
+
setIf('closeOnOutsideClick', closeOnOutsideClick);
|
|
97
|
+
setIf('closeOnEscape', closeOnEscape);
|
|
98
|
+
}, [backdrop, closeOnOutsideClick, closeOnEscape]);
|
|
99
|
+
// Convert React props to web component attributes
|
|
100
|
+
const webComponentProps = {
|
|
101
|
+
...props,
|
|
102
|
+
ref: elementRef,
|
|
103
|
+
};
|
|
104
|
+
if (isOpen)
|
|
105
|
+
webComponentProps.open = '';
|
|
106
|
+
// Default-true booleans use "false" string on the attribute side; the
|
|
107
|
+
// core's parseBoolAttr handles it correctly.
|
|
108
|
+
if (backdrop !== undefined && !coerceBool(backdrop)) {
|
|
109
|
+
webComponentProps.backdrop = 'false';
|
|
110
|
+
}
|
|
111
|
+
if (closeOnOutsideClick !== undefined && !coerceBool(closeOnOutsideClick)) {
|
|
112
|
+
webComponentProps['close-on-outside-click'] = 'false';
|
|
113
|
+
}
|
|
114
|
+
if (closeOnEscape !== undefined && !coerceBool(closeOnEscape)) {
|
|
115
|
+
webComponentProps['close-on-escape'] = 'false';
|
|
116
|
+
}
|
|
117
|
+
return React.createElement('ty-modal', webComponentProps, children);
|
|
118
|
+
});
|
|
119
|
+
TyModal.displayName = 'TyModal';
|
|
120
|
+
//# sourceMappingURL=TyModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TyModal.js","sourceRoot":"","sources":["../../src/components/TyModal.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface TyMultiselectEventDetail {
|
|
3
|
+
/** Array of currently selected values */
|
|
4
|
+
values: string[];
|
|
5
|
+
/** Action that triggered the change: "add" | "remove" */
|
|
6
|
+
action: 'add' | 'remove';
|
|
7
|
+
/** The specific item that was added or removed */
|
|
8
|
+
item: string;
|
|
9
|
+
}
|
|
10
|
+
export interface TyMultiselectProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange' | 'style'> {
|
|
11
|
+
style?: import('./TyInput').TyInputCSSProperties;
|
|
12
|
+
/** Current selected values as comma-separated string or array */
|
|
13
|
+
value?: string | string[];
|
|
14
|
+
/** Placeholder text when no items are selected */
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
/** Disable the multiselect component */
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Loading state — replaces the available-options area with a centered
|
|
20
|
+
* spinner. Search input stays usable. Pair with `externalSearch` while
|
|
21
|
+
* fetching results from a parent-owned data source.
|
|
22
|
+
*/
|
|
23
|
+
loading?: boolean;
|
|
24
|
+
/** Make the multiselect read-only */
|
|
25
|
+
readonly?: boolean;
|
|
26
|
+
/** Semantic styling variant */
|
|
27
|
+
flavor?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
28
|
+
/** Label text for the multiselect */
|
|
29
|
+
label?: string;
|
|
30
|
+
/** Mark the field as required */
|
|
31
|
+
required?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Switch to external (remote) search mode. Default is `false` — the
|
|
34
|
+
* multiselect filters its own children client-side. Set to `true` when you
|
|
35
|
+
* want to handle filtering yourself (e.g. server-side): the component will
|
|
36
|
+
* dispatch `search` events on each keystroke, and you must update the children
|
|
37
|
+
* in response. The `onSearch` prop receives those events.
|
|
38
|
+
*/
|
|
39
|
+
externalSearch?: boolean;
|
|
40
|
+
/** Debounce in milliseconds (0-5000) */
|
|
41
|
+
debounce?: number;
|
|
42
|
+
/** Mobile section label for selected items */
|
|
43
|
+
selectedLabel?: string;
|
|
44
|
+
/** Form field name for form submission */
|
|
45
|
+
name?: string;
|
|
46
|
+
/** Callback when selection changes */
|
|
47
|
+
onChange?: (event: CustomEvent<TyMultiselectEventDetail>) => void;
|
|
48
|
+
/** Callback fired on each search input change (debounced by `debounce`). Use for external/server-side filtering. */
|
|
49
|
+
onSearch?: (event: CustomEvent<{
|
|
50
|
+
query: string;
|
|
51
|
+
element: HTMLElement;
|
|
52
|
+
}>) => void;
|
|
53
|
+
/** Children should be TyTag components, not TyOption */
|
|
54
|
+
children?: React.ReactNode;
|
|
55
|
+
}
|
|
56
|
+
export declare const TyMultiselect: React.ForwardRefExoticComponent<TyMultiselectProps & React.RefAttributes<HTMLElement>>;
|
|
57
|
+
//# sourceMappingURL=TyMultiselect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TyMultiselect.d.ts","sourceRoot":"","sources":["../../src/components/TyMultiselect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAK9D,MAAM,WAAW,wBAAwB;IACvC,yCAAyC;IACzC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,yDAAyD;IACzD,MAAM,EAAE,KAAK,GAAG,QAAQ,CAAC;IACzB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IACvG,KAAK,CAAC,EAAE,OAAO,WAAW,EAAE,oBAAoB,CAAC;IACjD,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAE1B,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAEhF,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,8CAA8C;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sCAAsC;IACtC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,wBAAwB,CAAC,KAAK,IAAI,CAAC;IAElE,oHAAoH;IACpH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAE,CAAC,KAAK,IAAI,CAAC;IAEjF,wDAAwD;IACxD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAGD,eAAO,MAAM,aAAa,wFAoIzB,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { needsPropertyBridge } from '../utils/react-version';
|
|
3
|
+
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
|
+
// React wrapper for ty-multiselect web component
|
|
5
|
+
export const TyMultiselect = React.forwardRef(({ value, placeholder, disabled, loading, readonly, flavor, label, required, externalSearch, debounce, selectedLabel, name, onChange, onSearch, children, ...props }, ref) => {
|
|
6
|
+
const elementRef = useRef(null);
|
|
7
|
+
// Handle ref forwarding
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (ref && elementRef.current) {
|
|
10
|
+
if (typeof ref === 'function') {
|
|
11
|
+
ref(elementRef.current);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
ref.current = elementRef.current;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}, [ref]);
|
|
18
|
+
// Imperatively sync `value` to the underlying property so resets
|
|
19
|
+
// (`value=""` or null) reliably clear the visible selection.
|
|
20
|
+
// React 18 workaround; React 19+ handles this natively.
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!needsPropertyBridge)
|
|
23
|
+
return;
|
|
24
|
+
const element = elementRef.current;
|
|
25
|
+
if (!element)
|
|
26
|
+
return;
|
|
27
|
+
const next = props.value ?? '';
|
|
28
|
+
if (element.value !== next) {
|
|
29
|
+
element.value = next;
|
|
30
|
+
}
|
|
31
|
+
}, [props.value]);
|
|
32
|
+
// Handle change events
|
|
33
|
+
const handleChange = useCallback((event) => {
|
|
34
|
+
const customEvent = event;
|
|
35
|
+
if (onChange) {
|
|
36
|
+
onChange(customEvent);
|
|
37
|
+
}
|
|
38
|
+
}, [onChange]);
|
|
39
|
+
const handleSearch = useCallback((event) => {
|
|
40
|
+
const customEvent = event;
|
|
41
|
+
if (onSearch) {
|
|
42
|
+
onSearch(customEvent);
|
|
43
|
+
}
|
|
44
|
+
}, [onSearch]);
|
|
45
|
+
// Set up event listeners
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
const element = elementRef.current;
|
|
48
|
+
if (!element)
|
|
49
|
+
return;
|
|
50
|
+
if (onChange)
|
|
51
|
+
element.addEventListener('change', handleChange);
|
|
52
|
+
if (onSearch)
|
|
53
|
+
element.addEventListener('search', handleSearch);
|
|
54
|
+
return () => {
|
|
55
|
+
if (onChange)
|
|
56
|
+
element.removeEventListener('change', handleChange);
|
|
57
|
+
if (onSearch)
|
|
58
|
+
element.removeEventListener('search', handleSearch);
|
|
59
|
+
};
|
|
60
|
+
}, [handleChange, handleSearch, onChange, onSearch]);
|
|
61
|
+
// Imperative property sync for boolean props (see use-boolean-prop.ts).
|
|
62
|
+
const isDisabled = useBooleanProperty(elementRef, 'disabled', disabled);
|
|
63
|
+
const isLoading = useBooleanProperty(elementRef, 'loading', loading);
|
|
64
|
+
const isReadonly = useBooleanProperty(elementRef, 'readonly', readonly);
|
|
65
|
+
const isRequired = useBooleanProperty(elementRef, 'required', required);
|
|
66
|
+
const isExternalSearch = useBooleanProperty(elementRef, 'externalSearch', externalSearch);
|
|
67
|
+
// Convert React props to web component attributes
|
|
68
|
+
const webComponentProps = {
|
|
69
|
+
...props,
|
|
70
|
+
ref: elementRef,
|
|
71
|
+
};
|
|
72
|
+
// Handle value conversion (array to comma-separated string)
|
|
73
|
+
if (value !== undefined) {
|
|
74
|
+
const valueString = Array.isArray(value) ? value.join(',') : value;
|
|
75
|
+
webComponentProps.value = valueString;
|
|
76
|
+
}
|
|
77
|
+
// Add optional attributes only if they have values
|
|
78
|
+
if (placeholder) {
|
|
79
|
+
webComponentProps.placeholder = placeholder;
|
|
80
|
+
}
|
|
81
|
+
if (isLoading)
|
|
82
|
+
webComponentProps.loading = '';
|
|
83
|
+
if (isDisabled)
|
|
84
|
+
webComponentProps.disabled = '';
|
|
85
|
+
if (isReadonly)
|
|
86
|
+
webComponentProps.readonly = '';
|
|
87
|
+
if (isRequired)
|
|
88
|
+
webComponentProps.required = '';
|
|
89
|
+
if (isExternalSearch)
|
|
90
|
+
webComponentProps['external-search'] = '';
|
|
91
|
+
if (flavor) {
|
|
92
|
+
webComponentProps.flavor = flavor;
|
|
93
|
+
}
|
|
94
|
+
if (label) {
|
|
95
|
+
webComponentProps.label = label;
|
|
96
|
+
}
|
|
97
|
+
if (name) {
|
|
98
|
+
webComponentProps.name = name;
|
|
99
|
+
}
|
|
100
|
+
// Add debounce attribute
|
|
101
|
+
if (debounce !== undefined) {
|
|
102
|
+
webComponentProps.debounce = debounce;
|
|
103
|
+
}
|
|
104
|
+
// Add selectedLabel attribute
|
|
105
|
+
if (selectedLabel) {
|
|
106
|
+
webComponentProps['selected-label'] = selectedLabel;
|
|
107
|
+
}
|
|
108
|
+
return React.createElement('ty-multiselect', webComponentProps, children);
|
|
109
|
+
});
|
|
110
|
+
TyMultiselect.displayName = 'TyMultiselect';
|
|
111
|
+
//# sourceMappingURL=TyMultiselect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TyMultiselect.js","sourceRoot":"","sources":["../../src/components/TyMultiselect.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface TyOptionProps extends React.HTMLAttributes<HTMLElement> {
|
|
3
|
+
value?: string;
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
selected?: boolean;
|
|
6
|
+
hidden?: boolean;
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare const TyOption: React.ForwardRefExoticComponent<TyOptionProps & React.RefAttributes<HTMLElement>>;
|
|
10
|
+
//# sourceMappingURL=TyOption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TyOption.d.ts","sourceRoot":"","sources":["../../src/components/TyOption.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAIjD,MAAM,WAAW,aAAc,SAAQ,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAGD,eAAO,MAAM,QAAQ,mFA+BpB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
3
|
+
// React wrapper for ty-option web component
|
|
4
|
+
export const TyOption = React.forwardRef(({ children, disabled, selected, hidden, ...props }, ref) => {
|
|
5
|
+
const elementRef = useRef(null);
|
|
6
|
+
// Handle ref forwarding
|
|
7
|
+
useEffect(() => {
|
|
8
|
+
if (ref && elementRef.current) {
|
|
9
|
+
if (typeof ref === 'function') {
|
|
10
|
+
ref(elementRef.current);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
ref.current = elementRef.current;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}, [ref]);
|
|
17
|
+
const isDisabled = useBooleanProperty(elementRef, 'disabled', disabled);
|
|
18
|
+
const isSelected = useBooleanProperty(elementRef, 'selected', selected);
|
|
19
|
+
const isHidden = useBooleanProperty(elementRef, 'hidden', hidden);
|
|
20
|
+
return React.createElement('ty-option', {
|
|
21
|
+
...props,
|
|
22
|
+
...(isDisabled && { disabled: "" }),
|
|
23
|
+
...(isSelected && { selected: "" }),
|
|
24
|
+
...(isHidden && { hidden: "" }),
|
|
25
|
+
ref: elementRef,
|
|
26
|
+
}, children);
|
|
27
|
+
});
|
|
28
|
+
TyOption.displayName = 'TyOption';
|
|
29
|
+
//# sourceMappingURL=TyOption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TyOption.js","sourceRoot":"","sources":["../../src/components/TyOption.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAW/D,4CAA4C;AAC5C,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CACtC,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE;IAC1D,MAAM,UAAU,GAAG,MAAM,CAAc,IAAI,CAAC,CAAC;IAE7C,wBAAwB;IACxB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,GAAG,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YAC9B,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;gBAC9B,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,MAAM,UAAU,GAAG,kBAAkB,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,kBAAkB,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;IACxE,MAAM,QAAQ,GAAG,kBAAkB,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAElE,OAAO,KAAK,CAAC,aAAa,CACxB,WAAW,EACX;QACE,GAAG,KAAK;QACR,GAAG,CAAC,UAAU,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACnC,GAAG,CAAC,UAAU,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACnC,GAAG,CAAC,QAAQ,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QAC/B,GAAG,EAAE,UAAU;KAChB,EACD,QAAQ,CACT,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface TyPopupProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onClose'> {
|
|
3
|
+
/** Preferred placement of the popup relative to anchor parent: "top" | "bottom" | "left" | "right" */
|
|
4
|
+
placement?: 'top' | 'bottom' | 'left' | 'right';
|
|
5
|
+
/** Distance offset from the anchor in pixels (default: 8) */
|
|
6
|
+
offset?: number;
|
|
7
|
+
/** Disable automatic click trigger - requires manual open/close via ref methods */
|
|
8
|
+
manual?: boolean;
|
|
9
|
+
/** Disable automatic close on outside click and ESC key */
|
|
10
|
+
disableClose?: boolean;
|
|
11
|
+
/** Fired when the popup opens (after the open animation starts) */
|
|
12
|
+
onOpen?: (event: CustomEvent) => void;
|
|
13
|
+
/** Fired when the popup closes */
|
|
14
|
+
onClose?: (event: CustomEvent) => void;
|
|
15
|
+
/** Popup content - popup should be a child of the anchor element */
|
|
16
|
+
children?: React.ReactNode;
|
|
17
|
+
}
|
|
18
|
+
export interface TyPopupElement extends HTMLElement {
|
|
19
|
+
openPopup(): void;
|
|
20
|
+
closePopup(): void;
|
|
21
|
+
togglePopup(): void;
|
|
22
|
+
}
|
|
23
|
+
export declare const TyPopup: React.ForwardRefExoticComponent<TyPopupProps & React.RefAttributes<TyPopupElement>>;
|
|
24
|
+
//# sourceMappingURL=TyPopup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TyPopup.d.ts","sourceRoot":"","sources":["../../src/components/TyPopup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAIjD,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IACtF,sGAAsG;IACtG,SAAS,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;IAEhD,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,mFAAmF;IACnF,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,mEAAmE;IACnE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAEtC,kCAAkC;IAClC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAEvC,oEAAoE;IACpE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAGD,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,SAAS,IAAI,IAAI,CAAC;IAClB,UAAU,IAAI,IAAI,CAAC;IACnB,WAAW,IAAI,IAAI,CAAC;CACrB;AAGD,eAAO,MAAM,OAAO,qFA8EnB,CAAC"}
|