@seed-design/lynx-react 0.5.1 → 0.5.2
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/lib/components/RadioGroup/RadioGroup.d.ts.map +1 -1
- package/lib/components/RadioGroup/RadioGroup.jsx +2 -1
- package/lib/components/Tabs/Tabs.d.ts +1 -1
- package/lib/components/Tabs/Tabs.d.ts.map +1 -1
- package/lib/components/Tabs/Tabs.jsx +10 -3
- package/lib/components/Tabs/Tabs.utils.d.ts +1 -0
- package/lib/components/Tabs/Tabs.utils.d.ts.map +1 -1
- package/lib/components/Tabs/Tabs.utils.js +4 -1
- package/lib/components/TextField/TextField.d.ts.map +1 -1
- package/lib/components/TextField/TextField.jsx +4 -0
- package/package.json +2 -2
- package/src/components/RadioGroup/RadioGroup.tsx +2 -1
- package/src/components/Tabs/Tabs.test.tsx +26 -1
- package/src/components/Tabs/Tabs.tsx +14 -2
- package/src/components/Tabs/Tabs.utils.ts +7 -0
- package/src/components/TextField/TextField.test.tsx +48 -0
- package/src/components/TextField/TextField.tsx +8 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioGroup.d.ts","sourceRoot":"","sources":["../../../src/components/RadioGroup/RadioGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAInE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAE7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAKrF,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EAGvB,MAAM,aAAa,CAAC;AAsErB,MAAM,WAAW,mBACf,SAAQ,iBAAiB,EACvB,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,EAC5D,sBAAsB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,cAAc,qFAyDzB,CAAC;AAKH,MAAM,WAAW,mBAAoB,SAAQ,sBAAsB;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,cAAc,qFA+CzB,CAAC;AAKH,MAAM,WAAW,0BACf,SAAQ,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,EACzC,sBAAsB;CAAG;AAE7B,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"RadioGroup.d.ts","sourceRoot":"","sources":["../../../src/components/RadioGroup/RadioGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAInE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAE7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAKrF,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EAGvB,MAAM,aAAa,CAAC;AAsErB,MAAM,WAAW,mBACf,SAAQ,iBAAiB,EACvB,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC,EAC5D,sBAAsB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,cAAc,qFAyDzB,CAAC;AAKH,MAAM,WAAW,mBAAoB,SAAQ,sBAAsB;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,cAAc,qFA+CzB,CAAC;AAKH,MAAM,WAAW,0BACf,SAAQ,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,EACzC,sBAAsB;CAAG;AAE7B,eAAO,MAAM,qBAAqB,4FA8BjC,CAAC;AAKF,MAAM,WAAW,4BACf,SAAQ,IAAI,CAAC,sBAAsB,EAAE,WAAW,GAAG,OAAO,CAAC;IAC3D,kGAAkG;IAClG,SAAS,CAAC,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;IAC/C,0GAA0G;IAC1G,OAAO,CAAC,EAAE,YAAY,CAAC,oBAAoB,CAAC,CAAC;CAC9C;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,4BAA4B,qBA6B1E;yBA7Be,uBAAuB;;;AAkCvC,MAAM,WAAW,wBAAyB,SAAQ,sBAAsB;CAAG;AAE3E,eAAO,MAAM,mBAAmB,0FAoB/B,CAAC"}
|
|
@@ -119,11 +119,12 @@ var RadioGroupItemControl = React.forwardRef((props, ref) => {
|
|
|
119
119
|
pressed: itemContext.pressed
|
|
120
120
|
};
|
|
121
121
|
const classes = radiomark(radiomarkVariantProps);
|
|
122
|
+
const controlClassName = radio(groupContext.radioVariantProps).control;
|
|
122
123
|
return <RadiomarkControlContext.Provider value={{
|
|
123
124
|
iconClassName: classes.icon,
|
|
124
125
|
radiomarkVariantProps
|
|
125
126
|
}}>
|
|
126
|
-
<view {...ref ? { ref } : {}} className={clsx(classes.root, className)} {...nativeProps}>
|
|
127
|
+
<view {...ref ? { ref } : {}} className={clsx(classes.root, controlClassName, className)} {...nativeProps}>
|
|
127
128
|
{children}
|
|
128
129
|
</view>
|
|
129
130
|
</RadiomarkControlContext.Provider>;
|
|
@@ -3,7 +3,7 @@ import { IntrinsicElements } from '@lynx-js/types';
|
|
|
3
3
|
import { LynxAccessibilityProps, LynxStyledElementProps } from '../../types';
|
|
4
4
|
import * as React from "@lynx-js/react";
|
|
5
5
|
type NativeViewPagerProps = IntrinsicElements["viewpager"];
|
|
6
|
-
type TabsPublicVariantProps = Omit<TabsVariantProps, "selected" | "disabled" | "inCarousel">;
|
|
6
|
+
type TabsPublicVariantProps = Omit<TabsVariantProps, "selected" | "disabled" | "inCarousel" | "transitionEnabled">;
|
|
7
7
|
/**
|
|
8
8
|
* @platform Lynx
|
|
9
9
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../src/components/Tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,EACV,iBAAiB,EAMlB,MAAM,gBAAgB,CAAC;AAKxB,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EAGvB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../src/components/Tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,EACV,iBAAiB,EAMlB,MAAM,gBAAgB,CAAC;AAKxB,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EAGvB,MAAM,aAAa,CAAC;AAWrB,KAAK,oBAAoB,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;AAI3D,KAAK,sBAAsB,GAAG,IAAI,CAChC,gBAAgB,EAChB,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,mBAAmB,CAC7D,CAAC;AAkFF;;;;;;;GAOG;AACH,MAAM,WAAW,aAAc,SAAQ,sBAAsB,EAAE,sBAAsB;IACnF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,eAAO,MAAM,QAAQ,+EAoNnB,CAAC;AAyBH,MAAM,WAAW,aAAc,SAAQ,sBAAsB;CAAG;AAEhE,eAAO,MAAM,QAAQ,+EAkCnB,CAAC;AAKH,MAAM,WAAW,gBAAiB,SAAQ,sBAAsB;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qBAAqB,CAAC,EAAE,sBAAsB,CAAC,qBAAqB,CAAC,CAAC;CACvE;AAED,eAAO,MAAM,WAAW,kFAkEtB,CAAC;AAKH,MAAM,WAAW,kBAAmB,SAAQ,sBAAsB;CAAG;AAErE,eAAO,MAAM,aAAa,oFAiCxB,CAAC;AAKH,MAAM,WAAW,gBAAiB,SAAQ,sBAAsB;IAC9D,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,WAAW,kFAgCtB,CAAC;AAKH;;;;;GAKG;AACH,MAAM,WAAW,iBAAkB,SAAQ,sBAAsB;IAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2CAA2C;IAC3C,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,YAAY,mFA8BvB,CAAC;AAKH,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,cAAc,CAAC,EAAE,oBAAoB,CAAC,gBAAgB,CAAC,CAAC;IACxD,gBAAgB,CAAC,EAAE,oBAAoB,CAAC,kBAAkB,CAAC,CAAC;CAC7D;AAED,eAAO,MAAM,kBAAkB,yFAgH9B,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useControllableState } from "../../hooks/useControllableState.js";
|
|
2
2
|
import { usePressTap } from "../../hooks/usePressTap.js";
|
|
3
3
|
import { createSlotRecipeContext } from "../../utils/create-slot-recipe-context.jsx";
|
|
4
|
-
import { getTabsLayoutWidth, getTabsOrderedItems, getTabsTriggerRects } from "./Tabs.utils.js";
|
|
4
|
+
import { areTabsTransitionsEnabled, getTabsLayoutWidth, getTabsOrderedItems, getTabsTriggerRects } from "./Tabs.utils.js";
|
|
5
5
|
import * as React from "@lynx-js/react";
|
|
6
6
|
import clsx from "clsx";
|
|
7
7
|
import { tabs } from "@seed-design/lynx-css/recipes/tabs";
|
|
@@ -52,7 +52,6 @@ function useTabsCarouselContext(consumer) {
|
|
|
52
52
|
var TabsRoot = React.forwardRef((props, ref) => {
|
|
53
53
|
const [variantProps, otherProps] = tabs.splitVariantProps(props);
|
|
54
54
|
const { children, className, style, value: valueProp, defaultValue, onValueChange, ...nativeProps } = otherProps;
|
|
55
|
-
const classNames = tabs(variantProps);
|
|
56
55
|
const [value, setValueInternal] = useControllableState({
|
|
57
56
|
value: valueProp,
|
|
58
57
|
defaultValue,
|
|
@@ -70,6 +69,11 @@ var TabsRoot = React.forwardRef((props, ref) => {
|
|
|
70
69
|
const indicatorRef = React.useMainThreadRef(null);
|
|
71
70
|
const pagerValues = React.useMemo(() => contentValues.filter((contentValue) => !items.find((item) => item.value === contentValue)?.disabled), [contentValues, items]);
|
|
72
71
|
const triggerRects = React.useMemo(() => getTabsTriggerRects(items.map((item) => item.value), triggerWidths), [items, triggerWidths]);
|
|
72
|
+
const transitionsEnabled = areTabsTransitionsEnabled(items.map((item) => item.value), triggerRects);
|
|
73
|
+
const classNames = tabs({
|
|
74
|
+
...variantProps,
|
|
75
|
+
transitionEnabled: transitionsEnabled
|
|
76
|
+
});
|
|
73
77
|
const visualValue = indicatorValue ?? value;
|
|
74
78
|
const indicatorIndex = items.findIndex((item) => item.value === visualValue);
|
|
75
79
|
const selectedPagerIndex = value === void 0 ? -1 : pagerValues.indexOf(value);
|
|
@@ -152,6 +156,7 @@ var TabsRoot = React.forwardRef((props, ref) => {
|
|
|
152
156
|
indicatorIndex,
|
|
153
157
|
selectedPagerIndex,
|
|
154
158
|
indicatorRef,
|
|
159
|
+
transitionsEnabled,
|
|
155
160
|
triggerRects,
|
|
156
161
|
registerTrigger,
|
|
157
162
|
registerContent,
|
|
@@ -173,6 +178,7 @@ var TabsRoot = React.forwardRef((props, ref) => {
|
|
|
173
178
|
selectedPagerIndex,
|
|
174
179
|
indicatorRef,
|
|
175
180
|
triggerRects,
|
|
181
|
+
transitionsEnabled,
|
|
176
182
|
registerTrigger,
|
|
177
183
|
registerContent,
|
|
178
184
|
updateTriggerDisabled,
|
|
@@ -265,7 +271,8 @@ var TabsTrigger = React.forwardRef((props, ref) => {
|
|
|
265
271
|
const triggerClasses = tabs({
|
|
266
272
|
...context.variantProps,
|
|
267
273
|
selected: visuallySelected,
|
|
268
|
-
disabled
|
|
274
|
+
disabled,
|
|
275
|
+
transitionEnabled: context.transitionsEnabled
|
|
269
276
|
});
|
|
270
277
|
const label = typeof children === "string" || typeof children === "number" ? String(children) : void 0;
|
|
271
278
|
return <view {...ref ? { ref } : {}} {...nativeProps} {...pressHandlers} flatten={false} bindlayoutchange={handleLayoutChange} accessibility-element={true} accessibility-role-description="tab" accessibility-label={accessibilityLabel ?? label} accessibility-value={selected ? "selected" : "not selected"} accessibility-traits={disabled ? "disabled" : selected ? "selected" : "button"} className={clsx(triggerClasses.trigger, className)} style={style}>
|
|
@@ -15,4 +15,5 @@ export declare function getTabsOrderedItems<T extends {
|
|
|
15
15
|
value: string;
|
|
16
16
|
}>(items: T[], values: string[]): T[];
|
|
17
17
|
export declare function getTabsTriggerRects(values: string[], widths: Record<string, number>): Record<string, TabsLayoutRect>;
|
|
18
|
+
export declare function areTabsTransitionsEnabled(values: string[], rects: Record<string, TabsLayoutRect>): boolean;
|
|
18
19
|
//# sourceMappingURL=Tabs.utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.utils.d.ts","sourceRoot":"","sources":["../../../src/components/Tabs/Tabs.utils.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAI9E;AAED,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAC7D,KAAK,EAAE,CAAC,EAAE,EACV,MAAM,EAAE,MAAM,EAAE,GACf,CAAC,EAAE,CAUL;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EAAE,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAiBhC"}
|
|
1
|
+
{"version":3,"file":"Tabs.utils.d.ts","sourceRoot":"","sources":["../../../src/components/Tabs/Tabs.utils.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAI9E;AAED,wBAAgB,mBAAmB,CAAC,CAAC,SAAS;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAC7D,KAAK,EAAE,CAAC,EAAE,EACV,MAAM,EAAE,MAAM,EAAE,GACf,CAAC,EAAE,CAUL;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EAAE,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAiBhC;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GACpC,OAAO,CAET"}
|
|
@@ -33,5 +33,8 @@ function getTabsTriggerRects(values, widths) {
|
|
|
33
33
|
}
|
|
34
34
|
return rects;
|
|
35
35
|
}
|
|
36
|
+
function areTabsTransitionsEnabled(values, rects) {
|
|
37
|
+
return values.length > 0 && values.every((value) => rects[value] !== void 0);
|
|
38
|
+
}
|
|
36
39
|
//#endregion
|
|
37
|
-
export { getTabsLayoutWidth, getTabsOrderedItems, getTabsTriggerRects };
|
|
40
|
+
export { areTabsTransitionsEnabled, getTabsLayoutWidth, getTabsOrderedItems, getTabsTriggerRects };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextField.d.ts","sourceRoot":"","sources":["../../../src/components/TextField/TextField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAa,KAAK,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAIjG,OAAO,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,EAAe,MAAM,aAAa,CAAC;AAG/F,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AA+BpE;;;;;;GAMG;AACH,MAAM,WAAW,kBACf,SAAQ,IAAI,CAAC,qBAAqB,EAAE,SAAS,CAAC,EAC5C,sBAAsB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,mEAAmE;IACnE,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,aAAa,qFAuHzB,CAAC;AAKF,KAAK,gBAAgB,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;AACnD,KAAK,mBAAmB,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"TextField.d.ts","sourceRoot":"","sources":["../../../src/components/TextField/TextField.tsx"],"names":[],"mappings":"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"}
|
|
@@ -257,12 +257,16 @@ function useNativeTextControl({ forwardedRef, disabled: disabledProp, readOnly:
|
|
|
257
257
|
]);
|
|
258
258
|
const handleBlur = React.useCallback((event) => {
|
|
259
259
|
"background only";
|
|
260
|
+
const nativeValue = event.detail?.value;
|
|
261
|
+
if (typeof nativeValue === "string") lastNativeValueRef.current = nativeValue;
|
|
260
262
|
textFieldContext.setFocused(false);
|
|
261
263
|
keyboardAvoidance?.blur(ownerRef.current);
|
|
262
264
|
bindblur?.(event);
|
|
265
|
+
if (typeof nativeValue === "string") reconcileControlledValue(nativeValue);
|
|
263
266
|
}, [
|
|
264
267
|
bindblur,
|
|
265
268
|
keyboardAvoidance,
|
|
269
|
+
reconcileControlledValue,
|
|
266
270
|
textFieldContext.setFocused
|
|
267
271
|
]);
|
|
268
272
|
const notifyLayoutChanged = React.useCallback(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seed-design/lynx-react",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/daangn/seed-design.git",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@lynx-js/react": "^0.117.0",
|
|
41
41
|
"@lynx-js/types": "^3.7.0",
|
|
42
|
-
"@seed-design/lynx-css": "0.9.
|
|
42
|
+
"@seed-design/lynx-css": "0.9.3",
|
|
43
43
|
"@testing-library/jest-dom": "^6.9.1",
|
|
44
44
|
"jsdom": "^29.0.2",
|
|
45
45
|
"preact": "npm:@lynx-js/internal-preact@10.28.4-ee7bb26",
|
|
@@ -232,6 +232,7 @@ export const RadioGroupItemControl = React.forwardRef<unknown, RadioGroupItemCon
|
|
|
232
232
|
pressed: itemContext.pressed,
|
|
233
233
|
};
|
|
234
234
|
const classes = radiomark(radiomarkVariantProps);
|
|
235
|
+
const controlClassName = radio(groupContext.radioVariantProps).control;
|
|
235
236
|
|
|
236
237
|
return (
|
|
237
238
|
<RadiomarkControlContext.Provider
|
|
@@ -239,7 +240,7 @@ export const RadioGroupItemControl = React.forwardRef<unknown, RadioGroupItemCon
|
|
|
239
240
|
>
|
|
240
241
|
<view
|
|
241
242
|
{...(ref ? { ref: ref as LynxViewRef } : {})}
|
|
242
|
-
className={clsx(classes.root, className)}
|
|
243
|
+
className={clsx(classes.root, controlClassName, className)}
|
|
243
244
|
{...nativeProps}
|
|
244
245
|
>
|
|
245
246
|
{children}
|
|
@@ -3,7 +3,12 @@ import { fireEvent, render } from "@lynx-js/react/testing-library";
|
|
|
3
3
|
import { describe, expect, it, vi } from "vitest";
|
|
4
4
|
|
|
5
5
|
import * as Tabs from "./Tabs.namespace";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
areTabsTransitionsEnabled,
|
|
8
|
+
getTabsLayoutWidth,
|
|
9
|
+
getTabsOrderedItems,
|
|
10
|
+
getTabsTriggerRects,
|
|
11
|
+
} from "./Tabs.utils";
|
|
7
12
|
|
|
8
13
|
function BasicTabs(props: {
|
|
9
14
|
value?: string;
|
|
@@ -41,6 +46,26 @@ describe("Tabs", () => {
|
|
|
41
46
|
expect(listContent?.querySelectorAll(".seed-tabs__trigger")).toHaveLength(2);
|
|
42
47
|
});
|
|
43
48
|
|
|
49
|
+
it("disables label and indicator transitions during the initial render", () => {
|
|
50
|
+
const { container } = render(<BasicTabs defaultValue="two" />);
|
|
51
|
+
const labels = container.querySelectorAll<HTMLElement>(".seed-tabs__triggerLabel");
|
|
52
|
+
const indicator = container.querySelector<HTMLElement>(".seed-tabs__indicator");
|
|
53
|
+
|
|
54
|
+
expect(indicator).toHaveClass("seed-tabs__indicator--transitionEnabled_false");
|
|
55
|
+
expect(indicator?.style.transitionDuration).toBe("");
|
|
56
|
+
for (const label of labels) {
|
|
57
|
+
expect(label).toHaveClass("seed-tabs__triggerLabel--transitionEnabled_false");
|
|
58
|
+
expect(label.style.transitionDuration).toBe("");
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("disables transitions when a dynamically added trigger is unmeasured", () => {
|
|
63
|
+
const rects = getTabsTriggerRects(["one", "two"], { one: 80, two: 80 });
|
|
64
|
+
|
|
65
|
+
expect(areTabsTransitionsEnabled(["one", "two"], rects)).toBe(true);
|
|
66
|
+
expect(areTabsTransitionsEnabled(["one", "two", "three"], rects)).toBe(false);
|
|
67
|
+
});
|
|
68
|
+
|
|
44
69
|
it("changes an uncontrolled value when a trigger is tapped", () => {
|
|
45
70
|
const onValueChange = vi.fn();
|
|
46
71
|
const { container } = render(<BasicTabs defaultValue="one" onValueChange={onValueChange} />);
|
|
@@ -20,6 +20,7 @@ import type {
|
|
|
20
20
|
} from "../../types";
|
|
21
21
|
import { createSlotRecipeContext } from "../../utils/create-slot-recipe-context";
|
|
22
22
|
import {
|
|
23
|
+
areTabsTransitionsEnabled,
|
|
23
24
|
getTabsLayoutWidth,
|
|
24
25
|
getTabsOrderedItems,
|
|
25
26
|
getTabsTriggerRects,
|
|
@@ -31,7 +32,10 @@ type NativeViewPagerProps = IntrinsicElements["viewpager"];
|
|
|
31
32
|
type LayoutChangeHandler = NonNullable<NativeViewProps["bindlayoutchange"]>;
|
|
32
33
|
type TriggerRect = TabsLayoutRect;
|
|
33
34
|
type TriggerItem = { value: string; disabled: boolean };
|
|
34
|
-
type TabsPublicVariantProps = Omit<
|
|
35
|
+
type TabsPublicVariantProps = Omit<
|
|
36
|
+
TabsVariantProps,
|
|
37
|
+
"selected" | "disabled" | "inCarousel" | "transitionEnabled"
|
|
38
|
+
>;
|
|
35
39
|
|
|
36
40
|
const { ClassNamesProvider, useClassNames } = createSlotRecipeContext(tabs);
|
|
37
41
|
|
|
@@ -65,6 +69,7 @@ interface TabsContextValue {
|
|
|
65
69
|
selectedPagerIndex: number;
|
|
66
70
|
indicatorRef: React.RefObject<MainThread.Element>;
|
|
67
71
|
triggerRects: Record<string, TriggerRect>;
|
|
72
|
+
transitionsEnabled: boolean;
|
|
68
73
|
registerTrigger: (value: string, disabled: boolean) => () => void;
|
|
69
74
|
registerContent: (value: string) => () => void;
|
|
70
75
|
updateTriggerDisabled: (value: string, disabled: boolean) => void;
|
|
@@ -137,7 +142,6 @@ export const TabsRoot = React.forwardRef<unknown, TabsRootProps>((props, ref) =>
|
|
|
137
142
|
onValueChange,
|
|
138
143
|
...nativeProps
|
|
139
144
|
} = otherProps;
|
|
140
|
-
const classNames = tabs(variantProps);
|
|
141
145
|
const [value, setValueInternal] = useControllableState<string | undefined>({
|
|
142
146
|
value: valueProp,
|
|
143
147
|
defaultValue,
|
|
@@ -169,6 +173,11 @@ export const TabsRoot = React.forwardRef<unknown, TabsRootProps>((props, ref) =>
|
|
|
169
173
|
),
|
|
170
174
|
[items, triggerWidths],
|
|
171
175
|
);
|
|
176
|
+
const transitionsEnabled = areTabsTransitionsEnabled(
|
|
177
|
+
items.map((item) => item.value),
|
|
178
|
+
triggerRects,
|
|
179
|
+
);
|
|
180
|
+
const classNames = tabs({ ...variantProps, transitionEnabled: transitionsEnabled });
|
|
172
181
|
const visualValue = indicatorValue ?? value;
|
|
173
182
|
const indicatorIndex = items.findIndex((item) => item.value === visualValue);
|
|
174
183
|
const selectedPagerIndex = value === undefined ? -1 : pagerValues.indexOf(value);
|
|
@@ -283,6 +292,7 @@ export const TabsRoot = React.forwardRef<unknown, TabsRootProps>((props, ref) =>
|
|
|
283
292
|
indicatorIndex,
|
|
284
293
|
selectedPagerIndex,
|
|
285
294
|
indicatorRef,
|
|
295
|
+
transitionsEnabled,
|
|
286
296
|
triggerRects,
|
|
287
297
|
registerTrigger,
|
|
288
298
|
registerContent,
|
|
@@ -305,6 +315,7 @@ export const TabsRoot = React.forwardRef<unknown, TabsRootProps>((props, ref) =>
|
|
|
305
315
|
selectedPagerIndex,
|
|
306
316
|
indicatorRef,
|
|
307
317
|
triggerRects,
|
|
318
|
+
transitionsEnabled,
|
|
308
319
|
registerTrigger,
|
|
309
320
|
registerContent,
|
|
310
321
|
updateTriggerDisabled,
|
|
@@ -447,6 +458,7 @@ export const TabsTrigger = React.forwardRef<unknown, TabsTriggerProps>((props, r
|
|
|
447
458
|
...context.variantProps,
|
|
448
459
|
selected: visuallySelected,
|
|
449
460
|
disabled,
|
|
461
|
+
transitionEnabled: context.transitionsEnabled,
|
|
450
462
|
});
|
|
451
463
|
const label =
|
|
452
464
|
typeof children === "string" || typeof children === "number" ? String(children) : undefined;
|
|
@@ -54,3 +54,10 @@ export function getTabsTriggerRects(
|
|
|
54
54
|
|
|
55
55
|
return rects;
|
|
56
56
|
}
|
|
57
|
+
|
|
58
|
+
export function areTabsTransitionsEnabled(
|
|
59
|
+
values: string[],
|
|
60
|
+
rects: Record<string, TabsLayoutRect>,
|
|
61
|
+
): boolean {
|
|
62
|
+
return values.length > 0 && values.every((value) => rects[value] !== undefined);
|
|
63
|
+
}
|
|
@@ -301,6 +301,54 @@ describe("TextField", () => {
|
|
|
301
301
|
expect(invoke).not.toHaveBeenCalled();
|
|
302
302
|
});
|
|
303
303
|
|
|
304
|
+
it("restores the committed controlled value when blur reports a stale native value", async () => {
|
|
305
|
+
const inputRef = createRef<NodesRef>();
|
|
306
|
+
|
|
307
|
+
function ControlledInput() {
|
|
308
|
+
const [value, setValue] = useState("초기값");
|
|
309
|
+
|
|
310
|
+
return (
|
|
311
|
+
<TextField.Root value={value} onValueChange={setValue}>
|
|
312
|
+
<TextField.Input ref={inputRef} />
|
|
313
|
+
</TextField.Root>
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
render(<ControlledInput />);
|
|
318
|
+
|
|
319
|
+
const input = getRenderedRoot().querySelector("input");
|
|
320
|
+
if (!input || !inputRef.current) throw new Error("Expected native input to exist.");
|
|
321
|
+
|
|
322
|
+
const exec = vi.fn();
|
|
323
|
+
const invoke = vi.fn(() => ({ exec }));
|
|
324
|
+
inputRef.current.invoke = invoke as unknown as NodesRef["invoke"];
|
|
325
|
+
|
|
326
|
+
fireNativeEvent(inputRef.current, input, "input", {
|
|
327
|
+
value: "최신값",
|
|
328
|
+
selectionStart: 3,
|
|
329
|
+
selectionEnd: 3,
|
|
330
|
+
isComposing: false,
|
|
331
|
+
});
|
|
332
|
+
await flushControlledReconciliation();
|
|
333
|
+
|
|
334
|
+
fireNativeEvent(inputRef.current, input, "blur", { value: "이전값" });
|
|
335
|
+
await flushControlledReconciliation();
|
|
336
|
+
|
|
337
|
+
expect(invoke).toHaveBeenCalledTimes(1);
|
|
338
|
+
expect(invoke).toHaveBeenCalledWith(
|
|
339
|
+
expect.objectContaining({
|
|
340
|
+
method: "setValue",
|
|
341
|
+
params: { value: "최신값" },
|
|
342
|
+
}),
|
|
343
|
+
);
|
|
344
|
+
expect(exec).toHaveBeenCalledTimes(1);
|
|
345
|
+
|
|
346
|
+
fireNativeEvent(inputRef.current, input, "blur", { value: "최신값" });
|
|
347
|
+
await flushControlledReconciliation();
|
|
348
|
+
|
|
349
|
+
expect(invoke).toHaveBeenCalledTimes(1);
|
|
350
|
+
});
|
|
351
|
+
|
|
304
352
|
it("waits for a parent value update queued in a microtask", async () => {
|
|
305
353
|
const inputRef = createRef<NodesRef>();
|
|
306
354
|
|
|
@@ -456,11 +456,18 @@ function useNativeTextControl({
|
|
|
456
456
|
(event: Parameters<NonNullable<NativeInputProps["bindblur"]>>[0]) => {
|
|
457
457
|
"background only";
|
|
458
458
|
|
|
459
|
+
const nativeValue = event.detail?.value;
|
|
460
|
+
if (typeof nativeValue === "string") {
|
|
461
|
+
lastNativeValueRef.current = nativeValue;
|
|
462
|
+
}
|
|
459
463
|
textFieldContext.setFocused(false);
|
|
460
464
|
keyboardAvoidance?.blur(ownerRef.current);
|
|
461
465
|
bindblur?.(event);
|
|
466
|
+
if (typeof nativeValue === "string") {
|
|
467
|
+
reconcileControlledValue(nativeValue);
|
|
468
|
+
}
|
|
462
469
|
},
|
|
463
|
-
[bindblur, keyboardAvoidance, textFieldContext.setFocused],
|
|
470
|
+
[bindblur, keyboardAvoidance, reconcileControlledValue, textFieldContext.setFocused],
|
|
464
471
|
);
|
|
465
472
|
|
|
466
473
|
const notifyLayoutChanged = React.useCallback(() => {
|