tyrell-react 1.0.0-TC25 → 1.0.0-TC27

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.
Files changed (54) hide show
  1. package/dist/components/TyCalendar.d.ts +4 -0
  2. package/dist/components/TyCalendar.d.ts.map +1 -1
  3. package/dist/components/TyCalendar.js +7 -1
  4. package/dist/components/TyCalendar.js.map +1 -1
  5. package/dist/components/TyCalendarMonth.d.ts +4 -0
  6. package/dist/components/TyCalendarMonth.d.ts.map +1 -1
  7. package/dist/components/TyCalendarMonth.js +5 -1
  8. package/dist/components/TyCalendarMonth.js.map +1 -1
  9. package/dist/components/TyCalendarNavigation.d.ts +4 -0
  10. package/dist/components/TyCalendarNavigation.d.ts.map +1 -1
  11. package/dist/components/TyCalendarNavigation.js +5 -1
  12. package/dist/components/TyCalendarNavigation.js.map +1 -1
  13. package/dist/components/TyCheckbox.d.ts +2 -0
  14. package/dist/components/TyCheckbox.d.ts.map +1 -1
  15. package/dist/components/TyCheckbox.js +4 -1
  16. package/dist/components/TyCheckbox.js.map +1 -1
  17. package/dist/components/TyDatePicker.d.ts +4 -0
  18. package/dist/components/TyDatePicker.d.ts.map +1 -1
  19. package/dist/components/TyDatePicker.js +7 -1
  20. package/dist/components/TyDatePicker.js.map +1 -1
  21. package/dist/components/TyOption.d.ts +8 -0
  22. package/dist/components/TyOption.d.ts.map +1 -1
  23. package/dist/components/TyOption.js +3 -1
  24. package/dist/components/TyOption.js.map +1 -1
  25. package/dist/components/TySelect.d.ts +75 -0
  26. package/dist/components/TySelect.d.ts.map +1 -0
  27. package/dist/components/{TyMultiselect.js → TySelect.js} +54 -43
  28. package/dist/components/TySelect.js.map +1 -0
  29. package/dist/components/index.d.ts +6 -8
  30. package/dist/components/index.d.ts.map +1 -1
  31. package/dist/components/index.js +5 -4
  32. package/dist/components/index.js.map +1 -1
  33. package/dist/version.d.ts +1 -1
  34. package/dist/version.js +1 -1
  35. package/package.json +1 -1
  36. package/src/components/TyCalendar.tsx +16 -0
  37. package/src/components/TyCalendarMonth.tsx +11 -1
  38. package/src/components/TyCalendarNavigation.tsx +11 -1
  39. package/src/components/TyCheckbox.tsx +8 -2
  40. package/src/components/TyDatePicker.tsx +16 -0
  41. package/src/components/TyOption.tsx +14 -1
  42. package/src/components/TySelect.tsx +240 -0
  43. package/src/components/index.ts +8 -13
  44. package/src/version.ts +1 -1
  45. package/dist/components/TyDropdown.d.ts +0 -64
  46. package/dist/components/TyDropdown.d.ts.map +0 -1
  47. package/dist/components/TyDropdown.js +0 -136
  48. package/dist/components/TyDropdown.js.map +0 -1
  49. package/dist/components/TyMultiselect.d.ts +0 -59
  50. package/dist/components/TyMultiselect.d.ts.map +0 -1
  51. package/dist/components/TyMultiselect.js.map +0 -1
  52. package/src/components/EventConventionTest.tsx +0 -155
  53. package/src/components/TyDropdown.tsx +0 -252
  54. package/src/components/TyMultiselect.tsx +0 -219
@@ -44,9 +44,6 @@ export type { TyInputProps, TyInputEventDetail, TyInputCSSProperties } from './T
44
44
  export { TyTextarea } from './TyTextarea';
45
45
  export type { TyTextareaProps, TyTextareaEventDetail } from './TyTextarea';
46
46
 
47
- export { TyDropdown } from './TyDropdown';
48
- export type { TyDropdownProps, TyDropdownEventDetail } from './TyDropdown';
49
-
50
47
  export { TyOption } from './TyOption';
51
48
  export type { TyOptionProps } from './TyOption';
