From e971475372f393eeda5677b8a6da15ba6707dd34 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Wed, 10 Sep 2025 17:50:29 +0200 Subject: [PATCH 01/38] feat: stabilize Button and Link components feat: rename buttons chore: rename Button chore: fix imports feet: use internal Action component feet: use internal Action component feet: use internal Action component --- packages/react/docs/components/BareColor.tsx | 4 +- packages/react/docs/components/ColorToken.tsx | 7 +- .../components/Actions/Button/internal.tsx | 216 ------------- .../src/components/Actions/Link/index.tsx | 1 - .../src/components/F0Card/CardInternal.tsx | 4 +- .../F0Card/components/CardActions.tsx | 14 +- .../F0Card/components/CardOptions.tsx | 4 +- .../components/FiltersChipsList.tsx | 6 +- .../components/FiltersControls.tsx | 12 +- .../filterTypes/DateFilter/DateFilter.tsx | 4 +- .../filterTypes/InFilter/InFilter.tsx | 6 +- .../ProductBlankslate/index.stories.tsx | 6 +- .../UpsellingKit/ProductCard/index.tsx | 4 +- .../ProductModal/components/CustomModal.tsx | 2 +- .../UpsellingKit/ProductModal/index.tsx | 6 +- .../UpsellingKit/ProductWidget/index.tsx | 6 +- .../UpsellRequestResponseDialog/index.tsx | 6 +- .../UpsellingKit/UpsellingBanner/index.tsx | 4 +- .../UpsellingKit/UpsellingButton/index.tsx | 6 +- .../UpsellingKit/UpsellingPopover/index.tsx | 8 +- .../Await/__stories__/Await.stories.tsx | 4 +- .../F0Button/F0Button.tsx} | 14 +- .../F0Button/__stories__/F0Button.mdx} | 4 +- .../__stories__/F0Button.stories.tsx} | 144 ++++++--- .../F0Button/__tests__/F0Button.test.tsx} | 18 +- .../src/components/actions/F0Button/index.ts | 2 + .../actions/F0Button/internal-types.ts | 82 +++++ .../components/actions/F0Button/internal.tsx | 180 +++++++++++ .../src/components/actions/F0Button/types.ts | 7 + .../OneLink.tsx => actions/F0Link/F0Link.tsx} | 4 +- .../F0Link}/__mocks__/linkHandler.tsx | 0 .../F0Link/__stories__}/index.mdx | 4 +- .../F0Link}/__stories__/index.stories.tsx | 39 ++- .../F0Link}/__tests__/index.test.tsx | 22 +- .../src/components/actions/F0Link/index.tsx | 1 + .../OneDropdownButton.stories.tsx | 0 .../OneDropdownButton.test.tsx | 0 .../OneDropdownButton/OneDropdownButton.tsx | 0 .../OneDropdownButton/index.ts | 0 .../OneDropdownButton/theme.ts | 0 .../OneDropdownButton/types.ts | 0 .../{Actions => actions}/exports.tsx | 6 +- .../internal/F0ButtonCopy/F0ButtonCopy.tsx} | 10 +- .../__stories__/F0ButtonCopy.stories.tsx | 290 ++++++++++++++++++ .../actions/internal/F0ButtonCopy/index.ts | 1 + .../actions/internal/F0ButtonCopy/types.ts | 4 + .../avatars/F0AvatarPulse/F0AvatarPulse.tsx | 4 +- packages/react/src/components/exports.ts | 2 +- .../AiChat/HILActionConfirmation.tsx | 6 +- .../AiChat/components/AssistantMessage.tsx | 9 +- .../AiChat/components/ChatHeader.tsx | 2 +- .../AiChat/components/ChatTextarea.tsx | 2 +- .../AiChat/components/MessagesContainer.tsx | 2 +- .../experimental/AiChat/markdownRenderers.tsx | 10 +- .../experimental/Banners/BaseBanner/index.tsx | 8 +- .../Content/MainContent/Footer.tsx | 6 +- .../Forms/EntitySelect/CreateItem/index.tsx | 6 +- .../Forms/EntitySelect/ListItem/index.tsx | 4 +- .../Fields/Select/SelectBottomActions.tsx | 7 +- .../experimental/Forms/Form/index.stories.tsx | 8 +- .../src/experimental/Forms/Form/index.tsx | 4 +- .../Communities/HighlightBanner/index.tsx | 4 +- .../Communities/Post/CommunityPost/index.tsx | 22 +- .../Information/Headers/BaseHeader/index.tsx | 10 +- .../Information/Headers/Metadata/index.tsx | 8 +- .../Headers/SectionHeader/index.tsx | 18 +- .../Information/Reactions/Picker/index.tsx | 10 +- .../src/experimental/Information/utils.tsx | 4 +- .../Lists/OnePersonListItem/index.tsx | 6 +- .../Modals/OneModal/OneModal.stories.tsx | 2 +- .../OneModalHeader/OneModalHeader.tsx | 2 +- .../Navigation/DaytimePage/index.tsx | 4 +- .../Navigation/Dropdown/index.tsx | 12 +- .../Navigation/Dropdown/internal.tsx | 6 +- .../F0TableOfContent/Item/ItemDropDown.tsx | 4 +- .../Navigation/Header/PageHeader/index.tsx | 12 +- .../Header/ProductUpdates/index.tsx | 14 +- .../Navigation/Sidebar/Footer/index.tsx | 4 +- .../OneActionBar/index.stories.tsx | 4 +- .../src/experimental/OneActionBar/index.tsx | 12 +- .../react/src/experimental/OneAlert/index.tsx | 4 +- .../experimental/OneCalendar/OneCalendar.tsx | 8 +- .../CollectionActions/CollectionActions.tsx | 8 +- .../OneDataCollection/Settings/Settings.tsx | 4 +- .../Settings/components/GroupingSelector.tsx | 4 +- .../Settings/components/SortingSelector.tsx | 4 +- .../ItemActionsDropdown.tsx | 4 +- .../ItemActionsRow/ItemActionsRow.tsx | 4 +- .../OneDataCollection/visualizations.tsx | 14 +- .../collection/List/components/Row.tsx | 30 +- .../components/DateNavigatorTrigger.tsx | 10 +- .../OneEmptyState/OneEmptyState.tsx | 4 +- .../experimental/OneTable/index.stories.tsx | 8 +- .../Overlays/Dialog/index.stories.tsx | 6 +- .../experimental/Overlays/Dialog/index.tsx | 12 +- .../Overlays/Tooltip/index.stories.tsx | 6 +- .../CoreEditor/Extensions/AIBlock/index.tsx | 6 +- .../Extensions/LiveCompanion/index.tsx | 4 +- .../Extensions/MoodTracker/index.tsx | 4 +- .../Extensions/Transcript/index.tsx | 4 +- .../RichText/CoreEditor/Toolbar/index.tsx | 4 +- .../RichText/NotesTextEditor/Header/index.tsx | 4 +- .../NotesTextEditor/index.stories.tsx | 1 + .../Enhance/AcceptChanges/index.tsx | 8 +- .../RichText/RichTextEditor/Error/index.tsx | 4 +- .../Footer/ActionsMenu/index.tsx | 10 +- .../RichText/RichTextEditor/Footer/index.tsx | 6 +- .../RichText/RichTextEditor/Head/index.tsx | 8 +- .../Utilities/PrivateBox/index.stories.tsx | 6 +- .../Utilities/ScrollArea/index.stories.tsx | 6 +- .../Widgets/ChartWidgetEmptyState/index.tsx | 10 +- .../Content/ClockIn/ClockInControls/index.tsx | 14 +- .../src/experimental/Widgets/Widget/index.tsx | 8 +- packages/react/src/experimental/exports.ts | 2 +- packages/react/src/ui/Action/Action.tsx | 31 +- packages/react/src/ui/Action/variants.ts | 20 ++ .../ui/DatePickerPopup/OneDatePickerPopup.tsx | 4 +- 117 files changed, 1067 insertions(+), 627 deletions(-) delete mode 100644 packages/react/src/components/Actions/Button/internal.tsx delete mode 100644 packages/react/src/components/Actions/Link/index.tsx rename packages/react/src/components/{Actions/Button/index.tsx => actions/F0Button/F0Button.tsx} (61%) rename packages/react/src/components/{Actions/Button/index.mdx => actions/F0Button/__stories__/F0Button.mdx} (99%) rename packages/react/src/components/{Actions/Button/index.stories.tsx => actions/F0Button/__stories__/F0Button.stories.tsx} (63%) rename packages/react/src/components/{Actions/Button/index.test.tsx => actions/F0Button/__tests__/F0Button.test.tsx} (82%) create mode 100644 packages/react/src/components/actions/F0Button/index.ts create mode 100644 packages/react/src/components/actions/F0Button/internal-types.ts create mode 100644 packages/react/src/components/actions/F0Button/internal.tsx create mode 100644 packages/react/src/components/actions/F0Button/types.ts rename packages/react/src/components/{Actions/Link/OneLink.tsx => actions/F0Link/F0Link.tsx} (94%) rename packages/react/src/components/{Actions/Link => actions/F0Link}/__mocks__/linkHandler.tsx (100%) rename packages/react/src/components/{Actions/Link => actions/F0Link/__stories__}/index.mdx (94%) rename packages/react/src/components/{Actions/Link => actions/F0Link}/__stories__/index.stories.tsx (67%) rename packages/react/src/components/{Actions/Link => actions/F0Link}/__tests__/index.test.tsx (76%) create mode 100644 packages/react/src/components/actions/F0Link/index.tsx rename packages/react/src/components/{Actions => actions}/OneDropdownButton/OneDropdownButton.stories.tsx (100%) rename packages/react/src/components/{Actions => actions}/OneDropdownButton/OneDropdownButton.test.tsx (100%) rename packages/react/src/components/{Actions => actions}/OneDropdownButton/OneDropdownButton.tsx (100%) rename packages/react/src/components/{Actions => actions}/OneDropdownButton/index.ts (100%) rename packages/react/src/components/{Actions => actions}/OneDropdownButton/theme.ts (100%) rename packages/react/src/components/{Actions => actions}/OneDropdownButton/types.ts (100%) rename packages/react/src/components/{Actions => actions}/exports.tsx (51%) rename packages/react/src/components/{Actions/Button/copy.tsx => actions/internal/F0ButtonCopy/F0ButtonCopy.tsx} (91%) create mode 100644 packages/react/src/components/actions/internal/F0ButtonCopy/__stories__/F0ButtonCopy.stories.tsx create mode 100644 packages/react/src/components/actions/internal/F0ButtonCopy/index.ts create mode 100644 packages/react/src/components/actions/internal/F0ButtonCopy/types.ts diff --git a/packages/react/docs/components/BareColor.tsx b/packages/react/docs/components/BareColor.tsx index 72a6236b61..99ec986e26 100644 --- a/packages/react/docs/components/BareColor.tsx +++ b/packages/react/docs/components/BareColor.tsx @@ -1,7 +1,7 @@ import { useState } from "react" +import { F0Button } from "@/components/actions/F0Button" import { CopyIcon } from "lucide-react" -import { Button } from "../../src/components/Actions/Button" type Props = { name: string @@ -30,7 +30,7 @@ export function BareColor({ name }: Props) {
-
-
)} {primaryAction && (
-
- + +

+ Click either button to see the copy → check animation +

+ + ) + }, +} + +export const InContext: Story = { + parameters: withSnapshot({}), + render: (args) => ( +
+

Share this link

+
+ + https://factorial.com/shared/abc123 + + +
+
+ ), +} diff --git a/packages/react/src/components/actions/internal/F0ButtonCopy/index.ts b/packages/react/src/components/actions/internal/F0ButtonCopy/index.ts new file mode 100644 index 0000000000..aa5a7c519c --- /dev/null +++ b/packages/react/src/components/actions/internal/F0ButtonCopy/index.ts @@ -0,0 +1 @@ +export * from "./F0ButtonCopy" diff --git a/packages/react/src/components/actions/internal/F0ButtonCopy/types.ts b/packages/react/src/components/actions/internal/F0ButtonCopy/types.ts new file mode 100644 index 0000000000..ae1761a5c8 --- /dev/null +++ b/packages/react/src/components/actions/internal/F0ButtonCopy/types.ts @@ -0,0 +1,4 @@ +import { sizes } from "@/ui/button" + +export const buttonCopySizes = sizes +export type ButtonCopySize = (typeof buttonCopySizes)[number] diff --git a/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx b/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx index b4b4215cb3..8dfb73fea6 100644 --- a/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx +++ b/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx @@ -1,4 +1,4 @@ -import { Button as ActionButton } from "@/components/Actions/Button" +import { F0Button } from "@/components/actions/F0Button" import { F0Icon, F0IconProps, IconType } from "@/components/F0Icon" import { FaceNegative, @@ -182,7 +182,7 @@ export const F0AvatarPulse = ({ }} className="absolute -bottom-1 -right-1 rounded-sm bg-f1-background" > - {text &&

{text}

}
-
-
-
) diff --git a/packages/react/src/experimental/Information/Communities/Post/CommunityPost/index.tsx b/packages/react/src/experimental/Information/Communities/Post/CommunityPost/index.tsx index 7f7727fc71..09a84c813d 100644 --- a/packages/react/src/experimental/Information/Communities/Post/CommunityPost/index.tsx +++ b/packages/react/src/experimental/Information/Communities/Post/CommunityPost/index.tsx @@ -1,5 +1,5 @@ -import { Button } from "@/components/Actions/Button" -import { Link } from "@/components/Actions/Link" +import { F0Button } from "@/components/actions/F0Button" +import { F0Link } from "@/components/actions/F0Link" import { F0AvatarIcon } from "@/components/avatars/F0AvatarIcon" import { F0AvatarPerson } from "@/components/avatars/F0AvatarPerson" import { Reactions, ReactionsProps } from "@/experimental/Information/Reactions" @@ -102,13 +102,13 @@ export const BaseCommunityPost = ({ >
{author ? ( - + - + ) : ( )} @@ -119,7 +119,7 @@ export const BaseCommunityPost = ({
{author ? ( <> - - - + {authorFullName} - + ) : (
@@ -156,14 +156,14 @@ export const BaseCommunityPost = ({ > {inLabel} - {group.title} - + · @@ -230,7 +230,7 @@ export const BaseCommunityPost = ({

{countersDisplay}

{!noReactionsButton && ( -
{link && (
- + {link.label} - +
)}
{action && ( <>
-
-
{currentGrouping?.field && ( -
-
{actions?.map((action, index) => ( -
-
{loading && !isLinkStyled && ( - - - +
+ +
)} {loading && isLinkStyled && ( diff --git a/packages/react/src/ui/Action/variants.ts b/packages/react/src/ui/Action/variants.ts index 2b3557b32b..0bf0f3b2be 100644 --- a/packages/react/src/ui/Action/variants.ts +++ b/packages/react/src/ui/Action/variants.ts @@ -221,3 +221,23 @@ export const iconVariants = cva({ mode: "default", }, }) + +export const loadingVariants = cva({ + base: "rounded-full border-solid border-t-transparent will-change-transform", + variants: { + size: { + sm: "h-3 w-3 border-[1px]", + md: "h-4 w-4 border-2", + lg: "h-5 w-5 border-2", + }, + variant: { + default: "border-f1-foreground-inverse border-t-transparent", + outline: "border-f1-foreground border-t-transparent", + neutral: "border-f1-foreground border-t-transparent", + critical: "border-f1-icon-critical border-t-transparent", + ghost: "border-f1-foreground border-t-transparent", + promote: "border-f1-icon-promote border-t-transparent", + outlinePromote: "border-f1-icon-promote border-t-transparent", + }, + }, +}) diff --git a/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx b/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx index 855416b681..6549e9e0fa 100644 --- a/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx +++ b/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx @@ -1,4 +1,4 @@ -import { Button } from "@/components/Actions/Button" +import { F0Button } from "@/components/actions/F0Button" import { GranularityDefinitionKey, OneCalendar, @@ -206,7 +206,7 @@ export function OneDatePickerPopup({ {(presets.length > 0 || granularities.length > 1) && (
{presets.length > 0 && ( - diff --git a/packages/react/src/ui/Action/types.ts b/packages/react/src/ui/Action/types.ts index d8d9883a30..c522afe109 100644 --- a/packages/react/src/ui/Action/types.ts +++ b/packages/react/src/ui/Action/types.ts @@ -16,9 +16,9 @@ export interface ActionCommonProps { prependOutside?: ReactNode appendOutside?: ReactNode - onClick?: (event?: React.MouseEvent) => void - onFocus?: (event?: React.FocusEvent) => void - onBlur?: (event?: React.FocusEvent) => void + onClick?: (event: React.MouseEvent) => void + onFocus?: (event: React.FocusEvent) => void + onBlur?: (event: React.FocusEvent) => void disabled?: boolean loading?: boolean @@ -33,6 +33,9 @@ export interface ActionCommonProps { mode?: "default" | "only" } +export const buttonTypes = ["button", "submit", "reset"] as const +export type ButtonType = (typeof buttonTypes)[number] + export const navTargets = ["_blank", "_self", "_parent", "_top"] as const export type NavTarget = (typeof navTargets)[number] export interface LinkActionProps { @@ -43,4 +46,6 @@ export interface LinkActionProps { export type ActionProps = ActionCommonProps & Partial & ActionVariantProps & - DataAttributes + DataAttributes & { + type?: ButtonType + } diff --git a/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx b/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx index 0316275bdb..8d1fbf63ec 100644 --- a/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx +++ b/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx @@ -227,7 +227,6 @@ export function OneDatePickerPopup({ icon={ChevronLeft} variant="neutral" size="sm" - round hideLabel label="Back" onClick={handleBackToPresets} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4f1e748531..9ea3da63dd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -389,6 +389,9 @@ importers: '@storybook/addon-a11y': specifier: ^9.1.3 version: 9.1.3(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) + '@storybook/addon-designs': + specifier: ^10.0.2 + version: 10.0.2(@storybook/addon-docs@9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) '@storybook/addon-docs': specifier: ^9.1.3 version: 9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) @@ -2341,7 +2344,7 @@ packages: '@expo/bunyan@4.0.1': resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==} - engines: {'0': node >=0.10.0} + engines: {node: '>=0.10.0'} '@expo/cli@0.22.24': resolution: {integrity: sha512-lhdenxBC8/x/vL39j79eXE09mOaqNNLmiSDdY/PblnI+UNzGgsQ48hBTYa/MQhd0ioXXVKurZL2941dLKwcxJw==} @@ -2420,6 +2423,14 @@ packages: '@fastify/busboy@3.1.1': resolution: {integrity: sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==} + '@figspec/components@1.0.3': + resolution: {integrity: sha512-fBwHzJ4ouuOUJEi+yBZIrOy+0/fAjB3AeTcIHTT1PRxLz8P63xwC7R0EsIJXhScIcc+PljGmqbbVJCjLsnaGYA==} + + '@figspec/react@1.0.4': + resolution: {integrity: sha512-jaPvkIef4d6NjsRiw91OZabrfdPH9FtoPGYcY5mpXjYEcdUqIq1aHtLq3SkMVyVysEapTEJ6yS8amy93MyXBEQ==} + peerDependencies: + react: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + '@floating-ui/core@1.6.9': resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} @@ -3158,6 +3169,15 @@ packages: peerDependencies: '@langchain/core': '>=0.2.21 <0.4.0' + '@lit-labs/react@1.2.1': + resolution: {integrity: sha512-DiZdJYFU0tBbdQkfwwRSwYyI/mcWkg3sWesKRsHUd4G+NekTmmeq9fzsurvcKTNVa0comNljwtg4Hvi1ds3V+A==} + + '@lit-labs/ssr-dom-shim@1.4.0': + resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} + + '@lit/reactive-element@1.6.3': + resolution: {integrity: sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==} + '@lukeed/csprng@1.1.0': resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} engines: {node: '>=8'} @@ -4569,6 +4589,21 @@ packages: peerDependencies: storybook: ^8.6.12 + '@storybook/addon-designs@10.0.2': + resolution: {integrity: sha512-MP7av/of6QMPH7bRjwjTC34GySy2bfyh3WwLWeztQOuNWMEFUOWzjh9iIyCiOBl7VADSXeL4SOJGIiGzQznFZw==} + peerDependencies: + '@storybook/addon-docs': ^0.0.0-0 || ^9.0.0 || ^9.1.0-0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + storybook: ^0.0.0-0 || ^9.0.0 || ^9.1.0-0 + peerDependenciesMeta: + '@storybook/addon-docs': + optional: true + react: + optional: true + react-dom: + optional: true + '@storybook/addon-docs@9.1.3': resolution: {integrity: sha512-iCzuHRyUgir2+ExqPO4ouxm90zW+6dkNuB4lyyFwNU10slJhVT8yGPk8PVOT6LhXMIii+7Hqc4dB0tj+kLOW/A==} peerDependencies: @@ -9162,6 +9197,15 @@ packages: linkifyjs@4.2.0: resolution: {integrity: sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw==} + lit-element@3.3.3: + resolution: {integrity: sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==} + + lit-html@2.8.0: + resolution: {integrity: sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==} + + lit@2.8.0: + resolution: {integrity: sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==} + load-json-file@4.0.0: resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} engines: {node: '>=4'} @@ -15332,6 +15376,16 @@ snapshots: '@fastify/busboy@3.1.1': {} + '@figspec/components@1.0.3': + dependencies: + lit: 2.8.0 + + '@figspec/react@1.0.4(react@18.3.1)': + dependencies: + '@figspec/components': 1.0.3 + '@lit-labs/react': 1.2.1 + react: 18.3.1 + '@floating-ui/core@1.6.9': dependencies: '@floating-ui/utils': 0.2.9 @@ -15928,6 +15982,14 @@ snapshots: transitivePeerDependencies: - encoding + '@lit-labs/react@1.2.1': {} + + '@lit-labs/ssr-dom-shim@1.4.0': {} + + '@lit/reactive-element@1.6.3': + dependencies: + '@lit-labs/ssr-dom-shim': 1.4.0 + '@lukeed/csprng@1.1.0': {} '@lukeed/uuid@2.0.1': @@ -17611,6 +17673,15 @@ snapshots: storybook: 8.6.14(prettier@2.8.8) ts-dedent: 2.2.0 + '@storybook/addon-designs@10.0.2(@storybook/addon-docs@9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))': + dependencies: + '@figspec/react': 1.0.4(react@18.3.1) + storybook: 9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) + optionalDependencies: + '@storybook/addon-docs': 9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + '@storybook/addon-docs@9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))': dependencies: '@mdx-js/react': 3.1.0(@types/react@18.3.18)(react@18.3.1) @@ -18631,8 +18702,7 @@ snapshots: '@types/tough-cookie@4.0.5': {} - '@types/trusted-types@2.0.7': - optional: true + '@types/trusted-types@2.0.7': {} '@types/twemoji-parser@13.1.4': {} @@ -19366,6 +19436,14 @@ snapshots: picocolors: 1.1.1 playwright: 1.52.0 + axios@1.8.4: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + axios@1.8.4(debug@4.4.1): dependencies: follow-redirects: 1.15.9(debug@4.4.1) @@ -21281,6 +21359,8 @@ snapshots: flow-parser@0.263.0: {} + follow-redirects@1.15.9: {} + follow-redirects@1.15.9(debug@4.4.1): optionalDependencies: debug: 4.4.1 @@ -21835,7 +21915,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.9(debug@4.4.1) + follow-redirects: 1.15.9 requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -23054,6 +23134,22 @@ snapshots: linkifyjs@4.2.0: {} + lit-element@3.3.3: + dependencies: + '@lit-labs/ssr-dom-shim': 1.4.0 + '@lit/reactive-element': 1.6.3 + lit-html: 2.8.0 + + lit-html@2.8.0: + dependencies: + '@types/trusted-types': 2.0.7 + + lit@2.8.0: + dependencies: + '@lit/reactive-element': 1.6.3 + lit-element: 3.3.3 + lit-html: 2.8.0 + load-json-file@4.0.0: dependencies: graceful-fs: 4.2.11 @@ -27199,7 +27295,7 @@ snapshots: wait-on@7.2.0: dependencies: - axios: 1.8.4(debug@4.4.1) + axios: 1.8.4 joi: 17.13.3 lodash: 4.17.21 minimist: 1.2.8 From b788425ef932ab35007a0dc50a8ceee0a7d0012a Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 11:51:58 +0200 Subject: [PATCH 05/38] refactor: use action instad legacy ui/button --- .../UpsellingKit/ProductModal/index.tsx | 3 +- .../UpsellingKit/ProductWidget/index.tsx | 3 +- .../components/actions/F0Button/F0Button.tsx | 7 +- .../actions/F0Button/internal-types.ts | 2 +- .../components/actions/F0Button/internal.tsx | 161 +++++++++--------- .../src/components/actions/F0Button/types.ts | 6 +- .../actions/F0ButtonDropdown/types.ts | 4 +- .../actions/internal/F0ButtonCopy/index.ts | 1 - .../avatars/F0AvatarPulse/F0AvatarPulse.tsx | 14 +- .../AiChat/components/AssistantMessage.tsx | 4 +- .../Information/Headers/Metadata/index.tsx | 4 +- .../Information/Reactions/Picker/index.tsx | 1 + .../Information/Reactions/reaction.tsx | 28 ++- .../Carousel/DynamicCarousel/index.tsx | 27 ++- .../F0TableOfContent/Item/PrimitiveItem.tsx | 22 ++- .../Header/Breadcrumbs/index.stories.tsx | 24 +-- .../Navigation/Sidebar/Icon/index.tsx | 14 +- .../CoreEditor/Toolbar/LinkPopup/index.tsx | 27 +-- .../Toolbar/ToolbarButton/index.tsx | 1 - .../RichText/RichTextEditor/Enhance/index.tsx | 6 +- packages/react/src/ui/Action/Action.tsx | 23 ++- .../ui/Action/__stories__/Action.stories.tsx | 16 ++ packages/react/src/ui/Action/types.ts | 83 +++++++-- .../ButtonCopy/ButtonCopy.tsx} | 48 +++--- .../__stories__/F0ButtonCopy.stories.tsx | 46 ++--- packages/react/src/ui/ButtonCopy/index.ts | 1 + .../F0ButtonCopy => ui/ButtonCopy}/types.ts | 0 27 files changed, 330 insertions(+), 246 deletions(-) delete mode 100644 packages/react/src/components/actions/internal/F0ButtonCopy/index.ts rename packages/react/src/{components/actions/internal/F0ButtonCopy/F0ButtonCopy.tsx => ui/ButtonCopy/ButtonCopy.tsx} (74%) rename packages/react/src/{components/actions/internal/F0ButtonCopy => ui/ButtonCopy}/__stories__/F0ButtonCopy.stories.tsx (86%) create mode 100644 packages/react/src/ui/ButtonCopy/index.ts rename packages/react/src/{components/actions/internal/F0ButtonCopy => ui/ButtonCopy}/types.ts (100%) diff --git a/packages/react/src/components/UpsellingKit/ProductModal/index.tsx b/packages/react/src/components/UpsellingKit/ProductModal/index.tsx index 619f134bf7..449e782704 100644 --- a/packages/react/src/components/UpsellingKit/ProductModal/index.tsx +++ b/packages/react/src/components/UpsellingKit/ProductModal/index.tsx @@ -1,7 +1,6 @@ -import { F0Button } from "@/components/actions/F0Button" +import { ButtonVariant, F0Button } from "@/components/actions/F0Button" import { IconType } from "@/components/F0Icon" import { ModuleId } from "@/experimental" -import { ButtonVariant } from "@/ui/button" import { useState } from "react" import { ProductBlankslate } from "../ProductBlankslate" import { UpsellRequestResponseDialog } from "../UpsellRequestResponseDialog" diff --git a/packages/react/src/components/UpsellingKit/ProductWidget/index.tsx b/packages/react/src/components/UpsellingKit/ProductWidget/index.tsx index 670c7ad2ec..2287ab8473 100644 --- a/packages/react/src/components/UpsellingKit/ProductWidget/index.tsx +++ b/packages/react/src/components/UpsellingKit/ProductWidget/index.tsx @@ -1,6 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" +import { ButtonVariant, F0Button } from "@/components/actions/F0Button" import CrossIcon from "@/icons/app/Cross" -import { ButtonVariant } from "@/ui/button" import { Card, CardContent, CardFooter } from "@/ui/Card" import { Label } from "@/ui/label" import { useEffect, useState } from "react" diff --git a/packages/react/src/components/actions/F0Button/F0Button.tsx b/packages/react/src/components/actions/F0Button/F0Button.tsx index ed99b7ff1e..3334e1be5a 100644 --- a/packages/react/src/components/actions/F0Button/F0Button.tsx +++ b/packages/react/src/components/actions/F0Button/F0Button.tsx @@ -6,17 +6,14 @@ import { forwardRef } from "react" import { ButtonInternal } from "./internal" import { ButtonInternalProps } from "./internal-types" -const privateProps = ["append", "className", "pressed"] as const +const privateProps = ["append", "className", "pressed", "compact"] as const export type F0ButtonProps = Omit< ButtonInternalProps, (typeof privateProps)[number] > -const F0Button = forwardRef< - HTMLButtonElement | HTMLAnchorElement, - F0ButtonProps ->((props, ref) => { +const F0Button = forwardRef((props, ref) => { const publicProps = privateProps.reduce((acc, key) => { const { [key]: _, ...rest } = acc return rest diff --git a/packages/react/src/components/actions/F0Button/internal-types.ts b/packages/react/src/components/actions/F0Button/internal-types.ts index 4d063d1dd6..a6413d03d4 100644 --- a/packages/react/src/components/actions/F0Button/internal-types.ts +++ b/packages/react/src/components/actions/F0Button/internal-types.ts @@ -6,7 +6,7 @@ export type { ButtonType } export type ButtonInternalProps = Pick< ActionProps, - "size" | "disabled" | "className" | "pressed" + "size" | "disabled" | "className" | "pressed" | "compact" > & DataAttributes & { /** diff --git a/packages/react/src/components/actions/F0Button/internal.tsx b/packages/react/src/components/actions/F0Button/internal.tsx index 90d52e62b1..c3226d55d2 100644 --- a/packages/react/src/components/actions/F0Button/internal.tsx +++ b/packages/react/src/components/actions/F0Button/internal.tsx @@ -48,94 +48,93 @@ export const iconOnlyVariants = cva({ /** * A button component internal that includes the private slots and props */ -const ButtonInternal = forwardRef< - HTMLButtonElement | HTMLAnchorElement, - ButtonInternalProps ->(function Button( - { - label, - hideLabel, - onClick, - disabled, - loading: forceLoading, - icon, - emoji, - href, - target, - variant = "default", - size = "md", - append, - className, - type, - ...props - }, - ref -) { - useTextFormatEnforcer(label, { disallowEmpty: true, disallowEmojis: true }) +const ButtonInternal = forwardRef( + function Button( + { + label, + hideLabel, + onClick, + disabled, + loading: forceLoading, + icon, + emoji, + href, + target, + variant = "default", + size = "md", + append, + className, + ...props + }, + ref + ) { + useTextFormatEnforcer(label, { disallowEmpty: true, disallowEmojis: true }) - const [loading, setLoading] = useState(false) + const [loading, setLoading] = useState(false) - const handleClick = async ( - event: React.MouseEvent< - HTMLElement | HTMLAnchorElement | HTMLButtonElement, - MouseEvent - > - ) => { - const result = onClick?.(event) + const handleClick = async ( + event: React.MouseEvent< + HTMLElement | HTMLAnchorElement | HTMLButtonElement, + MouseEvent + > + ) => { + const result = onClick?.(event) - if (result instanceof Promise) { - setLoading(true) + if (result instanceof Promise) { + setLoading(true) - try { - await result - } finally { - setLoading(false) + try { + await result + } finally { + setLoading(false) + } } } - } - const isLoading = forceLoading || loading - const shouldHideLabel = hideLabel || emoji + const isLoading = forceLoading || loading + const shouldHideLabel = hideLabel || emoji - return ( - -
- {icon && ( - - )} - {emoji && ( - - )} - {label} - {append} -
-
- ) -}) + return ( + +
+ {icon && ( + + )} + {emoji && ( + + )} + {label} + {append} +
+
+ ) + } +) export { ButtonInternal } diff --git a/packages/react/src/components/actions/F0Button/types.ts b/packages/react/src/components/actions/F0Button/types.ts index 239a5ca55b..9629a1592b 100644 --- a/packages/react/src/components/actions/F0Button/types.ts +++ b/packages/react/src/components/actions/F0Button/types.ts @@ -1,7 +1,7 @@ -import { sizes, variants } from "@/ui/button" +import { actionSizes, actionVariants } from "@/ui/Action" -export const buttonVariants = variants +export const buttonVariants = actionVariants export type ButtonVariant = (typeof buttonVariants)[number] -export const buttonSizes = sizes +export const buttonSizes = actionSizes export type ButtonSize = (typeof buttonSizes)[number] diff --git a/packages/react/src/components/actions/F0ButtonDropdown/types.ts b/packages/react/src/components/actions/F0ButtonDropdown/types.ts index 4949d70e2d..dab1644f69 100644 --- a/packages/react/src/components/actions/F0ButtonDropdown/types.ts +++ b/packages/react/src/components/actions/F0ButtonDropdown/types.ts @@ -1,9 +1,9 @@ import { IconType } from "@/components/F0Icon" -import { sizes } from "@/ui/button.tsx" +import { actionSizes } from "@/ui/Action" export const buttonDropdownVariants = ["default", "outline", "neutral"] as const export type ButtonDropdownVariant = (typeof buttonDropdownVariants)[number] -export const buttonDropdownSizes = sizes +export const buttonDropdownSizes = actionSizes export type ButtonDropdownSize = (typeof buttonDropdownSizes)[number] export type ButtonDropdownItem = { diff --git a/packages/react/src/components/actions/internal/F0ButtonCopy/index.ts b/packages/react/src/components/actions/internal/F0ButtonCopy/index.ts deleted file mode 100644 index aa5a7c519c..0000000000 --- a/packages/react/src/components/actions/internal/F0ButtonCopy/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./F0ButtonCopy" diff --git a/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx b/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx index 8dfb73fea6..265f296de2 100644 --- a/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx +++ b/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { ButtonInternal } from "@/components/actions/F0Button/internal" import { F0Icon, F0IconProps, IconType } from "@/components/F0Icon" import { FaceNegative, @@ -10,7 +10,7 @@ import { } from "@/icons/app" import { EmojiImage } from "@/lib/emojis" import { useI18n } from "@/lib/providers/i18n" -import { Button } from "@/ui/button" +import { Action } from "@/ui/Action" import { AnimatePresence, motion } from "motion/react" import { ComponentProps, useState } from "react" import { BaseAvatar } from "../internal/BaseAvatar" @@ -153,22 +153,23 @@ export const F0AvatarPulse = ({ /> {pulse ? (
- +
) : ( -
- { if (isMetadataCopyAction(action)) { return ( - (null) + const buttonRef = useRef(null) const { fireEmojiConfetti } = useEmojiConfetti() - const handleClick = ( - event: React.MouseEvent, - emoji: string - ) => { + const handleClick = (event: React.MouseEvent, emoji: string) => { event.stopPropagation() setCount(count + (isActive ? -1 : 1)) setIsActive(!isActive) @@ -50,21 +43,22 @@ export function Reaction({ const tooltipContent = users?.map((user) => user.name).join(", ") || "" const button = ( - + ) return tooltipContent ? ( diff --git a/packages/react/src/experimental/Navigation/Carousel/DynamicCarousel/index.tsx b/packages/react/src/experimental/Navigation/Carousel/DynamicCarousel/index.tsx index 3c135281b7..24ad8c3bbb 100644 --- a/packages/react/src/experimental/Navigation/Carousel/DynamicCarousel/index.tsx +++ b/packages/react/src/experimental/Navigation/Carousel/DynamicCarousel/index.tsx @@ -1,7 +1,6 @@ -import { F0Icon } from "@/components/F0Icon" +import { ButtonInternal } from "@/components/actions/F0Button/internal" import { ChevronLeft, ChevronRight } from "@/icons/app" import { cn } from "@/lib/utils" -import { Button } from "@/ui/button" import { PropsWithChildren, useLayoutEffect, useRef, useState } from "react" export const SPACE_FOR_WIDGET_SHADOW = 28 @@ -117,35 +116,35 @@ export const DynamicCarousel = ({ children }: PropsWithChildren) => {
{canScrollPrev && ( - + icon={ChevronLeft} + label="Previous" + hideLabel + > )} {canScrollNext && ( - + icon={ChevronRight} + label="Next" + hideLabel + > )}
) diff --git a/packages/react/src/experimental/Navigation/F0TableOfContent/Item/PrimitiveItem.tsx b/packages/react/src/experimental/Navigation/F0TableOfContent/Item/PrimitiveItem.tsx index 59b215340f..15508ddd32 100644 --- a/packages/react/src/experimental/Navigation/F0TableOfContent/Item/PrimitiveItem.tsx +++ b/packages/react/src/experimental/Navigation/F0TableOfContent/Item/PrimitiveItem.tsx @@ -1,10 +1,10 @@ +import { ButtonInternal } from "@/components/actions/F0Button/internal" import { F0Icon } from "@/components/F0Icon" import { OneEllipsis } from "@/components/OneEllipsis/OneEllipsis" import { Counter } from "@/experimental" import { ChevronDown, ChevronRight, Handle } from "@/icons/app" import { useI18n } from "@/lib/providers/i18n" import { cn, focusRing } from "@/lib/utils" -import { Button } from "@/ui/button" import { AnimatePresence, DragControls, motion } from "motion/react" import { ReactNode } from "react" import { TOCItem } from "../types" @@ -56,8 +56,8 @@ export function PrimitiveItem({ return (
{collapsible && ( - + icon={isExpanded ? ChevronDown : ChevronRight} + label={translations.actions.toggle} + hideLabel + > )}
- +
) : ( icon && ( diff --git a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx index 6c493756cf..bef41cfe93 100644 --- a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx +++ b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx @@ -1,6 +1,7 @@ import { IconType } from "@/components/F0Icon" import { FiltersDefinition } from "@/components/OneFilterPicker" import { SelectItemProps } from "@/experimental/Forms/Fields/Select/types" +import { F0Button } from "@/f0" import { PaginatedFetchOptions } from "@/hooks/datasource" import { FIRST_NAMES_MOCK, @@ -10,7 +11,6 @@ import { } from "@/mocks" import type { Meta, StoryObj } from "@storybook/react-vite" import { useState } from "react" -import { Button } from "../../../../ui/button" import { Breadcrumbs, BreadcrumbsProps } from "./index" const meta: Meta = { @@ -324,7 +324,7 @@ export const Interactive: Story = { return (
- - - + label="Remove Breadcrumb" + > +
@@ -90,6 +90,6 @@ export function SidebarIcon() {
- + ) } diff --git a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/LinkPopup/index.tsx b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/LinkPopup/index.tsx index 97524fe56b..83a9d29320 100644 --- a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/LinkPopup/index.tsx +++ b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/LinkPopup/index.tsx @@ -1,3 +1,5 @@ +import { F0Button } from "@/components/actions/F0Button" +import { ButtonInternal } from "@/components/actions/F0Button/internal" import { F0ButtonToggle } from "@/components/F0ButtonToggle" import { F0Icon } from "@/components/F0Icon" import { Badge } from "@/experimental/Information/Badge" @@ -10,7 +12,6 @@ import { } from "@/icons/app" import { useI18n } from "@/lib/providers/i18n" import { cn, focusRing } from "@/lib/utils" -import { Button } from "@/ui/button" import * as Popover from "@radix-ui/react-popover" import { Editor } from "@tiptap/react" import { AnimatePresence, motion } from "motion/react" @@ -112,7 +113,8 @@ export const LinkPopup = ({ editor, disabled, labels }: LinkPopupProps) => { aria-label="Link popup" >
- + label="Close link popup" + hideLabel + icon={Cross} + >
{ /> )} - + label={labels.linkPaste} + >
- + label={i18n.actions.save} + >
)} diff --git a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/ToolbarButton/index.tsx b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/ToolbarButton/index.tsx index 19b8e7879a..58d169c2f2 100644 --- a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/ToolbarButton/index.tsx +++ b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/ToolbarButton/index.tsx @@ -2,7 +2,6 @@ import { F0Icon, IconType } from "@/components/F0Icon" import { Shortcut } from "@/experimental/Information/Shortcut" import { Tooltip } from "@/experimental/Overlays/Tooltip" import { cn } from "@/lib/utils" -import { Button } from "@/ui/button" import { ComponentProps, forwardRef } from "react" interface ToolbarButtonProps { diff --git a/packages/react/src/experimental/RichText/RichTextEditor/Enhance/index.tsx b/packages/react/src/experimental/RichText/RichTextEditor/Enhance/index.tsx index 03503e487d..929021ffbd 100644 --- a/packages/react/src/experimental/RichText/RichTextEditor/Enhance/index.tsx +++ b/packages/react/src/experimental/RichText/RichTextEditor/Enhance/index.tsx @@ -1,7 +1,7 @@ import { F0Icon } from "@/components/F0Icon" import { Ai } from "@/icons/app" import { cn } from "@/lib/utils" -import { Button } from "@/ui/button" +import { Action } from "@/ui/Action" import * as Popover from "@radix-ui/react-popover" import { Editor } from "@tiptap/react" import { AnimatePresence, motion } from "motion/react" @@ -59,7 +59,7 @@ const EnhanceActivator = ({ }} > - + ( variant, size = "md", mode = "default", - type = "button", + title, + compact = false, ...props }, ref @@ -49,17 +51,32 @@ export const Action = React.forwardRef( ? linkSizeVariants({ size }) : buttonSizeVariants({ size }) + const compactClasses = cva({ + variants: { + size: { + sm: "!px-1", + md: "!px-[6px]", + lg: "!px-[10px]", + }, + }, + defaultVariants: { + size: "md", + }, + }) const innerContent = ( <>
{prepend} - {children} + + {children} + {append}
@@ -96,6 +113,7 @@ export const Action = React.forwardRef( disabled, className: cn(variantClasses, sizeClasses, focusRing(), className), "aria-busy": loading, + title, ...props, } @@ -115,7 +133,6 @@ export const Action = React.forwardRef( {...CommonProps} ref={ref as React.Ref} data-pressed={pressed} - type={type} > {innerContent} diff --git a/packages/react/src/ui/Action/__stories__/Action.stories.tsx b/packages/react/src/ui/Action/__stories__/Action.stories.tsx index ec5a5951d0..0e8438f718 100644 --- a/packages/react/src/ui/Action/__stories__/Action.stories.tsx +++ b/packages/react/src/ui/Action/__stories__/Action.stories.tsx @@ -160,3 +160,19 @@ export const AllSizes: Story = {
), } + +export const AllCompact: Story = { + render: () => ( +
+ + + + + + + + + +
+ ), +} diff --git a/packages/react/src/ui/Action/types.ts b/packages/react/src/ui/Action/types.ts index c522afe109..d10017b98e 100644 --- a/packages/react/src/ui/Action/types.ts +++ b/packages/react/src/ui/Action/types.ts @@ -1,36 +1,92 @@ -import { sizes, variants } from "@/ui/button" import { ReactNode } from "react" import { ActionVariantProps } from "./internal-types" -export const actionVariants = variants +export const actionButtonVariants = [ + "default", + "outline", + "critical", + "neutral", + "ghost", + "promote", + "outlinePromote", +] as const +export type ActionButtonVariant = (typeof actionButtonVariants)[number] + +export const actionLinkVariants = ["link"] as const +export type ActionLinkVariant = (typeof actionLinkVariants)[number] + +export const actionVariants = [ + ...actionButtonVariants, + ...actionLinkVariants, +] as const export type ActionVariant = (typeof actionVariants)[number] -export const actionSizes = sizes +export const actionSizes = ["sm", "md", "lg"] as const export type ActionSize = (typeof actionSizes)[number] export interface ActionCommonProps { + /** + * The children of the action. + */ children: ReactNode + /** + * The prepend of the action. + */ prepend?: ReactNode + /** + * The append of the action. + */ append?: ReactNode + /** + * The prepend outside (next to the button) of the action. + */ prependOutside?: ReactNode + /** + * The append outside of the action. + */ appendOutside?: ReactNode onClick?: (event: React.MouseEvent) => void onFocus?: (event: React.FocusEvent) => void onBlur?: (event: React.FocusEvent) => void + /** + * The disabled state of the action. + */ disabled?: boolean + /** + * The loading state of the action. + */ loading?: boolean + /** + * The pressed state of the action. + */ pressed?: boolean + /** + * The class name of the action. + */ className?: string + /** + * The size of the action. + */ size?: ActionSize /** * The render mode. * @default "default" */ mode?: "default" | "only" + + /** + * The title of the action. + */ + title?: string + + /** + * make the left and right padding of the action smaller. + */ + compact?: boolean } export const buttonTypes = ["button", "submit", "reset"] as const @@ -38,14 +94,19 @@ export type ButtonType = (typeof buttonTypes)[number] export const navTargets = ["_blank", "_self", "_parent", "_top"] as const export type NavTarget = (typeof navTargets)[number] -export interface LinkActionProps { - href: string - target?: NavTarget -} export type ActionProps = ActionCommonProps & - Partial & ActionVariantProps & - DataAttributes & { - type?: ButtonType - } + DataAttributes & + // as link + (| { + href: string + target?: NavTarget + } + // as button + | { + type?: ButtonType + href?: never + target?: never + } + ) diff --git a/packages/react/src/components/actions/internal/F0ButtonCopy/F0ButtonCopy.tsx b/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx similarity index 74% rename from packages/react/src/components/actions/internal/F0ButtonCopy/F0ButtonCopy.tsx rename to packages/react/src/ui/ButtonCopy/ButtonCopy.tsx index efec530318..242e82a385 100644 --- a/packages/react/src/components/actions/internal/F0ButtonCopy/F0ButtonCopy.tsx +++ b/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx @@ -1,25 +1,27 @@ +import { F0Icon } from "@/components/F0Icon" import { Check, LayersFront } from "@/icons/app" import { useI18n } from "@/lib/providers/i18n" -import { Button as ShadcnButton } from "@/ui/button" +import { Action, ActionButtonVariant, ActionProps } from "@/ui/Action" import { AnimatePresence, motion } from "motion/react" -import { - ComponentProps, - forwardRef, - MouseEventHandler, - useEffect, - useState, -} from "react" -import { F0Icon } from "../../../F0Icon" -import { iconOnlyVariants } from "../../F0Button/internal" +import { forwardRef, MouseEventHandler, useEffect, useState } from "react" +import { iconOnlyVariants } from "../../components/actions/F0Button/internal" -export type F0ButtonCopyProps = Omit< - ComponentProps, - "onClick" | "children" | "title" | "label" | "hideLabel" | "icon" | "round" +export type ButtonCopyProps = Omit< + ActionProps, + | "onClick" + | "children" + | "title" + | "label" + | "hideLabel" + | "icon" + | "href" + | "target" > & { valueToCopy: string copiedTooltipLabel?: string copyTooltipLabel?: string - onCopy?: MouseEventHandler + onCopy?: MouseEventHandler + variant?: ActionButtonVariant } const copyIconMotionVariants = { @@ -29,7 +31,7 @@ const copyIconMotionVariants = { } const copyIconTransition = { duration: 0.15, ease: "easeOut" } -export const F0ButtonCopy = forwardRef( +export const ButtonCopy = forwardRef( ( { valueToCopy, @@ -63,7 +65,7 @@ export const F0ButtonCopy = forwardRef( } }, [isCopying]) - const handleCopyClick: MouseEventHandler = (event) => { + const handleCopyClick: MouseEventHandler = (event) => { event.stopPropagation() window.navigator.clipboard.writeText(valueToCopy) setIsCopying(true) @@ -71,16 +73,16 @@ export const F0ButtonCopy = forwardRef( } return ( - ( alignItems: "center", justifyContent: "center", verticalAlign: "middle", - width: "1em", - height: "1em", }} > - + ) } ) -F0ButtonCopy.displayName = "F0CopyButton" +ButtonCopy.displayName = "ButtonCopy" diff --git a/packages/react/src/components/actions/internal/F0ButtonCopy/__stories__/F0ButtonCopy.stories.tsx b/packages/react/src/ui/ButtonCopy/__stories__/F0ButtonCopy.stories.tsx similarity index 86% rename from packages/react/src/components/actions/internal/F0ButtonCopy/__stories__/F0ButtonCopy.stories.tsx rename to packages/react/src/ui/ButtonCopy/__stories__/F0ButtonCopy.stories.tsx index b0dd43658e..61efa58723 100644 --- a/packages/react/src/components/actions/internal/F0ButtonCopy/__stories__/F0ButtonCopy.stories.tsx +++ b/packages/react/src/ui/ButtonCopy/__stories__/F0ButtonCopy.stories.tsx @@ -2,16 +2,16 @@ import { withSnapshot } from "@/lib/storybook-utils/parameters" import type { Meta, StoryObj } from "@storybook/react-vite" import React, { useEffect } from "react" import { expect, userEvent, within } from "storybook/test" -import { F0ButtonCopy } from "../F0ButtonCopy" +import { ButtonCopy } from "../ButtonCopy" import { buttonCopySizes } from "../types" const meta = { - title: "Actions/ButtonCopy", - component: F0ButtonCopy, + title: "Components/ButtonCopy", + component: ButtonCopy, parameters: { layout: "centered", }, - tags: ["autodocs", "experimental", "internal"], + tags: ["autodocs", "internal"], args: { valueToCopy: "Hello World!", variant: "neutral", @@ -62,7 +62,7 @@ const meta = { description: "Callback fired when the copy action is performed.", }, }, -} satisfies Meta +} satisfies Meta export default meta type Story = StoryObj @@ -99,12 +99,12 @@ export const Variants: Story = { parameters: withSnapshot({}), render: (args) => (
- - - - - - + + + + + +
), } @@ -113,9 +113,9 @@ export const Sizes: Story = { parameters: withSnapshot({}), render: (args) => (
- - - + + +
), } @@ -150,7 +150,7 @@ export const DifferentValues: Story = {
Email: -
URL: -
Token: -
Code: - (
- - + +
), } @@ -204,7 +204,7 @@ export const InteractiveCopyTest: Story = { return (
-
- + - {appendOutside &&
{append}
} + {appendOutside &&
{appendOutside}
} ), })) @@ -76,7 +76,7 @@ describe("F0ButtonDropdown", () => { }) it("renders with default selection (first item)", () => { - render() + render() expect(screen.getByTestId("button-main")).toBeDefined() expect(screen.getByTestId("dropdown")).toBeDefined() @@ -86,11 +86,7 @@ describe("F0ButtonDropdown", () => { it("renders with provided value", () => { render( - + ) expect(screen.getByTestId("button-main")).toBeDefined() @@ -99,11 +95,7 @@ describe("F0ButtonDropdown", () => { it("passes dropdown items excluding the selected item", () => { render( - + ) const dropdownElement = screen.getByTestId("dropdown") @@ -123,11 +115,7 @@ describe("F0ButtonDropdown", () => { it("calls onClick with correct values when button is clicked", async () => { const user = userEvent.setup() render( - + ) await user.click(screen.getByTestId("button-main")) @@ -139,7 +127,7 @@ describe("F0ButtonDropdown", () => { it("does not open dropdown when disabled", async () => { const user = userEvent.setup() render( - { it.skip("changes selected value when dropdown item is clicked", async () => { const user = userEvent.setup() render( - + ) await openDropdown(user) diff --git a/packages/react/src/experimental/Navigation/Carousel/index.tsx b/packages/react/src/experimental/Navigation/Carousel/index.tsx index 7e3f52ac7e..9147bcf9d0 100644 --- a/packages/react/src/experimental/Navigation/Carousel/index.tsx +++ b/packages/react/src/experimental/Navigation/Carousel/index.tsx @@ -132,8 +132,8 @@ export const Carousel = ({ {showArrows && ( <> - - + + )}
diff --git a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.test.tsx b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.test.tsx index d3690624d4..3c4dc462a1 100644 --- a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.test.tsx +++ b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.test.tsx @@ -1,6 +1,6 @@ +import { Home, Settings } from "@/icons/app" import { render, within } from "@testing-library/react" import { beforeEach, describe, expect, it, vi } from "vitest" -import { Home, Settings } from "../../../../icons/app" import { Breadcrumbs } from "./index" // Mock ResizeObserver diff --git a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/ToolbarButton/index.tsx b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/ToolbarButton/index.tsx index 58d169c2f2..f1120e1f9d 100644 --- a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/ToolbarButton/index.tsx +++ b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/ToolbarButton/index.tsx @@ -2,6 +2,7 @@ import { F0Icon, IconType } from "@/components/F0Icon" import { Shortcut } from "@/experimental/Information/Shortcut" import { Tooltip } from "@/experimental/Overlays/Tooltip" import { cn } from "@/lib/utils" +import { Action } from "@/ui/Action" import { ComponentProps, forwardRef } from "react" interface ToolbarButtonProps { @@ -33,7 +34,7 @@ export const ToolbarButton = forwardRef( ref ) => { const CustomButton = ( - + ) return tooltip ? ( diff --git a/packages/react/src/experimental/RichText/NotesTextEditor/index.tsx b/packages/react/src/experimental/RichText/NotesTextEditor/index.tsx index 696c2ffdd7..beb5cf193d 100644 --- a/packages/react/src/experimental/RichText/NotesTextEditor/index.tsx +++ b/packages/react/src/experimental/RichText/NotesTextEditor/index.tsx @@ -1,9 +1,9 @@ +import { ButtonInternal } from "@/components/actions/F0Button/internal" import { F0Icon } from "@/components/F0Icon" import { Toolbar, ToolbarLabels } from "@/experimental/RichText/CoreEditor" import { SlashCommandGroupLabels } from "@/experimental/RichText/CoreEditor/Extensions/SlashCommand" import { Handle, Plus } from "@/icons/app" import { cn } from "@/lib/utils" -import { Button } from "@/ui/button" import { ScrollArea } from "@/ui/scrollarea" import DragHandle from "@tiptap/extension-drag-handle-react" import { Node } from "@tiptap/pm/model" @@ -257,25 +257,24 @@ const NotesTextEditorComponent = forwardRef< onNodeChange={handleNodeChange} >
- - +
diff --git a/packages/react/src/ui/ButtonCopy/types.ts b/packages/react/src/ui/ButtonCopy/types.ts index ae1761a5c8..29b1093eb4 100644 --- a/packages/react/src/ui/ButtonCopy/types.ts +++ b/packages/react/src/ui/ButtonCopy/types.ts @@ -1,4 +1,4 @@ -import { sizes } from "@/ui/button" +import { actionSizes } from "@/ui/Action" -export const buttonCopySizes = sizes +export const buttonCopySizes = actionSizes export type ButtonCopySize = (typeof buttonCopySizes)[number] diff --git a/packages/react/src/ui/button.tsx b/packages/react/src/ui/button.tsx deleted file mode 100644 index ead736aada..0000000000 --- a/packages/react/src/ui/button.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "cva" -import * as React from "react" -import { useRef } from "react" -import { cn, focusRing } from "../lib/utils" - -export const variants = [ - "default", - "outline", - "critical", - "neutral", - "ghost", - "promote", - "outlinePromote", -] as const -export type ButtonVariant = (typeof variants)[number] - -export const sizes = ["sm", "md", "lg"] as const -export type ButtonSize = (typeof sizes)[number] - -const buttonVariants = cva({ - base: cn( - "group relative inline-flex items-center justify-center gap-1 whitespace-nowrap rounded border-none p-0 text-base font-medium shadow-[0_2px_6px_-1px_rgba(13,22,37,.04),inset_0_-2px_4px_rgba(13,22,37,.04)] transition-colors [&_button]:transform-gpu [&_button]:transition-transform [&_button]:duration-100 active:[&_button]:translate-y-px" - ), - variants: { - disabled: { - true: "pointer-events-none opacity-50", - false: cn("cursor-pointer", focusRing()), - }, - pressed: { - true: "[&_button]:translate-y-px", - false: "", - }, - variant: { - default: cn( - "bg-f1-background-accent-bold text-f1-foreground-inverse shadow-[0_2px_6px_-1px_rgba(13,22,37,.10),inset_0_-2px_4px_rgba(13,22,37,.08)] after:pointer-events-none after:absolute after:inset-0 after:rounded after:shadow-[inset_0_1px_0_0_rgba(255,255,255,0.25)] after:content-[''] hover:bg-f1-background-accent-bold-hover", - "active:bg-f1-background-accent-bold-hover active:shadow-[0_-2px_6px_-1px_rgba(13,22,37,.10)] active:after:shadow-[inset_0_3px_6px_0_rgba(13,22,37,.2)]", - "data-[pressed=true]:bg-f1-background-accent-bold-hover data-[pressed=true]:shadow-[0_-2px_6px_-1px_rgba(13,22,37,.10)] data-[pressed=true]:after:shadow-[inset_0_3px_6px_0_rgba(13,22,37,.2)]" - ), - outline: cn( - "bg-f1-background-inverse-secondary text-f1-foreground after:pointer-events-none after:absolute after:inset-0 after:rounded after:ring-1 after:ring-inset after:ring-f1-border after:transition-all after:content-[''] hover:bg-f1-background-tertiary hover:after:opacity-70 hover:after:ring-f1-border-hover", - "active:bg-f1-background-tertiary active:shadow-[inset_0_2px_6px_0_rgba(13,22,37,.15)] active:after:opacity-70 active:after:ring-f1-border-hover", - "data-[pressed=true]:bg-f1-background-tertiary data-[pressed=true]:shadow-[inset_0_2px_6px_0_rgba(13,22,37,.15)] data-[pressed=true]:after:opacity-70 data-[pressed=true]:after:ring-f1-border-hover" - ), - neutral: cn( - "bg-f1-background-secondary text-f1-foreground hover:bg-f1-background-secondary-hover", - "active:bg-f1-background-secondary-hover active:shadow-[inset_0_2px_8px_0_rgba(13,22,37,.16)]", - "data-[pressed=true]:bg-f1-background-secondary-hover data-[pressed=true]:shadow-[inset_0_2px_8px_0_rgba(13,22,37,.16)]" - ), - critical: cn( - "bg-f1-background-secondary text-f1-foreground-critical after:pointer-events-none after:absolute after:inset-0 after:rounded after:ring-1 after:ring-inset after:ring-f1-border after:transition-all after:content-[''] hover:bg-f1-background-critical-bold hover:text-f1-foreground-inverse hover:after:ring-transparent dark:bg-transparent dark:hover:bg-f1-background-critical-bold", - "active:bg-f1-background-critical-bold active:text-f1-foreground-inverse active:after:shadow-[inset_0_3px_6px_0_rgba(13,22,37,.2)] active:after:ring-transparent", - "data-[pressed=true]:bg-f1-background-critical-bold data-[pressed=true]:text-f1-foreground-inverse data-[pressed=true]:after:shadow-[inset_0_3px_6px_0_rgba(13,22,37,.2)] data-[pressed=true]:after:ring-transparent" - ), - ghost: cn( - "bg-transparent text-f1-foreground shadow-none hover:bg-f1-background-secondary-hover hover:shadow-[0_2px_6px_-1px_rgba(13,22,37,.04),inset_0_-2px_4px_rgba(13,22,37,.04)]", - "active:bg-f1-background-secondary-hover active:shadow-[inset_0_2px_4px_0_rgba(13,22,37,.1)]", - "data-[pressed=true]:bg-f1-background-secondary-hover data-[pressed=true]:shadow-[inset_0_2px_4px_0_rgba(13,22,37,.1)]" - ), - promote: cn( - "bg-f1-background-promote text-f1-foreground shadow-[0_2px_6px_-1px_rgba(13,22,37,.04),inset_0_-2px_4px_rgba(245,165,28,.15)] after:pointer-events-none after:absolute after:inset-0 after:rounded after:ring-1 after:ring-inset after:ring-f1-border-promote after:transition-all after:content-[''] hover:bg-f1-background-promote-hover dark:shadow-[0_2px_6px_-1px_rgba(13,22,37,.04),inset_0_-2px_4px_rgba(13,22,37,.30)]", - "active:shadow-[inset_0_2px_4px_0_rgba(206,139,24,.5)]", - "data-[pressed=true]:shadow-[inset_0_2px_4px_0_rgba(206,139,24,.5)]" - ), - outlinePromote: cn( - "bg-f1-background-inverse-secondary text-f1-foreground after:pointer-events-none after:absolute after:inset-0 after:rounded after:ring-1 after:ring-inset after:ring-f1-border after:transition-all after:content-[''] hover:bg-f1-background-tertiary hover:after:opacity-70 hover:after:ring-f1-border-hover", - "active:bg-f1-background-tertiary active:shadow-[inset_0_2px_6px_0_rgba(13,22,37,.15)] active:after:opacity-70 active:after:ring-f1-border-hover", - "data-[pressed=true]:bg-f1-background-tertiary data-[pressed=true]:shadow-[inset_0_2px_6px_0_rgba(13,22,37,.15)] data-[pressed=true]:after:opacity-70 data-[pressed=true]:after:ring-f1-border-hover" - ), - } satisfies Record, - size: { - sm: "rounded-sm after:rounded-sm", - md: "rounded", - lg: "rounded-md after:rounded-md", - } satisfies Record, - }, - defaultVariants: { - variant: "default", - size: "md", - pressed: false, - }, -}) - -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean - round?: boolean - size?: ButtonSize - variant?: ButtonVariant - appendButton?: React.ReactNode - pressed?: boolean -} - -const Button = React.forwardRef( - ( - { - className, - round = false, - variant, - disabled, - size, - asChild = false, - appendButton, - pressed, - children, - ...props - }, - ref - ) => { - const innerRef = useRef(null) - // Combine the refs - use forwarded ref if provided, otherwise fall back to inner ref - const buttonRef = (ref || innerRef) as React.RefObject - - const Comp = asChild ? Slot : "div" - return ( - <> - button]:rounded-r-none", - className - )} - data-pressed={pressed} - aria-disabled={disabled} - tabIndex={disabled ? -1 : 0} - onClick={(e) => { - e.preventDefault() - buttonRef.current?.click() - }} - onKeyDown={(e) => { - if (e.key === "Enter" || e.key === " ") { - e.preventDefault() - buttonRef.current?.click() - } - }} - > - - - {appendButton && ( -
button]:rounded-l-none [&>div:after]:rounded-l-none [&>div]:rounded-l-none", - size === "sm" && "h-6 w-6", - size === "md" && "h-8 w-8", - size === "lg" && "h-10 w-10" - )} - > - {appendButton} -
- )} - - ) - } -) -Button.displayName = "Button" - -export { Button, buttonVariants } diff --git a/packages/react/src/ui/carousel.tsx b/packages/react/src/ui/carousel.tsx index f861a3253f..87161f4891 100644 --- a/packages/react/src/ui/carousel.tsx +++ b/packages/react/src/ui/carousel.tsx @@ -1,15 +1,15 @@ "use client" +import { ArrowLeft, ArrowRight } from "@/icons/app" import useEmblaCarousel, { type UseEmblaCarouselType, } from "embla-carousel-react" import * as React from "react" -import { F0Icon } from "../components/F0Icon" -import { ArrowLeft, ArrowRight } from "../icons/app" -import { SPACE_FOR_WIDGET_SHADOW } from "../experimental/Navigation/Carousel/DynamicCarousel" -import { cn } from "../lib/utils" -import { Button } from "./button" +import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternalProps } from "@/components/actions/F0Button/internal-types" +import { SPACE_FOR_WIDGET_SHADOW } from "@/experimental/Navigation/Carousel/DynamicCarousel" +import { cn } from "@/lib/utils" type CarouselApi = UseEmblaCarouselType[1] type UseCarouselParameters = Parameters @@ -211,76 +211,70 @@ const CarouselItem = React.forwardRef< }) CarouselItem.displayName = "CarouselItem" -const CarouselPrevious = React.forwardRef< - HTMLButtonElement, - React.ComponentProps ->(({ className, variant = "outline", ...props }, ref) => { - const { orientation, scrollPrev, canScrollPrev } = useCarousel() +const CarouselPrevious = React.forwardRef( + ({ className, variant = "outline", ...props }, ref) => { + const { orientation, scrollPrev, canScrollPrev } = useCarousel() - return ( -
- -
- ) -}) + +
+ ) + } +) CarouselPrevious.displayName = "CarouselPrevious" -const CarouselNext = React.forwardRef< - HTMLButtonElement, - React.ComponentProps ->(({ className, variant = "outline", ...props }, ref) => { - const { orientation, scrollNext, canScrollNext } = useCarousel() +const CarouselNext = React.forwardRef( + ({ className, variant = "outline", ...props }, ref) => { + const { orientation, scrollNext, canScrollNext } = useCarousel() - return ( -
- -
- ) -}) + +
+ ) + } +) CarouselNext.displayName = "CarouselNext" const CarouselDots = React.forwardRef< From d437f214e0427048fb4aa113d0155d2c86817ab6 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 13:21:45 +0200 Subject: [PATCH 07/38] chore: lint --- .../components/OneFilterPicker/components/FiltersChipsList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/components/OneFilterPicker/components/FiltersChipsList.tsx b/packages/react/src/components/OneFilterPicker/components/FiltersChipsList.tsx index 45dd7490c7..c4fe846f4e 100644 --- a/packages/react/src/components/OneFilterPicker/components/FiltersChipsList.tsx +++ b/packages/react/src/components/OneFilterPicker/components/FiltersChipsList.tsx @@ -1,6 +1,6 @@ import { F0Button } from "@/components/actions/F0Button" -import { AnimatePresence } from "motion/react" import { useI18n } from "@/lib/providers/i18n" +import { AnimatePresence } from "motion/react" import { FilterDefinitionsByType, FilterTypeDefinition, From 000a02bf2357a21b21532337200ca7b3fe62a75c Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 14:17:06 +0200 Subject: [PATCH 08/38] chore: fix --- .../src/experimental/RichText/NotesTextEditor/index.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx b/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx index 5621c2e9a5..1d0be760ac 100644 --- a/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx +++ b/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx @@ -336,7 +336,6 @@ export const Default: Story = { type: "text", label: "Text", content: "Metadata", - label: "Metadata", }, ], }, From 83c1cfa17a7ce7db741481b4d398dea666dc7809 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 14:22:21 +0200 Subject: [PATCH 09/38] chore: fix imports --- packages/react/src/components/F0ButtonToggle/types.ts | 2 +- .../Navigation/Header/Breadcrumbs/index.stories.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react/src/components/F0ButtonToggle/types.ts b/packages/react/src/components/F0ButtonToggle/types.ts index 71481e005f..46484b0c4e 100644 --- a/packages/react/src/components/F0ButtonToggle/types.ts +++ b/packages/react/src/components/F0ButtonToggle/types.ts @@ -1,4 +1,4 @@ -import { IconType } from "@/f0" +import { IconType } from "@/components/F0Icon" export const buttonToggleSizes = ["sm", "md", "lg"] as const export type ButtonToggleSize = (typeof buttonToggleSizes)[number] diff --git a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx index bef41cfe93..366f30cfea 100644 --- a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx +++ b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx @@ -1,7 +1,7 @@ +import { F0Button } from "@/components/actions/F0Button" import { IconType } from "@/components/F0Icon" import { FiltersDefinition } from "@/components/OneFilterPicker" import { SelectItemProps } from "@/experimental/Forms/Fields/Select/types" -import { F0Button } from "@/f0" import { PaginatedFetchOptions } from "@/hooks/datasource" import { FIRST_NAMES_MOCK, From a165fc46704ab3513c754fe5aa7486ce4d172dc6 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 15:35:19 +0200 Subject: [PATCH 10/38] chore: button aria label --- .../src/components/actions/F0Button/internal.tsx | 1 + packages/react/src/components/actions/exports.tsx | 14 ++------------ packages/react/src/components/exports.ts | 1 + packages/react/src/ui/Action/Action.tsx | 2 ++ packages/react/src/ui/Action/types.ts | 5 +++++ 5 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/react/src/components/actions/F0Button/internal.tsx b/packages/react/src/components/actions/F0Button/internal.tsx index dd90ac5aaa..63614d8af2 100644 --- a/packages/react/src/components/actions/F0Button/internal.tsx +++ b/packages/react/src/components/actions/F0Button/internal.tsx @@ -103,6 +103,7 @@ const ButtonInternal = forwardRef( loading={isLoading} className={className} mode={hideLabel ? "only" : "default"} + ariaLabel={props.title || label} >
( mode = "default", title, compact = false, + ariaLabel, ...props }, ref @@ -113,6 +114,7 @@ export const Action = React.forwardRef( disabled, className: cn(variantClasses, sizeClasses, focusRing(), className), "aria-busy": loading, + "aria-label": ariaLabel, title, ...props, } diff --git a/packages/react/src/ui/Action/types.ts b/packages/react/src/ui/Action/types.ts index d10017b98e..82da45d1c2 100644 --- a/packages/react/src/ui/Action/types.ts +++ b/packages/react/src/ui/Action/types.ts @@ -87,6 +87,11 @@ export interface ActionCommonProps { * make the left and right padding of the action smaller. */ compact?: boolean + + /** + * The aria label of the action. + */ + ariaLabel?: string } export const buttonTypes = ["button", "submit", "reset"] as const From dc8304db370551314912834b61ba70b60375d7a1 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 15:52:53 +0200 Subject: [PATCH 11/38] chore: button aria label --- .../UpsellingKit/UpsellingButton/index.stories.tsx | 2 +- packages/react/src/ui/Action/Action.tsx | 2 +- .../src/ui/Action/__stories__/Action.stories.tsx | 14 +++++--------- packages/react/src/ui/Action/types.ts | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/react/src/components/UpsellingKit/UpsellingButton/index.stories.tsx b/packages/react/src/components/UpsellingKit/UpsellingButton/index.stories.tsx index 7baf4f61ec..6aa50dd743 100644 --- a/packages/react/src/components/UpsellingKit/UpsellingButton/index.stories.tsx +++ b/packages/react/src/components/UpsellingKit/UpsellingButton/index.stories.tsx @@ -11,7 +11,7 @@ const meta = { url: "https://www.figma.com/design/pZzg1KTe9lpKTSGPUZa8OJ/Web-components?node-id=41-1256&t=99GWQFvFLZtKW49N-4", }, }, - tags: ["autodocs", "no-sidebar"], + tags: ["autodocs"], args: { label: "Request Information", size: "md", diff --git a/packages/react/src/ui/Action/Action.tsx b/packages/react/src/ui/Action/Action.tsx index 74515fe38f..c12527909d 100644 --- a/packages/react/src/ui/Action/Action.tsx +++ b/packages/react/src/ui/Action/Action.tsx @@ -55,7 +55,7 @@ export const Action = React.forwardRef( const compactClasses = cva({ variants: { size: { - sm: "!px-1", + sm: "!px-[4px]", md: "!px-[6px]", lg: "!px-[10px]", }, diff --git a/packages/react/src/ui/Action/__stories__/Action.stories.tsx b/packages/react/src/ui/Action/__stories__/Action.stories.tsx index 0e8438f718..e304c4ec7f 100644 --- a/packages/react/src/ui/Action/__stories__/Action.stories.tsx +++ b/packages/react/src/ui/Action/__stories__/Action.stories.tsx @@ -164,15 +164,11 @@ export const AllSizes: Story = { export const AllCompact: Story = { render: () => (
- - - - - - - - - + {actionSizes.map((size) => ( + + + + ))}
), } diff --git a/packages/react/src/ui/Action/types.ts b/packages/react/src/ui/Action/types.ts index 82da45d1c2..7a00b235fd 100644 --- a/packages/react/src/ui/Action/types.ts +++ b/packages/react/src/ui/Action/types.ts @@ -91,7 +91,7 @@ export interface ActionCommonProps { /** * The aria label of the action. */ - ariaLabel?: string + ariaLabel: string } export const buttonTypes = ["button", "submit", "reset"] as const From 47b6a05ae9f29f1f4608429a6302346b43bd01be Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 16:36:38 +0200 Subject: [PATCH 12/38] chore: fix tests --- .../OneFilterPicker/__test__/index.test.tsx | 560 +++++++-------- .../components/actions/F0Button/internal.tsx | 2 +- .../F0ButtonDropdown/F0ButtonDropdown.tsx | 1 + .../Forms/Fields/NumberInput/index.test.tsx | 20 +- .../Navigation/Sidebar/Icon/index.tsx | 1 + .../collection/Table/index.spec.tsx | 635 ++++++++---------- .../RichText/RichTextEditor/Enhance/index.tsx | 3 + packages/react/src/testing/test-utils.tsx | 6 +- packages/react/src/ui/Action/Action.tsx | 2 +- .../ui/Action/__stories__/Action.stories.tsx | 22 +- packages/react/src/ui/Action/types.ts | 2 +- .../react/src/ui/ButtonCopy/ButtonCopy.tsx | 1 + .../OneDatePickerPopup.test.tsx | 62 +- 13 files changed, 605 insertions(+), 712 deletions(-) diff --git a/packages/react/src/components/OneFilterPicker/__test__/index.test.tsx b/packages/react/src/components/OneFilterPicker/__test__/index.test.tsx index 40ff6f6dfd..f3b313d04f 100644 --- a/packages/react/src/components/OneFilterPicker/__test__/index.test.tsx +++ b/packages/react/src/components/OneFilterPicker/__test__/index.test.tsx @@ -1,9 +1,7 @@ -import { render, screen, waitFor } from "@/testing/test-utils" +import { zeroRender as render, screen, waitFor } from "@/testing/test-utils" import "@testing-library/jest-dom/vitest" import userEvent from "@testing-library/user-event" -import React from "react" import { describe, expect, it, vi } from "vitest" -import { defaultTranslations, I18nProvider } from "../../../lib/providers/i18n" import { OneFilterPicker } from "../index" import type { FiltersDefinition } from "../types" @@ -25,10 +23,6 @@ const definition = { }, } as const satisfies FiltersDefinition -const TestWrapper = ({ children }: { children: React.ReactNode }) => ( - {children} -) - describe("Filters", () => { describe("Filter State Management", () => { it("applies filters only when Apply button is clicked", async () => { @@ -36,13 +30,7 @@ describe("Filters", () => { const onChange = vi.fn() render( - - - + ) // Open filter popover @@ -69,16 +57,14 @@ describe("Filters", () => { // Render with initial state render( - - - + ) // Check for active filters in the UI @@ -101,13 +87,7 @@ describe("Filters", () => { const onChange = vi.fn() render( - - - + ) // Open and configure filter @@ -148,13 +128,7 @@ describe("Filters", () => { const onChange = vi.fn() render( - - - + ) // Open filter popover @@ -174,13 +148,11 @@ describe("Filters", () => { const onChange = vi.fn() render( - - - + ) // Open filter popover @@ -232,16 +204,14 @@ describe("Filters", () => { // Render with initial filters const { rerender } = render( - - - + ) // Find all close buttons in the document @@ -257,15 +227,13 @@ describe("Filters", () => { // Simulate the update rerender( - - - + ) // Verify department filter is gone @@ -279,13 +247,11 @@ describe("Filters", () => { // Start with engineering selected const { rerender } = render( - - - + ) // Open filter panel @@ -306,13 +272,11 @@ describe("Filters", () => { // Update the component with the new state rerender( - - - + ) // Verify the UI shows the updated filter @@ -339,14 +303,12 @@ describe("Presets", () => { ] render( - - - + ) // Verify preset buttons are rendered @@ -369,14 +331,12 @@ describe("Presets", () => { ] render( - - - + ) // Click on a preset @@ -402,14 +362,12 @@ describe("Presets", () => { // Render with filters matching the first preset render( - - - + ) // Get the preset elements @@ -442,14 +400,12 @@ describe("Presets", () => { ] const { rerender } = render( - - - + ) // Click on the first preset @@ -459,14 +415,12 @@ describe("Presets", () => { // Simulate the update rerender( - - - + ) // Reset the mock to track new calls @@ -489,14 +443,12 @@ describe("Presets", () => { ] const { rerender } = render( - - - + ) // Apply a preset @@ -506,14 +458,12 @@ describe("Presets", () => { // Simulate the update rerender( - - - + ) // Reset the mock to track new calls @@ -551,14 +501,12 @@ describe("Presets", () => { ] render( - - - + ) // Click on the preset @@ -580,214 +528,196 @@ describe("Filters Type Safety", () => { it.skip("should enforce type safety in props", () => { // Valid usage - this should type check render( - - {}} - /> - + }, + } as const + } + value={{ status: ["active"] }} + onChange={() => {}} + /> ) render( - - {}} - /> - + {}} + /> ) render( - - {}} - /> - + {}} + /> ) render( - - {}} - /> - + }, + } as const + } + // @ts-expect-error - Wrong value type for "in" filter (string instead of string[]) + value={{ status: "active" }} + onChange={() => {}} + /> ) render( - - {}} - /> - + }, + } as const + } + // @ts-expect-error - Invalid filter key in filters state + value={{ invalid: ["something"] }} + onChange={() => {}} + /> ) render( - - {}} - /> - + }, + } as const + } + // @ts-expect-error - Invalid value in options array + value={{ status: ["nonexistent"] }} + onChange={() => {}} + /> ) render( - - {}} - /> - + {}} + /> ) }) it.skip("should enforce type safety in presets", () => { // Valid usage - this should type check render( - - {}} - /> - + } as const + } + value={{}} + presets={[ + { + label: "Active Only", + filter: { status: ["active"] }, + }, + ]} + onChange={() => {}} + /> ) render( - - {}} - /> - + } as const + } + value={{}} + presets={[ + { + label: "Invalid Preset", + // @ts-expect-error - Invalid filter key in preset + filter: { invalid: ["something"] }, + }, + ]} + onChange={() => {}} + /> ) }) }) diff --git a/packages/react/src/components/actions/F0Button/internal.tsx b/packages/react/src/components/actions/F0Button/internal.tsx index 63614d8af2..470236a88e 100644 --- a/packages/react/src/components/actions/F0Button/internal.tsx +++ b/packages/react/src/components/actions/F0Button/internal.tsx @@ -103,7 +103,7 @@ const ButtonInternal = forwardRef( loading={isLoading} className={className} mode={hideLabel ? "only" : "default"} - ariaLabel={props.title || label} + aria-label={props.title || label} >
} className="rounded-r-none after:rounded-r-none" appendOutside={ diff --git a/packages/react/src/experimental/Forms/Fields/NumberInput/index.test.tsx b/packages/react/src/experimental/Forms/Fields/NumberInput/index.test.tsx index d4c6491e51..d587ffbcfb 100644 --- a/packages/react/src/experimental/Forms/Fields/NumberInput/index.test.tsx +++ b/packages/react/src/experimental/Forms/Fields/NumberInput/index.test.tsx @@ -9,14 +9,21 @@ const WithStepStory = composeStory(WithStep, Meta) describe("NumberInput", () => { test("renders the input", () => { - render() + render( + + ) const input = screen.getByRole("textbox") expect(input).toHaveValue("123,46") }) describe("when the value is null", () => { test("renders an empty input", () => { - render() + render() const input = screen.getByRole("textbox") expect(input).toHaveValue("") }) @@ -25,7 +32,14 @@ describe("NumberInput", () => { describe("when typing a number", () => { test("trigger the onChange callback with the number", async () => { const onChange = vi.fn() - render() + render( + + ) const input = screen.getByRole("textbox") await userEvent.type(input, "-34.") diff --git a/packages/react/src/experimental/Navigation/Sidebar/Icon/index.tsx b/packages/react/src/experimental/Navigation/Sidebar/Icon/index.tsx index 6403631cc4..98760d445e 100644 --- a/packages/react/src/experimental/Navigation/Sidebar/Icon/index.tsx +++ b/packages/react/src/experimental/Navigation/Sidebar/Icon/index.tsx @@ -83,6 +83,7 @@ export function SidebarIcon() { title="Close Sidebar" ref={buttonRef} compact + aria-label="Close Sidebar" >
diff --git a/packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/index.spec.tsx b/packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/index.spec.tsx index b4b3402a76..6dcd11ef25 100644 --- a/packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/index.spec.tsx +++ b/packages/react/src/experimental/OneDataCollection/visualizations/collection/Table/index.spec.tsx @@ -9,17 +9,15 @@ import { PaginatedFetchOptions, PaginationType, } from "@/hooks/datasource" -import { defaultTranslations, I18nProvider } from "@/lib/providers/i18n" +import { zeroRender as render, TestProviders } from "@/testing/test-utils" import { act, - render, renderHook, screen, waitFor, within, } from "@testing-library/react" import userEvent from "@testing-library/user-event" -import { ReactNode } from "react" import { describe, expect, it, vi } from "vitest" import { ItemActionsDefinition } from "../../../item-actions" import { SummariesDefinition } from "../../../summary" @@ -94,11 +92,6 @@ const createTestSource = ( setCurrentGrouping: vi.fn(), }) -// Test wrapper component that provides I18nProvider -const TestWrapper = ({ children }: { children: ReactNode }) => ( - {children} -) - class MockIntersectionObserver implements IntersectionObserver { root: Document | Element | null = null rootMargin: string = `` @@ -115,23 +108,21 @@ describe("TableCollection", () => { describe("rendering", () => { it("shows loading state initially", () => { render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createTestSource()} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createTestSource()} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) // The OneTable.Skeleton component uses aria-hidden="true" and role="presentation" @@ -148,23 +139,21 @@ describe("TableCollection", () => { it("renders table with data after loading", async () => { render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createTestSource()} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createTestSource()} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) // Wait for loading state to disappear by checking for actual data @@ -196,23 +185,21 @@ describe("TableCollection", () => { ] render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={columnsWithCustomRender} - source={createTestSource()} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={columnsWithCustomRender} + source={createTestSource()} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) await waitFor(() => { @@ -226,23 +213,21 @@ describe("TableCollection", () => { describe("edge cases", () => { it("handles empty data gracefully", async () => { render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createTestSource([])} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createTestSource([])} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) // Wait for loading state to finish @@ -260,23 +245,21 @@ describe("TableCollection", () => { const error = new Error(errorMessage) render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createTestSource([], error)} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createTestSource([], error)} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) // Wait for loading state to finish @@ -292,7 +275,7 @@ describe("TableCollection", () => { const { result } = renderHook( () => useDataCollectionData(createTestSource([], error)), { - wrapper: TestWrapper, + wrapper: TestProviders, } ) await waitFor(() => { @@ -371,25 +354,23 @@ describe("TableCollection", () => { it("renders pagination controls when pages pagination is enabled", async () => { render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createPaginatedTestSource({ - paginationType: "pages", - })} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createPaginatedTestSource({ + paginationType: "pages", + })} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) await waitFor(() => { @@ -405,25 +386,23 @@ describe("TableCollection", () => { IntersectionObserver ) render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createPaginatedTestSource({ - paginationType: "infinite-scroll", - })} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createPaginatedTestSource({ + paginationType: "infinite-scroll", + })} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) await waitFor(() => { @@ -436,23 +415,21 @@ describe("TableCollection", () => { it("shows loading state when switching pages", async () => { render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createPaginatedTestSource({})} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createPaginatedTestSource({})} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) // Wait for initial load @@ -472,23 +449,21 @@ describe("TableCollection", () => { it("displays correct data for each page", async () => { render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createPaginatedTestSource({})} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createPaginatedTestSource({})} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) // Check first page @@ -510,26 +485,24 @@ describe("TableCollection", () => { it("handles edge case with single page", async () => { render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createPaginatedTestSource({ - totalItems: 5, - itemsPerPage: 10, - })} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createPaginatedTestSource({ + totalItems: 5, + itemsPerPage: 10, + })} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) await waitFor(() => { @@ -540,26 +513,24 @@ describe("TableCollection", () => { it("handles edge case with empty data", async () => { render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={testColumns} - source={createPaginatedTestSource({ - totalItems: 0, - itemsPerPage: 10, - })} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={testColumns} + source={createPaginatedTestSource({ + totalItems: 0, + itemsPerPage: 10, + })} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) await waitFor(() => { @@ -597,23 +568,21 @@ describe("TableCollection", () => { ] render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={columnsWithSorting} - source={sortableSource} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={columnsWithSorting} + source={sortableSource} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) await waitFor(() => { @@ -644,33 +613,31 @@ describe("TableCollection", () => { } render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={[ - { - label: "name", - render: (item: Person) => item.name, - sorting: "name" as const, - }, - { - label: "email", - render: (item: Person) => item.email, - }, - ]} - source={modifiedSource} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={[ + { + label: "name", + render: (item: Person) => item.name, + sorting: "name" as const, + }, + { + label: "email", + render: (item: Person) => item.email, + }, + ]} + source={modifiedSource} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) // Wait for the table to load and verify it's rendered @@ -721,33 +688,31 @@ describe("TableCollection", () => { } render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={[ - { - label: "name", - render: (item: Person) => item.name, - sorting: "name" as const, - }, - { - label: "email", - render: (item: Person) => item.email, - }, - ]} - source={modifiedSource} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={[ + { + label: "name", + render: (item: Person) => item.name, + sorting: "name" as const, + }, + { + label: "email", + render: (item: Person) => item.email, + }, + ]} + source={modifiedSource} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) // Wait for the table to load and verify it's rendered @@ -801,33 +766,31 @@ describe("TableCollection", () => { } render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={[ - { - label: "name", - render: (item: Person) => item.name, - sorting: "name" as const, - }, - { - label: "email", - render: (item: Person) => item.email, - }, - ]} - source={modifiedSource} - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={[ + { + label: "name", + render: (item: Person) => item.name, + sorting: "name" as const, + }, + { + label: "email", + render: (item: Person) => item.email, + }, + ]} + source={modifiedSource} + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) // Wait for the table to load and verify it's rendered @@ -875,23 +838,21 @@ describe("TableCollection", () => { ] render( - - , - TestNavigationFilters, - GroupingDefinition - > - columns={columnsWithSorting} - source={createTestSource()} // No sortings defined - onSelectItems={vi.fn()} - onLoadData={vi.fn()} - onLoadError={vi.fn()} - /> - + , + TestNavigationFilters, + GroupingDefinition + > + columns={columnsWithSorting} + source={createTestSource()} // No sortings defined + onSelectItems={vi.fn()} + onLoadData={vi.fn()} + onLoadError={vi.fn()} + /> ) await waitFor(() => { @@ -948,15 +909,13 @@ describe("TableCollection", () => { ] render( - - - + ) await waitFor(() => { @@ -989,15 +948,13 @@ describe("TableCollection", () => { ] render( - - - + ) await waitFor(() => { diff --git a/packages/react/src/experimental/RichText/RichTextEditor/Enhance/index.tsx b/packages/react/src/experimental/RichText/RichTextEditor/Enhance/index.tsx index 929021ffbd..c9497203ea 100644 --- a/packages/react/src/experimental/RichText/RichTextEditor/Enhance/index.tsx +++ b/packages/react/src/experimental/RichText/RichTextEditor/Enhance/index.tsx @@ -67,6 +67,9 @@ const EnhanceActivator = ({ onClick={(e) => { handleEnhanceClick(e) }} + aria-label={ + enhanceConfig?.enhanceLabels.enhanceButtonLabel ?? "Magic" + } disabled={disableButtons || isLoadingEnhance} className={cn( "bg-gradient-to-r from-[#f9f0dd80] to-[#d4ccfd80] text-[#6143a7] dark:from-[#6143a7] dark:to-[#7846ef] dark:text-f1-foreground [&>button>svg]:text-[#6143a7] dark:[&>button>svg]:text-f1-foreground", diff --git a/packages/react/src/testing/test-utils.tsx b/packages/react/src/testing/test-utils.tsx index 161aab1b53..87f2dd38ec 100644 --- a/packages/react/src/testing/test-utils.tsx +++ b/packages/react/src/testing/test-utils.tsx @@ -12,7 +12,7 @@ export * from "@testing-library/react" import { MotionGlobalConfig } from "motion" MotionGlobalConfig.skipAnimations = true -const AllTheProviders = ({ children }: { children: React.ReactNode }) => { +const TestProviders = ({ children }: { children: React.ReactNode }) => { return ( {children} @@ -23,6 +23,6 @@ const AllTheProviders = ({ children }: { children: React.ReactNode }) => { const zeroRender = ( ui: ReactElement, options?: Omit -): RenderResult => render(ui, { wrapper: AllTheProviders, ...options }) +): RenderResult => render(ui, { wrapper: TestProviders, ...options }) -export { userEvent, zeroRender } +export { TestProviders, userEvent, zeroRender } diff --git a/packages/react/src/ui/Action/Action.tsx b/packages/react/src/ui/Action/Action.tsx index c12527909d..5a05e7d1f1 100644 --- a/packages/react/src/ui/Action/Action.tsx +++ b/packages/react/src/ui/Action/Action.tsx @@ -36,7 +36,7 @@ export const Action = React.forwardRef( mode = "default", title, compact = false, - ariaLabel, + "aria-label": ariaLabel, ...props }, ref diff --git a/packages/react/src/ui/Action/__stories__/Action.stories.tsx b/packages/react/src/ui/Action/__stories__/Action.stories.tsx index e304c4ec7f..f2b7f3b068 100644 --- a/packages/react/src/ui/Action/__stories__/Action.stories.tsx +++ b/packages/react/src/ui/Action/__stories__/Action.stories.tsx @@ -58,6 +58,7 @@ type Story = StoryObj export const Basic: Story = { args: { children: "Basic Action", + "aria-label": "Basic Action", }, } @@ -67,6 +68,7 @@ export const AsLink: Story = { href: "https://example.com", target: "_blank", append: , + "aria-label": "Link Action", }, } @@ -76,6 +78,7 @@ export const AsLinkWithButtonVariant: Story = { href: "https://example.com", target: "_blank", variant: "default", + "aria-label": "Link with Button Style", }, } @@ -83,6 +86,7 @@ export const AsButtonWithLinkVariant: Story = { args: { children: "Button with Link Style", variant: "link", + "aria-label": "Button with Link Style", }, } @@ -90,6 +94,7 @@ export const Disabled: Story = { args: { children: "Disabled Action", disabled: true, + "aria-label": "Disabled Action", }, } @@ -97,6 +102,7 @@ export const WithPrepend: Story = { args: { children: "Action with Prepend", prepend: , + "aria-label": "Action with Prepend", }, } @@ -105,6 +111,7 @@ export const WithAppendOutside: Story = { children: "Action with Append", append: , appendOutside: true, + "aria-label": "Action with Append", }, } @@ -114,6 +121,7 @@ export const LinkDisabled: Story = { href: "https://example.com", target: "_blank", disabled: true, + "aria-label": "Link Disabled", }, } @@ -154,9 +162,15 @@ export const AllVariants: Story = { export const AllSizes: Story = { render: () => (
- Small - Medium - Large + + Small + + + Medium + + + Large +
), } @@ -165,7 +179,7 @@ export const AllCompact: Story = { render: () => (
{actionSizes.map((size) => ( - + ))} diff --git a/packages/react/src/ui/Action/types.ts b/packages/react/src/ui/Action/types.ts index 7a00b235fd..46a0e0a285 100644 --- a/packages/react/src/ui/Action/types.ts +++ b/packages/react/src/ui/Action/types.ts @@ -91,7 +91,7 @@ export interface ActionCommonProps { /** * The aria label of the action. */ - ariaLabel: string + "aria-label": string } export const buttonTypes = ["button", "submit", "reset"] as const diff --git a/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx b/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx index 242e82a385..9132880150 100644 --- a/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx +++ b/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx @@ -16,6 +16,7 @@ export type ButtonCopyProps = Omit< | "icon" | "href" | "target" + | "aria-label" > & { valueToCopy: string copiedTooltipLabel?: string diff --git a/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.test.tsx b/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.test.tsx index 7a4caa771e..a76cde7f16 100644 --- a/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.test.tsx +++ b/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.test.tsx @@ -1,8 +1,8 @@ -import { render, screen } from "@testing-library/react" +import { zeroRender as render } from "@/testing/test-utils" +import { screen } from "@testing-library/react" + import userEvent from "@testing-library/user-event" -import React from "react" import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest" -import { defaultTranslations, I18nProvider } from "../../lib/providers/i18n" import { OneDatePickerPopup } from "./OneDatePickerPopup" import { DatePreset } from "./types" @@ -15,10 +15,6 @@ beforeAll(() => { } }) -const TestWrapper = ({ children }: { children: React.ReactNode }) => ( - {children} -) - describe("OneDatePickerPopup", () => { const mockOnSelect = vi.fn() const mockOnOpenChange = vi.fn() @@ -47,21 +43,13 @@ describe("OneDatePickerPopup", () => { }) it("renders the trigger button", () => { - render( - - - - ) + render() expect(screen.getByText("Open Date Picker")).toBeInTheDocument() }) it("shows presets when provided", async () => { const user = userEvent.setup() - render( - - - - ) + render() await user.click(screen.getByText("Open Date Picker")) expect(screen.getByRole("option", { name: "Today" })).toBeInTheDocument() @@ -72,11 +60,7 @@ describe("OneDatePickerPopup", () => { it("calls onSelect when a preset is selected", async () => { const user = userEvent.setup() - render( - - - - ) + render() await user.click(screen.getByText("Open Date Picker")) await user.click(screen.getByRole("option", { name: "Today" })) @@ -88,12 +72,10 @@ describe("OneDatePickerPopup", () => { it("shows granularity selector when multiple granularities are provided", async () => { const user = userEvent.setup() render( - - - + ) await user.click(screen.getByText("Open Date Picker")) @@ -105,11 +87,7 @@ describe("OneDatePickerPopup", () => { it("shows custom range mode when custom preset is selected", async () => { const user = userEvent.setup() - render( - - - - ) + render() await user.click(screen.getByText("Open Date Picker")) await user.click(screen.getByRole("option", { name: "Custom" })) @@ -123,13 +101,11 @@ describe("OneDatePickerPopup", () => { const maxDate = new Date("2024-12-31") render( - - - + ) await user.click(screen.getByText("Open Date Picker")) @@ -139,11 +115,7 @@ describe("OneDatePickerPopup", () => { }) it("handles disabled state correctly", async () => { - render( - - - - ) + render() const trigger = screen.getByText("Open Date Picker") // Try to click the trigger From 1d37996a5e5f1d4e83730187d9cf96c9b7b754b3 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 17:08:13 +0200 Subject: [PATCH 13/38] chore: merge main --- .../experimental/Banners/F0AiBanner/AiBannerInternal.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react/src/experimental/Banners/F0AiBanner/AiBannerInternal.tsx b/packages/react/src/experimental/Banners/F0AiBanner/AiBannerInternal.tsx index 14bd8aaa63..b0fee98b58 100644 --- a/packages/react/src/experimental/Banners/F0AiBanner/AiBannerInternal.tsx +++ b/packages/react/src/experimental/Banners/F0AiBanner/AiBannerInternal.tsx @@ -1,4 +1,4 @@ -import { Button } from "@/components/Actions/Button" +import { F0Button } from "@/components/actions/F0Button" import { OneEllipsis } from "@/components/OneEllipsis" import { RichTextDisplay } from "@/experimental/RichText/RichTextDisplay" import { Cross } from "@/icons/app" @@ -23,7 +23,7 @@ export const AiBannerInternal = forwardRef<
{title} {onClose && ( - -
-

- Click either button to see the copy → check animation -

-
- ) - }, -} - -export const InContext: Story = { - parameters: withSnapshot({}), - render: (args) => ( -
-

Share this link

-
- - https://factorial.com/shared/abc123 - - -
-
- ), -} From 8b8cf49ff00d3a9125294ff834506b052dd3abe2 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 17:40:04 +0200 Subject: [PATCH 15/38] chore: fix navigation link --- packages/react/.storybook/preview.tsx | 4 +++- packages/react/src/components/actions/F0Button/internal.tsx | 5 +---- .../src/experimental/Navigation/Header/PageHeader/index.tsx | 5 ----- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/react/.storybook/preview.tsx b/packages/react/.storybook/preview.tsx index 30e10d36ea..3a8de6b3ce 100644 --- a/packages/react/.storybook/preview.tsx +++ b/packages/react/.storybook/preview.tsx @@ -55,7 +55,9 @@ export const FactorialOne = (Story, { parameters }) => { action("Link clicked")(event, ...args) props?.onClick?.(event, ...args) event.preventDefault() - if (props.href) setCurrentPath(props.href) + if (props.href) { + setCurrentPath(props.href) + } }} /> ), diff --git a/packages/react/src/components/actions/F0Button/internal.tsx b/packages/react/src/components/actions/F0Button/internal.tsx index 470236a88e..6be883c867 100644 --- a/packages/react/src/components/actions/F0Button/internal.tsx +++ b/packages/react/src/components/actions/F0Button/internal.tsx @@ -71,10 +71,7 @@ const ButtonInternal = forwardRef( const [loading, setLoading] = useState(false) const handleClick = async ( - event: React.MouseEvent< - HTMLElement | HTMLAnchorElement | HTMLButtonElement, - MouseEvent - > + event: React.MouseEvent ) => { const result = onClick?.(event) diff --git a/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx b/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx index c57afa8a91..9d45f388bb 100644 --- a/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx +++ b/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx @@ -95,11 +95,6 @@ function PageNavigationLink({ label={label} icon={icon} hideLabel - onClick={(e) => { - e.preventDefault() - if (disabled) return - ref.current?.click() - }} /> ) } From da521c49a05b9ec9109a149080c63723d3a75115 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 18:39:13 +0200 Subject: [PATCH 16/38] chore: fix navigation link --- .../__stories__/ButtonCopy.stories.tsx | 290 ++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 packages/react/src/ui/ButtonCopy/__stories__/ButtonCopy.stories.tsx diff --git a/packages/react/src/ui/ButtonCopy/__stories__/ButtonCopy.stories.tsx b/packages/react/src/ui/ButtonCopy/__stories__/ButtonCopy.stories.tsx new file mode 100644 index 0000000000..61efa58723 --- /dev/null +++ b/packages/react/src/ui/ButtonCopy/__stories__/ButtonCopy.stories.tsx @@ -0,0 +1,290 @@ +import { withSnapshot } from "@/lib/storybook-utils/parameters" +import type { Meta, StoryObj } from "@storybook/react-vite" +import React, { useEffect } from "react" +import { expect, userEvent, within } from "storybook/test" +import { ButtonCopy } from "../ButtonCopy" +import { buttonCopySizes } from "../types" + +const meta = { + title: "Components/ButtonCopy", + component: ButtonCopy, + parameters: { + layout: "centered", + }, + tags: ["autodocs", "internal"], + args: { + valueToCopy: "Hello World!", + variant: "neutral", + size: "sm", + }, + argTypes: { + valueToCopy: { + control: "text", + description: + "The text value that will be copied to clipboard when the button is clicked.", + }, + variant: { + control: "select", + options: [ + "default", + "critical", + "neutral", + "ghost", + "outline", + "promote", + "outlinePromote", + ], + description: "Visual style variant of the copy button.", + }, + size: { + control: "select", + options: buttonCopySizes, + description: + "Sets the button size. Copy buttons are typically used in 'sm' size.", + }, + copyTooltipLabel: { + control: "text", + description: + "Custom tooltip label shown before copying. Defaults to translation for 'Copy'.", + }, + copiedTooltipLabel: { + control: "text", + description: + "Custom tooltip label shown after copying. Defaults to 'Copied'.", + }, + disabled: { + control: "boolean", + description: + "The button is inactive and does not respond to user interaction.", + }, + onCopy: { + action: "copied", + description: "Callback fired when the copy action is performed.", + }, + }, +} satisfies Meta + +export default meta +type Story = StoryObj + +// Basic Stories +export const Default: Story = { + args: { + valueToCopy: "This text will be copied!", + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement) + + await step("Verify initial state", async () => { + const button = canvas.getByRole("button") + expect(button).toBeInTheDocument() + expect(button.getAttribute("aria-label")).toBe("Copy") + expect(button.getAttribute("title")).toBe("Copy") + }) + + await step("Click copy button", async () => { + const button = canvas.getByRole("button") + await userEvent.click(button) + }) + + await step("Verify copied state", async () => { + const button = canvas.getByRole("button") + expect(button.getAttribute("aria-label")).toBe("Copied") + expect(button.getAttribute("title")).toBe("Copied") + }) + }, +} + +export const Variants: Story = { + parameters: withSnapshot({}), + render: (args) => ( +
+ + + + + + +
+ ), +} + +export const Sizes: Story = { + parameters: withSnapshot({}), + render: (args) => ( +
+ + + +
+ ), +} + +export const CustomLabels: Story = { + args: { + valueToCopy: "Custom labels example", + copyTooltipLabel: "Click to copy text", + copiedTooltipLabel: "Text copied successfully!", + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement) + + await step("Verify custom copy label", async () => { + const button = canvas.getByRole("button") + expect(button.getAttribute("aria-label")).toBe("Click to copy text") + }) + + await step("Click and verify custom copied label", async () => { + const button = canvas.getByRole("button") + await userEvent.click(button) + expect(button.getAttribute("aria-label")).toBe( + "Text copied successfully!" + ) + }) + }, +} + +export const DifferentValues: Story = { + parameters: withSnapshot({}), + render: () => ( +
+
+ Email: + +
+
+ URL: + +
+
+ Token: + +
+
+ Code: + +
+
+ ), +} + +export const States: Story = { + parameters: withSnapshot({}), + render: (args) => ( +
+ + +
+ ), +} + +export const InteractiveCopyTest: Story = { + render: (args) => { + const [copyCount, setCopyCount] = React.useState(0) + + const handleCopy = () => { + setCopyCount((prev) => prev + 1) + } + + return ( +
+ +

Copied {copyCount} times

+
+ ) + }, + play: async ({ canvasElement, step }) => { + const canvas = within(canvasElement) + + await step("Test multiple copy interactions", async () => { + const button = canvas.getByRole("button") + const counter = canvas.getByText(/Copied \d+ times/) + + // Initial state + expect(counter).toHaveTextContent("Copied 0 times") + + // First copy + await userEvent.click(button) + expect(counter).toHaveTextContent("Copied 1 times") + + // Wait for animation to complete before next click + await new Promise((resolve) => setTimeout(resolve, 1100)) + + // Second copy + await userEvent.click(button) + expect(counter).toHaveTextContent("Copied 2 times") + }) + }, +} + +export const AnimationStates: Story = { + render: (args) => { + const [showCopied, setShowCopied] = React.useState(false) + + const triggerCopy = () => { + setShowCopied(true) + setTimeout(() => setShowCopied(false), 1000) + } + + useEffect(() => { + console.log("showCopied", showCopied) + }, [showCopied]) + + return ( +
+
+ + +
+

+ Click either button to see the copy → check animation +

+
+ ) + }, +} + +export const InContext: Story = { + parameters: withSnapshot({}), + render: (args) => ( +
+

Share this link

+
+ + https://factorial.com/shared/abc123 + + +
+
+ ), +} From 6318feda6c89cb3acd7f43374cec927a703fee95 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 18 Sep 2025 18:50:39 +0200 Subject: [PATCH 17/38] chore: datacollection settings file --- .../src/experimental/OneDataCollection/Settings/Settings.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react/src/experimental/OneDataCollection/Settings/Settings.tsx b/packages/react/src/experimental/OneDataCollection/Settings/Settings.tsx index 9b3d222011..f5fed3d737 100644 --- a/packages/react/src/experimental/OneDataCollection/Settings/Settings.tsx +++ b/packages/react/src/experimental/OneDataCollection/Settings/Settings.tsx @@ -115,6 +115,7 @@ export const Settings = < icon={Sliders} onClick={() => {}} hideLabel + compact pressed={open} /> From 0c675baabf3166932f544f48d77b87e69cfd5a60 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Fri, 19 Sep 2025 09:23:28 +0200 Subject: [PATCH 18/38] chore: fix storybook play --- packages/react/docs/components/BareColor.tsx | 2 +- packages/react/docs/components/ColorToken.tsx | 2 +- .../src/components/{actions => }/F0Button/F0Button.tsx | 0 .../{actions => }/F0Button/__stories__/F0Button.mdx | 0 .../F0Button/__stories__/F0Button.stories.tsx | 2 +- .../{actions => }/F0Button/__tests__/F0Button.test.tsx | 0 .../react/src/components/{actions => }/F0Button/index.ts | 0 .../components/{actions => }/F0Button/internal-types.ts | 0 .../src/components/{actions => }/F0Button/internal.tsx | 0 .../react/src/components/{actions => }/F0Button/types.ts | 0 .../{actions => }/F0ButtonDropdown/F0ButtonDropdown.tsx | 0 .../F0ButtonDropdown/__stories__/F0ButtonDropdown.mdx | 0 .../__stories__/F0ButtonDropdown.stories.tsx | 2 +- .../F0ButtonDropdown/__tests__/F0ButtonDropdown.test.tsx | 0 .../components/{actions => }/F0ButtonDropdown/index.ts | 0 .../components/{actions => }/F0ButtonDropdown/theme.ts | 0 .../components/{actions => }/F0ButtonDropdown/types.ts | 0 packages/react/src/components/F0Card/CardInternal.tsx | 2 +- .../src/components/F0Card/components/CardActions.tsx | 4 ++-- .../src/components/F0Card/components/CardOptions.tsx | 2 +- .../react/src/components/{actions => }/F0Link/F0Link.tsx | 8 ++++---- .../{actions => }/F0Link/__mocks__/linkHandler.tsx | 2 +- .../{actions => }/F0Link/__stories__/index.mdx | 0 .../{actions => }/F0Link/__stories__/index.stories.tsx | 2 +- .../{actions => }/F0Link/__tests__/index.test.tsx | 0 .../react/src/components/{actions => }/F0Link/index.tsx | 0 .../OneFilterPicker/components/FiltersChipsList.tsx | 2 +- .../OneFilterPicker/components/FiltersControls.tsx | 4 ++-- .../filterTypes/DateFilter/DateFilter.tsx | 2 +- .../OneFilterPicker/filterTypes/InFilter/InFilter.tsx | 2 +- .../UpsellingKit/ProductBlankslate/index.stories.tsx | 2 +- .../src/components/UpsellingKit/ProductCard/index.tsx | 2 +- .../UpsellingKit/ProductModal/components/CustomModal.tsx | 2 +- .../src/components/UpsellingKit/ProductModal/index.tsx | 2 +- .../src/components/UpsellingKit/ProductWidget/index.tsx | 2 +- .../UpsellingKit/UpsellRequestResponseDialog/index.tsx | 2 +- .../components/UpsellingKit/UpsellingBanner/index.tsx | 2 +- .../components/UpsellingKit/UpsellingButton/index.tsx | 2 +- .../components/UpsellingKit/UpsellingPopover/index.tsx | 2 +- .../Utilities/Await/__stories__/Await.stories.tsx | 2 +- packages/react/src/components/actions/exports.tsx | 3 --- .../components/avatars/F0AvatarPulse/F0AvatarPulse.tsx | 2 +- packages/react/src/components/exports.ts | 4 +++- .../src/experimental/AiChat/HILActionConfirmation.tsx | 2 +- .../experimental/AiChat/components/AssistantMessage.tsx | 2 +- .../src/experimental/AiChat/components/ChatHeader.tsx | 2 +- .../src/experimental/AiChat/components/ChatTextarea.tsx | 2 +- .../experimental/AiChat/components/MessagesContainer.tsx | 2 +- .../react/src/experimental/AiChat/markdownRenderers.tsx | 4 ++-- .../react/src/experimental/Banners/BaseBanner/index.tsx | 2 +- .../experimental/Banners/F0AiBanner/AiBannerInternal.tsx | 2 +- .../Forms/EntitySelect/Content/MainContent/Footer.tsx | 4 ++-- .../experimental/Forms/EntitySelect/CreateItem/index.tsx | 2 +- .../experimental/Forms/EntitySelect/ListItem/index.tsx | 2 +- .../Forms/Fields/Select/SelectBottomActions.tsx | 2 +- .../react/src/experimental/Forms/Form/index.stories.tsx | 2 +- packages/react/src/experimental/Forms/Form/index.tsx | 2 +- .../Information/Communities/HighlightBanner/index.tsx | 2 +- .../Information/Communities/Post/CommunityPost/index.tsx | 2 +- .../Information/Headers/BaseHeader/index.tsx | 4 ++-- .../experimental/Information/Headers/Metadata/index.tsx | 2 +- .../Information/Headers/SectionHeader/index.tsx | 4 ++-- .../experimental/Information/Reactions/Picker/index.tsx | 4 ++-- .../src/experimental/Information/Reactions/index.tsx | 2 +- packages/react/src/experimental/Information/utils.tsx | 2 +- .../src/experimental/Lists/OnePersonListItem/index.tsx | 2 +- .../experimental/Modals/OneModal/OneModal.stories.tsx | 2 +- .../Modals/OneModal/OneModalHeader/OneModalHeader.tsx | 2 +- .../Navigation/Carousel/DynamicCarousel/index.tsx | 2 +- .../src/experimental/Navigation/DaytimePage/index.tsx | 2 +- .../react/src/experimental/Navigation/Dropdown/index.tsx | 2 +- .../src/experimental/Navigation/Dropdown/internal.tsx | 4 ++-- .../Navigation/F0TableOfContent/Item/ItemDropDown.tsx | 2 +- .../Navigation/F0TableOfContent/Item/PrimitiveItem.tsx | 2 +- .../Navigation/Header/Breadcrumbs/index.stories.tsx | 2 +- .../experimental/Navigation/Header/PageHeader/index.tsx | 4 ++-- .../Navigation/Header/ProductUpdates/index.tsx | 4 ++-- .../src/experimental/Navigation/Sidebar/Footer/index.tsx | 2 +- .../src/experimental/OneActionBar/index.stories.tsx | 2 +- packages/react/src/experimental/OneActionBar/index.tsx | 4 ++-- packages/react/src/experimental/OneAlert/index.tsx | 2 +- .../react/src/experimental/OneCalendar/OneCalendar.tsx | 2 +- .../CollectionActions/CollectionActions.tsx | 4 ++-- .../experimental/OneDataCollection/Settings/Settings.tsx | 2 +- .../Settings/components/GroupingSelector.tsx | 2 +- .../Settings/components/SortingSelector.tsx | 2 +- .../ItemActionsDropdown/ItemActionsDropdown.tsx | 2 +- .../itemActions/ItemActionsRow/ItemActionsRow.tsx | 2 +- .../experimental/OneDataCollection/visualizations.tsx | 2 +- .../visualizations/collection/List/components/Row.tsx | 2 +- .../OneDateNavigator/components/DateNavigatorTrigger.tsx | 4 ++-- .../src/experimental/OneEmptyState/OneEmptyState.tsx | 2 +- .../react/src/experimental/OneTable/index.stories.tsx | 2 +- .../src/experimental/Overlays/Dialog/index.stories.tsx | 2 +- .../react/src/experimental/Overlays/Dialog/index.tsx | 2 +- .../src/experimental/Overlays/Tooltip/index.stories.tsx | 2 +- .../RichText/CoreEditor/Extensions/AIBlock/index.tsx | 2 +- .../CoreEditor/Extensions/LiveCompanion/index.tsx | 2 +- .../RichText/CoreEditor/Extensions/MoodTracker/index.tsx | 2 +- .../RichText/CoreEditor/Extensions/Transcript/index.tsx | 2 +- .../RichText/CoreEditor/Toolbar/LinkPopup/index.tsx | 4 ++-- .../experimental/RichText/CoreEditor/Toolbar/index.tsx | 2 +- .../RichText/NotesTextEditor/Header/index.tsx | 2 +- .../src/experimental/RichText/NotesTextEditor/index.tsx | 2 +- .../RichTextEditor/Enhance/AcceptChanges/index.tsx | 2 +- .../experimental/RichText/RichTextEditor/Error/index.tsx | 2 +- .../RichText/RichTextEditor/Footer/ActionsMenu/index.tsx | 4 ++-- .../RichText/RichTextEditor/Footer/index.tsx | 2 +- .../experimental/RichText/RichTextEditor/Head/index.tsx | 2 +- .../experimental/Utilities/PrivateBox/index.stories.tsx | 2 +- .../experimental/Utilities/ScrollArea/index.stories.tsx | 2 +- .../experimental/Widgets/ChartWidgetEmptyState/index.tsx | 2 +- .../Widgets/Content/ClockIn/ClockInControls/index.tsx | 2 +- packages/react/src/experimental/Widgets/Widget/index.tsx | 2 +- packages/react/src/ui/ButtonCopy/ButtonCopy.tsx | 2 +- .../src/ui/ButtonCopy/__stories__/ButtonCopy.stories.tsx | 9 ++++++++- .../react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx | 2 +- packages/react/src/ui/carousel.tsx | 4 ++-- 118 files changed, 129 insertions(+), 123 deletions(-) rename packages/react/src/components/{actions => }/F0Button/F0Button.tsx (100%) rename packages/react/src/components/{actions => }/F0Button/__stories__/F0Button.mdx (100%) rename packages/react/src/components/{actions => }/F0Button/__stories__/F0Button.stories.tsx (99%) rename packages/react/src/components/{actions => }/F0Button/__tests__/F0Button.test.tsx (100%) rename packages/react/src/components/{actions => }/F0Button/index.ts (100%) rename packages/react/src/components/{actions => }/F0Button/internal-types.ts (100%) rename packages/react/src/components/{actions => }/F0Button/internal.tsx (100%) rename packages/react/src/components/{actions => }/F0Button/types.ts (100%) rename packages/react/src/components/{actions => }/F0ButtonDropdown/F0ButtonDropdown.tsx (100%) rename packages/react/src/components/{actions => }/F0ButtonDropdown/__stories__/F0ButtonDropdown.mdx (100%) rename packages/react/src/components/{actions => }/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx (98%) rename packages/react/src/components/{actions => }/F0ButtonDropdown/__tests__/F0ButtonDropdown.test.tsx (100%) rename packages/react/src/components/{actions => }/F0ButtonDropdown/index.ts (100%) rename packages/react/src/components/{actions => }/F0ButtonDropdown/theme.ts (100%) rename packages/react/src/components/{actions => }/F0ButtonDropdown/types.ts (100%) rename packages/react/src/components/{actions => }/F0Link/F0Link.tsx (90%) rename packages/react/src/components/{actions => }/F0Link/__mocks__/linkHandler.tsx (91%) rename packages/react/src/components/{actions => }/F0Link/__stories__/index.mdx (100%) rename packages/react/src/components/{actions => }/F0Link/__stories__/index.stories.tsx (98%) rename packages/react/src/components/{actions => }/F0Link/__tests__/index.test.tsx (100%) rename packages/react/src/components/{actions => }/F0Link/index.tsx (100%) delete mode 100644 packages/react/src/components/actions/exports.tsx diff --git a/packages/react/docs/components/BareColor.tsx b/packages/react/docs/components/BareColor.tsx index 99ec986e26..a8f3794d16 100644 --- a/packages/react/docs/components/BareColor.tsx +++ b/packages/react/docs/components/BareColor.tsx @@ -1,6 +1,6 @@ import { useState } from "react" -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { CopyIcon } from "lucide-react" type Props = { diff --git a/packages/react/docs/components/ColorToken.tsx b/packages/react/docs/components/ColorToken.tsx index fd5b953884..9f599a3f6e 100644 --- a/packages/react/docs/components/ColorToken.tsx +++ b/packages/react/docs/components/ColorToken.tsx @@ -1,6 +1,6 @@ import { useState } from "react" -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { cn } from "@/lib/utils" import { CopyIcon } from "lucide-react" type Props = { diff --git a/packages/react/src/components/actions/F0Button/F0Button.tsx b/packages/react/src/components/F0Button/F0Button.tsx similarity index 100% rename from packages/react/src/components/actions/F0Button/F0Button.tsx rename to packages/react/src/components/F0Button/F0Button.tsx diff --git a/packages/react/src/components/actions/F0Button/__stories__/F0Button.mdx b/packages/react/src/components/F0Button/__stories__/F0Button.mdx similarity index 100% rename from packages/react/src/components/actions/F0Button/__stories__/F0Button.mdx rename to packages/react/src/components/F0Button/__stories__/F0Button.mdx diff --git a/packages/react/src/components/actions/F0Button/__stories__/F0Button.stories.tsx b/packages/react/src/components/F0Button/__stories__/F0Button.stories.tsx similarity index 99% rename from packages/react/src/components/actions/F0Button/__stories__/F0Button.stories.tsx rename to packages/react/src/components/F0Button/__stories__/F0Button.stories.tsx index be6b5b43f3..eec617fdf2 100644 --- a/packages/react/src/components/actions/F0Button/__stories__/F0Button.stories.tsx +++ b/packages/react/src/components/F0Button/__stories__/F0Button.stories.tsx @@ -7,7 +7,7 @@ import { expect, within } from "storybook/test" import { F0Button } from "../F0Button" const meta = { - title: "Actions/Button", + title: "Button", component: F0Button, parameters: { layout: "centered", diff --git a/packages/react/src/components/actions/F0Button/__tests__/F0Button.test.tsx b/packages/react/src/components/F0Button/__tests__/F0Button.test.tsx similarity index 100% rename from packages/react/src/components/actions/F0Button/__tests__/F0Button.test.tsx rename to packages/react/src/components/F0Button/__tests__/F0Button.test.tsx diff --git a/packages/react/src/components/actions/F0Button/index.ts b/packages/react/src/components/F0Button/index.ts similarity index 100% rename from packages/react/src/components/actions/F0Button/index.ts rename to packages/react/src/components/F0Button/index.ts diff --git a/packages/react/src/components/actions/F0Button/internal-types.ts b/packages/react/src/components/F0Button/internal-types.ts similarity index 100% rename from packages/react/src/components/actions/F0Button/internal-types.ts rename to packages/react/src/components/F0Button/internal-types.ts diff --git a/packages/react/src/components/actions/F0Button/internal.tsx b/packages/react/src/components/F0Button/internal.tsx similarity index 100% rename from packages/react/src/components/actions/F0Button/internal.tsx rename to packages/react/src/components/F0Button/internal.tsx diff --git a/packages/react/src/components/actions/F0Button/types.ts b/packages/react/src/components/F0Button/types.ts similarity index 100% rename from packages/react/src/components/actions/F0Button/types.ts rename to packages/react/src/components/F0Button/types.ts diff --git a/packages/react/src/components/actions/F0ButtonDropdown/F0ButtonDropdown.tsx b/packages/react/src/components/F0ButtonDropdown/F0ButtonDropdown.tsx similarity index 100% rename from packages/react/src/components/actions/F0ButtonDropdown/F0ButtonDropdown.tsx rename to packages/react/src/components/F0ButtonDropdown/F0ButtonDropdown.tsx diff --git a/packages/react/src/components/actions/F0ButtonDropdown/__stories__/F0ButtonDropdown.mdx b/packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.mdx similarity index 100% rename from packages/react/src/components/actions/F0ButtonDropdown/__stories__/F0ButtonDropdown.mdx rename to packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.mdx diff --git a/packages/react/src/components/actions/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx b/packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx similarity index 98% rename from packages/react/src/components/actions/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx rename to packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx index 294afb9c98..4799d5e43f 100644 --- a/packages/react/src/components/actions/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx +++ b/packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx @@ -5,7 +5,7 @@ import { F0ButtonDropdown } from "../index" import { buttonDropdownSizes, buttonDropdownVariants } from "../types.ts" const meta = { - title: "Actions/ButtonDropdown", + title: "ButtonDropdown", component: F0ButtonDropdown, parameters: { layout: "centered", diff --git a/packages/react/src/components/actions/F0ButtonDropdown/__tests__/F0ButtonDropdown.test.tsx b/packages/react/src/components/F0ButtonDropdown/__tests__/F0ButtonDropdown.test.tsx similarity index 100% rename from packages/react/src/components/actions/F0ButtonDropdown/__tests__/F0ButtonDropdown.test.tsx rename to packages/react/src/components/F0ButtonDropdown/__tests__/F0ButtonDropdown.test.tsx diff --git a/packages/react/src/components/actions/F0ButtonDropdown/index.ts b/packages/react/src/components/F0ButtonDropdown/index.ts similarity index 100% rename from packages/react/src/components/actions/F0ButtonDropdown/index.ts rename to packages/react/src/components/F0ButtonDropdown/index.ts diff --git a/packages/react/src/components/actions/F0ButtonDropdown/theme.ts b/packages/react/src/components/F0ButtonDropdown/theme.ts similarity index 100% rename from packages/react/src/components/actions/F0ButtonDropdown/theme.ts rename to packages/react/src/components/F0ButtonDropdown/theme.ts diff --git a/packages/react/src/components/actions/F0ButtonDropdown/types.ts b/packages/react/src/components/F0ButtonDropdown/types.ts similarity index 100% rename from packages/react/src/components/actions/F0ButtonDropdown/types.ts rename to packages/react/src/components/F0ButtonDropdown/types.ts diff --git a/packages/react/src/components/F0Card/CardInternal.tsx b/packages/react/src/components/F0Card/CardInternal.tsx index e1ab8abc0f..65d1afb3c1 100644 --- a/packages/react/src/components/F0Card/CardInternal.tsx +++ b/packages/react/src/components/F0Card/CardInternal.tsx @@ -1,4 +1,4 @@ -import { F0Link } from "@/components/actions/F0Link" +import { F0Link } from "@/components/F0Link" import { Image } from "@/components/Utilities/Image" import { DropdownItem } from "@/experimental/Navigation/Dropdown" import { cn, focusRing } from "@/lib/utils" diff --git a/packages/react/src/components/F0Card/components/CardActions.tsx b/packages/react/src/components/F0Card/components/CardActions.tsx index 2208369db5..d0506b9df2 100644 --- a/packages/react/src/components/F0Card/components/CardActions.tsx +++ b/packages/react/src/components/F0Card/components/CardActions.tsx @@ -1,6 +1,6 @@ -import { F0Button } from "@/components/actions/F0Button" -import { F0Link, type F0LinkProps } from "@/components/actions/F0Link" +import { F0Button } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" +import { F0Link, type F0LinkProps } from "@/components/F0Link" import { cn } from "@/lib/utils" import { CardFooter } from "@/ui/Card" import { useMediaQuery } from "usehooks-ts" diff --git a/packages/react/src/components/F0Card/components/CardOptions.tsx b/packages/react/src/components/F0Card/components/CardOptions.tsx index e568d5ab5f..f86d06fafe 100644 --- a/packages/react/src/components/F0Card/components/CardOptions.tsx +++ b/packages/react/src/components/F0Card/components/CardOptions.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { F0Checkbox } from "@/components/F0Checkbox" import { Dropdown, DropdownItem } from "@/experimental/Navigation/Dropdown" import { Ellipsis } from "@/icons/app" diff --git a/packages/react/src/components/actions/F0Link/F0Link.tsx b/packages/react/src/components/F0Link/F0Link.tsx similarity index 90% rename from packages/react/src/components/actions/F0Link/F0Link.tsx rename to packages/react/src/components/F0Link/F0Link.tsx index 30e4c299e1..7626c888df 100644 --- a/packages/react/src/components/actions/F0Link/F0Link.tsx +++ b/packages/react/src/components/F0Link/F0Link.tsx @@ -1,12 +1,12 @@ import { cva, type VariantProps } from "cva" import { forwardRef } from "react" -import ExternalLink from "../../../icons/app/ExternalLink" +import ExternalLink from "../../icons/app/ExternalLink" import { Link as BaseLink, LinkProps as BaseLinkProps, -} from "../../../lib/linkHandler" -import { cn, focusRing } from "../../../lib/utils" -import { F0Icon } from "../../F0Icon" +} from "../../lib/linkHandler" +import { cn, focusRing } from "../../lib/utils" +import { F0Icon } from "../F0Icon" const linkVariants = cva({ base: "inline-flex flex-row items-center gap-1 text-base", diff --git a/packages/react/src/components/actions/F0Link/__mocks__/linkHandler.tsx b/packages/react/src/components/F0Link/__mocks__/linkHandler.tsx similarity index 91% rename from packages/react/src/components/actions/F0Link/__mocks__/linkHandler.tsx rename to packages/react/src/components/F0Link/__mocks__/linkHandler.tsx index 5f4cb6e33b..2d09e669ee 100644 --- a/packages/react/src/components/actions/F0Link/__mocks__/linkHandler.tsx +++ b/packages/react/src/components/F0Link/__mocks__/linkHandler.tsx @@ -1,6 +1,6 @@ import { PropsWithChildren, forwardRef } from "react" import { vi } from "vitest" -import { LinkProps } from "../../../../lib/linkHandler" +import { LinkProps } from "../../../lib/linkHandler" const isActive = vi.fn((_path?: string) => false) const useNavigation = vi.fn(() => ({ diff --git a/packages/react/src/components/actions/F0Link/__stories__/index.mdx b/packages/react/src/components/F0Link/__stories__/index.mdx similarity index 100% rename from packages/react/src/components/actions/F0Link/__stories__/index.mdx rename to packages/react/src/components/F0Link/__stories__/index.mdx diff --git a/packages/react/src/components/actions/F0Link/__stories__/index.stories.tsx b/packages/react/src/components/F0Link/__stories__/index.stories.tsx similarity index 98% rename from packages/react/src/components/actions/F0Link/__stories__/index.stories.tsx rename to packages/react/src/components/F0Link/__stories__/index.stories.tsx index 9cbad80ac5..8bf6cece58 100644 --- a/packages/react/src/components/actions/F0Link/__stories__/index.stories.tsx +++ b/packages/react/src/components/F0Link/__stories__/index.stories.tsx @@ -6,7 +6,7 @@ import { expect, within } from "storybook/test" import { F0Link } from ".." const meta = { - title: "Actions/Link", + title: "Link", component: F0Link, parameters: { layout: "centered", diff --git a/packages/react/src/components/actions/F0Link/__tests__/index.test.tsx b/packages/react/src/components/F0Link/__tests__/index.test.tsx similarity index 100% rename from packages/react/src/components/actions/F0Link/__tests__/index.test.tsx rename to packages/react/src/components/F0Link/__tests__/index.test.tsx diff --git a/packages/react/src/components/actions/F0Link/index.tsx b/packages/react/src/components/F0Link/index.tsx similarity index 100% rename from packages/react/src/components/actions/F0Link/index.tsx rename to packages/react/src/components/F0Link/index.tsx diff --git a/packages/react/src/components/OneFilterPicker/components/FiltersChipsList.tsx b/packages/react/src/components/OneFilterPicker/components/FiltersChipsList.tsx index c4fe846f4e..cb32b98683 100644 --- a/packages/react/src/components/OneFilterPicker/components/FiltersChipsList.tsx +++ b/packages/react/src/components/OneFilterPicker/components/FiltersChipsList.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { useI18n } from "@/lib/providers/i18n" import { AnimatePresence } from "motion/react" import { diff --git a/packages/react/src/components/OneFilterPicker/components/FiltersControls.tsx b/packages/react/src/components/OneFilterPicker/components/FiltersControls.tsx index 4b28a2ef09..a3a058c016 100644 --- a/packages/react/src/components/OneFilterPicker/components/FiltersControls.tsx +++ b/packages/react/src/components/OneFilterPicker/components/FiltersControls.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { F0Button } from "@/components/F0Button" +import { ButtonInternal } from "@/components/F0Button/internal" import { Filter } from "@/icons/app" import { useI18n } from "@/lib/providers/i18n" import { Popover, PopoverContent, PopoverTrigger } from "@/ui/popover" diff --git a/packages/react/src/components/OneFilterPicker/filterTypes/DateFilter/DateFilter.tsx b/packages/react/src/components/OneFilterPicker/filterTypes/DateFilter/DateFilter.tsx index 3e90290674..91e7f14106 100644 --- a/packages/react/src/components/OneFilterPicker/filterTypes/DateFilter/DateFilter.tsx +++ b/packages/react/src/components/OneFilterPicker/filterTypes/DateFilter/DateFilter.tsx @@ -1,6 +1,6 @@ "use client" -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { FilterTypeComponentProps } from "../types" import { OneCalendar } from "@/experimental/OneCalendar" diff --git a/packages/react/src/components/OneFilterPicker/filterTypes/InFilter/InFilter.tsx b/packages/react/src/components/OneFilterPicker/filterTypes/InFilter/InFilter.tsx index 9b5929b52e..e2e0b13a6e 100644 --- a/packages/react/src/components/OneFilterPicker/filterTypes/InFilter/InFilter.tsx +++ b/packages/react/src/components/OneFilterPicker/filterTypes/InFilter/InFilter.tsx @@ -1,6 +1,6 @@ "use client" -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0Checkbox } from "@/components/F0Checkbox" import { OneEllipsis } from "@/components/OneEllipsis" import { F1SearchBox } from "@/experimental/Forms/Fields/F1SearchBox" diff --git a/packages/react/src/components/UpsellingKit/ProductBlankslate/index.stories.tsx b/packages/react/src/components/UpsellingKit/ProductBlankslate/index.stories.tsx index b625ce2f9f..421fdf402e 100644 --- a/packages/react/src/components/UpsellingKit/ProductBlankslate/index.stories.tsx +++ b/packages/react/src/components/UpsellingKit/ProductBlankslate/index.stories.tsx @@ -1,5 +1,5 @@ // packages/react/src/experimental/ProductBlankslate/ProductBlankslate.stories.tsx -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import SalesIcon from "@/icons/modules/Sales" import type { Meta, StoryObj } from "@storybook/react-vite" import { ProductBlankslate } from "." diff --git a/packages/react/src/components/UpsellingKit/ProductCard/index.tsx b/packages/react/src/components/UpsellingKit/ProductCard/index.tsx index 7d4d89f8a7..5ff6ab52cf 100644 --- a/packages/react/src/components/UpsellingKit/ProductCard/index.tsx +++ b/packages/react/src/components/UpsellingKit/ProductCard/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0AvatarModule, ModuleId } from "@/components/avatars/F0AvatarModule" import CrossIcon from "@/icons/app/Cross" import { useEffect, useState } from "react" diff --git a/packages/react/src/components/UpsellingKit/ProductModal/components/CustomModal.tsx b/packages/react/src/components/UpsellingKit/ProductModal/components/CustomModal.tsx index e79be1b065..81619e7f19 100644 --- a/packages/react/src/components/UpsellingKit/ProductModal/components/CustomModal.tsx +++ b/packages/react/src/components/UpsellingKit/ProductModal/components/CustomModal.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { F0AvatarModule, ModuleId } from "@/components/avatars/F0AvatarModule" import CrossIcon from "@/icons/app/Cross" import { Dialog, DialogContent, DialogTitle } from "@/ui/dialog" diff --git a/packages/react/src/components/UpsellingKit/ProductModal/index.tsx b/packages/react/src/components/UpsellingKit/ProductModal/index.tsx index 449e782704..06535cfe76 100644 --- a/packages/react/src/components/UpsellingKit/ProductModal/index.tsx +++ b/packages/react/src/components/UpsellingKit/ProductModal/index.tsx @@ -1,4 +1,4 @@ -import { ButtonVariant, F0Button } from "@/components/actions/F0Button" +import { ButtonVariant, F0Button } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" import { ModuleId } from "@/experimental" import { useState } from "react" diff --git a/packages/react/src/components/UpsellingKit/ProductWidget/index.tsx b/packages/react/src/components/UpsellingKit/ProductWidget/index.tsx index 2287ab8473..e7f71949f1 100644 --- a/packages/react/src/components/UpsellingKit/ProductWidget/index.tsx +++ b/packages/react/src/components/UpsellingKit/ProductWidget/index.tsx @@ -1,4 +1,4 @@ -import { ButtonVariant, F0Button } from "@/components/actions/F0Button" +import { ButtonVariant, F0Button } from "@/components/F0Button" import CrossIcon from "@/icons/app/Cross" import { Card, CardContent, CardFooter } from "@/ui/Card" import { Label } from "@/ui/label" diff --git a/packages/react/src/components/UpsellingKit/UpsellRequestResponseDialog/index.tsx b/packages/react/src/components/UpsellingKit/UpsellRequestResponseDialog/index.tsx index 5ce811d668..2446abd815 100644 --- a/packages/react/src/components/UpsellingKit/UpsellRequestResponseDialog/index.tsx +++ b/packages/react/src/components/UpsellingKit/UpsellRequestResponseDialog/index.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" import { F0AvatarAlert } from "@/components/avatars/F0AvatarAlert" +import { F0Button } from "@/components/F0Button" import { F0Icon } from "@/components/F0Icon" import { CheckCircle, DottedCircle } from "@/icons/app" import { diff --git a/packages/react/src/components/UpsellingKit/UpsellingBanner/index.tsx b/packages/react/src/components/UpsellingKit/UpsellingBanner/index.tsx index 49f73b336e..612a0a6147 100644 --- a/packages/react/src/components/UpsellingKit/UpsellingBanner/index.tsx +++ b/packages/react/src/components/UpsellingKit/UpsellingBanner/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" import { BaseBanner, diff --git a/packages/react/src/components/UpsellingKit/UpsellingButton/index.tsx b/packages/react/src/components/UpsellingKit/UpsellingButton/index.tsx index 3eafb9845a..1fa2003178 100644 --- a/packages/react/src/components/UpsellingKit/UpsellingButton/index.tsx +++ b/packages/react/src/components/UpsellingKit/UpsellingButton/index.tsx @@ -1,4 +1,4 @@ -import { F0Button, F0ButtonProps } from "@/components/actions/F0Button" +import { F0Button, F0ButtonProps } from "@/components/F0Button" import { ErrorMessageProps, NextStepsProps, diff --git a/packages/react/src/components/UpsellingKit/UpsellingPopover/index.tsx b/packages/react/src/components/UpsellingKit/UpsellingPopover/index.tsx index 197908459b..0581c4b0a7 100644 --- a/packages/react/src/components/UpsellingKit/UpsellingPopover/index.tsx +++ b/packages/react/src/components/UpsellingKit/UpsellingPopover/index.tsx @@ -1,4 +1,4 @@ -import { F0Button, F0ButtonProps } from "@/components/actions/F0Button" +import { F0Button, F0ButtonProps } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" import { Popover, PopoverContent, PopoverTrigger } from "@/ui/popover" import { PopoverContentProps } from "@radix-ui/react-popover" diff --git a/packages/react/src/components/Utilities/Await/__stories__/Await.stories.tsx b/packages/react/src/components/Utilities/Await/__stories__/Await.stories.tsx index cd365809a1..2a40595481 100644 --- a/packages/react/src/components/Utilities/Await/__stories__/Await.stories.tsx +++ b/packages/react/src/components/Utilities/Await/__stories__/Await.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react-vite" -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Skeleton } from "@/ui/skeleton" import { ComponentProps, useCallback, useEffect, useState } from "react" import { Await } from "../index" diff --git a/packages/react/src/components/actions/exports.tsx b/packages/react/src/components/actions/exports.tsx deleted file mode 100644 index c22f9779dc..0000000000 --- a/packages/react/src/components/actions/exports.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./F0Button" -export * from "./F0ButtonDropdown" -export * from "./F0Link" diff --git a/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx b/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx index 265f296de2..d0b0d6252f 100644 --- a/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx +++ b/packages/react/src/components/avatars/F0AvatarPulse/F0AvatarPulse.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { F0Icon, F0IconProps, IconType } from "@/components/F0Icon" import { FaceNegative, diff --git a/packages/react/src/components/exports.ts b/packages/react/src/components/exports.ts index 5b92e92962..a3ad8ca398 100644 --- a/packages/react/src/components/exports.ts +++ b/packages/react/src/components/exports.ts @@ -1,11 +1,13 @@ -export * from "./actions/exports" export * from "./avatars/exports" export * from "./Charts/exports" +export * from "./F0Button" +export * from "./F0ButtonDropdown" export * from "./F0ButtonToggle" export * from "./F0Card" export * from "./F0Checkbox" export * from "./F0ChipList" export * from "./F0Icon" +export * from "./F0Link" export * from "./layouts/exports" export * from "./OneFilterPicker/exports" export * from "./tags/exports" diff --git a/packages/react/src/experimental/AiChat/HILActionConfirmation.tsx b/packages/react/src/experimental/AiChat/HILActionConfirmation.tsx index d6e523e4e0..981086ee71 100644 --- a/packages/react/src/experimental/AiChat/HILActionConfirmation.tsx +++ b/packages/react/src/experimental/AiChat/HILActionConfirmation.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import Check from "@/icons/app/Check" export type HILActionConfirmationProps = { diff --git a/packages/react/src/experimental/AiChat/components/AssistantMessage.tsx b/packages/react/src/experimental/AiChat/components/AssistantMessage.tsx index 6ee5c779db..8c5bc0ea21 100644 --- a/packages/react/src/experimental/AiChat/components/AssistantMessage.tsx +++ b/packages/react/src/experimental/AiChat/components/AssistantMessage.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Spinner } from "@/experimental" import { ThumbsDown, diff --git a/packages/react/src/experimental/AiChat/components/ChatHeader.tsx b/packages/react/src/experimental/AiChat/components/ChatHeader.tsx index 0012f10637..fc9d05e04b 100644 --- a/packages/react/src/experimental/AiChat/components/ChatHeader.tsx +++ b/packages/react/src/experimental/AiChat/components/ChatHeader.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import Cross from "@/icons/app/Cross" import { useI18n } from "@/lib/providers/i18n" import { cn } from "@/lib/utils" diff --git a/packages/react/src/experimental/AiChat/components/ChatTextarea.tsx b/packages/react/src/experimental/AiChat/components/ChatTextarea.tsx index 893c0dd177..15dec26f83 100644 --- a/packages/react/src/experimental/AiChat/components/ChatTextarea.tsx +++ b/packages/react/src/experimental/AiChat/components/ChatTextarea.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { ArrowUp, SolidStop } from "@/icons/app" import { cn } from "@/lib/utils" import { type InputProps } from "@copilotkit/react-ui" diff --git a/packages/react/src/experimental/AiChat/components/MessagesContainer.tsx b/packages/react/src/experimental/AiChat/components/MessagesContainer.tsx index 045171b118..a29a657468 100644 --- a/packages/react/src/experimental/AiChat/components/MessagesContainer.tsx +++ b/packages/react/src/experimental/AiChat/components/MessagesContainer.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { ArrowDown } from "@/icons/app" import { useI18n } from "@/lib/providers/i18n" import { cn } from "@/lib/utils" diff --git a/packages/react/src/experimental/AiChat/markdownRenderers.tsx b/packages/react/src/experimental/AiChat/markdownRenderers.tsx index f79d42b47d..bfa97e9242 100644 --- a/packages/react/src/experimental/AiChat/markdownRenderers.tsx +++ b/packages/react/src/experimental/AiChat/markdownRenderers.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" -import { F0Link } from "@/components/actions/F0Link/F0Link" +import { F0Button } from "@/components/F0Button" +import { F0Link } from "@/components/F0Link/F0Link" import DownloadIcon from "@/icons/app/Download" import { cn } from "@/lib/utils" import { type AssistantMessageProps } from "@copilotkit/react-ui" diff --git a/packages/react/src/experimental/Banners/BaseBanner/index.tsx b/packages/react/src/experimental/Banners/BaseBanner/index.tsx index 54132f53c2..2bf61d9df2 100644 --- a/packages/react/src/experimental/Banners/BaseBanner/index.tsx +++ b/packages/react/src/experimental/Banners/BaseBanner/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" import CrossIcon from "@/icons/app/Cross" import { withSkeleton } from "@/lib/skeleton" diff --git a/packages/react/src/experimental/Banners/F0AiBanner/AiBannerInternal.tsx b/packages/react/src/experimental/Banners/F0AiBanner/AiBannerInternal.tsx index b0fee98b58..54787d6f62 100644 --- a/packages/react/src/experimental/Banners/F0AiBanner/AiBannerInternal.tsx +++ b/packages/react/src/experimental/Banners/F0AiBanner/AiBannerInternal.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { OneEllipsis } from "@/components/OneEllipsis" import { RichTextDisplay } from "@/experimental/RichText/RichTextDisplay" import { Cross } from "@/icons/app" diff --git a/packages/react/src/experimental/Forms/EntitySelect/Content/MainContent/Footer.tsx b/packages/react/src/experimental/Forms/EntitySelect/Content/MainContent/Footer.tsx index 40088fd64d..b3f1e88918 100644 --- a/packages/react/src/experimental/Forms/EntitySelect/Content/MainContent/Footer.tsx +++ b/packages/react/src/experimental/Forms/EntitySelect/Content/MainContent/Footer.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" -import { F0ButtonDropdown } from "@/components/actions/F0ButtonDropdown" +import { F0Button } from "@/components/F0Button" +import { F0ButtonDropdown } from "@/components/F0ButtonDropdown" import { Action } from "../../../Fields/Select/SelectBottomActions" interface Props { diff --git a/packages/react/src/experimental/Forms/EntitySelect/CreateItem/index.tsx b/packages/react/src/experimental/Forms/EntitySelect/CreateItem/index.tsx index e285478c34..2eca782a4f 100644 --- a/packages/react/src/experimental/Forms/EntitySelect/CreateItem/index.tsx +++ b/packages/react/src/experimental/Forms/EntitySelect/CreateItem/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Plus } from "@/icons/app" import { cn } from "@/lib/utils" import { focusNextFocusable, focusPreviousFocusable } from "../ListItem" diff --git a/packages/react/src/experimental/Forms/EntitySelect/ListItem/index.tsx b/packages/react/src/experimental/Forms/EntitySelect/ListItem/index.tsx index a3d71615c2..b2c9a13fbe 100644 --- a/packages/react/src/experimental/Forms/EntitySelect/ListItem/index.tsx +++ b/packages/react/src/experimental/Forms/EntitySelect/ListItem/index.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" import { F0AvatarPerson } from "@/components/avatars/F0AvatarPerson" +import { F0Button } from "@/components/F0Button" import { F0Icon } from "@/components/F0Icon" import { Counter } from "@/experimental/Information/Counter" import { CheckCircle } from "@/icons/app" diff --git a/packages/react/src/experimental/Forms/Fields/Select/SelectBottomActions.tsx b/packages/react/src/experimental/Forms/Fields/Select/SelectBottomActions.tsx index 6b10672084..056adb5085 100644 --- a/packages/react/src/experimental/Forms/Fields/Select/SelectBottomActions.tsx +++ b/packages/react/src/experimental/Forms/Fields/Select/SelectBottomActions.tsx @@ -1,4 +1,4 @@ -import { F0Button, F0ButtonProps } from "@/components/actions/F0Button" +import { F0Button, F0ButtonProps } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" export type Action = { diff --git a/packages/react/src/experimental/Forms/Form/index.stories.tsx b/packages/react/src/experimental/Forms/Form/index.stories.tsx index a02210fd1e..3de1a5ba23 100644 --- a/packages/react/src/experimental/Forms/Form/index.stories.tsx +++ b/packages/react/src/experimental/Forms/Form/index.stories.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import type { Meta, StoryObj } from "@storybook/react-vite" import { F0Checkbox } from "@/components/F0Checkbox" diff --git a/packages/react/src/experimental/Forms/Form/index.tsx b/packages/react/src/experimental/Forms/Form/index.tsx index 264880be80..e7f6c88430 100644 --- a/packages/react/src/experimental/Forms/Form/index.tsx +++ b/packages/react/src/experimental/Forms/Form/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Form as FormProvider } from "@/ui/form" import { FormType, InferSchema, SchemaType } from "../lib/useForm" diff --git a/packages/react/src/experimental/Information/Communities/HighlightBanner/index.tsx b/packages/react/src/experimental/Information/Communities/HighlightBanner/index.tsx index 253dc8d3ea..5732172b20 100644 --- a/packages/react/src/experimental/Information/Communities/HighlightBanner/index.tsx +++ b/packages/react/src/experimental/Information/Communities/HighlightBanner/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0AvatarModule } from "@/components/avatars/F0AvatarModule" type HighlightBannerProps = { diff --git a/packages/react/src/experimental/Information/Communities/Post/CommunityPost/index.tsx b/packages/react/src/experimental/Information/Communities/Post/CommunityPost/index.tsx index 7c3b46420b..0de45b3c27 100644 --- a/packages/react/src/experimental/Information/Communities/Post/CommunityPost/index.tsx +++ b/packages/react/src/experimental/Information/Communities/Post/CommunityPost/index.tsx @@ -1,4 +1,4 @@ -import { F0Link } from "@/components/actions/F0Link" +import { F0Link } from "@/components/F0Link" import { F0AvatarIcon } from "@/components/avatars/F0AvatarIcon" import { F0AvatarPerson } from "@/components/avatars/F0AvatarPerson" import { Reactions, ReactionsProps } from "@/experimental/Information/Reactions" diff --git a/packages/react/src/experimental/Information/Headers/BaseHeader/index.tsx b/packages/react/src/experimental/Information/Headers/BaseHeader/index.tsx index bf166bc31f..f7885bb2ca 100644 --- a/packages/react/src/experimental/Information/Headers/BaseHeader/index.tsx +++ b/packages/react/src/experimental/Information/Headers/BaseHeader/index.tsx @@ -1,8 +1,8 @@ -import { F0Button, F0ButtonProps } from "@/components/actions/F0Button" +import { F0Button, F0ButtonProps } from "@/components/F0Button" import { F0ButtonDropdown, F0ButtonDropdownProps, -} from "@/components/actions/F0ButtonDropdown" +} from "@/components/F0ButtonDropdown" import { AvatarVariant, F0Avatar } from "@/components/avatars/F0Avatar" import { StatusVariant } from "@/components/tags/F0TagStatus" import { Description } from "@/experimental/Information/Headers/BaseHeader/Description" diff --git a/packages/react/src/experimental/Information/Headers/Metadata/index.tsx b/packages/react/src/experimental/Information/Headers/Metadata/index.tsx index 70cf797cac..05e73d1ee6 100644 --- a/packages/react/src/experimental/Information/Headers/Metadata/index.tsx +++ b/packages/react/src/experimental/Information/Headers/Metadata/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { ButtonCopy } from "@/ui/ButtonCopy" import { diff --git a/packages/react/src/experimental/Information/Headers/SectionHeader/index.tsx b/packages/react/src/experimental/Information/Headers/SectionHeader/index.tsx index 00822d8ccc..981ed49b9a 100644 --- a/packages/react/src/experimental/Information/Headers/SectionHeader/index.tsx +++ b/packages/react/src/experimental/Information/Headers/SectionHeader/index.tsx @@ -1,6 +1,6 @@ -import { F0Button, type F0ButtonProps } from "@/components/actions/F0Button" -import { F0Link } from "@/components/actions/F0Link" +import { F0Button, type F0ButtonProps } from "@/components/F0Button" import type { IconType } from "@/components/F0Icon" +import { F0Link } from "@/components/F0Link" import { useLayout } from "@/components/layouts/LayoutProvider" import { cn } from "@/lib/utils" diff --git a/packages/react/src/experimental/Information/Reactions/Picker/index.tsx b/packages/react/src/experimental/Information/Reactions/Picker/index.tsx index 2052aa3fba..92ffcf2b12 100644 --- a/packages/react/src/experimental/Information/Reactions/Picker/index.tsx +++ b/packages/react/src/experimental/Information/Reactions/Picker/index.tsx @@ -1,11 +1,11 @@ -import { F0ButtonProps } from "@/components/actions/F0Button" +import { F0ButtonProps } from "@/components/F0Button" import { Reaction } from "@/icons/app" import { Popover, PopoverContent, PopoverTrigger } from "@/ui/popover" import data from "@emoji-mart/data/sets/15/twitter.json" import EmojiPicker from "@emoji-mart/react" import { useState } from "react" -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import "./index.css" const EMOJI_BUTTON_SIZE = 36 diff --git a/packages/react/src/experimental/Information/Reactions/index.tsx b/packages/react/src/experimental/Information/Reactions/index.tsx index 003450b94a..7887e61113 100644 --- a/packages/react/src/experimental/Information/Reactions/index.tsx +++ b/packages/react/src/experimental/Information/Reactions/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" import { Picker } from "./Picker" import { Reaction, ReactionProps } from "./reaction" diff --git a/packages/react/src/experimental/Information/utils.tsx b/packages/react/src/experimental/Information/utils.tsx index 2a41c74180..7e259dfd70 100644 --- a/packages/react/src/experimental/Information/utils.tsx +++ b/packages/react/src/experimental/Information/utils.tsx @@ -1,4 +1,4 @@ -import { ButtonDropdownItem } from "@/components/actions/F0ButtonDropdown" +import { ButtonDropdownItem } from "@/components/F0ButtonDropdown" import { IconType } from "@/components/F0Icon" export interface PrimaryAction { diff --git a/packages/react/src/experimental/Lists/OnePersonListItem/index.tsx b/packages/react/src/experimental/Lists/OnePersonListItem/index.tsx index 04a34af6d2..00790ead7e 100644 --- a/packages/react/src/experimental/Lists/OnePersonListItem/index.tsx +++ b/packages/react/src/experimental/Lists/OnePersonListItem/index.tsx @@ -1,6 +1,6 @@ -import { F0Button } from "@/components/actions/F0Button" import { AvatarBadge } from "@/components/avatars/F0Avatar/types" import { F0AvatarPerson } from "@/components/avatars/F0AvatarPerson" +import { F0Button } from "@/components/F0Button" import { F0Icon, IconType } from "@/components/F0Icon" import { F0TagDot, TagDotProps } from "@/components/tags/F0TagDot" import { F0TagRaw, TagRawProps } from "@/components/tags/F0TagRaw" diff --git a/packages/react/src/experimental/Modals/OneModal/OneModal.stories.tsx b/packages/react/src/experimental/Modals/OneModal/OneModal.stories.tsx index c9a98a33bf..ee4244065e 100644 --- a/packages/react/src/experimental/Modals/OneModal/OneModal.stories.tsx +++ b/packages/react/src/experimental/Modals/OneModal/OneModal.stories.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { ActivityItemList } from "@/experimental/Information/Activity/ActivityItemList" import { Default as ActivityItemListDefault } from "@/experimental/Information/Activity/ActivityItemList/index.stories" import { ResourceHeader } from "@/experimental/Information/Headers/ResourceHeader" diff --git a/packages/react/src/experimental/Modals/OneModal/OneModalHeader/OneModalHeader.tsx b/packages/react/src/experimental/Modals/OneModal/OneModalHeader/OneModalHeader.tsx index b07c37c3ac..ec8adfd6b3 100644 --- a/packages/react/src/experimental/Modals/OneModal/OneModalHeader/OneModalHeader.tsx +++ b/packages/react/src/experimental/Modals/OneModal/OneModalHeader/OneModalHeader.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { ModuleId } from "@/components/avatars/F0AvatarModule" import { DropdownInternal, diff --git a/packages/react/src/experimental/Navigation/Carousel/DynamicCarousel/index.tsx b/packages/react/src/experimental/Navigation/Carousel/DynamicCarousel/index.tsx index 24ad8c3bbb..df8576c089 100644 --- a/packages/react/src/experimental/Navigation/Carousel/DynamicCarousel/index.tsx +++ b/packages/react/src/experimental/Navigation/Carousel/DynamicCarousel/index.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { ChevronLeft, ChevronRight } from "@/icons/app" import { cn } from "@/lib/utils" import { PropsWithChildren, useLayoutEffect, useRef, useState } from "react" diff --git a/packages/react/src/experimental/Navigation/DaytimePage/index.tsx b/packages/react/src/experimental/Navigation/DaytimePage/index.tsx index 6af1832306..a9c252e49f 100644 --- a/packages/react/src/experimental/Navigation/DaytimePage/index.tsx +++ b/packages/react/src/experimental/Navigation/DaytimePage/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0AvatarPerson } from "@/components/avatars/F0AvatarPerson" import { F0AvatarPulse } from "@/components/avatars/F0AvatarPulse" import { OneSwitch } from "@/experimental/AiChat/OneSwitch" diff --git a/packages/react/src/experimental/Navigation/Dropdown/index.tsx b/packages/react/src/experimental/Navigation/Dropdown/index.tsx index 307d4bb652..fb8eac93f8 100644 --- a/packages/react/src/experimental/Navigation/Dropdown/index.tsx +++ b/packages/react/src/experimental/Navigation/Dropdown/index.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { F0Icon } from "@/components/F0Icon" import { EllipsisHorizontal } from "@/icons/app" import { Link } from "@/lib/linkHandler" diff --git a/packages/react/src/experimental/Navigation/Dropdown/internal.tsx b/packages/react/src/experimental/Navigation/Dropdown/internal.tsx index b81bdfbb04..fda4393e6d 100644 --- a/packages/react/src/experimental/Navigation/Dropdown/internal.tsx +++ b/packages/react/src/experimental/Navigation/Dropdown/internal.tsx @@ -1,6 +1,6 @@ -import { F0ButtonProps } from "@/components/actions/F0Button" -import { ButtonInternal } from "@/components/actions/F0Button/internal" import { AvatarVariant } from "@/components/avatars/F0Avatar" +import { F0ButtonProps } from "@/components/F0Button" +import { ButtonInternal } from "@/components/F0Button/internal" import { IconType } from "@/components/F0Icon" import { EllipsisHorizontal } from "@/icons/app" import { Link } from "@/lib/linkHandler" diff --git a/packages/react/src/experimental/Navigation/F0TableOfContent/Item/ItemDropDown.tsx b/packages/react/src/experimental/Navigation/F0TableOfContent/Item/ItemDropDown.tsx index 3051581ed1..d7bfb4c8a0 100644 --- a/packages/react/src/experimental/Navigation/F0TableOfContent/Item/ItemDropDown.tsx +++ b/packages/react/src/experimental/Navigation/F0TableOfContent/Item/ItemDropDown.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { Ellipsis } from "@/icons/app" import { Dropdown, DropdownItem } from "../../Dropdown" diff --git a/packages/react/src/experimental/Navigation/F0TableOfContent/Item/PrimitiveItem.tsx b/packages/react/src/experimental/Navigation/F0TableOfContent/Item/PrimitiveItem.tsx index 15508ddd32..d57f2a2ac5 100644 --- a/packages/react/src/experimental/Navigation/F0TableOfContent/Item/PrimitiveItem.tsx +++ b/packages/react/src/experimental/Navigation/F0TableOfContent/Item/PrimitiveItem.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { F0Icon } from "@/components/F0Icon" import { OneEllipsis } from "@/components/OneEllipsis/OneEllipsis" import { Counter } from "@/experimental" diff --git a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx index 366f30cfea..a5873b5bc7 100644 --- a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx +++ b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.stories.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" import { FiltersDefinition } from "@/components/OneFilterPicker" import { SelectItemProps } from "@/experimental/Forms/Fields/Select/types" diff --git a/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx b/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx index 9d45f388bb..1fbb1d3628 100644 --- a/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx +++ b/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" import { ModuleId } from "@/components/avatars/F0AvatarModule" +import { F0Button } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" import type { StatusVariant } from "@/components/tags/F0TagStatus" import { F0TagStatus } from "@/components/tags/F0TagStatus" @@ -13,7 +13,7 @@ import { Skeleton } from "@/ui/skeleton" import { AnimatePresence, motion } from "motion/react" import { ReactElement, useRef, useState } from "react" -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { OneSwitch } from "@/experimental/AiChat/OneSwitch" import { Breadcrumbs, BreadcrumbsProps } from "../Breadcrumbs" import { FavoriteButton } from "../Favorites" diff --git a/packages/react/src/experimental/Navigation/Header/ProductUpdates/index.tsx b/packages/react/src/experimental/Navigation/Header/ProductUpdates/index.tsx index efa0af20fd..31a32f4d55 100644 --- a/packages/react/src/experimental/Navigation/Header/ProductUpdates/index.tsx +++ b/packages/react/src/experimental/Navigation/Header/ProductUpdates/index.tsx @@ -1,5 +1,5 @@ -import { F0Button, F0ButtonProps } from "@/components/actions/F0Button" -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { F0Button, F0ButtonProps } from "@/components/F0Button" +import { ButtonInternal } from "@/components/F0Button/internal" import { F0Icon } from "@/components/F0Icon" import { ProductCard } from "@/components/UpsellingKit/ProductCard" import AlertCircle from "@/icons/app/AlertCircle" diff --git a/packages/react/src/experimental/Navigation/Sidebar/Footer/index.tsx b/packages/react/src/experimental/Navigation/Sidebar/Footer/index.tsx index 85b34e1d40..0b6e7e97ed 100644 --- a/packages/react/src/experimental/Navigation/Sidebar/Footer/index.tsx +++ b/packages/react/src/experimental/Navigation/Sidebar/Footer/index.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" import { F0AvatarPerson } from "@/components/avatars/F0AvatarPerson" +import { F0Button } from "@/components/F0Button" import { OneEllipsis } from "@/components/OneEllipsis" import { Badge } from "@/experimental/Information/Badge" import { Tooltip } from "@/experimental/Overlays/Tooltip" diff --git a/packages/react/src/experimental/OneActionBar/index.stories.tsx b/packages/react/src/experimental/OneActionBar/index.stories.tsx index dccaa5ddc1..be9a262b78 100644 --- a/packages/react/src/experimental/OneActionBar/index.stories.tsx +++ b/packages/react/src/experimental/OneActionBar/index.stories.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0Checkbox } from "@/components/F0Checkbox" import { Delete, diff --git a/packages/react/src/experimental/OneActionBar/index.tsx b/packages/react/src/experimental/OneActionBar/index.tsx index 128d5468b9..c2678a5e98 100644 --- a/packages/react/src/experimental/OneActionBar/index.tsx +++ b/packages/react/src/experimental/OneActionBar/index.tsx @@ -1,6 +1,6 @@ -import { F0Button } from "@/components/actions/F0Button" -import { F0ButtonDropdown } from "@/components/actions/F0ButtonDropdown" import { F0AvatarAlert } from "@/components/avatars/F0AvatarAlert" +import { F0Button } from "@/components/F0Button" +import { F0ButtonDropdown } from "@/components/F0ButtonDropdown" import { IconType } from "@/components/F0Icon" import { Dropdown, diff --git a/packages/react/src/experimental/OneAlert/index.tsx b/packages/react/src/experimental/OneAlert/index.tsx index b34c0d5e8b..ed02edd968 100644 --- a/packages/react/src/experimental/OneAlert/index.tsx +++ b/packages/react/src/experimental/OneAlert/index.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" import { F0AvatarAlert } from "@/components/avatars/F0AvatarAlert" +import { F0Button } from "@/components/F0Button" import { F0Icon } from "@/components/F0Icon" import { ExternalLink } from "@/icons/app" import { cn, focusRing } from "@/lib/utils" diff --git a/packages/react/src/experimental/OneCalendar/OneCalendar.tsx b/packages/react/src/experimental/OneCalendar/OneCalendar.tsx index 56f0290ccc..e2fa40b49e 100644 --- a/packages/react/src/experimental/OneCalendar/OneCalendar.tsx +++ b/packages/react/src/experimental/OneCalendar/OneCalendar.tsx @@ -1,7 +1,7 @@ import { ChevronLeft, ChevronRight } from "@/icons/app" import { Input } from "@/ui/input" -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { useI18n } from "@/lib/providers/i18n" import { useCallback, useEffect, useMemo, useState } from "react" import { diff --git a/packages/react/src/experimental/OneDataCollection/CollectionActions/CollectionActions.tsx b/packages/react/src/experimental/OneDataCollection/CollectionActions/CollectionActions.tsx index 48703be77a..08d4da5bf0 100644 --- a/packages/react/src/experimental/OneDataCollection/CollectionActions/CollectionActions.tsx +++ b/packages/react/src/experimental/OneDataCollection/CollectionActions/CollectionActions.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { F0Button } from "@/components/F0Button" +import { ButtonInternal } from "@/components/F0Button/internal" import { Ellipsis } from "@/icons/app" import { useState } from "react" import { Dropdown } from "../../Navigation/Dropdown" diff --git a/packages/react/src/experimental/OneDataCollection/Settings/Settings.tsx b/packages/react/src/experimental/OneDataCollection/Settings/Settings.tsx index f5fed3d737..b611a9488b 100644 --- a/packages/react/src/experimental/OneDataCollection/Settings/Settings.tsx +++ b/packages/react/src/experimental/OneDataCollection/Settings/Settings.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { FiltersDefinition } from "@/components/OneFilterPicker/types" import { GroupingDefinition, diff --git a/packages/react/src/experimental/OneDataCollection/Settings/components/GroupingSelector.tsx b/packages/react/src/experimental/OneDataCollection/Settings/components/GroupingSelector.tsx index b60f058390..f1afc34d41 100644 --- a/packages/react/src/experimental/OneDataCollection/Settings/components/GroupingSelector.tsx +++ b/packages/react/src/experimental/OneDataCollection/Settings/components/GroupingSelector.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Select } from "@/experimental/Forms/Fields/Select" import { GroupingDefinition, diff --git a/packages/react/src/experimental/OneDataCollection/Settings/components/SortingSelector.tsx b/packages/react/src/experimental/OneDataCollection/Settings/components/SortingSelector.tsx index fcc3de35cb..01999dc645 100644 --- a/packages/react/src/experimental/OneDataCollection/Settings/components/SortingSelector.tsx +++ b/packages/react/src/experimental/OneDataCollection/Settings/components/SortingSelector.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Select } from "@/experimental/Forms/Fields/Select" import { SortingKey, diff --git a/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsDropdown/ItemActionsDropdown.tsx b/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsDropdown/ItemActionsDropdown.tsx index 8dfcdba573..bd33495e9d 100644 --- a/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsDropdown/ItemActionsDropdown.tsx +++ b/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsDropdown/ItemActionsDropdown.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { Dropdown, DropdownItem } from "@/experimental/Navigation/Dropdown" import { Ellipsis } from "@/icons/app" import { cn } from "@/lib/utils" diff --git a/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsRow/ItemActionsRow.tsx b/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsRow/ItemActionsRow.tsx index 03440433b0..fa856dabe6 100644 --- a/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsRow/ItemActionsRow.tsx +++ b/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsRow/ItemActionsRow.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { DropdownItem, DropdownItemSeparator, diff --git a/packages/react/src/experimental/OneDataCollection/visualizations.tsx b/packages/react/src/experimental/OneDataCollection/visualizations.tsx index fbdc1c453b..1ea32ac792 100644 --- a/packages/react/src/experimental/OneDataCollection/visualizations.tsx +++ b/packages/react/src/experimental/OneDataCollection/visualizations.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0Icon, IconType } from "@/components/F0Icon" import type { FiltersDefinition } from "@/components/OneFilterPicker/types" import { diff --git a/packages/react/src/experimental/OneDataCollection/visualizations/collection/List/components/Row.tsx b/packages/react/src/experimental/OneDataCollection/visualizations/collection/List/components/Row.tsx index 3d4a377b12..2643836469 100644 --- a/packages/react/src/experimental/OneDataCollection/visualizations/collection/List/components/Row.tsx +++ b/packages/react/src/experimental/OneDataCollection/visualizations/collection/List/components/Row.tsx @@ -1,5 +1,5 @@ -import { F0Link } from "@/components/actions/F0Link" import { F0Checkbox } from "@/components/F0Checkbox" +import { F0Link } from "@/components/F0Link" import { ItemActionsMobile } from "@/experimental/OneDataCollection/components/itemActions/ItemActionsMobile/ItemActionsMobile" import { ItemActionsRow } from "@/experimental/OneDataCollection/components/itemActions/ItemActionsRow/ItemActionsRow" import { ItemActionsRowContainer } from "@/experimental/OneDataCollection/components/itemActions/ItemActionsRowContainer" diff --git a/packages/react/src/experimental/OneDateNavigator/components/DateNavigatorTrigger.tsx b/packages/react/src/experimental/OneDateNavigator/components/DateNavigatorTrigger.tsx index c591fd8718..52dafc147e 100644 --- a/packages/react/src/experimental/OneDateNavigator/components/DateNavigatorTrigger.tsx +++ b/packages/react/src/experimental/OneDateNavigator/components/DateNavigatorTrigger.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { F0Button } from "@/components/F0Button" +import { ButtonInternal } from "@/components/F0Button/internal" import type { DateRange, DateRangeComplete, diff --git a/packages/react/src/experimental/OneEmptyState/OneEmptyState.tsx b/packages/react/src/experimental/OneEmptyState/OneEmptyState.tsx index ad5bb11502..a132208738 100644 --- a/packages/react/src/experimental/OneEmptyState/OneEmptyState.tsx +++ b/packages/react/src/experimental/OneEmptyState/OneEmptyState.tsx @@ -1,6 +1,6 @@ -import { F0Button } from "@/components/actions/F0Button" import { F0AvatarAlert } from "@/components/avatars/F0AvatarAlert" import { F0AvatarEmoji } from "@/components/avatars/F0AvatarEmoji" +import { F0Button } from "@/components/F0Button" import { UpsellingButton } from "@/components/UpsellingKit/UpsellingButton" import * as Types from "./types" diff --git a/packages/react/src/experimental/OneTable/index.stories.tsx b/packages/react/src/experimental/OneTable/index.stories.tsx index d02d9b4c05..4207943347 100644 --- a/packages/react/src/experimental/OneTable/index.stories.tsx +++ b/packages/react/src/experimental/OneTable/index.stories.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" import { F0AvatarPerson } from "@/components/avatars/F0AvatarPerson" +import { F0Button } from "@/components/F0Button" import { F0Checkbox } from "@/components/F0Checkbox" import { Delete, Ellipsis, Pencil } from "@/icons/app" import type { Meta, StoryObj } from "@storybook/react-vite" diff --git a/packages/react/src/experimental/Overlays/Dialog/index.stories.tsx b/packages/react/src/experimental/Overlays/Dialog/index.stories.tsx index 42d2c4dc9b..152b5887c3 100644 --- a/packages/react/src/experimental/Overlays/Dialog/index.stories.tsx +++ b/packages/react/src/experimental/Overlays/Dialog/index.stories.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Delete } from "@/icons/app" import type { Meta, StoryObj } from "@storybook/react-vite" import { useState } from "react" diff --git a/packages/react/src/experimental/Overlays/Dialog/index.tsx b/packages/react/src/experimental/Overlays/Dialog/index.tsx index d385498d49..8f15a47d59 100644 --- a/packages/react/src/experimental/Overlays/Dialog/index.tsx +++ b/packages/react/src/experimental/Overlays/Dialog/index.tsx @@ -1,4 +1,4 @@ -import { F0Button, F0ButtonProps } from "@/components/actions/F0Button" +import { F0Button, F0ButtonProps } from "@/components/F0Button" import { F0AvatarAlert, type AlertAvatarProps, diff --git a/packages/react/src/experimental/Overlays/Tooltip/index.stories.tsx b/packages/react/src/experimental/Overlays/Tooltip/index.stories.tsx index 67a83fc5c9..2761a6570a 100644 --- a/packages/react/src/experimental/Overlays/Tooltip/index.stories.tsx +++ b/packages/react/src/experimental/Overlays/Tooltip/index.stories.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import type { Meta, StoryObj } from "@storybook/react-vite" import { Tooltip } from "./index" diff --git a/packages/react/src/experimental/RichText/CoreEditor/Extensions/AIBlock/index.tsx b/packages/react/src/experimental/RichText/CoreEditor/Extensions/AIBlock/index.tsx index 69beb09a41..c4fab98b0c 100644 --- a/packages/react/src/experimental/RichText/CoreEditor/Extensions/AIBlock/index.tsx +++ b/packages/react/src/experimental/RichText/CoreEditor/Extensions/AIBlock/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0Icon, IconType } from "@/components/F0Icon" import { Dropdown, DropdownItem } from "@/experimental/Navigation/Dropdown" import { LiveCompanionLabels } from "@/experimental/RichText/CoreEditor/Extensions/LiveCompanion" diff --git a/packages/react/src/experimental/RichText/CoreEditor/Extensions/LiveCompanion/index.tsx b/packages/react/src/experimental/RichText/CoreEditor/Extensions/LiveCompanion/index.tsx index 151df9bcad..38c14b6e73 100644 --- a/packages/react/src/experimental/RichText/CoreEditor/Extensions/LiveCompanion/index.tsx +++ b/packages/react/src/experimental/RichText/CoreEditor/Extensions/LiveCompanion/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Dropdown } from "@/experimental/Navigation/Dropdown" import { ChevronDown, ChevronUp, Delete } from "@/icons/app" import { Node } from "@tiptap/core" diff --git a/packages/react/src/experimental/RichText/CoreEditor/Extensions/MoodTracker/index.tsx b/packages/react/src/experimental/RichText/CoreEditor/Extensions/MoodTracker/index.tsx index 897a6daf4d..6a72d382ef 100644 --- a/packages/react/src/experimental/RichText/CoreEditor/Extensions/MoodTracker/index.tsx +++ b/packages/react/src/experimental/RichText/CoreEditor/Extensions/MoodTracker/index.tsx @@ -1,9 +1,9 @@ -import { F0Button } from "@/components/actions/F0Button" import { Pulse, pulseIcon, pulseIconColor, } from "@/components/avatars/F0AvatarPulse" +import { F0Button } from "@/components/F0Button" import { F0Icon } from "@/components/F0Icon" import { Dropdown } from "@/experimental/Navigation/Dropdown" import { ChevronDown, ChevronUp, Delete } from "@/icons/app" diff --git a/packages/react/src/experimental/RichText/CoreEditor/Extensions/Transcript/index.tsx b/packages/react/src/experimental/RichText/CoreEditor/Extensions/Transcript/index.tsx index 6d41beb55f..4703e18e66 100644 --- a/packages/react/src/experimental/RichText/CoreEditor/Extensions/Transcript/index.tsx +++ b/packages/react/src/experimental/RichText/CoreEditor/Extensions/Transcript/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0AvatarPerson } from "@/components/avatars/F0AvatarPerson" import { Dropdown } from "@/experimental/Navigation/Dropdown" import { ChevronDown, ChevronUp, Delete } from "@/icons/app" diff --git a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/LinkPopup/index.tsx b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/LinkPopup/index.tsx index 83a9d29320..83b8b2d0bb 100644 --- a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/LinkPopup/index.tsx +++ b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/LinkPopup/index.tsx @@ -1,5 +1,5 @@ -import { F0Button } from "@/components/actions/F0Button" -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { F0Button } from "@/components/F0Button" +import { ButtonInternal } from "@/components/F0Button/internal" import { F0ButtonToggle } from "@/components/F0ButtonToggle" import { F0Icon } from "@/components/F0Icon" import { Badge } from "@/experimental/Information/Badge" diff --git a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/index.tsx b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/index.tsx index d3ad92b3f8..7e5cc36bbb 100644 --- a/packages/react/src/experimental/RichText/CoreEditor/Toolbar/index.tsx +++ b/packages/react/src/experimental/RichText/CoreEditor/Toolbar/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0ButtonToggle } from "@/components/F0ButtonToggle" import { Picker } from "@/experimental/Information/Reactions/Picker" import { diff --git a/packages/react/src/experimental/RichText/NotesTextEditor/Header/index.tsx b/packages/react/src/experimental/RichText/NotesTextEditor/Header/index.tsx index 862f46a4a2..891ded4340 100644 --- a/packages/react/src/experimental/RichText/NotesTextEditor/Header/index.tsx +++ b/packages/react/src/experimental/RichText/NotesTextEditor/Header/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0TagDot } from "@/components/tags/F0TagDot" import { F0TagRaw } from "@/components/tags/F0TagRaw" import { F0TagStatus } from "@/components/tags/F0TagStatus" diff --git a/packages/react/src/experimental/RichText/NotesTextEditor/index.tsx b/packages/react/src/experimental/RichText/NotesTextEditor/index.tsx index beb5cf193d..d01c9e24e3 100644 --- a/packages/react/src/experimental/RichText/NotesTextEditor/index.tsx +++ b/packages/react/src/experimental/RichText/NotesTextEditor/index.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/actions/F0Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { F0Icon } from "@/components/F0Icon" import { Toolbar, ToolbarLabels } from "@/experimental/RichText/CoreEditor" import { SlashCommandGroupLabels } from "@/experimental/RichText/CoreEditor/Extensions/SlashCommand" diff --git a/packages/react/src/experimental/RichText/RichTextEditor/Enhance/AcceptChanges/index.tsx b/packages/react/src/experimental/RichText/RichTextEditor/Enhance/AcceptChanges/index.tsx index d9ea45e1ba..ee85e14209 100644 --- a/packages/react/src/experimental/RichText/RichTextEditor/Enhance/AcceptChanges/index.tsx +++ b/packages/react/src/experimental/RichText/RichTextEditor/Enhance/AcceptChanges/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { ToolbarDivider } from "@/experimental/RichText/CoreEditor" import { enhanceLabelsType, diff --git a/packages/react/src/experimental/RichText/RichTextEditor/Error/index.tsx b/packages/react/src/experimental/RichText/RichTextEditor/Error/index.tsx index 993b64e6c0..9e36b5b7c3 100644 --- a/packages/react/src/experimental/RichText/RichTextEditor/Error/index.tsx +++ b/packages/react/src/experimental/RichText/RichTextEditor/Error/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { F0AvatarAlert } from "@/components/avatars/F0AvatarAlert" import { errorConfig } from "@/experimental/RichText/RichTextEditor/utils/types" import { Editor } from "@tiptap/react" diff --git a/packages/react/src/experimental/RichText/RichTextEditor/Footer/ActionsMenu/index.tsx b/packages/react/src/experimental/RichText/RichTextEditor/Footer/ActionsMenu/index.tsx index e15b0452d3..155f5f0284 100644 --- a/packages/react/src/experimental/RichText/RichTextEditor/Footer/ActionsMenu/index.tsx +++ b/packages/react/src/experimental/RichText/RichTextEditor/Footer/ActionsMenu/index.tsx @@ -1,8 +1,8 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { ButtonDropdownItem, F0ButtonDropdown, -} from "@/components/actions/F0ButtonDropdown" +} from "@/components/F0ButtonDropdown" import { Switch } from "@/experimental/Forms/Fields/Switch" import { ToolbarDivider } from "@/experimental/RichText/CoreEditor" import { diff --git a/packages/react/src/experimental/RichText/RichTextEditor/Footer/index.tsx b/packages/react/src/experimental/RichText/RichTextEditor/Footer/index.tsx index a0052f4024..8d01b0c762 100644 --- a/packages/react/src/experimental/RichText/RichTextEditor/Footer/index.tsx +++ b/packages/react/src/experimental/RichText/RichTextEditor/Footer/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Toolbar, ToolbarDivider, diff --git a/packages/react/src/experimental/RichText/RichTextEditor/Head/index.tsx b/packages/react/src/experimental/RichText/RichTextEditor/Head/index.tsx index 3d66bb2294..717e33f77b 100644 --- a/packages/react/src/experimental/RichText/RichTextEditor/Head/index.tsx +++ b/packages/react/src/experimental/RichText/RichTextEditor/Head/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { Maximize, Minimize } from "@/icons/app" interface HeadProps { diff --git a/packages/react/src/experimental/Utilities/PrivateBox/index.stories.tsx b/packages/react/src/experimental/Utilities/PrivateBox/index.stories.tsx index 65ca8b0b04..d58f2f7ca2 100644 --- a/packages/react/src/experimental/Utilities/PrivateBox/index.stories.tsx +++ b/packages/react/src/experimental/Utilities/PrivateBox/index.stories.tsx @@ -1,5 +1,5 @@ // Replace your-framework with the name of your framework -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { usePrivacyMode } from "@/lib/privacyMode" import type { Meta, StoryObj } from "@storybook/react-vite" import { PrivateBox } from "./index" diff --git a/packages/react/src/experimental/Utilities/ScrollArea/index.stories.tsx b/packages/react/src/experimental/Utilities/ScrollArea/index.stories.tsx index a7f27dd426..0440dbc614 100644 --- a/packages/react/src/experimental/Utilities/ScrollArea/index.stories.tsx +++ b/packages/react/src/experimental/Utilities/ScrollArea/index.stories.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { ScrollArea } from "./index" import { Placeholder } from "@/lib/storybook-utils/placeholder" diff --git a/packages/react/src/experimental/Widgets/ChartWidgetEmptyState/index.tsx b/packages/react/src/experimental/Widgets/ChartWidgetEmptyState/index.tsx index 988ce88009..365d68aeb1 100644 --- a/packages/react/src/experimental/Widgets/ChartWidgetEmptyState/index.tsx +++ b/packages/react/src/experimental/Widgets/ChartWidgetEmptyState/index.tsx @@ -1,4 +1,4 @@ -import { F0Button, type F0ButtonProps } from "@/components/actions/F0Button" +import { F0Button, type F0ButtonProps } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" import { cn } from "@/lib/utils" import { Card, CardContent, CardHeader, CardTitle } from "@/ui/Card" diff --git a/packages/react/src/experimental/Widgets/Content/ClockIn/ClockInControls/index.tsx b/packages/react/src/experimental/Widgets/Content/ClockIn/ClockInControls/index.tsx index e2bd711e8a..99f64eef7f 100644 --- a/packages/react/src/experimental/Widgets/Content/ClockIn/ClockInControls/index.tsx +++ b/packages/react/src/experimental/Widgets/Content/ClockIn/ClockInControls/index.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { IconType } from "@/components/F0Icon" import { F0TagRaw } from "@/components/tags/F0TagRaw" import { Select } from "@/experimental/Forms/Fields/Select" diff --git a/packages/react/src/experimental/Widgets/Widget/index.tsx b/packages/react/src/experimental/Widgets/Widget/index.tsx index 91bc2e3709..a7f394aaf9 100644 --- a/packages/react/src/experimental/Widgets/Widget/index.tsx +++ b/packages/react/src/experimental/Widgets/Widget/index.tsx @@ -1,4 +1,4 @@ -import { F0Button, type F0ButtonProps } from "@/components/actions/F0Button" +import { F0Button, type F0ButtonProps } from "@/components/F0Button" import { F0Icon, IconType } from "@/components/F0Icon" import { F0TagAlert } from "@/components/tags/F0TagAlert" import { F0TagStatus, StatusVariant } from "@/components/tags/F0TagStatus" diff --git a/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx b/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx index 9132880150..a18c75b01c 100644 --- a/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx +++ b/packages/react/src/ui/ButtonCopy/ButtonCopy.tsx @@ -4,7 +4,7 @@ import { useI18n } from "@/lib/providers/i18n" import { Action, ActionButtonVariant, ActionProps } from "@/ui/Action" import { AnimatePresence, motion } from "motion/react" import { forwardRef, MouseEventHandler, useEffect, useState } from "react" -import { iconOnlyVariants } from "../../components/actions/F0Button/internal" +import { iconOnlyVariants } from "../../components/F0Button/internal" export type ButtonCopyProps = Omit< ActionProps, diff --git a/packages/react/src/ui/ButtonCopy/__stories__/ButtonCopy.stories.tsx b/packages/react/src/ui/ButtonCopy/__stories__/ButtonCopy.stories.tsx index 61efa58723..3fe2582d10 100644 --- a/packages/react/src/ui/ButtonCopy/__stories__/ButtonCopy.stories.tsx +++ b/packages/react/src/ui/ButtonCopy/__stories__/ButtonCopy.stories.tsx @@ -72,9 +72,15 @@ export const Default: Story = { args: { valueToCopy: "This text will be copied!", }, - play: async ({ canvasElement, step }) => { + play: async ({ canvasElement, step, args }) => { const canvas = within(canvasElement) + let clipboard = "" + navigator.clipboard.writeText = (text: string) => { + clipboard = text + return Promise.resolve() + } + await step("Verify initial state", async () => { const button = canvas.getByRole("button") expect(button).toBeInTheDocument() @@ -91,6 +97,7 @@ export const Default: Story = { const button = canvas.getByRole("button") expect(button.getAttribute("aria-label")).toBe("Copied") expect(button.getAttribute("title")).toBe("Copied") + expect(clipboard).toBe(args.valueToCopy) }) }, } diff --git a/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx b/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx index 8d1fbf63ec..01d799cb59 100644 --- a/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx +++ b/packages/react/src/ui/DatePickerPopup/OneDatePickerPopup.tsx @@ -1,4 +1,4 @@ -import { F0Button } from "@/components/actions/F0Button" +import { F0Button } from "@/components/F0Button" import { GranularityDefinitionKey, OneCalendar, diff --git a/packages/react/src/ui/carousel.tsx b/packages/react/src/ui/carousel.tsx index 87161f4891..4df3732d3e 100644 --- a/packages/react/src/ui/carousel.tsx +++ b/packages/react/src/ui/carousel.tsx @@ -6,8 +6,8 @@ import useEmblaCarousel, { } from "embla-carousel-react" import * as React from "react" -import { ButtonInternal } from "@/components/actions/F0Button/internal" -import { ButtonInternalProps } from "@/components/actions/F0Button/internal-types" +import { ButtonInternal } from "@/components/F0Button/internal" +import { ButtonInternalProps } from "@/components/F0Button/internal-types" import { SPACE_FOR_WIDGET_SHADOW } from "@/experimental/Navigation/Carousel/DynamicCarousel" import { cn } from "@/lib/utils" From e4ccc05ce6b69454c8f370aad6c8c4a65199b053 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Fri, 19 Sep 2025 09:39:09 +0200 Subject: [PATCH 19/38] chore: fix button title --- packages/react/src/components/F0Button/internal.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react/src/components/F0Button/internal.tsx b/packages/react/src/components/F0Button/internal.tsx index 6be883c867..3dd179f287 100644 --- a/packages/react/src/components/F0Button/internal.tsx +++ b/packages/react/src/components/F0Button/internal.tsx @@ -101,6 +101,7 @@ const ButtonInternal = forwardRef( className={className} mode={hideLabel ? "only" : "default"} aria-label={props.title || label} + title={props.title || (hideLabel ? label : undefined)} >
Date: Fri, 19 Sep 2025 09:54:00 +0200 Subject: [PATCH 20/38] chore: fix test --- .../react/src/components/F0Button/__tests__/F0Button.test.tsx | 2 +- packages/react/src/components/F0Link/__tests__/index.test.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react/src/components/F0Button/__tests__/F0Button.test.tsx b/packages/react/src/components/F0Button/__tests__/F0Button.test.tsx index 8b664a76be..734f6777fc 100644 --- a/packages/react/src/components/F0Button/__tests__/F0Button.test.tsx +++ b/packages/react/src/components/F0Button/__tests__/F0Button.test.tsx @@ -1,7 +1,7 @@ +import { Add } from "@/icons/app" import { render, screen } from "@testing-library/react" import { userEvent } from "@testing-library/user-event" import { describe, expect, it, vi } from "vitest" -import { Add } from "../../../../icons/app" import { F0Button } from "../index" describe("F0Button", () => { diff --git a/packages/react/src/components/F0Link/__tests__/index.test.tsx b/packages/react/src/components/F0Link/__tests__/index.test.tsx index 3d1cc8748c..bf9370f542 100644 --- a/packages/react/src/components/F0Link/__tests__/index.test.tsx +++ b/packages/react/src/components/F0Link/__tests__/index.test.tsx @@ -1,7 +1,7 @@ +import { useNavigation } from "@/lib/linkHandler" import { render, screen } from "@testing-library/react" import { describe, expect, it, vi } from "vitest" import { F0Link } from ".." -import { useNavigation } from "../../../../lib/linkHandler" vi.mock("@/lib/linkHandler", async () => { const module = await import("../__mocks__/linkHandler") From e1fc561ba2079304cc0b938e71c9323f3643f20f Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 25 Sep 2025 12:17:41 +0200 Subject: [PATCH 21/38] chore: merge main --- pnpm-lock.yaml | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a37a5877de..e0d101ddc4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -388,14 +388,10 @@ importers: version: 11.2.0(size-limit@11.2.0) '@storybook/addon-a11y': specifier: ^9.1.3 -<<<<<<< HEAD - version: 9.1.3(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) + version: 9.1.3(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) '@storybook/addon-designs': specifier: ^10.0.2 - version: 10.0.2(@storybook/addon-docs@9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) -======= - version: 9.1.3(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) ->>>>>>> c4ce8ed312080660a0a0e6270f11ab09193f6287 + version: 10.0.2(@storybook/addon-docs@9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) '@storybook/addon-docs': specifier: ^9.1.3 version: 9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) @@ -2351,7 +2347,7 @@ packages: '@expo/bunyan@4.0.1': resolution: {integrity: sha512-+Lla7nYSiHZirgK+U/uYzsLv/X+HaJienbD5AKX1UQZHYfWaP+9uuQluRB4GrEVWF0GZ7vEVp/jzaOT9k/SQlg==} - engines: {node: '>=0.10.0'} + engines: {'0': node >=0.10.0} '@expo/cli@0.22.24': resolution: {integrity: sha512-lhdenxBC8/x/vL39j79eXE09mOaqNNLmiSDdY/PblnI+UNzGgsQ48hBTYa/MQhd0ioXXVKurZL2941dLKwcxJw==} @@ -17684,20 +17680,16 @@ snapshots: storybook: 8.6.14(prettier@2.8.8) ts-dedent: 2.2.0 -<<<<<<< HEAD - '@storybook/addon-designs@10.0.2(@storybook/addon-docs@9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))': + '@storybook/addon-designs@10.0.2(@storybook/addon-docs@9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))': dependencies: '@figspec/react': 1.0.4(react@18.3.1) - storybook: 9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) optionalDependencies: - '@storybook/addon-docs': 9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) + '@storybook/addon-docs': 9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/addon-docs@9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.0)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))': -======= '@storybook/addon-docs@9.1.3(@types/react@18.3.18)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))': ->>>>>>> c4ce8ed312080660a0a0e6270f11ab09193f6287 dependencies: '@mdx-js/react': 3.1.0(@types/react@18.3.18)(react@18.3.1) '@storybook/csf-plugin': 9.1.3(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) @@ -19463,14 +19455,6 @@ snapshots: picocolors: 1.1.1 playwright: 1.52.0 - axios@1.8.4: - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.2 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - axios@1.8.4(debug@4.4.1): dependencies: follow-redirects: 1.15.9(debug@4.4.1) @@ -21386,8 +21370,6 @@ snapshots: flow-parser@0.263.0: {} - follow-redirects@1.15.9: {} - follow-redirects@1.15.9(debug@4.4.1): optionalDependencies: debug: 4.4.1 @@ -21942,7 +21924,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.9 + follow-redirects: 1.15.9(debug@4.4.1) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -27322,7 +27304,7 @@ snapshots: wait-on@7.2.0: dependencies: - axios: 1.8.4 + axios: 1.8.4(debug@4.4.1) joi: 17.13.3 lodash: 4.17.21 minimist: 1.2.8 From 6a65c5862795ababaff363c6a8c02d4b0d403797 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 25 Sep 2025 12:36:20 +0200 Subject: [PATCH 22/38] chore: remove acation exports --- packages/react/src/components/Actions/exports.tsx | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 packages/react/src/components/Actions/exports.tsx diff --git a/packages/react/src/components/Actions/exports.tsx b/packages/react/src/components/Actions/exports.tsx deleted file mode 100644 index 0813c4b912..0000000000 --- a/packages/react/src/components/Actions/exports.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { Component } from "../../lib/component/component" -import { Link as LinkComponent } from "./Link" - -export * from "./Button" - -export type { LinkProps } from "./Link" -export const Link = Component( - { - name: "Link", - type: "info", - }, - LinkComponent -) From b4ffd83c1fb4c8d13ee4a18b48f70ae5cfadbf36 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Thu, 25 Sep 2025 12:42:38 +0200 Subject: [PATCH 23/38] chore: remove acation exports --- .../experimental/RichText/NotesTextEditor/index.stories.tsx | 1 + packages/react/src/ui/Kanban/components/KanbanCard.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx b/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx index eccb4ef427..3af4d8b68e 100644 --- a/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx +++ b/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx @@ -253,6 +253,7 @@ export const Default: Story = { { type: "text", content: "Metadata", + label: "Metadata", }, ], }, diff --git a/packages/react/src/ui/Kanban/components/KanbanCard.tsx b/packages/react/src/ui/Kanban/components/KanbanCard.tsx index 285559ad6c..692abcb9e4 100644 --- a/packages/react/src/ui/Kanban/components/KanbanCard.tsx +++ b/packages/react/src/ui/Kanban/components/KanbanCard.tsx @@ -1,5 +1,5 @@ -import { Link } from "@/components/Actions/Link" import { CardInternal } from "@/components/F0Card/CardInternal" +import { F0Link } from "@/components/F0Link" import { useDraggable } from "@/lib/dnd/hooks" import { cn, focusRing } from "@/lib/utils" import { @@ -104,7 +104,7 @@ export function KanbanCard({ > {props.link && ( - Date: Mon, 29 Sep 2025 10:14:53 +0200 Subject: [PATCH 24/38] chore: merge main --- pnpm-lock.yaml | 54 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a654a1f09b..4cc35c3997 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -31,7 +31,7 @@ importers: version: 0.4.20(eslint@9.27.0(jiti@2.4.2)) eslint-plugin-storybook: specifier: ^9.1.3 - version: 9.1.3(eslint@9.27.0(jiti@2.4.2))(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)))(typescript@5.8.2) + version: 9.1.3(eslint@9.27.0(jiti@2.4.2))(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))(typescript@5.8.2) lefthook: specifier: ^1.11.3 version: 1.11.3 @@ -68,7 +68,7 @@ importers: version: 3.5.2 tsup: specifier: ^8.3.5 - version: 8.3.6(@microsoft/api-extractor@7.52.8)(@swc/core@1.11.13)(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.2)(yaml@2.7.0) + version: 8.3.6(@microsoft/api-extractor@7.52.8(@types/node@22.15.21))(@swc/core@1.11.13(@swc/helpers@0.5.17))(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.2)(yaml@2.7.0) packages/react: dependencies: @@ -463,7 +463,7 @@ importers: version: 4.3.4(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) '@vitest/coverage-v8': specifier: ^3.2.4 - version: 3.2.4(vitest@3.0.7(@types/debug@4.1.12)(@types/node@22.15.21)(@vitest/ui@3.0.7)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(terser@5.43.1)(yaml@2.7.0)) + version: 3.2.4(vitest@3.0.7) '@vitest/ui': specifier: 3.0.7 version: 3.0.7(vitest@3.0.7) @@ -502,7 +502,7 @@ importers: version: 0.4.20(eslint@9.27.0(jiti@2.4.2)) eslint-plugin-storybook: specifier: ^9.1.3 - version: 9.1.3(eslint@9.27.0(jiti@2.4.2))(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)))(typescript@5.8.2) + version: 9.1.3(eslint@9.27.0(jiti@2.4.2))(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))(typescript@5.8.2) globals: specifier: ^16.0.0 version: 16.0.0 @@ -550,13 +550,13 @@ importers: version: 11.2.0 storybook: specifier: ^9.1.3 - version: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + version: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) storybook-addon-tag-badges: specifier: ^2.0.2 version: 2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) tsup: specifier: ^8.3.5 - version: 8.3.6(@microsoft/api-extractor@7.52.8)(@swc/core@1.11.13)(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.2)(yaml@2.7.0) + version: 8.3.6(@microsoft/api-extractor@7.52.8(@types/node@22.15.21))(@swc/core@1.11.13(@swc/helpers@0.5.17))(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.2)(yaml@2.7.0) typescript: specifier: ^5.7.2 version: 5.8.2 @@ -14459,7 +14459,7 @@ snapshots: chromatic: 12.2.0 filesize: 10.1.6 jsonfile: 6.1.0 - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) strip-ansi: 7.1.0 transitivePeerDependencies: - '@chromatic-com/cypress' @@ -17558,7 +17558,7 @@ snapshots: dependencies: '@storybook/global': 5.0.0 axe-core: 4.10.3 - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) '@storybook/addon-actions@8.6.14(storybook@8.6.14(prettier@2.8.8))': dependencies: @@ -17593,7 +17593,7 @@ snapshots: '@storybook/react-dom-shim': 9.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) ts-dedent: 2.2.0 transitivePeerDependencies: - '@types/react' @@ -17601,7 +17601,7 @@ snapshots: '@storybook/addon-links@9.1.3(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))': dependencies: '@storybook/global': 5.0.0 - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) optionalDependencies: react: 18.3.1 @@ -17665,13 +17665,13 @@ snapshots: '@storybook/addon-themes@9.1.3(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))': dependencies: - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) ts-dedent: 2.2.0 '@storybook/builder-vite@9.1.3(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))': dependencies: '@storybook/csf-plugin': 9.1.3(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) ts-dedent: 2.2.0 vite: 6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0) @@ -17702,7 +17702,7 @@ snapshots: '@storybook/csf-plugin@9.1.3(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))': dependencies: - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) unplugin: 1.16.1 '@storybook/csf@0.1.13': @@ -17741,7 +17741,7 @@ snapshots: dependencies: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) '@storybook/react-native-theming@8.6.4(react-native@0.76.9(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@18.3.18)(react@18.3.1))(react@18.3.1)': dependencies: @@ -17822,7 +17822,7 @@ snapshots: react-docgen: 8.0.0 react-dom: 18.3.1(react@18.3.1) resolve: 1.22.10 - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) tsconfig-paths: 4.2.0 vite: 6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0) transitivePeerDependencies: @@ -17851,7 +17851,7 @@ snapshots: '@storybook/react-dom-shim': 9.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) optionalDependencies: typescript: 5.8.2 @@ -17875,7 +17875,7 @@ snapshots: jest-watch-typeahead: 2.2.2(jest@29.7.0(@types/node@22.15.21)) nyc: 15.1.0 playwright: 1.52.0 - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) transitivePeerDependencies: - '@swc/helpers' - '@types/node' @@ -18748,7 +18748,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@3.2.4(vitest@3.0.7(@types/debug@4.1.12)(@types/node@22.15.21)(@vitest/ui@3.0.7)(jiti@2.4.2)(jsdom@26.0.0)(lightningcss@1.29.2)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(terser@5.43.1)(yaml@2.7.0))': + '@vitest/coverage-v8@3.2.4(vitest@3.0.7)': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -18799,7 +18799,7 @@ snapshots: msw: 2.10.4(@types/node@22.15.21)(typescript@5.8.2) vite: 6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0) - '@vitest/mocker@3.2.4(msw@2.10.4(typescript@5.8.2))(vite@6.3.5(jiti@2.4.2))': + '@vitest/mocker@3.2.4(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 @@ -20694,11 +20694,11 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 - eslint-plugin-storybook@9.1.3(eslint@9.27.0(jiti@2.4.2))(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)))(typescript@5.8.2): + eslint-plugin-storybook@9.1.3(eslint@9.27.0(jiti@2.4.2))(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)))(typescript@5.8.2): dependencies: '@typescript-eslint/utils': 8.32.1(eslint@9.27.0(jiti@2.4.2))(typescript@5.8.2) eslint: 9.27.0(jiti@2.4.2) - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) transitivePeerDependencies: - supports-color - typescript @@ -21866,7 +21866,7 @@ snapshots: isstream: 0.1.2 jsonwebtoken: 9.0.2 mime-types: 2.1.35 - retry-axios: 2.6.0(axios@1.8.4(debug@4.4.1)) + retry-axios: 2.6.0(axios@1.8.4) tough-cookie: 4.1.4 transitivePeerDependencies: - supports-color @@ -25667,7 +25667,7 @@ snapshots: onetime: 2.0.1 signal-exit: 3.0.7 - retry-axios@2.6.0(axios@1.8.4(debug@4.4.1)): + retry-axios@2.6.0(axios@1.8.4): dependencies: axios: 1.8.4(debug@4.4.1) @@ -26066,7 +26066,7 @@ snapshots: storybook-addon-tag-badges@2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0))): dependencies: '@storybook/icons': 1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)) + storybook: 9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) transitivePeerDependencies: - react - react-dom @@ -26081,13 +26081,13 @@ snapshots: - supports-color - utf-8-validate - storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(jiti@2.4.2)): + storybook@9.1.3(@testing-library/dom@10.4.1)(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(prettier@3.5.2)(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)): dependencies: '@storybook/global': 5.0.0 '@testing-library/jest-dom': 6.6.3 '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.1) '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(msw@2.10.4(typescript@5.8.2))(vite@6.3.5(jiti@2.4.2)) + '@vitest/mocker': 3.2.4(msw@2.10.4(@types/node@22.15.21)(typescript@5.8.2))(vite@6.3.5(@types/node@22.15.21)(jiti@2.4.2)(lightningcss@1.29.2)(terser@5.43.1)(yaml@2.7.0)) '@vitest/spy': 3.2.4 better-opn: 3.0.2 esbuild: 0.25.4 @@ -26574,7 +26574,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.3.6(@microsoft/api-extractor@7.52.8)(@swc/core@1.11.13)(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.2)(yaml@2.7.0): + tsup@8.3.6(@microsoft/api-extractor@7.52.8(@types/node@22.15.21))(@swc/core@1.11.13(@swc/helpers@0.5.17))(jiti@2.4.2)(postcss@8.5.3)(typescript@5.8.2)(yaml@2.7.0): dependencies: bundle-require: 5.1.0(esbuild@0.24.2) cac: 6.7.14 From 7c02afc40376162b322ec01fd81e3746b9c4eef0 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Tue, 30 Sep 2025 15:59:50 +0200 Subject: [PATCH 25/38] chore: button allow ariaLabel prop --- packages/react/src/components/F0Button/internal-types.ts | 8 +++++++- packages/react/src/components/F0Button/internal.tsx | 3 ++- packages/react/src/components/F0Link/F0Link.tsx | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/react/src/components/F0Button/internal-types.ts b/packages/react/src/components/F0Button/internal-types.ts index 41d92900e8..3a6594ed22 100644 --- a/packages/react/src/components/F0Button/internal-types.ts +++ b/packages/react/src/components/F0Button/internal-types.ts @@ -6,7 +6,13 @@ export type { ButtonType } export type ButtonInternalProps = Pick< ActionProps, - "size" | "disabled" | "className" | "pressed" | "compact" | "variant" + | "size" + | "disabled" + | "className" + | "pressed" + | "compact" + | "variant" + | "aria-label" > & DataAttributes & { /** diff --git a/packages/react/src/components/F0Button/internal.tsx b/packages/react/src/components/F0Button/internal.tsx index 3dd179f287..dedb281545 100644 --- a/packages/react/src/components/F0Button/internal.tsx +++ b/packages/react/src/components/F0Button/internal.tsx @@ -62,6 +62,7 @@ const ButtonInternal = forwardRef( size = "md", append, className, + "aria-label": ariaLabel, ...props }, ref @@ -100,7 +101,7 @@ const ButtonInternal = forwardRef( loading={isLoading} className={className} mode={hideLabel ? "only" : "default"} - aria-label={props.title || label} + aria-label={ariaLabel || props.title || label} title={props.title || (hideLabel ? label : undefined)} >
(function Link( focusRing("focus-visible:rounded-xs focus-visible:ring-offset-2"), className )} + aria-label={props["aria-label"] ?? props.title} > {children} {external && } From 50de3cb2b14c460eb2c2bdee1a7321b765bb6848 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Tue, 30 Sep 2025 16:46:03 +0200 Subject: [PATCH 26/38] chore: fix types --- .../src/experimental/RichText/NotesTextEditor/index.stories.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx b/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx index 73f3bcaa4e..c030f6b5cd 100644 --- a/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx +++ b/packages/react/src/experimental/RichText/NotesTextEditor/index.stories.tsx @@ -254,6 +254,7 @@ export const Default: Story = { { type: "text", content: "Metadata", + label: "Metadata", }, ], }, From 42d26f88095f89976b0de6ca60f9fdec48ee6879 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Tue, 30 Sep 2025 20:43:25 +0200 Subject: [PATCH 27/38] chore: a11y --- packages/react/src/components/F0Link/F0Link.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/react/src/components/F0Link/F0Link.tsx b/packages/react/src/components/F0Link/F0Link.tsx index 76e972e7da..a770bdcd6c 100644 --- a/packages/react/src/components/F0Link/F0Link.tsx +++ b/packages/react/src/components/F0Link/F0Link.tsx @@ -1,11 +1,8 @@ +import ExternalLink from "@/icons/app/ExternalLink" +import { Link as BaseLink, LinkProps as BaseLinkProps } from "@/lib/linkHandler" +import { cn, focusRing } from "@/lib/utils" import { cva, type VariantProps } from "cva" import { forwardRef } from "react" -import ExternalLink from "../../icons/app/ExternalLink" -import { - Link as BaseLink, - LinkProps as BaseLinkProps, -} from "../../lib/linkHandler" -import { cn, focusRing } from "../../lib/utils" import { F0Icon } from "../F0Icon" const linkVariants = cva({ @@ -61,6 +58,7 @@ export const F0Link = forwardRef(function Link( focusRing("focus-visible:rounded-xs focus-visible:ring-offset-2"), className )} + role="link" aria-label={props["aria-label"] ?? props.title} > {children} From 7ef236e2752b5a47811f46143d906cb9cd437507 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Wed, 1 Oct 2025 17:30:49 +0200 Subject: [PATCH 28/38] chore: fix onclick type inference --- packages/react/src/ui/Action/Action.tsx | 297 +++++++++++++----------- 1 file changed, 160 insertions(+), 137 deletions(-) diff --git a/packages/react/src/ui/Action/Action.tsx b/packages/react/src/ui/Action/Action.tsx index 2a11b0f345..bdd8dd5622 100644 --- a/packages/react/src/ui/Action/Action.tsx +++ b/packages/react/src/ui/Action/Action.tsx @@ -4,7 +4,7 @@ import { Skeleton } from "@/ui/skeleton" import { cva } from "cva" import { AnimatePresence, motion } from "motion/react" import React from "react" -import { ActionLinkProps, ActionProps } from "./types" +import { ActionButtonProps, ActionLinkProps, ActionProps } from "./types" import { isLinkStyled } from "./utils" import { actionVariants, @@ -14,152 +14,175 @@ import { loadingVariants, } from "./variants" -export const Action = React.forwardRef( - (props, ref) => { - const isLink = (props: ActionProps): props is ActionLinkProps => { - return "href" in props - } +const ActionImpl = React.forwardRef((props, ref) => { + const isLink = (props: ActionProps): props is ActionLinkProps => { + return "href" in props + } - const { - children, - prepend, - append, - prependOutside, - appendOutside, - disabled, - loading, - pressed, - className, - href, - target, - variant, - size = "md", - mode = "default", - title, - compact = false, - "aria-label": ariaLabel, - ...restProps - } = props + const { + children, + prepend, + append, + prependOutside, + appendOutside, + disabled, + loading, + pressed, + className, + href, + target, + variant, + size = "md", + mode = "default", + title, + compact = false, + "aria-label": ariaLabel, + ...restProps + } = props - const defaultVariant = isLink(props) ? "link" : "default" - const localVariant = variant ?? defaultVariant + const defaultVariant = isLink(props) ? "link" : "default" + const localVariant = variant ?? defaultVariant - const variantClasses = actionVariants({ - variant: localVariant, - pressed, - }) + const variantClasses = actionVariants({ + variant: localVariant, + pressed, + }) - const sizeClasses = isLinkStyled(localVariant) - ? linkSizeVariants({ size }) - : buttonSizeVariants({ size }) + const sizeClasses = isLinkStyled(localVariant) + ? linkSizeVariants({ size }) + : buttonSizeVariants({ size }) - const compactClasses = cva({ - variants: { - size: { - sm: "!px-[4px]", - md: "!px-[6px]", - lg: "!px-[10px]", - }, - }, - defaultVariants: { - size: "md", + const compactClasses = cva({ + variants: { + size: { + sm: "!px-[4px]", + md: "!px-[6px]", + lg: "!px-[10px]", }, - }) - const innerContent = ( - <> -
- {prepend} - - {children} - - {append} -
- - {loading && ( - <> - {isLinkStyled(localVariant) ? ( - - ) : ( -
- -
- )} - - )} -
- - ) + }, + defaultVariants: { + size: "md", + }, + }) + const innerContent = ( + <> +
+ {prepend} + + {children} + + {append} +
+ + {loading && ( + <> + {isLinkStyled(localVariant) ? ( + + ) : ( +
+ +
+ )} + + )} +
+ + ) - const CommonProps = { - disabled, - className: cn(variantClasses, sizeClasses, focusRing(), className), - "aria-busy": loading, - "aria-label": ariaLabel, - title, - ...restProps, - } + const CommonProps = { + disabled, + className: cn(variantClasses, sizeClasses, focusRing(), className), + "aria-busy": loading, + "aria-label": ariaLabel, + title, + ...restProps, + } - const mainElement = isLink(props) ? ( - } - href={href} - target={target} - rel={target === "_blank" ? "noopener noreferrer" : undefined} - aria-disabled={disabled} - > - {innerContent} - - ) : ( - + const mainElement = isLink(props) ? ( + } + href={href} + target={target} + rel={target === "_blank" ? "noopener noreferrer" : undefined} + aria-disabled={disabled} + > + {innerContent} + + ) : ( + + ) + + if (prependOutside || appendOutside) { + return ( +
+ {prependOutside} + {mainElement} + {appendOutside} +
) + } - if (prependOutside || appendOutside) { - return ( -
- {prependOutside} - {mainElement} - {appendOutside} -
- ) - } + return mainElement +}) - return mainElement - } -) +ActionImpl.displayName = "Action" + +// Overloaded Action component for better type inference +function ActionOverload( + props: ActionLinkProps & { ref?: React.Ref } +): React.ReactElement +function ActionOverload( + props: ActionButtonProps & { ref?: React.Ref } +): React.ReactElement +function ActionOverload( + props: ActionProps & { ref?: React.Ref } +): React.ReactElement { + return React.createElement(ActionImpl, props) +} + +export const Action = ActionOverload as { + ( + props: ActionLinkProps & { ref?: React.Ref } + ): React.ReactElement + ( + props: ActionButtonProps & { ref?: React.Ref } + ): React.ReactElement + displayName?: string +} Action.displayName = "Action" From f76d016e12d265544cf13af36544b87629301e10 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Wed, 1 Oct 2025 22:05:46 +0200 Subject: [PATCH 29/38] chore: fix dropdown button --- packages/react/src/components/F0Button/internal.tsx | 2 +- .../src/experimental/Banners/F0Callout/CalloutInternal.tsx | 6 +++--- .../react/src/experimental/Navigation/Dropdown/internal.tsx | 1 + packages/react/src/ui/Action/Action.tsx | 4 +++- packages/react/src/ui/ButtonCopy/ButtonCopy.tsx | 1 - 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/react/src/components/F0Button/internal.tsx b/packages/react/src/components/F0Button/internal.tsx index dedb281545..64260ce071 100644 --- a/packages/react/src/components/F0Button/internal.tsx +++ b/packages/react/src/components/F0Button/internal.tsx @@ -72,7 +72,7 @@ const ButtonInternal = forwardRef( const [loading, setLoading] = useState(false) const handleClick = async ( - event: React.MouseEvent + event: React.MouseEvent ) => { const result = onClick?.(event) diff --git a/packages/react/src/experimental/Banners/F0Callout/CalloutInternal.tsx b/packages/react/src/experimental/Banners/F0Callout/CalloutInternal.tsx index 33b8c2aa0d..51695e4dba 100644 --- a/packages/react/src/experimental/Banners/F0Callout/CalloutInternal.tsx +++ b/packages/react/src/experimental/Banners/F0Callout/CalloutInternal.tsx @@ -1,4 +1,4 @@ -import { Button } from "@/components/Actions/Button" +import { F0Button } from "@/components/F0Button" import { F0Icon, IconType } from "@/components/F0Icon" import { OneEllipsis } from "@/components/OneEllipsis" import { CheckDouble, Cross, InfoCircle, Warning } from "@/icons/app" @@ -72,7 +72,7 @@ export const CalloutInternal = forwardRef(
{onClose && ( -
{isCompactMode && (
- From 96e67fc956598fe5abe887dacf6c497b972c66fa Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Tue, 14 Oct 2025 22:21:34 +0200 Subject: [PATCH 35/38] chore: lint improvements --- packages/react/src/ui/Action/variants.ts | 1 + packages/react/src/ui/carousel.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/react/src/ui/Action/variants.ts b/packages/react/src/ui/Action/variants.ts index 3cbdac0ae4..6ecf59782e 100644 --- a/packages/react/src/ui/Action/variants.ts +++ b/packages/react/src/ui/Action/variants.ts @@ -250,6 +250,7 @@ export const loadingVariants = cva({ ghost: "border-f1-foreground border-t-transparent", promote: "border-f1-icon-promote border-t-transparent", outlinePromote: "border-f1-icon-promote border-t-transparent", + unstyled: "", }, }, }) diff --git a/packages/react/src/ui/carousel.tsx b/packages/react/src/ui/carousel.tsx index 4597865647..9e77e945ba 100644 --- a/packages/react/src/ui/carousel.tsx +++ b/packages/react/src/ui/carousel.tsx @@ -239,7 +239,7 @@ const CarouselPrevious = React.forwardRef< label="Previous" icon={ArrowLeft} hideLabel - > + />
) }) @@ -271,7 +271,7 @@ const CarouselNext = React.forwardRef( label="Next" icon={ArrowRight} hideLabel - > + />
) } From 25c83679fc54463caf34746fd8237e94650931be Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Tue, 14 Oct 2025 22:25:06 +0200 Subject: [PATCH 36/38] chore: merge main --- .../layouts/page/PageLayout/PageLayout.tsx | 118 ------------- .../__stories__/PageLayout.stories.tsx | 160 ------------------ .../PageLayout/components/PageLayoutBlock.tsx | 84 --------- .../layouts/page/PageLayout/index.ts | 3 - .../AiChat/components/SuggestionsList.tsx | 2 +- .../AiChat/components/WelcomeScreen.tsx | 2 +- 6 files changed, 2 insertions(+), 367 deletions(-) delete mode 100644 packages/react/src/components/layouts/page/PageLayout/PageLayout.tsx delete mode 100644 packages/react/src/components/layouts/page/PageLayout/__stories__/PageLayout.stories.tsx delete mode 100644 packages/react/src/components/layouts/page/PageLayout/components/PageLayoutBlock.tsx delete mode 100644 packages/react/src/components/layouts/page/PageLayout/index.ts diff --git a/packages/react/src/components/layouts/page/PageLayout/PageLayout.tsx b/packages/react/src/components/layouts/page/PageLayout/PageLayout.tsx deleted file mode 100644 index 9b1afdd676..0000000000 --- a/packages/react/src/components/layouts/page/PageLayout/PageLayout.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import { cn } from "@/lib/utils" -import { - Children, - ReactElement, - ReactNode, - forwardRef, - isValidElement, -} from "react" -import { - PageLayoutBlock, - PageLayoutBlockComponent, - PageLayoutBlockProps, -} from "./components/PageLayoutBlock" - -// Type for components that inherit from PageLayoutBlock -export type PageLayoutBlockElement = ReactElement - -export interface PageLayoutProps { - children: ReactNode - aside?: ReactNode - header?: ReactNode - variant?: "main-aside" | "aside-main" -} - -// Utility to check if a component is a valid PageLayoutBlock -const isPageLayoutBlockComponent = ( - child: ReactNode -): child is PageLayoutBlockElement => { - return ( - isValidElement(child) && - ((child.type as unknown as PageLayoutBlockComponent) - ?.__isPageLayoutBlock === true || - child.type === PageLayoutBlock || - (typeof child.type === "function" && - (child.type as { displayName?: string }).displayName === - "PageLayoutBlock")) - ) -} - -// Utility to validate all children are PageLayoutBlock components -const validatePageLayoutChildren = (children: ReactNode): void => { - const childArray = Children.toArray(children) - - for (const child of childArray) { - if (!isPageLayoutBlockComponent(child)) { - console.warn( - `PageLayout: Child component must inherit from PageLayoutBlock. Found:`, - child - ) - } - } -} - -const PageLayoutComponent = forwardRef( - function PageLayout( - { children: mainContent, aside, header, variant = "main-aside" }, - ref - ) { - const stickyHeader = true - const stickyAside = true - - // Validate that all children are PageLayoutBlock components in development - if (process.env.NODE_ENV === "development") { - validatePageLayoutChildren(mainContent) - } - - return ( -
-
-
- {header && ( -
- {header} -
- )} -
{mainContent}
-
- - {aside && ( - - )} -
-
- ) - } -) - -export const PageLayout = Object.assign(PageLayoutComponent, { - Block: PageLayoutBlock, - isBlockComponent: isPageLayoutBlockComponent, - validateChildren: validatePageLayoutChildren, -}) diff --git a/packages/react/src/components/layouts/page/PageLayout/__stories__/PageLayout.stories.tsx b/packages/react/src/components/layouts/page/PageLayout/__stories__/PageLayout.stories.tsx deleted file mode 100644 index e439eeaef0..0000000000 --- a/packages/react/src/components/layouts/page/PageLayout/__stories__/PageLayout.stories.tsx +++ /dev/null @@ -1,160 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react-vite" - -import { DetailsItemsList } from "@/experimental/Lists/DetailsItemsList" -import * as DetailsItemsListStories from "@/experimental/Lists/DetailsItemsList/index.stories" -import { Dashboard } from "@/experimental/Widgets/Layout/Dashboard" -import * as DashboardStories from "@/experimental/Widgets/Layout/Dashboard/index.stories" -import { PageDecorator } from "@/lib/storybook-utils/pageDecorator" -import { ComponentProps } from "react" -import { PageLayoutContentBlock } from "../components/PageLayoutContentBlock" -import { PageLayout } from "../index" - -const FocusableElement = () => { - return ( -
- -
- -
-
- ) -} -const meta = { - title: "Layout/Page/Page Layout", - component: PageLayout, - tags: ["autodocs"], - decorators: [PageDecorator], - args: { - children: ( -
- Main - -

- Should the the first focusable element even if main is on right side -

-
- ), - header: ( -
- Header - -
- ), - aside: ( -
- Aside - -
- ), - }, - parameters: { - a11y: { - config: { - rules: [{ id: "svg-img-alt", enabled: false }], - }, - }, - docs: { - description: { - component: [ - "A page layout component that is used to display a main content, header and an aside content. This component manages the responsiveness of the content.", - "This component doesnt provide any padding or margin for the content, only the content layout", - ] - .map((line) => `

${line}

`) - .join(""), - }, - story: { - height: "650px", - }, - }, - }, -} satisfies Meta - -export default meta -type Story = StoryObj - -export const Default: Story = {} - -export const ProfileExample: Story = { - args: { - variant: "main-aside", - children: ( - - - - ), - header: ( - -
- Header -
-
- ), - aside: ( - - )} - /> - - ), - }, -} - -export const AsideMainVariant: Story = { - args: { - ...Default.args, - variant: "aside-main", - }, -} - -export const WithContentBlocks: Story = { - args: { - ...Default.args, - children: ( - <> - - - - - -
- - -
-
- - -
- All systems operational ✅ -
-
- - ), - }, - parameters: { - docs: { - description: { - story: - "Example showing multiple PageLayoutContentBlock components with different configurations - titles, descriptions, and content types.", - }, - }, - }, -} diff --git a/packages/react/src/components/layouts/page/PageLayout/components/PageLayoutBlock.tsx b/packages/react/src/components/layouts/page/PageLayout/components/PageLayoutBlock.tsx deleted file mode 100644 index 4538ec4abe..0000000000 --- a/packages/react/src/components/layouts/page/PageLayout/components/PageLayoutBlock.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { cn } from "@/lib/utils" -import { cva } from "cva" -import { forwardRef } from "react" - -export interface PageLayoutBlockProps { - children: React.ReactNode - variant?: "default" | "full-width" | "full" - fullHeight?: boolean - className?: string - // Drag and drop props (for future implementation) - draggable?: boolean - onDragStart?: (e: React.DragEvent) => void - onDragEnd?: (e: React.DragEvent) => void - onDrop?: (e: React.DragEvent) => void - dragId?: string -} - -// Base marker interface for PageLayoutBlock components -export interface PageLayoutBlockComponent { - __isPageLayoutBlock: true - displayName?: string -} - -const variants = cva({ - base: "flex w-full flex-col p-4", - variants: { - variant: { - default: "", - "full-width": "px-0", - full: "p-0", - }, - }, -}) - -export const PageLayoutBlock = forwardRef( - ( - { - children, - variant = "default", - className, - draggable = false, - onDragStart, - onDragEnd, - onDrop, - dragId, - ...props - }, - ref - ) => { - return ( -
- {children} -
- ) - } -) - -PageLayoutBlock.displayName = "PageLayoutBlock" -// Mark as a valid PageLayoutBlock component -;(PageLayoutBlock as unknown as PageLayoutBlockComponent).__isPageLayoutBlock = - true - -// Helper function to create components that inherit from PageLayoutBlock -export const createPageLayoutBlock = >( - displayName: string, - Component: React.ComponentType -): React.ComponentType => { - const WrappedComponent = Component as React.ComponentType< - PageLayoutBlockProps & T - > & - PageLayoutBlockComponent - WrappedComponent.displayName = displayName - WrappedComponent.__isPageLayoutBlock = true - return WrappedComponent -} diff --git a/packages/react/src/components/layouts/page/PageLayout/index.ts b/packages/react/src/components/layouts/page/PageLayout/index.ts deleted file mode 100644 index 290d060d46..0000000000 --- a/packages/react/src/components/layouts/page/PageLayout/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./components/PageLayoutBlock" -export * from "./components/PageLayoutContentBlock" -export * from "./PageLayout" diff --git a/packages/react/src/experimental/AiChat/components/SuggestionsList.tsx b/packages/react/src/experimental/AiChat/components/SuggestionsList.tsx index 5e5be5b8e2..4d1caf4870 100644 --- a/packages/react/src/experimental/AiChat/components/SuggestionsList.tsx +++ b/packages/react/src/experimental/AiChat/components/SuggestionsList.tsx @@ -1,4 +1,4 @@ -import { ButtonInternal } from "@/components/Actions/Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { RenderSuggestionsListProps } from "@copilotkit/react-ui" export const SuggestionsList = ({ diff --git a/packages/react/src/experimental/AiChat/components/WelcomeScreen.tsx b/packages/react/src/experimental/AiChat/components/WelcomeScreen.tsx index c51aff7710..6778bc7d9d 100644 --- a/packages/react/src/experimental/AiChat/components/WelcomeScreen.tsx +++ b/packages/react/src/experimental/AiChat/components/WelcomeScreen.tsx @@ -1,6 +1,6 @@ import { AnimatePresence, motion } from "motion/react" -import { ButtonInternal } from "@/components/Actions/Button/internal" +import { ButtonInternal } from "@/components/F0Button/internal" import { IconType } from "@/components/F0Icon/F0Icon" import { useCopilotChatInternal } from "@copilotkit/react-core" import { Message, randomId } from "@copilotkit/shared" From af2f5486d9fda804f62f6d1f0fbb0dc115d2c178 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Wed, 15 Oct 2025 13:00:36 +0200 Subject: [PATCH 37/38] feat: tooltip in buttons and links --- .../src/components/F0Button/F0Button.tsx | 9 +- .../F0Button/__stories__/F0Button.mdx | 309 ------------------ .../F0Button/__stories__/F0Button.stories.tsx | 11 +- .../F0Button/__stories__/controls.mdx | 7 + .../src/components/F0Button/internal-types.ts | 20 +- .../src/components/F0Button/internal.tsx | 8 +- .../F0ButtonDropdown/F0ButtonDropdown.tsx | 1 + .../__stories__/F0ButtonDropdown.mdx | 95 ------ .../__stories__/F0ButtonDropdown.stories.tsx | 64 ++++ .../src/components/F0ButtonDropdown/types.ts | 5 + .../F0Link/__stories__/F0Link.stories.tsx | 6 + .../Information/Headers/BaseHeader/index.tsx | 65 +--- .../Headers/ResourceHeader/index.stories.tsx | 6 + .../Navigation/Dropdown/index.tsx | 1 + .../Navigation/Dropdown/internal.tsx | 6 +- .../Header/Breadcrumbs/index.test.tsx | 4 +- .../__tests__/ItemActionsDropdown.test.tsx | 3 +- .../providers/i18n/i18n-provider-defaults.ts | 1 + .../lib/providers/i18n/i18n-provider.spec.tsx | 1 + packages/react/src/ui/Action/Action.tsx | 13 +- packages/react/src/ui/Action/types.ts | 4 + 21 files changed, 174 insertions(+), 465 deletions(-) delete mode 100644 packages/react/src/components/F0Button/__stories__/F0Button.mdx create mode 100644 packages/react/src/components/F0Button/__stories__/controls.mdx delete mode 100644 packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.mdx diff --git a/packages/react/src/components/F0Button/F0Button.tsx b/packages/react/src/components/F0Button/F0Button.tsx index c6b03d7541..c965c8e1f0 100644 --- a/packages/react/src/components/F0Button/F0Button.tsx +++ b/packages/react/src/components/F0Button/F0Button.tsx @@ -6,7 +6,14 @@ import { forwardRef } from "react" import { ButtonInternal } from "./internal" import { ButtonInternalProps } from "./internal-types" -const privateProps = ["append", "className", "pressed", "compact"] as const +const privateProps = [ + "append", + "className", + "pressed", + "compact", + "noTitle", + "noAutoTooltip", +] as const export type F0ButtonProps = Omit< ButtonInternalProps, diff --git a/packages/react/src/components/F0Button/__stories__/F0Button.mdx b/packages/react/src/components/F0Button/__stories__/F0Button.mdx deleted file mode 100644 index 90605a83d8..0000000000 --- a/packages/react/src/components/F0Button/__stories__/F0Button.mdx +++ /dev/null @@ -1,309 +0,0 @@ -import { Canvas, Meta, Controls } from "@storybook/addon-docs/blocks" -import * as ButtonStories from "./F0Button.stories" -import { DoDonts } from "@/lib/storybook-utils/do-donts" - - - -# Button - -## Introduction - -### Definition - -The Button is a core UI component that allows users to trigger actions and -navigate to different parts of the application. It establishes visual hierarchy -to highlight the most important actions in each workflow while ensuring -consistency and accessibility. - -### Purpose - -- **Visual hierarchy**: Highlight the most important actions in each workflow -- **Consistent interaction**: Ensure consistent behavior and appearance across - all areas -- **Accessibility**: Provide inclusive sizes, contrasts, and states for all - users -- **Flexibility**: Adapt to multiple use cases from primary flows to contextual - actions - -## Anatomy - - - - -- **Label**: The main text describing the action -- **Icon**: (Optional) Visual symbol to reinforce the action -- **States**: Default, Hover, Pressed, Disabled, Loading -- **Variants**: Visual styles for different contexts (primary, secondary, ghost, - etc.) -- **Sizes**: Small, Medium, Large - -## Variants - -### Type - -Buttons adapt to different use cases and visual hierarchies: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VariantDescriptionProperties
Default - Is the main, highlighted action used for the most important user tasks. - Should only appear once per screen. - - variant="default" -
OutlineHas a subtle, minimal style and is used for secondary actions. - variant="outline" -
Neutral - Represents tertiary or less important options within the interface but - offers an extra level of hierarchy. - - variant="neutral" -
Ghost - Is for secondary actions, blending subtly with content and standing out - only on hover or focus. - - variant="ghost" -
Critical - Has a warning color scheme and is used for destructive actions that - require user confirmation (e.g., delete or remove). - - variant="critical" -
Promote - Indicates actions related to upselling, such as offering higher-value - products or upgrades to existing customers. - - variant="promote" -
- -### Icon - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeDescriptionProperties
With icon - Combines an icon with descriptive text for better clarity and - recognition. - icon, label
Only icon - Buttons that contain only an icon without visible text. Useful for - toolbars or compact actions. - icon, hideLabel, round
Only emoji - A special case of icon-only button, using an emoji as the icon. Useful - for playful or expressive actions. - emoji, hideLabel, round
- -### Sizes - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SizeDescriptionProperties
lg (40)Designed for mobile devices as they require a larger touch area.variant="lg"
md (32)Standard size for desktop, used in most cases.variant="md"
sm (24) - Perfect for secondary actions on desktop, such as buttons in tables, - selectors, etc., where space is more limited. - variant="sm"
- -### States - -Buttons can appear in different visual and functional states, each communicating -an intention or restriction to the user. - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
StateDescriptionProperties
PressedRepresents the active or selected state of the button.pressed
DisabledThe button is inactive and does not respond to user interaction.disabled
LoadingIndicates that an action is in progress.loading
- -###### Async Loading - -Demonstrates a real asynchronous action: the button enters a loading state after -being clicked and provides feedback to the user. - - - -##### Best practices: - -- Use the disabled state to prevent invalid actions, not just for visual - deactivation. -- The loading state blocks interaction until the action is complete. -- Provide clear feedback after asynchronous actions (e.g., show a success or - error message). - -## Guidelines - -### Content best practices - -- Use clear, concise, and actionable language for button labels. -- Ensure button labels are consistent with the associated action or - functionality. -- Be specific and actionable - - ✅ **Correct:** "Create employee", "Submit request", "Download report" - - ❌ **Incorrect:** "OK", "Send", "Do" -- Use imperative verbs - - ✅ **Correct:** "Save changes", "Delete account", "Export data" - - ❌ **Incorrect:** "Saved", "Deletion", "Exportation" - -### Design best practices - -#### When to use - -- Use buttons whenever you need the user to trigger an action or navigate to a - different part of the application. -- Choose the appropriate button type based on the importance and context of the - action. -- Utilize the different button variants to create a clear visual hierarchy and - guide the user's attention. -- Only one primary button per section or screen on the right. - -#### How to use - -- Position the most important actions as **Primary** buttons, with less crucial - actions as **Outline** or **Neutral** buttons. -- Use the **Ghost** button type sparingly, as it can be less visually prominent. -- Avoid using the **Critical** button type for anything other than truly - destructive actions that require user confirmation. -- Consider adding icons to buttons when they can enhance recognition and - usability, but don't overuse icons. -- Ensure that button sizes are consistent within the same context, following the - recommended size guidelines. -- Always provide a **disabled** state for buttons that may become unavailable - based on user actions or application state. - - - ), - }} - dont={{ - guidelines: [ - "Don't mix too many button styles in a single group.", - "Avoid breaking the visual flow of action groups.", - "Don't group unrelated actions together.", - ], - children: ( - Incorrect button group usage - ), - }} -/> diff --git a/packages/react/src/components/F0Button/__stories__/F0Button.stories.tsx b/packages/react/src/components/F0Button/__stories__/F0Button.stories.tsx index eec617fdf2..4742cb31d1 100644 --- a/packages/react/src/components/F0Button/__stories__/F0Button.stories.tsx +++ b/packages/react/src/components/F0Button/__stories__/F0Button.stories.tsx @@ -91,6 +91,11 @@ const meta = { description: "Callback fired when the button is clicked. Supports async functions for loading state.", }, + tooltip: { + control: "text", + description: + "The tooltip to show when the button is hovered. If not provided, when the hideLabel is true, the tooltip will be generated based on the label property.", + }, href: { control: "text", description: @@ -248,9 +253,9 @@ export const Sizes: Story = { parameters: withSnapshot({}), render: (args) => (
- - - + + +
), } diff --git a/packages/react/src/components/F0Button/__stories__/controls.mdx b/packages/react/src/components/F0Button/__stories__/controls.mdx new file mode 100644 index 0000000000..55b30fefe5 --- /dev/null +++ b/packages/react/src/components/F0Button/__stories__/controls.mdx @@ -0,0 +1,7 @@ +import { Meta, Controls } from "@storybook/addon-docs/blocks" + +import * as Stories from "./F0Button.stories" + + + + diff --git a/packages/react/src/components/F0Button/internal-types.ts b/packages/react/src/components/F0Button/internal-types.ts index 1db8694131..156996469a 100644 --- a/packages/react/src/components/F0Button/internal-types.ts +++ b/packages/react/src/components/F0Button/internal-types.ts @@ -6,7 +6,13 @@ export type { ButtonType } export type ButtonInternalProps = Pick< ActionProps, - "size" | "disabled" | "className" | "pressed" | "compact" | "variant" + | "size" + | "disabled" + | "className" + | "pressed" + | "compact" + | "variant" + | "tooltip" > & DataAttributes & { /** @@ -52,6 +58,7 @@ export type ButtonInternalProps = Pick< */ size?: ButtonSize /** + * @private * Appends a React node after the button content (for custom UI extensions). */ append?: React.ReactNode @@ -60,9 +67,20 @@ export type ButtonInternalProps = Pick< */ disabled?: boolean /** + * @private * If true, the button is visually active or selected (pressed state). */ pressed?: boolean + /** + * @private + * If true, the button will not automatically add a tooltip based on the hideLabel and label properties. + */ + noAutoTooltip?: boolean + /** + * @private + * If true, the button will not automatically add a title based label + */ + noTitle?: boolean } & ( // Target can only be used if href is provided | { /** diff --git a/packages/react/src/components/F0Button/internal.tsx b/packages/react/src/components/F0Button/internal.tsx index f1136af177..2cf6622664 100644 --- a/packages/react/src/components/F0Button/internal.tsx +++ b/packages/react/src/components/F0Button/internal.tsx @@ -65,6 +65,9 @@ const ButtonInternal = forwardRef< append, className, "aria-label": ariaLabel, + tooltip, + noAutoTooltip, + noTitle, ...props }, ref @@ -99,12 +102,15 @@ const ButtonInternal = forwardRef< disabled={disabled || isLoading} ref={ref} {...props} + tooltip={tooltip ?? (!noAutoTooltip && hideLabel && label)} onClick={handleClick} loading={isLoading} className={className} mode={hideLabel ? "only" : "default"} aria-label={ariaLabel || props.title || label} - title={props.title || (hideLabel ? label : undefined)} + title={ + noTitle ? undefined : props.title || (hideLabel ? label : undefined) + } compact={!!shouldHideLabel} >
diff --git a/packages/react/src/components/F0ButtonDropdown/F0ButtonDropdown.tsx b/packages/react/src/components/F0ButtonDropdown/F0ButtonDropdown.tsx index 321d65d947..e53f478ffa 100644 --- a/packages/react/src/components/F0ButtonDropdown/F0ButtonDropdown.tsx +++ b/packages/react/src/components/F0ButtonDropdown/F0ButtonDropdown.tsx @@ -61,6 +61,7 @@ const F0ButtonDropdown = ({ aria-label={selectedItem.label} prepend={selectedItem.icon && } className="rounded-r-none after:rounded-r-none" + tooltip={props.tooltip} appendOutside={ - -# F0ButtonDropdown - -## Introduction - -### Definition - -The F0ButtonDropdown is an action button component that combines a primary -action with a dropdown menu for additional related actions. It allows users to -execute the most common action directly while providing access to alternative -actions through a dropdown interface. - -### Purpose - -- Provide quick access to the most common action while offering related - alternatives -- Reduce visual clutter by consolidating multiple related actions into a single - component -- Maintain clear visual hierarchy with a prominent primary action -- Support efficient workflows where users frequently switch between related - actions - -## Anatomy - - - - -The component consists of two main parts: - -### Primary action button - -- Displays the currently selected action with its label and optional icon -- Executes the action when clicked -- Takes visual prominence as the main interactive element - -### Dropdown trigger - -- Located immediately to the right of the primary button -- Shows a chevron down icon to indicate expandable content -- Opens a dropdown menu with alternative actions when clicked - -## Guidelines - -### Content best practices - -- Action labels should be concise and action-oriented (2-4 words) -- Use consistent verb + noun format (e.g., "Add item", "Replace content") -- Group related actions that users would logically switch between -- Place the most common or important action first in the items array - -### Design best practices - - - -### Behavior - -- The first item in the items array becomes the default primary action -- Clicking the primary button executes the currently selected action -- Clicking the dropdown arrow reveals alternative actions -- Selecting an alternative action makes it the new primary action -- The component maintains the selected action state internally -- Supports keyboard navigation and screen reader accessibility - -### Layout - -- The dropdown arrow is visually connected to the primary button -- Alternative actions appear in a dropdown menu aligned to the button -- Icons are optional but should be consistent across all items when used -- The component adapts to different sizes while maintaining proportions diff --git a/packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx b/packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx index 4799d5e43f..2f2807f0f4 100644 --- a/packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx +++ b/packages/react/src/components/F0ButtonDropdown/__stories__/F0ButtonDropdown.stories.tsx @@ -1,6 +1,7 @@ import type { Meta, StoryObj } from "@storybook/react-vite" import { Add, Replace } from "@/icons/app/index.ts" +import { withSnapshot } from "@/lib/storybook-utils/parameters.ts" import { F0ButtonDropdown } from "../index" import { buttonDropdownSizes, buttonDropdownVariants } from "../types.ts" @@ -33,6 +34,11 @@ const meta = { control: "select", options: buttonDropdownVariants, description: "Visual style variant of the button", + table: { + type: { + summary: buttonDropdownVariants.join(" | "), + }, + }, }, size: { control: "select", @@ -54,9 +60,19 @@ const meta = { table: { type: { summary: "ButtonDropdownItem[]", + detail: `type ButtonDropdownItem = { + value: string; + label: string; + icon?: IconType; + critical?: boolean +}`, }, }, }, + tooltip: { + control: "text", + description: "Tooltip to explain the button", + }, }, } satisfies Meta @@ -85,3 +101,51 @@ export const Default: Story = { ], }, } + +// Basic Variants +export const WithTooltip: Story = { + args: { + variant: "default", + tooltip: "Tooltip to explain the button", + items: [ + { + value: "1", + label: "Item 1", + icon: Add, + }, + { + value: "2", + label: "Item 2", + icon: Replace, + }, + { + value: "3", + label: "Item 3", + }, + ], + }, +} + +export const Snapshot: Story = { + parameters: withSnapshot({}), + args: { + items: [ + { + value: "1", + label: "Item 1", + icon: Add, + }, + { + value: "2", + label: "Item 2", + icon: Replace, + }, + { + value: "3", + label: "Item 3", + critical: true, + }, + ], + }, + render: (args) => , +} diff --git a/packages/react/src/components/F0ButtonDropdown/types.ts b/packages/react/src/components/F0ButtonDropdown/types.ts index dab1644f69..b1f36a48b3 100644 --- a/packages/react/src/components/F0ButtonDropdown/types.ts +++ b/packages/react/src/components/F0ButtonDropdown/types.ts @@ -55,6 +55,11 @@ export type F0ButtonDropdownProps = { * @default false */ loading?: boolean + /** + * The tooltip of the button. + * @default undefined + */ + tooltip?: string /** * The callback function to be called when the button is clicked. * @param value The value of the item that was clicked. diff --git a/packages/react/src/components/F0Link/__stories__/F0Link.stories.tsx b/packages/react/src/components/F0Link/__stories__/F0Link.stories.tsx index 84ea343b3a..16528f7859 100644 --- a/packages/react/src/components/F0Link/__stories__/F0Link.stories.tsx +++ b/packages/react/src/components/F0Link/__stories__/F0Link.stories.tsx @@ -22,6 +22,10 @@ const meta = { control: "select", options: linkVariants, }, + tooltip: { + control: "text", + description: "The tooltip to show when the link is hovered.", + }, }, args: { children: "Link", @@ -91,6 +95,8 @@ export const Snapshot: Story = {

Disabled

+

Tooltip

+
), } diff --git a/packages/react/src/experimental/Information/Headers/BaseHeader/index.tsx b/packages/react/src/experimental/Information/Headers/BaseHeader/index.tsx index f7885bb2ca..8e6a90a42e 100644 --- a/packages/react/src/experimental/Information/Headers/BaseHeader/index.tsx +++ b/packages/react/src/experimental/Information/Headers/BaseHeader/index.tsx @@ -1,8 +1,5 @@ -import { F0Button, F0ButtonProps } from "@/components/F0Button" -import { - F0ButtonDropdown, - F0ButtonDropdownProps, -} from "@/components/F0ButtonDropdown" +import { F0Button } from "@/components/F0Button" +import { F0ButtonDropdown } from "@/components/F0ButtonDropdown" import { AvatarVariant, F0Avatar } from "@/components/avatars/F0Avatar" import { StatusVariant } from "@/components/tags/F0TagStatus" import { Description } from "@/experimental/Information/Headers/BaseHeader/Description" @@ -22,10 +19,12 @@ import { DropdownItem, MobileDropdown, } from "@/experimental/Navigation/Dropdown" -import { Tooltip } from "@/experimental/Overlays/Tooltip" import { cn } from "@/lib/utils" -import { Fragment, memo } from "react" +import { Fragment } from "react" +export type HeaderSecondaryAction = SecondaryAction & { + hideLabel?: boolean +} interface BaseHeaderProps { title: string avatar?: @@ -38,7 +37,7 @@ interface BaseHeaderProps { description?: string primaryAction?: PrimaryActionButton | PrimaryDropdownAction - secondaryActions?: SecondaryAction[] + secondaryActions?: HeaderSecondaryAction[] otherActions?: (DropdownItem & { isVisible?: boolean })[] status?: { label: string @@ -52,42 +51,6 @@ interface BaseHeaderProps { const isVisible = (action: { isVisible?: boolean }) => action.isVisible !== false -const ButtonWithTooltip = memo(function ButtonWithTooltip({ - tooltip, - ...buttonProps -}: F0ButtonProps & { tooltip?: string }) { - if (tooltip) { - const Wrapper = buttonProps.disabled ? "span" : Fragment - return ( - - - - - - ) - } - return -}) - -const DropdownButtonWithTooltip = memo(function DropdownButtonWithTooltip({ - tooltip, - ...dropdownProps -}: F0ButtonDropdownProps & { - tooltip?: string -}) { - if (tooltip) { - const Wrapper = dropdownProps.disabled ? "span" : Fragment - return ( - - - - - - ) - } - return -}) - export function BaseHeader({ title, avatar, @@ -173,7 +136,7 @@ export function BaseHeader({
{isPrimaryActionVisible && isPrimaryActionButton(primaryAction) && (
- - (
- @@ -230,11 +194,12 @@ export function BaseHeader({ {visibleSecondaryActions.map((action) => (
- @@ -247,7 +212,7 @@ export function BaseHeader({ )} {isPrimaryActionVisible && isPrimaryActionButton(primaryAction) && (
- - { variant="outline" size="lg" pressed={open} + noTitle /> )} diff --git a/packages/react/src/experimental/Navigation/Dropdown/internal.tsx b/packages/react/src/experimental/Navigation/Dropdown/internal.tsx index e3f3bda913..5385d9fa25 100644 --- a/packages/react/src/experimental/Navigation/Dropdown/internal.tsx +++ b/packages/react/src/experimental/Navigation/Dropdown/internal.tsx @@ -4,6 +4,7 @@ import { ButtonInternal } from "@/components/F0Button/internal" import { IconType } from "@/components/F0Icon" import { EllipsisHorizontal } from "@/icons/app" import { Link } from "@/lib/linkHandler" +import { useI18n } from "@/lib/providers/i18n" import { cn } from "@/lib/utils" import { DropdownMenu, @@ -86,6 +87,7 @@ export function DropdownInternal({ onOpenChange: controlledOnOpenChange, ...rest }: DropdownInternalProps) { + const i18n = useI18n() const [internalOpen, setInternalOpen] = useState(false) const isControlled = @@ -102,10 +104,12 @@ export function DropdownInternal({ hideLabel icon={icon} size={size} - label="..." + label={i18n.actions.toggle_dropdown_menu} variant="outline" pressed={open} compact + noAutoTooltip + noTitle /> )} diff --git a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.test.tsx b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.test.tsx index 3c4dc462a1..97c185c599 100644 --- a/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.test.tsx +++ b/packages/react/src/experimental/Navigation/Header/Breadcrumbs/index.test.tsx @@ -1,5 +1,7 @@ import { Home, Settings } from "@/icons/app" -import { render, within } from "@testing-library/react" +import { zeroRender as render } from "@/testing/test-utils" +import { within } from "@testing-library/react" + import { beforeEach, describe, expect, it, vi } from "vitest" import { Breadcrumbs } from "./index" diff --git a/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsDropdown/__tests__/ItemActionsDropdown.test.tsx b/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsDropdown/__tests__/ItemActionsDropdown.test.tsx index 6f8973fc6a..18fdbe8383 100644 --- a/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsDropdown/__tests__/ItemActionsDropdown.test.tsx +++ b/packages/react/src/experimental/OneDataCollection/components/itemActions/ItemActionsDropdown/__tests__/ItemActionsDropdown.test.tsx @@ -1,5 +1,5 @@ import { DropdownItem } from "@/experimental/Navigation/Dropdown/internal" -import { render, screen } from "@testing-library/react" +import { zeroRender as render, screen } from "@/testing/test-utils" import { describe, expect, it, vi } from "vitest" import { ItemActionsDropdown } from "../ItemActionsDropdown" @@ -15,6 +15,7 @@ vi.mock("@/lib/utils", () => ({ vi.mock("@/icons/app", () => ({ Ellipsis: () =>
...
, + Windows: () =>
Windows
, })) vi.mock("@/experimental/Navigation/Dropdown", () => ({ diff --git a/packages/react/src/lib/providers/i18n/i18n-provider-defaults.ts b/packages/react/src/lib/providers/i18n/i18n-provider-defaults.ts index b93235b356..1125cf286c 100644 --- a/packages/react/src/lib/providers/i18n/i18n-provider-defaults.ts +++ b/packages/react/src/lib/providers/i18n/i18n-provider-defaults.ts @@ -38,6 +38,7 @@ export const defaultTranslations = { thumbsDown: "Dislike", other: "Other actions", toggle: "Toggle", + toggle_dropdown_menu: "Toggle dropdown menu", }, status: { selected: { diff --git a/packages/react/src/lib/providers/i18n/i18n-provider.spec.tsx b/packages/react/src/lib/providers/i18n/i18n-provider.spec.tsx index 0734b30543..5b013703bd 100644 --- a/packages/react/src/lib/providers/i18n/i18n-provider.spec.tsx +++ b/packages/react/src/lib/providers/i18n/i18n-provider.spec.tsx @@ -14,6 +14,7 @@ describe("I18nProvider", () => { const customTranslations: TranslationsType = { ...defaultTranslations, actions: { + ...defaultTranslations.actions, add: "Add", edit: "Edit", save: "Desar", diff --git a/packages/react/src/ui/Action/Action.tsx b/packages/react/src/ui/Action/Action.tsx index 4f256a14f7..95dab3b07f 100644 --- a/packages/react/src/ui/Action/Action.tsx +++ b/packages/react/src/ui/Action/Action.tsx @@ -1,3 +1,4 @@ +import { Tooltip } from "@/experimental/Overlays/Tooltip" import { Link } from "@/lib/linkHandler" import { cn, focusRing } from "@/lib/utils" import { Skeleton } from "@/ui/skeleton" @@ -40,6 +41,7 @@ export const Action = React.forwardRef< title, compact = false, "aria-label": ariaLabel, + tooltip, ...restProps } = props @@ -152,17 +154,24 @@ export const Action = React.forwardRef< ) + const element = + !disabled && tooltip ? ( + {mainElement} + ) : ( + mainElement + ) + if (prependOutside || appendOutside) { return (
{prependOutside} - {mainElement} + {element} {appendOutside}
) } - return mainElement + return element }) Action.displayName = "Action" diff --git a/packages/react/src/ui/Action/types.ts b/packages/react/src/ui/Action/types.ts index 12f2313f64..bfa9ce8549 100644 --- a/packages/react/src/ui/Action/types.ts +++ b/packages/react/src/ui/Action/types.ts @@ -24,6 +24,10 @@ export const actionSizes = ["sm", "md", "lg"] as const export type ActionSize = (typeof actionSizes)[number] export interface ActionCommonProps { + /** + * Tooltip + */ + tooltip?: string | false /** * The variant of the action. */ From 22e08e6105a4b938f5bb23d5a5b171a887035539 Mon Sep 17 00:00:00 2001 From: Segio Carracedo Date: Wed, 15 Oct 2025 14:59:59 +0200 Subject: [PATCH 38/38] chore: tooltip internal delay prop --- .../F0ButtonDropdown/__stories__/controls.mdx | 7 ++++ .../avatars/F0AvatarFile/F0AvatarFile.tsx | 2 +- .../avatars/F0AvatarList/F0AvatarList.tsx | 2 +- .../Navigation/Header/PageHeader/index.tsx | 2 +- .../experimental/OneTable/TableHead/index.tsx | 2 +- .../Overlays/Tooltip/index.stories.tsx | 8 ++--- .../experimental/Overlays/Tooltip/index.tsx | 32 ++++++++++++++++--- .../src/experimental/Overlays/exports.tsx | 1 + .../Widgets/Content/TwoColumnsList/index.tsx | 6 ++-- packages/react/src/experimental/exports.ts | 1 - packages/react/src/ui/Action/Action.tsx | 15 +++++---- packages/react/src/ui/Card/Card.tsx | 6 ++-- 12 files changed, 57 insertions(+), 27 deletions(-) create mode 100644 packages/react/src/components/F0ButtonDropdown/__stories__/controls.mdx diff --git a/packages/react/src/components/F0ButtonDropdown/__stories__/controls.mdx b/packages/react/src/components/F0ButtonDropdown/__stories__/controls.mdx new file mode 100644 index 0000000000..d28d1c4678 --- /dev/null +++ b/packages/react/src/components/F0ButtonDropdown/__stories__/controls.mdx @@ -0,0 +1,7 @@ +import { Meta, Controls } from "@storybook/addon-docs/blocks" + +import * as Stories from "./F0ButtonDropdown.stories" + + + + diff --git a/packages/react/src/components/avatars/F0AvatarFile/F0AvatarFile.tsx b/packages/react/src/components/avatars/F0AvatarFile/F0AvatarFile.tsx index 9f19fd07ed..dc1ea3ebcc 100644 --- a/packages/react/src/components/avatars/F0AvatarFile/F0AvatarFile.tsx +++ b/packages/react/src/components/avatars/F0AvatarFile/F0AvatarFile.tsx @@ -1,5 +1,4 @@ import { Badge } from "@/experimental/Information/Badge" -import { Tooltip } from "@/experimental/Overlays/Tooltip" import { cn } from "@/lib/utils" import { Avatar, AvatarFallback, InternalAvatarProps } from "@/ui/Avatar" import { ElementRef, forwardRef, useMemo } from "react" @@ -7,6 +6,7 @@ import { BaseAvatarProps, sizesMapping } from "../internal/BaseAvatar" import { AvatarFileSize, FileDef } from "./types" import { getAvatarSize, getBadgeSize, getFileTypeInfo } from "./utils" +import { Tooltip } from "@/experimental/Overlays/Tooltip" import { AvatarBadge } from "../F0Avatar/types" import { F0AvatarModule } from "../F0AvatarModule" diff --git a/packages/react/src/components/avatars/F0AvatarList/F0AvatarList.tsx b/packages/react/src/components/avatars/F0AvatarList/F0AvatarList.tsx index d54a4a7aa5..0583401061 100644 --- a/packages/react/src/components/avatars/F0AvatarList/F0AvatarList.tsx +++ b/packages/react/src/components/avatars/F0AvatarList/F0AvatarList.tsx @@ -1,8 +1,8 @@ -import { Tooltip } from "@/experimental/Overlays/Tooltip" import { OverflowList } from "@/ui/OverflowList" import { AvatarVariant, F0Avatar } from "../F0Avatar" import { MaxCounter } from "./components/MaxCounter" +import { Tooltip } from "@/experimental/Overlays/Tooltip" import { useMemo } from "react" import { AvatarListSize, avatarListSizes, F0AvatarListProps } from "./types" import { getAvatarDisplayName } from "./utils" diff --git a/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx b/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx index 077b385b6f..b89bb7cdde 100644 --- a/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx +++ b/packages/react/src/experimental/Navigation/Header/PageHeader/index.tsx @@ -5,7 +5,6 @@ import type { StatusVariant } from "@/components/tags/F0TagStatus" import { F0TagStatus } from "@/components/tags/F0TagStatus" import { useSidebar } from "@/experimental/Navigation/ApplicationFrame/FrameProvider" import { Dropdown } from "@/experimental/Navigation/Dropdown" -import { Tooltip } from "@/experimental/Overlays/Tooltip" import { ChevronDown, ChevronLeft, ChevronUp, Menu } from "@/icons/app" import { Link } from "@/lib/linkHandler" import { cn } from "@/lib/utils" @@ -15,6 +14,7 @@ import { ReactElement, useRef, useState } from "react" import { ButtonInternal } from "@/components/F0Button/internal" import { OneSwitch } from "@/experimental/AiChat/OneSwitch" +import { Tooltip } from "@/experimental/Overlays/Tooltip" import { Breadcrumbs, BreadcrumbsProps } from "../Breadcrumbs" import { FavoriteButton } from "../Favorites" import { ProductUpdates, ProductUpdatesProp } from "../ProductUpdates" diff --git a/packages/react/src/experimental/OneTable/TableHead/index.tsx b/packages/react/src/experimental/OneTable/TableHead/index.tsx index 604b7cd07d..2efc686008 100644 --- a/packages/react/src/experimental/OneTable/TableHead/index.tsx +++ b/packages/react/src/experimental/OneTable/TableHead/index.tsx @@ -1,9 +1,9 @@ +import { Tooltip } from "@/experimental/Overlays/Tooltip" import { TableHead as TableHeadRoot } from "@/ui/table" import { AnimatePresence, motion } from "motion/react" import { F0Icon, IconType } from "../../../components/F0Icon" import { ArrowDown, InfoCircleLine } from "../../../icons/app" import { cn, focusRing } from "../../../lib/utils" -import { Tooltip } from "../../Overlays/Tooltip" import { useTable } from "../utils/TableContext" import { getColWidth } from "../utils/colWidth" import { ColumnWidth } from "../utils/sizes" diff --git a/packages/react/src/experimental/Overlays/Tooltip/index.stories.tsx b/packages/react/src/experimental/Overlays/Tooltip/index.stories.tsx index 2761a6570a..2c790d7e50 100644 --- a/packages/react/src/experimental/Overlays/Tooltip/index.stories.tsx +++ b/packages/react/src/experimental/Overlays/Tooltip/index.stories.tsx @@ -1,10 +1,10 @@ import { F0Button } from "@/components/F0Button" import type { Meta, StoryObj } from "@storybook/react-vite" -import { Tooltip } from "./index" +import { TooltipInternal } from "./index" -const meta: Meta = { +const meta: Meta = { title: "Tooltip", - component: Tooltip, + component: TooltipInternal, tags: ["autodocs", "experimental"], decorators: [ (Story) => ( @@ -15,7 +15,7 @@ const meta: Meta = { export default meta -type Story = StoryObj +type Story = StoryObj export const Basic: Story = { args: { diff --git a/packages/react/src/experimental/Overlays/Tooltip/index.tsx b/packages/react/src/experimental/Overlays/Tooltip/index.tsx index 5c3066e0a2..b9503a0f4f 100644 --- a/packages/react/src/experimental/Overlays/Tooltip/index.tsx +++ b/packages/react/src/experimental/Overlays/Tooltip/index.tsx @@ -8,9 +8,10 @@ import React, { ComponentProps } from "react" import { cn } from "../../../lib/utils" import { Shortcut } from "../../Information/Shortcut" -type TooltipProps = { +type TooltipInternalProps = { children: React.ReactNode shortcut?: ComponentProps["keys"] + delay?: number } & ( | { label: string @@ -22,15 +23,16 @@ type TooltipProps = { } ) -export function Tooltip({ +export function TooltipInternal({ label, description, children, shortcut, -}: TooltipProps) { + delay = 700, +}: TooltipInternalProps) { return ( <> - + {children} @@ -41,7 +43,9 @@ export function Tooltip({ {label &&

{label}

} {shortcut && }
- {description &&

{description}

} + {description && ( +

{description.toString()}

+ )}
@@ -49,3 +53,21 @@ export function Tooltip({ ) } + +const privateProps = ["delay"] as const + +export type TooltipProps = Omit< + TooltipInternalProps, + (typeof privateProps)[number] +> + +const Tooltip = (props: TooltipProps) => { + const publicProps = privateProps.reduce((acc, key) => { + const { [key]: _, ...rest } = acc + return rest + }, props as TooltipInternalProps) + + return +} + +export { Tooltip } diff --git a/packages/react/src/experimental/Overlays/exports.tsx b/packages/react/src/experimental/Overlays/exports.tsx index aa8f527c7b..b06322348d 100644 --- a/packages/react/src/experimental/Overlays/exports.tsx +++ b/packages/react/src/experimental/Overlays/exports.tsx @@ -1,5 +1,6 @@ import { Component } from "../../lib/component/component" import { Dialog as DialogComponent } from "./Dialog" +export { Tooltip, type TooltipProps } from "./Tooltip" export const Dialog = Component( { diff --git a/packages/react/src/experimental/Widgets/Content/TwoColumnsList/index.tsx b/packages/react/src/experimental/Widgets/Content/TwoColumnsList/index.tsx index 2dfdcb6d80..57a2424cf6 100644 --- a/packages/react/src/experimental/Widgets/Content/TwoColumnsList/index.tsx +++ b/packages/react/src/experimental/Widgets/Content/TwoColumnsList/index.tsx @@ -1,7 +1,7 @@ +import { F0Icon } from "@/components/F0Icon" +import { Tooltip } from "@/experimental/Overlays/Tooltip" +import { InfoCircleLine } from "@/icons/app" import { forwardRef, ReactNode } from "react" -import { F0Icon } from "../../../../components/F0Icon" -import { InfoCircleLine } from "../../../../icons/app" -import { Tooltip } from "../../../Overlays/Tooltip" interface TwoColumnsItemType { title: string diff --git a/packages/react/src/experimental/exports.ts b/packages/react/src/experimental/exports.ts index 61f6e94113..1a63f29cc5 100644 --- a/packages/react/src/experimental/exports.ts +++ b/packages/react/src/experimental/exports.ts @@ -19,7 +19,6 @@ export * from "./OneDateNavigator" export * from "./OneEmptyState" export * from "./OnePagination" export * from "./Overlays/exports" -export * from "./Overlays/Tooltip" export * from "./RichText/exports" export * from "./Utilities/exports" export * from "./Widgets/exports" diff --git a/packages/react/src/ui/Action/Action.tsx b/packages/react/src/ui/Action/Action.tsx index 95dab3b07f..6486d41558 100644 --- a/packages/react/src/ui/Action/Action.tsx +++ b/packages/react/src/ui/Action/Action.tsx @@ -1,4 +1,4 @@ -import { Tooltip } from "@/experimental/Overlays/Tooltip" +import { TooltipInternal } from "@/experimental/Overlays/Tooltip" import { Link } from "@/lib/linkHandler" import { cn, focusRing } from "@/lib/utils" import { Skeleton } from "@/ui/skeleton" @@ -154,12 +154,13 @@ export const Action = React.forwardRef< ) - const element = - !disabled && tooltip ? ( - {mainElement} - ) : ( - mainElement - ) + const element = tooltip ? ( + + {mainElement} + + ) : ( + mainElement + ) if (prependOutside || appendOutside) { return ( diff --git a/packages/react/src/ui/Card/Card.tsx b/packages/react/src/ui/Card/Card.tsx index 60e05ce688..839f2e7950 100644 --- a/packages/react/src/ui/Card/Card.tsx +++ b/packages/react/src/ui/Card/Card.tsx @@ -1,9 +1,9 @@ import * as React from "react" -import { cn } from "../../lib/utils" +import { cn } from "@/lib/utils" -import ChevronRight from "../../icons/app/ChevronRight" -import InfoCircleLine from "../../icons/app/InfoCircleLine" +import ChevronRight from "@/icons/app/ChevronRight" +import InfoCircleLine from "@/icons/app/InfoCircleLine" import { F0Icon, IconType } from "@/components/F0Icon" import { Link } from "@/lib/linkHandler"