@seed-design/lynx-react 0.5.1 → 0.6.0

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 (99) hide show
  1. package/lib/components/Checkbox/Checkbox.d.ts +26 -0
  2. package/lib/components/Checkbox/Checkbox.d.ts.map +1 -1
  3. package/lib/components/Checkbox/Checkbox.jsx +1 -1
  4. package/lib/components/Icon/Icon.d.ts +5 -0
  5. package/lib/components/Icon/Icon.d.ts.map +1 -1
  6. package/lib/components/Icon/Icon.jsx +14 -3
  7. package/lib/components/MannerTemp/MannerTemp.d.ts +19 -0
  8. package/lib/components/MannerTemp/MannerTemp.d.ts.map +1 -0
  9. package/lib/components/MannerTemp/MannerTemp.jsx +47 -0
  10. package/lib/components/MannerTemp/index.d.ts +2 -0
  11. package/lib/components/MannerTemp/index.d.ts.map +1 -0
  12. package/lib/components/MannerTempBadge/MannerTempBadge.d.ts +13 -0
  13. package/lib/components/MannerTempBadge/MannerTempBadge.d.ts.map +1 -0
  14. package/lib/components/MannerTempBadge/MannerTempBadge.jsx +15 -0
  15. package/lib/components/MannerTempBadge/index.d.ts +2 -0
  16. package/lib/components/MannerTempBadge/index.d.ts.map +1 -0
  17. package/lib/components/NotificationBadge/NotificationBadge.d.ts +18 -0
  18. package/lib/components/NotificationBadge/NotificationBadge.d.ts.map +1 -0
  19. package/lib/components/NotificationBadge/NotificationBadge.jsx +34 -0
  20. package/lib/components/NotificationBadge/index.d.ts +2 -0
  21. package/lib/components/NotificationBadge/index.d.ts.map +1 -0
  22. package/lib/components/PageBanner/PageBanner.d.ts +35 -0
  23. package/lib/components/PageBanner/PageBanner.d.ts.map +1 -0
  24. package/lib/components/PageBanner/PageBanner.jsx +150 -0
  25. package/lib/components/PageBanner/PageBanner.namespace.d.ts +2 -0
  26. package/lib/components/PageBanner/PageBanner.namespace.d.ts.map +1 -0
  27. package/lib/components/PageBanner/PageBanner.namespace.js +14 -0
  28. package/lib/components/PageBanner/index.d.ts +3 -0
  29. package/lib/components/PageBanner/index.d.ts.map +1 -0
  30. package/lib/components/RadioGroup/RadioGroup.d.ts +9 -0
  31. package/lib/components/RadioGroup/RadioGroup.d.ts.map +1 -1
  32. package/lib/components/RadioGroup/RadioGroup.jsx +3 -2
  33. package/lib/components/SegmentedControl/SegmentedControl.d.ts +27 -0
  34. package/lib/components/SegmentedControl/SegmentedControl.d.ts.map +1 -0
  35. package/lib/components/SegmentedControl/SegmentedControl.jsx +120 -0
  36. package/lib/components/SegmentedControl/SegmentedControl.namespace.d.ts +2 -0
  37. package/lib/components/SegmentedControl/SegmentedControl.namespace.d.ts.map +1 -0
  38. package/lib/components/SegmentedControl/SegmentedControl.namespace.js +10 -0
  39. package/lib/components/SegmentedControl/index.d.ts +3 -0
  40. package/lib/components/SegmentedControl/index.d.ts.map +1 -0
  41. package/lib/components/SelectBox/CheckSelectBox.namespace.d.ts +2 -0
  42. package/lib/components/SelectBox/CheckSelectBox.namespace.d.ts.map +1 -0
  43. package/lib/components/SelectBox/CheckSelectBox.namespace.js +17 -0
  44. package/lib/components/SelectBox/RadioSelectBox.namespace.d.ts +2 -0
  45. package/lib/components/SelectBox/RadioSelectBox.namespace.d.ts.map +1 -0
  46. package/lib/components/SelectBox/RadioSelectBox.namespace.js +15 -0
  47. package/lib/components/SelectBox/SelectBox.d.ts +85 -0
  48. package/lib/components/SelectBox/SelectBox.d.ts.map +1 -0
  49. package/lib/components/SelectBox/SelectBox.jsx +237 -0
  50. package/lib/components/SelectBox/index.d.ts +4 -0
  51. package/lib/components/SelectBox/index.d.ts.map +1 -0
  52. package/lib/components/Tabs/Tabs.d.ts +1 -1
  53. package/lib/components/Tabs/Tabs.d.ts.map +1 -1
  54. package/lib/components/Tabs/Tabs.jsx +10 -3
  55. package/lib/components/Tabs/Tabs.utils.d.ts +1 -0
  56. package/lib/components/Tabs/Tabs.utils.d.ts.map +1 -1
  57. package/lib/components/Tabs/Tabs.utils.js +4 -1
  58. package/lib/components/TextField/TextField.d.ts.map +1 -1
  59. package/lib/components/TextField/TextField.jsx +4 -0
  60. package/lib/components/index.d.ts +6 -0
  61. package/lib/components/index.d.ts.map +1 -1
  62. package/lib/hooks/useIconColor.d.ts +1 -0
  63. package/lib/hooks/useIconColor.d.ts.map +1 -1
  64. package/lib/hooks/useIconColor.js +4 -1
  65. package/lib/index.js +11 -1
  66. package/package.json +3 -3
  67. package/src/components/Checkbox/Checkbox.tsx +1 -1
  68. package/src/components/Icon/Icon.test.tsx +25 -1
  69. package/src/components/Icon/Icon.tsx +22 -1
  70. package/src/components/MannerTemp/MannerTemp.test.tsx +41 -0
  71. package/src/components/MannerTemp/MannerTemp.tsx +85 -0
  72. package/src/components/MannerTemp/index.ts +1 -0
  73. package/src/components/MannerTempBadge/MannerTempBadge.test.tsx +35 -0
  74. package/src/components/MannerTempBadge/MannerTempBadge.tsx +34 -0
  75. package/src/components/MannerTempBadge/index.ts +1 -0
  76. package/src/components/NotificationBadge/NotificationBadge.test.tsx +28 -0
  77. package/src/components/NotificationBadge/NotificationBadge.tsx +81 -0
  78. package/src/components/NotificationBadge/index.ts +1 -0
  79. package/src/components/PageBanner/PageBanner.namespace.ts +16 -0
  80. package/src/components/PageBanner/PageBanner.test.tsx +124 -0
  81. package/src/components/PageBanner/PageBanner.tsx +340 -0
  82. package/src/components/PageBanner/index.ts +18 -0
  83. package/src/components/RadioGroup/RadioGroup.tsx +3 -2
  84. package/src/components/SegmentedControl/SegmentedControl.namespace.ts +8 -0
  85. package/src/components/SegmentedControl/SegmentedControl.test.tsx +81 -0
  86. package/src/components/SegmentedControl/SegmentedControl.tsx +236 -0
  87. package/src/components/SegmentedControl/index.ts +10 -0
  88. package/src/components/SelectBox/CheckSelectBox.namespace.ts +22 -0
  89. package/src/components/SelectBox/RadioSelectBox.namespace.ts +18 -0
  90. package/src/components/SelectBox/SelectBox.test.tsx +169 -0
  91. package/src/components/SelectBox/SelectBox.tsx +533 -0
  92. package/src/components/SelectBox/index.ts +3 -0
  93. package/src/components/Tabs/Tabs.test.tsx +26 -1
  94. package/src/components/Tabs/Tabs.tsx +14 -2
  95. package/src/components/Tabs/Tabs.utils.ts +7 -0
  96. package/src/components/TextField/TextField.test.tsx +48 -0
  97. package/src/components/TextField/TextField.tsx +8 -1
  98. package/src/components/index.ts +6 -0
  99. package/src/hooks/useIconColor.ts +6 -1
