tyrell-react 1.0.0-RC11 → 1.0.0-RC13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/components/TyButton.d.ts.map +1 -1
- package/dist/components/TyButton.js +2 -1
- package/dist/components/TyButton.js.map +1 -1
- package/dist/components/TyCalendar.d.ts +11 -0
- package/dist/components/TyCalendar.d.ts.map +1 -1
- package/dist/components/TyCalendar.js +21 -3
- package/dist/components/TyCalendar.js.map +1 -1
- package/dist/components/TyCalendarMonth.d.ts +9 -0
- package/dist/components/TyCalendarMonth.d.ts.map +1 -1
- package/dist/components/TyCalendarMonth.js +9 -2
- package/dist/components/TyCalendarMonth.js.map +1 -1
- package/dist/components/TyCalendarNavigation.d.ts +4 -0
- package/dist/components/TyCalendarNavigation.d.ts.map +1 -1
- package/dist/components/TyCalendarNavigation.js +7 -2
- package/dist/components/TyCalendarNavigation.js.map +1 -1
- package/dist/components/TyCheckbox.d.ts +6 -1
- package/dist/components/TyCheckbox.d.ts.map +1 -1
- package/dist/components/TyCheckbox.js +6 -2
- package/dist/components/TyCheckbox.js.map +1 -1
- package/dist/components/TyCopy.d.ts +8 -1
- package/dist/components/TyCopy.d.ts.map +1 -1
- package/dist/components/TyCopy.js +21 -2
- package/dist/components/TyCopy.js.map +1 -1
- package/dist/components/TyDatePicker.d.ts +15 -4
- package/dist/components/TyDatePicker.d.ts.map +1 -1
- package/dist/components/TyDatePicker.js +9 -2
- package/dist/components/TyDatePicker.js.map +1 -1
- package/dist/components/TyFileUpload.d.ts.map +1 -1
- package/dist/components/TyFileUpload.js +2 -1
- package/dist/components/TyFileUpload.js.map +1 -1
- package/dist/components/TyInput.d.ts +6 -2
- package/dist/components/TyInput.d.ts.map +1 -1
- package/dist/components/TyInput.js +2 -1
- package/dist/components/TyInput.js.map +1 -1
- package/dist/components/TyModal.d.ts +5 -0
- package/dist/components/TyModal.d.ts.map +1 -1
- package/dist/components/TyModal.js +5 -2
- package/dist/components/TyModal.js.map +1 -1
- package/dist/components/TyOption.d.ts +8 -0
- package/dist/components/TyOption.d.ts.map +1 -1
- package/dist/components/TyOption.js +5 -2
- package/dist/components/TyOption.js.map +1 -1
- package/dist/components/TyPopup.d.ts.map +1 -1
- package/dist/components/TyPopup.js +2 -1
- package/dist/components/TyPopup.js.map +1 -1
- package/dist/components/TyRadio.d.ts +4 -1
- package/dist/components/TyRadio.d.ts.map +1 -1
- package/dist/components/TyRadio.js +2 -1
- package/dist/components/TyRadio.js.map +1 -1
- package/dist/components/TyRadioGroup.d.ts +4 -1
- package/dist/components/TyRadioGroup.d.ts.map +1 -1
- package/dist/components/TyRadioGroup.js +2 -1
- package/dist/components/TyRadioGroup.js.map +1 -1
- package/dist/components/TyResizeObserver.d.ts.map +1 -1
- package/dist/components/TyResizeObserver.js +2 -1
- package/dist/components/TyResizeObserver.js.map +1 -1
- package/dist/components/TyScrollContainer.d.ts +26 -1
- package/dist/components/TyScrollContainer.d.ts.map +1 -1
- package/dist/components/TyScrollContainer.js +43 -25
- package/dist/components/TyScrollContainer.js.map +1 -1
- package/dist/components/TySelect.d.ts +114 -0
- package/dist/components/TySelect.d.ts.map +1 -0
- package/dist/components/TySelect.js +159 -0
- package/dist/components/TySelect.js.map +1 -0
- package/dist/components/TyStep.d.ts.map +1 -1
- package/dist/components/TyStep.js +2 -1
- package/dist/components/TyStep.js.map +1 -1
- package/dist/components/TySwitch.d.ts +4 -1
- package/dist/components/TySwitch.d.ts.map +1 -1
- package/dist/components/TySwitch.js +2 -1
- package/dist/components/TySwitch.js.map +1 -1
- package/dist/components/TyTab.d.ts.map +1 -1
- package/dist/components/TyTab.js +2 -1
- package/dist/components/TyTab.js.map +1 -1
- package/dist/components/TyTabs.d.ts.map +1 -1
- package/dist/components/TyTabs.js +2 -1
- package/dist/components/TyTabs.js.map +1 -1
- package/dist/components/TyTag.d.ts +4 -1
- package/dist/components/TyTag.d.ts.map +1 -1
- package/dist/components/TyTag.js +2 -1
- package/dist/components/TyTag.js.map +1 -1
- package/dist/components/TyTextarea.d.ts.map +1 -1
- package/dist/components/TyTextarea.js +2 -1
- package/dist/components/TyTextarea.js.map +1 -1
- package/dist/components/TyTooltip.d.ts +4 -1
- package/dist/components/TyTooltip.d.ts.map +1 -1
- package/dist/components/TyTooltip.js +2 -1
- package/dist/components/TyTooltip.js.map +1 -1
- package/dist/components/TyWizard.d.ts.map +1 -1
- package/dist/components/TyWizard.js +2 -1
- package/dist/components/TyWizard.js.map +1 -1
- package/dist/components/index.d.ts +6 -8
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +5 -4
- package/dist/components/index.js.map +1 -1
- package/dist/utils/host-props.d.ts +11 -0
- package/dist/utils/host-props.d.ts.map +1 -0
- package/dist/utils/host-props.js +16 -0
- package/dist/utils/host-props.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/components/TyButton.tsx +2 -1
- package/src/components/TyCalendar.tsx +44 -3
- package/src/components/TyCalendarMonth.tsx +22 -3
- package/src/components/TyCalendarNavigation.tsx +13 -2
- package/src/components/TyCheckbox.tsx +14 -4
- package/src/components/TyCopy.tsx +31 -3
- package/src/components/TyDatePicker.tsx +31 -6
- package/src/components/TyFileUpload.tsx +2 -1
- package/src/components/TyInput.tsx +8 -3
- package/src/components/TyModal.tsx +10 -1
- package/src/components/TyOption.tsx +16 -2
- package/src/components/TyPopup.tsx +2 -1
- package/src/components/TyRadio.tsx +6 -2
- package/src/components/TyRadioGroup.tsx +6 -2
- package/src/components/TyResizeObserver.tsx +2 -1
- package/src/components/TyScrollContainer.tsx +76 -25
- package/src/components/TySelect.tsx +305 -0
- package/src/components/TyStep.tsx +2 -1
- package/src/components/TySwitch.tsx +6 -2
- package/src/components/TyTab.tsx +2 -1
- package/src/components/TyTabs.tsx +2 -1
- package/src/components/TyTag.tsx +6 -2
- package/src/components/TyTextarea.tsx +2 -1
- package/src/components/TyTooltip.tsx +6 -2
- package/src/components/TyWizard.tsx +2 -1
- package/src/components/index.ts +8 -13
- package/src/utils/host-props.ts +14 -0
- package/src/version.ts +1 -1
- package/dist/components/TyDropdown.d.ts +0 -62
- package/dist/components/TyDropdown.d.ts.map +0 -1
- package/dist/components/TyDropdown.js +0 -124
- package/dist/components/TyDropdown.js.map +0 -1
- package/dist/components/TyMultiselect.d.ts +0 -57
- package/dist/components/TyMultiselect.d.ts.map +0 -1
- package/dist/components/TyMultiselect.js +0 -111
- package/dist/components/TyMultiselect.js.map +0 -1
- package/src/components/EventConventionTest.tsx +0 -155
- package/src/components/TyDropdown.tsx +0 -240
- package/src/components/TyMultiselect.tsx +0 -208
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
3
4
|
|
|
5
|
+
type BuiltinFlavor = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
6
|
+
type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
|
|
7
|
+
|
|
4
8
|
// Type definitions for Ty Copy component
|
|
5
9
|
export interface TyCopyProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange'> {
|
|
6
10
|
/** Text to copy */
|
|
@@ -13,7 +17,7 @@ export interface TyCopyProps extends Omit<React.HTMLAttributes<HTMLElement>, 'on
|
|
|
13
17
|
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
14
18
|
|
|
15
19
|
/** Semantic styling variant */
|
|
16
|
-
flavor?:
|
|
20
|
+
flavor?: ShadedFlavor | (string & {});
|
|
17
21
|
|
|
18
22
|
/** Display format */
|
|
19
23
|
format?: 'text' | 'code';
|
|
@@ -26,6 +30,12 @@ export interface TyCopyProps extends Omit<React.HTMLAttributes<HTMLElement>, 'on
|
|
|
26
30
|
|
|
27
31
|
/** Required field */
|
|
28
32
|
required?: boolean;
|
|
33
|
+
|
|
34
|
+
/** Fired after the value is copied to the clipboard */
|
|
35
|
+
onCopySuccess?: (event: CustomEvent) => void;
|
|
36
|
+
|
|
37
|
+
/** Fired when copying to the clipboard fails */
|
|
38
|
+
onCopyError?: (event: CustomEvent) => void;
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
// React wrapper for ty-copy web component
|
|
@@ -39,7 +49,9 @@ export const TyCopy = React.forwardRef<HTMLElement, TyCopyProps>(
|
|
|
39
49
|
multiline,
|
|
40
50
|
disabled,
|
|
41
51
|
required,
|
|
42
|
-
|
|
52
|
+
onCopySuccess,
|
|
53
|
+
onCopyError,
|
|
54
|
+
...props
|
|
43
55
|
}, ref) => {
|
|
44
56
|
const elementRef = useRef<HTMLElement>(null);
|
|
45
57
|
|
|
@@ -54,13 +66,29 @@ export const TyCopy = React.forwardRef<HTMLElement, TyCopyProps>(
|
|
|
54
66
|
}
|
|
55
67
|
}, [ref]);
|
|
56
68
|
|
|
69
|
+
// Custom events → React callbacks
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
const el = elementRef.current;
|
|
72
|
+
if (!el) return;
|
|
73
|
+
const bound: Array<[string, EventListener]> = [];
|
|
74
|
+
if (onCopySuccess) {
|
|
75
|
+
const h = (e: Event) => onCopySuccess(e as CustomEvent);
|
|
76
|
+
el.addEventListener('copy-success', h); bound.push(['copy-success', h]);
|
|
77
|
+
}
|
|
78
|
+
if (onCopyError) {
|
|
79
|
+
const h = (e: Event) => onCopyError(e as CustomEvent);
|
|
80
|
+
el.addEventListener('copy-error', h); bound.push(['copy-error', h]);
|
|
81
|
+
}
|
|
82
|
+
return () => bound.forEach(([n, h]) => el.removeEventListener(n, h));
|
|
83
|
+
}, [onCopySuccess, onCopyError]);
|
|
84
|
+
|
|
57
85
|
const isMultiline = useBooleanProperty(elementRef, 'multiline', multiline);
|
|
58
86
|
const isDisabled = useBooleanProperty(elementRef, 'disabled', disabled);
|
|
59
87
|
const isRequired = useBooleanProperty(elementRef, 'required', required);
|
|
60
88
|
|
|
61
89
|
// Convert React props to web component attributes
|
|
62
90
|
const webComponentProps: Record<string, any> = {
|
|
63
|
-
...props,
|
|
91
|
+
...hostProps(props),
|
|
64
92
|
ref: elementRef,
|
|
65
93
|
};
|
|
66
94
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { needsPropertyBridge } from '../utils/react-version';
|
|
3
4
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
5
|
|
|
6
|
+
type BuiltinFlavor = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
7
|
+
type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
|
|
8
|
+
|
|
5
9
|
// Type definitions for Ty DatePicker component
|
|
6
10
|
export interface TyDatePickerEventDetail {
|
|
7
11
|
/** The selected date value (ISO string or formatted string based on format) */
|
|
@@ -18,11 +22,11 @@ export interface TyDatePickerProps extends Omit<React.HTMLAttributes<HTMLElement
|
|
|
18
22
|
/** The selected date value (ISO string or formatted string) */
|
|
19
23
|
value?: string;
|
|
20
24
|
|
|
21
|
-
/**
|
|
25
|
+
/** Field size — fields come in exactly three; legacy xs/xl map to sm/lg */
|
|
22
26
|
size?: 'sm' | 'md' | 'lg';
|
|
23
27
|
|
|
24
|
-
/** Visual flavor
|
|
25
|
-
flavor?: 'default' |
|
|
28
|
+
/** Visual flavor — built-in semantic, +/- shade, or a custom flavor backed by --ty-*-X tokens. Also tints the popup calendar's selected/today day. */
|
|
29
|
+
flavor?: 'default' | ShadedFlavor | (string & {});
|
|
26
30
|
|
|
27
31
|
/** Label text displayed above the input */
|
|
28
32
|
label?: string;
|
|
@@ -50,6 +54,12 @@ export interface TyDatePickerProps extends Omit<React.HTMLAttributes<HTMLElement
|
|
|
50
54
|
|
|
51
55
|
/** Whether to include time selection */
|
|
52
56
|
withTime?: boolean;
|
|
57
|
+
|
|
58
|
+
/** Earliest selectable date (ISO "YYYY-MM-DD") */
|
|
59
|
+
min?: string;
|
|
60
|
+
|
|
61
|
+
/** Latest selectable date (ISO "YYYY-MM-DD") */
|
|
62
|
+
max?: string;
|
|
53
63
|
|
|
54
64
|
/** Callback when the date value changes */
|
|
55
65
|
onChange?: (event: CustomEvent<TyDatePickerEventDetail>) => void;
|
|
@@ -61,8 +71,13 @@ export interface TyDatePickerProps extends Omit<React.HTMLAttributes<HTMLElement
|
|
|
61
71
|
onClose?: (event: CustomEvent<{}>) => void;
|
|
62
72
|
}
|
|
63
73
|
|
|
74
|
+
/** The underlying custom element, typed with its imperative clear() method. */
|
|
75
|
+
export interface TyDatePickerElement extends HTMLElement {
|
|
76
|
+
clear(): void;
|
|
77
|
+
}
|
|
78
|
+
|
|
64
79
|
// React wrapper for ty-date-picker web component
|
|
65
|
-
export const TyDatePicker = React.forwardRef<
|
|
80
|
+
export const TyDatePicker = React.forwardRef<TyDatePickerElement, TyDatePickerProps>(
|
|
66
81
|
({
|
|
67
82
|
value,
|
|
68
83
|
size,
|
|
@@ -76,12 +91,14 @@ export const TyDatePicker = React.forwardRef<HTMLElement, TyDatePickerProps>(
|
|
|
76
91
|
format,
|
|
77
92
|
locale,
|
|
78
93
|
withTime,
|
|
94
|
+
min,
|
|
95
|
+
max,
|
|
79
96
|
onChange,
|
|
80
97
|
onOpen,
|
|
81
98
|
onClose,
|
|
82
99
|
...props
|
|
83
100
|
}, ref) => {
|
|
84
|
-
const elementRef = useRef<
|
|
101
|
+
const elementRef = useRef<TyDatePickerElement>(null);
|
|
85
102
|
|
|
86
103
|
// Handle ref forwarding
|
|
87
104
|
useEffect(() => {
|
|
@@ -159,7 +176,7 @@ export const TyDatePicker = React.forwardRef<HTMLElement, TyDatePickerProps>(
|
|
|
159
176
|
|
|
160
177
|
// Convert React props to web component attributes
|
|
161
178
|
const webComponentProps: Record<string, any> = {
|
|
162
|
-
...props,
|
|
179
|
+
...hostProps(props),
|
|
163
180
|
ref: elementRef,
|
|
164
181
|
};
|
|
165
182
|
|
|
@@ -208,6 +225,14 @@ export const TyDatePicker = React.forwardRef<HTMLElement, TyDatePickerProps>(
|
|
|
208
225
|
webComponentProps['with-time'] = ''; // Convert camelCase to kebab-case
|
|
209
226
|
}
|
|
210
227
|
|
|
228
|
+
if (min) {
|
|
229
|
+
webComponentProps.min = min;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (max) {
|
|
233
|
+
webComponentProps.max = max;
|
|
234
|
+
}
|
|
235
|
+
|
|
211
236
|
return React.createElement('ty-date-picker', webComponentProps);
|
|
212
237
|
}
|
|
213
238
|
);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
3
4
|
|
|
4
5
|
// Type definitions for Ty File Upload component
|
|
@@ -87,7 +88,7 @@ export const TyFileUpload = React.forwardRef<HTMLElement, TyFileUploadProps>(
|
|
|
87
88
|
const isRequired = useBooleanProperty(elementRef, 'required', required);
|
|
88
89
|
|
|
89
90
|
const webComponentProps: Record<string, any> = {
|
|
90
|
-
...props,
|
|
91
|
+
...hostProps(props),
|
|
91
92
|
ref: elementRef,
|
|
92
93
|
};
|
|
93
94
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useCallback } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { needsPropertyBridge } from '../utils/react-version';
|
|
3
4
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
5
|
|
|
6
|
+
type BuiltinFlavor = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
7
|
+
type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
|
|
8
|
+
|
|
5
9
|
// Event detail structure for ty-input events
|
|
6
10
|
export interface TyInputEventDetail {
|
|
7
11
|
value: any; // shadow value (processed/parsed)
|
|
@@ -31,10 +35,11 @@ export interface TyInputProps extends Omit<React.HTMLAttributes<HTMLElement>, 'o
|
|
|
31
35
|
| 'currency' | 'percent' | 'compact';
|
|
32
36
|
|
|
33
37
|
/** Semantic styling variant */
|
|
34
|
-
flavor?:
|
|
38
|
+
flavor?: ShadedFlavor | (string & {});
|
|
35
39
|
|
|
36
40
|
/** Input size */
|
|
37
|
-
size
|
|
41
|
+
/** Field size — fields come in exactly three; legacy xs/xl map to sm/lg */
|
|
42
|
+
size?: 'sm' | 'md' | 'lg';
|
|
38
43
|
|
|
39
44
|
/** Input value */
|
|
40
45
|
value?: string;
|
|
@@ -214,7 +219,7 @@ export const TyInput = React.forwardRef<HTMLElement, TyInputProps>(
|
|
|
214
219
|
|
|
215
220
|
// Convert React props to web component attributes
|
|
216
221
|
const webComponentProps: Record<string, any> = {
|
|
217
|
-
...props,
|
|
222
|
+
...hostProps(props),
|
|
218
223
|
ref: elementRef,
|
|
219
224
|
};
|
|
220
225
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useImperativeHandle } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { useBooleanProperty, coerceBool } from '../utils/use-boolean-prop';
|
|
3
4
|
import { needsPropertyBridge } from '../utils/react-version';
|
|
4
5
|
|
|
@@ -32,6 +33,12 @@ export interface TyModalProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
32
33
|
/** Allow closing modal with Escape key (default: true) */
|
|
33
34
|
closeOnEscape?: boolean;
|
|
34
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Accessible name — sets aria-label on the internal <dialog>. The dialog
|
|
38
|
+
* gets role="dialog" for free, but nothing names it unless you set this.
|
|
39
|
+
*/
|
|
40
|
+
label?: string;
|
|
41
|
+
|
|
35
42
|
/** React event handlers */
|
|
36
43
|
onOpen?: (event: CustomEvent<TyModalEventDetail>) => void;
|
|
37
44
|
onClose?: (event: CustomEvent<TyModalEventDetail>) => void;
|
|
@@ -64,6 +71,7 @@ export const TyModal = React.forwardRef<TyModalRef, TyModalProps>(
|
|
|
64
71
|
backdrop,
|
|
65
72
|
closeOnOutsideClick,
|
|
66
73
|
closeOnEscape,
|
|
74
|
+
label,
|
|
67
75
|
onOpen,
|
|
68
76
|
onClose,
|
|
69
77
|
onBeforeClose,
|
|
@@ -166,7 +174,7 @@ export const TyModal = React.forwardRef<TyModalRef, TyModalProps>(
|
|
|
166
174
|
|
|
167
175
|
// Convert React props to web component attributes
|
|
168
176
|
const webComponentProps: Record<string, any> = {
|
|
169
|
-
...props,
|
|
177
|
+
...hostProps(props),
|
|
170
178
|
ref: elementRef,
|
|
171
179
|
};
|
|
172
180
|
|
|
@@ -183,6 +191,7 @@ export const TyModal = React.forwardRef<TyModalRef, TyModalProps>(
|
|
|
183
191
|
if (closeOnEscape !== undefined && !coerceBool(closeOnEscape)) {
|
|
184
192
|
webComponentProps['close-on-escape'] = 'false';
|
|
185
193
|
}
|
|
194
|
+
if (label) webComponentProps.label = label;
|
|
186
195
|
|
|
187
196
|
return React.createElement(
|
|
188
197
|
'ty-modal',
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
3
4
|
|
|
4
5
|
// Type definitions for Ty Option component
|
|
5
6
|
export interface TyOptionProps extends React.HTMLAttributes<HTMLElement> {
|
|
6
7
|
value?: string;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Clean display text (native <option label> semantics) — used by ty-select
|
|
11
|
+
* for field summaries and by ty-selected-options chips when the option's
|
|
12
|
+
* children are rich HTML. data-* attributes feed chip templates.
|
|
13
|
+
*/
|
|
14
|
+
label?: string;
|
|
15
|
+
|
|
16
|
+
/** Semantic flavor — carried onto ty-selected-options chips */
|
|
17
|
+
flavor?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'neutral' | 'info';
|
|
18
|
+
|
|
7
19
|
disabled?: boolean;
|
|
8
20
|
selected?: boolean;
|
|
9
21
|
hidden?: boolean;
|
|
@@ -12,7 +24,7 @@ export interface TyOptionProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
12
24
|
|
|
13
25
|
// React wrapper for ty-option web component
|
|
14
26
|
export const TyOption = React.forwardRef<HTMLElement, TyOptionProps>(
|
|
15
|
-
({ children, disabled, selected, hidden, ...props }, ref) => {
|
|
27
|
+
({ children, label, flavor, disabled, selected, hidden, ...props }, ref) => {
|
|
16
28
|
const elementRef = useRef<HTMLElement>(null);
|
|
17
29
|
|
|
18
30
|
// Handle ref forwarding
|
|
@@ -33,7 +45,9 @@ export const TyOption = React.forwardRef<HTMLElement, TyOptionProps>(
|
|
|
33
45
|
return React.createElement(
|
|
34
46
|
'ty-option',
|
|
35
47
|
{
|
|
36
|
-
...props,
|
|
48
|
+
...hostProps(props),
|
|
49
|
+
...(label && { label }),
|
|
50
|
+
...(flavor && { flavor }),
|
|
37
51
|
...(isDisabled && { disabled: "" }),
|
|
38
52
|
...(isSelected && { selected: "" }),
|
|
39
53
|
...(isHidden && { hidden: "" }),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
3
4
|
|
|
4
5
|
// Type definitions for Ty Popup component
|
|
@@ -86,7 +87,7 @@ export const TyPopup = React.forwardRef<TyPopupElement, TyPopupProps>(
|
|
|
86
87
|
|
|
87
88
|
// Convert React props to web component attributes
|
|
88
89
|
const webComponentProps: Record<string, any> = {
|
|
89
|
-
...props,
|
|
90
|
+
...hostProps(props),
|
|
90
91
|
ref: elementRef,
|
|
91
92
|
};
|
|
92
93
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
3
4
|
|
|
5
|
+
type BuiltinFlavor = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
6
|
+
type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
|
|
7
|
+
|
|
4
8
|
export interface TyRadioProps extends React.HTMLAttributes<HTMLElement> {
|
|
5
9
|
/** Form field value (selected by parent ty-radio-group when matches its `value`) */
|
|
6
10
|
value?: string;
|
|
@@ -18,7 +22,7 @@ export interface TyRadioProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
18
22
|
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
19
23
|
|
|
20
24
|
/** Semantic styling variant — typically inherited from the parent group */
|
|
21
|
-
flavor?:
|
|
25
|
+
flavor?: ShadedFlavor | (string & {});
|
|
22
26
|
|
|
23
27
|
/** Label content (wrap in a `<label>` for click delegation, see ty-radio docs) */
|
|
24
28
|
children?: React.ReactNode;
|
|
@@ -43,7 +47,7 @@ export const TyRadio = React.forwardRef<HTMLElement, TyRadioProps>(
|
|
|
43
47
|
const isDisabled = useBooleanProperty(elementRef, 'disabled', disabled);
|
|
44
48
|
|
|
45
49
|
const webComponentProps: Record<string, any> = {
|
|
46
|
-
...props,
|
|
50
|
+
...hostProps(props),
|
|
47
51
|
ref: elementRef,
|
|
48
52
|
};
|
|
49
53
|
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
3
4
|
|
|
5
|
+
type BuiltinFlavor = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
6
|
+
type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
|
|
7
|
+
|
|
4
8
|
export interface TyRadioGroupProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange' | 'onInput'> {
|
|
5
9
|
/** Currently selected value (matches one child `<TyRadio value="...">`) */
|
|
6
10
|
value?: string;
|
|
@@ -27,7 +31,7 @@ export interface TyRadioGroupProps extends Omit<React.HTMLAttributes<HTMLElement
|
|
|
27
31
|
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
28
32
|
|
|
29
33
|
/** Group flavor — propagates to all `<TyRadio>` children */
|
|
30
|
-
flavor?:
|
|
34
|
+
flavor?: ShadedFlavor | (string & {});
|
|
31
35
|
|
|
32
36
|
/**
|
|
33
37
|
* Fires when selection changes (React convention)
|
|
@@ -103,7 +107,7 @@ export const TyRadioGroup = React.forwardRef<HTMLElement, TyRadioGroupProps>(
|
|
|
103
107
|
const isRequired = useBooleanProperty(elementRef, 'required', required);
|
|
104
108
|
|
|
105
109
|
const webComponentProps: Record<string, any> = {
|
|
106
|
-
...props,
|
|
110
|
+
...hostProps(props),
|
|
107
111
|
ref: elementRef,
|
|
108
112
|
};
|
|
109
113
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
|
|
3
4
|
// Type definitions for Ty ResizeObserver component
|
|
4
5
|
export interface TyResizeObserverProps extends React.HTMLAttributes<HTMLElement> {
|
|
@@ -35,7 +36,7 @@ export const TyResizeObserver = React.forwardRef<HTMLElement, TyResizeObserverPr
|
|
|
35
36
|
|
|
36
37
|
// Convert React props to web component attributes
|
|
37
38
|
const webComponentProps: Record<string, any> = {
|
|
38
|
-
...props,
|
|
39
|
+
...hostProps(props),
|
|
39
40
|
ref: elementRef,
|
|
40
41
|
id,
|
|
41
42
|
};
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useImperativeHandle } from 'react';
|
|
2
|
+
import { hostProps } from '../utils/host-props';
|
|
2
3
|
import { needsPropertyBridge } from '../utils/react-version';
|
|
3
4
|
import { useBooleanProperty, coerceBool } from '../utils/use-boolean-prop';
|
|
4
5
|
|
|
6
|
+
/** Detail payload for nearstart / nearend events. */
|
|
7
|
+
export interface TyScrollNearEdgeDetail {
|
|
8
|
+
distance: number;
|
|
9
|
+
scrollTop: number;
|
|
10
|
+
scrollHeight: number;
|
|
11
|
+
clientHeight: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
5
14
|
// Type definitions for Ty ScrollContainer component
|
|
6
15
|
export interface TyScrollContainerProps extends React.HTMLAttributes<HTMLElement> {
|
|
7
16
|
/** Maximum height of the scroll container */
|
|
@@ -10,9 +19,27 @@ export interface TyScrollContainerProps extends React.HTMLAttributes<HTMLElement
|
|
|
10
19
|
/** Enable/disable scroll shadows (default: true) */
|
|
11
20
|
shadow?: boolean;
|
|
12
21
|
|
|
13
|
-
/** Hide native scrollbar */
|
|
22
|
+
/** Hide native scrollbar (no custom scrollbar) */
|
|
14
23
|
hideScrollbar?: boolean;
|
|
15
24
|
|
|
25
|
+
/** Use the styled custom scrollbar */
|
|
26
|
+
customScrollbar?: boolean;
|
|
27
|
+
|
|
28
|
+
/** Enable horizontal scrolling */
|
|
29
|
+
overflowX?: boolean;
|
|
30
|
+
|
|
31
|
+
/** Preserve visual position when content is prepended above the viewport */
|
|
32
|
+
scrollAnchoring?: boolean;
|
|
33
|
+
|
|
34
|
+
/** Distance (px) from an edge at which nearstart/nearend fire (default 100) */
|
|
35
|
+
nearEdgeThreshold?: number;
|
|
36
|
+
|
|
37
|
+
/** Fired once when scrolled within the threshold of the bottom */
|
|
38
|
+
onNearEnd?: (event: CustomEvent<TyScrollNearEdgeDetail>) => void;
|
|
39
|
+
|
|
40
|
+
/** Fired once when scrolled within the threshold of the top */
|
|
41
|
+
onNearStart?: (event: CustomEvent<TyScrollNearEdgeDetail>) => void;
|
|
42
|
+
|
|
16
43
|
/** Content to scroll */
|
|
17
44
|
children?: React.ReactNode;
|
|
18
45
|
}
|
|
@@ -25,6 +52,12 @@ export interface TyScrollContainerRef {
|
|
|
25
52
|
scrollToTop: (smooth?: boolean) => void;
|
|
26
53
|
/** Scroll to bottom */
|
|
27
54
|
scrollToBottom: (smooth?: boolean) => void;
|
|
55
|
+
/** Scroll to far left */
|
|
56
|
+
scrollToLeft: (smooth?: boolean) => void;
|
|
57
|
+
/** Scroll to far right */
|
|
58
|
+
scrollToRight: (smooth?: boolean) => void;
|
|
59
|
+
/** Scroll a descendant (element or CSS selector) into view */
|
|
60
|
+
scrollToElement: (target: Element | string, smooth?: boolean) => void;
|
|
28
61
|
/** Get the underlying scroll element */
|
|
29
62
|
scrollElement: HTMLElement | null;
|
|
30
63
|
/** Get the native element */
|
|
@@ -38,35 +71,29 @@ export const TyScrollContainer = React.forwardRef<TyScrollContainerRef, TyScroll
|
|
|
38
71
|
maxHeight,
|
|
39
72
|
shadow,
|
|
40
73
|
hideScrollbar,
|
|
74
|
+
customScrollbar,
|
|
75
|
+
overflowX,
|
|
76
|
+
scrollAnchoring,
|
|
77
|
+
nearEdgeThreshold,
|
|
78
|
+
onNearEnd,
|
|
79
|
+
onNearStart,
|
|
41
80
|
...props
|
|
42
81
|
}, ref) => {
|
|
43
82
|
const elementRef = useRef<HTMLElement>(null);
|
|
44
83
|
|
|
45
84
|
// Expose imperative methods via ref
|
|
46
85
|
useImperativeHandle(ref, () => ({
|
|
47
|
-
updateShadows: () => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
},
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
scrollToBottom: (smooth = true) => {
|
|
56
|
-
const el = elementRef.current as any;
|
|
57
|
-
el?.scrollToBottom?.(smooth);
|
|
58
|
-
},
|
|
59
|
-
get scrollElement() {
|
|
60
|
-
const el = elementRef.current as any;
|
|
61
|
-
return el?.scrollElement ?? null;
|
|
62
|
-
},
|
|
63
|
-
get element() {
|
|
64
|
-
return elementRef.current;
|
|
65
|
-
}
|
|
86
|
+
updateShadows: () => { (elementRef.current as any)?.updateShadows?.(); },
|
|
87
|
+
scrollToTop: (smooth = true) => { (elementRef.current as any)?.scrollToTop?.(smooth); },
|
|
88
|
+
scrollToBottom: (smooth = true) => { (elementRef.current as any)?.scrollToBottom?.(smooth); },
|
|
89
|
+
scrollToLeft: (smooth = true) => { (elementRef.current as any)?.scrollToLeft?.(smooth); },
|
|
90
|
+
scrollToRight: (smooth = true) => { (elementRef.current as any)?.scrollToRight?.(smooth); },
|
|
91
|
+
scrollToElement: (target, smooth = true) => { (elementRef.current as any)?.scrollToElement?.(target, smooth); },
|
|
92
|
+
get scrollElement() { return (elementRef.current as any)?.scrollElement ?? null; },
|
|
93
|
+
get element() { return elementRef.current; }
|
|
66
94
|
}), []);
|
|
67
95
|
|
|
68
|
-
// shadow defaults to true;
|
|
69
|
-
// attribute level. Bridge it imperatively so flipping back to true
|
|
96
|
+
// shadow defaults to true; bridge it imperatively so flipping back to true
|
|
70
97
|
// propagates on React 18.
|
|
71
98
|
useEffect(() => {
|
|
72
99
|
if (!needsPropertyBridge) return;
|
|
@@ -76,20 +103,44 @@ export const TyScrollContainer = React.forwardRef<TyScrollContainerRef, TyScroll
|
|
|
76
103
|
const next = coerceBool(shadow);
|
|
77
104
|
if (Boolean(el.shadow) !== next) el.shadow = next;
|
|
78
105
|
}, [shadow]);
|
|
106
|
+
|
|
79
107
|
const isHideScrollbar = useBooleanProperty(elementRef, 'hideScrollbar', hideScrollbar);
|
|
108
|
+
const isCustomScrollbar = useBooleanProperty(elementRef, 'customScrollbar', customScrollbar);
|
|
109
|
+
const isOverflowX = useBooleanProperty(elementRef, 'overflowX', overflowX);
|
|
110
|
+
const isScrollAnchoring = useBooleanProperty(elementRef, 'scrollAnchoring', scrollAnchoring);
|
|
111
|
+
|
|
112
|
+
// Custom events → React callbacks
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
const el = elementRef.current;
|
|
115
|
+
if (!el) return;
|
|
116
|
+
const bound: Array<[string, EventListener]> = [];
|
|
117
|
+
if (onNearEnd) {
|
|
118
|
+
const h = (e: Event) => onNearEnd(e as CustomEvent<TyScrollNearEdgeDetail>);
|
|
119
|
+
el.addEventListener('nearend', h); bound.push(['nearend', h]);
|
|
120
|
+
}
|
|
121
|
+
if (onNearStart) {
|
|
122
|
+
const h = (e: Event) => onNearStart(e as CustomEvent<TyScrollNearEdgeDetail>);
|
|
123
|
+
el.addEventListener('nearstart', h); bound.push(['nearstart', h]);
|
|
124
|
+
}
|
|
125
|
+
return () => bound.forEach(([n, h]) => el.removeEventListener(n, h));
|
|
126
|
+
}, [onNearEnd, onNearStart]);
|
|
80
127
|
|
|
81
128
|
// Convert React props to web component attributes
|
|
82
129
|
const webComponentProps: Record<string, any> = {
|
|
83
|
-
...props,
|
|
130
|
+
...hostProps(props),
|
|
84
131
|
ref: elementRef,
|
|
85
132
|
};
|
|
86
133
|
|
|
87
|
-
//
|
|
134
|
+
// String attributes
|
|
88
135
|
if (maxHeight) webComponentProps['max-height'] = maxHeight;
|
|
136
|
+
if (nearEdgeThreshold != null) webComponentProps['near-edge-threshold'] = String(nearEdgeThreshold);
|
|
89
137
|
|
|
90
|
-
//
|
|
138
|
+
// Boolean attributes
|
|
91
139
|
if (shadow !== undefined && !coerceBool(shadow)) webComponentProps.shadow = 'false';
|
|
92
140
|
if (isHideScrollbar) webComponentProps['hide-scrollbar'] = '';
|
|
141
|
+
if (isCustomScrollbar) webComponentProps['custom-scrollbar'] = '';
|
|
142
|
+
if (isOverflowX) webComponentProps['overflow-x'] = '';
|
|
143
|
+
if (isScrollAnchoring) webComponentProps['scroll-anchoring'] = '';
|
|
93
144
|
|
|
94
145
|
return React.createElement(
|
|
95
146
|
'ty-scroll-container',
|