@seed-design/lynx-react 0.7.1 → 0.9.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.
- package/lib/components/Accordion/Accordion.jsx +2 -2
- package/lib/components/ActionButton/ActionButton.jsx +1 -1
- package/lib/components/AlertDialog/AlertDialog.d.ts +64 -0
- package/lib/components/AlertDialog/AlertDialog.d.ts.map +1 -0
- package/lib/components/AlertDialog/AlertDialog.jsx +138 -0
- package/lib/components/AlertDialog/AlertDialog.namespace.d.ts +2 -0
- package/lib/components/AlertDialog/AlertDialog.namespace.d.ts.map +1 -0
- package/lib/components/AlertDialog/AlertDialog.namespace.js +17 -0
- package/lib/components/AlertDialog/index.d.ts +3 -0
- package/lib/components/AlertDialog/index.d.ts.map +1 -0
- package/lib/components/AppBar/AppBar.d.ts +14 -1
- package/lib/components/AppBar/AppBar.d.ts.map +1 -1
- package/lib/components/AppBar/AppBar.jsx +42 -16
- package/lib/components/AppBar/AppBar.namespace.d.ts +1 -1
- package/lib/components/AppBar/AppBar.namespace.d.ts.map +1 -1
- package/lib/components/AppBar/context.d.ts +2 -1
- package/lib/components/AppBar/context.d.ts.map +1 -1
- package/lib/components/AppBar/index.d.ts +1 -1
- package/lib/components/AppBar/index.d.ts.map +1 -1
- package/lib/components/AppBar/useAppBar.d.ts +2 -1
- package/lib/components/AppBar/useAppBar.d.ts.map +1 -1
- package/lib/components/AppBar/useAppBar.js +17 -15
- package/lib/components/AttachmentDisplay/AttachmentDisplay.d.ts +182 -0
- package/lib/components/AttachmentDisplay/AttachmentDisplay.d.ts.map +1 -0
- package/lib/components/AttachmentDisplay/AttachmentDisplay.jsx +444 -0
- package/lib/components/AttachmentDisplay/index.d.ts +2 -0
- package/lib/components/AttachmentDisplay/index.d.ts.map +1 -0
- package/lib/components/AttachmentInput/AttachmentInput.d.ts +179 -0
- package/lib/components/AttachmentInput/AttachmentInput.d.ts.map +1 -0
- package/lib/components/AttachmentInput/AttachmentInput.jsx +520 -0
- package/lib/components/AttachmentInput/index.d.ts +2 -0
- package/lib/components/AttachmentInput/index.d.ts.map +1 -0
- package/lib/components/BottomSheet/BottomSheet.d.ts +1 -1
- package/lib/components/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/lib/components/BottomSheet/BottomSheet.jsx +1 -7
- package/lib/components/Box/Box.d.ts +3 -3
- package/lib/components/Box/Box.d.ts.map +1 -1
- package/lib/components/Callout/Callout.jsx +2 -2
- package/lib/components/Checkbox/Checkbox.jsx +2 -2
- package/lib/components/Chip/Chip.jsx +2 -2
- package/lib/components/ChipTabs/ChipTabs.d.ts +41 -0
- package/lib/components/ChipTabs/ChipTabs.d.ts.map +1 -0
- package/lib/components/ChipTabs/ChipTabs.jsx +39 -0
- package/lib/components/ChipTabs/ChipTabs.namespace.d.ts +2 -0
- package/lib/components/ChipTabs/ChipTabs.namespace.d.ts.map +1 -0
- package/lib/components/ChipTabs/ChipTabs.namespace.js +13 -0
- package/lib/components/ChipTabs/index.d.ts +3 -0
- package/lib/components/ChipTabs/index.d.ts.map +1 -0
- package/lib/components/ContextualFloatingButton/ContextualFloatingButton.d.ts +18 -0
- package/lib/components/ContextualFloatingButton/ContextualFloatingButton.d.ts.map +1 -0
- package/lib/components/ContextualFloatingButton/ContextualFloatingButton.jsx +113 -0
- package/lib/components/ContextualFloatingButton/index.d.ts +2 -0
- package/lib/components/ContextualFloatingButton/index.d.ts.map +1 -0
- package/lib/components/Dialog/Dialog.d.ts +87 -0
- package/lib/components/Dialog/Dialog.d.ts.map +1 -0
- package/lib/components/Dialog/Dialog.jsx +147 -0
- package/lib/components/Dialog/Dialog.namespace.d.ts +2 -0
- package/lib/components/Dialog/Dialog.namespace.d.ts.map +1 -0
- package/lib/components/Dialog/Dialog.namespace.js +18 -0
- package/lib/components/Dialog/index.d.ts +3 -0
- package/lib/components/Dialog/index.d.ts.map +1 -0
- package/lib/components/FloatingActionButton/FloatingActionButton.d.ts +23 -0
- package/lib/components/FloatingActionButton/FloatingActionButton.d.ts.map +1 -0
- package/lib/components/FloatingActionButton/FloatingActionButton.jsx +76 -0
- package/lib/components/FloatingActionButton/FloatingActionButton.namespace.d.ts +2 -0
- package/lib/components/FloatingActionButton/FloatingActionButton.namespace.d.ts.map +1 -0
- package/lib/components/FloatingActionButton/FloatingActionButton.namespace.js +10 -0
- package/lib/components/FloatingActionButton/index.d.ts +3 -0
- package/lib/components/FloatingActionButton/index.d.ts.map +1 -0
- package/lib/components/HelpBubble/HelpBubble.d.ts +67 -0
- package/lib/components/HelpBubble/HelpBubble.d.ts.map +1 -0
- package/lib/components/HelpBubble/HelpBubble.jsx +600 -0
- package/lib/components/HelpBubble/HelpBubble.namespace.d.ts +2 -0
- package/lib/components/HelpBubble/HelpBubble.namespace.d.ts.map +1 -0
- package/lib/components/HelpBubble/HelpBubble.namespace.js +18 -0
- package/lib/components/HelpBubble/index.d.ts +3 -0
- package/lib/components/HelpBubble/index.d.ts.map +1 -0
- package/lib/components/Icon/Icon.d.ts +1 -0
- package/lib/components/Icon/Icon.d.ts.map +1 -1
- package/lib/components/Icon/Icon.jsx +2 -1
- package/lib/components/IdentityPlaceholder/IdentityPlaceholder.d.ts +28 -0
- package/lib/components/IdentityPlaceholder/IdentityPlaceholder.d.ts.map +1 -0
- package/lib/components/IdentityPlaceholder/IdentityPlaceholder.jsx +37 -0
- package/lib/components/IdentityPlaceholder/IdentityPlaceholder.namespace.d.ts +2 -0
- package/lib/components/IdentityPlaceholder/IdentityPlaceholder.namespace.d.ts.map +1 -0
- package/lib/components/IdentityPlaceholder/IdentityPlaceholder.namespace.js +9 -0
- package/lib/components/IdentityPlaceholder/identity-placeholder-business.js +4 -0
- package/lib/components/IdentityPlaceholder/identity-placeholder-person.js +4 -0
- package/lib/components/IdentityPlaceholder/index.d.ts +3 -0
- package/lib/components/IdentityPlaceholder/index.d.ts.map +1 -0
- package/lib/components/InputButton/InputButton.d.ts +2 -0
- package/lib/components/InputButton/InputButton.d.ts.map +1 -1
- package/lib/components/InputButton/InputButton.jsx +40 -8
- package/lib/components/List/List.d.ts +1 -1
- package/lib/components/List/List.d.ts.map +1 -1
- package/lib/components/List/List.jsx +26 -12
- package/lib/components/Menu/Menu.d.ts.map +1 -1
- package/lib/components/Menu/Menu.jsx +15 -5
- package/lib/components/PageBanner/PageBanner.d.ts +3 -0
- package/lib/components/PageBanner/PageBanner.d.ts.map +1 -1
- package/lib/components/PageBanner/PageBanner.jsx +49 -11
- package/lib/components/QuantityPicker/QuantityPicker.d.ts +53 -0
- package/lib/components/QuantityPicker/QuantityPicker.d.ts.map +1 -0
- package/lib/components/QuantityPicker/QuantityPicker.jsx +282 -0
- package/lib/components/QuantityPicker/QuantityPicker.namespace.d.ts +2 -0
- package/lib/components/QuantityPicker/QuantityPicker.namespace.d.ts.map +1 -0
- package/lib/components/QuantityPicker/QuantityPicker.namespace.js +11 -0
- package/lib/components/QuantityPicker/index.d.ts +3 -0
- package/lib/components/QuantityPicker/index.d.ts.map +1 -0
- package/lib/components/RadioGroup/RadioGroup.jsx +2 -2
- package/lib/components/ReactionButton/ReactionButton.d.ts +1 -1
- package/lib/components/ReactionButton/ReactionButton.d.ts.map +1 -1
- package/lib/components/ReactionButton/ReactionButton.jsx +22 -13
- package/lib/components/ScrollFog/ScrollFog.d.ts +41 -0
- package/lib/components/ScrollFog/ScrollFog.d.ts.map +1 -0
- package/lib/components/ScrollFog/ScrollFog.jsx +65 -0
- package/lib/components/ScrollFog/index.d.ts +2 -0
- package/lib/components/ScrollFog/index.d.ts.map +1 -0
- package/lib/components/SegmentedControl/SegmentedControl.jsx +2 -2
- package/lib/components/Select/Select.d.ts +112 -0
- package/lib/components/Select/Select.d.ts.map +1 -0
- package/lib/components/Select/Select.jsx +885 -0
- package/lib/components/Select/Select.namespace.d.ts +2 -0
- package/lib/components/Select/Select.namespace.d.ts.map +1 -0
- package/lib/components/Select/Select.namespace.js +23 -0
- package/lib/components/Select/index.d.ts +3 -0
- package/lib/components/Select/index.d.ts.map +1 -0
- package/lib/components/Skeleton/Skeleton.d.ts +15 -0
- package/lib/components/Skeleton/Skeleton.d.ts.map +1 -0
- package/lib/components/Skeleton/Skeleton.jsx +18 -0
- package/lib/components/Skeleton/index.d.ts +2 -0
- package/lib/components/Skeleton/index.d.ts.map +1 -0
- package/lib/components/Slider/Slider.d.ts +101 -0
- package/lib/components/Slider/Slider.d.ts.map +1 -0
- package/lib/components/Slider/Slider.jsx +573 -0
- package/lib/components/Slider/Slider.namespace.d.ts +2 -0
- package/lib/components/Slider/Slider.namespace.d.ts.map +1 -0
- package/lib/components/Slider/Slider.namespace.js +19 -0
- package/lib/components/Slider/Slider.utils.d.ts +19 -0
- package/lib/components/Slider/Slider.utils.d.ts.map +1 -0
- package/lib/components/Slider/Slider.utils.js +106 -0
- package/lib/components/Slider/index.d.ts +3 -0
- package/lib/components/Slider/index.d.ts.map +1 -0
- package/lib/components/Stack/Stack.d.ts +7 -9
- package/lib/components/Stack/Stack.d.ts.map +1 -1
- package/lib/components/SwipeableMenuSheet/SwipeableMenuSheet.d.ts.map +1 -1
- package/lib/components/SwipeableMenuSheet/SwipeableMenuSheet.jsx +22 -8
- package/lib/components/Switch/Switch.d.ts.map +1 -1
- package/lib/components/Switch/Switch.jsx +5 -3
- package/lib/components/Tabs/Tabs.d.ts +34 -2
- package/lib/components/Tabs/Tabs.d.ts.map +1 -1
- package/lib/components/Tabs/Tabs.jsx +186 -56
- package/lib/components/Tabs/Tabs.utils.d.ts +14 -1
- package/lib/components/Tabs/Tabs.utils.d.ts.map +1 -1
- package/lib/components/Tabs/Tabs.utils.js +24 -3
- package/lib/components/Tabs/index.d.ts +1 -1
- package/lib/components/Tabs/index.d.ts.map +1 -1
- package/lib/components/index.d.ts +14 -0
- package/lib/components/index.d.ts.map +1 -1
- package/lib/hooks/useControllableState.d.ts +1 -14
- package/lib/hooks/useControllableState.d.ts.map +1 -1
- package/lib/hooks/usePressTap.d.ts +1 -27
- package/lib/hooks/usePressTap.d.ts.map +1 -1
- package/lib/hooks/useSafeArea.d.ts +8 -4
- package/lib/hooks/useSafeArea.d.ts.map +1 -1
- package/lib/hooks/useSafeArea.js +22 -20
- package/lib/index.js +29 -6
- package/lib/{hooks/useControllableState.js → packages/lynx-react-headless/use-controllable-state/lib/index.js} +2 -3
- package/lib/{hooks/usePressTap.js → packages/lynx-react-headless/use-press-tap/lib/index.js} +13 -10
- package/lib/types.d.ts +1 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/utils/styled.d.ts +46 -6
- package/lib/utils/styled.d.ts.map +1 -1
- package/lib/utils/styled.js +19 -4
- package/package.json +9 -5
- package/src/components/AlertDialog/AlertDialog.namespace.ts +22 -0
- package/src/components/AlertDialog/AlertDialog.test.tsx +226 -0
- package/src/components/AlertDialog/AlertDialog.tsx +374 -0
- package/src/components/AlertDialog/index.ts +24 -0
- package/src/components/AppBar/AppBar.namespace.ts +1 -0
- package/src/components/AppBar/AppBar.test.tsx +252 -3
- package/src/components/AppBar/AppBar.tsx +108 -25
- package/src/components/AppBar/context.ts +3 -1
- package/src/components/AppBar/index.ts +1 -0
- package/src/components/AppBar/useAppBar.ts +21 -15
- package/src/components/AttachmentDisplay/AttachmentDisplay.tsx +886 -0
- package/src/components/AttachmentDisplay/index.ts +48 -0
- package/src/components/AttachmentInput/AttachmentInput.tsx +1001 -0
- package/src/components/AttachmentInput/index.ts +49 -0
- package/src/components/BottomSheet/BottomSheet.test.tsx +22 -7
- package/src/components/BottomSheet/BottomSheet.tsx +1 -19
- package/src/components/Box/Box.test.tsx +104 -0
- package/src/components/Box/Box.tsx +9 -6
- package/src/components/ChipTabs/ChipTabs.namespace.ts +14 -0
- package/src/components/ChipTabs/ChipTabs.tsx +119 -0
- package/src/components/ChipTabs/index.ts +16 -0
- package/src/components/ContextualFloatingButton/ContextualFloatingButton.test.tsx +63 -0
- package/src/components/ContextualFloatingButton/ContextualFloatingButton.tsx +232 -0
- package/src/components/ContextualFloatingButton/index.ts +4 -0
- package/src/components/Dialog/Dialog.namespace.ts +24 -0
- package/src/components/Dialog/Dialog.test.tsx +172 -0
- package/src/components/Dialog/Dialog.tsx +373 -0
- package/src/components/Dialog/index.ts +26 -0
- package/src/components/FloatingActionButton/FloatingActionButton.namespace.ts +8 -0
- package/src/components/FloatingActionButton/FloatingActionButton.test.tsx +59 -0
- package/src/components/FloatingActionButton/FloatingActionButton.tsx +207 -0
- package/src/components/FloatingActionButton/index.ts +10 -0
- package/src/components/HelpBubble/HelpBubble.namespace.ts +24 -0
- package/src/components/HelpBubble/HelpBubble.tsx +998 -0
- package/src/components/HelpBubble/index.ts +26 -0
- package/src/components/Icon/Icon.test.tsx +0 -3
- package/src/components/Icon/Icon.tsx +11 -1
- package/src/components/IdentityPlaceholder/IdentityPlaceholder.namespace.ts +6 -0
- package/src/components/IdentityPlaceholder/IdentityPlaceholder.tsx +103 -0
- package/src/components/IdentityPlaceholder/assets.d.ts +4 -0
- package/src/components/IdentityPlaceholder/identity-placeholder-business.webp +0 -0
- package/src/components/IdentityPlaceholder/identity-placeholder-person.webp +0 -0
- package/src/components/IdentityPlaceholder/index.ts +8 -0
- package/src/components/InputButton/InputButton.test.tsx +128 -1
- package/src/components/InputButton/InputButton.tsx +60 -9
- package/src/components/List/List.test.tsx +54 -2
- package/src/components/List/List.tsx +43 -10
- package/src/components/Menu/Menu.tsx +14 -4
- package/src/components/Menu/__tests__/Menu.test.tsx +34 -0
- package/src/components/PageBanner/PageBanner.test.tsx +110 -3
- package/src/components/PageBanner/PageBanner.tsx +83 -19
- package/src/components/QuantityPicker/QuantityPicker.namespace.ts +10 -0
- package/src/components/QuantityPicker/QuantityPicker.test.tsx +235 -0
- package/src/components/QuantityPicker/QuantityPicker.tsx +605 -0
- package/src/components/QuantityPicker/index.ts +14 -0
- package/src/components/ReactionButton/ReactionButton.feedback.test.tsx +50 -0
- package/src/components/ReactionButton/ReactionButton.test.tsx +5 -3
- package/src/components/ReactionButton/ReactionButton.tsx +20 -12
- package/src/components/ScrollFog/ScrollFog.test.tsx +222 -0
- package/src/components/ScrollFog/ScrollFog.tsx +172 -0
- package/src/components/ScrollFog/index.ts +1 -0
- package/src/components/Select/Select.namespace.ts +34 -0
- package/src/components/Select/Select.test.tsx +297 -0
- package/src/components/Select/Select.tsx +1483 -0
- package/src/components/Select/index.ts +39 -0
- package/src/components/Skeleton/Skeleton.test.tsx +64 -0
- package/src/components/Skeleton/Skeleton.tsx +45 -0
- package/src/components/Skeleton/index.ts +1 -0
- package/src/components/Slider/Slider.namespace.ts +26 -0
- package/src/components/Slider/Slider.test.tsx +260 -0
- package/src/components/Slider/Slider.tsx +897 -0
- package/src/components/Slider/Slider.utils.ts +167 -0
- package/src/components/Slider/index.ts +30 -0
- package/src/components/Stack/Stack.test.tsx +7 -0
- package/src/components/Stack/Stack.tsx +11 -10
- package/src/components/SwipeableMenuSheet/SwipeableMenuSheet.test.tsx +21 -1
- package/src/components/SwipeableMenuSheet/SwipeableMenuSheet.tsx +30 -7
- package/src/components/Switch/Switch.tsx +14 -13
- package/src/components/Tabs/Tabs.test.tsx +218 -1
- package/src/components/Tabs/Tabs.tsx +346 -75
- package/src/components/Tabs/Tabs.utils.ts +51 -1
- package/src/components/Tabs/index.ts +17 -1
- package/src/components/index.ts +14 -0
- package/src/hooks/useControllableState.ts +1 -43
- package/src/hooks/usePressTap.test.ts +23 -11
- package/src/hooks/usePressTap.ts +1 -60
- package/src/hooks/useSafeArea.test.ts +13 -1
- package/src/hooks/useSafeArea.ts +25 -23
- package/src/types.ts +1 -0
- package/src/utils/styled.ts +127 -9
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DialogBackdrop as DialogBackdropPrimitive,
|
|
3
|
+
DialogClose as DialogClosePrimitive,
|
|
4
|
+
DialogContent as DialogContentPrimitive,
|
|
5
|
+
DialogRoot as DialogRootPrimitive,
|
|
6
|
+
DialogTrigger as DialogTriggerPrimitive,
|
|
7
|
+
DialogView as DialogViewPrimitive,
|
|
8
|
+
type DialogBackdropProps as DialogPrimitiveBackdropProps,
|
|
9
|
+
type DialogCloseProps as DialogPrimitiveCloseProps,
|
|
10
|
+
type DialogContentProps as DialogPrimitiveContentProps,
|
|
11
|
+
type DialogRootProps as DialogPrimitiveRootProps,
|
|
12
|
+
type DialogTriggerProps as DialogPrimitiveTriggerProps,
|
|
13
|
+
type DialogViewProps as DialogPrimitiveViewProps,
|
|
14
|
+
} from "@lynx-js/lynx-ui-dialog";
|
|
15
|
+
import {
|
|
16
|
+
forwardRef,
|
|
17
|
+
type ForwardRefExoticComponent,
|
|
18
|
+
type PropsWithoutRef,
|
|
19
|
+
type ReactElement,
|
|
20
|
+
type RefAttributes,
|
|
21
|
+
} from "@lynx-js/react";
|
|
22
|
+
import { dialog, type DialogVariantProps } from "@seed-design/lynx-css/recipes/dialog";
|
|
23
|
+
import clsx from "clsx";
|
|
24
|
+
|
|
25
|
+
import type { LynxStyledElementProps, LynxTextRef, LynxViewRef } from "../../types";
|
|
26
|
+
import { useStyleProps, type StyleProps } from "../../utils/styled";
|
|
27
|
+
import { createSlotRecipeContext } from "../../utils/create-slot-recipe-context";
|
|
28
|
+
type DialogComponent<Props> = ((props: Props) => ReactElement) & {
|
|
29
|
+
displayName?: string;
|
|
30
|
+
};
|
|
31
|
+
type LynxForwardRefComponent<T, Props> = ForwardRefExoticComponent<
|
|
32
|
+
PropsWithoutRef<Props> & RefAttributes<T>
|
|
33
|
+
>;
|
|
34
|
+
|
|
35
|
+
type NativeLifecycleHandlers = {
|
|
36
|
+
bindanimationstart?: unknown;
|
|
37
|
+
bindanimationend?: unknown;
|
|
38
|
+
bindanimationcancel?: unknown;
|
|
39
|
+
bindtransitionstart?: unknown;
|
|
40
|
+
bindtransitionend?: unknown;
|
|
41
|
+
bindtap?: unknown;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const { ClassNamesProvider, PropsProvider, useClassNames, useProps } =
|
|
45
|
+
createSlotRecipeContext(dialog);
|
|
46
|
+
|
|
47
|
+
function omitHeadlessLifecycleHandlers<Props extends object>(
|
|
48
|
+
props: Props | undefined,
|
|
49
|
+
): Props | undefined {
|
|
50
|
+
if (!props) return props;
|
|
51
|
+
|
|
52
|
+
const {
|
|
53
|
+
bindanimationstart: _bindanimationstart,
|
|
54
|
+
bindanimationend: _bindanimationend,
|
|
55
|
+
bindanimationcancel: _bindanimationcancel,
|
|
56
|
+
bindtransitionstart: _bindtransitionstart,
|
|
57
|
+
bindtransitionend: _bindtransitionend,
|
|
58
|
+
bindtap: _bindtap,
|
|
59
|
+
...nativeProps
|
|
60
|
+
} = props as Props & NativeLifecycleHandlers;
|
|
61
|
+
|
|
62
|
+
return nativeProps as Props;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function useDialogTransition(transition: boolean | undefined) {
|
|
66
|
+
const skipAnimation = useProps()?.skipAnimation === true;
|
|
67
|
+
|
|
68
|
+
return skipAnimation ? false : (transition ?? true);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
72
|
+
// Root
|
|
73
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
74
|
+
|
|
75
|
+
export interface DialogRootProps
|
|
76
|
+
extends DialogVariantProps,
|
|
77
|
+
Omit<DialogPrimitiveRootProps, "show" | "defaultShow" | "onShowChange"> {
|
|
78
|
+
/**
|
|
79
|
+
* Whether the dialog is open (controlled mode).
|
|
80
|
+
* Internally mapped to `show` of `@lynx-js/lynx-ui-dialog`.
|
|
81
|
+
*/
|
|
82
|
+
open?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Whether the dialog is open by default (uncontrolled mode).
|
|
85
|
+
* Internally mapped to `defaultShow`.
|
|
86
|
+
* @defaultValue false
|
|
87
|
+
*/
|
|
88
|
+
defaultOpen?: boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Called when the dialog's open state is about to change.
|
|
91
|
+
* The Lynx headless implementation provides only the next boolean state.
|
|
92
|
+
*/
|
|
93
|
+
onOpenChange?: (open: boolean) => void;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @platform Lynx — wraps `@lynx-js/lynx-ui-dialog`.
|
|
98
|
+
*
|
|
99
|
+
* Unlike the React Dialog primitive, Lynx does not support refs, `lazyMount`,
|
|
100
|
+
* `unmountOnExit`, focus management, title/description associations, Escape-key
|
|
101
|
+
* dismissal, `asChild`, or close-reason details. Use `forceMount` from the
|
|
102
|
+
* underlying Lynx dialog when content must remain mounted while closed.
|
|
103
|
+
*/
|
|
104
|
+
export const DialogRoot = forwardRef<never, DialogRootProps>((props, _ref) => {
|
|
105
|
+
const [variantProps, restProps] = dialog.splitVariantProps(props);
|
|
106
|
+
const { children, open, defaultOpen, onOpenChange, ...nativeProps } = restProps;
|
|
107
|
+
const classNames = dialog(variantProps);
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<ClassNamesProvider value={classNames}>
|
|
111
|
+
<PropsProvider value={variantProps}>
|
|
112
|
+
<DialogRootPrimitive
|
|
113
|
+
{...nativeProps}
|
|
114
|
+
show={open}
|
|
115
|
+
defaultShow={defaultOpen}
|
|
116
|
+
onShowChange={onOpenChange}
|
|
117
|
+
>
|
|
118
|
+
{children}
|
|
119
|
+
</DialogRootPrimitive>
|
|
120
|
+
</PropsProvider>
|
|
121
|
+
</ClassNamesProvider>
|
|
122
|
+
);
|
|
123
|
+
}) as DialogComponent<DialogRootProps>;
|
|
124
|
+
DialogRoot.displayName = "DialogRoot";
|
|
125
|
+
|
|
126
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
127
|
+
// Trigger
|
|
128
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
129
|
+
|
|
130
|
+
export interface DialogTriggerProps extends DialogPrimitiveTriggerProps {}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @platform Lynx — `asChild` and refs are unsupported.
|
|
134
|
+
*/
|
|
135
|
+
export const DialogTrigger = forwardRef<never, DialogTriggerProps>((props, _ref) => {
|
|
136
|
+
const { children, transition, ...nativeProps } = props;
|
|
137
|
+
const resolvedTransition = useDialogTransition(transition);
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<DialogTriggerPrimitive {...nativeProps} transition={resolvedTransition}>
|
|
141
|
+
{children}
|
|
142
|
+
</DialogTriggerPrimitive>
|
|
143
|
+
);
|
|
144
|
+
}) as DialogComponent<DialogTriggerProps>;
|
|
145
|
+
DialogTrigger.displayName = "DialogTrigger";
|
|
146
|
+
|
|
147
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
148
|
+
// Positioner
|
|
149
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
150
|
+
|
|
151
|
+
export interface DialogPositionerProps extends DialogPrimitiveViewProps {}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @platform Lynx — maps to `DialogView`; refs are unsupported.
|
|
155
|
+
*/
|
|
156
|
+
export const DialogPositioner = forwardRef<never, DialogPositionerProps>((props, _ref) => {
|
|
157
|
+
const { children, className, transition, ...nativeProps } = props;
|
|
158
|
+
const classNames = useClassNames();
|
|
159
|
+
const resolvedTransition = useDialogTransition(transition);
|
|
160
|
+
|
|
161
|
+
return (
|
|
162
|
+
<DialogViewPrimitive
|
|
163
|
+
{...nativeProps}
|
|
164
|
+
className={clsx(classNames.positioner, className)}
|
|
165
|
+
transition={resolvedTransition}
|
|
166
|
+
>
|
|
167
|
+
{children}
|
|
168
|
+
</DialogViewPrimitive>
|
|
169
|
+
);
|
|
170
|
+
}) as DialogComponent<DialogPositionerProps>;
|
|
171
|
+
DialogPositioner.displayName = "DialogPositioner";
|
|
172
|
+
|
|
173
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
174
|
+
// Backdrop
|
|
175
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
176
|
+
|
|
177
|
+
export interface DialogBackdropProps extends DialogPrimitiveBackdropProps {}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* @platform Lynx — refs are unsupported. Native lifecycle handlers in
|
|
181
|
+
* `dialogBackdropProps` are reserved by the headless primitive and are omitted
|
|
182
|
+
* so they cannot replace its presence and dismissal handlers.
|
|
183
|
+
*/
|
|
184
|
+
export const DialogBackdrop = forwardRef<never, DialogBackdropProps>((props, _ref) => {
|
|
185
|
+
const { children, className, transition, dialogBackdropProps, ...nativeProps } = props;
|
|
186
|
+
const classNames = useClassNames();
|
|
187
|
+
const resolvedTransition = useDialogTransition(transition);
|
|
188
|
+
|
|
189
|
+
return (
|
|
190
|
+
<DialogBackdropPrimitive
|
|
191
|
+
{...nativeProps}
|
|
192
|
+
className={clsx(classNames.backdrop, className)}
|
|
193
|
+
transition={resolvedTransition}
|
|
194
|
+
dialogBackdropProps={omitHeadlessLifecycleHandlers(dialogBackdropProps)}
|
|
195
|
+
>
|
|
196
|
+
{children}
|
|
197
|
+
</DialogBackdropPrimitive>
|
|
198
|
+
);
|
|
199
|
+
}) as DialogComponent<DialogBackdropProps>;
|
|
200
|
+
DialogBackdrop.displayName = "DialogBackdrop";
|
|
201
|
+
|
|
202
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
203
|
+
// Content
|
|
204
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
205
|
+
|
|
206
|
+
export interface DialogContentProps extends DialogPrimitiveContentProps {}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @platform Lynx — refs are unsupported. Native lifecycle handlers in
|
|
210
|
+
* `dialogContentProps` are reserved by the headless primitive and are omitted
|
|
211
|
+
* so they cannot replace its presence handlers.
|
|
212
|
+
*/
|
|
213
|
+
export const DialogContent = forwardRef<never, DialogContentProps>((props, _ref) => {
|
|
214
|
+
const { children, className, transition, dialogContentProps, ...nativeProps } = props;
|
|
215
|
+
const classNames = useClassNames();
|
|
216
|
+
const resolvedTransition = useDialogTransition(transition);
|
|
217
|
+
|
|
218
|
+
return (
|
|
219
|
+
<DialogContentPrimitive
|
|
220
|
+
{...nativeProps}
|
|
221
|
+
className={clsx(classNames.content, className)}
|
|
222
|
+
transition={resolvedTransition}
|
|
223
|
+
dialogContentProps={omitHeadlessLifecycleHandlers(dialogContentProps)}
|
|
224
|
+
>
|
|
225
|
+
{children}
|
|
226
|
+
</DialogContentPrimitive>
|
|
227
|
+
);
|
|
228
|
+
}) as DialogComponent<DialogContentProps>;
|
|
229
|
+
DialogContent.displayName = "DialogContent";
|
|
230
|
+
|
|
231
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
232
|
+
// Local slots
|
|
233
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
234
|
+
|
|
235
|
+
export interface DialogHeaderProps extends StyleProps, LynxStyledElementProps {}
|
|
236
|
+
|
|
237
|
+
export const DialogHeader: LynxForwardRefComponent<unknown, DialogHeaderProps> = forwardRef<
|
|
238
|
+
unknown,
|
|
239
|
+
DialogHeaderProps
|
|
240
|
+
>((props, ref) => {
|
|
241
|
+
const { style, restProps } = useStyleProps(props);
|
|
242
|
+
const { children, className, ...nativeProps } = restProps;
|
|
243
|
+
const classNames = useClassNames();
|
|
244
|
+
|
|
245
|
+
return (
|
|
246
|
+
<view
|
|
247
|
+
{...(ref ? ({ ref: ref as LynxViewRef } as Record<string, unknown>) : {})}
|
|
248
|
+
{...nativeProps}
|
|
249
|
+
className={clsx(classNames.header, className)}
|
|
250
|
+
style={style as never}
|
|
251
|
+
>
|
|
252
|
+
{children}
|
|
253
|
+
</view>
|
|
254
|
+
);
|
|
255
|
+
});
|
|
256
|
+
DialogHeader.displayName = "DialogHeader";
|
|
257
|
+
|
|
258
|
+
export interface DialogBodyProps extends StyleProps, LynxStyledElementProps {}
|
|
259
|
+
|
|
260
|
+
export const DialogBody: LynxForwardRefComponent<unknown, DialogBodyProps> = forwardRef<
|
|
261
|
+
unknown,
|
|
262
|
+
DialogBodyProps
|
|
263
|
+
>((props, ref) => {
|
|
264
|
+
const { style, restProps } = useStyleProps(props);
|
|
265
|
+
const { children, className, ...nativeProps } = restProps;
|
|
266
|
+
const classNames = useClassNames();
|
|
267
|
+
|
|
268
|
+
return (
|
|
269
|
+
<scroll-view
|
|
270
|
+
{...(ref ? ({ ref: ref as LynxViewRef } as Record<string, unknown>) : {})}
|
|
271
|
+
{...nativeProps}
|
|
272
|
+
scroll-y
|
|
273
|
+
className={clsx(classNames.body, className)}
|
|
274
|
+
style={style}
|
|
275
|
+
>
|
|
276
|
+
{children}
|
|
277
|
+
</scroll-view>
|
|
278
|
+
);
|
|
279
|
+
});
|
|
280
|
+
DialogBody.displayName = "DialogBody";
|
|
281
|
+
|
|
282
|
+
export interface DialogTitleProps extends StyleProps, LynxStyledElementProps {}
|
|
283
|
+
|
|
284
|
+
export const DialogTitle: LynxForwardRefComponent<unknown, DialogTitleProps> = forwardRef<
|
|
285
|
+
unknown,
|
|
286
|
+
DialogTitleProps
|
|
287
|
+
>((props, ref) => {
|
|
288
|
+
const { style, restProps } = useStyleProps(props);
|
|
289
|
+
const { children, className, ...nativeProps } = restProps;
|
|
290
|
+
const classNames = useClassNames();
|
|
291
|
+
|
|
292
|
+
return (
|
|
293
|
+
<text
|
|
294
|
+
{...(ref ? ({ ref: ref as LynxTextRef } as Record<string, unknown>) : {})}
|
|
295
|
+
{...nativeProps}
|
|
296
|
+
className={clsx(classNames.title, className)}
|
|
297
|
+
style={style as never}
|
|
298
|
+
>
|
|
299
|
+
{children}
|
|
300
|
+
</text>
|
|
301
|
+
);
|
|
302
|
+
});
|
|
303
|
+
DialogTitle.displayName = "DialogTitle";
|
|
304
|
+
|
|
305
|
+
export interface DialogDescriptionProps extends StyleProps, LynxStyledElementProps {}
|
|
306
|
+
|
|
307
|
+
export const DialogDescription: LynxForwardRefComponent<unknown, DialogDescriptionProps> =
|
|
308
|
+
forwardRef<unknown, DialogDescriptionProps>((props, ref) => {
|
|
309
|
+
const { style, restProps } = useStyleProps(props);
|
|
310
|
+
const { children, className, ...nativeProps } = restProps;
|
|
311
|
+
const classNames = useClassNames();
|
|
312
|
+
|
|
313
|
+
return (
|
|
314
|
+
<text
|
|
315
|
+
{...(ref ? ({ ref: ref as LynxTextRef } as Record<string, unknown>) : {})}
|
|
316
|
+
{...nativeProps}
|
|
317
|
+
className={clsx(classNames.description, className)}
|
|
318
|
+
style={style as never}
|
|
319
|
+
>
|
|
320
|
+
{children}
|
|
321
|
+
</text>
|
|
322
|
+
);
|
|
323
|
+
});
|
|
324
|
+
DialogDescription.displayName = "DialogDescription";
|
|
325
|
+
|
|
326
|
+
export interface DialogFooterProps extends StyleProps, LynxStyledElementProps {}
|
|
327
|
+
|
|
328
|
+
export const DialogFooter: LynxForwardRefComponent<unknown, DialogFooterProps> = forwardRef<
|
|
329
|
+
unknown,
|
|
330
|
+
DialogFooterProps
|
|
331
|
+
>((props, ref) => {
|
|
332
|
+
const { style, restProps } = useStyleProps(props);
|
|
333
|
+
const { children, className, ...nativeProps } = restProps;
|
|
334
|
+
const classNames = useClassNames();
|
|
335
|
+
|
|
336
|
+
return (
|
|
337
|
+
<view
|
|
338
|
+
{...(ref ? ({ ref: ref as LynxViewRef } as Record<string, unknown>) : {})}
|
|
339
|
+
{...nativeProps}
|
|
340
|
+
className={clsx(classNames.footer, className)}
|
|
341
|
+
style={style as never}
|
|
342
|
+
>
|
|
343
|
+
{children}
|
|
344
|
+
</view>
|
|
345
|
+
);
|
|
346
|
+
});
|
|
347
|
+
DialogFooter.displayName = "DialogFooter";
|
|
348
|
+
|
|
349
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
350
|
+
// Action
|
|
351
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
352
|
+
|
|
353
|
+
export interface DialogActionProps extends DialogPrimitiveCloseProps {}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @platform Lynx — maps to `DialogClose`; `asChild` and refs are unsupported.
|
|
357
|
+
*/
|
|
358
|
+
export const DialogAction = forwardRef<never, DialogActionProps>((props, _ref) => {
|
|
359
|
+
const { children, className, transition, ...nativeProps } = props;
|
|
360
|
+
const classNames = useClassNames();
|
|
361
|
+
const resolvedTransition = useDialogTransition(transition);
|
|
362
|
+
|
|
363
|
+
return (
|
|
364
|
+
<DialogClosePrimitive
|
|
365
|
+
{...nativeProps}
|
|
366
|
+
className={clsx(classNames.action, className)}
|
|
367
|
+
transition={resolvedTransition}
|
|
368
|
+
>
|
|
369
|
+
{children}
|
|
370
|
+
</DialogClosePrimitive>
|
|
371
|
+
);
|
|
372
|
+
}) as DialogComponent<DialogActionProps>;
|
|
373
|
+
DialogAction.displayName = "DialogAction";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export {
|
|
2
|
+
DialogAction,
|
|
3
|
+
type DialogActionProps,
|
|
4
|
+
DialogBackdrop,
|
|
5
|
+
type DialogBackdropProps,
|
|
6
|
+
DialogBody,
|
|
7
|
+
type DialogBodyProps,
|
|
8
|
+
DialogContent,
|
|
9
|
+
type DialogContentProps,
|
|
10
|
+
DialogDescription,
|
|
11
|
+
type DialogDescriptionProps,
|
|
12
|
+
DialogFooter,
|
|
13
|
+
type DialogFooterProps,
|
|
14
|
+
DialogHeader,
|
|
15
|
+
type DialogHeaderProps,
|
|
16
|
+
DialogPositioner,
|
|
17
|
+
type DialogPositionerProps,
|
|
18
|
+
DialogRoot,
|
|
19
|
+
type DialogRootProps,
|
|
20
|
+
DialogTitle,
|
|
21
|
+
type DialogTitleProps,
|
|
22
|
+
DialogTrigger,
|
|
23
|
+
type DialogTriggerProps,
|
|
24
|
+
} from "./Dialog";
|
|
25
|
+
|
|
26
|
+
export * as Dialog from "./Dialog.namespace";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export {
|
|
2
|
+
FloatingActionButtonIcon as Icon,
|
|
3
|
+
FloatingActionButtonLabel as Label,
|
|
4
|
+
FloatingActionButtonRoot as Root,
|
|
5
|
+
type FloatingActionButtonIconProps as IconProps,
|
|
6
|
+
type FloatingActionButtonLabelProps as LabelProps,
|
|
7
|
+
type FloatingActionButtonRootProps as RootProps,
|
|
8
|
+
} from "./FloatingActionButton";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import { render } from "@lynx-js/react/testing-library";
|
|
3
|
+
import { describe, expect, it } from "vitest";
|
|
4
|
+
|
|
5
|
+
import { FloatingActionButtonLabel, FloatingActionButtonRoot } from "./FloatingActionButton";
|
|
6
|
+
|
|
7
|
+
function getFloatingActionButtonRoot(container: HTMLElement) {
|
|
8
|
+
const root = container.querySelector<HTMLElement>(".seed-floating-action-button__root");
|
|
9
|
+
|
|
10
|
+
if (!root) {
|
|
11
|
+
throw new Error("Expected FloatingActionButton root to exist.");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return root;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe("FloatingActionButton", () => {
|
|
18
|
+
it("removes and restores the label node while preserving the root accessibility name", () => {
|
|
19
|
+
const { container, rerender } = render(
|
|
20
|
+
<FloatingActionButtonRoot extended accessibility-label="새 글 작성">
|
|
21
|
+
<FloatingActionButtonLabel>Extended</FloatingActionButtonLabel>
|
|
22
|
+
</FloatingActionButtonRoot>,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
expect(container.querySelector(".seed-floating-action-button__label")).toHaveTextContent(
|
|
26
|
+
"Extended",
|
|
27
|
+
);
|
|
28
|
+
expect(getFloatingActionButtonRoot(container)).toHaveAttribute(
|
|
29
|
+
"accessibility-label",
|
|
30
|
+
"새 글 작성",
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
rerender(
|
|
34
|
+
<FloatingActionButtonRoot extended={false} accessibility-label="새 글 작성">
|
|
35
|
+
<FloatingActionButtonLabel>Extended</FloatingActionButtonLabel>
|
|
36
|
+
</FloatingActionButtonRoot>,
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
expect(container.querySelector(".seed-floating-action-button__label")).not.toBeInTheDocument();
|
|
40
|
+
expect(getFloatingActionButtonRoot(container)).toHaveAttribute(
|
|
41
|
+
"accessibility-label",
|
|
42
|
+
"새 글 작성",
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
rerender(
|
|
46
|
+
<FloatingActionButtonRoot extended accessibility-label="새 글 작성">
|
|
47
|
+
<FloatingActionButtonLabel>Extended</FloatingActionButtonLabel>
|
|
48
|
+
</FloatingActionButtonRoot>,
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
expect(container.querySelector(".seed-floating-action-button__label")).toHaveTextContent(
|
|
52
|
+
"Extended",
|
|
53
|
+
);
|
|
54
|
+
expect(getFloatingActionButtonRoot(container)).toHaveAttribute(
|
|
55
|
+
"accessibility-label",
|
|
56
|
+
"새 글 작성",
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import * as React from "@lynx-js/react";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
floatingActionButton,
|
|
6
|
+
type FloatingActionButtonVariantProps,
|
|
7
|
+
} from "@seed-design/lynx-css/recipes/floating-action-button";
|
|
8
|
+
|
|
9
|
+
import { usePressTap } from "../../hooks/usePressTap";
|
|
10
|
+
import { useScaleFeedback } from "../../hooks/useScaleFeedback";
|
|
11
|
+
import type {
|
|
12
|
+
LynxAccessibilityProps,
|
|
13
|
+
LynxPressableProps,
|
|
14
|
+
LynxStyledElementProps,
|
|
15
|
+
LynxTextProps,
|
|
16
|
+
LynxTextRef,
|
|
17
|
+
LynxTouchProps,
|
|
18
|
+
LynxViewRef,
|
|
19
|
+
LynxViewProps,
|
|
20
|
+
} from "../../types";
|
|
21
|
+
import { createSlotRecipeContext } from "../../utils/create-slot-recipe-context";
|
|
22
|
+
import { mergeProps } from "../../utils/merge-props";
|
|
23
|
+
import { InternalIcon, type InternalIconProps } from "../Icon/Icon";
|
|
24
|
+
|
|
25
|
+
const { ClassNamesProvider, PropsProvider, useClassNames, useProps, withContext } =
|
|
26
|
+
createSlotRecipeContext(floatingActionButton);
|
|
27
|
+
|
|
28
|
+
type FloatingActionButtonPublicVariantProps = Omit<
|
|
29
|
+
FloatingActionButtonVariantProps,
|
|
30
|
+
"pressed" | "transitionEnabled"
|
|
31
|
+
>;
|
|
32
|
+
|
|
33
|
+
const LabelWidthContext = React.createContext<((width: number) => void) | null>(null);
|
|
34
|
+
|
|
35
|
+
interface FloatingActionButtonRootViewProps
|
|
36
|
+
extends FloatingActionButtonVariantProps,
|
|
37
|
+
LynxStyledElementProps,
|
|
38
|
+
LynxTouchProps,
|
|
39
|
+
LynxAccessibilityProps {
|
|
40
|
+
flatten?: false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const FloatingActionButtonRootView = React.forwardRef<unknown, FloatingActionButtonRootViewProps>(
|
|
44
|
+
(props, ref) => {
|
|
45
|
+
const [variantProps, otherProps] = floatingActionButton.splitVariantProps(props);
|
|
46
|
+
const { children, className, style, ...nativeProps } = otherProps;
|
|
47
|
+
const initiallyExtended = React.useRef(variantProps.extended !== false);
|
|
48
|
+
const [labelWidth, setLabelWidth] = React.useState<number>();
|
|
49
|
+
const classNames = floatingActionButton({
|
|
50
|
+
...variantProps,
|
|
51
|
+
transitionEnabled: labelWidth !== undefined || !initiallyExtended.current,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<ClassNamesProvider value={classNames}>
|
|
56
|
+
<PropsProvider value={variantProps}>
|
|
57
|
+
<LabelWidthContext.Provider value={setLabelWidth}>
|
|
58
|
+
<view
|
|
59
|
+
{...mergeProps(ref ? { ref: ref as LynxViewRef } : {}, nativeProps)}
|
|
60
|
+
className={clsx(classNames.root, className)}
|
|
61
|
+
style={
|
|
62
|
+
{
|
|
63
|
+
"--fab-label-width": `${labelWidth ?? 0}px`,
|
|
64
|
+
...style,
|
|
65
|
+
} as LynxViewProps["style"]
|
|
66
|
+
}
|
|
67
|
+
>
|
|
68
|
+
{children}
|
|
69
|
+
</view>
|
|
70
|
+
</LabelWidthContext.Provider>
|
|
71
|
+
</PropsProvider>
|
|
72
|
+
</ClassNamesProvider>
|
|
73
|
+
);
|
|
74
|
+
},
|
|
75
|
+
);
|
|
76
|
+
FloatingActionButtonRootView.displayName = "FloatingActionButtonRootView";
|
|
77
|
+
|
|
78
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @platform Lynx
|
|
82
|
+
*
|
|
83
|
+
* Web DOM button props, `asChild`, `aria-*`, and `onClick` are not supported.
|
|
84
|
+
* Use native `bindtap` / `main-thread:bindtap` and `accessibility-*` props instead.
|
|
85
|
+
*/
|
|
86
|
+
export interface FloatingActionButtonRootProps
|
|
87
|
+
extends FloatingActionButtonPublicVariantProps,
|
|
88
|
+
LynxStyledElementProps,
|
|
89
|
+
LynxPressableProps,
|
|
90
|
+
LynxAccessibilityProps {
|
|
91
|
+
disabled?: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const FloatingActionButtonRoot = React.forwardRef<unknown, FloatingActionButtonRootProps>(
|
|
95
|
+
(props, ref) => {
|
|
96
|
+
const {
|
|
97
|
+
bindtap,
|
|
98
|
+
"main-thread:bindtap": mainThreadBindtap,
|
|
99
|
+
disabled = false,
|
|
100
|
+
"accessibility-element": accessibilityElement = true,
|
|
101
|
+
"accessibility-role-description": accessibilityRoleDescription = "button",
|
|
102
|
+
"accessibility-traits": accessibilityTraits,
|
|
103
|
+
...otherProps
|
|
104
|
+
} = props;
|
|
105
|
+
const { pressed, bindtouchstart, bindtouchend, bindtouchcancel, ...pressTapHandlers } =
|
|
106
|
+
usePressTap({
|
|
107
|
+
disabled,
|
|
108
|
+
onTap: bindtap,
|
|
109
|
+
mainThreadOnTap: mainThreadBindtap,
|
|
110
|
+
});
|
|
111
|
+
const { scaleFeedbackTriggerProps, scaleFeedbackTargetProps } = useScaleFeedback({
|
|
112
|
+
disabled,
|
|
113
|
+
onTouchStart: bindtouchstart,
|
|
114
|
+
onTouchEnd: bindtouchend,
|
|
115
|
+
onTouchCancel: bindtouchcancel,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<FloatingActionButtonRootView
|
|
120
|
+
{...mergeProps(
|
|
121
|
+
ref ? { ref } : {},
|
|
122
|
+
disabled ? {} : scaleFeedbackTargetProps,
|
|
123
|
+
disabled ? {} : scaleFeedbackTriggerProps,
|
|
124
|
+
disabled ? {} : pressTapHandlers,
|
|
125
|
+
otherProps,
|
|
126
|
+
)}
|
|
127
|
+
disabled={disabled}
|
|
128
|
+
pressed={pressed}
|
|
129
|
+
accessibility-element={accessibilityElement}
|
|
130
|
+
accessibility-role-description={accessibilityRoleDescription}
|
|
131
|
+
accessibility-traits={accessibilityTraits ?? (disabled ? "disabled" : undefined)}
|
|
132
|
+
flatten={false}
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
FloatingActionButtonRoot.displayName = "FloatingActionButtonRoot";
|
|
138
|
+
|
|
139
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
140
|
+
|
|
141
|
+
export interface FloatingActionButtonIconProps
|
|
142
|
+
extends Omit<InternalIconProps, "deps" | "disableDefaultResize"> {}
|
|
143
|
+
|
|
144
|
+
const StyledIcon = withContext<unknown, InternalIconProps>(InternalIcon, "icon");
|
|
145
|
+
|
|
146
|
+
export const FloatingActionButtonIcon = React.forwardRef<unknown, FloatingActionButtonIconProps>(
|
|
147
|
+
(props, ref) => {
|
|
148
|
+
const { className, ...iconProps } = props;
|
|
149
|
+
const classNames = useClassNames();
|
|
150
|
+
|
|
151
|
+
return (
|
|
152
|
+
<StyledIcon
|
|
153
|
+
{...mergeProps(ref ? { ref } : {}, iconProps)}
|
|
154
|
+
className={className}
|
|
155
|
+
deps={[classNames.icon]}
|
|
156
|
+
disableDefaultResize={true}
|
|
157
|
+
accessibility-elements-hidden={true}
|
|
158
|
+
/>
|
|
159
|
+
);
|
|
160
|
+
},
|
|
161
|
+
);
|
|
162
|
+
FloatingActionButtonIcon.displayName = "FloatingActionButtonIcon";
|
|
163
|
+
|
|
164
|
+
////////////////////////////////////////////////////////////////////////////////////
|
|
165
|
+
|
|
166
|
+
export interface FloatingActionButtonLabelProps extends LynxStyledElementProps {}
|
|
167
|
+
|
|
168
|
+
export const FloatingActionButtonLabel = React.forwardRef<unknown, FloatingActionButtonLabelProps>(
|
|
169
|
+
(props, ref) => {
|
|
170
|
+
const { children, className, ...nativeProps } = props;
|
|
171
|
+
const classNames = useClassNames();
|
|
172
|
+
const variantProps = useProps();
|
|
173
|
+
const setLabelWidth = React.useContext(LabelWidthContext);
|
|
174
|
+
|
|
175
|
+
if (!setLabelWidth) {
|
|
176
|
+
throw new Error("FloatingActionButtonLabel must be used within FloatingActionButtonRoot.");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const handleLayoutChange = React.useCallback<NonNullable<LynxTextProps["bindlayoutchange"]>>(
|
|
180
|
+
(event) => {
|
|
181
|
+
"background only";
|
|
182
|
+
const width = event.detail.width;
|
|
183
|
+
if (Number.isFinite(width) && width >= 0) setLabelWidth(width);
|
|
184
|
+
},
|
|
185
|
+
[setLabelWidth],
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
if (variantProps?.extended === false) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return (
|
|
193
|
+
<text
|
|
194
|
+
{...mergeProps(
|
|
195
|
+
ref ? { ref: ref as LynxTextRef } : {},
|
|
196
|
+
{ bindlayoutchange: handleLayoutChange },
|
|
197
|
+
nativeProps,
|
|
198
|
+
)}
|
|
199
|
+
className={clsx(classNames.label, className)}
|
|
200
|
+
accessibility-elements-hidden={true}
|
|
201
|
+
>
|
|
202
|
+
{children}
|
|
203
|
+
</text>
|
|
204
|
+
);
|
|
205
|
+
},
|
|
206
|
+
);
|
|
207
|
+
FloatingActionButtonLabel.displayName = "FloatingActionButtonLabel";
|