9c9c34fccf
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.
90 lines
2.8 KiB
TypeScript
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),
|
|
}}
|
|
/>
|
|
);
|
|
};
|