Files
twenty/packages/twenty-front/src/modules/advanced-text-editor/components/TurnIntoBlockDropdown.tsx
T
Raphaël Bosi 9c9c34fccf Remove twenty-ui-deprecated and migrate frontend to twenty-ui (#21596)
Migrates `twenty-front`, `twenty-sdk`, and
`twenty-front-component-renderer` from `twenty-ui-deprecated` to
`twenty-ui` (mechanical import swap — the packages have API parity) and
deletes the deprecated package along with its workspace/CI/config
wiring.

Also adds `@linaria/react`/`@linaria/core` as direct deps of
`twenty-front` (it used them transitively via the deprecated package).

Note: move the required status check from `ci-ui-status-check` to
`ci-new-ui-status-check`.

Argos: the Storybook box-model/button-reset baseline shift (the bulk of
the visual diffs) is isolated in #21665 — Storybook now loads
twenty-ui's global `reset.scss`, which the production app already ships.
Once #21665 merges and this branch is rebased, the remaining Argos diffs
are component-level visual-parity items only.
2026-06-17 09:41:11 +00:00

90 lines
2.8 KiB
TypeScript

import { useTurnIntoBlockOptions } from '@/advanced-text-editor/hooks/useTurnIntoBlockOptions';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useToggleDropdown } from '@/ui/layout/dropdown/hooks/useToggleDropdown';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { type Editor } from '@tiptap/react';
import { useContext, useId } from 'react';
import { IconPilcrow } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledMenuItem = styled.button`
align-items: center;
background: none;
border: none;
border-radius: ${themeCssVariables.spacing[1.5]};
color: ${themeCssVariables.font.color.tertiary};
cursor: pointer;
display: flex;
font-size: ${themeCssVariables.font.size.sm};
font-weight: ${themeCssVariables.font.weight.regular};
gap: 4px;
height: ${themeCssVariables.spacing[6]};
padding: 0 ${themeCssVariables.spacing[1.5]};
padding: 0;
width: 100%;
:hover {
background: ${themeCssVariables.background.transparent.medium};
}
:focus {
outline: none;
}
`;
type TurnIntoBlockDropdownProps = {
editor: Editor;
};
export const TurnIntoBlockDropdown = ({
editor,
}: TurnIntoBlockDropdownProps) => {
const { theme } = useContext(ThemeContext);
const instanceId = useId();
const dropdownId = `turn-into-block-dropdown-${instanceId}`;
const { toggleDropdown } = useToggleDropdown();
const options = useTurnIntoBlockOptions(editor);
const activeItem = options.find((option) => option.isActive());
const { icon: ActiveIcon = IconPilcrow, title: activeTitle = t`Paragraph` } =
activeItem ?? {};
return (
<Dropdown
dropdownComponents={
<DropdownContent>
<DropdownMenuItemsContainer>
{options.map(({ id, title, icon, onClick }) => (
<MenuItem
key={id}
text={title}
LeftIcon={icon}
onClick={() => {
onClick();
toggleDropdown({
dropdownComponentInstanceIdFromProps: dropdownId,
});
}}
/>
))}
</DropdownMenuItemsContainer>
</DropdownContent>
}
dropdownId={dropdownId}
clickableComponent={
<StyledMenuItem>
<ActiveIcon size={theme.icon.size.md} />
{activeTitle}
</StyledMenuItem>
}
dropdownOffset={{
y: parseInt(theme.spacing[1], 10),
}}
/>
);
};