diff --git a/apps/api/plane/api/serializers/issue.py b/apps/api/plane/api/serializers/issue.py
index 5a771f2ad5c..e0e7d592767 100644
--- a/apps/api/plane/api/serializers/issue.py
+++ b/apps/api/plane/api/serializers/issue.py
@@ -105,18 +105,32 @@ def validate(self, data):
# Validate assignees are from project
if data.get("assignees", []):
- data["assignees"] = ProjectMember.objects.filter(
- project_id=self.context.get("project_id"),
- is_active=True,
- role__gte=15,
- member_id__in=data["assignees"],
- ).values_list("member_id", flat=True)
+ valid_assignee_ids = set(
+ ProjectMember.objects.filter(
+ project_id=self.context.get("project_id"),
+ is_active=True,
+ role__gte=15,
+ member_id__in=data["assignees"],
+ ).values_list("member_id", flat=True)
+ )
+ invalid_assignee_ids = set(data["assignees"]) - valid_assignee_ids
+ if invalid_assignee_ids:
+ raise serializers.ValidationError(
+ f"Assignees {list(invalid_assignee_ids)} are not active members of this project"
+ )
+ data["assignees"] = list(valid_assignee_ids)
# Validate labels are from project
if data.get("labels", []):
- data["labels"] = Label.objects.filter(
- project_id=self.context.get("project_id"), id__in=data["labels"]
- ).values_list("id", flat=True)
+ valid_label_ids = set(
+ Label.objects.filter(
+ project_id=self.context.get("project_id"), id__in=data["labels"]
+ ).values_list("id", flat=True)
+ )
+ invalid_label_ids = set(data["labels"]) - valid_label_ids
+ if invalid_label_ids:
+ raise serializers.ValidationError(f"Labels {list(invalid_label_ids)} do not belong to this project")
+ data["labels"] = list(valid_label_ids)
# Check state is from the project only else raise validation error
if (
diff --git a/apps/api/plane/api/views/cycle.py b/apps/api/plane/api/views/cycle.py
index 6274b94de84..a6f2df0f96c 100644
--- a/apps/api/plane/api/views/cycle.py
+++ b/apps/api/plane/api/views/cycle.py
@@ -813,7 +813,7 @@ def post(self, request, slug, project_id, cycle_id):
Only cycles that have ended can be archived.
"""
cycle = Cycle.objects.get(pk=cycle_id, project_id=project_id, workspace__slug=slug)
- if cycle.end_date >= timezone.now():
+ if cycle.end_date is None or cycle.end_date >= timezone.now():
return Response(
{"error": "Only completed cycles can be archived"},
status=status.HTTP_400_BAD_REQUEST,
diff --git a/apps/api/plane/app/views/cycle/archive.py b/apps/api/plane/app/views/cycle/archive.py
index 772fcedea19..aaaf4c68038 100644
--- a/apps/api/plane/app/views/cycle/archive.py
+++ b/apps/api/plane/app/views/cycle/archive.py
@@ -587,7 +587,7 @@ def get(self, request, slug, project_id, pk=None):
def post(self, request, slug, project_id, cycle_id):
cycle = Cycle.objects.get(pk=cycle_id, project_id=project_id, workspace__slug=slug)
- if cycle.end_date >= timezone.now():
+ if cycle.end_date is None or cycle.end_date >= timezone.now():
return Response(
{"error": "Only completed cycles can be archived"},
status=status.HTTP_400_BAD_REQUEST,
diff --git a/apps/api/plane/tests/contract/api/test_issue_assignee_label_validation.py b/apps/api/plane/tests/contract/api/test_issue_assignee_label_validation.py
new file mode 100644
index 00000000000..768a2b6e445
--- /dev/null
+++ b/apps/api/plane/tests/contract/api/test_issue_assignee_label_validation.py
@@ -0,0 +1,136 @@
+# Copyright (c) 2023-present Plane Software, Inc. and contributors
+# SPDX-License-Identifier: AGPL-3.0-only
+# See the LICENSE file for details.
+
+import pytest
+from rest_framework import status
+
+from plane.celery import app as celery_app
+from plane.db.models import Issue, Label, Project, ProjectMember, State, User
+
+
+@pytest.fixture(autouse=True)
+def celery_eager():
+ """
+ Run Celery tasks synchronously in-process instead of publishing to a
+ broker. There's no RabbitMQ/broker in this local sandbox, and these
+ tests only care about the HTTP response contract, not async delivery.
+ """
+ original = celery_app.conf.task_always_eager
+ celery_app.conf.task_always_eager = True
+ celery_app.conf.task_eager_propagates = False
+ yield
+ celery_app.conf.task_always_eager = original
+
+
+@pytest.fixture
+def project(db, workspace, create_user):
+ """Create a test project with the user as an admin member and a default state."""
+ project = Project.objects.create(
+ name="Test Project", identifier="TP", workspace=workspace, created_by=create_user
+ )
+ ProjectMember.objects.create(project=project, member=create_user, role=20, is_active=True)
+ State.objects.create(
+ name="Backlog",
+ color="#000000",
+ group="backlog",
+ default=True,
+ project=project,
+ workspace=workspace,
+ created_by=create_user,
+ )
+ return project
+
+
+@pytest.fixture
+def create_issue(db, project, workspace, create_user):
+ return Issue.objects.create(name="Existing Issue", project=project, workspace=workspace, created_by=create_user)
+
+
+@pytest.fixture
+def outsider_user(db):
+ """A user who exists in the workspace/system but is NOT a member of `project`."""
+ user = User.objects.create(email="outsider@plane.so", username="outsider-user")
+ user.set_password("outsider-password")
+ user.save()
+ return user
+
+
+@pytest.mark.contract
+class TestIssueAssigneeLabelValidationContract:
+ """
+ Contract: creating/updating a work item through the external REST API
+ (``/api/v1/...``) must reject assignee/label ids that don't belong to the
+ project with a 400, instead of silently dropping them and returning
+ 200/201. See makeplane/plane#9517.
+ """
+
+ def get_list_url(self, workspace_slug, project_id):
+ return f"/api/v1/workspaces/{workspace_slug}/projects/{project_id}/issues/"
+
+ def get_detail_url(self, workspace_slug, project_id, issue_id):
+ return f"/api/v1/workspaces/{workspace_slug}/projects/{project_id}/issues/{issue_id}/"
+
+ @pytest.mark.django_db
+ def test_create_with_non_member_assignee_is_rejected(self, api_key_client, workspace, project, outsider_user):
+ url = self.get_list_url(workspace.slug, project.id)
+
+ response = api_key_client.post(
+ url, {"name": "New Issue", "assignees": [str(outsider_user.id)]}, format="json"
+ )
+
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+ assert not Issue.objects.filter(name="New Issue").exists()
+
+ @pytest.mark.django_db
+ def test_create_with_foreign_label_is_rejected(self, api_key_client, workspace, project):
+ other_project = Project.objects.create(name="Other", identifier="OTH", workspace=workspace)
+ foreign_label = Label.objects.create(name="Foreign", project=other_project)
+
+ url = self.get_list_url(workspace.slug, project.id)
+ response = api_key_client.post(
+ url, {"name": "New Issue", "labels": [str(foreign_label.id)]}, format="json"
+ )
+
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+ assert not Issue.objects.filter(name="New Issue").exists()
+
+ @pytest.mark.django_db
+ def test_update_with_non_member_assignee_is_rejected_and_leaves_assignees_unchanged(
+ self, api_key_client, workspace, project, create_issue, outsider_user
+ ):
+ url = self.get_detail_url(workspace.slug, project.id, create_issue.id)
+
+ response = api_key_client.patch(url, {"assignees": [str(outsider_user.id)]}, format="json")
+
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+ assert list(create_issue.assignees.all()) == []
+
+ @pytest.mark.django_db
+ def test_create_with_mix_of_valid_and_invalid_assignee_is_rejected_entirely(
+ self, api_key_client, workspace, project, create_user, outsider_user
+ ):
+ """A partially-valid list must reject the whole request, not silently keep only the valid id."""
+ url = self.get_list_url(workspace.slug, project.id)
+
+ response = api_key_client.post(
+ url,
+ {"name": "New Issue", "assignees": [str(create_user.id), str(outsider_user.id)]},
+ format="json",
+ )
+
+ assert response.status_code == status.HTTP_400_BAD_REQUEST
+ assert not Issue.objects.filter(name="New Issue").exists()
+
+ @pytest.mark.django_db
+ def test_create_with_valid_assignee_still_works(self, api_key_client, workspace, project, create_user):
+ """Regression guard: a genuinely valid project member must still be assignable."""
+ url = self.get_list_url(workspace.slug, project.id)
+
+ response = api_key_client.post(
+ url, {"name": "New Issue", "assignees": [str(create_user.id)]}, format="json"
+ )
+
+ assert response.status_code == status.HTTP_201_CREATED
+ issue = Issue.objects.get(name="New Issue")
+ assert list(issue.assignees.values_list("id", flat=True)) == [create_user.id]
diff --git a/apps/api/plane/tests/unit/serializers/test_issue_serializer_api.py b/apps/api/plane/tests/unit/serializers/test_issue_serializer_api.py
new file mode 100644
index 00000000000..8b3c8ff75d7
--- /dev/null
+++ b/apps/api/plane/tests/unit/serializers/test_issue_serializer_api.py
@@ -0,0 +1,61 @@
+# Copyright (c) 2023-present Plane Software, Inc. and contributors
+# SPDX-License-Identifier: AGPL-3.0-only
+# See the LICENSE file for details.
+
+import pytest
+
+from plane.api.serializers.issue import IssueSerializer
+from plane.db.models import Project, ProjectMember, Label, User
+
+
+@pytest.mark.unit
+class TestIssueSerializerAssigneeAndLabelValidation:
+ """Test that IssueSerializer rejects invalid assignees/labels instead of silently dropping them"""
+
+ @pytest.mark.django_db
+ def test_rejects_assignee_who_is_not_an_active_project_member(self, db, workspace, create_user):
+ """An assignee id that isn't an active project member (role >= 15) must raise a validation error"""
+ project = Project.objects.create(name="Test Project", identifier="TEST", workspace=workspace)
+
+ outsider = User.objects.create(
+ email="outsider@example.com", first_name="Out", last_name="Sider", username="outsider"
+ )
+ # Not a member of the project at all
+
+ serializer = IssueSerializer(
+ data={"name": "Test Issue", "assignees": [str(outsider.id)]},
+ context={"project_id": project.id, "workspace_id": workspace.id},
+ )
+
+ assert not serializer.is_valid()
+ assert "assignees" in str(serializer.errors).lower() or "assignee" in str(serializer.errors).lower()
+
+ @pytest.mark.django_db
+ def test_rejects_label_that_does_not_belong_to_project(self, db, workspace, create_user):
+ """A label id that belongs to a different project must raise a validation error"""
+ project = Project.objects.create(name="Test Project", identifier="TEST", workspace=workspace)
+ other_project = Project.objects.create(name="Other Project", identifier="OTHER", workspace=workspace)
+
+ foreign_label = Label.objects.create(name="Foreign Label", project=other_project)
+
+ serializer = IssueSerializer(
+ data={"name": "Test Issue", "labels": [str(foreign_label.id)]},
+ context={"project_id": project.id, "workspace_id": workspace.id},
+ )
+
+ assert not serializer.is_valid()
+ assert "labels" in str(serializer.errors).lower() or "label" in str(serializer.errors).lower()
+
+ @pytest.mark.django_db
+ def test_accepts_assignee_who_is_an_active_project_member(self, db, workspace, create_user):
+ """A valid active project member id should still be accepted"""
+ project = Project.objects.create(name="Test Project", identifier="TEST", workspace=workspace)
+ ProjectMember.objects.create(project=project, member=create_user, role=15, is_active=True)
+
+ serializer = IssueSerializer(
+ data={"name": "Test Issue", "assignees": [str(create_user.id)]},
+ context={"project_id": project.id, "workspace_id": workspace.id},
+ )
+
+ assert serializer.is_valid(), serializer.errors
+ assert list(serializer.validated_data["assignees"]) == [create_user.id]
diff --git a/apps/web/core/store/issue/helpers/base-issues.store.ts b/apps/web/core/store/issue/helpers/base-issues.store.ts
index 09c24d25f45..c0de20f495f 100644
--- a/apps/web/core/store/issue/helpers/base-issues.store.ts
+++ b/apps/web/core/store/issue/helpers/base-issues.store.ts
@@ -1212,7 +1212,7 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
const issueId = issue?.id ?? issueBeforeUpdate?.id;
if (!issueId) return;
- // Get display filters to check if 'Show sub Work items' is enabled - Donot add Work item to main list if disabled.
+ // Get display filters to check if 'Show sub Work items' is enabled - Do not add Work item to main list if disabled.
const isShowWorkItemsEnabled = this.issueFilterStore.issueFilters?.displayFilters?.sub_issue ?? false;
// get issueUpdates from another method by passing down the three arguments
diff --git a/packages/editor/package.json b/packages/editor/package.json
index 20e4a41be4b..8f71154da72 100644
--- a/packages/editor/package.json
+++ b/packages/editor/package.json
@@ -37,6 +37,7 @@
"@floating-ui/react": "catalog:",
"@headlessui/react": "catalog:",
"@hocuspocus/provider": "catalog:",
+ "@makeplane/propel": "catalog:",
"@plane/constants": "workspace:*",
"@plane/hooks": "workspace:*",
"@plane/propel": "workspace:*",
diff --git a/packages/editor/src/components/links/link-edit-view.tsx b/packages/editor/src/components/links/link-edit-view.tsx
index 3adbefa27cd..cc4b2b990d7 100644
--- a/packages/editor/src/components/links/link-edit-view.tsx
+++ b/packages/editor/src/components/links/link-edit-view.tsx
@@ -5,7 +5,7 @@
*/
import type { Node } from "@tiptap/pm/model";
-import { Link2Off } from "lucide-react";
+import { UnlinkOutline } from "@makeplane/propel/icons";
import { useCallback, useEffect, useRef, useState } from "react";
// components
import type { LinkViewProps, LinkViews } from "@/components/links";
@@ -148,7 +148,7 @@ export function LinkEditView({ viewProps }: LinkEditViewProps) {
-
+
diff --git a/packages/editor/src/components/links/link-preview.tsx b/packages/editor/src/components/links/link-preview.tsx
index f47c97bd434..b689dcf8301 100644
--- a/packages/editor/src/components/links/link-preview.tsx
+++ b/packages/editor/src/components/links/link-preview.tsx
@@ -4,8 +4,7 @@
* See the LICENSE file for details.
*/
-import { Link2Off } from "lucide-react";
-import { CopyIcon, GlobeIcon, EditIcon } from "@plane/propel/icons";
+import { CopyOutline, EditOutline, GlobeOutline, UnlinkOutline } from "@makeplane/propel/icons";
// components
import type { LinkViewProps, LinkViews } from "@/components/links";
@@ -36,11 +35,11 @@ export function LinkPreview({
}}
>
-
+
{url?.length > 40 ? url.slice(0, 40) + "..." : url}
{editor.isEditable && (
<>
@@ -48,10 +47,10 @@ export function LinkPreview({
onClick={() => switchView("LinkEditView")}
className="cursor-pointer transition-colors hover:text-primary"
>
-
+
>
)}
diff --git a/packages/editor/src/components/menus/block-menu-options.tsx b/packages/editor/src/components/menus/block-menu-options.tsx
index 9a8b42c7fbd..6fe33c2ed7b 100644
--- a/packages/editor/src/components/menus/block-menu-options.tsx
+++ b/packages/editor/src/components/menus/block-menu-options.tsx
@@ -7,7 +7,7 @@
import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
import { TableMap } from "@tiptap/pm/tables";
import type { Editor } from "@tiptap/react";
-import { MoveHorizontal } from "lucide-react";
+import { DragDropOutline } from "@makeplane/propel/icons";
// constants
import { CORE_EXTENSIONS } from "@/constants/extension";
// types
@@ -84,7 +84,7 @@ const setTableToFullWidth = (editor: Editor): void => {
export const getNodeOptions = (editor: Editor): BlockMenuOption[] => [
{
- icon: MoveHorizontal,
+ icon: DragDropOutline,
key: "table-full-width",
label: "Fit to width",
isDisabled: !editor.isActive(CORE_EXTENSIONS.TABLE),
diff --git a/packages/editor/src/components/menus/block-menu.tsx b/packages/editor/src/components/menus/block-menu.tsx
index c3dff0d20e9..d50feae2b28 100644
--- a/packages/editor/src/components/menus/block-menu.tsx
+++ b/packages/editor/src/components/menus/block-menu.tsx
@@ -17,7 +17,7 @@ import {
import type { Editor } from "@tiptap/react";
import type { LucideIcon } from "lucide-react";
import { useCallback, useEffect, useRef, useState } from "react";
-import { CopyIcon, TrashIcon } from "@plane/propel/icons";
+import { CopyOutline, DeleteOutline } from "@makeplane/propel/icons";
import type { ISvgIcons } from "@plane/propel/icons";
import { cn } from "@plane/utils";
// constants
@@ -150,7 +150,7 @@ export function BlockMenu(props: Props) {
const MENU_ITEMS: BlockMenuOption[] = [
{
- icon: TrashIcon,
+ icon: DeleteOutline,
key: "delete",
label: "Delete",
onClick: (_e) => {
@@ -159,7 +159,7 @@ export function BlockMenu(props: Props) {
},
},
{
- icon: CopyIcon,
+ icon: CopyOutline,
key: "duplicate",
label: "Duplicate",
isDisabled:
diff --git a/packages/editor/src/components/menus/bubble-menu/alignment-selector.tsx b/packages/editor/src/components/menus/bubble-menu/alignment-selector.tsx
index 0bfad5a6717..311eaa54ec5 100644
--- a/packages/editor/src/components/menus/bubble-menu/alignment-selector.tsx
+++ b/packages/editor/src/components/menus/bubble-menu/alignment-selector.tsx
@@ -5,8 +5,8 @@
*/
import type { Editor } from "@tiptap/core";
-import type { LucideIcon } from "lucide-react";
-import { AlignCenter, AlignLeft, AlignRight } from "lucide-react";
+import type { ComponentType, SVGProps } from "react";
+import { AlignCenterOutline, AlignLeftOutline, AlignRightOutline } from "@makeplane/propel/icons";
// plane utils
import { cn } from "@plane/utils";
// components
@@ -27,14 +27,14 @@ export function TextAlignmentSelector(props: Props) {
const textAlignmentOptions: {
itemKey: TEditorCommands;
renderKey: string;
- icon: LucideIcon;
+ icon: ComponentType
>;
command: () => void;
isActive: () => boolean;
}[] = [
{
itemKey: "text-align",
renderKey: "text-align-left",
- icon: AlignLeft,
+ icon: AlignLeftOutline,
command: () =>
menuItem.command({
alignment: "left",
@@ -44,7 +44,7 @@ export function TextAlignmentSelector(props: Props) {
{
itemKey: "text-align",
renderKey: "text-align-center",
- icon: AlignCenter,
+ icon: AlignCenterOutline,
command: () =>
menuItem.command({
alignment: "center",
@@ -54,7 +54,7 @@ export function TextAlignmentSelector(props: Props) {
{
itemKey: "text-align",
renderKey: "text-align-right",
- icon: AlignRight,
+ icon: AlignRightOutline,
command: () =>
menuItem.command({
alignment: "right",
diff --git a/packages/editor/src/components/menus/bubble-menu/color-selector.tsx b/packages/editor/src/components/menus/bubble-menu/color-selector.tsx
index d8151b8b61c..b2ad51e9eae 100644
--- a/packages/editor/src/components/menus/bubble-menu/color-selector.tsx
+++ b/packages/editor/src/components/menus/bubble-menu/color-selector.tsx
@@ -5,7 +5,8 @@
*/
import type { Editor } from "@tiptap/react";
-import { ALargeSmall, Ban } from "lucide-react";
+import { Ban } from "lucide-react";
+import { TextOutline } from "@makeplane/propel/icons";
import { useMemo } from "react";
// plane utils
import { cn } from "@plane/utils";
@@ -48,7 +49,7 @@ export function BubbleMenuColorSelector(props: Props) {
backgroundColor: activeBackgroundColor ? activeBackgroundColor.backgroundColor : "transparent",
}}
>
-
Link
-
+
>
}
options={options}
@@ -102,7 +102,7 @@ export function BubbleMenuLinkSelector(props: Props) {
context.onOpenChange(false);
}}
>
-
+
) : (
)}
diff --git a/packages/editor/src/components/menus/bubble-menu/node-selector.tsx b/packages/editor/src/components/menus/bubble-menu/node-selector.tsx
index e31fe563591..78663abc2c2 100644
--- a/packages/editor/src/components/menus/bubble-menu/node-selector.tsx
+++ b/packages/editor/src/components/menus/bubble-menu/node-selector.tsx
@@ -6,7 +6,7 @@
import type { Editor } from "@tiptap/react";
-import { CheckIcon, ChevronDownIcon } from "@plane/propel/icons";
+import { ChevronDownOutline, TickOutline } from "@makeplane/propel/icons";
// plane utils
import { cn } from "@plane/utils";
// components
@@ -73,7 +73,7 @@ export function BubbleMenuNodeSelector(props: Props) {
menuButton={
<>
{activeItem?.name}
-
+
>
}
options={options}
@@ -101,7 +101,7 @@ export function BubbleMenuNodeSelector(props: Props) {
{item.name}
- {activeItem.name === item.name &&
}
+ {activeItem.name === item.name &&
}
))}
diff --git a/packages/editor/src/components/menus/menu-items.ts b/packages/editor/src/components/menus/menu-items.ts
index 74407c9a03b..90f54d7807c 100644
--- a/packages/editor/src/components/menus/menu-items.ts
+++ b/packages/editor/src/components/menus/menu-items.ts
@@ -6,30 +6,30 @@
import type { Editor } from "@tiptap/react";
import {
- BoldIcon,
- Heading1,
- CheckSquare,
- Heading2,
- Heading3,
- TextQuote,
- ImageIcon,
- TableIcon,
- ListIcon,
- ListOrderedIcon,
- ItalicIcon,
- UnderlineIcon,
- StrikethroughIcon,
- CodeIcon,
- Heading4,
- Heading5,
- Heading6,
- CaseSensitive,
- MinusSquare,
- Palette,
- AlignCenter,
-} from "lucide-react";
-import type { LucideIcon } from "lucide-react";
-import { LinkIcon } from "@plane/propel/icons";
+ AlignCenterOutline,
+ BoldOutline,
+ CheckSquareOutline,
+ CodeOutline,
+ H1Outline,
+ H2Outline,
+ H3Outline,
+ H4Outline,
+ H5Outline,
+ H6Outline,
+ ImageOutline,
+ ItalicOutline,
+ LinkOutline,
+ ListOutline,
+ MinusSquareOutline,
+ NumberedListOutline,
+ PaletteOutline,
+ QuoteOutline,
+ StrikethroughOutline,
+ TableOutline,
+ TextOutline,
+ UnderlineOutline,
+} from "@makeplane/propel/icons";
+import type { ComponentType, SVGProps } from "react";
// constants
import { CORE_EXTENSIONS } from "@/constants/extension";
// helpers
@@ -56,7 +56,6 @@ import {
} from "@/helpers/editor-commands";
// types
import type { TCommandWithProps, TEditorCommands } from "@/types";
-import type { ISvgIcons } from "@plane/propel/icons";
type isActiveFunction
= (params?: TCommandWithProps) => boolean;
type commandFunction = (params?: TCommandWithProps) => void;
@@ -64,7 +63,7 @@ export type EditorMenuItem = {
key: T;
name: string;
command: commandFunction;
- icon: LucideIcon | React.FC;
+ icon: ComponentType>;
isActive: isActiveFunction;
};
@@ -73,7 +72,7 @@ export const TextItem = (editor: Editor): EditorMenuItem<"text"> => ({
name: "Text",
isActive: () => editor.isActive(CORE_EXTENSIONS.PARAGRAPH),
command: () => setText(editor),
- icon: CaseSensitive,
+ icon: TextOutline,
});
type SupportedHeadingLevels = Extract;
@@ -83,7 +82,7 @@ const HeadingItem = (
level: 1 | 2 | 3 | 4 | 5 | 6,
key: T,
name: string,
- icon: LucideIcon
+ icon: ComponentType>
): EditorMenuItem => ({
key,
name,
@@ -93,29 +92,29 @@ const HeadingItem = (
});
export const HeadingOneItem = (editor: Editor): EditorMenuItem<"h1"> =>
- HeadingItem(editor, 1, "h1", "Heading 1", Heading1);
+ HeadingItem(editor, 1, "h1", "Heading 1", H1Outline);
export const HeadingTwoItem = (editor: Editor): EditorMenuItem<"h2"> =>
- HeadingItem(editor, 2, "h2", "Heading 2", Heading2);
+ HeadingItem(editor, 2, "h2", "Heading 2", H2Outline);
export const HeadingThreeItem = (editor: Editor): EditorMenuItem<"h3"> =>
- HeadingItem(editor, 3, "h3", "Heading 3", Heading3);
+ HeadingItem(editor, 3, "h3", "Heading 3", H3Outline);
export const HeadingFourItem = (editor: Editor): EditorMenuItem<"h4"> =>
- HeadingItem(editor, 4, "h4", "Heading 4", Heading4);
+ HeadingItem(editor, 4, "h4", "Heading 4", H4Outline);
export const HeadingFiveItem = (editor: Editor): EditorMenuItem<"h5"> =>
- HeadingItem(editor, 5, "h5", "Heading 5", Heading5);
+ HeadingItem(editor, 5, "h5", "Heading 5", H5Outline);
export const HeadingSixItem = (editor: Editor): EditorMenuItem<"h6"> =>
- HeadingItem(editor, 6, "h6", "Heading 6", Heading6);
+ HeadingItem(editor, 6, "h6", "Heading 6", H6Outline);
export const BoldItem = (editor: Editor): EditorMenuItem<"bold"> => ({
key: "bold",
name: "Bold",
isActive: () => editor?.isActive(CORE_EXTENSIONS.BOLD),
command: () => toggleBold(editor),
- icon: BoldIcon,
+ icon: BoldOutline,
});
export const ItalicItem = (editor: Editor): EditorMenuItem<"italic"> => ({
@@ -123,7 +122,7 @@ export const ItalicItem = (editor: Editor): EditorMenuItem<"italic"> => ({
name: "Italic",
isActive: () => editor?.isActive(CORE_EXTENSIONS.ITALIC),
command: () => toggleItalic(editor),
- icon: ItalicIcon,
+ icon: ItalicOutline,
});
export const UnderLineItem = (editor: Editor): EditorMenuItem<"underline"> => ({
@@ -131,7 +130,7 @@ export const UnderLineItem = (editor: Editor): EditorMenuItem<"underline"> => ({
name: "Underline",
isActive: () => editor?.isActive(CORE_EXTENSIONS.UNDERLINE),
command: () => toggleUnderline(editor),
- icon: UnderlineIcon,
+ icon: UnderlineOutline,
});
export const StrikeThroughItem = (editor: Editor): EditorMenuItem<"strikethrough"> => ({
@@ -139,7 +138,7 @@ export const StrikeThroughItem = (editor: Editor): EditorMenuItem<"strikethrough
name: "Strikethrough",
isActive: () => editor?.isActive(CORE_EXTENSIONS.STRIKETHROUGH),
command: () => toggleStrike(editor),
- icon: StrikethroughIcon,
+ icon: StrikethroughOutline,
});
export const BulletListItem = (editor: Editor): EditorMenuItem<"bulleted-list"> => ({
@@ -147,7 +146,7 @@ export const BulletListItem = (editor: Editor): EditorMenuItem<"bulleted-list">
name: "Bulleted list",
isActive: () => editor?.isActive(CORE_EXTENSIONS.BULLET_LIST),
command: () => toggleBulletList(editor),
- icon: ListIcon,
+ icon: ListOutline,
});
export const NumberedListItem = (editor: Editor): EditorMenuItem<"numbered-list"> => ({
@@ -155,7 +154,7 @@ export const NumberedListItem = (editor: Editor): EditorMenuItem<"numbered-list"
name: "Numbered list",
isActive: () => editor?.isActive(CORE_EXTENSIONS.ORDERED_LIST),
command: () => toggleOrderedList(editor),
- icon: ListOrderedIcon,
+ icon: NumberedListOutline,
});
export const TodoListItem = (editor: Editor): EditorMenuItem<"to-do-list"> => ({
@@ -163,7 +162,7 @@ export const TodoListItem = (editor: Editor): EditorMenuItem<"to-do-list"> => ({
name: "To-do list",
isActive: () => editor.isActive(CORE_EXTENSIONS.TASK_ITEM),
command: () => toggleTaskList(editor),
- icon: CheckSquare,
+ icon: CheckSquareOutline,
});
export const QuoteItem = (editor: Editor): EditorMenuItem<"quote"> => ({
@@ -171,7 +170,7 @@ export const QuoteItem = (editor: Editor): EditorMenuItem<"quote"> => ({
name: "Quote",
isActive: () => editor?.isActive(CORE_EXTENSIONS.BLOCKQUOTE),
command: () => toggleBlockquote(editor),
- icon: TextQuote,
+ icon: QuoteOutline,
});
export const CodeItem = (editor: Editor): EditorMenuItem<"code"> => ({
@@ -179,7 +178,7 @@ export const CodeItem = (editor: Editor): EditorMenuItem<"code"> => ({
name: "Code",
isActive: () => editor?.isActive(CORE_EXTENSIONS.CODE_INLINE) || editor?.isActive(CORE_EXTENSIONS.CODE_BLOCK),
command: () => toggleCodeBlock(editor),
- icon: CodeIcon,
+ icon: CodeOutline,
});
export const TableItem = (editor: Editor): EditorMenuItem<"table"> => ({
@@ -187,7 +186,7 @@ export const TableItem = (editor: Editor): EditorMenuItem<"table"> => ({
name: "Table",
isActive: () => editor?.isActive(CORE_EXTENSIONS.TABLE),
command: () => insertTableCommand(editor),
- icon: TableIcon,
+ icon: TableOutline,
});
export const ImageItem = (editor: Editor): EditorMenuItem<"image"> => ({
@@ -195,7 +194,7 @@ export const ImageItem = (editor: Editor): EditorMenuItem<"image"> => ({
name: "Image",
isActive: () => editor?.isActive(CORE_EXTENSIONS.IMAGE) || editor?.isActive(CORE_EXTENSIONS.CUSTOM_IMAGE),
command: () => insertImage({ editor, event: "insert", pos: editor.state.selection.from }),
- icon: ImageIcon,
+ icon: ImageOutline,
});
export const HorizontalRuleItem = (editor: Editor): EditorMenuItem<"divider"> =>
@@ -204,7 +203,7 @@ export const HorizontalRuleItem = (editor: Editor): EditorMenuItem<"divider"> =>
name: "Divider",
isActive: () => editor?.isActive(CORE_EXTENSIONS.HORIZONTAL_RULE),
command: () => insertHorizontalRule(editor),
- icon: MinusSquare,
+ icon: MinusSquareOutline,
}) as const;
export const LinkItem = (editor: Editor): EditorMenuItem<"link"> =>
@@ -219,7 +218,7 @@ export const LinkItem = (editor: Editor): EditorMenuItem<"link"> =>
else unsetLinkEditor(editor);
},
- icon: LinkIcon,
+ icon: LinkOutline,
}) as const;
export const TextColorItem = (editor: Editor): EditorMenuItem<"text-color"> => ({
@@ -230,7 +229,7 @@ export const TextColorItem = (editor: Editor): EditorMenuItem<"text-color"> => (
if (!props) return;
toggleTextColor(props.color, editor);
},
- icon: Palette,
+ icon: PaletteOutline,
});
export const BackgroundColorItem = (editor: Editor): EditorMenuItem<"background-color"> => ({
@@ -241,7 +240,7 @@ export const BackgroundColorItem = (editor: Editor): EditorMenuItem<"background-
if (!props) return;
toggleBackgroundColor(props.color, editor);
},
- icon: Palette,
+ icon: PaletteOutline,
});
export const TextAlignItem = (editor: Editor): EditorMenuItem<"text-align"> => ({
@@ -252,7 +251,7 @@ export const TextAlignItem = (editor: Editor): EditorMenuItem<"text-align"> => (
if (!props) return;
setTextAlign(props.alignment, editor);
},
- icon: AlignCenter,
+ icon: AlignCenterOutline,
});
export const getEditorMenuItems = (editor: Editor | null): EditorMenuItem[] => {
diff --git a/packages/editor/src/constants/common.ts b/packages/editor/src/constants/common.ts
index b90069944cb..a202ab5624e 100644
--- a/packages/editor/src/constants/common.ts
+++ b/packages/editor/src/constants/common.ts
@@ -4,30 +4,30 @@
* See the LICENSE file for details.
*/
-import type { LucideIcon } from "lucide-react";
+import type { ComponentType, SVGProps } from "react";
import {
- AlignCenter,
- AlignLeft,
- AlignRight,
- Bold,
- CaseSensitive,
- Code2,
- Heading1,
- Heading2,
- Heading3,
- Heading4,
- Heading5,
- Heading6,
- Image,
- Italic,
- List,
- ListOrdered,
- ListTodo,
- Strikethrough,
- Table,
- TextQuote,
- Underline,
-} from "lucide-react";
+ AlignCenterOutline,
+ AlignLeftOutline,
+ AlignRightOutline,
+ BoldOutline,
+ CodeOutline,
+ H1Outline,
+ H2Outline,
+ H3Outline,
+ H4Outline,
+ H5Outline,
+ H6Outline,
+ ImageOutline,
+ ItalicOutline,
+ ListOutline,
+ NumberedListOutline,
+ QuoteOutline,
+ StrikethroughOutline,
+ TableEditorOutline,
+ TextOutline,
+ ToDoOutline,
+ UnderlineOutline,
+} from "@makeplane/propel/icons";
import { MonospaceIcon, SansSerifIcon, SerifIcon } from "@plane/propel/icons";
import type { TCommandExtraProps, TEditorCommands, TEditorFontStyle } from "@/types";
@@ -42,20 +42,20 @@ export type ToolbarMenuItem = {
itemKey: T;
renderKey: string;
name: string;
- icon: LucideIcon;
+ icon: ComponentType>;
shortcut?: string[];
editors: TEditorTypes[];
extraProps?: ExtraPropsForCommand;
};
export const TYPOGRAPHY_ITEMS: ToolbarMenuItem<"text" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6">[] = [
- { itemKey: "text", renderKey: "text", name: "Text", icon: CaseSensitive, editors: ["document"] },
- { itemKey: "h1", renderKey: "h1", name: "Heading 1", icon: Heading1, editors: ["document"] },
- { itemKey: "h2", renderKey: "h2", name: "Heading 2", icon: Heading2, editors: ["document"] },
- { itemKey: "h3", renderKey: "h3", name: "Heading 3", icon: Heading3, editors: ["document"] },
- { itemKey: "h4", renderKey: "h4", name: "Heading 4", icon: Heading4, editors: ["document"] },
- { itemKey: "h5", renderKey: "h5", name: "Heading 5", icon: Heading5, editors: ["document"] },
- { itemKey: "h6", renderKey: "h6", name: "Heading 6", icon: Heading6, editors: ["document"] },
+ { itemKey: "text", renderKey: "text", name: "Text", icon: TextOutline, editors: ["document"] },
+ { itemKey: "h1", renderKey: "h1", name: "Heading 1", icon: H1Outline, editors: ["document"] },
+ { itemKey: "h2", renderKey: "h2", name: "Heading 2", icon: H2Outline, editors: ["document"] },
+ { itemKey: "h3", renderKey: "h3", name: "Heading 3", icon: H3Outline, editors: ["document"] },
+ { itemKey: "h4", renderKey: "h4", name: "Heading 4", icon: H4Outline, editors: ["document"] },
+ { itemKey: "h5", renderKey: "h5", name: "Heading 5", icon: H5Outline, editors: ["document"] },
+ { itemKey: "h6", renderKey: "h6", name: "Heading 6", icon: H6Outline, editors: ["document"] },
];
export const TEXT_ALIGNMENT_ITEMS: ToolbarMenuItem<"text-align">[] = [
@@ -63,7 +63,7 @@ export const TEXT_ALIGNMENT_ITEMS: ToolbarMenuItem<"text-align">[] = [
itemKey: "text-align",
renderKey: "text-align-left",
name: "Left align",
- icon: AlignLeft,
+ icon: AlignLeftOutline,
shortcut: ["Cmd", "Shift", "L"],
editors: ["lite", "document"],
extraProps: {
@@ -74,7 +74,7 @@ export const TEXT_ALIGNMENT_ITEMS: ToolbarMenuItem<"text-align">[] = [
itemKey: "text-align",
renderKey: "text-align-center",
name: "Center align",
- icon: AlignCenter,
+ icon: AlignCenterOutline,
shortcut: ["Cmd", "Shift", "E"],
editors: ["lite", "document"],
extraProps: {
@@ -85,7 +85,7 @@ export const TEXT_ALIGNMENT_ITEMS: ToolbarMenuItem<"text-align">[] = [
itemKey: "text-align",
renderKey: "text-align-right",
name: "Right align",
- icon: AlignRight,
+ icon: AlignRightOutline,
shortcut: ["Cmd", "Shift", "R"],
editors: ["lite", "document"],
extraProps: {
@@ -99,7 +99,7 @@ const BASIC_MARK_ITEMS: ToolbarMenuItem<"bold" | "italic" | "underline" | "strik
itemKey: "bold",
renderKey: "bold",
name: "Bold",
- icon: Bold,
+ icon: BoldOutline,
shortcut: ["Cmd", "B"],
editors: ["lite", "document"],
},
@@ -107,7 +107,7 @@ const BASIC_MARK_ITEMS: ToolbarMenuItem<"bold" | "italic" | "underline" | "strik
itemKey: "italic",
renderKey: "italic",
name: "Italic",
- icon: Italic,
+ icon: ItalicOutline,
shortcut: ["Cmd", "I"],
editors: ["lite", "document"],
},
@@ -115,7 +115,7 @@ const BASIC_MARK_ITEMS: ToolbarMenuItem<"bold" | "italic" | "underline" | "strik
itemKey: "underline",
renderKey: "underline",
name: "Underline",
- icon: Underline,
+ icon: UnderlineOutline,
shortcut: ["Cmd", "U"],
editors: ["lite", "document"],
},
@@ -123,7 +123,7 @@ const BASIC_MARK_ITEMS: ToolbarMenuItem<"bold" | "italic" | "underline" | "strik
itemKey: "strikethrough",
renderKey: "strikethrough",
name: "Strikethrough",
- icon: Strikethrough,
+ icon: StrikethroughOutline,
shortcut: ["Cmd", "Shift", "S"],
editors: ["lite", "document"],
},
@@ -134,7 +134,7 @@ const LIST_ITEMS: ToolbarMenuItem<"bulleted-list" | "numbered-list" | "to-do-lis
itemKey: "bulleted-list",
renderKey: "bulleted-list",
name: "Bulleted list",
- icon: List,
+ icon: ListOutline,
shortcut: ["Cmd", "Shift", "7"],
editors: ["lite", "document"],
},
@@ -142,7 +142,7 @@ const LIST_ITEMS: ToolbarMenuItem<"bulleted-list" | "numbered-list" | "to-do-lis
itemKey: "numbered-list",
renderKey: "numbered-list",
name: "Numbered list",
- icon: ListOrdered,
+ icon: NumberedListOutline,
shortcut: ["Cmd", "Shift", "8"],
editors: ["lite", "document"],
},
@@ -150,20 +150,20 @@ const LIST_ITEMS: ToolbarMenuItem<"bulleted-list" | "numbered-list" | "to-do-lis
itemKey: "to-do-list",
renderKey: "to-do-list",
name: "To-do list",
- icon: ListTodo,
+ icon: ToDoOutline,
shortcut: ["Cmd", "Shift", "9"],
editors: ["lite", "document"],
},
];
export const USER_ACTION_ITEMS: ToolbarMenuItem<"quote" | "code">[] = [
- { itemKey: "quote", renderKey: "quote", name: "Quote", icon: TextQuote, editors: ["lite", "document"] },
- { itemKey: "code", renderKey: "code", name: "Code", icon: Code2, editors: ["lite", "document"] },
+ { itemKey: "quote", renderKey: "quote", name: "Quote", icon: QuoteOutline, editors: ["lite", "document"] },
+ { itemKey: "code", renderKey: "code", name: "Code", icon: CodeOutline, editors: ["lite", "document"] },
];
export const COMPLEX_ITEMS: ToolbarMenuItem<"table" | "image">[] = [
- { itemKey: "table", renderKey: "table", name: "Table", icon: Table, editors: ["document"] },
- { itemKey: "image", renderKey: "image", name: "Image", icon: Image, editors: ["lite", "document"] },
+ { itemKey: "table", renderKey: "table", name: "Table", icon: TableEditorOutline, editors: ["document"] },
+ { itemKey: "image", renderKey: "image", name: "Image", icon: ImageOutline, editors: ["lite", "document"] },
];
export const IMAGE_ITEM = COMPLEX_ITEMS.find((item): item is ToolbarMenuItem<"image"> => item.itemKey === "image")!;
diff --git a/packages/editor/src/extensions/callout/color-selector.tsx b/packages/editor/src/extensions/callout/color-selector.tsx
index a51e2f4eab9..cb535b380c6 100644
--- a/packages/editor/src/extensions/callout/color-selector.tsx
+++ b/packages/editor/src/extensions/callout/color-selector.tsx
@@ -5,7 +5,7 @@
*/
import { Ban } from "lucide-react";
-import { ChevronDownIcon } from "@plane/propel/icons";
+import { ChevronDownOutline } from "@makeplane/propel/icons";
// plane utils
import { cn } from "@plane/utils";
// constants
@@ -50,7 +50,7 @@ export function CalloutBlockColorSelector(props: Props) {
disabled={disabled}
>
Color
-
+
{isOpen && (
diff --git a/packages/editor/src/extensions/code/code-block-node-view.tsx b/packages/editor/src/extensions/code/code-block-node-view.tsx
index 6df877d44b6..4a1acf3949c 100644
--- a/packages/editor/src/extensions/code/code-block-node-view.tsx
+++ b/packages/editor/src/extensions/code/code-block-node-view.tsx
@@ -8,9 +8,8 @@ import type { Node as ProseMirrorNode } from "@tiptap/pm/model";
import { NodeViewWrapper, NodeViewContent } from "@tiptap/react";
import ts from "highlight.js/lib/languages/typescript";
import { common, createLowlight } from "lowlight";
-import { CheckIcon } from "lucide-react";
+import { CopyOutline, TickOutline } from "@makeplane/propel/icons";
import { useState } from "react";
-import { CopyIcon } from "@plane/propel/icons";
// ui
import { Tooltip } from "@plane/propel/tooltip";
// plane utils
@@ -58,9 +57,9 @@ export function CodeBlockComponent({ node }: Props) {
onClick={(e) => void copyToClipboard(e)}
>
{copied ? (
-
+
) : (
-
+
)}
diff --git a/packages/editor/src/extensions/custom-image/components/toolbar/alignment.tsx b/packages/editor/src/extensions/custom-image/components/toolbar/alignment.tsx
index ecdcf0c6ea9..2b8602b4abb 100644
--- a/packages/editor/src/extensions/custom-image/components/toolbar/alignment.tsx
+++ b/packages/editor/src/extensions/custom-image/components/toolbar/alignment.tsx
@@ -7,7 +7,7 @@
import { useEffect, useRef, useState } from "react";
// plane imports
import { useOutsideClickDetector } from "@plane/hooks";
-import { ChevronDownIcon } from "@plane/propel/icons";
+import { ChevronDownOutline } from "@makeplane/propel/icons";
import { Tooltip } from "@plane/propel/tooltip";
// local imports
import type { TCustomImageAlignment } from "../../types";
@@ -44,7 +44,7 @@ export function ImageAlignmentAction(props: Props) {
onClick={() => setIsDropdownOpen((prev) => !prev)}
>
{activeAlignmentDetails && }
-
+
{isDropdownOpen && (
diff --git a/packages/editor/src/extensions/custom-image/components/toolbar/download.tsx b/packages/editor/src/extensions/custom-image/components/toolbar/download.tsx
index 772ddd0fb99..9230989ee3e 100644
--- a/packages/editor/src/extensions/custom-image/components/toolbar/download.tsx
+++ b/packages/editor/src/extensions/custom-image/components/toolbar/download.tsx
@@ -4,7 +4,7 @@
* See the LICENSE file for details.
*/
-import { Download } from "lucide-react";
+import { DownloadOutline } from "@makeplane/propel/icons";
// plane imports
import { Tooltip } from "@plane/propel/tooltip";
@@ -23,7 +23,7 @@ export function ImageDownloadAction(props: Props) {
className="grid h-full flex-shrink-0 place-items-center text-white/60 transition-colors hover:text-white"
aria-label="Download image"
>
-
+
);
diff --git a/packages/editor/src/extensions/custom-image/components/toolbar/full-screen/modal.tsx b/packages/editor/src/extensions/custom-image/components/toolbar/full-screen/modal.tsx
index 044607e9ecd..b1da541deaf 100644
--- a/packages/editor/src/extensions/custom-image/components/toolbar/full-screen/modal.tsx
+++ b/packages/editor/src/extensions/custom-image/components/toolbar/full-screen/modal.tsx
@@ -4,10 +4,9 @@
* See the LICENSE file for details.
*/
-import { Download, Minus } from "lucide-react";
+import { AddOutline, CloseOutline, DownloadOutline, MinusOutline, NewTabOutline } from "@makeplane/propel/icons";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import ReactDOM from "react-dom";
-import { NewTabIcon, PlusIcon, CloseIcon } from "@plane/propel/icons";
// plane imports
import { cn } from "@plane/utils";
@@ -219,7 +218,7 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
className="absolute top-10 right-10 grid size-8 place-items-center"
aria-label="Close image viewer"
>
-
+
-
+
{Math.round(100 * magnification)}%
{!isTouchDevice && (
@@ -278,7 +277,7 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
className="grid size-8 flex-shrink-0 place-items-center text-white/60 transition-colors duration-200 hover:text-white"
aria-label="Download image"
>
-
+
)}
{!isTouchDevice && (
@@ -288,7 +287,7 @@ function ImageFullScreenModalWithoutPortal(props: Props) {
className="grid size-8 flex-shrink-0 place-items-center text-white/60 transition-colors duration-200 hover:text-white"
aria-label="Open image in new tab"
>
-
+
)}
diff --git a/packages/editor/src/extensions/custom-image/components/toolbar/full-screen/root.tsx b/packages/editor/src/extensions/custom-image/components/toolbar/full-screen/root.tsx
index 79e116a3b8f..5baa86b4ccb 100644
--- a/packages/editor/src/extensions/custom-image/components/toolbar/full-screen/root.tsx
+++ b/packages/editor/src/extensions/custom-image/components/toolbar/full-screen/root.tsx
@@ -4,7 +4,7 @@
* See the LICENSE file for details.
*/
-import { Maximize } from "lucide-react";
+import { FullScreenOutline } from "@makeplane/propel/icons";
import { useEffect, useState } from "react";
// plane imports
import { Tooltip } from "@plane/propel/tooltip";
@@ -56,7 +56,7 @@ export function ImageFullScreenActionRoot(props: Props) {
className="grid h-full flex-shrink-0 place-items-center text-on-color/60 transition-colors hover:text-on-color"
aria-label="View image in full screen"
>
-
+
>
diff --git a/packages/editor/src/extensions/custom-image/components/uploader.tsx b/packages/editor/src/extensions/custom-image/components/uploader.tsx
index 13dd5a4ba5b..4e13930ddee 100644
--- a/packages/editor/src/extensions/custom-image/components/uploader.tsx
+++ b/packages/editor/src/extensions/custom-image/components/uploader.tsx
@@ -4,7 +4,7 @@
* See the LICENSE file for details.
*/
-import { ImageIcon, RotateCcw } from "lucide-react";
+import { ImageOutline, RefreshOutline } from "@makeplane/propel/icons";
import type { ChangeEvent } from "react";
import { useCallback, useEffect, useMemo, useRef } from "react";
// plane imports
@@ -235,7 +235,7 @@ export function CustomImageUploader(props: CustomImageUploaderProps) {
}
}}
>
-
+
{getDisplayMessage()}
{hasDuplicationFailed && editor.isEditable && (
)}
diff --git a/packages/editor/src/extensions/custom-image/utils.ts b/packages/editor/src/extensions/custom-image/utils.ts
index 5e7ed2de72e..fbeeb387c89 100644
--- a/packages/editor/src/extensions/custom-image/utils.ts
+++ b/packages/editor/src/extensions/custom-image/utils.ts
@@ -5,8 +5,8 @@
*/
import type { Editor } from "@tiptap/core";
-import { AlignCenter, AlignLeft, AlignRight } from "lucide-react";
-import type { LucideIcon } from "lucide-react";
+import { AlignCenterOutline, AlignLeftOutline, AlignRightOutline } from "@makeplane/propel/icons";
+import type { ComponentType, SVGProps } from "react";
// local imports
import { ECustomImageAttributeNames, ECustomImageStatus } from "./types";
import type { TCustomImageAlignment, Pixel, TCustomImageAttributes } from "./types";
@@ -41,22 +41,22 @@ export const ensurePixelString = (
export const IMAGE_ALIGNMENT_OPTIONS: {
label: string;
value: TCustomImageAlignment;
- icon: LucideIcon;
+ icon: ComponentType>;
}[] = [
{
label: "Left",
value: "left",
- icon: AlignLeft,
+ icon: AlignLeftOutline,
},
{
label: "Center",
value: "center",
- icon: AlignCenter,
+ icon: AlignCenterOutline,
},
{
label: "Right",
value: "right",
- icon: AlignRight,
+ icon: AlignRightOutline,
},
];
export const getImageBlockId = (id: string) => `editor-image-block-${id}`;
diff --git a/packages/editor/src/extensions/slash-commands/command-items-list.tsx b/packages/editor/src/extensions/slash-commands/command-items-list.tsx
index c1de43e5fe1..699813202d1 100644
--- a/packages/editor/src/extensions/slash-commands/command-items-list.tsx
+++ b/packages/editor/src/extensions/slash-commands/command-items-list.tsx
@@ -4,26 +4,25 @@
* See the LICENSE file for details.
*/
+import { Smile } from "lucide-react";
import {
- ALargeSmall,
- CaseSensitive,
- Code2,
- Heading1,
- Heading2,
- Heading3,
- Heading4,
- Heading5,
- Heading6,
- ImageIcon,
- List,
- ListOrdered,
- ListTodo,
- MessageSquareText,
- MinusSquare,
- Smile,
- Table,
- TextQuote,
-} from "lucide-react";
+ ChatOutline,
+ CodeOutline,
+ H1Outline,
+ H2Outline,
+ H3Outline,
+ H4Outline,
+ H5Outline,
+ H6Outline,
+ ImageOutline,
+ ListOutline,
+ MinusSquareOutline,
+ NumberedListOutline,
+ QuoteOutline,
+ TableEditorOutline,
+ TextOutline,
+ ToDoOutline,
+} from "@makeplane/propel/icons";
// constants
import { COLORS_LIST } from "@/constants/common";
// helpers
@@ -68,7 +67,7 @@ export const getSlashCommandFilteredSections =
title: "Text",
description: "Just start typing with plain text.",
searchTerms: ["p", "paragraph"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => setText(editor, range),
},
{
@@ -77,7 +76,7 @@ export const getSlashCommandFilteredSections =
title: "Heading 1",
description: "Big section heading.",
searchTerms: ["title", "big", "large"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleHeading(editor, 1, range),
},
{
@@ -86,7 +85,7 @@ export const getSlashCommandFilteredSections =
title: "Heading 2",
description: "Medium section heading.",
searchTerms: ["subtitle", "medium"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleHeading(editor, 2, range),
},
{
@@ -95,7 +94,7 @@ export const getSlashCommandFilteredSections =
title: "Heading 3",
description: "Small section heading.",
searchTerms: ["subtitle", "small"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleHeading(editor, 3, range),
},
{
@@ -104,7 +103,7 @@ export const getSlashCommandFilteredSections =
title: "Heading 4",
description: "Small section heading.",
searchTerms: ["subtitle", "small"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleHeading(editor, 4, range),
},
{
@@ -113,7 +112,7 @@ export const getSlashCommandFilteredSections =
title: "Heading 5",
description: "Small section heading.",
searchTerms: ["subtitle", "small"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleHeading(editor, 5, range),
},
{
@@ -122,7 +121,7 @@ export const getSlashCommandFilteredSections =
title: "Heading 6",
description: "Small section heading.",
searchTerms: ["subtitle", "small"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleHeading(editor, 6, range),
},
@@ -132,7 +131,7 @@ export const getSlashCommandFilteredSections =
title: "Numbered list",
description: "Create a numbered list.",
searchTerms: ["ordered"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleOrderedList(editor, range),
},
{
@@ -141,7 +140,7 @@ export const getSlashCommandFilteredSections =
title: "Bulleted list",
description: "Create a bulleted list.",
searchTerms: ["unordered", "point"],
- icon:
,
+ icon: ,
command: ({ editor, range }) => toggleBulletList(editor, range),
},
{
@@ -150,7 +149,7 @@ export const getSlashCommandFilteredSections =
title: "To-do list",
description: "Create a to-do list.",
searchTerms: ["todo", "task", "list", "check", "checkbox"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleTaskList(editor, range),
},
{
@@ -159,7 +158,7 @@ export const getSlashCommandFilteredSections =
title: "Table",
description: "Create a table",
searchTerms: ["table", "cell", "db", "data", "tabular"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => insertTableCommand(editor, range),
},
{
@@ -168,7 +167,7 @@ export const getSlashCommandFilteredSections =
title: "Quote",
description: "Capture a quote.",
searchTerms: ["blockquote"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleBlockquote(editor, range),
},
{
@@ -177,14 +176,14 @@ export const getSlashCommandFilteredSections =
title: "Code",
description: "Capture a code snippet.",
searchTerms: ["codeblock"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).toggleCodeBlock().run(),
},
{
commandKey: "callout",
key: "callout",
title: "Callout",
- icon: ,
+ icon: ,
description: "Insert callout",
searchTerms: ["callout", "comment", "message", "info", "alert"],
command: ({ editor, range }: CommandProps) => insertCallout(editor, range),
@@ -195,7 +194,7 @@ export const getSlashCommandFilteredSections =
title: "Divider",
description: "Visually divide blocks.",
searchTerms: ["line", "divider", "horizontal", "rule", "separate"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => editor.chain().focus().deleteRange(range).setHorizontalRule().run(),
},
{
@@ -221,7 +220,7 @@ export const getSlashCommandFilteredSections =
title: "Default",
description: "Change text color",
searchTerms: ["color", "text", "default"],
- icon: ,
+ icon: ,
command: ({ editor, range }) => toggleTextColor(undefined, editor, range),
},
...COLORS_LIST.map(
@@ -234,7 +233,7 @@ export const getSlashCommandFilteredSections =
searchTerms: ["color", "text", color.label],
icon: (
- ,
+ icon: ,
iconContainerStyle: {
borderRadius: "4px",
backgroundColor: "var(--background-color-surface-1)",
@@ -273,7 +272,7 @@ export const getSlashCommandFilteredSections =
title: color.label,
description: "Change background color",
searchTerms: ["color", "bg", "background", color.label],
- icon: ,
+ icon: ,
iconContainerStyle: {
borderRadius: "4px",
@@ -293,7 +292,7 @@ export const getSlashCommandFilteredSections =
commandKey: "image",
key: "image",
title: "Image",
- icon: ,
+ icon: ,
description: "Insert an image",
searchTerms: ["img", "photo", "picture", "media", "upload"],
command: ({ editor, range }: CommandProps) => insertImage({ editor, event: "insert", range }),
diff --git a/packages/editor/src/extensions/table/plugins/drag-handles/color-selector.tsx b/packages/editor/src/extensions/table/plugins/drag-handles/color-selector.tsx
index ae555bba82d..881129bcb52 100644
--- a/packages/editor/src/extensions/table/plugins/drag-handles/color-selector.tsx
+++ b/packages/editor/src/extensions/table/plugins/drag-handles/color-selector.tsx
@@ -6,9 +6,9 @@
import { Disclosure } from "@headlessui/react";
import type { Editor } from "@tiptap/core";
-import { Ban, Palette } from "lucide-react";
+import { Ban } from "lucide-react";
+import { ChevronRightOutline, PaletteOutline } from "@makeplane/propel/icons";
// plane imports
-import { ChevronRightIcon } from "@plane/propel/icons";
import { cn } from "@plane/utils";
// constants
import { COLORS_LIST } from "@/constants/common";
@@ -54,10 +54,10 @@ export function TableDragHandleDropdownColorSelector(props: Props) {
{({ open }) => (
<>
-
+
Color
-
-
+
{isDropdownOpen && (
diff --git a/packages/editor/src/extensions/table/plugins/drag-handles/column/dropdown.tsx b/packages/editor/src/extensions/table/plugins/drag-handles/column/dropdown.tsx
index f1c0ee3e7f8..2dc43bc840c 100644
--- a/packages/editor/src/extensions/table/plugins/drag-handles/column/dropdown.tsx
+++ b/packages/editor/src/extensions/table/plugins/drag-handles/column/dropdown.tsx
@@ -6,11 +6,17 @@
import type { Editor } from "@tiptap/core";
import { TableMap } from "@tiptap/pm/tables";
-import { ArrowLeft, ArrowRight, ToggleRight } from "lucide-react";
+import {
+ ArrowNarrowLeftOutline,
+ ArrowNarrowRightOutline,
+ CloseOutline,
+ CopyOutline,
+ DeleteOutline,
+ ToggleFilled,
+} from "@makeplane/propel/icons";
import type { LucideIcon } from "lucide-react";
// extensions
import type { ISvgIcons } from "@plane/propel/icons";
-import { CopyIcon, TrashIcon, CloseIcon } from "@plane/propel/icons";
import { findTable, getSelectedColumns } from "@/extensions/table/table/utilities/helpers";
// local imports
import { duplicateColumns } from "../actions";
@@ -25,19 +31,19 @@ const DROPDOWN_ITEMS: {
{
key: "insert-left",
label: "Insert left",
- icon: ArrowLeft,
+ icon: ArrowNarrowLeftOutline,
action: (editor) => editor.chain().focus().addColumnBefore().run(),
},
{
key: "insert-right",
label: "Insert right",
- icon: ArrowRight,
+ icon: ArrowNarrowRightOutline,
action: (editor) => editor.chain().focus().addColumnAfter().run(),
},
{
key: "duplicate",
label: "Duplicate",
- icon: CopyIcon,
+ icon: CopyOutline,
action: (editor) => {
const table = findTable(editor.state.selection);
if (!table) return;
@@ -52,13 +58,13 @@ const DROPDOWN_ITEMS: {
{
key: "clear-contents",
label: "Clear contents",
- icon: CloseIcon,
+ icon: CloseOutline,
action: (editor) => editor.chain().focus().clearSelectedCells().run(),
},
{
key: "delete",
label: "Delete",
- icon: TrashIcon,
+ icon: DeleteOutline,
action: (editor) => editor.chain().focus().deleteColumn().run(),
},
];
@@ -84,7 +90,7 @@ export function ColumnOptionsDropdown(props: Props) {
}}
>
Header column
-
+
diff --git a/packages/editor/src/extensions/table/plugins/drag-handles/row/drag-handle.tsx b/packages/editor/src/extensions/table/plugins/drag-handles/row/drag-handle.tsx
index ef038f99518..d970b016f57 100644
--- a/packages/editor/src/extensions/table/plugins/drag-handles/row/drag-handle.tsx
+++ b/packages/editor/src/extensions/table/plugins/drag-handles/row/drag-handle.tsx
@@ -17,7 +17,7 @@ import {
useRole,
} from "@floating-ui/react";
import type { Editor } from "@tiptap/core";
-import { Ellipsis } from "lucide-react";
+import { MoreHorizontalOutline } from "@makeplane/propel/icons";
import { useCallback, useEffect, useRef, useState } from "react";
// plane imports
import { cn } from "@plane/utils";
@@ -234,7 +234,7 @@ export function RowDragHandle(props: RowDragHandleProps) {
"hover:bg-layer-1-hover": !isDropdownOpen,
})}
>
-
+
{isDropdownOpen && (
diff --git a/packages/editor/src/extensions/table/plugins/drag-handles/row/dropdown.tsx b/packages/editor/src/extensions/table/plugins/drag-handles/row/dropdown.tsx
index 6359adffac4..1ad0b762034 100644
--- a/packages/editor/src/extensions/table/plugins/drag-handles/row/dropdown.tsx
+++ b/packages/editor/src/extensions/table/plugins/drag-handles/row/dropdown.tsx
@@ -6,11 +6,17 @@
import type { Editor } from "@tiptap/core";
import { TableMap } from "@tiptap/pm/tables";
-import { ArrowDown, ArrowUp, ToggleRight } from "lucide-react";
+import {
+ ArrowDownOutline,
+ CloseOutline,
+ CopyOutline,
+ DeleteOutline,
+ ToggleFilled,
+ TopArrowOutline,
+} from "@makeplane/propel/icons";
import type { LucideIcon } from "lucide-react";
// extensions
import type { ISvgIcons } from "@plane/propel/icons";
-import { CopyIcon, TrashIcon, CloseIcon } from "@plane/propel/icons";
import { findTable, getSelectedRows } from "@/extensions/table/table/utilities/helpers";
// local imports
import { duplicateRows } from "../actions";
@@ -25,19 +31,19 @@ const DROPDOWN_ITEMS: {
{
key: "insert-above",
label: "Insert above",
- icon: ArrowUp,
+ icon: TopArrowOutline,
action: (editor) => editor.chain().focus().addRowBefore().run(),
},
{
key: "insert-below",
label: "Insert below",
- icon: ArrowDown,
+ icon: ArrowDownOutline,
action: (editor) => editor.chain().focus().addRowAfter().run(),
},
{
key: "duplicate",
label: "Duplicate",
- icon: CopyIcon,
+ icon: CopyOutline,
action: (editor) => {
const table = findTable(editor.state.selection);
if (!table) return;
@@ -52,13 +58,13 @@ const DROPDOWN_ITEMS: {
{
key: "clear-contents",
label: "Clear contents",
- icon: CloseIcon,
+ icon: CloseOutline,
action: (editor) => editor.chain().focus().clearSelectedCells().run(),
},
{
key: "delete",
label: "Delete",
- icon: TrashIcon,
+ icon: DeleteOutline,
action: (editor) => editor.chain().focus().deleteRow().run(),
},
];
@@ -84,7 +90,7 @@ export function RowOptionsDropdown(props: Props) {
}}
>
Header row
-
+
diff --git a/packages/propel/package.json b/packages/propel/package.json
index f98add27732..6226ec3ea9b 100644
--- a/packages/propel/package.json
+++ b/packages/propel/package.json
@@ -64,6 +64,7 @@
},
"dependencies": {
"@base-ui-components/react": "catalog:",
+ "@makeplane/propel": "catalog:",
"@plane/constants": "workspace:*",
"@plane/hooks": "workspace:*",
"@plane/types": "workspace:*",
diff --git a/packages/propel/src/accordion/accordion.tsx b/packages/propel/src/accordion/accordion.tsx
index 1eebc748d54..ac5071cf6d9 100644
--- a/packages/propel/src/accordion/accordion.tsx
+++ b/packages/propel/src/accordion/accordion.tsx
@@ -7,7 +7,7 @@
import * as React from "react";
import { Accordion as BaseAccordion } from "@base-ui-components/react";
-import { PlusIcon } from "../icons";
+import { AddOutline } from "@makeplane/propel/icons";
export interface AccordionRootProps {
defaultValue?: string[];
@@ -55,7 +55,7 @@ function AccordionItem({ value, disabled, className = "", children }: AccordionI
function AccordionTrigger({
className = "",
- icon = ,
+ icon = ,
iconClassName = "",
children,
asChild = false,
diff --git a/packages/propel/src/calendar/root.tsx b/packages/propel/src/calendar/root.tsx
index eb962064be6..13f18b3f9f6 100644
--- a/packages/propel/src/calendar/root.tsx
+++ b/packages/propel/src/calendar/root.tsx
@@ -6,7 +6,7 @@
import * as React from "react";
import { DayPicker } from "react-day-picker";
-import { ChevronLeftIcon } from "../icons/arrows/chevron-left";
+import { ChevronLeftOutline } from "@makeplane/propel/icons";
import { cn } from "../utils";
@@ -24,7 +24,7 @@ export function Calendar({ className, showOutsideDays = true, ...props }: Calend
weekStartsOn={props.weekStartsOn}
components={{
Chevron: ({ className, ...props }) => (
-
Click to toggle
-
+
@@ -78,7 +78,7 @@ export const Controlled: Story = {
setIsOpen(!isOpen)} className="w-96">
Controlled Collapsible
-
+
@@ -99,7 +99,7 @@ export const NestedContent: Story = {
setIsOpen(!isOpen)} className="w-96">
Collapsible with Nested Content
-
+
@@ -126,7 +126,7 @@ export const CustomStyling: Story = {
setIsOpen(!isOpen)} className="w-96">
Custom Styled Trigger
-
+
@@ -145,7 +145,7 @@ export const MultipleCollapsibles: Story = {
First Item
-
+
@@ -157,7 +157,7 @@ export const MultipleCollapsibles: Story = {
Second Item
-
+
@@ -169,7 +169,7 @@ export const MultipleCollapsibles: Story = {
Third Item
-
+
diff --git a/packages/propel/src/combobox/combobox.stories.tsx b/packages/propel/src/combobox/combobox.stories.tsx
index 86d898154ab..2db76f698d0 100644
--- a/packages/propel/src/combobox/combobox.stories.tsx
+++ b/packages/propel/src/combobox/combobox.stories.tsx
@@ -6,9 +6,8 @@
import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
-import { ChevronsUpDown } from "lucide-react";
+import { ChevronExpandOutline, TickOutline } from "@makeplane/propel/icons";
import { useArgs } from "storybook/preview-api";
-import { CheckIcon } from "../icons";
import { Combobox } from "./combobox";
const frameworks = [
@@ -46,7 +45,7 @@ const meta = {
setValue(v as string)}>
{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}
-
+
{frameworks.map((framework) => (
@@ -55,7 +54,7 @@ const meta = {
value={framework.value}
className="flex items-center gap-2 px-4 py-2"
>
- {value === framework.value && }
+ {value === framework.value && }
{framework.label}
))}
@@ -77,7 +76,7 @@ export const WithoutSearch: Story = {
setValue(v as string)}>
{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}
-
+
{frameworks.map((framework) => (
@@ -86,7 +85,7 @@ export const WithoutSearch: Story = {
value={framework.value}
className="flex items-center gap-2 px-4 py-2"
>
- {value === framework.value && }
+ {value === framework.value && }
{framework.label}
))}
@@ -104,7 +103,7 @@ export const MultiSelect: Story = {
setValue(v as string[])}>
{value.length > 0 ? `${value.length} selected` : "Select frameworks..."}
-
+
{frameworks.map((framework) => (
@@ -113,7 +112,7 @@ export const MultiSelect: Story = {
value={framework.value}
className="flex items-center gap-2 px-4 py-2"
>
- {value.includes(framework.value) && }
+ {value.includes(framework.value) && }
{framework.label}
))}
@@ -134,7 +133,7 @@ export const MultiSelectWithLimit: Story = {
{value.length > 0 ? `${value.length}/3 selected` : "Select up to 3 frameworks..."}
-
+
{frameworks.map((framework) => (
@@ -143,7 +142,7 @@ export const MultiSelectWithLimit: Story = {
value={framework.value}
className="flex items-center gap-2 px-4 py-2"
>
- {value.includes(framework.value) && }
+ {value.includes(framework.value) && }
{framework.label}
))}
@@ -163,7 +162,7 @@ export const Disabled: Story = {
setValue(v as string)}>
{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}
-
+
{frameworks.map((framework) => (
@@ -172,7 +171,7 @@ export const Disabled: Story = {
value={framework.value}
className="flex items-center gap-2 px-4 py-2"
>
- {value === framework.value && }
+ {value === framework.value && }
{framework.label}
))}
@@ -189,7 +188,7 @@ export const DisabledOptions: Story = {
setValue(v as string)}>
{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}
-
+
{frameworks.map((framework) => (
@@ -199,7 +198,7 @@ export const DisabledOptions: Story = {
disabled={framework.value === "angular" || framework.value === "svelte"}
className="flex items-center gap-2 px-4 py-2"
>
- {value === framework.value && }
+ {value === framework.value && }
{framework.label}
))}
@@ -216,7 +215,7 @@ export const CustomMaxHeight: Story = {
setValue(v as string)}>
{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}
-
+
{frameworks.map((framework) => (
@@ -225,7 +224,7 @@ export const CustomMaxHeight: Story = {
value={framework.value}
className="flex items-center gap-2 px-4 py-2"
>
- {value === framework.value && }
+ {value === framework.value && }
{framework.label}
))}
@@ -242,7 +241,7 @@ export const CustomEmptyMessage: Story = {
setValue(v as string)}>
{value ? frameworks.find((f) => f.value === value)?.label : "Select framework..."}
-
+
- {value === framework.value && }
+ {value === framework.value && }
{framework.label}
))}
diff --git a/packages/propel/src/combobox/combobox.tsx b/packages/propel/src/combobox/combobox.tsx
index 4f680078aa9..c4e83c0568d 100644
--- a/packages/propel/src/combobox/combobox.tsx
+++ b/packages/propel/src/combobox/combobox.tsx
@@ -6,7 +6,7 @@
import * as React from "react";
import { Combobox as BaseCombobox } from "@base-ui-components/react/combobox";
-import { SearchIcon } from "../icons";
+import { SearchOutline } from "@makeplane/propel/icons";
import { cn } from "../utils/classname";
// Type definitions
@@ -181,7 +181,7 @@ function ComboboxOptions({
{showSearch && (
-
+
-
+
Documents
-
+
Downloads
-
+
README.md
-
+
package.json
@@ -85,21 +85,21 @@ export const WithCategories: Story = {
User
-
+
Profile
-
+
Settings
Files
-
+
Open Folder
-
+
New File
@@ -148,15 +148,15 @@ export const WithoutSearch: Story = {
-
+
Profile
-
+
Settings
-
+
Files
diff --git a/packages/propel/src/command/command.tsx b/packages/propel/src/command/command.tsx
index d87b332a0f0..3d9496930cb 100644
--- a/packages/propel/src/command/command.tsx
+++ b/packages/propel/src/command/command.tsx
@@ -6,7 +6,7 @@
import * as React from "react";
import { Command as CommandPrimitive } from "cmdk";
-import { SearchIcon } from "../icons";
+import { SearchOutline } from "@makeplane/propel/icons";
import { cn } from "../utils/classname";
function CommandComponent({ className, ...props }: React.ComponentProps) {
@@ -19,7 +19,7 @@ function CommandInput({ className, ...props }: React.ComponentProps
-
+
);
diff --git a/packages/propel/src/context-menu/context-menu.stories.tsx b/packages/propel/src/context-menu/context-menu.stories.tsx
index 7ce5f3ece61..c7069a0dcc4 100644
--- a/packages/propel/src/context-menu/context-menu.stories.tsx
+++ b/packages/propel/src/context-menu/context-menu.stories.tsx
@@ -5,9 +5,16 @@
*/
import type { Meta, StoryObj } from "@storybook/react-vite";
-import { Download, Edit, Share, Star, Archive } from "lucide-react";
-import { CopyIcon, TrashIcon } from "../icons";
-import { ChevronRightIcon } from "../icons/arrows/chevron-right";
+import {
+ ArchiveOutline,
+ ChevronRightOutline,
+ CopyOutline,
+ DeleteOutline,
+ DownloadOutline,
+ EditOutline,
+ ShareOutline,
+ StarOutline,
+} from "@makeplane/propel/icons";
import { ContextMenu } from "./context-menu";
// cannot use satisfies here because base-ui does not have portable types.
@@ -70,24 +77,24 @@ export const WithIcons: Story = {
-
+
Copy
-
+
Edit
-
+
Download
-
+
Share
-
+
Delete
@@ -109,19 +116,19 @@ export const WithSubmenus: Story = {
-
+
Copy
-
+
Edit
-
+
Share
-
+
@@ -133,7 +140,7 @@ export const WithSubmenus: Story = {
-
+
Delete
@@ -155,24 +162,24 @@ export const DisabledItems: Story = {
-
+
Copy
-
+
Edit (Disabled)
-
+
Download
-
+
Share (Disabled)
-
+
Delete
@@ -202,24 +209,24 @@ export const OnFileCard: Story = {
-
+
Download
-
+
Copy Link
-
+
Add to Favorites
-
+
Archive
-
+
Delete
@@ -241,15 +248,15 @@ export const OnImage: Story = {
-
+
Save Image
-
+
Copy Image
-
+
Copy Image URL
@@ -277,11 +284,11 @@ export const OnText: Story = {
-
+
Copy
-
+
Edit
@@ -310,7 +317,7 @@ export const NestedSubmenus: Story = {
Import
-
+
@@ -319,7 +326,7 @@ export const NestedSubmenus: Story = {
From Cloud
-
+
@@ -334,7 +341,7 @@ export const NestedSubmenus: Story = {
-
+
Delete
@@ -356,23 +363,23 @@ export const WithKeyboardShortcuts: Story = {
-
+
Copy
⌘C
-
+
Edit
⌘E
-
+
Download
⌘D
-
+
Delete
⌘⌫
diff --git a/packages/propel/src/dialog/dialog.stories.tsx b/packages/propel/src/dialog/dialog.stories.tsx
index fb9b17bcab5..36281bf5d8b 100644
--- a/packages/propel/src/dialog/dialog.stories.tsx
+++ b/packages/propel/src/dialog/dialog.stories.tsx
@@ -7,7 +7,7 @@
import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { useArgs } from "storybook/preview-api";
-import { CloseIcon } from "../icons/actions/close-icon";
+import { CloseOutline } from "@makeplane/propel/icons";
import { Dialog, EDialogWidth } from "./root";
const meta = {
@@ -208,7 +208,7 @@ export const WithCloseButton: Story = {
Dialog with Close Button
diff --git a/packages/propel/src/emoji-reaction/emoji-reaction-picker.stories.tsx b/packages/propel/src/emoji-reaction/emoji-reaction-picker.stories.tsx
index 9da60797550..537473966f7 100644
--- a/packages/propel/src/emoji-reaction/emoji-reaction-picker.stories.tsx
+++ b/packages/propel/src/emoji-reaction/emoji-reaction-picker.stories.tsx
@@ -6,7 +6,7 @@
import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
-import { SmilePlus } from "lucide-react";
+import { ReactionOutline } from "@makeplane/propel/icons";
import { stringToEmoji } from "../emoji-icon-picker";
import type { EmojiReactionType } from "./emoji-reaction";
import { EmojiReactionGroup } from "./emoji-reaction";
@@ -44,7 +44,7 @@ export const Default: Story = {
closeOnSelect
label={
- {selectedEmoji ? stringToEmoji(selectedEmoji) : }
+ {selectedEmoji ? stringToEmoji(selectedEmoji) : }
}
/>
@@ -76,7 +76,7 @@ export const WithCustomLabel: Story = {
closeOnSelect
label={
}
@@ -141,7 +141,7 @@ export const InlineReactions: Story = {
closeOnSelect
label={
}
/>
@@ -172,7 +172,7 @@ export const DifferentPlacements: Story = {
handleToggle={setIsOpen1}
onChange={() => {}}
placement="bottom-start"
- label={}
+ label={}
/>
@@ -182,7 +182,7 @@ export const DifferentPlacements: Story = {
handleToggle={setIsOpen2}
onChange={() => {}}
placement="bottom-end"
- label={}
+ label={}
/>
@@ -192,7 +192,7 @@ export const DifferentPlacements: Story = {
handleToggle={setIsOpen3}
onChange={() => {}}
placement="top-start"
- label={}
+ label={}
/>
@@ -202,7 +202,7 @@ export const DifferentPlacements: Story = {
handleToggle={setIsOpen4}
onChange={() => {}}
placement="top-end"
- label={}
+ label={}
/>
@@ -385,7 +385,7 @@ export const InMessageContext: Story = {
closeOnSelect
label={
}
/>
diff --git a/packages/propel/src/emoji-reaction/emoji-reaction.tsx b/packages/propel/src/emoji-reaction/emoji-reaction.tsx
index b71b6230404..c5898285e72 100644
--- a/packages/propel/src/emoji-reaction/emoji-reaction.tsx
+++ b/packages/propel/src/emoji-reaction/emoji-reaction.tsx
@@ -7,7 +7,7 @@
import * as React from "react";
import { AnimatedCounter } from "../animated-counter";
import { stringToEmoji } from "../emoji-icon-picker";
-import { AddReactionIcon } from "../icons";
+import { ReactionOutline } from "@makeplane/propel/icons";
import { Tooltip } from "../tooltip";
import { cn } from "../utils";
import { IconButton } from "../icon-button";
@@ -110,7 +110,7 @@ const EmojiReactionButton = React.forwardRef(function EmojiReactionButton(
alert("Profile")}>
-
+
Profile
alert("Settings")}>
-
+
Settings
alert("Messages")}>
-
+
Messages
alert("Logout")}>
-
+
Logout
@@ -213,14 +220,14 @@ export const ComplexMenu: Story = {