52
49
 
@@ -55,12 +52,15 @@ export type { TyIconProps } from './TyIcon';
55
52
 
56
53
  export { TyModal } from './TyModal';
57
54
  export type { TyModalProps, TyModalEventDetail, TyModalRef } from './TyModal';
55
+ // Platform/ARIA name alias (the element is also registered as ty-dialog)
56
+ export { TyModal as TyDialog } from './TyModal';
57
+ export type { TyModalProps as TyDialogProps, TyModalEventDetail as TyDialogEventDetail, TyModalRef as TyDialogRef } from './TyModal';
58
58
 
59
59
  export { TyTooltip } from './TyTooltip';
60
60
  export type { TyTooltipProps } from './TyTooltip';
61
61
 
62
- export { TyMultiselect } from './TyMultiselect';
63
- export type { TyMultiselectProps, TyMultiselectEventDetail } from './TyMultiselect';
62
+ export { TySelect, TySelectedTags } from './TySelect';
63
+ export type { TySelectProps, TySelectEventDetail, TySelectItem, TySelectedTagsProps } from './TySelect';
64
64
 
65
65
  export { TyCalendar } from './TyCalendar';
66
66
  export type { TyCalendarProps, TyCalendarChangeEventDetail, TyCalendarNavigateEventDetail } from './TyCalendar';
@@ -85,6 +85,9 @@ export type { TyRadioGroupProps, TyRadioGroupEventDetail } from './TyRadioGroup'
85
85
 
86
86
  export { TyCopy } from './TyCopy';
87
87
  export type { TyCopyProps } from './TyCopy';
88
+ // Descriptive name alias (the element is also registered as ty-copy-field)
89
+ export { TyCopy as TyCopyField } from './TyCopy';
90
+ export type { TyCopyProps as TyCopyFieldProps } from './TyCopy';
88
91
 
89
92
  export { TyFileUpload } from './TyFileUpload';
90
93
  export type { TyFileUploadProps, TyFileUploadEventDetail } from './TyFileUpload';
@@ -122,12 +125,10 @@ export { TyButton as Button } from './TyButton';
122
125
  export { TyTag as Tag } from './TyTag';
123
126
  export { TyInput as Input } from './TyInput';
124
127
  export { TyTextarea as Textarea } from './TyTextarea';
125
- export { TyDropdown as Dropdown } from './TyDropdown';
126
128
  export { TyOption as Option } from './TyOption';
127
129
  export { TyIcon as Icon } from './TyIcon';
128
130
  export { TyModal as Modal } from './TyModal';
129
131
  export { TyTooltip as Tooltip } from './TyTooltip';
130
- export { TyMultiselect as Multiselect } from './TyMultiselect';
131
132
  export { TyCalendar as Calendar } from './TyCalendar';
132
133
  export { TyDatePicker as DatePicker } from './TyDatePicker';
133
134
  export { TyPopup as Popup } from './TyPopup';
