diff --git a/.gitignore b/.gitignore index 053db6d29e5..4a756d030f7 100644 --- a/.gitignore +++ b/.gitignore @@ -102,5 +102,6 @@ dev-editor storybook-static CLAUDE.md +AGENTS.md -temp/ \ No newline at end of file +temp/ diff --git a/apps/space/core/components/issues/issue-layouts/properties/due-date.tsx b/apps/space/core/components/issues/issue-layouts/properties/due-date.tsx index 2f1669837ed..71afb2489b1 100644 --- a/apps/space/core/components/issues/issue-layouts/properties/due-date.tsx +++ b/apps/space/core/components/issues/issue-layouts/properties/due-date.tsx @@ -1,7 +1,7 @@ "use client"; import { observer } from "mobx-react"; -import { CalendarCheck2 } from "lucide-react"; +import { DueDatePropertyIcon } from "@plane/propel/icons"; import { Tooltip } from "@plane/propel/tooltip"; import { cn } from "@plane/utils"; // helpers @@ -33,7 +33,7 @@ export const IssueBlockDate = observer((props: Props) => { "border-[0.5px] border-custom-border-300": shouldShowBorder, })} > - + {formattedDate ? formattedDate : "No Date"} diff --git a/apps/space/core/components/issues/issue-layouts/properties/labels.tsx b/apps/space/core/components/issues/issue-layouts/properties/labels.tsx index 12ed76d3a59..9e4b80fff55 100644 --- a/apps/space/core/components/issues/issue-layouts/properties/labels.tsx +++ b/apps/space/core/components/issues/issue-layouts/properties/labels.tsx @@ -1,7 +1,7 @@ "use client"; import { observer } from "mobx-react"; -import { Tags } from "lucide-react"; +import { LabelPropertyIcon } from "@plane/propel/icons"; // plane imports import { Tooltip } from "@plane/propel/tooltip"; // hooks @@ -25,7 +25,7 @@ export const IssueBlockLabels = observer(({ labelIds, shouldShowLabel = false }:
- + {shouldShowLabel && No Labels}
diff --git a/apps/space/core/components/issues/issue-layouts/properties/member.tsx b/apps/space/core/components/issues/issue-layouts/properties/member.tsx index a5baae8a3b3..6b1bce1f95a 100644 --- a/apps/space/core/components/issues/issue-layouts/properties/member.tsx +++ b/apps/space/core/components/issues/issue-layouts/properties/member.tsx @@ -3,7 +3,7 @@ import { observer } from "mobx-react"; // icons import type { LucideIcon } from "lucide-react"; -import { Users } from "lucide-react"; +import { MembersPropertyIcon } from "@plane/propel/icons"; // plane ui import { Avatar, AvatarGroup } from "@plane/ui"; // plane utils @@ -49,7 +49,11 @@ export const ButtonAvatars: React.FC = observer((props: AvatarProps } } - return Icon ? : ; + return Icon ? ( + + ) : ( + + ); }); export const IssueBlockMembers = observer(({ memberIds, shouldShowBorder = true }: Props) => { diff --git a/apps/space/core/components/issues/navbar/layout-icon.tsx b/apps/space/core/components/issues/navbar/layout-icon.tsx index e9aed2b2679..2d5a5db5a6a 100644 --- a/apps/space/core/components/issues/navbar/layout-icon.tsx +++ b/apps/space/core/components/issues/navbar/layout-icon.tsx @@ -1,13 +1,22 @@ -import type { LucideProps } from "lucide-react"; -import { List, Kanban } from "lucide-react"; import type { TIssueLayout } from "@plane/constants"; +import { ListLayoutIcon, BoardLayoutIcon } from "@plane/propel/icons"; +import type { ISvgIcons } from "@plane/propel/icons"; + +export const IssueLayoutIcon = ({ + layout, + size, + ...props +}: { layout: TIssueLayout; size?: number } & Omit) => { + const iconProps = { + ...props, + ...(size && { width: size, height: size }), + }; -export const IssueLayoutIcon = ({ layout, ...props }: { layout: TIssueLayout } & LucideProps) => { switch (layout) { case "list": - return ; + return ; case "kanban": - return ; + return ; default: return null; } diff --git a/apps/space/core/components/issues/peek-overview/issue-properties.tsx b/apps/space/core/components/issues/peek-overview/issue-properties.tsx index 6ea937d19b8..94507922a59 100644 --- a/apps/space/core/components/issues/peek-overview/issue-properties.tsx +++ b/apps/space/core/components/issues/peek-overview/issue-properties.tsx @@ -2,10 +2,9 @@ import { observer } from "mobx-react"; import { useParams } from "next/navigation"; -import { CalendarCheck2, Signal } from "lucide-react"; // plane imports import { useTranslation } from "@plane/i18n"; -import { DoubleCircleIcon, StateGroupIcon } from "@plane/propel/icons"; +import { StatePropertyIcon, StateGroupIcon, PriorityPropertyIcon, DueDatePropertyIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { cn, getIssuePriorityFilters } from "@plane/utils"; // components @@ -66,7 +65,7 @@ export const PeekOverviewIssueProperties: React.FC = observer(({ issueDet
- + State
@@ -77,7 +76,7 @@ export const PeekOverviewIssueProperties: React.FC = observer(({ issueDet
- + Priority
@@ -106,7 +105,7 @@ export const PeekOverviewIssueProperties: React.FC = observer(({ issueDet
- + Due date
@@ -116,7 +115,7 @@ export const PeekOverviewIssueProperties: React.FC = observer(({ issueDet "text-red-500": shouldHighlightIssueDueDate(issueDetails.target_date, state?.group), })} > - + {renderFormattedDate(issueDetails.target_date)}
) : ( diff --git a/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/mobile-header.tsx b/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/mobile-header.tsx index f56a3207991..747e65c1660 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/mobile-header.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(detail)/mobile-header.tsx @@ -4,10 +4,11 @@ import { useCallback, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons -import { Calendar, ChevronDown, Kanban, List } from "lucide-react"; +import { ChevronDown } from "lucide-react"; // plane imports import { EIssueFilterType, ISSUE_LAYOUTS, ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; +import { CalendarLayoutIcon, BoardLayoutIcon, ListLayoutIcon } from "@plane/propel/icons"; import type { IIssueDisplayFilterOptions, IIssueDisplayProperties, EIssueLayoutTypes } from "@plane/types"; import { EIssuesStoreType } from "@plane/types"; import { CustomMenu } from "@plane/ui"; @@ -21,9 +22,9 @@ import { useIssues } from "@/hooks/store/use-issues"; import { useProject } from "@/hooks/store/use-project"; const SUPPORTED_LAYOUTS = [ - { key: "list", titleTranslationKey: "issue.layouts.list", icon: List }, - { key: "kanban", titleTranslationKey: "issue.layouts.kanban", icon: Kanban }, - { key: "calendar", titleTranslationKey: "issue.layouts.calendar", icon: Calendar }, + { key: "list", titleTranslationKey: "issue.layouts.list", icon: ListLayoutIcon }, + { key: "kanban", titleTranslationKey: "issue.layouts.kanban", icon: BoardLayoutIcon }, + { key: "calendar", titleTranslationKey: "issue.layouts.calendar", icon: CalendarLayoutIcon }, ]; export const CycleIssuesMobileHeader = observer(() => { diff --git a/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(list)/mobile-header.tsx b/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(list)/mobile-header.tsx index 97838d349c1..4c8e4e9c49b 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(list)/mobile-header.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/cycles/(list)/mobile-header.tsx @@ -1,9 +1,10 @@ "use client"; +import type React from "react"; import { observer } from "mobx-react"; // ui -import { GanttChartSquare, LayoutGrid, List } from "lucide-react"; -import type { LucideIcon } from "lucide-react"; +import type { ISvgIcons } from "@plane/propel/icons"; +import { TimelineLayoutIcon, GridLayoutIcon, ListLayoutIcon } from "@plane/propel/icons"; // plane package imports import type { TCycleLayoutOptions } from "@plane/types"; import { CustomMenu } from "@plane/ui"; @@ -13,22 +14,22 @@ import { useProject } from "@/hooks/store/use-project"; const CYCLE_VIEW_LAYOUTS: { key: TCycleLayoutOptions; - icon: LucideIcon; + icon: React.FC; title: string; }[] = [ { key: "list", - icon: List, + icon: ListLayoutIcon, title: "List layout", }, { key: "board", - icon: LayoutGrid, + icon: GridLayoutIcon, title: "Gallery layout", }, { key: "gantt", - icon: GanttChartSquare, + icon: TimelineLayoutIcon, title: "Timeline layout", }, ]; @@ -45,7 +46,7 @@ export const CyclesListMobileHeader = observer(() => { // placement="bottom-start" customButton={ - + Layout } diff --git a/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/mobile-header.tsx b/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/mobile-header.tsx index 77b0e2b244f..ae450f5de67 100644 --- a/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/mobile-header.tsx +++ b/apps/web/app/(all)/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/modules/(detail)/mobile-header.tsx @@ -4,10 +4,11 @@ import { useCallback, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons -import { Calendar, ChevronDown, Kanban, List } from "lucide-react"; +import { ChevronDown } from "lucide-react"; // plane imports import { EIssueFilterType, ISSUE_LAYOUTS, ISSUE_DISPLAY_FILTERS_BY_PAGE } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; +import { CalendarLayoutIcon, BoardLayoutIcon, ListLayoutIcon } from "@plane/propel/icons"; import type { IIssueDisplayFilterOptions, IIssueDisplayProperties, EIssueLayoutTypes } from "@plane/types"; import { EIssuesStoreType } from "@plane/types"; import { CustomMenu } from "@plane/ui"; @@ -21,9 +22,9 @@ import { useModule } from "@/hooks/store/use-module"; import { useProject } from "@/hooks/store/use-project"; const SUPPORTED_LAYOUTS = [ - { key: "list", i18n_title: "issue.layouts.list", icon: List }, - { key: "kanban", i18n_title: "issue.layouts.kanban", icon: Kanban }, - { key: "calendar", i18n_title: "issue.layouts.calendar", icon: Calendar }, + { key: "list", i18n_title: "issue.layouts.list", icon: ListLayoutIcon }, + { key: "kanban", i18n_title: "issue.layouts.kanban", icon: BoardLayoutIcon }, + { key: "calendar", i18n_title: "issue.layouts.calendar", icon: CalendarLayoutIcon }, ]; export const ModuleIssuesMobileHeader = observer(() => { diff --git a/apps/web/ce/components/issues/issue-layouts/utils.tsx b/apps/web/ce/components/issues/issue-layouts/utils.tsx index 61a32c4fd90..2d2a1deb8c1 100644 --- a/apps/web/ce/components/issues/issue-layouts/utils.tsx +++ b/apps/web/ce/components/issues/issue-layouts/utils.tsx @@ -1,19 +1,18 @@ import type { FC } from "react"; -import { - CalendarCheck2, - CalendarClock, - CalendarDays, - LayersIcon, - Link2, - Paperclip, - Signal, - Tag, - Triangle, - Users, -} from "lucide-react"; +import { CalendarDays, LayersIcon, Link2, Paperclip } from "lucide-react"; // types import type { ISvgIcons } from "@plane/propel/icons"; -import { CycleIcon, DoubleCircleIcon, ModuleIcon } from "@plane/propel/icons"; +import { + CycleIcon, + StatePropertyIcon, + ModuleIcon, + MembersPropertyIcon, + DueDatePropertyIcon, + EstimatePropertyIcon, + LabelPropertyIcon, + PriorityPropertyIcon, + StartDatePropertyIcon, +} from "@plane/propel/icons"; import type { IGroupByColumn, IIssueDisplayProperties, TGetColumns, TSpreadsheetColumn } from "@plane/types"; // components import { @@ -66,16 +65,16 @@ export const getScopeMemberIds = ({ isWorkspaceLevel, projectId }: TGetColumns): export const getTeamProjectColumns = (): IGroupByColumn[] | undefined => undefined; export const SpreadSheetPropertyIconMap: Record> = { - Users: Users, + MembersPropertyIcon: MembersPropertyIcon, CalenderDays: CalendarDays, - CalenderCheck2: CalendarCheck2, - Triangle: Triangle, - Tag: Tag, + DueDatePropertyIcon: DueDatePropertyIcon, + EstimatePropertyIcon: EstimatePropertyIcon, + LabelPropertyIcon: LabelPropertyIcon, ModuleIcon: ModuleIcon, ContrastIcon: CycleIcon, - Signal: Signal, - CalendarClock: CalendarClock, - DoubleCircleIcon: DoubleCircleIcon, + PriorityPropertyIcon: PriorityPropertyIcon, + StartDatePropertyIcon: StartDatePropertyIcon, + StatePropertyIcon: StatePropertyIcon, Link2: Link2, Paperclip: Paperclip, LayersIcon: LayersIcon, diff --git a/apps/web/ce/components/relations/index.tsx b/apps/web/ce/components/relations/index.tsx index 2a7ebf0ebc8..f9d72944c23 100644 --- a/apps/web/ce/components/relations/index.tsx +++ b/apps/web/ce/components/relations/index.tsx @@ -1,5 +1,5 @@ -import { CircleDot, CopyPlus, XCircle } from "lucide-react"; -import { RelatedIcon } from "@plane/propel/icons"; +import { CircleDot, XCircle } from "lucide-react"; +import { RelatedIcon, DuplicatePropertyIcon } from "@plane/propel/icons"; import type { TRelationObject } from "@/components/issues/issue-detail-widgets/relations"; import type { TIssueRelationTypes } from "../../types"; @@ -17,7 +17,7 @@ export const ISSUE_RELATION_OPTIONS: Record , + icon: (size) => , placeholder: "None", }, blocked_by: { diff --git a/apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx b/apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx index edc6f54fa6f..90ad9394dbc 100644 --- a/apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx +++ b/apps/web/ce/hooks/work-item-filters/use-work-item-filters-config.tsx @@ -1,23 +1,19 @@ import { useCallback, useMemo } from "react"; -import { - AtSign, - Briefcase, - Calendar, - CalendarCheck2, - CalendarClock, - CircleUserRound, - SignalHigh, - Tag, - Users, -} from "lucide-react"; +import { AtSign, Briefcase, Calendar } from "lucide-react"; // plane imports import { CycleGroupIcon, CycleIcon, ModuleIcon, - DoubleCircleIcon, + StatePropertyIcon, PriorityIcon, StateGroupIcon, + MembersPropertyIcon, + LabelPropertyIcon, + StartDatePropertyIcon, + DueDatePropertyIcon, + UserCirclePropertyIcon, + PriorityPropertyIcon, } from "@plane/propel/icons"; import type { ICycle, @@ -149,7 +145,7 @@ export const useWorkItemFiltersConfig = (props: TUseWorkItemFiltersConfigProps): () => getStateGroupFilterConfig("state_group")({ isEnabled: isFilterEnabled("state_group"), - filterIcon: DoubleCircleIcon, + filterIcon: StatePropertyIcon, getOptionIcon: (stateGroupKey) => , ...operatorConfigs, }), @@ -161,7 +157,7 @@ export const useWorkItemFiltersConfig = (props: TUseWorkItemFiltersConfigProps): () => getStateFilterConfig("state_id")({ isEnabled: isFilterEnabled("state_id") && workItemStates !== undefined, - filterIcon: DoubleCircleIcon, + filterIcon: StatePropertyIcon, getOptionIcon: (state) => , states: workItemStates ?? [], ...operatorConfigs, @@ -174,7 +170,7 @@ export const useWorkItemFiltersConfig = (props: TUseWorkItemFiltersConfigProps): () => getLabelFilterConfig("label_id")({ isEnabled: isFilterEnabled("label_id") && workItemLabels !== undefined, - filterIcon: Tag, + filterIcon: LabelPropertyIcon, labels: workItemLabels ?? [], getOptionIcon: (color) => ( @@ -215,7 +211,7 @@ export const useWorkItemFiltersConfig = (props: TUseWorkItemFiltersConfigProps): () => getAssigneeFilterConfig("assignee_id")({ isEnabled: isFilterEnabled("assignee_id") && members !== undefined, - filterIcon: Users, + filterIcon: MembersPropertyIcon, members: members ?? [], getOptionIcon: (memberDetails) => ( getCreatedByFilterConfig("created_by_id")({ isEnabled: isFilterEnabled("created_by_id") && members !== undefined, - filterIcon: CircleUserRound, + filterIcon: UserCirclePropertyIcon, members: members ?? [], getOptionIcon: (memberDetails) => ( getSubscriberFilterConfig("subscriber_id")({ isEnabled: isFilterEnabled("subscriber_id") && members !== undefined, - filterIcon: Users, + filterIcon: MembersPropertyIcon, members: members ?? [], getOptionIcon: (memberDetails) => ( getPriorityFilterConfig("priority")({ isEnabled: isFilterEnabled("priority"), - filterIcon: SignalHigh, + filterIcon: PriorityPropertyIcon, getOptionIcon: (priority) => , ...operatorConfigs, }), @@ -307,7 +303,7 @@ export const useWorkItemFiltersConfig = (props: TUseWorkItemFiltersConfigProps): () => getStartDateFilterConfig("start_date")({ isEnabled: true, - filterIcon: CalendarClock, + filterIcon: StartDatePropertyIcon, ...operatorConfigs, }), [operatorConfigs] @@ -318,7 +314,7 @@ export const useWorkItemFiltersConfig = (props: TUseWorkItemFiltersConfigProps): () => getTargetDateFilterConfig("target_date")({ isEnabled: true, - filterIcon: CalendarCheck2, + filterIcon: DueDatePropertyIcon, ...operatorConfigs, }), [operatorConfigs] diff --git a/apps/web/core/components/automation/auto-close-automation.tsx b/apps/web/core/components/automation/auto-close-automation.tsx index f493f16ae7b..19e294a22d5 100644 --- a/apps/web/core/components/automation/auto-close-automation.tsx +++ b/apps/web/core/components/automation/auto-close-automation.tsx @@ -15,7 +15,7 @@ import { PROJECT_SETTINGS_TRACKER_EVENTS, } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; -import { StateGroupIcon, DoubleCircleIcon } from "@plane/propel/icons"; +import { StateGroupIcon, StatePropertyIcon } from "@plane/propel/icons"; import type { IProject } from "@plane/types"; // ui import { CustomSelect, CustomSearchSelect, ToggleSwitch, Loader } from "@plane/ui"; @@ -188,7 +188,7 @@ export const AutoCloseAutomation: React.FC = observer((props) => { size={EIconSize.LG} /> ) : ( - + )} {selectedOption?.name ? selectedOption.name diff --git a/apps/web/core/components/command-palette/actions/issue-actions/actions-list.tsx b/apps/web/core/components/command-palette/actions/issue-actions/actions-list.tsx index 0af68d137a6..eefe3dabc80 100644 --- a/apps/web/core/components/command-palette/actions/issue-actions/actions-list.tsx +++ b/apps/web/core/components/command-palette/actions/issue-actions/actions-list.tsx @@ -3,8 +3,8 @@ import { Command } from "cmdk"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; -import { LinkIcon, Signal, Trash2, UserMinus2, UserPlus2, Users } from "lucide-react"; -import { DoubleCircleIcon } from "@plane/propel/icons"; +import { LinkIcon, Trash2, UserMinus2, UserPlus2 } from "lucide-react"; +import { StatePropertyIcon, PriorityPropertyIcon, MembersPropertyIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { TIssue } from "@plane/types"; import { EIssueServiceType } from "@plane/types"; @@ -90,7 +90,7 @@ export const CommandPaletteIssueActions: React.FC = observer((props) => { className="focus:outline-none" >
- + Change state...
@@ -103,7 +103,7 @@ export const CommandPaletteIssueActions: React.FC = observer((props) => { className="focus:outline-none" >
- + Change priority...
@@ -116,7 +116,7 @@ export const CommandPaletteIssueActions: React.FC = observer((props) => { className="focus:outline-none" >
- + Assign to...
diff --git a/apps/web/core/components/common/activity/helper.tsx b/apps/web/core/components/common/activity/helper.tsx index 48cc39b8742..8c656f33e21 100644 --- a/apps/web/core/components/common/activity/helper.tsx +++ b/apps/web/core/components/common/activity/helper.tsx @@ -1,17 +1,13 @@ import type { ReactNode } from "react"; import { - Signal, RotateCcw, Network, Link as LinkIcon, Calendar, - Tag, Inbox, AlignLeft, - Users, Paperclip, Type, - Triangle, FileText, Globe, Hash, @@ -25,7 +21,19 @@ import { } from "lucide-react"; // components -import { ArchiveIcon, CycleIcon, DoubleCircleIcon, IntakeIcon, ModuleIcon } from "@plane/propel/icons"; +import { + ArchiveIcon, + CycleIcon, + StatePropertyIcon, + IntakeIcon, + ModuleIcon, + PriorityPropertyIcon, + StartDatePropertyIcon, + DueDatePropertyIcon, + LabelPropertyIcon, + MembersPropertyIcon, + EstimatePropertyIcon, +} from "@plane/propel/icons"; import { store } from "@/lib/store-context"; import type { TProjectActivity } from "@/plane-web/types"; @@ -33,20 +41,20 @@ type ActivityIconMap = { [key: string]: ReactNode; }; export const iconsMap: ActivityIconMap = { - priority: , + priority: , archived_at: , restored: , link: , - start_date: , - target_date: , - label: , + start_date: , + target_date: , + label: , inbox: , description: , - assignee: , + assignee: , attachment: , name: , - state: , - estimate: , + state: , + estimate: , cycle: , module: , page: , diff --git a/apps/web/core/components/core/modals/user-image-upload-modal.tsx b/apps/web/core/components/core/modals/user-image-upload-modal.tsx index cade5209668..e12ca566e0a 100644 --- a/apps/web/core/components/core/modals/user-image-upload-modal.tsx +++ b/apps/web/core/components/core/modals/user-image-upload-modal.tsx @@ -3,11 +3,11 @@ import React, { useState } from "react"; import { observer } from "mobx-react"; import { useDropzone } from "react-dropzone"; -import { UserCircle2 } from "lucide-react"; import { Transition, Dialog } from "@headlessui/react"; // plane imports import { ACCEPTED_AVATAR_IMAGE_MIME_TYPES_FOR_REACT_DROPZONE, MAX_FILE_SIZE } from "@plane/constants"; import { Button } from "@plane/propel/button"; +import { UserCirclePropertyIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { EFileAssetType } from "@plane/types"; import { getAssetIdFromUrl, getFileURL, checkURLValidity } from "@plane/utils"; @@ -146,7 +146,7 @@ export const UserImageUploadModal: React.FC = observer((props) => { ) : (
- + {isDragActive ? "Drop image here to upload" : "Drag & drop image here"} diff --git a/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx b/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx index 496319f7528..decf8047000 100644 --- a/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx +++ b/apps/web/core/components/core/modals/workspace-image-upload-modal.tsx @@ -3,11 +3,11 @@ import React, { useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { useDropzone } from "react-dropzone"; -import { UserCircle2 } from "lucide-react"; import { Transition, Dialog } from "@headlessui/react"; // plane imports import { ACCEPTED_AVATAR_IMAGE_MIME_TYPES_FOR_REACT_DROPZONE, MAX_FILE_SIZE } from "@plane/constants"; import { Button } from "@plane/propel/button"; +import { UserCirclePropertyIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { EFileAssetType } from "@plane/types"; import { getAssetIdFromUrl, getFileURL, checkURLValidity } from "@plane/utils"; @@ -158,7 +158,7 @@ export const WorkspaceImageUploadModal: React.FC = observer((props) => { ) : (
- + {isDragActive ? "Drop image here to upload" : "Drag & drop image here"} diff --git a/apps/web/core/components/cycles/analytics-sidebar/sidebar-details.tsx b/apps/web/core/components/cycles/analytics-sidebar/sidebar-details.tsx index e3e83216a1a..7c6e6b4edb3 100644 --- a/apps/web/core/components/cycles/analytics-sidebar/sidebar-details.tsx +++ b/apps/web/core/components/cycles/analytics-sidebar/sidebar-details.tsx @@ -3,11 +3,11 @@ import type { FC } from "react"; import React from "react"; import { isEmpty } from "lodash-es"; import { observer } from "mobx-react"; -import { SquareUser, Users } from "lucide-react"; +import { SquareUser } from "lucide-react"; // plane types import { EEstimateSystem } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; -import { WorkItemsIcon } from "@plane/propel/icons"; +import { MembersPropertyIcon, WorkItemsIcon } from "@plane/propel/icons"; import type { ICycle } from "@plane/types"; // plane ui import { Avatar, AvatarGroup, TextArea } from "@plane/ui"; @@ -87,7 +87,7 @@ export const CycleSidebarDetails: FC = observer((props) => {
- + {t("members")}
diff --git a/apps/web/core/components/cycles/list/cycle-list-item-action.tsx b/apps/web/core/components/cycles/list/cycle-list-item-action.tsx index 9a3e256b0a1..efcc22583d2 100644 --- a/apps/web/core/components/cycles/list/cycle-list-item-action.tsx +++ b/apps/web/core/components/cycles/list/cycle-list-item-action.tsx @@ -5,7 +5,7 @@ import React, { useEffect, useMemo, useState } from "react"; import { observer } from "mobx-react"; import { useParams, usePathname, useSearchParams } from "next/navigation"; import { useForm } from "react-hook-form"; -import { Eye, Users, ArrowRight, CalendarDays } from "lucide-react"; +import { Eye, ArrowRight, CalendarDays } from "lucide-react"; // plane imports import { CYCLE_TRACKER_EVENTS, @@ -16,7 +16,7 @@ import { } from "@plane/constants"; import { useLocalStorage } from "@plane/hooks"; import { useTranslation } from "@plane/i18n"; -import { TransferIcon, WorkItemsIcon } from "@plane/propel/icons"; +import { TransferIcon, WorkItemsIcon, MembersPropertyIcon } from "@plane/propel/icons"; import { setPromiseToast } from "@plane/propel/toast"; import { Tooltip } from "@plane/propel/tooltip"; import type { ICycle, TCycleGroups } from "@plane/types"; @@ -314,7 +314,7 @@ export const CycleListItemAction: FC = observer((props) => { })} ) : ( - + )}
diff --git a/apps/web/core/components/dropdowns/date-range.tsx b/apps/web/core/components/dropdowns/date-range.tsx index 83f0c904ee8..69e74c05c43 100644 --- a/apps/web/core/components/dropdowns/date-range.tsx +++ b/apps/web/core/components/dropdowns/date-range.tsx @@ -5,13 +5,14 @@ import type { Placement } from "@popperjs/core"; import { observer } from "mobx-react"; import { createPortal } from "react-dom"; import { usePopper } from "react-popper"; -import { ArrowRight, CalendarCheck2, CalendarDays, X } from "lucide-react"; +import { ArrowRight, CalendarDays, X } from "lucide-react"; import { Combobox } from "@headlessui/react"; // plane imports import { useTranslation } from "@plane/i18n"; // ui import type { DateRange, Matcher } from "@plane/propel/calendar"; import { Calendar } from "@plane/propel/calendar"; +import { DueDatePropertyIcon } from "@plane/propel/icons"; import { ComboDropDown } from "@plane/ui"; import { cn, renderFormattedDate } from "@plane/utils"; // helpers @@ -236,7 +237,7 @@ export const DateRangeDropdown: React.FC = observer((props) => { buttonToDateClassName )} > - {!hideIcon.to && } + {!hideIcon.to && } {dateRange.to ? renderFormattedDate(dateRange.to) : renderPlaceholder ? placeholder.to : ""} {isClearable && !disabled && hasDisplayedDates && ( diff --git a/apps/web/core/components/dropdowns/estimate.tsx b/apps/web/core/components/dropdowns/estimate.tsx index 3a8ec917407..2888183ebf1 100644 --- a/apps/web/core/components/dropdowns/estimate.tsx +++ b/apps/web/core/components/dropdowns/estimate.tsx @@ -3,10 +3,11 @@ import { useRef, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { usePopper } from "react-popper"; -import { Check, ChevronDown, Search, Triangle } from "lucide-react"; +import { Check, ChevronDown, Search } from "lucide-react"; import { Combobox } from "@headlessui/react"; // plane imports import { useTranslation } from "@plane/i18n"; +import { EstimatePropertyIcon } from "@plane/propel/icons"; import { EEstimateSystem } from "@plane/types"; import { ComboDropDown } from "@plane/ui"; import { convertMinutesToHoursMinutesString, cn } from "@plane/utils"; @@ -104,7 +105,7 @@ export const EstimateDropdown: React.FC = observer((props) => { query: `${currentEstimatePoint?.value}`, content: (
- + {currentActiveEstimate?.type === EEstimateSystem.TIME ? convertMinutesToHoursMinutesString(Number(currentEstimatePoint.value)) @@ -121,7 +122,7 @@ export const EstimateDropdown: React.FC = observer((props) => { query: t("project_settings.estimates.no_estimate"), content: (
- + {t("project_settings.estimates.no_estimate")}
), @@ -189,7 +190,7 @@ export const EstimateDropdown: React.FC = observer((props) => { variant={buttonVariant} renderToolTipByDefault={renderByDefault} > - {!hideIcon && } + {!hideIcon && } {(selectedEstimate || placeholder) && BUTTON_VARIANTS_WITH_TEXT.includes(buttonVariant) && ( {selectedEstimate @@ -249,7 +250,7 @@ export const EstimateDropdown: React.FC = observer((props) => { > {/* NOTE: This condition renders when estimates are not enabled for the project */}
- + {t("project_settings.estimates.no_estimate")}
diff --git a/apps/web/core/components/dropdowns/member/avatar.tsx b/apps/web/core/components/dropdowns/member/avatar.tsx index 5dc01268a66..826369abb7d 100644 --- a/apps/web/core/components/dropdowns/member/avatar.tsx +++ b/apps/web/core/components/dropdowns/member/avatar.tsx @@ -2,7 +2,7 @@ import { observer } from "mobx-react"; import type { LucideIcon } from "lucide-react"; -import { Users } from "lucide-react"; +import { MembersPropertyIcon } from "@plane/propel/icons"; // plane ui import { Avatar, AvatarGroup } from "@plane/ui"; import { cn, getFileURL } from "@plane/utils"; @@ -49,5 +49,9 @@ export const ButtonAvatars: React.FC = observer((props) => { } } - return Icon ? : ; + return Icon ? ( + + ) : ( + + ); }); diff --git a/apps/web/core/components/inbox/content/issue-properties.tsx b/apps/web/core/components/inbox/content/issue-properties.tsx index 41a1677d51b..c1df42157c6 100644 --- a/apps/web/core/components/inbox/content/issue-properties.tsx +++ b/apps/web/core/components/inbox/content/issue-properties.tsx @@ -2,8 +2,14 @@ import React from "react"; import { observer } from "mobx-react"; -import { CalendarCheck2, CopyPlus, Signal, Tag, Users } from "lucide-react"; -import { DoubleCircleIcon } from "@plane/propel/icons"; +import { + StatePropertyIcon, + MembersPropertyIcon, + PriorityPropertyIcon, + DueDatePropertyIcon, + LabelPropertyIcon, + DuplicatePropertyIcon, +} from "@plane/propel/icons"; import { Tooltip } from "@plane/propel/tooltip"; import type { TInboxDuplicateIssueDetails, TIssue } from "@plane/types"; import { ControlLink } from "@plane/ui"; @@ -56,7 +62,7 @@ export const InboxIssueContentProperties: React.FC = observer((props) => {/* State */}
- + State
{issue?.state_id && ( @@ -79,7 +85,7 @@ export const InboxIssueContentProperties: React.FC = observer((props) => {/* Assignee */}
- + Assignees
= observer((props) => {/* Priority */}
- + Priority
= observer((props) => {/* Due Date */}
- + Due date
= observer((props) => {/* Labels */}
- + Labels
@@ -177,7 +183,7 @@ export const InboxIssueContentProperties: React.FC = observer((props) => {duplicateIssueDetails && (
- + Duplicate of
diff --git a/apps/web/core/components/inbox/modals/create-modal/issue-properties.tsx b/apps/web/core/components/inbox/modals/create-modal/issue-properties.tsx index 92b823d3a6f..3d7c5abba44 100644 --- a/apps/web/core/components/inbox/modals/create-modal/issue-properties.tsx +++ b/apps/web/core/components/inbox/modals/create-modal/issue-properties.tsx @@ -1,9 +1,8 @@ import type { FC } from "react"; import { useState } from "react"; import { observer } from "mobx-react"; -import { LayoutPanelTop } from "lucide-react"; -// plane imports import { ETabIndices } from "@plane/constants"; +import { ParentPropertyIcon } from "@plane/propel/icons"; import type { ISearchIssueResponse, TIssue } from "@plane/types"; import { CustomMenu } from "@plane/ui"; import { renderFormattedPayloadDate, getDate, getTabIndex } from "@plane/utils"; @@ -177,7 +176,7 @@ export const InboxIssueProperties: FC = observer((props) type="button" className="flex cursor-pointer items-center justify-between gap-1 h-full rounded border-[0.5px] border-custom-border-300 px-2 py-0.5 text-xs hover:bg-custom-background-80" > - + {selectedParentIssue ? `${selectedParentIssue.project__identifier}-${selectedParentIssue.sequence_id}` @@ -211,7 +210,7 @@ export const InboxIssueProperties: FC = observer((props) className="flex cursor-pointer items-center justify-between gap-1 h-full rounded border-[0.5px] border-custom-border-300 px-2 py-0.5 text-xs hover:bg-custom-background-80" onClick={() => setParentIssueModalOpen(true)} > - + Add parent )} diff --git a/apps/web/core/components/integration/github/root.tsx b/apps/web/core/components/integration/github/root.tsx index 1a8fbb47263..cccef5da4ce 100644 --- a/apps/web/core/components/integration/github/root.tsx +++ b/apps/web/core/components/integration/github/root.tsx @@ -6,7 +6,8 @@ import Link from "next/link"; import { useParams, useSearchParams } from "next/navigation"; import { useForm } from "react-hook-form"; import useSWR, { mutate } from "swr"; -import { ArrowLeft, Check, List, Settings, UploadCloud, Users } from "lucide-react"; +import { ArrowLeft, Check, List, Settings, UploadCloud } from "lucide-react"; +import { MembersPropertyIcon } from "@plane/propel/icons"; // types import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { IGithubRepoCollaborator, IGithubServiceImportFormData } from "@plane/types"; @@ -68,7 +69,7 @@ const integrationWorkflowData = [ { title: "Users", key: "import-users", - icon: Users, + icon: MembersPropertyIcon, }, { title: "Confirm", diff --git a/apps/web/core/components/integration/jira/root.tsx b/apps/web/core/components/integration/jira/root.tsx index ed9fa09ba2d..f2d5c99553d 100644 --- a/apps/web/core/components/integration/jira/root.tsx +++ b/apps/web/core/components/integration/jira/root.tsx @@ -7,9 +7,10 @@ import { useParams } from "next/navigation"; import { FormProvider, useForm } from "react-hook-form"; import { mutate } from "swr"; // icons -import { ArrowLeft, Check, List, Settings, Users } from "lucide-react"; -// types +import { ArrowLeft, Check, List, Settings } from "lucide-react"; import { Button } from "@plane/propel/button"; +import { MembersPropertyIcon } from "@plane/propel/icons"; +// types import type { IJiraImporterForm } from "@plane/types"; // ui // fetch keys @@ -42,7 +43,7 @@ const integrationWorkflowData: Array<{ { title: "Users", key: "import-users", - icon: Users, + icon: MembersPropertyIcon, }, { title: "Confirm", diff --git a/apps/web/core/components/issues/issue-detail-widgets/action-buttons.tsx b/apps/web/core/components/issues/issue-detail-widgets/action-buttons.tsx index ae8387efc45..ec4cba9aa98 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/action-buttons.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/action-buttons.tsx @@ -2,9 +2,9 @@ import type { FC } from "react"; import React from "react"; -import { Link, Paperclip, Waypoints } from "lucide-react"; +import { Link, Paperclip } from "lucide-react"; import { useTranslation } from "@plane/i18n"; -import { ViewsIcon } from "@plane/propel/icons"; +import { ViewsIcon, RelationPropertyIcon } from "@plane/propel/icons"; // plane imports import type { TIssueServiceType, TWorkItemWidgets } from "@plane/types"; // plane web imports @@ -52,7 +52,7 @@ export const IssueDetailWidgetActionButtons: FC = (props) => { customButton={ } + icon={} disabled={disabled} /> } diff --git a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx index 6295c853839..35097a29863 100644 --- a/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx +++ b/apps/web/core/components/issues/issue-detail-widgets/sub-issues/issues-list/properties.tsx @@ -2,8 +2,8 @@ import type { SyntheticEvent } from "react"; import { useMemo } from "react"; import { observer } from "mobx-react"; -import { CalendarCheck2, CalendarClock } from "lucide-react"; import { useTranslation } from "@plane/i18n"; +import { StartDatePropertyIcon, DueDatePropertyIcon } from "@plane/propel/icons"; import type { IIssueDisplayProperties, TIssue } from "@plane/types"; import { getDate, renderFormattedPayloadDate, shouldHighlightIssueDueDate } from "@plane/utils"; // components @@ -165,7 +165,7 @@ export const SubIssuesListItemProperties: React.FC = observer((props) => onChange={handleStartDate} maxDate={maxDate} placeholder={t("common.order_by.start_date")} - icon={} + icon={} buttonVariant={issue.start_date ? "border-with-text" : "border-without-text"} optionsClassName="z-30" disabled={!canEdit} @@ -186,7 +186,7 @@ export const SubIssuesListItemProperties: React.FC = observer((props) => onChange={handleTargetDate} minDate={minDate} placeholder={t("common.order_by.due_date")} - icon={} + icon={} buttonVariant={issue.target_date ? "border-with-text" : "border-without-text"} buttonClassName={shouldHighlight ? "text-red-500" : ""} clearIconClassName="text-custom-text-100" diff --git a/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/assignee.tsx b/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/assignee.tsx index 97294839fbc..5c4466f8a83 100644 --- a/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/assignee.tsx +++ b/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/assignee.tsx @@ -1,7 +1,7 @@ import type { FC } from "react"; import { observer } from "mobx-react"; // icons -import { Users } from "lucide-react"; +import { MembersPropertyIcon } from "@plane/propel/icons"; // hooks; import { useIssueDetail } from "@/hooks/store/use-issue-detail"; // components @@ -21,7 +21,7 @@ export const IssueAssigneeActivity: FC = observer((props if (!activity) return <>; return ( } + icon={} activityId={activityId} ends={ends} > diff --git a/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/estimate.tsx b/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/estimate.tsx index 8c43a2171e0..ada9b523794 100644 --- a/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/estimate.tsx +++ b/apps/web/core/components/issues/issue-detail/issue-activity/activity/actions/estimate.tsx @@ -1,6 +1,6 @@ import type { FC } from "react"; import { observer } from "mobx-react"; -import { Triangle } from "lucide-react"; +import { EstimatePropertyIcon } from "@plane/propel/icons"; // hooks import { useIssueDetail } from "@/hooks/store/use-issue-detail"; // components @@ -21,7 +21,7 @@ export const IssueEstimateActivity: FC = observer((props return (
diff --git a/apps/web/core/components/issues/issue-detail/sidebar.tsx b/apps/web/core/components/issues/issue-detail/sidebar.tsx index f93fb67e160..4c6fc38378a 100644 --- a/apps/web/core/components/issues/issue-detail/sidebar.tsx +++ b/apps/web/core/components/issues/issue-detail/sidebar.tsx @@ -2,11 +2,22 @@ import React from "react"; import { observer } from "mobx-react"; -import { CalendarCheck2, CalendarClock, LayoutPanelTop, Signal, Tag, Triangle, UserCircle2, Users } from "lucide-react"; // i18n import { useTranslation } from "@plane/i18n"; // ui -import { CycleIcon, DoubleCircleIcon, ModuleIcon } from "@plane/propel/icons"; +import { + CycleIcon, + StatePropertyIcon, + ModuleIcon, + MembersPropertyIcon, + PriorityPropertyIcon, + StartDatePropertyIcon, + DueDatePropertyIcon, + LabelPropertyIcon, + UserCirclePropertyIcon, + EstimatePropertyIcon, + ParentPropertyIcon, +} from "@plane/propel/icons"; import { cn, getDate, renderFormattedPayloadDate, shouldHighlightIssueDueDate } from "@plane/utils"; // components import { DateDropdown } from "@/components/dropdowns/date"; @@ -74,7 +85,7 @@ export const IssueDetailsSidebar: React.FC = observer((props) => {
- + {t("common.state")}
= observer((props) => {
- + {t("common.assignees")}
= observer((props) => {
- + {t("common.priority")}
= observer((props) => { {createdByDetails && (
- + {t("common.created_by")}
@@ -146,7 +157,7 @@ export const IssueDetailsSidebar: React.FC = observer((props) => {
- + {t("common.order_by.start_date")}
= observer((props) => {
- + {t("common.order_by.due_date")}
= observer((props) => { {projectId && areEstimateEnabledByProjectId(projectId) && (
- + {t("common.estimate")}
= observer((props) => {
- + {t("common.parent")}
= observer((props) => {
- + {t("common.labels")}
diff --git a/apps/web/core/components/issues/issue-layouts/layout-icon.tsx b/apps/web/core/components/issues/issue-layouts/layout-icon.tsx index e4f7f000440..c55669c68dd 100644 --- a/apps/web/core/components/issues/issue-layouts/layout-icon.tsx +++ b/apps/web/core/components/issues/issue-layouts/layout-icon.tsx @@ -1,19 +1,34 @@ -import type { LucideProps } from "lucide-react"; -import { List, Kanban, Calendar, Sheet, GanttChartSquare } from "lucide-react"; +import { + ListLayoutIcon, + BoardLayoutIcon, + CalendarLayoutIcon, + SheetLayoutIcon, + TimelineLayoutIcon, +} from "@plane/propel/icons"; +import type { ISvgIcons } from "@plane/propel/icons"; import { EIssueLayoutTypes } from "@plane/types"; -export const IssueLayoutIcon = ({ layout, ...props }: { layout: EIssueLayoutTypes } & LucideProps) => { +export const IssueLayoutIcon = ({ + layout, + size, + ...props +}: { layout: EIssueLayoutTypes; size?: number } & Omit) => { + const iconProps = { + ...props, + ...(size && { width: size, height: size }), + }; + switch (layout) { case EIssueLayoutTypes.LIST: - return ; + return ; case EIssueLayoutTypes.KANBAN: - return ; + return ; case EIssueLayoutTypes.CALENDAR: - return ; + return ; case EIssueLayoutTypes.SPREADSHEET: - return ; + return ; case EIssueLayoutTypes.GANTT: - return ; + return ; default: return null; } diff --git a/apps/web/core/components/issues/issue-layouts/properties/all-properties.tsx b/apps/web/core/components/issues/issue-layouts/properties/all-properties.tsx index 0a5f0a392fb..a61d6ccf421 100644 --- a/apps/web/core/components/issues/issue-layouts/properties/all-properties.tsx +++ b/apps/web/core/components/issues/issue-layouts/properties/all-properties.tsx @@ -6,12 +6,12 @@ import { xor } from "lodash-es"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons -import { CalendarCheck2, CalendarClock, Link, Paperclip } from "lucide-react"; +import { Link, Paperclip } from "lucide-react"; // types import { WORK_ITEM_TRACKER_EVENTS } from "@plane/constants"; // i18n import { useTranslation } from "@plane/i18n"; -import { ViewsIcon } from "@plane/propel/icons"; +import { StartDatePropertyIcon, ViewsIcon, DueDatePropertyIcon } from "@plane/propel/icons"; import { Tooltip } from "@plane/propel/tooltip"; import type { TIssue, IIssueDisplayProperties, TIssuePriorities } from "@plane/types"; // ui @@ -324,7 +324,7 @@ export const IssueProperties: React.FC = observer((props) => { onChange={handleStartDate} maxDate={maxDate} placeholder={t("common.order_by.start_date")} - icon={} + icon={} buttonVariant={issue.start_date ? "border-with-text" : "border-without-text"} optionsClassName="z-10" disabled={isReadOnly} @@ -346,7 +346,7 @@ export const IssueProperties: React.FC = observer((props) => { onChange={handleTargetDate} minDate={minDate} placeholder={t("common.order_by.due_date")} - icon={} + icon={} buttonVariant={issue.target_date ? "border-with-text" : "border-without-text"} buttonClassName={shouldHighlightIssueDueDate(issue.target_date, stateDetails?.group) ? "text-red-500" : ""} clearIconClassName="!text-custom-text-100" diff --git a/apps/web/core/components/issues/issue-layouts/properties/labels.tsx b/apps/web/core/components/issues/issue-layouts/properties/labels.tsx index eb02435e096..ecb856a0cd8 100644 --- a/apps/web/core/components/issues/issue-layouts/properties/labels.tsx +++ b/apps/web/core/components/issues/issue-layouts/properties/labels.tsx @@ -3,11 +3,11 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import type { Placement } from "@popperjs/core"; import { observer } from "mobx-react"; -import { Tags } from "lucide-react"; // plane helpers import { useOutsideClickDetector } from "@plane/hooks"; // i18n import { useTranslation } from "@plane/i18n"; +import { LabelPropertyIcon } from "@plane/propel/icons"; // types import { Tooltip } from "@plane/propel/tooltip"; import type { IIssueLabel } from "@plane/types"; @@ -101,7 +101,7 @@ export const IssuePropertyLabels: React.FC = observer((pro fullWidth && "w-full" )} > - + {placeholderText}
diff --git a/apps/web/core/components/issues/issue-layouts/spreadsheet/columns/due-date-column.tsx b/apps/web/core/components/issues/issue-layouts/spreadsheet/columns/due-date-column.tsx index 1d793c3209f..087e349b6bc 100644 --- a/apps/web/core/components/issues/issue-layouts/spreadsheet/columns/due-date-column.tsx +++ b/apps/web/core/components/issues/issue-layouts/spreadsheet/columns/due-date-column.tsx @@ -1,6 +1,6 @@ import React from "react"; import { observer } from "mobx-react"; -import { CalendarCheck2 } from "lucide-react"; +import { DueDatePropertyIcon } from "@plane/propel/icons"; // types import type { TIssue } from "@plane/types"; import { cn, getDate, renderFormattedPayloadDate, shouldHighlightIssueDueDate } from "@plane/utils"; @@ -42,7 +42,7 @@ export const SpreadsheetDueDateColumn: React.FC = observer((props: Props) }} disabled={disabled} placeholder="Due date" - icon={} + icon={} buttonVariant="transparent-with-text" buttonContainerClassName="w-full" buttonClassName={cn( diff --git a/apps/web/core/components/issues/issue-layouts/spreadsheet/columns/start-date-column.tsx b/apps/web/core/components/issues/issue-layouts/spreadsheet/columns/start-date-column.tsx index f1c35a4b576..bcdc01a1dfc 100644 --- a/apps/web/core/components/issues/issue-layouts/spreadsheet/columns/start-date-column.tsx +++ b/apps/web/core/components/issues/issue-layouts/spreadsheet/columns/start-date-column.tsx @@ -1,6 +1,6 @@ import React from "react"; import { observer } from "mobx-react"; -import { CalendarClock } from "lucide-react"; +import { StartDatePropertyIcon } from "@plane/propel/icons"; // types import type { TIssue } from "@plane/types"; // components @@ -36,7 +36,7 @@ export const SpreadsheetStartDateColumn: React.FC = observer((props: Prop }} disabled={disabled} placeholder="Start date" - icon={} + icon={} buttonVariant="transparent-with-text" buttonClassName="text-left rounded-none group-[.selected-issue-row]:bg-custom-primary-100/5 group-[.selected-issue-row]:hover:bg-custom-primary-100/10 px-page-x" buttonContainerClassName="w-full" diff --git a/apps/web/core/components/issues/issue-modal/components/default-properties.tsx b/apps/web/core/components/issues/issue-modal/components/default-properties.tsx index f7bba82d309..e9def41c6ff 100644 --- a/apps/web/core/components/issues/issue-modal/components/default-properties.tsx +++ b/apps/web/core/components/issues/issue-modal/components/default-properties.tsx @@ -4,10 +4,9 @@ import React, { useState } from "react"; import { observer } from "mobx-react"; import type { Control } from "react-hook-form"; import { Controller } from "react-hook-form"; -import { LayoutPanelTop } from "lucide-react"; -// plane imports import { ETabIndices, EUserPermissions, EUserPermissionsLevel } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; +import { ParentPropertyIcon } from "@plane/propel/icons"; // types import type { ISearchIssueResponse, TIssue } from "@plane/types"; // ui @@ -313,7 +312,7 @@ export const IssueDefaultProperties: React.FC = ob className="flex cursor-pointer items-center justify-between gap-1 h-full rounded border-[0.5px] border-custom-border-300 px-2 py-0.5 text-xs hover:bg-custom-background-80" onClick={() => setParentIssueListModalOpen(true)} > - + {t("add_parent")} )} diff --git a/apps/web/core/components/issues/peek-overview/properties.tsx b/apps/web/core/components/issues/peek-overview/properties.tsx index bd6a727ea03..34f5265dc24 100644 --- a/apps/web/core/components/issues/peek-overview/properties.tsx +++ b/apps/web/core/components/issues/peek-overview/properties.tsx @@ -2,11 +2,22 @@ import type { FC } from "react"; import { observer } from "mobx-react"; -import { Signal, Tag, Triangle, LayoutPanelTop, CalendarClock, CalendarCheck2, Users, UserCircle2 } from "lucide-react"; // i18n import { useTranslation } from "@plane/i18n"; // ui icons -import { CycleIcon, DoubleCircleIcon, ModuleIcon } from "@plane/propel/icons"; +import { + CycleIcon, + StatePropertyIcon, + ModuleIcon, + MembersPropertyIcon, + PriorityPropertyIcon, + StartDatePropertyIcon, + DueDatePropertyIcon, + LabelPropertyIcon, + UserCirclePropertyIcon, + EstimatePropertyIcon, + ParentPropertyIcon, +} from "@plane/propel/icons"; import { cn, getDate, renderFormattedPayloadDate, shouldHighlightIssueDueDate } from "@plane/utils"; // components import { DateDropdown } from "@/components/dropdowns/date"; @@ -69,7 +80,7 @@ export const PeekOverviewProperties: FC = observer((pro {/* state */}
- + {t("common.state")}
= observer((pro {/* assignee */}
- + {t("common.assignees")}
= observer((pro {/* priority */}
- + {t("common.priority")}
= observer((pro {createdByDetails && (
- + {t("common.created_by")}
@@ -148,7 +159,7 @@ export const PeekOverviewProperties: FC = observer((pro {/* start date */}
- + {t("common.order_by.start_date")}
= observer((pro {/* due date */}
- + {t("common.order_by.due_date")}
= observer((pro {isEstimateEnabled && (
- + {t("common.estimate")}
= observer((pro {/* parent */}
- +

{t("common.parent")}

= observer((pro {/* label */}
- + {t("common.labels")}
diff --git a/apps/web/core/components/issues/select/base.tsx b/apps/web/core/components/issues/select/base.tsx index eb0bb02c782..a81eebcd918 100644 --- a/apps/web/core/components/issues/select/base.tsx +++ b/apps/web/core/components/issues/select/base.tsx @@ -2,12 +2,13 @@ import React, { useEffect, useRef, useState } from "react"; import type { Placement } from "@popperjs/core"; import { observer } from "mobx-react"; import { usePopper } from "react-popper"; -import { Check, Component, Loader, Search, Tag } from "lucide-react"; +import { Check, Component, Loader, Search } from "lucide-react"; import { Combobox } from "@headlessui/react"; import { getRandomLabelColor } from "@plane/constants"; // plane imports import { useOutsideClickDetector } from "@plane/hooks"; import { useTranslation } from "@plane/i18n"; +import { LabelPropertyIcon } from "@plane/propel/icons"; import type { IIssueLabel } from "@plane/types"; import { cn } from "@plane/utils"; // components @@ -181,7 +182,7 @@ export const WorkItemLabelSelectBase: React.FC = buttonClassName )} > - + {t("labels")}
)} diff --git a/apps/web/core/components/issues/workspace-draft/draft-issue-properties.tsx b/apps/web/core/components/issues/workspace-draft/draft-issue-properties.tsx index 04ca1b82d41..e931bd25c66 100644 --- a/apps/web/core/components/issues/workspace-draft/draft-issue-properties.tsx +++ b/apps/web/core/components/issues/workspace-draft/draft-issue-properties.tsx @@ -4,7 +4,7 @@ import { useCallback, useMemo } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; // icons -import { CalendarCheck2, CalendarClock } from "lucide-react"; +import { DueDatePropertyIcon, StartDatePropertyIcon } from "@plane/propel/icons"; // types import type { TIssuePriorities, TWorkspaceDraftIssue } from "@plane/types"; import { getDate, renderFormattedPayloadDate, shouldHighlightIssueDueDate } from "@plane/utils"; @@ -177,7 +177,7 @@ export const DraftIssueProperties: React.FC = observer((props) onChange={handleStartDate} maxDate={maxDate} placeholder="Start date" - icon={} + icon={} buttonVariant={issue.start_date ? "border-with-text" : "border-without-text"} optionsClassName="z-10" renderByDefault={isMobile} @@ -192,7 +192,7 @@ export const DraftIssueProperties: React.FC = observer((props) onChange={handleTargetDate} minDate={minDate} placeholder="Due date" - icon={} + icon={} buttonVariant={issue.target_date ? "border-with-text" : "border-without-text"} buttonClassName={ shouldHighlightIssueDueDate(issue?.target_date || null, stateDetails?.group) ? "text-red-500" : "" diff --git a/apps/web/core/components/modules/analytics-sidebar/root.tsx b/apps/web/core/components/modules/analytics-sidebar/root.tsx index fa47aa146c5..5e33b6e438c 100644 --- a/apps/web/core/components/modules/analytics-sidebar/root.tsx +++ b/apps/web/core/components/modules/analytics-sidebar/root.tsx @@ -4,7 +4,7 @@ import React, { useEffect, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; import { Controller, useForm } from "react-hook-form"; -import { CalendarClock, ChevronDown, ChevronRight, Info, Plus, SquareUser, Users } from "lucide-react"; +import { ChevronDown, ChevronRight, Info, Plus, SquareUser } from "lucide-react"; import { Disclosure, Transition } from "@headlessui/react"; import { MODULE_STATUS, @@ -16,7 +16,7 @@ import { } from "@plane/constants"; // plane types import { useTranslation } from "@plane/i18n"; -import { ModuleStatusIcon, WorkItemsIcon } from "@plane/propel/icons"; +import { MembersPropertyIcon, ModuleStatusIcon, WorkItemsIcon, StartDatePropertyIcon } from "@plane/propel/icons"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import type { ILinkDetails, IModule, ModuleLink } from "@plane/types"; // plane ui @@ -303,7 +303,7 @@ export const ModuleAnalyticsSidebar: React.FC = observer((props) => {
- + {t("date_range")}
@@ -371,7 +371,7 @@ export const ModuleAnalyticsSidebar: React.FC = observer((props) => {
- + {t("members")}
= (props) => { // get Layout icon const icons = { - list: List, - board: LayoutGrid, - gantt: GanttChartSquare, + list: ListLayoutIcon, + board: GridLayoutIcon, + gantt: TimelineLayoutIcon, }; const Icon = icons[layoutType ?? "list"]; @@ -28,10 +28,10 @@ export const ModuleLayoutIcon: React.FC = (props) => { <> {withContainer ? (
- +
) : ( - + )} ); diff --git a/apps/web/core/components/modules/select/status.tsx b/apps/web/core/components/modules/select/status.tsx index e93f557b7a8..e89fe2f7be8 100644 --- a/apps/web/core/components/modules/select/status.tsx +++ b/apps/web/core/components/modules/select/status.tsx @@ -7,7 +7,7 @@ import type { FieldError, Control } from "react-hook-form"; import { Controller } from "react-hook-form"; import { MODULE_STATUS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; -import { DoubleCircleIcon, ModuleStatusIcon } from "@plane/propel/icons"; +import { StatePropertyIcon, ModuleStatusIcon } from "@plane/propel/icons"; import type { IModule } from "@plane/types"; // ui import { CustomSelect } from "@plane/ui"; @@ -37,7 +37,7 @@ export const ModuleStatusSelect: React.FC = ({ control, error, tabIndex } {value ? ( ) : ( - + )} {(selectedValue && t(selectedValue?.i18n_label)) ?? ( Status diff --git a/apps/web/core/components/modules/sidebar-select/select-status.tsx b/apps/web/core/components/modules/sidebar-select/select-status.tsx index 90d18409b6a..83e6cf6dd83 100644 --- a/apps/web/core/components/modules/sidebar-select/select-status.tsx +++ b/apps/web/core/components/modules/sidebar-select/select-status.tsx @@ -7,7 +7,7 @@ import type { Control, UseFormWatch } from "react-hook-form"; import { Controller } from "react-hook-form"; import { MODULE_STATUS } from "@plane/constants"; import { useTranslation } from "@plane/i18n"; -import { DoubleCircleIcon } from "@plane/propel/icons"; +import { StatePropertyIcon } from "@plane/propel/icons"; import type { IModule } from "@plane/types"; // ui import { CustomSelect } from "@plane/ui"; @@ -26,7 +26,7 @@ export const SidebarStatusSelect: React.FC = ({ control, submitChanges, w return (
- +

Status

diff --git a/apps/web/core/components/profile/overview/stats.tsx b/apps/web/core/components/profile/overview/stats.tsx index 5998b9a7a41..13bb3c8d850 100644 --- a/apps/web/core/components/profile/overview/stats.tsx +++ b/apps/web/core/components/profile/overview/stats.tsx @@ -4,9 +4,8 @@ import Link from "next/link"; import { useParams } from "next/navigation"; // ui -import { UserCircle2 } from "lucide-react"; import { useTranslation } from "@plane/i18n"; -import { CreateIcon, LayerStackIcon } from "@plane/propel/icons"; +import { UserCirclePropertyIcon, CreateIcon, LayerStackIcon } from "@plane/propel/icons"; import type { IUserProfileData } from "@plane/types"; import { Loader, Card, ECardSpacing, ECardDirection } from "@plane/ui"; // types @@ -28,7 +27,7 @@ export const ProfileStats: React.FC = ({ userProfile }) => { value: userProfile?.created_issues ?? "...", }, { - icon: UserCircle2, + icon: UserCirclePropertyIcon, route: "assigned", i18n_title: "profile.stats.assigned", value: userProfile?.assigned_issues ?? "...", diff --git a/apps/web/core/components/readonly/estimate.tsx b/apps/web/core/components/readonly/estimate.tsx index ea71ce3d59f..e67ee740881 100644 --- a/apps/web/core/components/readonly/estimate.tsx +++ b/apps/web/core/components/readonly/estimate.tsx @@ -2,9 +2,8 @@ import { useEffect } from "react"; import { observer } from "mobx-react"; -import { Triangle } from "lucide-react"; -// plane imports import { useTranslation } from "@plane/i18n"; +import { EstimatePropertyIcon } from "@plane/propel/icons"; import { EEstimateSystem } from "@plane/types"; import { cn, convertMinutesToHoursMinutesString } from "@plane/utils"; // hooks @@ -46,7 +45,7 @@ export const ReadonlyEstimate: React.FC = observer((prop return (
- {!hideIcon && } + {!hideIcon && } {displayValue ?? placeholder ?? t("common.none")}
); diff --git a/packages/constants/src/issue/common.ts b/packages/constants/src/issue/common.ts index 665fa930ad9..e19a752b2ff 100644 --- a/packages/constants/src/issue/common.ts +++ b/packages/constants/src/issue/common.ts @@ -241,7 +241,7 @@ export const SPREADSHEET_PROPERTY_DETAILS: { ascendingOrderTitle: "A", descendingOrderKey: "-assignees__first_name", descendingOrderTitle: "Z", - icon: "Users", + icon: "MembersPropertyIcon", }, created_on: { i18n_title: "common.sort.created_on", @@ -257,7 +257,7 @@ export const SPREADSHEET_PROPERTY_DETAILS: { ascendingOrderTitle: "New", descendingOrderKey: "target_date", descendingOrderTitle: "Old", - icon: "CalendarCheck2", + icon: "DueDatePropertyIcon", }, estimate: { i18n_title: "common.estimate", @@ -265,7 +265,7 @@ export const SPREADSHEET_PROPERTY_DETAILS: { ascendingOrderTitle: "Low", descendingOrderKey: "-estimate_point__key", descendingOrderTitle: "High", - icon: "Triangle", + icon: "EstimatePropertyIcon", }, labels: { i18n_title: "common.labels", @@ -273,7 +273,7 @@ export const SPREADSHEET_PROPERTY_DETAILS: { ascendingOrderTitle: "A", descendingOrderKey: "-labels__name", descendingOrderTitle: "Z", - icon: "Tag", + icon: "LabelPropertyIcon", }, modules: { i18n_title: "common.modules", @@ -297,7 +297,7 @@ export const SPREADSHEET_PROPERTY_DETAILS: { ascendingOrderTitle: "None", descendingOrderKey: "-priority", descendingOrderTitle: "Urgent", - icon: "Signal", + icon: "PriorityPropertyIcon", }, start_date: { i18n_title: "common.order_by.start_date", @@ -305,7 +305,7 @@ export const SPREADSHEET_PROPERTY_DETAILS: { ascendingOrderTitle: "New", descendingOrderKey: "start_date", descendingOrderTitle: "Old", - icon: "CalendarClock", + icon: "StartDatePropertyIcon", }, state: { i18n_title: "common.state", @@ -313,7 +313,7 @@ export const SPREADSHEET_PROPERTY_DETAILS: { ascendingOrderTitle: "A", descendingOrderKey: "-state__name", descendingOrderTitle: "Z", - icon: "DoubleCircleIcon", + icon: "StatePropertyIcon", }, updated_on: { i18n_title: "common.sort.updated_on", diff --git a/packages/propel/src/icons/add-icon.tsx b/packages/propel/src/icons/actions/add-icon.tsx similarity index 62% rename from packages/propel/src/icons/add-icon.tsx rename to packages/propel/src/icons/actions/add-icon.tsx index 13d87f3d389..c7e0a1c0fb6 100644 --- a/packages/propel/src/icons/add-icon.tsx +++ b/packages/propel/src/icons/actions/add-icon.tsx @@ -1,33 +1,17 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const AddIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - - +export const AddIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + - - - - - - - -); + + ); +}; diff --git a/packages/propel/src/icons/actions/index.ts b/packages/propel/src/icons/actions/index.ts new file mode 100644 index 00000000000..0ef51f7211c --- /dev/null +++ b/packages/propel/src/icons/actions/index.ts @@ -0,0 +1 @@ +export * from "./add-icon"; diff --git a/packages/propel/src/icons/constants.tsx b/packages/propel/src/icons/constants.tsx new file mode 100644 index 00000000000..4dc86d08d0d --- /dev/null +++ b/packages/propel/src/icons/constants.tsx @@ -0,0 +1,62 @@ +import { Icon } from "./icon"; +export const ActionsIconsMap = [{ icon: , title: "AddIcon" }]; + +export const WorkspaceIconsMap = [ + { icon: , title: "AnalyticsIcon" }, + { icon: , title: "ArchiveIcon" }, + { icon: , title: "DashboardIcon" }, + { icon: , title: "DraftIcon" }, + { icon: , title: "HomeIcon" }, + { icon: , title: "InboxIcon" }, + { icon: , title: "ProjectIcon" }, + { icon: , title: "YourWorkIcon" }, +]; + +export const ProjectIconsMap = [ + { icon: , title: "CycleIcon" }, + { icon: , title: "EpicIcon" }, + { icon: , title: "IntakeIcon" }, + { icon: , title: "ModuleIcon" }, + { icon: , title: "PageIcon" }, + { icon: , title: "ViewIcon" }, + { icon: , title: "WorkItemsIcon" }, +]; + +export const SubBrandIconsMap = [ + { icon: , title: "PiChatLogo" }, + { icon: , title: "PlaneIcon" }, + { icon: , title: "WikiIcon" }, +]; + +export const LayoutIconsMap = [ + { icon: , title: "CalendarLayoutIcon" }, + { icon: , title: "CardLayoutIcon" }, + { icon: , title: "TimelineLayoutIcon" }, + { icon: , title: "GridLayoutIcon" }, + { icon: , title: "BoardLayoutIcon" }, + { icon: , title: "ListLayoutIcon" }, + { icon: , title: "SheetLayoutIcon" }, +]; + +export const PropertyIconsMap = [ + { icon: , title: "BooleanPropertyIcon" }, + { icon: , title: "DropdownPropertyIcon" }, + { icon: , title: "DueDatePropertyIcon" }, + { icon: , title: "DuplicatePropertyIcon" }, + { icon: , title: "EstimatePropertyIcon" }, + { icon: , title: "HashPropertyIcon" }, + { icon: , title: "LabelPropertyIcon" }, + { icon: , title: "MembersPropertyIcon" }, + { icon: , title: "OverdueDatePropertyIcon" }, + { icon: , title: "ParentPropertyIcon" }, + { icon: , title: "PriorityPropertyIcon" }, + { icon: , title: "RelatesToPropertyIcon" }, + { icon: , title: "RelationPropertyIcon" }, + { icon: , title: "ScopePropertyIcon" }, + { icon: , title: "StartDatePropertyIcon" }, + { icon: , title: "StatePropertyIcon" }, + { icon: , title: "UserCirclePropertyIcon" }, + { icon: , title: "UserPropertyIcon" }, + { icon: , title: "UserSquarePropertyIcon" }, + { icon: , title: "WorkflowsPropertyIcon" }, +]; diff --git a/packages/propel/src/icons/cycle/cycle-group-icon.tsx b/packages/propel/src/icons/cycle/cycle-group-icon.tsx index 6062ac36ea9..6e095d6f0a6 100644 --- a/packages/propel/src/icons/cycle/cycle-group-icon.tsx +++ b/packages/propel/src/icons/cycle/cycle-group-icon.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { CircleDotDashed, Circle } from "lucide-react"; -import { CycleIcon } from "../cycle-icon"; +import { CycleIcon } from "../project/cycle-icon"; import { CircleDotFullIcon } from "./circle-dot-full-icon"; import { CYCLE_GROUP_COLORS, ICycleGroupIcon } from "./helper"; diff --git a/packages/propel/src/icons/default-icon.tsx b/packages/propel/src/icons/default-icon.tsx new file mode 100644 index 00000000000..cf1fbed943c --- /dev/null +++ b/packages/propel/src/icons/default-icon.tsx @@ -0,0 +1,10 @@ +import * as React from "react"; + +import { IconWrapper } from "./icon-wrapper"; +import { ISvgIcons } from "./type"; + +export const DefaultIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/epic-icon.tsx b/packages/propel/src/icons/epic-icon.tsx deleted file mode 100644 index c78a98261ba..00000000000 --- a/packages/propel/src/icons/epic-icon.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from "react"; - -export type Props = { - className?: string; - width?: string | number; - height?: string | number; - color?: string; -}; - -export const EpicIcon: React.FC = ({ width = "16", height = "16", className }) => ( - - - - -); diff --git a/packages/propel/src/icons/helpers.ts b/packages/propel/src/icons/helpers.ts new file mode 100644 index 00000000000..0cf0bf64b35 --- /dev/null +++ b/packages/propel/src/icons/helpers.ts @@ -0,0 +1,29 @@ +import { ICON_REGISTRY, IconName } from "./registry"; + +/** + * Get the icon component by name + * @param name - The icon name from the registry + * @returns The icon component or default icon if not found + */ +export const getIconComponent = (name: IconName) => ICON_REGISTRY[name] || ICON_REGISTRY.default; + +/** + * Check if the icon name exists in the registry + * @param name - The icon name to check + * @returns True if the icon exists in the registry + */ +export const isValidIconName = (name: string): name is IconName => name in ICON_REGISTRY; + +/** + * Get all available icon names + * @returns Array of all icon names in the registry + */ +export const getIconNames = (): IconName[] => Object.keys(ICON_REGISTRY) as IconName[]; + +/** + * Get icons by category + * @param category - The category prefix (e.g., 'workspace', 'project') + * @returns Array of icon names matching the category + */ +export const getIconsByCategory = (category: string): IconName[] => + getIconNames().filter((name) => name.startsWith(`${category}.`)); diff --git a/packages/propel/src/icons/icon-wrapper.tsx b/packages/propel/src/icons/icon-wrapper.tsx new file mode 100644 index 00000000000..fb6123353ba --- /dev/null +++ b/packages/propel/src/icons/icon-wrapper.tsx @@ -0,0 +1,42 @@ +import * as React from "react"; + +import { ISvgIcons } from "./type"; + +interface IIconWrapper extends ISvgIcons { + children: React.ReactNode; + clipPathId?: string; + viewBox?: string; +} + +export const IconWrapper: React.FC = ({ + width = "16", + height = "16", + className = "text-current", + children, + clipPathId, + viewBox = "0 0 16 16", + ...rest +}) => ( + + {clipPathId ? ( + <> + {children} + + + + + + + ) : ( + children + )} + +); diff --git a/packages/propel/src/icons/icon.tsx b/packages/propel/src/icons/icon.tsx new file mode 100644 index 00000000000..68bc0e3494c --- /dev/null +++ b/packages/propel/src/icons/icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { ICON_REGISTRY, IconName } from "./registry"; +import { ISvgIcons } from "./type"; + +export interface IconProps extends Omit { + name: IconName; +} + +export const Icon: React.FC = ({ name, ...props }) => { + const IconComponent = ICON_REGISTRY[name] || ICON_REGISTRY.default; + return ; +}; diff --git a/packages/propel/src/icons/icons.stories.tsx b/packages/propel/src/icons/icons.stories.tsx new file mode 100644 index 00000000000..4bab5581c78 --- /dev/null +++ b/packages/propel/src/icons/icons.stories.tsx @@ -0,0 +1,196 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { + ActionsIconsMap, + LayoutIconsMap, + ProjectIconsMap, + PropertyIconsMap, + SubBrandIconsMap, + WorkspaceIconsMap, +} from "./constants"; +import { Icon } from "./icon"; +import { CycleIcon } from "./project/cycle-icon"; +import { HomeIcon } from "./workspace/home-icon"; +import { ProjectIcon } from "./workspace/project-icon"; + +const meta: Meta = { + title: "Icons", + parameters: { + layout: "padded", + docs: { + description: { + component: + "A comprehensive collection of all icons used throughout the application. Supports both direct imports and registry-based usage.", + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const AllIcons: Story = { + render: () => ( +
+
+

Sub-Brand Icons

+
+ {SubBrandIconsMap.map((item) => ( +
+
{item.icon}
+

{item.title}

+
+ ))} +
+
+ +
+

Workspace Icons

+
+ {WorkspaceIconsMap.map((item) => ( +
+
{item.icon}
+

{item.title}

+
+ ))} +
+
+ +
+

Project Icons

+
+ {ProjectIconsMap.map((item) => ( +
+
{item.icon}
+

{item.title}

+
+ ))} +
+
+ +
+

Layout Icons

+
+ {LayoutIconsMap.map((item) => ( +
+
{item.icon}
+

{item.title}

+
+ ))} +
+
+ +
+

Property Icons

+
+ {PropertyIconsMap.map((item) => ( +
+
{item.icon}
+

{item.title}

+
+ ))} +
+
+ +
+

Actions Icons

+
+ {ActionsIconsMap.map((item) => ( +
+
{item.icon}
+

{item.title}

+
+ ))} +
+
+
+ ), +}; + +export const RegistryUsage: Story = { + render: () => ( +
+
+

Registry-Based Usage

+

+ Use the Icon component with{" "} + name prop for dynamic icon selection. +

+
+
+ +

workspace.home

+
+
+ +

project.cycle

+
+
+ +

layout.board

+
+
+ +

property.priority

+
+
+
+ +
+

Direct Import Usage

+

+ Import icon components directly for better tree-shaking and type safety. +

+
+
+ +

HomeIcon

+
+
+ +

CycleIcon

+
+
+ +

ProjectIcon

+
+
+
+
+ ), +}; + +export const IconSizes: Story = { + render: () => ( +
+
+

Icon Sizes

+

+ Icons can be rendered in different sizes using width and height props. +

+
+ +
+
+ +

12x12

+
+
+ +

16x16 (default)

+
+
+ +

24x24

+
+
+ +

32x32

+
+
+ +

48x48

+
+
+
+ ), +}; diff --git a/packages/propel/src/icons/index.ts b/packages/propel/src/icons/index.ts index 0c0529a2243..ace2a42257c 100644 --- a/packages/propel/src/icons/index.ts +++ b/packages/propel/src/icons/index.ts @@ -1,9 +1,10 @@ export type { ISvgIcons } from "./type"; +export type { IconName } from "./registry"; +export type { IconProps } from "./icon"; +export { ICON_REGISTRY } from "./registry"; +export * from "./actions"; export * from "./activity-icon"; -export * from "./add-icon"; export * from "./ai-icon"; -export * from "./analytics-icon"; -export * from "./archive-icon"; export * from "./at-risk-icon"; export * from "./bar-icon"; export * from "./blocked-icon"; @@ -15,58 +16,51 @@ export * from "./center-panel-icon"; export * from "./comment-fill-icon"; export * from "./create-icon"; export * from "./cycle"; -export * from "./cycle-icon"; -export * from "./dashboard-icon"; +export * from "./default-icon"; export * from "./dice-icon"; export * from "./discord-icon"; export * from "./display-properties"; export * from "./done-icon"; -export * from "./draft-icon"; export * from "./dropdown-icon"; -export * from "./epic-icon"; export * from "./favorite-folder-icon"; export * from "./full-screen-panel-icon"; export * from "./github-icon"; export * from "./gitlab-icon"; -export * from "./home-icon"; -export * from "./inbox-icon"; +export * from "./helpers"; +export * from "./icon"; +export * from "./icon-wrapper"; export * from "./info-fill-icon"; export * from "./info-icon"; export * from "./in-progress-icon"; export * from "./intake"; -export * from "./intake-icon"; export * from "./layer-stack"; export * from "./layers-icon"; +export * from "./layouts"; export * from "./lead-icon"; export * from "./module"; -export * from "./module-icon"; export * from "./monospace-icon"; export * from "./multiple-sticky"; export * from "./off-track-icon"; export * from "./on-track-icon"; export * from "./overview-icon"; -export * from "./page-icon"; export * from "./pending-icon"; export * from "./photo-filter-icon"; -export * from "./pi-chat"; export * from "./planned-icon"; -export * from "./plane-icon"; export * from "./priority-icon"; -export * from "./project-icon"; +export * from "./project"; +export * from "./properties"; export * from "./related-icon"; export * from "./sans-serif-icon"; export * from "./serif-icon"; export * from "./side-panel-icon"; export * from "./state"; export * from "./sticky-note-icon"; +export * from "./sub-brand"; export * from "./suspended-user"; export * from "./teams"; export * from "./transfer-icon"; export * from "./tree-map-icon"; export * from "./updates-icon"; export * from "./user-activity-icon"; -export * from "./view-icon"; -export * from "./wiki-icon"; -export * from "./work-items-icon"; +export * from "./workspace"; export * from "./workspace-icon"; -export * from "./your-work-icon"; diff --git a/packages/propel/src/icons/layouts/board-icon.tsx b/packages/propel/src/icons/layouts/board-icon.tsx new file mode 100644 index 00000000000..aac682c632d --- /dev/null +++ b/packages/propel/src/icons/layouts/board-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const BoardLayoutIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/layouts/calendar-icon.tsx b/packages/propel/src/icons/layouts/calendar-icon.tsx new file mode 100644 index 00000000000..803d4a60a47 --- /dev/null +++ b/packages/propel/src/icons/layouts/calendar-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const CalendarLayoutIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/layouts/card-icon.tsx b/packages/propel/src/icons/layouts/card-icon.tsx new file mode 100644 index 00000000000..64be0629cd3 --- /dev/null +++ b/packages/propel/src/icons/layouts/card-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const CardLayoutIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/layouts/grid-icon.tsx b/packages/propel/src/icons/layouts/grid-icon.tsx new file mode 100644 index 00000000000..91cb6b71710 --- /dev/null +++ b/packages/propel/src/icons/layouts/grid-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const GridLayoutIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/layouts/index.ts b/packages/propel/src/icons/layouts/index.ts new file mode 100644 index 00000000000..649d93d3b08 --- /dev/null +++ b/packages/propel/src/icons/layouts/index.ts @@ -0,0 +1,7 @@ +export * from "./calendar-icon"; +export * from "./card-icon"; +export * from "./timeline-icon"; +export * from "./grid-icon"; +export * from "./board-icon"; +export * from "./list-icon"; +export * from "./sheet-icon"; diff --git a/packages/propel/src/icons/layouts/list-icon.tsx b/packages/propel/src/icons/layouts/list-icon.tsx new file mode 100644 index 00000000000..7d993c218f5 --- /dev/null +++ b/packages/propel/src/icons/layouts/list-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const ListLayoutIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/layouts/sheet-icon.tsx b/packages/propel/src/icons/layouts/sheet-icon.tsx new file mode 100644 index 00000000000..eea1b9fe1c7 --- /dev/null +++ b/packages/propel/src/icons/layouts/sheet-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const SheetLayoutIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/layouts/timeline-icon.tsx b/packages/propel/src/icons/layouts/timeline-icon.tsx new file mode 100644 index 00000000000..36950de1c30 --- /dev/null +++ b/packages/propel/src/icons/layouts/timeline-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const TimelineLayoutIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/cycle-icon.tsx b/packages/propel/src/icons/project/cycle-icon.tsx similarity index 52% rename from packages/propel/src/icons/cycle-icon.tsx rename to packages/propel/src/icons/project/cycle-icon.tsx index 181a7dd7439..7eee10ca48a 100644 --- a/packages/propel/src/icons/cycle-icon.tsx +++ b/packages/propel/src/icons/project/cycle-icon.tsx @@ -1,24 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const CycleIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - - +export const CycleIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + = ({ d="M7.99951 12.3337C10.3928 12.3337 12.3328 10.3936 12.3328 8.00033C12.3328 5.60709 10.3928 3.66699 7.99951 3.66699V12.3337Z" fill={color} /> - - - - - - - -); + + ); +}; diff --git a/packages/propel/src/icons/project/epic-icon.tsx b/packages/propel/src/icons/project/epic-icon.tsx new file mode 100644 index 00000000000..35bebaafcb8 --- /dev/null +++ b/packages/propel/src/icons/project/epic-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const EpicIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/project/index.ts b/packages/propel/src/icons/project/index.ts new file mode 100644 index 00000000000..0ace8ff7405 --- /dev/null +++ b/packages/propel/src/icons/project/index.ts @@ -0,0 +1,7 @@ +export * from "./cycle-icon"; +export * from "./epic-icon"; +export * from "./intake-icon"; +export * from "./module-icon"; +export * from "./page-icon"; +export * from "./view-icon"; +export * from "./work-items-icon"; diff --git a/packages/propel/src/icons/intake-icon.tsx b/packages/propel/src/icons/project/intake-icon.tsx similarity index 72% rename from packages/propel/src/icons/intake-icon.tsx rename to packages/propel/src/icons/project/intake-icon.tsx index 38daabf48eb..6bee44333ab 100644 --- a/packages/propel/src/icons/intake-icon.tsx +++ b/packages/propel/src/icons/project/intake-icon.tsx @@ -1,33 +1,17 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const IntakeIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - - +export const IntakeIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + - - - - - - - -); + + ); +}; diff --git a/packages/propel/src/icons/module-icon.tsx b/packages/propel/src/icons/project/module-icon.tsx similarity index 91% rename from packages/propel/src/icons/module-icon.tsx rename to packages/propel/src/icons/project/module-icon.tsx index 188b570fac5..6c4341a8da5 100644 --- a/packages/propel/src/icons/module-icon.tsx +++ b/packages/propel/src/icons/project/module-icon.tsx @@ -1,23 +1,10 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const ModuleIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - +export const ModuleIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + = ({ d="M6.54286 9H5.45714C5.29713 9 5.21712 9 5.156 9.03114C5.10224 9.05854 5.05853 9.10223 5.03114 9.156C5 9.21711 5 9.29712 5 9.45714V10.5429C5 10.7029 5 10.7829 5.03114 10.844C5.05853 10.8978 5.10224 10.9415 5.156 10.9689C5.21712 11 5.29713 11 5.45714 11H6.54286C6.70287 11 6.78288 11 6.844 10.9689C6.89776 10.9415 6.94147 10.8978 6.96886 10.844C7 10.7829 7 10.7029 7 10.5429V9.45714C7 9.29712 7 9.21711 6.96886 9.156C6.94147 9.10223 6.89776 9.05854 6.844 9.03114C6.78288 9 6.70287 9 6.54286 9Z" fill={color} /> - + ); diff --git a/packages/propel/src/icons/page-icon.tsx b/packages/propel/src/icons/project/page-icon.tsx similarity index 89% rename from packages/propel/src/icons/page-icon.tsx rename to packages/propel/src/icons/project/page-icon.tsx index c9eeb486e27..a98a740d82b 100644 --- a/packages/propel/src/icons/page-icon.tsx +++ b/packages/propel/src/icons/project/page-icon.tsx @@ -1,26 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const PageIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - +export const PageIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + - + ); diff --git a/packages/propel/src/icons/view-icon.tsx b/packages/propel/src/icons/project/view-icon.tsx similarity index 74% rename from packages/propel/src/icons/view-icon.tsx rename to packages/propel/src/icons/project/view-icon.tsx index e51a7044f9f..1b6f6a38bf5 100644 --- a/packages/propel/src/icons/view-icon.tsx +++ b/packages/propel/src/icons/project/view-icon.tsx @@ -1,33 +1,17 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const ViewsIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - - +export const ViewsIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + - - - - - - - -); + + ); +}; diff --git a/packages/propel/src/icons/project/work-items-icon.tsx b/packages/propel/src/icons/project/work-items-icon.tsx new file mode 100644 index 00000000000..d48c8e58c51 --- /dev/null +++ b/packages/propel/src/icons/project/work-items-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const WorkItemsIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/boolean-icon.tsx b/packages/propel/src/icons/properties/boolean-icon.tsx new file mode 100644 index 00000000000..5c9588c90d6 --- /dev/null +++ b/packages/propel/src/icons/properties/boolean-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const BooleanPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/dropdown-icon.tsx b/packages/propel/src/icons/properties/dropdown-icon.tsx new file mode 100644 index 00000000000..b0215524db6 --- /dev/null +++ b/packages/propel/src/icons/properties/dropdown-icon.tsx @@ -0,0 +1,17 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const DropdownPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + + + + ); +}; diff --git a/packages/propel/src/icons/properties/due-date-icon.tsx b/packages/propel/src/icons/properties/due-date-icon.tsx new file mode 100644 index 00000000000..d8f73c04a0e --- /dev/null +++ b/packages/propel/src/icons/properties/due-date-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const DueDatePropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/duplicate-icon.tsx b/packages/propel/src/icons/properties/duplicate-icon.tsx new file mode 100644 index 00000000000..8384fc8c13e --- /dev/null +++ b/packages/propel/src/icons/properties/duplicate-icon.tsx @@ -0,0 +1,17 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const DuplicatePropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + + + + ); +}; diff --git a/packages/propel/src/icons/properties/estimate-icon.tsx b/packages/propel/src/icons/properties/estimate-icon.tsx new file mode 100644 index 00000000000..ad59eb02bd4 --- /dev/null +++ b/packages/propel/src/icons/properties/estimate-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const EstimatePropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/hash-icon.tsx b/packages/propel/src/icons/properties/hash-icon.tsx new file mode 100644 index 00000000000..c218a797182 --- /dev/null +++ b/packages/propel/src/icons/properties/hash-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const HashPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/index.ts b/packages/propel/src/icons/properties/index.ts new file mode 100644 index 00000000000..52e36a7f478 --- /dev/null +++ b/packages/propel/src/icons/properties/index.ts @@ -0,0 +1,20 @@ +export * from "./boolean-icon"; +export * from "./dropdown-icon"; +export * from "./due-date-icon"; +export * from "./duplicate-icon"; +export * from "./estimate-icon"; +export * from "./hash-icon"; +export * from "./label-icon"; +export * from "./members-icon"; +export * from "./overdue-date-icon"; +export * from "./parent-icon"; +export * from "./priority-icon"; +export * from "./relates-to-icon"; +export * from "./relation-icon"; +export * from "./scope-icon"; +export * from "./start-date-icon"; +export * from "./state-icon"; +export * from "./user-circle-icon"; +export * from "./user-icon"; +export * from "./user-square-icon"; +export * from "./workflows-icon"; diff --git a/packages/propel/src/icons/properties/label-icon.tsx b/packages/propel/src/icons/properties/label-icon.tsx new file mode 100644 index 00000000000..97bd7f5b735 --- /dev/null +++ b/packages/propel/src/icons/properties/label-icon.tsx @@ -0,0 +1,21 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const LabelPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + + + + + ); +}; diff --git a/packages/propel/src/icons/properties/members-icon.tsx b/packages/propel/src/icons/properties/members-icon.tsx new file mode 100644 index 00000000000..3627ec3a18e --- /dev/null +++ b/packages/propel/src/icons/properties/members-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const MembersPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/overdue-date-icon.tsx b/packages/propel/src/icons/properties/overdue-date-icon.tsx new file mode 100644 index 00000000000..1c4152c63e3 --- /dev/null +++ b/packages/propel/src/icons/properties/overdue-date-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const OverdueDatePropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/parent-icon.tsx b/packages/propel/src/icons/properties/parent-icon.tsx new file mode 100644 index 00000000000..1104f248172 --- /dev/null +++ b/packages/propel/src/icons/properties/parent-icon.tsx @@ -0,0 +1,21 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const ParentPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + + + +); diff --git a/packages/propel/src/icons/properties/priority-icon.tsx b/packages/propel/src/icons/properties/priority-icon.tsx new file mode 100644 index 00000000000..904235557d9 --- /dev/null +++ b/packages/propel/src/icons/properties/priority-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const PriorityPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/relates-to-icon.tsx b/packages/propel/src/icons/properties/relates-to-icon.tsx new file mode 100644 index 00000000000..625999e6da6 --- /dev/null +++ b/packages/propel/src/icons/properties/relates-to-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const RelatesToPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/relation-icon.tsx b/packages/propel/src/icons/properties/relation-icon.tsx new file mode 100644 index 00000000000..82326b2d04c --- /dev/null +++ b/packages/propel/src/icons/properties/relation-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const RelationPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/scope-icon.tsx b/packages/propel/src/icons/properties/scope-icon.tsx new file mode 100644 index 00000000000..0f66ee10a58 --- /dev/null +++ b/packages/propel/src/icons/properties/scope-icon.tsx @@ -0,0 +1,17 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const ScopePropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + + + + ); +}; diff --git a/packages/propel/src/icons/properties/start-date-icon.tsx b/packages/propel/src/icons/properties/start-date-icon.tsx new file mode 100644 index 00000000000..28741aecf15 --- /dev/null +++ b/packages/propel/src/icons/properties/start-date-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const StartDatePropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/state-icon.tsx b/packages/propel/src/icons/properties/state-icon.tsx new file mode 100644 index 00000000000..fc69eace629 --- /dev/null +++ b/packages/propel/src/icons/properties/state-icon.tsx @@ -0,0 +1,17 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const StatePropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + + + + ); +}; diff --git a/packages/propel/src/icons/properties/user-circle-icon.tsx b/packages/propel/src/icons/properties/user-circle-icon.tsx new file mode 100644 index 00000000000..06fd6f3eb18 --- /dev/null +++ b/packages/propel/src/icons/properties/user-circle-icon.tsx @@ -0,0 +1,17 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const UserCirclePropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + + + + ); +}; diff --git a/packages/propel/src/icons/properties/user-icon.tsx b/packages/propel/src/icons/properties/user-icon.tsx new file mode 100644 index 00000000000..d1dd3ca83c0 --- /dev/null +++ b/packages/propel/src/icons/properties/user-icon.tsx @@ -0,0 +1,13 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const UserPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + +); diff --git a/packages/propel/src/icons/properties/user-square-icon.tsx b/packages/propel/src/icons/properties/user-square-icon.tsx new file mode 100644 index 00000000000..3e7521f2811 --- /dev/null +++ b/packages/propel/src/icons/properties/user-square-icon.tsx @@ -0,0 +1,17 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const UserSquarePropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + + + + ); +}; diff --git a/packages/propel/src/icons/properties/workflows-icon.tsx b/packages/propel/src/icons/properties/workflows-icon.tsx new file mode 100644 index 00000000000..ed3a2b6bdb5 --- /dev/null +++ b/packages/propel/src/icons/properties/workflows-icon.tsx @@ -0,0 +1,21 @@ +import * as React from "react"; + +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; + +export const WorkflowsPropertyIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + + + + + +); diff --git a/packages/propel/src/icons/registry.ts b/packages/propel/src/icons/registry.ts new file mode 100644 index 00000000000..5bff8585058 --- /dev/null +++ b/packages/propel/src/icons/registry.ts @@ -0,0 +1,115 @@ +import { AddIcon } from "./actions/add-icon"; +import { DefaultIcon } from "./default-icon"; +import { BoardLayoutIcon } from "./layouts/board-icon"; +import { CalendarLayoutIcon } from "./layouts/calendar-icon"; +import { CardLayoutIcon } from "./layouts/card-icon"; +import { GridLayoutIcon } from "./layouts/grid-icon"; +import { ListLayoutIcon } from "./layouts/list-icon"; +import { SheetLayoutIcon } from "./layouts/sheet-icon"; +import { TimelineLayoutIcon } from "./layouts/timeline-icon"; +import { CycleIcon } from "./project/cycle-icon"; +import { EpicIcon } from "./project/epic-icon"; +import { IntakeIcon } from "./project/intake-icon"; +import { ModuleIcon } from "./project/module-icon"; +import { PageIcon } from "./project/page-icon"; +import { ViewsIcon } from "./project/view-icon"; +import { WorkItemsIcon } from "./project/work-items-icon"; +import { BooleanPropertyIcon } from "./properties/boolean-icon"; +import { DropdownPropertyIcon } from "./properties/dropdown-icon"; +import { DueDatePropertyIcon } from "./properties/due-date-icon"; +import { DuplicatePropertyIcon } from "./properties/duplicate-icon"; +import { EstimatePropertyIcon } from "./properties/estimate-icon"; +import { HashPropertyIcon } from "./properties/hash-icon"; +import { LabelPropertyIcon } from "./properties/label-icon"; +import { MembersPropertyIcon } from "./properties/members-icon"; +import { OverdueDatePropertyIcon } from "./properties/overdue-date-icon"; +import { ParentPropertyIcon } from "./properties/parent-icon"; +import { PriorityPropertyIcon } from "./properties/priority-icon"; +import { RelatesToPropertyIcon } from "./properties/relates-to-icon"; +import { RelationPropertyIcon } from "./properties/relation-icon"; +import { ScopePropertyIcon } from "./properties/scope-icon"; +import { StartDatePropertyIcon } from "./properties/start-date-icon"; +import { StatePropertyIcon } from "./properties/state-icon"; +import { UserCirclePropertyIcon } from "./properties/user-circle-icon"; +import { UserPropertyIcon } from "./properties/user-icon"; +import { UserSquarePropertyIcon } from "./properties/user-square-icon"; +import { WorkflowsPropertyIcon } from "./properties/workflows-icon"; +import { PiChatLogo } from "./sub-brand/pi-chat"; +import { PlaneNewIcon } from "./sub-brand/plane-icon"; +import { WikiIcon } from "./sub-brand/wiki-icon"; +import { AnalyticsIcon } from "./workspace/analytics-icon"; +import { ArchiveIcon } from "./workspace/archive-icon"; +import { DashboardIcon } from "./workspace/dashboard-icon"; +import { DraftIcon } from "./workspace/draft-icon"; +import { HomeIcon } from "./workspace/home-icon"; +import { InboxIcon } from "./workspace/inbox-icon"; +import { ProjectIcon } from "./workspace/project-icon"; +import { YourWorkIcon } from "./workspace/your-work-icon"; + +export const ICON_REGISTRY = { + // Sub-brand icons + "sub-brand.plane": PlaneNewIcon, + "sub-brand.wiki": WikiIcon, + "sub-brand.pi-chat": PiChatLogo, + + // Workspace icons + "workspace.analytics": AnalyticsIcon, + "workspace.archive": ArchiveIcon, + "workspace.cycle": CycleIcon, + "workspace.dashboard": DashboardIcon, + "workspace.draft": DraftIcon, + "workspace.home": HomeIcon, + "workspace.inbox": InboxIcon, + "workspace.page": PageIcon, + "workspace.project": ProjectIcon, + "workspace.views": ViewsIcon, + "workspace.your-work": YourWorkIcon, + + // Project icons + "project.cycle": CycleIcon, + "project.epic": EpicIcon, + "project.intake": IntakeIcon, + "project.module": ModuleIcon, + "project.page": PageIcon, + "project.view": ViewsIcon, + "project.work-items": WorkItemsIcon, + + // Layout icons + "layout.calendar": CalendarLayoutIcon, + "layout.card": CardLayoutIcon, + "layout.timeline": TimelineLayoutIcon, + "layout.grid": GridLayoutIcon, + "layout.board": BoardLayoutIcon, + "layout.list": ListLayoutIcon, + "layout.sheet": SheetLayoutIcon, + + // Property icons + "property.boolean": BooleanPropertyIcon, + "property.dropdown": DropdownPropertyIcon, + "property.due-date": DueDatePropertyIcon, + "property.duplicate": DuplicatePropertyIcon, + "property.estimate": EstimatePropertyIcon, + "property.hash": HashPropertyIcon, + "property.label": LabelPropertyIcon, + "property.members": MembersPropertyIcon, + "property.overdue-date": OverdueDatePropertyIcon, + "property.parent": ParentPropertyIcon, + "property.priority": PriorityPropertyIcon, + "property.relates-to": RelatesToPropertyIcon, + "property.relation": RelationPropertyIcon, + "property.scope": ScopePropertyIcon, + "property.start-date": StartDatePropertyIcon, + "property.state": StatePropertyIcon, + "property.user-circle": UserCirclePropertyIcon, + "property.user": UserPropertyIcon, + "property.user-square": UserSquarePropertyIcon, + "property.workflows": WorkflowsPropertyIcon, + + // Action icons + "action.add": AddIcon, + + // Default fallback + default: DefaultIcon, +} as const; + +export type IconName = keyof typeof ICON_REGISTRY; diff --git a/packages/propel/src/icons/sub-brand/index.ts b/packages/propel/src/icons/sub-brand/index.ts new file mode 100644 index 00000000000..7a0d0cefb08 --- /dev/null +++ b/packages/propel/src/icons/sub-brand/index.ts @@ -0,0 +1,3 @@ +export * from "./pi-chat"; +export * from "./plane-icon"; +export * from "./wiki-icon"; diff --git a/packages/propel/src/icons/pi-chat.tsx b/packages/propel/src/icons/sub-brand/pi-chat.tsx similarity index 82% rename from packages/propel/src/icons/pi-chat.tsx rename to packages/propel/src/icons/sub-brand/pi-chat.tsx index e2e49a28f38..1f947706649 100644 --- a/packages/propel/src/icons/pi-chat.tsx +++ b/packages/propel/src/icons/sub-brand/pi-chat.tsx @@ -1,21 +1,15 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const PiChatLogo: React.FC = ({ width = "16", height = "16", className, color = "currentColor" }) => ( - +export const PiChatLogo: React.FC = ({ color = "currentColor", ...rest }) => ( + - + ); diff --git a/packages/propel/src/icons/plane-icon.tsx b/packages/propel/src/icons/sub-brand/plane-icon.tsx similarity index 54% rename from packages/propel/src/icons/plane-icon.tsx rename to packages/propel/src/icons/sub-brand/plane-icon.tsx index 113d2dfd041..e645dedf7a0 100644 --- a/packages/propel/src/icons/plane-icon.tsx +++ b/packages/propel/src/icons/sub-brand/plane-icon.tsx @@ -1,22 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const PlaneNewIcon: React.FC = ({ - width = "16", - height = "16", - className, - color = "currentColor", -}) => ( - - +export const PlaneNewIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + = ({ d="M14.66 0H6.49582C5.75553 0 5.1543 0.600183 5.1543 1.34152V5.15488H9.50615C10.2464 5.15488 10.8477 5.75506 10.8477 6.49641V10.8483H14.661C15.4013 10.8483 16.0026 10.2481 16.0026 9.50673V1.34152C16.0026 0.601229 15.4024 0 14.661 0H14.66Z" fill={color} /> - - - - - - - -); + + ); +}; diff --git a/packages/propel/src/icons/wiki-icon.tsx b/packages/propel/src/icons/sub-brand/wiki-icon.tsx similarity index 54% rename from packages/propel/src/icons/wiki-icon.tsx rename to packages/propel/src/icons/sub-brand/wiki-icon.tsx index 5a3b992c7f6..8d534dc0d80 100644 --- a/packages/propel/src/icons/wiki-icon.tsx +++ b/packages/propel/src/icons/sub-brand/wiki-icon.tsx @@ -1,26 +1,17 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const WikiIcon: React.FC = ({ width = "16", height = "16", className, color = "currentColor" }) => ( - - +export const WikiIcon: React.FC = ({ color = "currentColor", ...rest }) => { + const clipPathId = React.useId(); + + return ( + - - - - - - - -); + + ); +}; diff --git a/packages/propel/src/icons/work-items-icon.tsx b/packages/propel/src/icons/work-items-icon.tsx deleted file mode 100644 index f07145b3350..00000000000 --- a/packages/propel/src/icons/work-items-icon.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import * as React from "react"; - -import { ISvgIcons } from "./type"; - -export const WorkItemsIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - - - -); diff --git a/packages/propel/src/icons/analytics-icon.tsx b/packages/propel/src/icons/workspace/analytics-icon.tsx similarity index 87% rename from packages/propel/src/icons/analytics-icon.tsx rename to packages/propel/src/icons/workspace/analytics-icon.tsx index 4e1f6502328..d0be0ebb3de 100644 --- a/packages/propel/src/icons/analytics-icon.tsx +++ b/packages/propel/src/icons/workspace/analytics-icon.tsx @@ -1,26 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const AnalyticsIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - +export const AnalyticsIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + - + ); diff --git a/packages/propel/src/icons/archive-icon.tsx b/packages/propel/src/icons/workspace/archive-icon.tsx similarity index 89% rename from packages/propel/src/icons/archive-icon.tsx rename to packages/propel/src/icons/workspace/archive-icon.tsx index b83ce69a85c..1d359d3601e 100644 --- a/packages/propel/src/icons/archive-icon.tsx +++ b/packages/propel/src/icons/workspace/archive-icon.tsx @@ -1,12 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const ArchiveIcon: React.FC = ({ className = "text-current", color = "currentColor", ...rest }) => ( - +export const ArchiveIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + - + ); diff --git a/packages/propel/src/icons/dashboard-icon.tsx b/packages/propel/src/icons/workspace/dashboard-icon.tsx similarity index 86% rename from packages/propel/src/icons/dashboard-icon.tsx rename to packages/propel/src/icons/workspace/dashboard-icon.tsx index a451d798405..fab6d145b33 100644 --- a/packages/propel/src/icons/dashboard-icon.tsx +++ b/packages/propel/src/icons/workspace/dashboard-icon.tsx @@ -1,26 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const DashboardIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - +export const DashboardIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + - + ); diff --git a/packages/propel/src/icons/draft-icon.tsx b/packages/propel/src/icons/workspace/draft-icon.tsx similarity index 82% rename from packages/propel/src/icons/draft-icon.tsx rename to packages/propel/src/icons/workspace/draft-icon.tsx index d821fa358c8..bec049e6baa 100644 --- a/packages/propel/src/icons/draft-icon.tsx +++ b/packages/propel/src/icons/workspace/draft-icon.tsx @@ -1,26 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const DraftIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - +export const DraftIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + - + ); diff --git a/packages/propel/src/icons/home-icon.tsx b/packages/propel/src/icons/workspace/home-icon.tsx similarity index 91% rename from packages/propel/src/icons/home-icon.tsx rename to packages/propel/src/icons/workspace/home-icon.tsx index dfcd1a18212..cfc3c06f57f 100644 --- a/packages/propel/src/icons/home-icon.tsx +++ b/packages/propel/src/icons/workspace/home-icon.tsx @@ -1,19 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const HomeIcon: React.FC = ({ width = "16", height = "16", className, color = "currentColor" }) => ( - +export const HomeIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + - + ); diff --git a/packages/propel/src/icons/inbox-icon.tsx b/packages/propel/src/icons/workspace/inbox-icon.tsx similarity index 88% rename from packages/propel/src/icons/inbox-icon.tsx rename to packages/propel/src/icons/workspace/inbox-icon.tsx index e6a1c20eb94..c4a6151b43c 100644 --- a/packages/propel/src/icons/inbox-icon.tsx +++ b/packages/propel/src/icons/workspace/inbox-icon.tsx @@ -1,26 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const InboxIcon: React.FC = ({ - width = "16", - height = "16", - className, - color = "currentColor", - ...rest -}) => ( - +export const InboxIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + - + ); diff --git a/packages/propel/src/icons/workspace/index.ts b/packages/propel/src/icons/workspace/index.ts new file mode 100644 index 00000000000..dd1b8a05991 --- /dev/null +++ b/packages/propel/src/icons/workspace/index.ts @@ -0,0 +1,8 @@ +export * from "./analytics-icon"; +export * from "./archive-icon"; +export * from "./dashboard-icon"; +export * from "./draft-icon"; +export * from "./home-icon"; +export * from "./inbox-icon"; +export * from "./project-icon"; +export * from "./your-work-icon"; diff --git a/packages/propel/src/icons/project-icon.tsx b/packages/propel/src/icons/workspace/project-icon.tsx similarity index 91% rename from packages/propel/src/icons/project-icon.tsx rename to packages/propel/src/icons/workspace/project-icon.tsx index 8a9ad6280d3..357f0333933 100644 --- a/packages/propel/src/icons/project-icon.tsx +++ b/packages/propel/src/icons/workspace/project-icon.tsx @@ -1,26 +1,13 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const ProjectIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - +export const ProjectIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + - + ); diff --git a/packages/propel/src/icons/your-work-icon.tsx b/packages/propel/src/icons/workspace/your-work-icon.tsx similarity index 81% rename from packages/propel/src/icons/your-work-icon.tsx rename to packages/propel/src/icons/workspace/your-work-icon.tsx index 2f003a2396d..75a2ea79ec0 100644 --- a/packages/propel/src/icons/your-work-icon.tsx +++ b/packages/propel/src/icons/workspace/your-work-icon.tsx @@ -1,23 +1,10 @@ import * as React from "react"; -import { ISvgIcons } from "./type"; +import { IconWrapper } from "../icon-wrapper"; +import { ISvgIcons } from "../type"; -export const YourWorkIcon: React.FC = ({ - width = "16", - height = "16", - className = "text-current", - color = "currentColor", - ...rest -}) => ( - +export const YourWorkIcon: React.FC = ({ color = "currentColor", ...rest }) => ( + = ({ d="M11.6338 9.27539C11.9026 9.27559 12.1415 9.44806 12.2265 9.70312L13.0332 12.124L13.1406 11.8027L13.1797 11.7109C13.2861 11.5072 13.4981 11.375 13.7334 11.375H14.667C15.0119 11.3752 15.2917 11.6551 15.292 12C15.292 12.3451 15.012 12.6248 14.667 12.625H14.1836L13.6259 14.2979C13.5409 14.5531 13.3022 14.7256 13.0332 14.7256C12.7642 14.7255 12.5255 14.553 12.4404 14.2979L11.6328 11.877L11.5263 12.1982C11.4412 12.4533 11.2024 12.6249 10.9336 12.625H9.99997C9.65479 12.625 9.37497 12.3452 9.37497 12C9.37518 11.655 9.65492 11.375 9.99997 11.375H10.4834L11.04 9.70312C11.1251 9.44791 11.3647 9.27539 11.6338 9.27539Z" fill={color} /> - + );