tyrell-react 1.0.0-RC13 → 1.0.0-RC15
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/dist/components/TyButton.d.ts +1 -1
- package/dist/components/TyButton.d.ts.map +1 -1
- package/dist/components/TyCalendar.d.ts +4 -3
- package/dist/components/TyCalendar.d.ts.map +1 -1
- package/dist/components/TyCalendar.js +4 -12
- package/dist/components/TyCalendar.js.map +1 -1
- package/dist/components/TyCalendarMonth.d.ts +1 -1
- package/dist/components/TyCalendarMonth.d.ts.map +1 -1
- package/dist/components/TyCalendarMonth.js +0 -5
- package/dist/components/TyCalendarMonth.js.map +1 -1
- package/dist/components/TyCalendarNavigation.d.ts.map +1 -1
- package/dist/components/TyCalendarNavigation.js +0 -5
- package/dist/components/TyCalendarNavigation.js.map +1 -1
- package/dist/components/TyCheckbox.d.ts +1 -1
- package/dist/components/TyCheckbox.d.ts.map +1 -1
- package/dist/components/TyCheckbox.js +0 -8
- package/dist/components/TyCheckbox.js.map +1 -1
- package/dist/components/TyCopy.d.ts +4 -2
- package/dist/components/TyCopy.d.ts.map +1 -1
- package/dist/components/TyCopy.js +4 -7
- package/dist/components/TyCopy.js.map +1 -1
- package/dist/components/TyDatePicker.d.ts +7 -3
- package/dist/components/TyDatePicker.d.ts.map +1 -1
- package/dist/components/TyDatePicker.js +6 -12
- package/dist/components/TyDatePicker.js.map +1 -1
- package/dist/components/TyFileUpload.d.ts.map +1 -1
- package/dist/components/TyFileUpload.js +0 -1
- package/dist/components/TyFileUpload.js.map +1 -1
- package/dist/components/TyIcon.d.ts.map +1 -1
- package/dist/components/TyIcon.js +0 -4
- package/dist/components/TyIcon.js.map +1 -1
- package/dist/components/TyInput.d.ts +4 -4
- package/dist/components/TyInput.d.ts.map +1 -1
- package/dist/components/TyInput.js +0 -10
- package/dist/components/TyInput.js.map +1 -1
- package/dist/components/TyModal.d.ts +16 -2
- package/dist/components/TyModal.d.ts.map +1 -1
- package/dist/components/TyModal.js +17 -17
- package/dist/components/TyModal.js.map +1 -1
- package/dist/components/TyOption.d.ts +1 -1
- package/dist/components/TyOption.d.ts.map +1 -1
- package/dist/components/TyOption.js +0 -2
- package/dist/components/TyOption.js.map +1 -1
- package/dist/components/TyPopup.d.ts +4 -2
- package/dist/components/TyPopup.d.ts.map +1 -1
- package/dist/components/TyPopup.js +2 -9
- package/dist/components/TyPopup.js.map +1 -1
- package/dist/components/TyRadio.d.ts +1 -1
- package/dist/components/TyRadio.d.ts.map +1 -1
- package/dist/components/TyRadioGroup.d.ts +1 -1
- package/dist/components/TyRadioGroup.d.ts.map +1 -1
- package/dist/components/TyResizeObserver.d.ts.map +1 -1
- package/dist/components/TyResizeObserver.js +0 -4
- package/dist/components/TyResizeObserver.js.map +1 -1
- package/dist/components/TyScrollContainer.d.ts.map +1 -1
- package/dist/components/TyScrollContainer.js +0 -6
- package/dist/components/TyScrollContainer.js.map +1 -1
- package/dist/components/TySelect.d.ts +13 -11
- package/dist/components/TySelect.d.ts.map +1 -1
- package/dist/components/TySelect.js +5 -12
- package/dist/components/TySelect.js.map +1 -1
- package/dist/components/TyStep.d.ts.map +1 -1
- package/dist/components/TyStep.js +0 -5
- package/dist/components/TyStep.js.map +1 -1
- package/dist/components/TySwitch.d.ts +1 -1
- package/dist/components/TySwitch.d.ts.map +1 -1
- package/dist/components/TyTab.d.ts.map +1 -1
- package/dist/components/TyTab.js +0 -6
- package/dist/components/TyTab.js.map +1 -1
- package/dist/components/TyTabs.d.ts +2 -0
- package/dist/components/TyTabs.d.ts.map +1 -1
- package/dist/components/TyTabs.js +4 -6
- package/dist/components/TyTabs.js.map +1 -1
- package/dist/components/TyTag.d.ts +1 -1
- package/dist/components/TyTag.d.ts.map +1 -1
- package/dist/components/TyTag.js +0 -2
- package/dist/components/TyTag.js.map +1 -1
- package/dist/components/TyTextarea.d.ts.map +1 -1
- package/dist/components/TyTextarea.js +0 -6
- package/dist/components/TyTextarea.js.map +1 -1
- package/dist/components/TyTooltip.d.ts +4 -3
- package/dist/components/TyTooltip.d.ts.map +1 -1
- package/dist/components/TyTooltip.js +0 -4
- package/dist/components/TyTooltip.js.map +1 -1
- package/dist/components/TyWizard.d.ts.map +1 -1
- package/dist/components/TyWizard.js +0 -5
- package/dist/components/TyWizard.js.map +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -62
- package/dist/components/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/components/TyButton.tsx +1 -1
- package/src/components/TyCalendar.tsx +7 -15
- package/src/components/TyCalendarMonth.tsx +1 -7
- package/src/components/TyCalendarNavigation.tsx +0 -6
- package/src/components/TyCheckbox.tsx +1 -10
- package/src/components/TyCopy.tsx +8 -9
- package/src/components/TyDatePicker.tsx +20 -16
- package/src/components/TyFileUpload.tsx +0 -2
- package/src/components/TyIcon.tsx +0 -5
- package/src/components/TyInput.tsx +4 -16
- package/src/components/TyModal.tsx +36 -21
- package/src/components/TyOption.tsx +1 -4
- package/src/components/TyPopup.tsx +10 -13
- package/src/components/TyRadio.tsx +1 -1
- package/src/components/TyRadioGroup.tsx +1 -1
- package/src/components/TyResizeObserver.tsx +0 -5
- package/src/components/TyScrollContainer.tsx +0 -8
- package/src/components/TySelect.tsx +22 -24
- package/src/components/TyStep.tsx +0 -6
- package/src/components/TySwitch.tsx +1 -1
- package/src/components/TyTab.tsx +0 -7
- package/src/components/TyTabs.tsx +6 -6
- package/src/components/TyTag.tsx +1 -4
- package/src/components/TyTextarea.tsx +0 -8
- package/src/components/TyTooltip.tsx +8 -8
- package/src/components/TyWizard.tsx +0 -6
- package/src/components/index.ts +2 -97
- package/src/version.ts +1 -1
|
@@ -3,7 +3,6 @@ import { hostProps } from '../utils/host-props';
|
|
|
3
3
|
import { useBooleanProperty, coerceBool } from '../utils/use-boolean-prop';
|
|
4
4
|
import { needsPropertyBridge } from '../utils/react-version';
|
|
5
5
|
|
|
6
|
-
// Event detail structure for modal events
|
|
7
6
|
export interface TyModalEventDetail {
|
|
8
7
|
reason?: 'programmatic' | 'native' | 'backdrop' | 'escape' | 'close-button';
|
|
9
8
|
returnValue?: string;
|
|
@@ -19,7 +18,6 @@ export interface TyModalBeforeCloseDetail {
|
|
|
19
18
|
reason: 'programmatic' | 'backdrop' | 'escape' | 'close-button' | 'native';
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
// Type definitions for Ty Modal component
|
|
23
21
|
export interface TyModalProps extends React.HTMLAttributes<HTMLElement> {
|
|
24
22
|
/** Controls modal visibility */
|
|
25
23
|
open?: boolean;
|
|
@@ -27,12 +25,28 @@ export interface TyModalProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
27
25
|
/** Show backdrop behind modal (default: true) */
|
|
28
26
|
backdrop?: boolean;
|
|
29
27
|
|
|
30
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated Use `preventOutsideClick` — string-boolean attrs are being
|
|
30
|
+
* phased out. Still works; prevent-* wins when both are set.
|
|
31
|
+
*/
|
|
31
32
|
closeOnOutsideClick?: boolean;
|
|
32
33
|
|
|
33
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* @deprecated Use `preventEscape` — string-boolean attrs are being phased
|
|
36
|
+
* out. Still works; prevent-* wins when both are set.
|
|
37
|
+
*/
|
|
34
38
|
closeOnEscape?: boolean;
|
|
35
39
|
|
|
40
|
+
/** Backdrop clicks no longer close the modal (also hides the built-in ✕) */
|
|
41
|
+
preventOutsideClick?: boolean;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* ESC no longer closes the modal (keydown is consumed, so the browser's
|
|
45
|
+
* double-ESC anti-trap never fires). A fully guarded modal must render its
|
|
46
|
+
* own close control — WCAG 2.1.2.
|
|
47
|
+
*/
|
|
48
|
+
preventEscape?: boolean;
|
|
49
|
+
|
|
36
50
|
/**
|
|
37
51
|
* Accessible name — sets aria-label on the internal <dialog>. The dialog
|
|
38
52
|
* gets role="dialog" for free, but nothing names it unless you set this.
|
|
@@ -52,7 +66,6 @@ export interface TyModalProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
52
66
|
children?: React.ReactNode;
|
|
53
67
|
}
|
|
54
68
|
|
|
55
|
-
// Ref interface for imperative methods
|
|
56
69
|
export interface TyModalRef {
|
|
57
70
|
show: () => void;
|
|
58
71
|
/**
|
|
@@ -64,13 +77,14 @@ export interface TyModalRef {
|
|
|
64
77
|
element: HTMLElement | null;
|
|
65
78
|
}
|
|
66
79
|
|
|
67
|
-
// React wrapper for ty-modal web component
|
|
68
80
|
export const TyModal = React.forwardRef<TyModalRef, TyModalProps>(
|
|
69
81
|
({
|
|
70
82
|
open,
|
|
71
83
|
backdrop,
|
|
72
84
|
closeOnOutsideClick,
|
|
73
85
|
closeOnEscape,
|
|
86
|
+
preventOutsideClick,
|
|
87
|
+
preventEscape,
|
|
74
88
|
label,
|
|
75
89
|
onOpen,
|
|
76
90
|
onClose,
|
|
@@ -80,7 +94,6 @@ export const TyModal = React.forwardRef<TyModalRef, TyModalProps>(
|
|
|
80
94
|
}, ref) => {
|
|
81
95
|
const elementRef = useRef<HTMLElement>(null);
|
|
82
96
|
|
|
83
|
-
// Expose imperative methods through ref
|
|
84
97
|
useImperativeHandle(ref, () => ({
|
|
85
98
|
show: () => {
|
|
86
99
|
if (elementRef.current && typeof (elementRef.current as any).show === 'function') {
|
|
@@ -95,17 +108,12 @@ export const TyModal = React.forwardRef<TyModalRef, TyModalProps>(
|
|
|
95
108
|
element: elementRef.current,
|
|
96
109
|
}), []);
|
|
97
110
|
|
|
98
|
-
//
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
// type, same listener. Without the `event.target === element` guard, an
|
|
105
|
-
// `onClose={() => setIsOpen(false)}` callback would fire every time the
|
|
106
|
-
// user closes a dropdown inside the modal, and the React state flip
|
|
107
|
-
// would close the modal. Core's modal.ts already applies the same guard
|
|
108
|
-
// on its internal <dialog>.onclose; this is the React-layer mirror.
|
|
111
|
+
// Popup lifecycle events (`open`/`close`, plus `beforeclose` on the modal)
|
|
112
|
+
// no longer bubble — core dispatches them non-composed on the element
|
|
113
|
+
// itself, like the native <dialog> events they mirror, so a dropdown or
|
|
114
|
+
// nested modal closing inside this one can't reach these listeners. The
|
|
115
|
+
// `event.target === element` guard stays as belt-and-braces for consumers
|
|
116
|
+
// pinned to an older tyrell-components.
|
|
109
117
|
useEffect(() => {
|
|
110
118
|
const element = elementRef.current;
|
|
111
119
|
if (!element) return;
|
|
@@ -125,7 +133,6 @@ export const TyModal = React.forwardRef<TyModalRef, TyModalProps>(
|
|
|
125
133
|
if (onBeforeClose) onBeforeClose(event);
|
|
126
134
|
};
|
|
127
135
|
|
|
128
|
-
// Listen for custom modal events
|
|
129
136
|
if (onOpen) {
|
|
130
137
|
element.addEventListener('open', handleOpen as EventListener);
|
|
131
138
|
}
|
|
@@ -170,9 +177,10 @@ export const TyModal = React.forwardRef<TyModalRef, TyModalProps>(
|
|
|
170
177
|
setIf('backdrop', backdrop);
|
|
171
178
|
setIf('closeOnOutsideClick', closeOnOutsideClick);
|
|
172
179
|
setIf('closeOnEscape', closeOnEscape);
|
|
173
|
-
|
|
180
|
+
setIf('preventOutsideClick', preventOutsideClick);
|
|
181
|
+
setIf('preventEscape', preventEscape);
|
|
182
|
+
}, [backdrop, closeOnOutsideClick, closeOnEscape, preventOutsideClick, preventEscape]);
|
|
174
183
|
|
|
175
|
-
// Convert React props to web component attributes
|
|
176
184
|
const webComponentProps: Record<string, any> = {
|
|
177
185
|
...hostProps(props),
|
|
178
186
|
ref: elementRef,
|
|
@@ -191,6 +199,13 @@ export const TyModal = React.forwardRef<TyModalRef, TyModalProps>(
|
|
|
191
199
|
if (closeOnEscape !== undefined && !coerceBool(closeOnEscape)) {
|
|
192
200
|
webComponentProps['close-on-escape'] = 'false';
|
|
193
201
|
}
|
|
202
|
+
// Presence booleans: render the bare attribute only when true
|
|
203
|
+
if (preventOutsideClick !== undefined && coerceBool(preventOutsideClick)) {
|
|
204
|
+
webComponentProps['prevent-outside-click'] = '';
|
|
205
|
+
}
|
|
206
|
+
if (preventEscape !== undefined && coerceBool(preventEscape)) {
|
|
207
|
+
webComponentProps['prevent-escape'] = '';
|
|
208
|
+
}
|
|
194
209
|
if (label) webComponentProps.label = label;
|
|
195
210
|
|
|
196
211
|
return React.createElement(
|
|
@@ -2,7 +2,6 @@ import React, { useEffect, useRef } from 'react';
|
|
|
2
2
|
import { hostProps } from '../utils/host-props';
|
|
3
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
4
|
|
|
5
|
-
// Type definitions for Ty Option component
|
|
6
5
|
export interface TyOptionProps extends React.HTMLAttributes<HTMLElement> {
|
|
7
6
|
value?: string;
|
|
8
7
|
|
|
@@ -14,7 +13,7 @@ export interface TyOptionProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
14
13
|
label?: string;
|
|
15
14
|
|
|
16
15
|
/** Semantic flavor — carried onto ty-selected-options chips */
|
|
17
|
-
flavor?: 'primary' | '
|
|
16
|
+
flavor?: 'primary' | 'success' | 'danger' | 'warning' | 'neutral' | 'info';
|
|
18
17
|
|
|
19
18
|
disabled?: boolean;
|
|
20
19
|
selected?: boolean;
|
|
@@ -22,12 +21,10 @@ export interface TyOptionProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
22
21
|
children?: React.ReactNode;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
// React wrapper for ty-option web component
|
|
26
24
|
export const TyOption = React.forwardRef<HTMLElement, TyOptionProps>(
|
|
27
25
|
({ children, label, flavor, disabled, selected, hidden, ...props }, ref) => {
|
|
28
26
|
const elementRef = useRef<HTMLElement>(null);
|
|
29
27
|
|
|
30
|
-
// Handle ref forwarding
|
|
31
28
|
useEffect(() => {
|
|
32
29
|
if (ref && elementRef.current) {
|
|
33
30
|
if (typeof ref === 'function') {
|
|
@@ -2,10 +2,15 @@ import React, { useEffect, useRef } from 'react';
|
|
|
2
2
|
import { hostProps } from '../utils/host-props';
|
|
3
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
type Placement =
|
|
6
|
+
| 'top-start' | 'top' | 'top-end'
|
|
7
|
+
| 'right-start' | 'right' | 'right-end'
|
|
8
|
+
| 'bottom-start' | 'bottom' | 'bottom-end'
|
|
9
|
+
| 'left-start' | 'left' | 'left-end';
|
|
10
|
+
|
|
6
11
|
export interface TyPopupProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onClose'> {
|
|
7
|
-
/** Preferred placement of the popup relative to anchor parent:
|
|
8
|
-
placement?:
|
|
12
|
+
/** Preferred placement of the popup relative to anchor parent: a side plus an optional cross-axis alignment (e.g. "bottom-start") */
|
|
13
|
+
placement?: Placement;
|
|
9
14
|
|
|
10
15
|
/** Distance offset from the anchor in pixels (default: 8) */
|
|
11
16
|
offset?: number;
|
|
@@ -26,14 +31,12 @@ export interface TyPopupProps extends Omit<React.HTMLAttributes<HTMLElement>, 'o
|
|
|
26
31
|
children?: React.ReactNode;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
// Programmatic API for popup control
|
|
30
34
|
export interface TyPopupElement extends HTMLElement {
|
|
31
35
|
openPopup(): void;
|
|
32
36
|
closePopup(): void;
|
|
33
37
|
togglePopup(): void;
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
// React wrapper for ty-popup web component
|
|
37
40
|
export const TyPopup = React.forwardRef<TyPopupElement, TyPopupProps>(
|
|
38
41
|
({
|
|
39
42
|
placement,
|
|
@@ -47,7 +50,6 @@ export const TyPopup = React.forwardRef<TyPopupElement, TyPopupProps>(
|
|
|
47
50
|
}, ref) => {
|
|
48
51
|
const elementRef = useRef<TyPopupElement>(null);
|
|
49
52
|
|
|
50
|
-
// Handle ref forwarding
|
|
51
53
|
useEffect(() => {
|
|
52
54
|
if (ref && elementRef.current) {
|
|
53
55
|
if (typeof ref === 'function') {
|
|
@@ -58,11 +60,8 @@ export const TyPopup = React.forwardRef<TyPopupElement, TyPopupProps>(
|
|
|
58
60
|
}
|
|
59
61
|
}, [ref]);
|
|
60
62
|
|
|
61
|
-
// Listen for popup open/close events.
|
|
62
|
-
//
|
|
63
|
-
// from popup-like descendants (ty-dropdown, ty-multiselect, ty-date-picker
|
|
64
|
-
// when slotted inside this popup) don't fire the consumer's onOpen/onClose.
|
|
65
|
-
// See TyModal.tsx for the same pattern + rationale.
|
|
63
|
+
// Listen for popup open/close events. See TyModal.tsx for why the
|
|
64
|
+
// `event.target === element` guard is still here.
|
|
66
65
|
useEffect(() => {
|
|
67
66
|
const element = elementRef.current;
|
|
68
67
|
if (!element) return;
|
|
@@ -85,13 +84,11 @@ export const TyPopup = React.forwardRef<TyPopupElement, TyPopupProps>(
|
|
|
85
84
|
};
|
|
86
85
|
}, [onOpen, onClose]);
|
|
87
86
|
|
|
88
|
-
// Convert React props to web component attributes
|
|
89
87
|
const webComponentProps: Record<string, any> = {
|
|
90
88
|
...hostProps(props),
|
|
91
89
|
ref: elementRef,
|
|
92
90
|
};
|
|
93
91
|
|
|
94
|
-
// Add optional attributes only if they have values
|
|
95
92
|
if (placement) {
|
|
96
93
|
webComponentProps.placement = placement;
|
|
97
94
|
}
|
|
@@ -2,7 +2,7 @@ import React, { useEffect, useRef } from 'react';
|
|
|
2
2
|
import { hostProps } from '../utils/host-props';
|
|
3
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
4
|
|
|
5
|
-
type BuiltinFlavor = 'primary' | '
|
|
5
|
+
type BuiltinFlavor = 'primary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
6
6
|
type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
|
|
7
7
|
|
|
8
8
|
export interface TyRadioProps extends React.HTMLAttributes<HTMLElement> {
|
|
@@ -2,7 +2,7 @@ import React, { useEffect, useRef } from 'react';
|
|
|
2
2
|
import { hostProps } from '../utils/host-props';
|
|
3
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
4
|
|
|
5
|
-
type BuiltinFlavor = 'primary' | '
|
|
5
|
+
type BuiltinFlavor = 'primary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
6
6
|
type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
|
|
7
7
|
|
|
8
8
|
export interface TyRadioGroupProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange' | 'onInput'> {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { hostProps } from '../utils/host-props';
|
|
3
3
|
|
|
4
|
-
// Type definitions for Ty ResizeObserver component
|
|
5
4
|
export interface TyResizeObserverProps extends React.HTMLAttributes<HTMLElement> {
|
|
6
5
|
/** Required unique identifier for size registry */
|
|
7
6
|
id: string;
|
|
@@ -13,7 +12,6 @@ export interface TyResizeObserverProps extends React.HTMLAttributes<HTMLElement>
|
|
|
13
12
|
children?: React.ReactNode;
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
// React wrapper for ty-resize-observer web component
|
|
17
15
|
export const TyResizeObserver = React.forwardRef<HTMLElement, TyResizeObserverProps>(
|
|
18
16
|
({
|
|
19
17
|
children,
|
|
@@ -23,7 +21,6 @@ export const TyResizeObserver = React.forwardRef<HTMLElement, TyResizeObserverPr
|
|
|
23
21
|
}, ref) => {
|
|
24
22
|
const elementRef = useRef<HTMLElement>(null);
|
|
25
23
|
|
|
26
|
-
// Combine refs if needed
|
|
27
24
|
useEffect(() => {
|
|
28
25
|
if (ref && elementRef.current) {
|
|
29
26
|
if (typeof ref === 'function') {
|
|
@@ -34,14 +31,12 @@ export const TyResizeObserver = React.forwardRef<HTMLElement, TyResizeObserverPr
|
|
|
34
31
|
}
|
|
35
32
|
}, [ref]);
|
|
36
33
|
|
|
37
|
-
// Convert React props to web component attributes
|
|
38
34
|
const webComponentProps: Record<string, any> = {
|
|
39
35
|
...hostProps(props),
|
|
40
36
|
ref: elementRef,
|
|
41
37
|
id,
|
|
42
38
|
};
|
|
43
39
|
|
|
44
|
-
// Add number attributes
|
|
45
40
|
if (debounce !== undefined) webComponentProps.debounce = debounce;
|
|
46
41
|
|
|
47
42
|
return React.createElement(
|
|
@@ -11,7 +11,6 @@ export interface TyScrollNearEdgeDetail {
|
|
|
11
11
|
clientHeight: number;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
// Type definitions for Ty ScrollContainer component
|
|
15
14
|
export interface TyScrollContainerProps extends React.HTMLAttributes<HTMLElement> {
|
|
16
15
|
/** Maximum height of the scroll container */
|
|
17
16
|
maxHeight?: string;
|
|
@@ -44,7 +43,6 @@ export interface TyScrollContainerProps extends React.HTMLAttributes<HTMLElement
|
|
|
44
43
|
children?: React.ReactNode;
|
|
45
44
|
}
|
|
46
45
|
|
|
47
|
-
// Ref interface for imperative methods
|
|
48
46
|
export interface TyScrollContainerRef {
|
|
49
47
|
/** Force update shadows (useful after dynamic content changes) */
|
|
50
48
|
updateShadows: () => void;
|
|
@@ -64,7 +62,6 @@ export interface TyScrollContainerRef {
|
|
|
64
62
|
element: HTMLElement | null;
|
|
65
63
|
}
|
|
66
64
|
|
|
67
|
-
// React wrapper for ty-scroll-container web component
|
|
68
65
|
export const TyScrollContainer = React.forwardRef<TyScrollContainerRef, TyScrollContainerProps>(
|
|
69
66
|
({
|
|
70
67
|
children,
|
|
@@ -81,7 +78,6 @@ export const TyScrollContainer = React.forwardRef<TyScrollContainerRef, TyScroll
|
|
|
81
78
|
}, ref) => {
|
|
82
79
|
const elementRef = useRef<HTMLElement>(null);
|
|
83
80
|
|
|
84
|
-
// Expose imperative methods via ref
|
|
85
81
|
useImperativeHandle(ref, () => ({
|
|
86
82
|
updateShadows: () => { (elementRef.current as any)?.updateShadows?.(); },
|
|
87
83
|
scrollToTop: (smooth = true) => { (elementRef.current as any)?.scrollToTop?.(smooth); },
|
|
@@ -109,7 +105,6 @@ export const TyScrollContainer = React.forwardRef<TyScrollContainerRef, TyScroll
|
|
|
109
105
|
const isOverflowX = useBooleanProperty(elementRef, 'overflowX', overflowX);
|
|
110
106
|
const isScrollAnchoring = useBooleanProperty(elementRef, 'scrollAnchoring', scrollAnchoring);
|
|
111
107
|
|
|
112
|
-
// Custom events → React callbacks
|
|
113
108
|
useEffect(() => {
|
|
114
109
|
const el = elementRef.current;
|
|
115
110
|
if (!el) return;
|
|
@@ -125,17 +120,14 @@ export const TyScrollContainer = React.forwardRef<TyScrollContainerRef, TyScroll
|
|
|
125
120
|
return () => bound.forEach(([n, h]) => el.removeEventListener(n, h));
|
|
126
121
|
}, [onNearEnd, onNearStart]);
|
|
127
122
|
|
|
128
|
-
// Convert React props to web component attributes
|
|
129
123
|
const webComponentProps: Record<string, any> = {
|
|
130
124
|
...hostProps(props),
|
|
131
125
|
ref: elementRef,
|
|
132
126
|
};
|
|
133
127
|
|
|
134
|
-
// String attributes
|
|
135
128
|
if (maxHeight) webComponentProps['max-height'] = maxHeight;
|
|
136
129
|
if (nearEdgeThreshold != null) webComponentProps['near-edge-threshold'] = String(nearEdgeThreshold);
|
|
137
130
|
|
|
138
|
-
// Boolean attributes
|
|
139
131
|
if (shadow !== undefined && !coerceBool(shadow)) webComponentProps.shadow = 'false';
|
|
140
132
|
if (isHideScrollbar) webComponentProps['hide-scrollbar'] = '';
|
|
141
133
|
if (isCustomScrollbar) webComponentProps['custom-scrollbar'] = '';
|
|
@@ -3,10 +3,14 @@ import { hostProps } from '../utils/host-props';
|
|
|
3
3
|
import { needsPropertyBridge } from '../utils/react-version';
|
|
4
4
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
5
5
|
|
|
6
|
-
type BuiltinFlavor = 'primary' | '
|
|
6
|
+
type BuiltinFlavor = 'primary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
7
7
|
type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
|
|
8
|
+
type Placement =
|
|
9
|
+
| 'top-start' | 'top' | 'top-end'
|
|
10
|
+
| 'right-start' | 'right' | 'right-end'
|
|
11
|
+
| 'bottom-start' | 'bottom' | 'bottom-end'
|
|
12
|
+
| 'left-start' | 'left' | 'left-end';
|
|
8
13
|
|
|
9
|
-
// Type definitions for Ty Select component
|
|
10
14
|
export interface TySelectItem {
|
|
11
15
|
value: string;
|
|
12
16
|
label: string;
|
|
@@ -56,11 +60,10 @@ export interface TySelectProps extends Omit<React.HTMLAttributes<HTMLElement>, '
|
|
|
56
60
|
/** Mark the field as required */
|
|
57
61
|
required?: boolean;
|
|
58
62
|
|
|
59
|
-
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
|
|
63
|
-
searchable?: 'auto' | 'always' | 'never' | boolean;
|
|
63
|
+
/** Drop the popup search row. A select is searchable by default; this is
|
|
64
|
+
* the single opt-out. Cannot override externalSearch/allowCreate, where
|
|
65
|
+
* the input is the only way to get a query out. */
|
|
66
|
+
notSearchable?: boolean;
|
|
64
67
|
|
|
65
68
|
/**
|
|
66
69
|
* External (remote) search mode — the component stops filtering and emits
|
|
@@ -89,12 +92,15 @@ export interface TySelectProps extends Omit<React.HTMLAttributes<HTMLElement>, '
|
|
|
89
92
|
/** Loading state — shows a spinner in the options area (external search in flight) */
|
|
90
93
|
loading?: boolean;
|
|
91
94
|
|
|
92
|
-
/**
|
|
93
|
-
|
|
94
|
-
size?: 'sm' | 'md' | 'lg';
|
|
95
|
+
/** Field size — the ladder shared by every field component
|
|
96
|
+
* (styles/field-size.ts). Defaults to 'sm'. */
|
|
97
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
98
|
+
|
|
99
|
+
/** Horizontal popup anchor: "start" (default, trigger's left edge), "center", or "end" (trigger's right edge) — clamped into the viewport either way. Useful with a custom slot="trigger" element. Ignored when `placement` is set. */
|
|
100
|
+
align?: 'start' | 'center' | 'end';
|
|
95
101
|
|
|
96
|
-
/**
|
|
97
|
-
|
|
102
|
+
/** Full placement, same vocabulary as ty-popup/ty-tooltip: a side plus an optional cross-axis alignment (e.g. "bottom-end"). Takes precedence over `align` when set. */
|
|
103
|
+
placement?: Placement;
|
|
98
104
|
|
|
99
105
|
/** Built-in x clear button in the default/compact trigger, shown once something is selected. Default true. Not shown with slot="trigger" — use the ref's clear() method there instead. */
|
|
100
106
|
clearable?: boolean;
|
|
@@ -126,7 +132,6 @@ export interface TySelectElement extends HTMLElement {
|
|
|
126
132
|
clear(): void;
|
|
127
133
|
}
|
|
128
134
|
|
|
129
|
-
// React wrapper for ty-select web component
|
|
130
135
|
export const TySelect = React.forwardRef<TySelectElement, TySelectProps>(
|
|
131
136
|
({
|
|
132
137
|
value,
|
|
@@ -138,7 +143,7 @@ export const TySelect = React.forwardRef<TySelectElement, TySelectProps>(
|
|
|
138
143
|
disabled,
|
|
139
144
|
readonly,
|
|
140
145
|
required,
|
|
141
|
-
|
|
146
|
+
notSearchable,
|
|
142
147
|
externalSearch,
|
|
143
148
|
debounce,
|
|
144
149
|
allowCreate,
|
|
@@ -146,6 +151,7 @@ export const TySelect = React.forwardRef<TySelectElement, TySelectProps>(
|
|
|
146
151
|
loading,
|
|
147
152
|
size,
|
|
148
153
|
align,
|
|
154
|
+
placement,
|
|
149
155
|
clearable,
|
|
150
156
|
flavor,
|
|
151
157
|
onChange,
|
|
@@ -158,7 +164,6 @@ export const TySelect = React.forwardRef<TySelectElement, TySelectProps>(
|
|
|
158
164
|
}, ref) => {
|
|
159
165
|
const elementRef = useRef<TySelectElement>(null);
|
|
160
166
|
|
|
161
|
-
// Handle ref forwarding
|
|
162
167
|
useEffect(() => {
|
|
163
168
|
if (ref && elementRef.current) {
|
|
164
169
|
if (typeof ref === 'function') {
|
|
@@ -181,7 +186,6 @@ export const TySelect = React.forwardRef<TySelectElement, TySelectProps>(
|
|
|
181
186
|
}
|
|
182
187
|
}, [value]);
|
|
183
188
|
|
|
184
|
-
// Handle events
|
|
185
189
|
const handleChange = useCallback((event: Event) => {
|
|
186
190
|
if (onChange) onChange(event as CustomEvent<TySelectEventDetail>);
|
|
187
191
|
}, [onChange]);
|
|
@@ -196,7 +200,6 @@ export const TySelect = React.forwardRef<TySelectElement, TySelectProps>(
|
|
|
196
200
|
if (onCreate) onCreate(event as CustomEvent<{ value: string; label: string }>);
|
|
197
201
|
}, [onCreate]);
|
|
198
202
|
|
|
199
|
-
// Set up event listeners
|
|
200
203
|
useEffect(() => {
|
|
201
204
|
const element = elementRef.current;
|
|
202
205
|
if (!element) return;
|
|
@@ -227,13 +230,11 @@ export const TySelect = React.forwardRef<TySelectElement, TySelectProps>(
|
|
|
227
230
|
const isAllowCreate = useBooleanProperty(elementRef, 'allowCreate', allowCreate);
|
|
228
231
|
const isClearable = useBooleanProperty(elementRef, 'clearable', clearable);
|
|
229
232
|
|
|
230
|
-
// Convert React props to web component attributes
|
|
231
233
|
const webComponentProps: Record<string, any> = {
|
|
232
234
|
...hostProps(props),
|
|
233
235
|
ref: elementRef,
|
|
234
236
|
};
|
|
235
237
|
|
|
236
|
-
// Handle value conversion (array to comma-separated string)
|
|
237
238
|
if (value !== undefined) {
|
|
238
239
|
webComponentProps.value = Array.isArray(value) ? value.join(',') : value;
|
|
239
240
|
}
|
|
@@ -252,13 +253,12 @@ export const TySelect = React.forwardRef<TySelectElement, TySelectProps>(
|
|
|
252
253
|
if (name) webComponentProps.name = name;
|
|
253
254
|
if (size) webComponentProps.size = size;
|
|
254
255
|
if (align) webComponentProps.align = align;
|
|
256
|
+
if (placement) webComponentProps.placement = placement;
|
|
255
257
|
if (isClearable) webComponentProps.clearable = '';
|
|
256
258
|
if (flavor) webComponentProps.flavor = flavor;
|
|
257
259
|
if (debounce !== undefined) webComponentProps.debounce = debounce.toString();
|
|
258
260
|
if (createTransform) webComponentProps['create-transform'] = createTransform;
|
|
259
|
-
if (
|
|
260
|
-
else if (searchable === 'never' || searchable === false) webComponentProps.searchable = 'false';
|
|
261
|
-
// 'auto' / undefined → omit (component default)
|
|
261
|
+
if (notSearchable) webComponentProps['not-searchable'] = '';
|
|
262
262
|
|
|
263
263
|
return React.createElement('ty-select', webComponentProps, children);
|
|
264
264
|
}
|
|
@@ -266,11 +266,9 @@ export const TySelect = React.forwardRef<TySelectElement, TySelectProps>(
|
|
|
266
266
|
|
|
267
267
|
TySelect.displayName = 'TySelect';
|
|
268
268
|
|
|
269
|
-
// ============================================================================
|
|
270
269
|
// TySelectedOptions — out-of-band chip display for a TySelect
|
|
271
270
|
// (ty-selected-tags below is the same element under its original tag name,
|
|
272
271
|
// kept for backward compatibility.)
|
|
273
|
-
// ============================================================================
|
|
274
272
|
|
|
275
273
|
export interface TySelectedTagsProps extends React.HTMLAttributes<HTMLElement> {
|
|
276
274
|
/** id of the ty-select to display. Falls back to the previous element sibling. */
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { hostProps } from '../utils/host-props';
|
|
3
3
|
|
|
4
|
-
// Type definitions for Ty Step component
|
|
5
4
|
export interface TyStepProps extends React.HTMLAttributes<HTMLElement> {
|
|
6
5
|
/** Required unique identifier for the step */
|
|
7
6
|
id: string;
|
|
@@ -22,7 +21,6 @@ export interface TyStepProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
22
21
|
children?: React.ReactNode;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
// React wrapper for ty-step web component
|
|
26
24
|
export const TyStep = React.forwardRef<HTMLElement, TyStepProps>(
|
|
27
25
|
({
|
|
28
26
|
children,
|
|
@@ -35,7 +33,6 @@ export const TyStep = React.forwardRef<HTMLElement, TyStepProps>(
|
|
|
35
33
|
}, ref) => {
|
|
36
34
|
const elementRef = useRef<HTMLElement>(null);
|
|
37
35
|
|
|
38
|
-
// Combine refs if needed
|
|
39
36
|
useEffect(() => {
|
|
40
37
|
if (ref && elementRef.current) {
|
|
41
38
|
if (typeof ref === 'function') {
|
|
@@ -46,19 +43,16 @@ export const TyStep = React.forwardRef<HTMLElement, TyStepProps>(
|
|
|
46
43
|
}
|
|
47
44
|
}, [ref]);
|
|
48
45
|
|
|
49
|
-
// Convert React props to web component attributes
|
|
50
46
|
const webComponentProps: Record<string, any> = {
|
|
51
47
|
...hostProps(props),
|
|
52
48
|
ref: elementRef,
|
|
53
49
|
id,
|
|
54
50
|
};
|
|
55
51
|
|
|
56
|
-
// Add string attributes
|
|
57
52
|
if (label) webComponentProps.label = label;
|
|
58
53
|
if (description) webComponentProps.description = description;
|
|
59
54
|
if (status) webComponentProps.status = status;
|
|
60
55
|
|
|
61
|
-
// Add boolean attributes
|
|
62
56
|
if (disabled) webComponentProps.disabled = true;
|
|
63
57
|
|
|
64
58
|
return React.createElement(
|
|
@@ -2,7 +2,7 @@ import React, { useEffect, useRef } from 'react';
|
|
|
2
2
|
import { hostProps } from '../utils/host-props';
|
|
3
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
4
|
|
|
5
|
-
type BuiltinFlavor = 'primary' | '
|
|
5
|
+
type BuiltinFlavor = 'primary' | 'success' | 'danger' | 'warning' | 'neutral';
|
|
6
6
|
type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
|
|
7
7
|
|
|
8
8
|
export interface TySwitchProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange' | 'onInput'> {
|
package/src/components/TyTab.tsx
CHANGED
|
@@ -2,7 +2,6 @@ import React, { useEffect, useRef } from 'react';
|
|
|
2
2
|
import { hostProps } from '../utils/host-props';
|
|
3
3
|
import { useBooleanProperty } from '../utils/use-boolean-prop';
|
|
4
4
|
|
|
5
|
-
// Type definitions for Ty Tab component
|
|
6
5
|
export interface TyTabProps extends React.HTMLAttributes<HTMLElement> {
|
|
7
6
|
/** Required unique identifier */
|
|
8
7
|
id: string;
|
|
@@ -17,7 +16,6 @@ export interface TyTabProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
17
16
|
children?: React.ReactNode;
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
// React wrapper for ty-tab web component
|
|
21
19
|
export const TyTab = React.forwardRef<HTMLElement, TyTabProps>(
|
|
22
20
|
({
|
|
23
21
|
children,
|
|
@@ -28,7 +26,6 @@ export const TyTab = React.forwardRef<HTMLElement, TyTabProps>(
|
|
|
28
26
|
}, ref) => {
|
|
29
27
|
const elementRef = useRef<HTMLElement>(null);
|
|
30
28
|
|
|
31
|
-
// Combine refs if needed
|
|
32
29
|
useEffect(() => {
|
|
33
30
|
if (ref && elementRef.current) {
|
|
34
31
|
if (typeof ref === 'function') {
|
|
@@ -39,20 +36,16 @@ export const TyTab = React.forwardRef<HTMLElement, TyTabProps>(
|
|
|
39
36
|
}
|
|
40
37
|
}, [ref]);
|
|
41
38
|
|
|
42
|
-
// Convert React props to web component attributes
|
|
43
39
|
const webComponentProps: Record<string, any> = {
|
|
44
40
|
...hostProps(props),
|
|
45
41
|
ref: elementRef,
|
|
46
42
|
};
|
|
47
43
|
|
|
48
|
-
// Add required attribute
|
|
49
44
|
webComponentProps.id = id;
|
|
50
45
|
|
|
51
|
-
// Add boolean attributes
|
|
52
46
|
const isDisabled = useBooleanProperty(elementRef, 'disabled', disabled);
|
|
53
47
|
if (isDisabled) webComponentProps.disabled = '';
|
|
54
48
|
|
|
55
|
-
// Add string attributes
|
|
56
49
|
if (label) webComponentProps.label = label;
|
|
57
50
|
|
|
58
51
|
return React.createElement(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { hostProps } from '../utils/host-props';
|
|
3
3
|
|
|
4
|
-
// Type definitions for Ty Tabs component
|
|
5
4
|
export interface TyTabsProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange'> {
|
|
6
5
|
/** Content area width (accepts px or %) */
|
|
7
6
|
width?: string;
|
|
@@ -15,6 +14,9 @@ export interface TyTabsProps extends Omit<React.HTMLAttributes<HTMLElement>, 'on
|
|
|
15
14
|
/** Position of tab buttons */
|
|
16
15
|
placement?: 'top' | 'bottom';
|
|
17
16
|
|
|
17
|
+
/** Divide the bar equally between the tabs instead of scrolling them */
|
|
18
|
+
fixed?: boolean;
|
|
19
|
+
|
|
18
20
|
/** Tab change event handler */
|
|
19
21
|
onChange?: (event: CustomEvent<TabChangeDetail>) => void;
|
|
20
22
|
|
|
@@ -29,7 +31,6 @@ export interface TabChangeDetail {
|
|
|
29
31
|
previousIndex: number | null;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
// React wrapper for ty-tabs web component
|
|
33
34
|
export const TyTabs = React.forwardRef<HTMLElement, TyTabsProps>(
|
|
34
35
|
({
|
|
35
36
|
children,
|
|
@@ -37,12 +38,12 @@ export const TyTabs = React.forwardRef<HTMLElement, TyTabsProps>(
|
|
|
37
38
|
height,
|
|
38
39
|
active,
|
|
39
40
|
placement,
|
|
41
|
+
fixed,
|
|
40
42
|
onChange,
|
|
41
43
|
...props
|
|
42
44
|
}, ref) => {
|
|
43
45
|
const elementRef = useRef<HTMLElement>(null);
|
|
44
46
|
|
|
45
|
-
// Handle change events
|
|
46
47
|
useEffect(() => {
|
|
47
48
|
const element = elementRef.current;
|
|
48
49
|
if (!element) return;
|
|
@@ -60,7 +61,6 @@ export const TyTabs = React.forwardRef<HTMLElement, TyTabsProps>(
|
|
|
60
61
|
};
|
|
61
62
|
}, [onChange]);
|
|
62
63
|
|
|
63
|
-
// Combine refs if needed
|
|
64
64
|
useEffect(() => {
|
|
65
65
|
if (ref && elementRef.current) {
|
|
66
66
|
if (typeof ref === 'function') {
|
|
@@ -71,17 +71,17 @@ export const TyTabs = React.forwardRef<HTMLElement, TyTabsProps>(
|
|
|
71
71
|
}
|
|
72
72
|
}, [ref]);
|
|
73
73
|
|
|
74
|
-
// Convert React props to web component attributes
|
|
75
74
|
const webComponentProps: Record<string, any> = {
|
|
76
75
|
...hostProps(props),
|
|
77
76
|
ref: elementRef,
|
|
78
77
|
};
|
|
79
78
|
|
|
80
|
-
// Add string attributes
|
|
81
79
|
if (width) webComponentProps.width = width;
|
|
82
80
|
if (height) webComponentProps.height = height;
|
|
83
81
|
if (active) webComponentProps.active = active;
|
|
84
82
|
if (placement) webComponentProps.placement = placement;
|
|
83
|
+
// Presence boolean — render the bare attribute only when true.
|
|
84
|
+
if (fixed) webComponentProps.fixed = '';
|
|
85
85
|
|
|
86
86
|
return React.createElement(
|
|
87
87
|
'ty-tabs',
|