@@ -162,9 +163,6 @@ export type { TyInputProps as InputProps, TyInputEventDetail as InputEventDetail
162
163
  // Textarea types
163
164
  export type { TyTextareaProps as TextareaProps, TyTextareaEventDetail as TextareaEventDetail } from './TyTextarea';
164
165
 
165
- // Dropdown types
166
- export type { TyDropdownProps as DropdownProps, TyDropdownEventDetail as DropdownEventDetail, OptionData } from './TyDropdown';
167
-
168
166
  // Option types
169
167
  export type { TyOptionProps as OptionProps } from './TyOption';
170
168
 
@@ -177,9 +175,6 @@ export type { TyModalProps as ModalProps, TyModalEventDetail as ModalEventDetail
177
175
  // Tooltip types
178
176
  export type { TyTooltipProps as TooltipProps } from './TyTooltip';
179
177
 
180
- // Multiselect types
181
- export type { TyMultiselectProps as MultiselectProps, TyMultiselectEventDetail as MultiselectEventDetail } from './TyMultiselect';
182
-
183
178
  // Calendar types
184
179
  export type { TyCalendarProps as CalendarProps, TyCalendarChangeEventDetail as CalendarChangeEventDetail, TyCalendarNavigateEventDetail as CalendarNavigateEventDetail } from './TyCalendar';
185
180
 
package/src/version.ts CHANGED
@@ -3,4 +3,4 @@
3
3
  // Run 'npm run generate:version' to regenerate.
4
4
 
5
5
  /** Current version of tyrell-react. Synced with package.json on build. */
6
- export const VERSION = '1.0.0-TC25'
6
+ export const VERSION = '1.0.0-TC27'
@@ -1,64 +0,0 @@
1
- import React from 'react';
2
- export interface OptionData {
3
- value: string;
4
- text: string;
5
- disabled?: boolean;
6
- }
7
- export interface TyDropdownEventDetail {
8
- option: HTMLElement;
9
- }
10
- export interface TyDropdownProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange' | 'style'> {
11
- style?: import('./TyInput').TyInputCSSProperties;
12
- /** Semantic styling variant */
13
- flavor?: 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'neutral';
14
- /** Dropdown size */
15
- size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
16
- /** Selected value */
17
- value?: string;
18
- /** Placeholder text */
19
- placeholder?: string;
20
- /** Dropdown label */
21
- label?: string;
22
- /** Disable the dropdown */
23
- disabled?: boolean;
24
- /**
25
- * Loading state — replaces the open popup options list with a centered
26
- * spinner. Search input stays usable. Pair with `externalSearch` while
27
- * fetching results from a parent-owned data source.
28
- */
29
- loading?: boolean;
30
- /** Make dropdown readonly */
31
- readonly?: boolean;
32
- /** Required field */
33
- required?: boolean;
34
- /** Show clear button */
35
- clearable?: boolean;
36
- /** Disable clear button (alias for clearable={false}) */
37
- notClearable?: boolean;
38
- /** Debounce in milliseconds (0-5000) */
39
- debounce?: number;
40
- /**
41
- * Switch to external (remote) search mode. Default is `false` — the dropdown
42
- * filters its options locally. When `true`, the dropdown stops filtering and
43
- * dispatches `search` events on each keystroke; the parent owns filtering
44
- * and updates the children.
45
- */
46
- externalSearch?: boolean;
47
- /** @deprecated Use `externalSearch` instead. */
48
- notSearchable?: boolean;
49
- /** @deprecated Use `externalSearch` instead. Pass `searchable={false}` was equivalent to `externalSearch={true}`. */
50
- searchable?: boolean;
51
- /** Form field name for form submission */
52
- name?: string;
53
- options?: OptionData[];
54
- onChange?: (event: CustomEvent<TyDropdownEventDetail>) => void;
55
- onSearch?: (event: CustomEvent<{
56
- query: string;
57
- element: HTMLElement;
58
- }>) => void;
59
- onOpen?: (event: CustomEvent) => void;
60
- onClose?: (event: CustomEvent) => void;
61
- children?: React.ReactNode;
62
- }
63
- export declare const TyDropdown: React.ForwardRefExoticComponent<TyDropdownProps & React.RefAttributes<HTMLElement>>;
64
- //# sourceMappingURL=TyDropdown.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TyDropdown.d.ts","sourceRoot":"","sources":["../../src/components/TyDropdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAK9D,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,WAAW,CAAC;CACrB;AAGD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IACpG,KAAK,CAAC,EAAE,OAAO,WAAW,EAAE,oBAAoB,CAAC;IACjD,+BAA+B;IAC/B,MAAM,CAAC,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAEhF,oBAAoB;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAExC,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,wBAAwB;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,yDAAyD;IACzD,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,gDAAgD;IAChD,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,qHAAqH;IACrH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC;IAGvB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,qBAAqB,CAAC,KAAK,IAAI,CAAC;IAC/D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAE,CAAC,KAAK,IAAI,CAAC;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAGvC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAGD,eAAO,MAAM,UAAU,qFA+JtB,CAAC"}
@@ -1,136 +0,0 @@
1
- import React, { useEffect, useRef, useCallback } from 'react';
2
- import { needsPropertyBridge } from '../utils/react-version';
3
- import { useBooleanProperty, coerceBool } from '../utils/use-boolean-prop';
4
- // React wrapper for ty-dropdown web component
5
- export const TyDropdown = React.forwardRef(({ options, children, onChange, onSearch, onOpen, onClose, disabled, loading, externalSearch, notSearchable, searchable, clearable, notClearable, debounce, name, value, ...props }, ref) => {
6
- const elementRef = useRef(null);
7
- const handleChange = useCallback((event) => {
8
- if (onChange) {
9
- onChange(event);
10
- }
11
- }, [onChange]);
12
- const handleSearch = useCallback((event) => {
13
- if (onSearch) {
14
- onSearch(event);
15
- }
16
- }, [onSearch]);
17
- const handleOpen = useCallback((event) => { if (onOpen)
18
- onOpen(event); }, [onOpen]);
19
- const handleClose = useCallback((event) => { if (onClose)
20
- onClose(event); }, [onClose]);
21
- useEffect(() => {
22
- const element = elementRef.current;
23
- if (!element)
24
- return;
25
- // Listen for custom events from ty-dropdown
26
- if (onChange) {
27
- element.addEventListener('change', handleChange);
28
- }
29
- if (onSearch) {
30
- element.addEventListener('search', handleSearch);
31
- }
32
- if (onOpen)
33
- element.addEventListener('open', handleOpen);
34
- if (onClose)
35
- element.addEventListener('close', handleClose);
36
- return () => {
37
- if (onChange) {
38
- element.removeEventListener('change', handleChange);
39
- }
40
- if (onSearch) {
41
- element.removeEventListener('search', handleSearch);
42
- }
43
- if (onOpen)
44
- element.removeEventListener('open', handleOpen);
45
- if (onClose)
46
- element.removeEventListener('close', handleClose);
47
- };
48
- }, [handleChange, handleSearch, handleOpen, handleClose, onChange, onSearch, onOpen, onClose]);
49
- // Imperatively sync `value` to the underlying element's property whenever
50
- // it changes. React 18's prop-to-property bridging for custom elements is
51
- // unreliable for empty strings (programmatic resets), so we set the
52
- // property directly to guarantee the dropdown clears on `value=""`.
53
- // React 19+ handles this natively, so the effect short-circuits there.
54
- useEffect(() => {
55
- if (!needsPropertyBridge)
56
- return;
57
- const element = elementRef.current;
58
- if (!element)
59
- return;
60
- if (element.value !== value) {
61
- element.value = value ?? '';
62
- }
63
- }, [value]);
64
- // Handle ref forwarding
65
- useEffect(() => {
66
- if (ref && elementRef.current) {
67
- if (typeof ref === 'function') {
68
- ref(elementRef.current);
69
- }
70
- else {
71
- ref.current = elementRef.current;
72
- }
73
- }
74
- }, [ref]);
75
- // Render options from data if provided, otherwise use children
76
- const renderContent = () => {
77
- if (options && options.length > 0) {
78
- // Data-driven approach - create ty-option elements
79
- return options.map((option, index) => React.createElement('ty-option', {
80
- key: option.value || index,
81
- value: option.value,
82
- ...(option.disabled && { disabled: "" }),
83
- }, option.text));
84
- }
85
- // Slotted approach - use provided children
86
- return children;
87
- };
88
- // Imperative property sync for boolean props (see use-boolean-prop.ts).
89
- const isDisabled = useBooleanProperty(elementRef, 'disabled', disabled);
90
- const isLoading = useBooleanProperty(elementRef, 'loading', loading);
91
- const isExternalSearch = coerceBool(externalSearch) || coerceBool(notSearchable) || searchable === false;
92
- useBooleanProperty(elementRef, 'externalSearch', isExternalSearch);
93
- // clearable: explicit boolean OR the `notClearable` alias inverts it
94
- const isClearable = clearable !== undefined
95
- ? coerceBool(clearable)
96
- : (coerceBool(notClearable) ? false : undefined);
97
- useEffect(() => {
98
- if (!needsPropertyBridge)
99
- return;
100
- if (isClearable === undefined)
101
- return;
102
- const el = elementRef.current;
103
- if (!el)
104
- return;
105
- if (Boolean(el.clearable) !== isClearable)
106
- el.clearable = isClearable;
107
- }, [isClearable]);
108
- // Convert React props to web component attributes
109
- const webComponentProps = {
110
- ...props,
111
- ref: elementRef,
112
- };
113
- if (isDisabled)
114
- webComponentProps.disabled = '';
115
- if (isLoading)
116
- webComponentProps.loading = '';
117
- if (isExternalSearch)
118
- webComponentProps['external-search'] = '';
119
- // Handle clearable functionality
120
- if (isClearable === true) {
121
- webComponentProps.clearable = '';
122
- }
123
- else if (isClearable === false) {
124
- webComponentProps['not-clearable'] = '';
125
- }
126
- // Add debounce attribute
127
- if (debounce !== undefined) {
128
- webComponentProps.debounce = debounce;
129
- }
130
- // Add string attributes
131
- if (name)
132
- webComponentProps.name = name;
133
- return React.createElement('ty-dropdown', webComponentProps, renderContent());
134
- });
135
- TyDropdown.displayName = 'TyDropdown';
136
- //# sourceMappingURL=TyDropdown.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TyDropdown.js","sourceRoot":"","sources":["../../src/components/TyDropdown.tsx"],"names":[],"mappings":"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"}
@@ -1,59 +0,0 @@
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
- onOpen?: (event: CustomEvent) => void;
54
- onClose?: (event: CustomEvent) => void;
55
- /** Children should be TyTag components, not TyOption */
56
- children?: React.ReactNode;
57
- }
58
- export declare const TyMultiselect: React.ForwardRefExoticComponent<TyMultiselectProps & React.RefAttributes<HTMLElement>>;
59
- //# sourceMappingURL=TyMultiselect.d.ts.map
@@ -1 +0,0 @@
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;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;IAEvC,wDAAwD;IACxD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAGD,eAAO,MAAM,aAAa,wFA6IzB,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"TyMultiselect.js","sourceRoot":"","sources":["../../src/components/TyMultiselect.tsx"],"names":[],"mappings":"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"}
@@ -1,155 +0,0 @@
1
- /**
2
- * Test Example: React Event Convention
3
- *
4
- * This file demonstrates the new event handling convention
5
- * for tyrell-react components.
6
- *
7
- * To test:
8
- * 1. Create a new React project or use existing
9
- * 2. npm install tyrell-react
10
- * 3. Add this component to your app
11
- * 4. Observe console logs and state updates
12
- */
13
-
14
- import React, { useState } from 'react';
15
- import { TyInput } from './TyInput';
16
- import { TyTextarea } from './TyTextarea';
17
- import { TyCheckbox } from './TyCheckbox';
18
- import type { TyInputEventDetail } from './TyInput';
19
- import type { TyTextareaEventDetail } from './TyTextarea';
20
- import type { TyCheckboxEventDetail } from './TyCheckbox';
21
-
22
- export function EventConventionTest() {
23
- const [inputValue, setInputValue] = useState('');
24
- const [textareaValue, setTextareaValue] = useState('');
25
- const [checked, setChecked] = useState(false);
26
- const [logs, setLogs] = useState<string[]>([]);
27
-
28
- const addLog = (message: string) => {
29
- setLogs(prev => [...prev, `${new Date().toLocaleTimeString()}: ${message}`]);
30
- };
31
-
32
- return (
33
- <div className="p-8 space-y-6 max-w-2xl">
34
- <h1 className="text-2xl font-bold">React Event Convention Test</h1>
35
-
36
- {/* Input Test */}
37
- <div className="space-y-2">
38
- <h2 className="text-lg font-semibold">TyInput Test</h2>
39
- <TyInput
40
- label="Email"
41
- placeholder="Type to test onChange..."
42
- value={inputValue}
43
- onChange={(e: CustomEvent<TyInputEventDetail>) => {
44
- setInputValue(e.detail.value);
45
- addLog(`onChange: "${e.detail.value}" (fires on keystroke)`);
46
- }}
47
- onChangeCommit={(e: CustomEvent<TyInputEventDetail>) => {
48
- addLog(`onChangeCommit: "${e.detail.value}" (fires on blur)`);
49
- }}
50
- onFocus={() => addLog('onFocus')}
51
- onBlur={() => addLog('onBlur')}
52
- />
53
- <p className="text-sm text-gray-600">
54
- Current value: <strong>{inputValue}</strong>
55
- </p>
56
- </div>
57
-
58
- {/* Textarea Test */}
59
- <div className="space-y-2">
60
- <h2 className="text-lg font-semibold">TyTextarea Test</h2>
61
- <TyTextarea
62
- label="Comments"
63
- placeholder="Type to test onChange..."
64
- value={textareaValue}
65
- rows={3}
66
- onChange={(e: CustomEvent<TyTextareaEventDetail>) => {
67
- setTextareaValue(e.detail.value);
68
- addLog(`Textarea onChange: "${e.detail.value}"`);
69
- }}
70
- onChangeCommit={(e: CustomEvent<TyTextareaEventDetail>) => {
71
- addLog(`Textarea onChangeCommit: "${e.detail.value}"`);
72
- }}
73
- />
74
- <p className="text-sm text-gray-600">
75
- Current value: <strong>{textareaValue}</strong>
76
- </p>
77
- </div>
78
-
79
- {/* Checkbox Test */}
80
- <div className="space-y-2">
81
- <h2 className="text-lg font-semibold">TyCheckbox Test</h2>
82
- <TyCheckbox
83
- checked={checked}
84
- onChange={(e: CustomEvent<TyCheckboxEventDetail>) => {
85
- setChecked(e.detail.checked);
86
- addLog(`Checkbox onChange: ${e.detail.checked} (fires immediately)`);
87
- }}
88
- onChangeCommit={(e: CustomEvent<TyCheckboxEventDetail>) => {
89
- addLog(`Checkbox onChangeCommit: ${e.detail.checked} (fires on blur)`);
90
- }}
91
- >
92
- Subscribe to newsletter
93
- </TyCheckbox>
94
- <p className="text-sm text-gray-600">
95
- Current state: <strong>{checked ? 'Checked' : 'Unchecked'}</strong>
96
- </p>
97
- </div>
98
-
99
- {/* Event Log */}
100
- <div className="space-y-2">
101
- <h2 className="text-lg font-semibold">Event Log</h2>
102
- <div className="bg-gray-100 p-4 rounded max-h-64 overflow-y-auto font-mono text-xs">
103
- {logs.length === 0 ? (
104
- <p className="text-gray-500">No events yet. Start typing or checking boxes!</p>
105
- ) : (
106
- logs.map((log, i) => (
107
- <div key={i} className="text-gray-800">
108
- {log}
109
- </div>
110
- ))
111
- )}
112
- </div>
113
- <button
114
- onClick={() => setLogs([])}
115
- className="px-4 py-2 bg-gray-200 rounded hover:bg-gray-300"
116
- >
117
- Clear Log
118
- </button>
119
- </div>
120
-
121
- {/* Expected Behavior */}
122
- <div className="bg-blue-50 p-4 rounded">
123
- <h3 className="font-semibold mb-2">Expected Behavior:</h3>
124
- <ul className="list-disc list-inside space-y-1 text-sm">
125
- <li>
126
- <strong>onChange</strong> - Fires on every keystroke/state change (React convention)
127
- </li>
128
- <li>
129
- <strong>onChangeCommit</strong> - Fires on blur if value changed (optional)
130
- </li>
131
- <li>
132
- <strong>onFocus</strong> - Fires when element gains focus
133
- </li>
134
- <li>
135
- <strong>onBlur</strong> - Fires when element loses focus
136
- </li>
137
- </ul>
138
- </div>
139
-
140
- {/* Verification */}
141
- <div className="bg-green-50 p-4 rounded">
142
- <h3 className="font-semibold mb-2">Verification Checklist:</h3>
143
- <ul className="list-disc list-inside space-y-1 text-sm">
144
- <li>✅ onChange fires on EVERY keystroke (not just on blur)</li>
145
- <li>✅ State updates in real-time as you type</li>
146
- <li>✅ onChangeCommit fires ONLY on blur (if value changed)</li>
147
- <li>✅ Event order: onChange → onBlur → onChangeCommit</li>
148
- <li>✅ Checkbox onChange fires immediately on click</li>
149
- </ul>
150
- </div>
151
- </div>
152
- );
153
- }
154
-
155
- export default EventConventionTest;