@@ -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(() => {
@@ -11,8 +11,14 @@ export * from "./Divider";
11
11
  export * from "./Field";
12
12
  export * from "./Icon";
13
13
  export * from "./KeyboardAvoidingScrollView";
14
+ export * from "./MannerTemp";
15
+ export * from "./MannerTempBadge";
16
+ export * from "./NotificationBadge";
17
+ export * from "./PageBanner";
14
18
  export * from "./ProgressCircle";
15
19
  export * from "./RadioGroup";
20
+ export * from "./SegmentedControl";
21
+ export * from "./SelectBox";
16
22
  export * from "./Stack";
17
23
  export * from "./Switch";
18
24
  export * from "./Tabs";
@@ -9,6 +9,7 @@ type IconElement = MainThread.Element & {
9
9
 
10
10
  export interface UseIconColorOptions {
11
11
  sourceRef?: RefObject<MainThread.Element>;
12
+ enabled?: boolean;
12
13
  }
13
14
 
14
15
  // Lynx `<image>` 의 `tint-color` attribute 에 CSS variable 문자열을 직접 넣는 경로는
@@ -86,20 +87,24 @@ export function useIconColor(
86
87
  } {
87
88
  const ref = useMainThreadRef<IconElement>(null);
88
89
  const sourceRef = options?.sourceRef as RefObject<IconElement> | undefined;
90
+ const enabled = options?.enabled ?? true;
89
91
  const frameRef = useMainThreadRef<number>(0);
90
92
 
91
93
  function syncOnUiAppear() {
92
94
  "main thread";
95
+ if (!enabled) return;
93
96
  syncTintColorOnce(ref, sourceRef);
94
97
  }
95
98
 
96
99
  // deps 는 caller 가 책임.
97
100
  useEffect(() => {
101
+ if (!enabled) return;
102
+
98
103
  runOnMainThread(scheduleTintColorSync)(ref, sourceRef, frameRef);
99
104
  return () => {
100
105
  runOnMainThread(cancelTintColorSync)(frameRef);
101
106
  };
102
- }, deps);
107
+ }, [...deps, enabled]);
103
108
 
104
109
  return { ref, "main-thread:binduiappear": syncOnUiAppear };
105
110
  }