From edc15e324251ded745f43f74073f74c5d2a4c8ff Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Thu, 3 Oct 2024 13:22:42 +0530 Subject: [PATCH 01/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20design=20updated.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_elements/_navigation-container.scss | 14 +- packages/ui/navigation/src/navigation.tsx | 9 +- .../navigation/stories/navigation.stories.tsx | 133 +++++++++--------- 3 files changed, 88 insertions(+), 68 deletions(-) diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss index db4e7d21f..4f360471f 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss @@ -17,7 +17,7 @@ display: flex; gap: $spacing-lg; justify-content: space-between; - padding: $spacing-lg $spacing-2xl; + padding: $spacing-default $spacing-2xl; .sui-dropdown__popover { .sui-dropdown__menu-group-title { @@ -36,6 +36,18 @@ } } + @include element(actions) { + display: flex; + align-items: center; + gap: $spacing-lg; + padding-left: $spacing-lg; + border-left: $border-width-sm solid $color-extended-neutral-80; + + .sui-dropdown { + display: flex; + } + } + @include media(max-width, md) { padding: $spacing-xl; } diff --git a/packages/ui/navigation/src/navigation.tsx b/packages/ui/navigation/src/navigation.tsx index d588a52e9..c1bb3878a 100644 --- a/packages/ui/navigation/src/navigation.tsx +++ b/packages/ui/navigation/src/navigation.tsx @@ -12,6 +12,7 @@ const Navigation: React.FC = ({ children, brand = { title: "title", description: "" }, user, + actions = [], _htmlProps, _style, }) => { @@ -36,8 +37,12 @@ const Navigation: React.FC = ({ ))} - {/* Render the navigation user component */} - +
+ {/* Show actions */} + {actions.length > 0 && actions.map((action, index) => action)} + {/* Render the navigation user component */} + +
) } diff --git a/packages/ui/navigation/stories/navigation.stories.tsx b/packages/ui/navigation/stories/navigation.stories.tsx index c95be64f3..9bada43b3 100644 --- a/packages/ui/navigation/stories/navigation.stories.tsx +++ b/packages/ui/navigation/stories/navigation.stories.tsx @@ -74,12 +74,76 @@ export const Navigation = (props: { }, ], }} + actions={[ + +
+ +
+
, + ]} > @@ -87,7 +151,7 @@ export const Navigation = (props: { icon="Bell" type="tertiary" colorScheme="black" - isResponsive={true} + iconOnly={true} > Documentation @@ -95,71 +159,10 @@ export const Navigation = (props: { icon="PluginSmush" type="tertiary" colorScheme="black" - isResponsive={true} + iconOnly={true} > Support Smush - -
- -
-
From d4466e1fba0b48aa3201feeb803fc176f581c791 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Fri, 4 Oct 2024 12:04:36 +0530 Subject: [PATCH 02/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20design=20updated.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_elements/_navigation-user.scss | 22 +++++++++++++++++++ .../ui/navigation/src/navigation-user.tsx | 4 ++++ .../ui/navigation/src/navigation.types.ts | 4 ++++ .../navigation/stories/navigation.stories.tsx | 8 +++++++ 4 files changed, 38 insertions(+) diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-user.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-user.scss index 768409936..53c16b02a 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-user.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-user.scss @@ -26,6 +26,28 @@ color: $color-extended-neutral-60; } } + + @include element(dropdown) { + @include modifier(split) { + .sui-dropdown__menu-items { + .sui-dropdown__menu-item { + &:last-child { + position: relative; + margin-top: $spacing-lg; + + &:after { + content: ""; + position: absolute; + top: -#{$spacing-md}; + left: 0; + right: 0; + border-top: $border-width-sm solid $color-extended-neutral-80; + } + } + } + } + } + } } } diff --git a/packages/ui/navigation/src/navigation-user.tsx b/packages/ui/navigation/src/navigation-user.tsx index d72ffc01f..64745ac8b 100644 --- a/packages/ui/navigation/src/navigation-user.tsx +++ b/packages/ui/navigation/src/navigation-user.tsx @@ -9,6 +9,7 @@ import { isEmpty } from "@wpmudev/sui-utils" const NavigationUser: React.FC = ({ user, menu, + splitLastItem = false, isMenuDisabled = false, status, }) => { @@ -64,6 +65,9 @@ const NavigationUser: React.FC = ({ trigger={userAvatarBtn} renderContentOnTop={true} menu={menu ?? []} + {...(splitLastItem && { + className: "sui-navigation__dropdown--split", + })} > {getUserBlock()} diff --git a/packages/ui/navigation/src/navigation.types.ts b/packages/ui/navigation/src/navigation.types.ts index 7d6ba06ac..6ec249177 100644 --- a/packages/ui/navigation/src/navigation.types.ts +++ b/packages/ui/navigation/src/navigation.types.ts @@ -89,6 +89,10 @@ interface NavigationUserProps { * The user status */ status?: AvatarProps["status"] + /* + * Seperate last item from menu. + */ + splitLastItem?: boolean } // interface definition for the Navigation diff --git a/packages/ui/navigation/stories/navigation.stories.tsx b/packages/ui/navigation/stories/navigation.stories.tsx index 9bada43b3..e8b4aba02 100644 --- a/packages/ui/navigation/stories/navigation.stories.tsx +++ b/packages/ui/navigation/stories/navigation.stories.tsx @@ -49,6 +49,7 @@ export const Navigation = (props: { }, status, isMenuDisabled, + splitLastItem: true, menu: [ { id: "the-hub", @@ -72,6 +73,13 @@ export const Navigation = (props: { variation: "smush", }, }, + { + id: "logout", + label: "Logout", + props: { + icon: "Exit", + }, + }, ], }} actions={[ From 0f859eacd88a0ad89b3c4d966a5b2fa649052bf5 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Wed, 9 Oct 2024 09:34:14 +0530 Subject: [PATCH 03/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20design=20updated.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_elements/_dropdown-popover.scss | 15 ++++++++++- .../_modifiers/_dropdown-placement.scss | 7 ++++- .../_elements/_navigation-user.scss | 3 +++ .../assets/css/src/scss/_utils/_tokens.scss | 9 ++++++- packages/assets/css/src/tokens/core.json | 4 +++ packages/assets/css/src/tokens/dropdown.json | 26 +++++++++++++++++++ packages/ui/dropdown/src/dropdown.tsx | 2 ++ packages/ui/dropdown/src/dropdown.types.ts | 4 +++ .../ui/navigation/src/navigation-user.tsx | 9 ++++--- 9 files changed, 72 insertions(+), 7 deletions(-) diff --git a/packages/assets/css/src/scss/_components/_dropdown/_elements/_dropdown-popover.scss b/packages/assets/css/src/scss/_components/_dropdown/_elements/_dropdown-popover.scss index 6adf992c1..d491f8c13 100644 --- a/packages/assets/css/src/scss/_components/_dropdown/_elements/_dropdown-popover.scss +++ b/packages/assets/css/src/scss/_components/_dropdown/_elements/_dropdown-popover.scss @@ -17,7 +17,7 @@ top: 100%; left: 0; display: none; - margin: $spacing-md 0 0; + margin: $spacing-lg 0 0; padding: $spacing-md 0; border-radius: $border-radius-md; background: $color-extended-neutral-100; @@ -43,6 +43,19 @@ } } + @include modifier(arrow) { + position: absolute; + top: -#{$dropdown-position-xs}; + left: $dropdown-position-md; + box-shadow: $border-width-sm $border-width-sm 0px $border-width-xs + $color-extended-neutral-80 inset; + height: $dropdown-size-height-3xs; + width: $dropdown-size-width-2xs; + height: $dropdown-size-height-2xs; + background: $color-extended-neutral-100; + transform: rotate(45deg); + } + @include modifier(sm) { min-width: $dropdown-size-width-sm; } diff --git a/packages/assets/css/src/scss/_components/_dropdown/_modifiers/_dropdown-placement.scss b/packages/assets/css/src/scss/_components/_dropdown/_modifiers/_dropdown-placement.scss index e081ade1b..ef2701eed 100644 --- a/packages/assets/css/src/scss/_components/_dropdown/_modifiers/_dropdown-placement.scss +++ b/packages/assets/css/src/scss/_components/_dropdown/_modifiers/_dropdown-placement.scss @@ -12,7 +12,12 @@ @include element(popover) { @include modifier(placement-left) { left: auto; - right: 0; + right: -#{$dropdown-position-sm}; + + .sui-#{$block}__popover--arrow { + right: $dropdown-position-md; + left: auto; + } } @include modifier(placement-top) { diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-user.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-user.scss index 53c16b02a..0131e5dd7 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-user.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-user.scss @@ -28,6 +28,9 @@ } @include element(dropdown) { + .sui-dropdown__popover { + border: $border-width-sm solid $color-extended-neutral-80; + } @include modifier(split) { .sui-dropdown__menu-items { .sui-dropdown__menu-item { diff --git a/packages/assets/css/src/scss/_utils/_tokens.scss b/packages/assets/css/src/scss/_utils/_tokens.scss index 48927ca79..9da6a076e 100644 --- a/packages/assets/css/src/scss/_utils/_tokens.scss +++ b/packages/assets/css/src/scss/_utils/_tokens.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Mon, 16 Sep 2024 05:01:25 GMT +// Generated on Wed, 09 Oct 2024 03:58:25 GMT $accordion-border-radius-sm: 10px; $advanced-banner-background: linear-gradient(90deg, #222 0%, #383323 48.96%, #514524 100%); @@ -293,6 +293,7 @@ $shadow-offset-lg: 12px; $shadow-offset-xl: 16px; $shadow-offset-2xl: 20px; $shadow-offset-default: 6px; +$border-width-xs: 0.5px; $border-width-sm: 1px; $border-width-md: 2px; $border-width-xl: 4px; @@ -345,10 +346,16 @@ $datepicker-size-height-lg: 248px; $datepicker-border-radius-lg: 20px; $drawer-size-sm: 320px; $drawer-size-lg: 520px; +$dropdown-size-width-2xs: 12px; $dropdown-size-width-sm: 160px; $dropdown-size-width-md: 240px; $dropdown-size-width-lg: 280px; +$dropdown-size-height-3xs: 10px; +$dropdown-size-height-2xs: 12px; $dropdown-size-height-md: 225px; +$dropdown-position-xs: 7px; +$dropdown-position-sm: 10px; +$dropdown-position-md: 20px; $dropdown-spacing-default: 12px; $emptystate-spacing-sm: 24px; $emptystate-spacing-md: 32px; diff --git a/packages/assets/css/src/tokens/core.json b/packages/assets/css/src/tokens/core.json index a26eed31d..627c2695a 100644 --- a/packages/assets/css/src/tokens/core.json +++ b/packages/assets/css/src/tokens/core.json @@ -937,6 +937,10 @@ }, "border": { "width": { + "xs": { + "value": "0.5px", + "type": "borderWidth" + }, "sm": { "value": "1px", "type": "borderWidth" diff --git a/packages/assets/css/src/tokens/dropdown.json b/packages/assets/css/src/tokens/dropdown.json index 431996a5b..0048c92d0 100644 --- a/packages/assets/css/src/tokens/dropdown.json +++ b/packages/assets/css/src/tokens/dropdown.json @@ -2,6 +2,10 @@ "dropdown": { "size": { "width": { + "2xs": { + "value": "12px", + "type": "sizing" + }, "sm": { "value": "160px", "type": "sizing" @@ -16,12 +20,34 @@ } }, "height": { + "3xs": { + "value": "10px", + "type": "sizing" + }, + "2xs": { + "value": "12px", + "type": "sizing" + }, "md": { "value": "225px", "type": "sizing" } } }, + "position": { + "xs": { + "value": "7px", + "type": "sizing" + }, + "sm": { + "value": "10px", + "type": "sizing" + }, + "md": { + "value": "20px", + "type": "sizing" + } + }, "spacing": { "default": { "value": "12px", diff --git a/packages/ui/dropdown/src/dropdown.tsx b/packages/ui/dropdown/src/dropdown.tsx index 420441414..c4b189dad 100644 --- a/packages/ui/dropdown/src/dropdown.tsx +++ b/packages/ui/dropdown/src/dropdown.tsx @@ -43,6 +43,7 @@ const Dropdown = forwardRef( children, menu, placement = "right", + arrow = false, buttonIcon, onMenuClick, trigger, @@ -356,6 +357,7 @@ const Dropdown = forwardRef( width: `${menuCustomWidth}px`, }} > + {arrow &&
} {renderContentOnTop && !!children && (
{children}
)} diff --git a/packages/ui/dropdown/src/dropdown.types.ts b/packages/ui/dropdown/src/dropdown.types.ts index aacbe493a..3166d863b 100644 --- a/packages/ui/dropdown/src/dropdown.types.ts +++ b/packages/ui/dropdown/src/dropdown.types.ts @@ -269,6 +269,10 @@ interface DropdownProps * Custom search placeholder */ searchPlaceholder?: string + /** + * arrow in dropdown + */ + arrow?: boolean } // Type definition for the modal handling functions diff --git a/packages/ui/navigation/src/navigation-user.tsx b/packages/ui/navigation/src/navigation-user.tsx index 64745ac8b..70eee8d0d 100644 --- a/packages/ui/navigation/src/navigation-user.tsx +++ b/packages/ui/navigation/src/navigation-user.tsx @@ -4,7 +4,7 @@ import { Dropdown, DropdownRefProps } from "@wpmudev/sui-dropdown" import { Avatar } from "@wpmudev/sui-avatar" import { NavigationUserProps } from "./navigation.types" -import { isEmpty } from "@wpmudev/sui-utils" +import { generateCN, isEmpty } from "@wpmudev/sui-utils" const NavigationUser: React.FC = ({ user, @@ -61,12 +61,13 @@ const NavigationUser: React.FC = ({ ref={userBtnRef} label="Menu Button" placement="left" - size="md" + size="lg" trigger={userAvatarBtn} renderContentOnTop={true} menu={menu ?? []} - {...(splitLastItem && { - className: "sui-navigation__dropdown--split", + arrow={true} + className={generateCN("sui-navigation__dropdown", { + split: splitLastItem, })} > {getUserBlock()} From e932f846aa0e6e74b32448c71da3e8e1fc3b9288 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Wed, 9 Oct 2024 10:20:55 +0530 Subject: [PATCH 04/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20design=20updated.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/ui/dropdown/src/dropdown.tsx | 11 ++++++++--- packages/ui/dropdown/src/dropdown.types.ts | 10 +++++++++- packages/ui/navigation/src/navigation-user.tsx | 2 +- packages/ui/navigation/stories/navigation.stories.tsx | 5 +++-- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/ui/dropdown/src/dropdown.tsx b/packages/ui/dropdown/src/dropdown.tsx index c4b189dad..e11eeb9a2 100644 --- a/packages/ui/dropdown/src/dropdown.tsx +++ b/packages/ui/dropdown/src/dropdown.tsx @@ -43,7 +43,8 @@ const Dropdown = forwardRef( children, menu, placement = "right", - arrow = false, + arrow = true, + dropdownArrow = false, buttonIcon, onMenuClick, trigger, @@ -64,6 +65,7 @@ const Dropdown = forwardRef( getOptions, menuCustomWidth, searchPlaceholder, + _buttonProps = {}, _htmlProps = {}, _style = {}, }, @@ -331,8 +333,9 @@ const Dropdown = forwardRef( onClick={() => handleOnOpen(!isOpen)} isResponsive={isResponsive} isDisabled={isDisabled} - {...(!iconOnly && { endIcon: "ChevronDown" })} + {...(!iconOnly && arrow && { endIcon: "ChevronDown" })} colorScheme={colorScheme as ButtonProps["colorScheme"]} + {..._buttonProps} > {label} @@ -357,7 +360,9 @@ const Dropdown = forwardRef( width: `${menuCustomWidth}px`, }} > - {arrow &&
} + {dropdownArrow && ( +
+ )} {renderContentOnTop && !!children && (
{children}
)} diff --git a/packages/ui/dropdown/src/dropdown.types.ts b/packages/ui/dropdown/src/dropdown.types.ts index 3166d863b..15d281e88 100644 --- a/packages/ui/dropdown/src/dropdown.types.ts +++ b/packages/ui/dropdown/src/dropdown.types.ts @@ -270,9 +270,17 @@ interface DropdownProps */ searchPlaceholder?: string /** - * arrow in dropdown + * Arrow in dropdown button */ arrow?: boolean + /** + * Dropdown arrow in dropdown + */ + dropdownArrow?: boolean + /** + * Button props + */ + _buttonProps?: ButtonProps } // Type definition for the modal handling functions diff --git a/packages/ui/navigation/src/navigation-user.tsx b/packages/ui/navigation/src/navigation-user.tsx index 70eee8d0d..141a33fdd 100644 --- a/packages/ui/navigation/src/navigation-user.tsx +++ b/packages/ui/navigation/src/navigation-user.tsx @@ -65,7 +65,7 @@ const NavigationUser: React.FC = ({ trigger={userAvatarBtn} renderContentOnTop={true} menu={menu ?? []} - arrow={true} + dropdownArrow={true} className={generateCN("sui-navigation__dropdown", { split: splitLastItem, })} diff --git a/packages/ui/navigation/stories/navigation.stories.tsx b/packages/ui/navigation/stories/navigation.stories.tsx index e8b4aba02..688f62690 100644 --- a/packages/ui/navigation/stories/navigation.stories.tsx +++ b/packages/ui/navigation/stories/navigation.stories.tsx @@ -85,8 +85,9 @@ export const Navigation = (props: { actions={[ Date: Wed, 9 Oct 2024 12:32:56 +0530 Subject: [PATCH 05/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20props=20added=20for=20arrows.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_elements/_navigation-container.scss | 4 + packages/ui/navigation/src/navigation.tsx | 2 +- .../navigation/stories/navigation.stories.tsx | 285 ++++++++++++------ 3 files changed, 190 insertions(+), 101 deletions(-) diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss index 4f360471f..711d48219 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss @@ -46,6 +46,10 @@ .sui-dropdown { display: flex; } + + .sui-button { + margin: 0; + } } @include media(max-width, md) { diff --git a/packages/ui/navigation/src/navigation.tsx b/packages/ui/navigation/src/navigation.tsx index c1bb3878a..6bf395fcb 100644 --- a/packages/ui/navigation/src/navigation.tsx +++ b/packages/ui/navigation/src/navigation.tsx @@ -41,7 +41,7 @@ const Navigation: React.FC = ({ {/* Show actions */} {actions.length > 0 && actions.map((action, index) => action)} {/* Render the navigation user component */} - + {user && } ) diff --git a/packages/ui/navigation/stories/navigation.stories.tsx b/packages/ui/navigation/stories/navigation.stories.tsx index 688f62690..59ce3f6e7 100644 --- a/packages/ui/navigation/stories/navigation.stories.tsx +++ b/packages/ui/navigation/stories/navigation.stories.tsx @@ -23,13 +23,16 @@ export default { // Build story export const Navigation = (props: { + isPro: boolean + action: boolean status: NavigationUserProps["status"] isMenuDisabled: NavigationUserProps["isMenuDisabled"] plugin: PluginsSlug title: string description: string }) => { - const { status, isMenuDisabled, plugin, title, description } = props + const { action, isPro, status, isMenuDisabled, plugin, title, description } = + props return (
@@ -41,112 +44,188 @@ export const Navigation = (props: { title, description, }} - user={{ + {...(isPro && { user: { - image: "https://avatars.githubusercontent.com/u/14994452?v=4", - name: "John doe", - email: "john.doe@incsub.com", - }, - status, - isMenuDisabled, - splitLastItem: true, - menu: [ - { - id: "the-hub", - label: "The Hub", - props: { - icon: "PluginDefender", - }, + user: { + image: "https://avatars.githubusercontent.com/u/14994452?v=4", + name: "John doe", + email: "john.doe@incsub.com", }, - { - id: "product-roadmap", - label: "Product Roadmap", - props: { - icon: "PluginSmush", + status, + isMenuDisabled, + splitLastItem: true, + menu: [ + { + id: "the-hub", + label: "The Hub", + props: { + icon: "PluginDefender", + }, }, - }, - { - id: "product-roadmap", - label: "Unlock Pro features", - props: { - icon: "PluginSmush", - variation: "smush", + { + id: "product-roadmap", + label: "Product Roadmap", + props: { + icon: "PluginSmush", + }, }, - }, - { - id: "logout", - label: "Logout", - props: { - icon: "Exit", + { + id: "product-roadmap", + label: "Unlock Pro features", + props: { + icon: "PluginSmush", + variation: "smush", + }, }, - }, - ], - }} - actions={[ - +
+ +
+
, + ], + })} + {...(action && + !isPro && { + actions: [ + -
- -
-
, - ]} +
+ +
+ , + , + ], + })} > -
@@ -180,6 +251,8 @@ export const Navigation = (props: { } Navigation.args = { + isPro: false, + action: false, isMenuDisabled: false, status: "confirmed", plugin: "smush", @@ -188,6 +261,18 @@ Navigation.args = { } Navigation.argTypes = { + isPro: { + name: "Pro", + control: { + type: "boolean", + }, + }, + action: { + name: "Action buttons", + control: { + type: "boolean", + }, + }, isMenuDisabled: { name: "Menu Disabled", control: { From e1cfd9be6906568ee986d63c9ef7cbe589f415e7 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Thu, 10 Oct 2024 09:05:26 +0530 Subject: [PATCH 06/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20mobile=20actions=20added.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_elements/_navigation-container.scss | 13 ++ .../_elements/_navigation-nav.scss | 4 +- packages/ui/navigation/src/navigation.tsx | 6 + .../ui/navigation/src/navigation.types.ts | 4 + .../navigation/stories/navigation.stories.tsx | 134 +++++++++++++++++- 5 files changed, 157 insertions(+), 4 deletions(-) diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss index 711d48219..67536d3fd 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss @@ -50,6 +50,19 @@ .sui-button { margin: 0; } + + @include media(max-width, sm) { + display: none; + } + + @include modifier(mobile) { + display: none; + @include media(max-width, sm) { + display: block; + border-left: 0; + padding-left: 0; + } + } } @include media(max-width, md) { diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-nav.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-nav.scss index 4b35bb8cc..da35ea1e6 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-nav.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-nav.scss @@ -19,8 +19,8 @@ gap: $spacing-md; margin: 0; - @include media(max-width, md) { - gap: $spacing-lg; + @include media(max-width, sm) { + display: none; } } diff --git a/packages/ui/navigation/src/navigation.tsx b/packages/ui/navigation/src/navigation.tsx index 6bf395fcb..c7e6caef6 100644 --- a/packages/ui/navigation/src/navigation.tsx +++ b/packages/ui/navigation/src/navigation.tsx @@ -13,6 +13,7 @@ const Navigation: React.FC = ({ brand = { title: "title", description: "" }, user, actions = [], + mobileActions = [], _htmlProps, _style, }) => { @@ -43,6 +44,11 @@ const Navigation: React.FC = ({ {/* Render the navigation user component */} {user && } +
+ {/* Show actions */} + {mobileActions.length > 0 && + mobileActions.map((action, index) => action)} +
) } diff --git a/packages/ui/navigation/src/navigation.types.ts b/packages/ui/navigation/src/navigation.types.ts index 6ec249177..0c144a8a3 100644 --- a/packages/ui/navigation/src/navigation.types.ts +++ b/packages/ui/navigation/src/navigation.types.ts @@ -116,6 +116,10 @@ interface NavigationProps * Navigation actions list */ actions?: ReactNode[] + /** + * Navigation actions list + */ + mobileActions?: ReactNode[] } export type { NavigationProps, NavigationBrandProps, NavigationUserProps } diff --git a/packages/ui/navigation/stories/navigation.stories.tsx b/packages/ui/navigation/stories/navigation.stories.tsx index 59ce3f6e7..6a0a036de 100644 --- a/packages/ui/navigation/stories/navigation.stories.tsx +++ b/packages/ui/navigation/stories/navigation.stories.tsx @@ -154,6 +154,71 @@ export const Navigation = (props: {
, ], + mobileActions: [ + +
+ +
+
, + ], })} {...(action && !isPro && { @@ -225,6 +290,71 @@ export const Navigation = (props: { Upgrade to pro , ], + mobileActions: [ + +
+ +
+
, + ], })} > + + + + + ) +} + // Build story export const Navigation = (props: { isPro: boolean @@ -31,6 +72,9 @@ export const Navigation = (props: { title: string description: string }) => { + const ref = createRef() + const refLogoDrawer = createRef() + const { action, isPro, status, isMenuDisabled, plugin, title, description } = props @@ -38,6 +82,15 @@ export const Navigation = (props: {
+ <_internalDrawer + toggleRef={ref} + {...props} + placement="left" + title="Drawer title" + desc="Drawer for body container, it is fixed positioned" + hasContainer={true} + disableShadow={true} + /> , ], mobileActions: [ - { + refLogoDrawer?.current?.toggle() + }} > -
- -
-
, + WPMUDEV Logo + , + , ], })} {...(action && @@ -374,6 +388,15 @@ export const Navigation = (props: { Documentation
+ <_internalDrawer + toggleRef={refLogoDrawer} + {...props} + placement="left" + title="Drawer title" + desc="Drawer for body container, it is fixed positioned" + hasContainer={true} + disableShadow={true} + />
From 9c8193a60880bd6ddb601ad9117cbccf31e83a78 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Thu, 10 Oct 2024 11:45:52 +0530 Subject: [PATCH 08/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20mobile=20actions=20added.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_elements/_navigation-container.scss | 7 + packages/ui/navigation/src/navigation.tsx | 65 +- .../ui/navigation/src/navigation.types.ts | 4 + .../navigation/stories/navigation.stories.tsx | 638 +++++++++--------- 4 files changed, 385 insertions(+), 329 deletions(-) diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss index cb55e6b80..a3631096a 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss @@ -36,6 +36,13 @@ } } + @include element(drawer) { + .sui-drawer { + top: 118px; + border-top: $border-width-sm solid $color-extended-neutral-80; + } + } + @include element(actions) { display: flex; align-items: center; diff --git a/packages/ui/navigation/src/navigation.tsx b/packages/ui/navigation/src/navigation.tsx index c7e6caef6..11aef8491 100644 --- a/packages/ui/navigation/src/navigation.tsx +++ b/packages/ui/navigation/src/navigation.tsx @@ -14,6 +14,7 @@ const Navigation: React.FC = ({ user, actions = [], mobileActions = [], + mobileDrawer = [], _htmlProps, _style, }) => { @@ -23,33 +24,43 @@ const Navigation: React.FC = ({ return ( // Render the navigation component - + <> + + {mobileDrawer.length > 0 && + mobileDrawer.map((action, index) => { + return ( +
+ {action} +
+ ) + })} + ) } diff --git a/packages/ui/navigation/src/navigation.types.ts b/packages/ui/navigation/src/navigation.types.ts index 0c144a8a3..62cdb506e 100644 --- a/packages/ui/navigation/src/navigation.types.ts +++ b/packages/ui/navigation/src/navigation.types.ts @@ -120,6 +120,10 @@ interface NavigationProps * Navigation actions list */ mobileActions?: ReactNode[] + /** + * Navigation actions list + */ + mobileDrawer?: ReactNode[] } export type { NavigationProps, NavigationBrandProps, NavigationUserProps } diff --git a/packages/ui/navigation/stories/navigation.stories.tsx b/packages/ui/navigation/stories/navigation.stories.tsx index 6e9ba0006..972972ac3 100644 --- a/packages/ui/navigation/stories/navigation.stories.tsx +++ b/packages/ui/navigation/stories/navigation.stories.tsx @@ -62,6 +62,39 @@ const _internalDrawer = ({ ) } +const _internalDrawerLogo = ({ + toggleRef, + title = "Drawer header", + desc = "", + ...props +}: { + toggleRef: RefObject + title: string + desc: string + [key: string]: any +}) => { + return ( + + +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque + rutrum sem eros, sed tempor sapien porta ac. Nullam purus metus. +
+
+ +
+ + +
+
+
+ ) +} + // Build story export const Navigation = (props: { isPro: boolean @@ -81,323 +114,324 @@ export const Navigation = (props: { return (
-
- <_internalDrawer - toggleRef={ref} - {...props} - placement="left" - title="Drawer title" - desc="Drawer for body container, it is fixed positioned" - hasContainer={true} - disableShadow={true} - /> - + -
- -
- , - ], - mobileActions: [ - , - , - ], - })} - {...(action && - !isPro && { - actions: [ - + Unlock bonus features + +
+ , + ], + mobileActions: [ + , + , + ], + })} + {...(action && + !isPro && { + actions: [ + +
-
- -
- , - , - ], - mobileActions: [ - +
+
, + , + ], + mobileActions: [ + +
-
- -
- , - ], - })} + Unlock bonus features + +
+
, + ], + })} + mobileDrawer={[ + <_internalDrawerLogo + key="logo-drawer" + toggleRef={refLogoDrawer} + {...props} + placement="left" + title="Drawer title" + desc="Drawer for body container, it is fixed positioned" + hasContainer={true} + disableShadow={true} + />, + ]} + > + - - - <_internalDrawer - toggleRef={refLogoDrawer} - {...props} - placement="left" - title="Drawer title" - desc="Drawer for body container, it is fixed positioned" - hasContainer={true} - disableShadow={true} - /> -
+ Help + + +
) From 92276a457c2edd90abe6e46d9e8e546895945c4e Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Thu, 10 Oct 2024 12:15:56 +0530 Subject: [PATCH 09/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20mobile=20actions=20added.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/ui/navigation/src/navigation.tsx | 65 ++++++++----------- .../navigation/stories/navigation.stories.tsx | 25 +++---- 2 files changed, 41 insertions(+), 49 deletions(-) diff --git a/packages/ui/navigation/src/navigation.tsx b/packages/ui/navigation/src/navigation.tsx index 11aef8491..853c3f47d 100644 --- a/packages/ui/navigation/src/navigation.tsx +++ b/packages/ui/navigation/src/navigation.tsx @@ -24,43 +24,34 @@ const Navigation: React.FC = ({ return ( // Render the navigation component - <> - - {mobileDrawer.length > 0 && - mobileDrawer.map((action, index) => { - return ( -
- {action} -
- ) - })} - + + ) } diff --git a/packages/ui/navigation/stories/navigation.stories.tsx b/packages/ui/navigation/stories/navigation.stories.tsx index 972972ac3..f2acf2453 100644 --- a/packages/ui/navigation/stories/navigation.stories.tsx +++ b/packages/ui/navigation/stories/navigation.stories.tsx @@ -402,18 +402,6 @@ export const Navigation = (props: { , ], })} - mobileDrawer={[ - <_internalDrawerLogo - key="logo-drawer" - toggleRef={refLogoDrawer} - {...props} - placement="left" - title="Drawer title" - desc="Drawer for body container, it is fixed positioned" - hasContainer={true} - disableShadow={true} - />, - ]} > + {mobileDrawer} + + ) +} + +// Export the MoreFromWPMUDEV component +export { MoreFromWPMUDEV } diff --git a/packages/common/modules/src/more-from-wpmudev/types.ts b/packages/common/modules/src/more-from-wpmudev/types.ts new file mode 100644 index 000000000..984a55472 --- /dev/null +++ b/packages/common/modules/src/more-from-wpmudev/types.ts @@ -0,0 +1,34 @@ +import { + SuiHTMLAttributes, + SuiStyleType, + PluginsSlug, +} from "@wpmudev/sui-utils" +import { DropdownProps } from "@wpmudev/sui-dropdown" + +/** + * Represents a plugin's details. + */ +type Plugin = { + plugin: PluginsSlug + title: string + description: string + link: string + props?: SuiHTMLAttributes +} + +/** + * Represents the properties for a dropdown component. + */ +interface WPMUDEVProps extends DropdownProps, SuiStyleType { + title?: string + plugins?: Plugin[] + upsell?: { + link: string + title: string + description: string + props?: SuiHTMLAttributes + } + filter?: PluginsSlug[] +} + +export type { WPMUDEVProps } diff --git a/packages/common/modules/src/more-from-wpmudev/upsell-icon.tsx b/packages/common/modules/src/more-from-wpmudev/upsell-icon.tsx new file mode 100644 index 000000000..2d22e0fc1 --- /dev/null +++ b/packages/common/modules/src/more-from-wpmudev/upsell-icon.tsx @@ -0,0 +1,314 @@ +import React from "react" + +const UpsellIcon = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export { UpsellIcon } diff --git a/packages/ui/drawer/src/drawer-header.tsx b/packages/ui/drawer/src/drawer-header.tsx index f7420d840..034b83178 100644 --- a/packages/ui/drawer/src/drawer-header.tsx +++ b/packages/ui/drawer/src/drawer-header.tsx @@ -10,6 +10,7 @@ const DrawerHeader = ({ className = "", title = "", hintText = "", + hasBack = false, tooltipOptions = {}, _style, }: DrawerHeaderTypes) => { @@ -26,6 +27,19 @@ const DrawerHeader = ({ return (
+ {hasBack && ( + -
- , + , ], mobileActions: [ -
- , + , , From b190c9e551eaf5e2577f24589582b41bde836c58 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Mon, 14 Oct 2024 10:44:47 +0530 Subject: [PATCH 11/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20added=20ne?= =?UTF-8?q?w=20component=20more=20from=20wpmudev=20for=20navigatio0n.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_drawer/_elements/_drawer-container.scss | 6 +++ .../_elements/_navigation-container.scss | 22 +++++----- .../_wpmudev/_elements/_wpmudev-list.scss | 27 ++++++++++-- .../modules/src/more-from-wpmudev/index.tsx | 43 +++++++++++-------- packages/ui/drawer/src/drawer-header.tsx | 6 ++- packages/ui/drawer/src/drawer.tsx | 5 ++- packages/ui/drawer/src/drawer.types.ts | 15 +++++++ 7 files changed, 90 insertions(+), 34 deletions(-) diff --git a/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-container.scss b/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-container.scss index 4442387c6..a9e1ae5a0 100644 --- a/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-container.scss +++ b/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-container.scss @@ -21,6 +21,12 @@ background: $color-extended-alpha-grey-90; } + @include modifier(full) { + @include modifies-element(inner) { + width: 100%; + } + } + @include modifier(has-container) { z-index: 1; width: $drawer-size-lg; diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss index a3631096a..8e7a3f893 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss @@ -58,18 +58,18 @@ margin: 0; } - @include media(max-width, sm) { - display: none; - } + // @include media(max-width, sm) { + // display: none; + // } - @include modifier(mobile) { - display: none; - @include media(max-width, sm) { - display: flex; - border-left: 0; - padding-left: 0; - } - } + // @include modifier(mobile) { + // display: none; + // @include media(max-width, sm) { + // display: flex; + // border-left: 0; + // padding-left: 0; + // } + // } } @include media(max-width, md) { diff --git a/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss b/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss index f62e2d81c..bcbc7b576 100644 --- a/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss +++ b/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss @@ -13,19 +13,25 @@ @include sui-class($rtl: false, $theme: null) { @include block($block) { .sui-dropdown__popover { - padding: $spacing-xl; margin-top: 2px; } + @include element(title, dropdown-content) { + padding: $spacing-xl; + } + @include element(title) { padding-bottom: $spacing-xl; } @include element(list) { display: grid; - grid-template-columns: auto auto; gap: $spacing-lg; - margin: $spacing-xl 0 $spacing-lg; + margin: 0 0 $spacing-lg; + + @include media(min-width, sm) { + grid-template-columns: auto auto; + } } @include element(list-item) { @@ -79,6 +85,21 @@ flex-direction: column; gap: $spacing-sm; } + + @include element(drawer) { + @include media(min-width, md) { + display: none; + } + } + + @include element(dropdown) { + &.sui-dropdown { + display: none; + @include media(min-width, md) { + display: block; + } + } + } } } } diff --git a/packages/common/modules/src/more-from-wpmudev/index.tsx b/packages/common/modules/src/more-from-wpmudev/index.tsx index 9eee99901..308089b74 100644 --- a/packages/common/modules/src/more-from-wpmudev/index.tsx +++ b/packages/common/modules/src/more-from-wpmudev/index.tsx @@ -15,7 +15,6 @@ import { Drawer, DrawerActions, DrawerBody, - DrawerFooter, DrawerHeader, } from "@wpmudev/sui-drawer" @@ -102,14 +101,18 @@ const MoreFromWPMUDEV: React.FC = ({ }) => { const drawerRef = createRef() - const classNames = generateCN("sui-wpmudev", {}, className) + const classNames = generateCN( + "sui-wpmudev", + {}, + `sui-wpmudev__dropdown ${className}`, + ) const filteredPlugins = plugins.filter( (pluginItem) => !filter.includes(pluginItem.plugin), ) const dropdownContent = ( - <> +
{filteredPlugins && (
    {filteredPlugins.map((pluginItem) => { @@ -170,7 +173,7 @@ const MoreFromWPMUDEV: React.FC = ({
)} - + ) const mobileDrawer = ( @@ -178,7 +181,9 @@ const MoreFromWPMUDEV: React.FC = ({ ref={drawerRef} placement="left" hasContainer={false} + hasOverlay={false} disableShadow={true} + isFullWidth={true} > {dropdownContent} @@ -191,7 +196,6 @@ const MoreFromWPMUDEV: React.FC = ({ label={label} placement="left" buttonIcon="Logo" - isResponsive={true} arrow={false} menuCustomWidth={584} className={classNames} @@ -205,19 +209,22 @@ const MoreFromWPMUDEV: React.FC = ({ )} {dropdownContent} - - {mobileDrawer} +
+ + {mobileDrawer} +
) } diff --git a/packages/ui/drawer/src/drawer-header.tsx b/packages/ui/drawer/src/drawer-header.tsx index 034b83178..062259988 100644 --- a/packages/ui/drawer/src/drawer-header.tsx +++ b/packages/ui/drawer/src/drawer-header.tsx @@ -11,6 +11,7 @@ const DrawerHeader = ({ title = "", hintText = "", hasBack = false, + onBack = () => {}, tooltipOptions = {}, _style, }: DrawerHeaderTypes) => { @@ -34,7 +35,10 @@ const DrawerHeader = ({ colorScheme="black" isSmall={true} iconOnly={true} - onClick={onClose} + onClick={() => { + onClose() + onBack() + }} _htmlProps={{ "aria-label": "close", }} diff --git a/packages/ui/drawer/src/drawer.tsx b/packages/ui/drawer/src/drawer.tsx index 38aaa7b41..a77663e40 100644 --- a/packages/ui/drawer/src/drawer.tsx +++ b/packages/ui/drawer/src/drawer.tsx @@ -24,8 +24,10 @@ const Drawer = forwardRef( size = "default", placement = "right", hasContainer = false, + hasOverlay = true, disableShadow = false, outerClickClose = true, + isFullWidth = false, _htmlProps, _style, }, @@ -54,10 +56,11 @@ const Drawer = forwardRef( open: isOpen, "has-container": !!hasContainer, "no-shadow": !!disableShadow, - overlay: !hasContainer, + overlay: !hasContainer && hasOverlay, hidden: !isVisible, [size]: !!size, [placement]: !!placement, + full: isFullWidth, }, suiInlineClassname, ) diff --git a/packages/ui/drawer/src/drawer.types.ts b/packages/ui/drawer/src/drawer.types.ts index c02f88243..e2729a30f 100644 --- a/packages/ui/drawer/src/drawer.types.ts +++ b/packages/ui/drawer/src/drawer.types.ts @@ -27,6 +27,11 @@ export interface DrawerTypes */ isOpen?: boolean + /** + * Indicates whether the Drawer is open or not + */ + isFullWidth?: boolean + /** * Size of the Drawer, default is "default" or can be "sm" */ @@ -42,6 +47,11 @@ export interface DrawerTypes */ hasContainer?: boolean + /** + * Indicates whether the Drawer has a container + */ + hasOverlay?: boolean + /** * Indicates whether shadow should be disabled for the Drawer */ @@ -72,6 +82,11 @@ export interface DrawerHeaderTypes extends SuiStyleType { */ hasBack?: boolean + /** + * Has back button. + */ + onBack?: () => void + /** * Optional hint text to be displayed */ From 0a809cd45e3d05ba328c6f302d6ba62400163711 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Tue, 15 Oct 2024 08:29:22 +0530 Subject: [PATCH 12/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20cleaning?= =?UTF-8?q?=20up=20navigation=20component.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/common/modules/src/index.ts | 3 +- packages/ui/navigation-wpmudev/.gitignore | 11 + packages/ui/navigation-wpmudev/CHANGELOG.md | 26 ++ packages/ui/navigation-wpmudev/LICENSE | 339 +++++++++++++++ packages/ui/navigation-wpmudev/README.md | 13 + .../__tests__/navigation.test.tsx | 73 ++++ packages/ui/navigation-wpmudev/package.json | 64 +++ packages/ui/navigation-wpmudev/src/index.ts | 2 + .../src/more-from-wpmudev/index.tsx | 233 ++++++++++ .../src/more-from-wpmudev/types.ts | 34 ++ .../src/more-from-wpmudev/upsell-icon.tsx | 314 ++++++++++++++ .../src/navigation-brand.tsx | 48 +++ .../src/navigation-user.tsx | 81 ++++ .../ui/navigation-wpmudev/src/navigation.tsx | 58 +++ .../src/navigation.types.ts | 129 ++++++ .../stories/images/accounts-states.svg | 154 +++++++ .../stories/images/anatomy.svg | 34 ++ .../stories/images/behaviour.svg | 122 ++++++ .../stories/images/max-width.svg | 109 +++++ .../stories/images/spacing.svg | 215 +++++++++ .../navigation-wpmudev/stories/navigation.mdx | 24 ++ .../stories/navigation.stories.tsx | 408 ++++++++++++++++++ .../stories/tabs/TabCode.mdx | 87 ++++ .../stories/tabs/TabExamples.mdx | 281 ++++++++++++ .../stories/tabs/TabUsage.mdx | 50 +++ packages/ui/navigation/src/navigation.tsx | 7 - .../ui/navigation/src/navigation.types.ts | 8 - 27 files changed, 2910 insertions(+), 17 deletions(-) create mode 100644 packages/ui/navigation-wpmudev/.gitignore create mode 100644 packages/ui/navigation-wpmudev/CHANGELOG.md create mode 100644 packages/ui/navigation-wpmudev/LICENSE create mode 100644 packages/ui/navigation-wpmudev/README.md create mode 100644 packages/ui/navigation-wpmudev/__tests__/navigation.test.tsx create mode 100644 packages/ui/navigation-wpmudev/package.json create mode 100644 packages/ui/navigation-wpmudev/src/index.ts create mode 100644 packages/ui/navigation-wpmudev/src/more-from-wpmudev/index.tsx create mode 100644 packages/ui/navigation-wpmudev/src/more-from-wpmudev/types.ts create mode 100644 packages/ui/navigation-wpmudev/src/more-from-wpmudev/upsell-icon.tsx create mode 100644 packages/ui/navigation-wpmudev/src/navigation-brand.tsx create mode 100644 packages/ui/navigation-wpmudev/src/navigation-user.tsx create mode 100644 packages/ui/navigation-wpmudev/src/navigation.tsx create mode 100644 packages/ui/navigation-wpmudev/src/navigation.types.ts create mode 100644 packages/ui/navigation-wpmudev/stories/images/accounts-states.svg create mode 100644 packages/ui/navigation-wpmudev/stories/images/anatomy.svg create mode 100644 packages/ui/navigation-wpmudev/stories/images/behaviour.svg create mode 100644 packages/ui/navigation-wpmudev/stories/images/max-width.svg create mode 100644 packages/ui/navigation-wpmudev/stories/images/spacing.svg create mode 100644 packages/ui/navigation-wpmudev/stories/navigation.mdx create mode 100644 packages/ui/navigation-wpmudev/stories/navigation.stories.tsx create mode 100644 packages/ui/navigation-wpmudev/stories/tabs/TabCode.mdx create mode 100644 packages/ui/navigation-wpmudev/stories/tabs/TabExamples.mdx create mode 100644 packages/ui/navigation-wpmudev/stories/tabs/TabUsage.mdx diff --git a/packages/common/modules/src/index.ts b/packages/common/modules/src/index.ts index 15c491828..057423d18 100644 --- a/packages/common/modules/src/index.ts +++ b/packages/common/modules/src/index.ts @@ -2,6 +2,5 @@ import * as Table from "@wpmudev/sui-table" import * as DashboardWidget from "@wpmudev/sui-dashboard-widget" import * as Navigation from "@wpmudev/sui-navigation" import * as Integration from "@wpmudev/sui-integration" -import { MoreFromWPMUDEV } from "./more-from-wpmudev" -export { Table, DashboardWidget, Navigation, Integration, MoreFromWPMUDEV } +export { Table, DashboardWidget, Navigation, Integration } diff --git a/packages/ui/navigation-wpmudev/.gitignore b/packages/ui/navigation-wpmudev/.gitignore new file mode 100644 index 000000000..18ff8e72c --- /dev/null +++ b/packages/ui/navigation-wpmudev/.gitignore @@ -0,0 +1,11 @@ +# Ignore error logs. +*.log +.dccache + +# Ignore test package. +*.tgz +/package + +# Miscellaneous. +node_modules +.DS_Store diff --git a/packages/ui/navigation-wpmudev/CHANGELOG.md b/packages/ui/navigation-wpmudev/CHANGELOG.md new file mode 100644 index 000000000..287186974 --- /dev/null +++ b/packages/ui/navigation-wpmudev/CHANGELOG.md @@ -0,0 +1,26 @@ +# Change Log + +## 0.0.1 + +### Patch Changes + +- Initial release +- Updated dependencies + - @wpmudev/sui-icons@0.0.1 + - @wpmudev/sui-avatar@0.0.1 + - @wpmudev/sui-button@0.0.1 + - @wpmudev/sui-dropdown@0.0.1 + - @wpmudev/sui-utils@0.0.1 + +All notable changes to this project will be documented in this file. See +[Conventional Commits](https://conventionalcommits.org/) for commit guidelines. + +## v1.0.0 (Unreleased) + +#### ✨ New Features + +- feat: Initial release ([@iamleigh](https://github.com/iamleigh)) + +#### Committers: 1 + +- Leighton Sapir ([@iamleigh](https://github.com/iamleigh)) diff --git a/packages/ui/navigation-wpmudev/LICENSE b/packages/ui/navigation-wpmudev/LICENSE new file mode 100644 index 000000000..d159169d1 --- /dev/null +++ b/packages/ui/navigation-wpmudev/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/packages/ui/navigation-wpmudev/README.md b/packages/ui/navigation-wpmudev/README.md new file mode 100644 index 000000000..2d15c09e2 --- /dev/null +++ b/packages/ui/navigation-wpmudev/README.md @@ -0,0 +1,13 @@ +

@wpmudev/sui-navigation

+ +
+Version License +
+

Description

The Navigation component provides a user-friendly and intuitive way to navigate through different sections + + +[![-----------------------------------------------------](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/colored.png)](#license) + +## ➤ License + +Licensed under [GPL-2.0](https://opensource.org/licenses/GPL-2.0). diff --git a/packages/ui/navigation-wpmudev/__tests__/navigation.test.tsx b/packages/ui/navigation-wpmudev/__tests__/navigation.test.tsx new file mode 100644 index 000000000..9740711a1 --- /dev/null +++ b/packages/ui/navigation-wpmudev/__tests__/navigation.test.tsx @@ -0,0 +1,73 @@ +import React, { Fragment } from "react" +import "@testing-library/jest-dom" +import { screen, render } from "@testing-library/react" +import { a11yTest } from "@wpmudev/sui-utils" +import { Navigation } from "../src" + +describe("@wpmudev/sui-navigation", () => { + const Component = () => ( + ACTIONS list]} + brand={{ + title: "Smush Pro", + description: "Description for Smush Pro", + }} + user={{ + user: { + image: "https://avatars.githubusercontent.com/u/14994452?v=4", + name: "John doe", + email: "john.doe@incsub.com", + }, + menu: [ + { + id: "the-hub", + label: "The Hub", + props: { + icon: "PluginDefender", + }, + }, + { + id: "product-roadmap", + label: "Product Roadmap", + props: { + icon: "PluginSmush", + }, + }, + { + id: "product-roadmap", + label: "Unlock Pro features", + props: { + icon: "PluginSmush", + variation: "smush", + }, + }, + ], + }} + > + CUSTOM CONTENT + + ) + + beforeEach(() => { + render() + }) + + it("renders correctly", () => { + expect(screen.getByTestId("navigation")).toBeInTheDocument() + }) + + it("brand prop renders correctly", () => { + expect(screen.getByText("Smush Pro")).toBeVisible() + expect(screen.getByText("Description for Smush Pro")).toBeVisible() + }) + + it("user prop renders correctly", () => { + expect(screen.getByText("John doe")).toBeVisible() + expect(screen.getByText("john.doe@incsub.com")).toBeVisible() + }) + + // eslint-disable-next-line jest/expect-expect + it("passes a11y test", async () => { + await a11yTest() + }) +}) diff --git a/packages/ui/navigation-wpmudev/package.json b/packages/ui/navigation-wpmudev/package.json new file mode 100644 index 000000000..880cfdf41 --- /dev/null +++ b/packages/ui/navigation-wpmudev/package.json @@ -0,0 +1,64 @@ +{ + "name": "@wpmudev/sui-navigation-wpmudev", + "version": "0.0.1", + "description": "The Navigation component provides a user-friendly and intuitive way to navigate through different sections", + "keywords": [], + "author": "WPMU DEV (https://wpmudev.com)", + "contributors": [ + { + "name": "Govind Kumar", + "email": "gkprmr@gmail.com", + "url": "https://govind.js.org" + }, + { + "name": "Pawan Kumar", + "email": "40248406+creador-dev@users.noreply.github.com", + "url": "https://creador.dev/" + }, + { + "name": "Abderrahman DOUARA", + "email": "aer17013@gmail.com", + "url": "https://douara.me" + } + ], + "license": "GPL-2.0", + "main": "src/index.ts", + "directories": { + "src": "src", + "test": "__tests__" + }, + "files": [ + "dist" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/wpmudev/sui-react.git", + "directory": "packages/navigation" + }, + "scripts": { + "clean": "rm -rf dist && rm -rf lib", + "build": "npx tsup", + "build:dev": "npx tsup --watch", + "build:fast": "tsup src", + "dev": "npm build:fast -- --watch", + "prepack": "clean-package", + "postpack": "clean-package restore", + "build:readme": "readme generate --input ../../../blueprint.md" + }, + "bugs": { + "url": "https://github.com/wpmudev/sui-react/issues" + }, + "homepage": "https://github.com/wpmudev/sui-react#readme", + "clean-package": "../../../postpack.config.json", + "dependencies": { + "@wpmudev/sui-avatar": "^0.0.1", + "@wpmudev/sui-icon": "^0.0.1", + "@wpmudev/sui-dropdown": "^0.0.1", + "@wpmudev/sui-icons": "^0.0.1", + "@wpmudev/sui-utils": "^0.0.1", + "react": "^18.2.0" + } +} diff --git a/packages/ui/navigation-wpmudev/src/index.ts b/packages/ui/navigation-wpmudev/src/index.ts new file mode 100644 index 000000000..039a63e3b --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/index.ts @@ -0,0 +1,2 @@ +export { Navigation } from "./navigation" +export type { NavigationProps, NavigationUserProps } from "./navigation.types" diff --git a/packages/ui/navigation-wpmudev/src/more-from-wpmudev/index.tsx b/packages/ui/navigation-wpmudev/src/more-from-wpmudev/index.tsx new file mode 100644 index 000000000..308089b74 --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/more-from-wpmudev/index.tsx @@ -0,0 +1,233 @@ +import React, { createRef } from "react" +import { Dropdown } from "@wpmudev/sui-dropdown" +import { Button } from "@wpmudev/sui-button" +import { + _renderHTMLPropsSafely, + generateCN, + PluginIconTypes, + PluginsIcons, +} from "@wpmudev/sui-utils" +import { IconProps } from "@wpmudev/sui-icon" +import Icons, { IconsNamesType, ExternalLink } from "@wpmudev/sui-icons" +import { WPMUDEVProps } from "./types" +import { UpsellIcon } from "./upsell-icon" +import { + Drawer, + DrawerActions, + DrawerBody, + DrawerHeader, +} from "@wpmudev/sui-drawer" + +const MoreFromWPMUDEV: React.FC = ({ + label = "More from WPMU DEV", + title = "More free plugins from WPMU DEV", + className = "", + plugins = [ + { + plugin: "smush", + title: "Smush", + description: "Best image optimization", + link: "https://www.wpmudev.com", + props: {}, + }, + { + plugin: "forminator", + title: "Forminator", + description: "Best form builder plugin", + link: "https://www.wpmudev.com", + props: {}, + }, + { + plugin: "defender", + title: "Defender", + description: "Best security plugin", + link: "https://www.wpmudev.com", + props: {}, + }, + { + plugin: "hustle", + title: "Hustle", + description: "Best newsletter plugin", + link: "https://www.wpmudev.com", + props: {}, + }, + { + plugin: "hummingbird", + title: "Hummingbird", + description: "Best security plugin", + link: "https://www.wpmudev.com", + props: {}, + }, + { + plugin: "branda", + title: "Branda", + description: "No-code white label plugin", + link: "https://www.wpmudev.com", + props: {}, + }, + { + plugin: "beehive", + title: "Beehive", + description: "Google Analytic dashboards", + link: "https://www.wpmudev.com", + props: {}, + }, + { + plugin: "snapshot", + title: "Snapshot", + description: "WordPress backup plugin", + link: "https://www.wpmudev.com", + props: {}, + }, + { + plugin: "blc", + title: "Broken Link Checker", + description: "Scan broken links", + link: "https://www.wpmudev.com", + props: {}, + }, + ], + upsell = { + title: "Everything you need for WordPress", + description: + "Get all 12 WPMU DEV premium plugins and more starting from just $3/month.", + link: "https://www.wpmudev.com", + props: {}, + }, + filter = [], + _htmlProps = {}, + _style = {}, + ...props +}) => { + const drawerRef = createRef() + + const classNames = generateCN( + "sui-wpmudev", + {}, + `sui-wpmudev__dropdown ${className}`, + ) + + const filteredPlugins = plugins.filter( + (pluginItem) => !filter.includes(pluginItem.plugin), + ) + + const dropdownContent = ( +
+ {filteredPlugins && ( +
    + {filteredPlugins.map((pluginItem) => { + // Icon for the specified plugin or use a default "Plugin" icon. + const PluginIcon: PluginIconTypes = pluginItem.plugin + ? PluginsIcons?.[pluginItem.plugin] + : { icon: "Plugin" } + + // Dynamically determine the IconTag based on the provided icon prop. + let IconTag: React.ComponentType | null = null + if (!!PluginIcon) { + IconTag = Icons?.[PluginIcon.icon as IconsNamesType] + } + return ( +
  • + +
    + {!!IconTag && } +
    +
    +
    + {pluginItem.title} +
    +

    + {pluginItem.description} +

    +
    +
    +
  • + ) + })} +
+ )} + {upsell && ( + + +
+
+ {upsell.title} + +
+

{upsell.description}

+
+
+ )} +
+ ) + + const mobileDrawer = ( + + + {dropdownContent} + + ) + + return ( + <> + + {title && ( +
+

{title}

+
+ )} + {dropdownContent} +
+
+ + {mobileDrawer} +
+ + ) +} + +// Export the MoreFromWPMUDEV component +export { MoreFromWPMUDEV } diff --git a/packages/ui/navigation-wpmudev/src/more-from-wpmudev/types.ts b/packages/ui/navigation-wpmudev/src/more-from-wpmudev/types.ts new file mode 100644 index 000000000..984a55472 --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/more-from-wpmudev/types.ts @@ -0,0 +1,34 @@ +import { + SuiHTMLAttributes, + SuiStyleType, + PluginsSlug, +} from "@wpmudev/sui-utils" +import { DropdownProps } from "@wpmudev/sui-dropdown" + +/** + * Represents a plugin's details. + */ +type Plugin = { + plugin: PluginsSlug + title: string + description: string + link: string + props?: SuiHTMLAttributes +} + +/** + * Represents the properties for a dropdown component. + */ +interface WPMUDEVProps extends DropdownProps, SuiStyleType { + title?: string + plugins?: Plugin[] + upsell?: { + link: string + title: string + description: string + props?: SuiHTMLAttributes + } + filter?: PluginsSlug[] +} + +export type { WPMUDEVProps } diff --git a/packages/ui/navigation-wpmudev/src/more-from-wpmudev/upsell-icon.tsx b/packages/ui/navigation-wpmudev/src/more-from-wpmudev/upsell-icon.tsx new file mode 100644 index 000000000..2d22e0fc1 --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/more-from-wpmudev/upsell-icon.tsx @@ -0,0 +1,314 @@ +import React from "react" + +const UpsellIcon = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} + +export { UpsellIcon } diff --git a/packages/ui/navigation-wpmudev/src/navigation-brand.tsx b/packages/ui/navigation-wpmudev/src/navigation-brand.tsx new file mode 100644 index 000000000..e17696e03 --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/navigation-brand.tsx @@ -0,0 +1,48 @@ +import React from "react" + +import { + _renderHTMLPropsSafely, + generateCN, + PluginIconTypes, + PluginsIcons, +} from "@wpmudev/sui-utils" +import { IconProps } from "@wpmudev/sui-icon" +import { NavigationBrandProps } from "./navigation.types" +import Icons, { IconsNamesType } from "@wpmudev/sui-icons" +import { useStyles } from "@wpmudev/sui-hooks" + +const NavigationBrand: React.FC = ({ + plugin, + title = "", + description = "", +}) => { + // Icon for the specified plugin or use a default "Plugin" icon. + const PluginIcon: PluginIconTypes = plugin + ? PluginsIcons?.[plugin] + : { icon: "Plugin" } + + // Dynamically determine the IconTag based on the provided icon prop. + let IconTag: React.ComponentType | null = null + if (!!PluginIcon) { + IconTag = Icons?.[PluginIcon.icon as IconsNamesType] + } + + return ( +
+
+ {!!IconTag && } +
+
+

{title}

+ {description} +
+
+ ) +} + +NavigationBrand.displayName = "NavigationBrand" + +export { NavigationBrand } diff --git a/packages/ui/navigation-wpmudev/src/navigation-user.tsx b/packages/ui/navigation-wpmudev/src/navigation-user.tsx new file mode 100644 index 000000000..141a33fdd --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/navigation-user.tsx @@ -0,0 +1,81 @@ +import React, { useRef } from "react" + +import { Dropdown, DropdownRefProps } from "@wpmudev/sui-dropdown" +import { Avatar } from "@wpmudev/sui-avatar" + +import { NavigationUserProps } from "./navigation.types" +import { generateCN, isEmpty } from "@wpmudev/sui-utils" + +const NavigationUser: React.FC = ({ + user, + menu, + splitLastItem = false, + isMenuDisabled = false, + status, +}) => { + // Create a ref for the user dropdown button + const userBtnRef = useRef(null) + + // Define the user's avatar button component + const userAvatarBtn = ( + { + // Toggle the user dropdown when the avatar is clicked + userBtnRef?.current?.toggle() + }, + })} + /> + ) + + /** + * Get user block + */ + const getUserBlock = () => { + // Return null if both name and email are missing or empty + if (isEmpty(user?.name ?? "") && isEmpty(user?.email ?? "")) { + return null + } + + // Render otherwise + return ( +
+ {!isEmpty(user?.name ?? "") && ( +
{user?.name}
+ )} + {!isEmpty(user?.email ?? "") && ( +
{user?.email}
+ )} +
+ ) + } + + return ( +
+ + {getUserBlock()} + +
+ ) +} + +NavigationUser.displayName = "NavigationUser" + +export { NavigationUser } diff --git a/packages/ui/navigation-wpmudev/src/navigation.tsx b/packages/ui/navigation-wpmudev/src/navigation.tsx new file mode 100644 index 000000000..7fcbb7406 --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/navigation.tsx @@ -0,0 +1,58 @@ +import React, { Children } from "react" + +import { _renderHTMLPropsSafely, generateCN } from "@wpmudev/sui-utils" +import { NavigationProps } from "./navigation.types" +import { NavigationBrand } from "./navigation-brand" +import { NavigationUser } from "./navigation-user" +import { useStyles } from "@wpmudev/sui-hooks" + +// Navigation component +const Navigation: React.FC = ({ + children, + brand = { title: "title", description: "" }, + user, + actions = [], + mobileActions = [], + mobileDrawer = [], + _htmlProps, + _style, +}) => { + const { suiInlineClassname } = useStyles(_style) + // Generate CSS class names for the navigation component + const classNames = generateCN("sui-navigation", {}, suiInlineClassname) + + return ( + // Render the navigation component + + + ) +} + +// Export the Navigation component +export { Navigation } diff --git a/packages/ui/navigation-wpmudev/src/navigation.types.ts b/packages/ui/navigation-wpmudev/src/navigation.types.ts new file mode 100644 index 000000000..62cdb506e --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/navigation.types.ts @@ -0,0 +1,129 @@ +/* + * Props for the Notification component. + */ +import { ReactNode, HTMLProps } from "react" + +import { DropdownMenuItemProps } from "@wpmudev/sui-dropdown" + +import { + PluginsSlug, + SuiHTMLAttributes, + SuiStyleType, +} from "@wpmudev/sui-utils" + +import { AvatarProps } from "@wpmudev/sui-avatar" +import { useStylesTypes } from "@wpmudev/sui-hooks" + +// Represents the base props for a DropdownMenu component. +interface NavigationUserMenuBaseProps { + /* + * Unique identifier for the NavigationUser menu item. + */ + id: string | number + /* + * Content to display as the label for the NavigationUser menu item. + */ + label: ReactNode | string +} + +// Props for an individual item within the NavigationUser menu. +interface NavigationUserMenuItemProps extends NavigationUserMenuBaseProps { + /* + * Additional props for the underlying MenuItem component. + */ + props: Omit +} + +// Props for a group of NavigationUser menu items. +interface NavigationUserMenuGroupProps extends NavigationUserMenuBaseProps { + /* + * An array of NavigationUserMenuItemProps representing the items in the group. + */ + menus: Array +} + +interface NavigationBrandProps extends SuiStyleType, SuiHTMLAttributes { + /* + * Optional: Plugin information for the brand. + */ + plugin?: PluginsSlug + /* + * Optional: Title for the brand. + */ + title?: string + /* + * Optional: Description for the brand. + */ + description?: string +} + +type NavigationUserType = { + /* + * Image URL for the user's profile picture. + */ + image?: string + /* + * Name of the user. + */ + name?: string + /* + * Email address of the user. + */ + email?: string +} + +interface NavigationUserProps { + /* + * User information. + */ + user?: NavigationUserType + /* + * Array of menu items or groups in the user's navigation menu. + */ + menu?: Array + /* + * When set to true the menu will be disabled + */ + isMenuDisabled?: boolean + /* + * The user status + */ + status?: AvatarProps["status"] + /* + * Seperate last item from menu. + */ + splitLastItem?: boolean +} + +// interface definition for the Navigation +interface NavigationProps + extends SuiStyleType, + SuiHTMLAttributes> { + /* + * Brand information. + */ + brand?: NavigationBrandProps + /* + * Optional: Navigation content. + */ + children?: ReactNode + + /* + * Optional: User + */ + user?: NavigationUserProps + /** + * Navigation actions list + */ + actions?: ReactNode[] + /** + * Navigation actions list + */ + mobileActions?: ReactNode[] + /** + * Navigation actions list + */ + mobileDrawer?: ReactNode[] +} + +export type { NavigationProps, NavigationBrandProps, NavigationUserProps } diff --git a/packages/ui/navigation-wpmudev/stories/images/accounts-states.svg b/packages/ui/navigation-wpmudev/stories/images/accounts-states.svg new file mode 100644 index 000000000..295415860 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/images/accounts-states.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/ui/navigation-wpmudev/stories/images/anatomy.svg b/packages/ui/navigation-wpmudev/stories/images/anatomy.svg new file mode 100644 index 000000000..81f1f0c77 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/images/anatomy.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/ui/navigation-wpmudev/stories/images/behaviour.svg b/packages/ui/navigation-wpmudev/stories/images/behaviour.svg new file mode 100644 index 000000000..6eb32a6a2 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/images/behaviour.svg @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/ui/navigation-wpmudev/stories/images/max-width.svg b/packages/ui/navigation-wpmudev/stories/images/max-width.svg new file mode 100644 index 000000000..3f70cf296 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/images/max-width.svg @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/ui/navigation-wpmudev/stories/images/spacing.svg b/packages/ui/navigation-wpmudev/stories/images/spacing.svg new file mode 100644 index 000000000..fd5d5a681 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/images/spacing.svg @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/ui/navigation-wpmudev/stories/navigation.mdx b/packages/ui/navigation-wpmudev/stories/navigation.mdx new file mode 100644 index 000000000..8002e39c2 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/navigation.mdx @@ -0,0 +1,24 @@ +import { Page } from "@wpmudev/sui-docs" +import { Unstyled } from "@storybook/blocks" + +import TabUsage from "./tabs/TabUsage.mdx" +import TabCode from "./tabs/TabCode.mdx" +import TabExamples from "./tabs/TabExamples.mdx" + + + +
+ +
+
+ +
+
+ +
+
+
diff --git a/packages/ui/navigation-wpmudev/stories/navigation.stories.tsx b/packages/ui/navigation-wpmudev/stories/navigation.stories.tsx new file mode 100644 index 000000000..2383e5da9 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/navigation.stories.tsx @@ -0,0 +1,408 @@ +import React, { createRef, RefObject } from "react" + +// Import required component(s) +import { Navigation as SuiNavigation, NavigationUserProps } from "../src" +import { PluginsSlug } from "@wpmudev/sui-utils" +import { Button } from "@wpmudev/sui-button" +import { Dropdown } from "@wpmudev/sui-dropdown" +import { + Drawer, + DrawerActions, + DrawerBody, + DrawerFooter, + DrawerHeader, +} from "@wpmudev/sui-drawer" +import { MoreFromWPMUDEV } from "@wpmudev/sui-modules" + +// Import documentation main page +import docs from "./navigation.mdx" + +// Configure default options +export default { + title: "SUI/Components/Modules/Navigation", + component: SuiNavigation, + parameters: { + layout: "fullscreen", + docs: { + page: docs, + }, + }, +} + +const _internalDrawer = ({ + toggleRef, + title = "Drawer header", + desc = "", + ...props +}: { + toggleRef: RefObject + title: string + desc: string + [key: string]: any +}) => { + return ( + + + +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque + rutrum sem eros, sed tempor sapien porta ac. Nullam purus metus. +
+
+ +
+ + +
+
+
+ ) +} + +const _internalDrawerLogo = ({ + toggleRef, + title = "Drawer header", + desc = "", + ...props +}: { + toggleRef: RefObject + title: string + desc: string + [key: string]: any +}) => { + return ( + + +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque + rutrum sem eros, sed tempor sapien porta ac. Nullam purus metus. +
+
+ +
+ + +
+
+
+ ) +} + +// Build story +export const Navigation = (props: { + isPro: boolean + action: boolean + status: NavigationUserProps["status"] + isMenuDisabled: NavigationUserProps["isMenuDisabled"] + plugin: PluginsSlug + title: string + description: string +}) => { + const ref = createRef() + const refLogoDrawer = createRef() + + const { action, isPro, status, isMenuDisabled, plugin, title, description } = + props + + return ( +
+
+ <_internalDrawer + toggleRef={ref} + {...props} + placement="left" + title="Drawer title" + desc="Drawer for body container, it is fixed positioned" + hasContainer={true} + disableShadow={true} + /> + , + ], + mobileActions: [ + , + , + ], + })} + {...(action && + !isPro && { + actions: [ + , + , + ], + mobileActions: [ + +
+ +
+
, + ], + })} + > + + +
+ <_internalDrawerLogo + key="logo-drawer" + toggleRef={refLogoDrawer} + {...props} + placement="left" + title="Drawer title" + desc="Drawer for body container, it is fixed positioned" + hasContainer={true} + disableShadow={true} + _style={{ + top: "118px", + }} + /> +
+
+ ) +} + +Navigation.args = { + isPro: true, + action: true, + isMenuDisabled: false, + status: "confirmed", + plugin: "smush", + title: "Smush Pro", + description: "Description", +} + +Navigation.argTypes = { + isPro: { + name: "Pro", + control: { + type: "boolean", + }, + }, + action: { + name: "Action buttons", + control: { + type: "boolean", + }, + }, + isMenuDisabled: { + name: "Menu Disabled", + control: { + type: "boolean", + }, + }, + status: { + name: "User Status", + options: ["none", "confirmed", "awaiting", "not-accepted", "not-connected"], + control: { + type: "select", + labels: { + none: "None", + confirmed: "Confirmed", + awaiting: "Awaiting", + "not-accepted": "Not Accepted", + "not-connected": "Not Connected", + }, + }, + }, + plugin: { + name: "Plugin", + options: [ + "smush", + "defender", + "snapshot", + "hummingbird", + "forminator", + "beehive", + "hustle", + "smartcrawl", + "shipper", + "branda", + "blc", + "thc", + "dashboard", + ], + control: { + type: "select", + labels: { + smush: "smush", + defendre: "defender", + snapshot: "snapshot", + hummigbird: "hummingbird", + forminator: "forminator", + beehive: "beehive", + hustle: "hustle", + smartcrawl: "smartcrawl", + shipper: "shipper", + branda: "branda", + blc: "blc", + thc: "thc", + }, + }, + }, + title: { + name: "Title", + control: { + type: "text", + }, + }, + description: { + name: "Description", + control: { + type: "text", + }, + }, +} diff --git a/packages/ui/navigation-wpmudev/stories/tabs/TabCode.mdx b/packages/ui/navigation-wpmudev/stories/tabs/TabCode.mdx new file mode 100644 index 000000000..1fba62206 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/tabs/TabCode.mdx @@ -0,0 +1,87 @@ +import { Section, Row, Col, Table, List, Code, Tag, PackageInstallGuide, PropSection, CommonPropsNotice } from "@wpmudev/sui-docs" + + + +
+ +

+ Brand information, this represents one of our plugins, the object accepts + the following keys +

+

+ + + title* The plugin title + + } + /> + + description A subheading that + accompagnes the plugin title{" "} + + } + /> + +

+
+ + +

+ The user information, it accepts two keys +

+

+ + + user*: An object with an image, name and email + + } + /> + + status* + Indicates the user status and dispalys an icon for it, could be one of these values: + none + confirmed + awaiting + not-accepted + not-connected + + } + /> + + menu* An array of menu items + + } + /> + + isMenuDisabled* A boolean to indicate the state of the menu + + } + /> + +

+

+ Check the examples tab for more details +

+
+ + +

+ The content of the navigation, usually menu items and buttons +

+
+ +
+ + \ No newline at end of file diff --git a/packages/ui/navigation-wpmudev/stories/tabs/TabExamples.mdx b/packages/ui/navigation-wpmudev/stories/tabs/TabExamples.mdx new file mode 100644 index 000000000..7a72a34bc --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/tabs/TabExamples.mdx @@ -0,0 +1,281 @@ +import { Section, Switcher, Preview, Snippet, Code } from "@wpmudev/sui-docs" +import { Navigation } from "../../src" +import { Button } from "@wpmudev/sui-button" +import { Dropdown } from "@wpmudev/sui-dropdown" +import dedent from "dedent" + +export const generalCode = dedent` + + + + + { + console.log("DEBUG: Menu Item Clicked", id, e) + }} + menu={[ + { + id: "group-1", + label: "Extra Optimization", + menus: [ + { + id: "menu-2", + label: "Uptime Monitoring", + props: { + icon: "CheckAlt", + }, + }, + { + id: "menu-2", + label: "Site management tools", + props: {}, + }, + ], + }, + { + id: "group-2", + label: "Performance", + menus: [ + { + id: "menu-2", + label: "Uptime Monitoring", + props: {}, + }, + { + id: "menu-2", + label: "Site management tools", + props: {}, + }, + ], + }, + ]} + > +
+ +
+
+
+` + +
+

Below is a general example of the Navigation component

+
+ + + + + { + console.log("DEBUG: Menu Item Clicked", id, e) + }} + menu={[ + { + id: "group-1", + label: "Extra Optimization", + menus: [ + { + id: "menu-2", + label: "Uptime Monitoring", + props: { + icon: "CheckAlt", + }, + }, + { + id: "menu-2", + label: "Site management tools", + props: {}, + }, + ], + }, + { + id: "group-2", + label: "Performance", + menus: [ + { + id: "menu-2", + label: "Uptime Monitoring", + props: {}, + }, + { + id: "menu-2", + label: "Site management tools", + props: {}, + }, + ], + }, + ]} + > +
+ +
+
+
+
+ {generalCode} +
diff --git a/packages/ui/navigation-wpmudev/stories/tabs/TabUsage.mdx b/packages/ui/navigation-wpmudev/stories/tabs/TabUsage.mdx new file mode 100644 index 000000000..745ef1181 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/tabs/TabUsage.mdx @@ -0,0 +1,50 @@ +import { Section, Row, Col } from "@wpmudev/sui-docs" + +import Anatomy from "../images/anatomy.svg" +import AccountsStates from "../images/accounts-states.svg" +import Behaviour from "../images/behaviour.svg" +import Spacing from "../images/spacing.svg" +import MaxWidth from "../images/max-width.svg" + +
+ Navigation Anatomy +

1. Branding

+

Branding include the brand icon, brand name and tagline.

+

2. Navigation menu

+

+ The navigation menu includes the links of helpful resources for the plugin. +

+

3. User Profile

+

+ It includes a user avatar or icon that provides access to account settings + and personal information. +

+
+ +
+ Navigation Accounts States +
+ +
+ Navigation Behaviour +
+ +
+ Navigation Spacing +
+ +
+ Navigation Maximum Width +
diff --git a/packages/ui/navigation/src/navigation.tsx b/packages/ui/navigation/src/navigation.tsx index 7fcbb7406..dbde64d1c 100644 --- a/packages/ui/navigation/src/navigation.tsx +++ b/packages/ui/navigation/src/navigation.tsx @@ -12,8 +12,6 @@ const Navigation: React.FC = ({ brand = { title: "title", description: "" }, user, actions = [], - mobileActions = [], - mobileDrawer = [], _htmlProps, _style, }) => { @@ -45,11 +43,6 @@ const Navigation: React.FC = ({ {/* Render the navigation user component */} {user && } -
- {/* Show actions */} - {mobileActions.length > 0 && - mobileActions.map((action, index) => action)} -
) } diff --git a/packages/ui/navigation/src/navigation.types.ts b/packages/ui/navigation/src/navigation.types.ts index 62cdb506e..6ec249177 100644 --- a/packages/ui/navigation/src/navigation.types.ts +++ b/packages/ui/navigation/src/navigation.types.ts @@ -116,14 +116,6 @@ interface NavigationProps * Navigation actions list */ actions?: ReactNode[] - /** - * Navigation actions list - */ - mobileActions?: ReactNode[] - /** - * Navigation actions list - */ - mobileDrawer?: ReactNode[] } export type { NavigationProps, NavigationBrandProps, NavigationUserProps } From cc136f32c6b7a120de251c51657e9dbbe8b2c7ab Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Wed, 16 Oct 2024 09:49:21 +0530 Subject: [PATCH 13/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20for=20plugins.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../_drawer/_elements/_drawer-header.scss | 10 +- .../_drawer/_elements/_drawer-inner.scss | 4 + .../_elements/_navigation-container.scss | 13 - .../_elements/_navigation-nav.scss | 6 +- .../_wpmudev/_elements/_wpmudev-list.scss | 227 ++++++++- .../assets/css/src/scss/_utils/_tokens.scss | 2 +- packages/common/modules/package.json | 1 + packages/common/modules/src/index.ts | 3 +- .../modules/src/more-from-wpmudev/types.ts | 34 -- packages/ui/drawer/src/drawer-header.tsx | 41 +- packages/ui/drawer/src/drawer.types.ts | 11 +- .../index.tsx => elements/wpmudev-button.tsx} | 47 +- .../src/elements/wpmudev-drawer.tsx | 45 ++ .../src/elements/wpmudev-help.tsx | 169 +++++++ .../src/elements/wpmudev-notifications.tsx | 132 ++++++ .../src/elements/wpmudev-user.tsx} | 6 +- .../src/icons}/upsell-icon.tsx | 0 packages/ui/navigation-wpmudev/src/index.ts | 3 +- .../src/more-from-wpmudev/types.ts | 34 -- .../src/more-from-wpmudev/upsell-icon.tsx | 314 ------------- .../src/navigation-brand.tsx | 2 +- .../src/navigation-user.tsx | 2 +- .../src/navigation-wpmudev.tsx | 429 ++++++++++++++++++ .../src/navigation-wpmudev.types.ts | 102 +++++ .../ui/navigation-wpmudev/src/navigation.tsx | 58 --- .../src/navigation.types.ts | 129 ------ .../stories/navigation-wpmudev.stories.tsx | 134 ++++++ .../stories/navigation.stories.tsx | 408 ----------------- .../ui/navigation/src/navigation-user.tsx | 2 +- packages/ui/navigation/src/navigation.tsx | 14 +- packages/utils/src/index.ts | 21 + 31 files changed, 1345 insertions(+), 1058 deletions(-) delete mode 100644 packages/common/modules/src/more-from-wpmudev/types.ts rename packages/ui/navigation-wpmudev/src/{more-from-wpmudev/index.tsx => elements/wpmudev-button.tsx} (86%) create mode 100644 packages/ui/navigation-wpmudev/src/elements/wpmudev-drawer.tsx create mode 100644 packages/ui/navigation-wpmudev/src/elements/wpmudev-help.tsx create mode 100644 packages/ui/navigation-wpmudev/src/elements/wpmudev-notifications.tsx rename packages/{common/modules/src/more-from-wpmudev/index.tsx => ui/navigation-wpmudev/src/elements/wpmudev-user.tsx} (97%) rename packages/{common/modules/src/more-from-wpmudev => ui/navigation-wpmudev/src/icons}/upsell-icon.tsx (100%) delete mode 100644 packages/ui/navigation-wpmudev/src/more-from-wpmudev/types.ts delete mode 100644 packages/ui/navigation-wpmudev/src/more-from-wpmudev/upsell-icon.tsx create mode 100644 packages/ui/navigation-wpmudev/src/navigation-wpmudev.tsx create mode 100644 packages/ui/navigation-wpmudev/src/navigation-wpmudev.types.ts delete mode 100644 packages/ui/navigation-wpmudev/src/navigation.tsx delete mode 100644 packages/ui/navigation-wpmudev/src/navigation.types.ts create mode 100644 packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx delete mode 100644 packages/ui/navigation-wpmudev/stories/navigation.stories.tsx diff --git a/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-header.scss b/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-header.scss index d1006d1ca..210363d06 100644 --- a/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-header.scss +++ b/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-header.scss @@ -21,11 +21,19 @@ padding: $spacing-lg $spacing-xl; } + @include element(back) { + @include modifier(md) { + @include media(min-width, md) { + display: none; + } + } + } + @include element(header-title) { display: flex; align-items: center; font-weight: $font-weight-lg; - gap: $spacing-sm; + gap: $spacing-md; } } } diff --git a/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-inner.scss b/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-inner.scss index 4b0103010..9a0835480 100644 --- a/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-inner.scss +++ b/packages/assets/css/src/scss/_components/_drawer/_elements/_drawer-inner.scss @@ -30,6 +30,10 @@ transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1); visibility: hidden; width: $drawer-size-lg; + + @include media(max-width, sm) { + width: 100%; + } } @include modifier(overlay) { diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss index 8e7a3f893..123e9b952 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-container.scss @@ -57,19 +57,6 @@ .sui-button { margin: 0; } - - // @include media(max-width, sm) { - // display: none; - // } - - // @include modifier(mobile) { - // display: none; - // @include media(max-width, sm) { - // display: flex; - // border-left: 0; - // padding-left: 0; - // } - // } } @include media(max-width, md) { diff --git a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-nav.scss b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-nav.scss index da35ea1e6..8a5be40c4 100644 --- a/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-nav.scss +++ b/packages/assets/css/src/scss/_components/_navigation/_elements/_navigation-nav.scss @@ -18,14 +18,12 @@ justify-content: flex-end; gap: $spacing-md; margin: 0; - - @include media(max-width, sm) { - display: none; - } } @include element(nav-item) { + display: flex; margin: 0; + gap: $spacing-md; } } } diff --git a/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss b/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss index bcbc7b576..31403e8b8 100644 --- a/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss +++ b/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss @@ -41,10 +41,17 @@ border-radius: $border-radius-xl; background: $color-extended-neutral-95; text-decoration: none; + border: $border-width-md solid transparent; &:hover { background: $color-extended-neutral-80; } + + &:focus, + &:active { + border-color: $color-primary-50; + background: $color-extended-neutral-90; + } } @include element(list-icon) { @@ -68,10 +75,16 @@ padding: $spacing-lg; background: $color-primary-90; border-radius: $border-radius-md; + border: $border-width-md solid transparent; &:hover { background: $color-primary-80; } + + &:focus, + &:active { + border-color: $color-primary-50; + } } @include element(upsell-title) { @@ -86,17 +99,219 @@ gap: $spacing-sm; } - @include element(drawer) { - @include media(min-width, md) { - display: none; + // Help Section + @include element(help) { + .sui-#{$block}__list-icon { + border-radius: $border-radius-md; + } + + .sui-#{$block}__list-title { + display: flex; + gap: $spacing-md; + font-weight: $font-weight-md; + align-items: center; + } + } + + @include element(help-title) { + font-size: $font-size-xs; + letter-spacing: $font-spacing-2xl; + color: $color-extended-neutral-50; + text-transform: uppercase; + } + + @include element(help-content) { + display: flex; + flex-direction: column; + padding: $spacing-xl; + } + + @include element(help-link) { + padding: $spacing-lg 0; + border-bottom: $border-width-sm solid $color-extended-neutral-80; + font-weight: $font-weight-md; + } + + @include element(help-readings) { + display: flex; + flex-direction: column; + margin-bottom: $spacing-lg; + } + + @include element(help-list) { + display: flex; + flex-direction: column; + gap: $spacing-lg; + margin-top: $spacing-lg; + + @include modifier(item) { + display: flex; + gap: $spacing-lg; + text-decoration: none; + } + } + + @include element(support) { + padding: $spacing-lg; + background: $color-extended-success-90; + border-radius: $border-radius-md; + } + + @include element(list-text-small) { + margin: 0; + } + + @include element(list-actions) { + padding-top: $spacing-lg; + } + + // Notifications + @include element(notifications) { + .sui-dropdown__popover { + padding: 0; + } + + @include modifier(header, footer) { + padding: $spacing-xl; + } + + @include modifier(header, item) { + border-bottom: $border-width-sm solid $color-extended-neutral-80; + } + + @include modifier(footer) { + border-top: $border-width-sm solid $color-extended-neutral-80; + } + + .sui-wpmudev__notifications--list { + max-height: 444px; + overflow-y: scroll; + } + + @include modifier(item) { + display: flex; + flex-direction: column; + gap: $spacing-md; + padding: $spacing-lg $spacing-xl; + + &:first-child { + .sui-wpmudev__notifications--item-action { + flex: 1; + .sui-button { + width: 100%; + } + } + } + + &:last-child { + border-bottom: none; + } + + &:hover { + background: $color-primary-90; + } + } + + @include modifier(item-actions) { + display: flex; + gap: $spacing-lg; + } + + @include modifier(item-meta) { + display: flex; + gap: $spacing-lg; + font-size: $font-size-xs; + line-height: $font-height-xs; + color: $color-extended-neutral-10; + } + + @include modifier(item-title) { + font-weight: $font-weight-md; + color: $color-extended-neutral-10; + margin: 0; + } + + @include modifier(version) { + font-weight: $font-weight-md; + } + + @include modifier(time) { + position: relative; + color: $color-extended-neutral-50; + + &:after { + content: ""; + position: absolute; + border-radius: 100%; + background: $color-extended-neutral-50; + width: 5px; + height: 5px; + top: 50%; + transform: translateY(-50%); + left: -#{$spacing-md + 3px}; + } + } + } + + @include element(notifications-drawer) { + .sui-drawer__footer { + justify-content: flex-start; } } - @include element(dropdown) { - &.sui-dropdown { + @include element(navigation) { + .sui-navigation__actions { + @include media(max-width, md) { + border: none; + } + } + + .sui-navigation__avatar { + @include media(max-width, md) { + display: none; + } + } + + @include modifier(actions) { + display: flex; + gap: $spacing-md; + } + + @include modifier(hide-mobile) { display: none; @include media(min-width, md) { - display: block; + display: flex; + } + } + + @include modifier(hide-desktop) { + @include media(min-width, md) { + display: none; + } + } + } + + // hamburger + @include element(hamburger-menu) { + display: flex; + gap: $spacing-sm; + flex-direction: column; + margin: $spacing-sm 0; + + li { + margin: 0; + + .sui-button { + border: none; + background: transparent; + border-radius: 0; + justify-content: flex-start; + color: $color-extended-neutral-50; + + &:hover { + background: $color-extended-neutral-90; + color: $color-extended-neutral-10; + } } } } diff --git a/packages/assets/css/src/scss/_utils/_tokens.scss b/packages/assets/css/src/scss/_utils/_tokens.scss index 9da6a076e..dd5e08f5c 100644 --- a/packages/assets/css/src/scss/_utils/_tokens.scss +++ b/packages/assets/css/src/scss/_utils/_tokens.scss @@ -1,6 +1,6 @@ // Do not edit directly -// Generated on Wed, 09 Oct 2024 03:58:25 GMT +// Generated on Tue, 15 Oct 2024 03:22:11 GMT $accordion-border-radius-sm: 10px; $advanced-banner-background: linear-gradient(90deg, #222 0%, #383323 48.96%, #514524 100%); diff --git a/packages/common/modules/package.json b/packages/common/modules/package.json index 14cb1ce17..86595cf35 100644 --- a/packages/common/modules/package.json +++ b/packages/common/modules/package.json @@ -45,6 +45,7 @@ "dependencies": { "@wpmudev/sui-dashboard-widget": "^0.0.1", "@wpmudev/sui-integration": "^0.0.1", + "@wpmudev/sui-navigation-wpmudev": "^0.0.1", "@wpmudev/sui-navigation": "^0.0.1", "@wpmudev/sui-table": "^0.0.1" }, diff --git a/packages/common/modules/src/index.ts b/packages/common/modules/src/index.ts index 057423d18..be570f3d1 100644 --- a/packages/common/modules/src/index.ts +++ b/packages/common/modules/src/index.ts @@ -1,6 +1,7 @@ import * as Table from "@wpmudev/sui-table" import * as DashboardWidget from "@wpmudev/sui-dashboard-widget" import * as Navigation from "@wpmudev/sui-navigation" +import * as NavigationWPMUDEV from "@wpmudev/sui-navigation-wpmudev" import * as Integration from "@wpmudev/sui-integration" -export { Table, DashboardWidget, Navigation, Integration } +export { Table, DashboardWidget, Navigation, Integration, NavigationWPMUDEV } diff --git a/packages/common/modules/src/more-from-wpmudev/types.ts b/packages/common/modules/src/more-from-wpmudev/types.ts deleted file mode 100644 index 984a55472..000000000 --- a/packages/common/modules/src/more-from-wpmudev/types.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - SuiHTMLAttributes, - SuiStyleType, - PluginsSlug, -} from "@wpmudev/sui-utils" -import { DropdownProps } from "@wpmudev/sui-dropdown" - -/** - * Represents a plugin's details. - */ -type Plugin = { - plugin: PluginsSlug - title: string - description: string - link: string - props?: SuiHTMLAttributes -} - -/** - * Represents the properties for a dropdown component. - */ -interface WPMUDEVProps extends DropdownProps, SuiStyleType { - title?: string - plugins?: Plugin[] - upsell?: { - link: string - title: string - description: string - props?: SuiHTMLAttributes - } - filter?: PluginsSlug[] -} - -export type { WPMUDEVProps } diff --git a/packages/ui/drawer/src/drawer-header.tsx b/packages/ui/drawer/src/drawer-header.tsx index 062259988..7dc61cbcd 100644 --- a/packages/ui/drawer/src/drawer-header.tsx +++ b/packages/ui/drawer/src/drawer-header.tsx @@ -10,8 +10,11 @@ const DrawerHeader = ({ className = "", title = "", hintText = "", - hasBack = false, - onBack = () => {}, + back = { + show: false, + mobileOnly: false, + action: () => {}, + }, tooltipOptions = {}, _style, }: DrawerHeaderTypes) => { @@ -25,24 +28,28 @@ const DrawerHeader = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [ctx.isOpen]) + const { show, mobileOnly = false, action = () => {} } = back + return (
- {hasBack && ( -
)} {title} {!isEmpty(hintText) && ( diff --git a/packages/ui/drawer/src/drawer.types.ts b/packages/ui/drawer/src/drawer.types.ts index e2729a30f..c92863a74 100644 --- a/packages/ui/drawer/src/drawer.types.ts +++ b/packages/ui/drawer/src/drawer.types.ts @@ -80,7 +80,16 @@ export interface DrawerHeaderTypes extends SuiStyleType { /** * Has back button. */ - hasBack?: boolean + back?: { + show: boolean + + mobileOnly?: boolean + + /** + * Has back button. + */ + action?: () => void + } /** * Has back button. diff --git a/packages/ui/navigation-wpmudev/src/more-from-wpmudev/index.tsx b/packages/ui/navigation-wpmudev/src/elements/wpmudev-button.tsx similarity index 86% rename from packages/ui/navigation-wpmudev/src/more-from-wpmudev/index.tsx rename to packages/ui/navigation-wpmudev/src/elements/wpmudev-button.tsx index 308089b74..cd6dc65ba 100644 --- a/packages/ui/navigation-wpmudev/src/more-from-wpmudev/index.tsx +++ b/packages/ui/navigation-wpmudev/src/elements/wpmudev-button.tsx @@ -9,8 +9,8 @@ import { } from "@wpmudev/sui-utils" import { IconProps } from "@wpmudev/sui-icon" import Icons, { IconsNamesType, ExternalLink } from "@wpmudev/sui-icons" -import { WPMUDEVProps } from "./types" -import { UpsellIcon } from "./upsell-icon" +import { WPMUDEVButtonProps } from "../navigation-wpmudev.types" +import { UpsellIcon } from "../icons/upsell-icon" import { Drawer, DrawerActions, @@ -18,7 +18,7 @@ import { DrawerHeader, } from "@wpmudev/sui-drawer" -const MoreFromWPMUDEV: React.FC = ({ +const MoreFromWPMUDEV: React.FC = ({ label = "More from WPMU DEV", title = "More free plugins from WPMU DEV", className = "", @@ -104,7 +104,7 @@ const MoreFromWPMUDEV: React.FC = ({ const classNames = generateCN( "sui-wpmudev", {}, - `sui-wpmudev__dropdown ${className}`, + `sui-wpmudev__dropdown sui-wpmudev__navigation--hide-mobile ${className}`, ) const filteredPlugins = plugins.filter( @@ -185,31 +185,32 @@ const MoreFromWPMUDEV: React.FC = ({ disableShadow={true} isFullWidth={true} > - + {dropdownContent} ) return ( <> - - {title && ( -
-

{title}

-
- )} - {dropdownContent} -
-
+
+ + {title && ( +
+

{title}

+
+ )} + {dropdownContent} +
+
+
+
+ )} + + ) + } + + return ( +
+
{title}
+ {content && ( +
+ {content.map((item, index) => ( + + {item.label} + + ))} +
+ )} +
{resources.title}
+
    + {resourcesSection} + {supportSection()} +
+
+ ) +} + +// Export the MoreFromWPMUDEV component +export { HelpWPMUDEVContent } diff --git a/packages/ui/navigation-wpmudev/src/elements/wpmudev-notifications.tsx b/packages/ui/navigation-wpmudev/src/elements/wpmudev-notifications.tsx new file mode 100644 index 000000000..f7dc6e346 --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/elements/wpmudev-notifications.tsx @@ -0,0 +1,132 @@ +import React, { createRef, useRef } from "react" +import { Dropdown, DropdownRefProps } from "@wpmudev/sui-dropdown" +import { Button } from "@wpmudev/sui-button" +import { _renderHTMLPropsSafely, generateCN } from "@wpmudev/sui-utils" +import { WPMUDEVNotificationProps } from "../navigation-wpmudev.types" +import { + Drawer, + DrawerActions, + DrawerBody, + DrawerFooter, + DrawerHeader, +} from "@wpmudev/sui-drawer" +import { Tooltip } from "@wpmudev/sui-tooltip" +import { Link } from "@wpmudev/sui-link" + +const NotificationWPMUDEV: React.FC = ({ + label = "What’s new on Smush?", + title = "What's new", + notifications, + footerActions = [ + + Mark all as read + , + ], + className = "", + _htmlProps = {}, + _style = {}, + ...props +}) => { + // Create a ref for the user dropdown button + const notificationRef = useRef(null) + + const classNames = generateCN( + "sui-wpmudev", + {}, + `sui-wpmudev__notifications ${className}`, + ) + + return ( + <> + { + notificationRef?.current?.toggle() + }} + > + {title} + + } + arrow={false} + menuCustomWidth={360} + className={classNames} + {..._renderHTMLPropsSafely(_htmlProps)} + {...props} + > + {label && ( +
+

{label}

+
+ )} + + {footerActions && ( +
+ {footerActions.map((action, index) => action)} +
+ )} +
+ + ) +} + +const NotificationWPMUDEVContent: React.FC = ({ + notifications, + className = "", + _htmlProps = {}, + _style = {}, + ...props +}) => { + const classNames = generateCN( + "sui-wpmudev__notifications--list", + {}, + className, + ) + + return ( +
+ {notifications.map((notification, index) => ( +
+
+ + v{notification.version} + + + {notification.time} + +
+

+ {notification.title} +

+
+ {notification.actions?.map((action, actionIndex) => ( +
+ {action} +
+ ))} +
+
+ ))} +
+ ) +} + +// Export the MoreFromWPMUDEV component +export { NotificationWPMUDEV, NotificationWPMUDEVContent } diff --git a/packages/common/modules/src/more-from-wpmudev/index.tsx b/packages/ui/navigation-wpmudev/src/elements/wpmudev-user.tsx similarity index 97% rename from packages/common/modules/src/more-from-wpmudev/index.tsx rename to packages/ui/navigation-wpmudev/src/elements/wpmudev-user.tsx index 308089b74..0822c3b1a 100644 --- a/packages/common/modules/src/more-from-wpmudev/index.tsx +++ b/packages/ui/navigation-wpmudev/src/elements/wpmudev-user.tsx @@ -9,8 +9,8 @@ import { } from "@wpmudev/sui-utils" import { IconProps } from "@wpmudev/sui-icon" import Icons, { IconsNamesType, ExternalLink } from "@wpmudev/sui-icons" -import { WPMUDEVProps } from "./types" -import { UpsellIcon } from "./upsell-icon" +import { WPMUDEVProps } from "./icons/types" +import { UpsellIcon } from "../icons/upsell-icon" import { Drawer, DrawerActions, @@ -185,7 +185,7 @@ const MoreFromWPMUDEV: React.FC = ({ disableShadow={true} isFullWidth={true} > - + {dropdownContent} ) diff --git a/packages/common/modules/src/more-from-wpmudev/upsell-icon.tsx b/packages/ui/navigation-wpmudev/src/icons/upsell-icon.tsx similarity index 100% rename from packages/common/modules/src/more-from-wpmudev/upsell-icon.tsx rename to packages/ui/navigation-wpmudev/src/icons/upsell-icon.tsx diff --git a/packages/ui/navigation-wpmudev/src/index.ts b/packages/ui/navigation-wpmudev/src/index.ts index 039a63e3b..4ead1840f 100644 --- a/packages/ui/navigation-wpmudev/src/index.ts +++ b/packages/ui/navigation-wpmudev/src/index.ts @@ -1,2 +1 @@ -export { Navigation } from "./navigation" -export type { NavigationProps, NavigationUserProps } from "./navigation.types" +export { NavigationWPMUDEV } from "./navigation-wpmudev" diff --git a/packages/ui/navigation-wpmudev/src/more-from-wpmudev/types.ts b/packages/ui/navigation-wpmudev/src/more-from-wpmudev/types.ts deleted file mode 100644 index 984a55472..000000000 --- a/packages/ui/navigation-wpmudev/src/more-from-wpmudev/types.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { - SuiHTMLAttributes, - SuiStyleType, - PluginsSlug, -} from "@wpmudev/sui-utils" -import { DropdownProps } from "@wpmudev/sui-dropdown" - -/** - * Represents a plugin's details. - */ -type Plugin = { - plugin: PluginsSlug - title: string - description: string - link: string - props?: SuiHTMLAttributes -} - -/** - * Represents the properties for a dropdown component. - */ -interface WPMUDEVProps extends DropdownProps, SuiStyleType { - title?: string - plugins?: Plugin[] - upsell?: { - link: string - title: string - description: string - props?: SuiHTMLAttributes - } - filter?: PluginsSlug[] -} - -export type { WPMUDEVProps } diff --git a/packages/ui/navigation-wpmudev/src/more-from-wpmudev/upsell-icon.tsx b/packages/ui/navigation-wpmudev/src/more-from-wpmudev/upsell-icon.tsx deleted file mode 100644 index 2d22e0fc1..000000000 --- a/packages/ui/navigation-wpmudev/src/more-from-wpmudev/upsell-icon.tsx +++ /dev/null @@ -1,314 +0,0 @@ -import React from "react" - -const UpsellIcon = () => { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ) -} - -export { UpsellIcon } diff --git a/packages/ui/navigation-wpmudev/src/navigation-brand.tsx b/packages/ui/navigation-wpmudev/src/navigation-brand.tsx index e17696e03..6e1003d49 100644 --- a/packages/ui/navigation-wpmudev/src/navigation-brand.tsx +++ b/packages/ui/navigation-wpmudev/src/navigation-brand.tsx @@ -7,7 +7,7 @@ import { PluginsIcons, } from "@wpmudev/sui-utils" import { IconProps } from "@wpmudev/sui-icon" -import { NavigationBrandProps } from "./navigation.types" +import { NavigationBrandProps } from "./navigation-wpmudev.types" import Icons, { IconsNamesType } from "@wpmudev/sui-icons" import { useStyles } from "@wpmudev/sui-hooks" diff --git a/packages/ui/navigation-wpmudev/src/navigation-user.tsx b/packages/ui/navigation-wpmudev/src/navigation-user.tsx index 141a33fdd..2ade2a7c8 100644 --- a/packages/ui/navigation-wpmudev/src/navigation-user.tsx +++ b/packages/ui/navigation-wpmudev/src/navigation-user.tsx @@ -3,7 +3,7 @@ import React, { useRef } from "react" import { Dropdown, DropdownRefProps } from "@wpmudev/sui-dropdown" import { Avatar } from "@wpmudev/sui-avatar" -import { NavigationUserProps } from "./navigation.types" +import { NavigationUserProps } from "./navigation-wpmudev.types" import { generateCN, isEmpty } from "@wpmudev/sui-utils" const NavigationUser: React.FC = ({ diff --git a/packages/ui/navigation-wpmudev/src/navigation-wpmudev.tsx b/packages/ui/navigation-wpmudev/src/navigation-wpmudev.tsx new file mode 100644 index 000000000..0100e7f49 --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/navigation-wpmudev.tsx @@ -0,0 +1,429 @@ +import React, { Children, createRef, RefObject } from "react" +import { Navigation } from "@wpmudev/sui-navigation" +import { _renderHTMLPropsSafely, generateCN } from "@wpmudev/sui-utils" +import { useStyles } from "@wpmudev/sui-hooks" +import { Button } from "@wpmudev/sui-button" +import { MoreFromWPMUDEV } from "./elements/wpmudev-button" +import { HelpWPMUDEVContent } from "./elements/wpmudev-help" +import { + NotificationWPMUDEV, + NotificationWPMUDEVContent, +} from "./elements/wpmudev-notifications" +import { + Drawer, + DrawerActions, + DrawerBody, + DrawerFooter, + DrawerHeader, +} from "@wpmudev/sui-drawer" +import { Tooltip } from "@wpmudev/sui-tooltip" +import { WPMUDEVDrawer } from "./elements/wpmudev-drawer" +import { Link } from "@wpmudev/sui-link" + +// Navigation component +const NavigationWPMUDEV: React.FC = ({ + _htmlProps, + _style, +}) => { + const ref = createRef() + const drawerRef = createRef() + const notificationRef = createRef() + + const { suiInlineClassname } = useStyles(_style) + // Generate CSS class names for the navigation component + const classNames = generateCN( + "sui-wpmudev__navigation", + {}, + suiInlineClassname, + ) + + const navActions = ( +
+ { + drawerRef?.current?.toggle() + }} + > + Help and resources + + + View detail + , + , + ], + }, + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + ], + }, + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + ], + }, + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + ], + }, + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + ], + }, + ]} + /> +
+ ) + + const hamburgerMenu = ( +
    +
  • + +
  • +
  • + +
  • +
+ ) + + const drawer = ( + <> + + Upgrade to pro + , + ]} + > + {hamburgerMenu} + + { + drawerRef?.current?.hide() + ref?.current?.open() + }, + }} + > + + + { + notificationRef?.current?.hide() + ref?.current?.open() + }, + }} + footer={[ + + Mark all as read + , + ]} + > + + View detail + , + , + ], + }, + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + ], + }, + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + ], + }, + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + ], + }, + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + ], + }, + ]} + /> + + + ) + + return ( +
+ {drawer} + , + , + ]} + > + {navActions} + +
+ ) +} + +// Export the NavigationWPMUDEV component +export { NavigationWPMUDEV } diff --git a/packages/ui/navigation-wpmudev/src/navigation-wpmudev.types.ts b/packages/ui/navigation-wpmudev/src/navigation-wpmudev.types.ts new file mode 100644 index 000000000..506b2821b --- /dev/null +++ b/packages/ui/navigation-wpmudev/src/navigation-wpmudev.types.ts @@ -0,0 +1,102 @@ +import { + SuiHTMLAttributes, + SuiStyleType, + PluginsSlug, + PluginIconTypes, +} from "@wpmudev/sui-utils" +import { DropdownProps } from "@wpmudev/sui-dropdown" +import { ReactNode, RefObject } from "react" +import { + DrawerActions, + DrawerHeaderTypes, + DrawerTypes, +} from "@wpmudev/sui-drawer" + +/** + * Represents a plugin's details. + */ +type Plugin = { + plugin: PluginsSlug + title: string + description: string + link: string + props?: SuiHTMLAttributes +} + +/** + * Represents the properties for a WPMUDEV button props. + */ +interface WPMUDEVButtonProps extends DropdownProps, SuiStyleType { + title?: string + plugins?: Plugin[] + upsell?: { + link: string + title: string + description: string + props?: SuiHTMLAttributes + } + filter?: PluginsSlug[] +} + +/** + * Represents the properties for a WPMUDEV help. + */ +interface WPMUDEVHelpProps extends DropdownProps, SuiStyleType { + label?: string + title?: string + isPro?: boolean + content: Array<{ + link: string + label: string + }> + resources?: { + title: string + content: Array<{ + icon: PluginIconTypes + title: string + description: string + link: string + }> + } + support?: { + icon: PluginIconTypes + title: string + description: string + message: string + } +} + +/** + * Represents the properties for a WPMUDEV notification. + */ +interface WPMUDEVNotificationProps extends DropdownProps, SuiStyleType { + title?: string + label?: string + notifications: Array<{ + version: string + time: string + title: string + actions: Array + }> + footerActions?: Array +} + +/** + * Represents the properties for a WPMUDEV notification. + */ +interface WPMUDEVDrawerProps extends DrawerTypes, SuiStyleType { + title?: string + toggleRef: RefObject + footer?: ReactNode + placement?: "left" | "right" + className?: string + children: ReactNode + back?: DrawerHeaderTypes["back"] +} + +export type { + WPMUDEVButtonProps, + WPMUDEVHelpProps, + WPMUDEVNotificationProps, + WPMUDEVDrawerProps, +} diff --git a/packages/ui/navigation-wpmudev/src/navigation.tsx b/packages/ui/navigation-wpmudev/src/navigation.tsx deleted file mode 100644 index 7fcbb7406..000000000 --- a/packages/ui/navigation-wpmudev/src/navigation.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React, { Children } from "react" - -import { _renderHTMLPropsSafely, generateCN } from "@wpmudev/sui-utils" -import { NavigationProps } from "./navigation.types" -import { NavigationBrand } from "./navigation-brand" -import { NavigationUser } from "./navigation-user" -import { useStyles } from "@wpmudev/sui-hooks" - -// Navigation component -const Navigation: React.FC = ({ - children, - brand = { title: "title", description: "" }, - user, - actions = [], - mobileActions = [], - mobileDrawer = [], - _htmlProps, - _style, -}) => { - const { suiInlineClassname } = useStyles(_style) - // Generate CSS class names for the navigation component - const classNames = generateCN("sui-navigation", {}, suiInlineClassname) - - return ( - // Render the navigation component - - - ) -} - -// Export the Navigation component -export { Navigation } diff --git a/packages/ui/navigation-wpmudev/src/navigation.types.ts b/packages/ui/navigation-wpmudev/src/navigation.types.ts deleted file mode 100644 index 62cdb506e..000000000 --- a/packages/ui/navigation-wpmudev/src/navigation.types.ts +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Props for the Notification component. - */ -import { ReactNode, HTMLProps } from "react" - -import { DropdownMenuItemProps } from "@wpmudev/sui-dropdown" - -import { - PluginsSlug, - SuiHTMLAttributes, - SuiStyleType, -} from "@wpmudev/sui-utils" - -import { AvatarProps } from "@wpmudev/sui-avatar" -import { useStylesTypes } from "@wpmudev/sui-hooks" - -// Represents the base props for a DropdownMenu component. -interface NavigationUserMenuBaseProps { - /* - * Unique identifier for the NavigationUser menu item. - */ - id: string | number - /* - * Content to display as the label for the NavigationUser menu item. - */ - label: ReactNode | string -} - -// Props for an individual item within the NavigationUser menu. -interface NavigationUserMenuItemProps extends NavigationUserMenuBaseProps { - /* - * Additional props for the underlying MenuItem component. - */ - props: Omit -} - -// Props for a group of NavigationUser menu items. -interface NavigationUserMenuGroupProps extends NavigationUserMenuBaseProps { - /* - * An array of NavigationUserMenuItemProps representing the items in the group. - */ - menus: Array -} - -interface NavigationBrandProps extends SuiStyleType, SuiHTMLAttributes { - /* - * Optional: Plugin information for the brand. - */ - plugin?: PluginsSlug - /* - * Optional: Title for the brand. - */ - title?: string - /* - * Optional: Description for the brand. - */ - description?: string -} - -type NavigationUserType = { - /* - * Image URL for the user's profile picture. - */ - image?: string - /* - * Name of the user. - */ - name?: string - /* - * Email address of the user. - */ - email?: string -} - -interface NavigationUserProps { - /* - * User information. - */ - user?: NavigationUserType - /* - * Array of menu items or groups in the user's navigation menu. - */ - menu?: Array - /* - * When set to true the menu will be disabled - */ - isMenuDisabled?: boolean - /* - * The user status - */ - status?: AvatarProps["status"] - /* - * Seperate last item from menu. - */ - splitLastItem?: boolean -} - -// interface definition for the Navigation -interface NavigationProps - extends SuiStyleType, - SuiHTMLAttributes> { - /* - * Brand information. - */ - brand?: NavigationBrandProps - /* - * Optional: Navigation content. - */ - children?: ReactNode - - /* - * Optional: User - */ - user?: NavigationUserProps - /** - * Navigation actions list - */ - actions?: ReactNode[] - /** - * Navigation actions list - */ - mobileActions?: ReactNode[] - /** - * Navigation actions list - */ - mobileDrawer?: ReactNode[] -} - -export type { NavigationProps, NavigationBrandProps, NavigationUserProps } diff --git a/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx b/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx new file mode 100644 index 000000000..35fd5b732 --- /dev/null +++ b/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx @@ -0,0 +1,134 @@ +import React, { createRef, RefObject } from "react" + +// Import required component(s) +import { NavigationWPMUDEV as SuiNavigation } from "../src" +import { PluginsSlug } from "@wpmudev/sui-utils" + +// Import documentation main page +// import docs from "./navigation.mdx" + +// Configure default options +export default { + title: "SUI/Components/Modules/Navigation WPMUDEV", + component: SuiNavigation, + parameters: { + layout: "fullscreen", + docs: { + // page: docs, + }, + }, +} + +// Build story +export const Navigation = (props: { + isPro: boolean + action: boolean + status: NavigationUserProps["status"] + isMenuDisabled: NavigationUserProps["isMenuDisabled"] + plugin: PluginsSlug + title: string + description: string +}) => { + const { action, isPro, status, isMenuDisabled, plugin, title, description } = + props + + return ( +
+
+ +
+
+ ) +} + +Navigation.args = { + isPro: true, + action: true, + isMenuDisabled: false, + status: "confirmed", + plugin: "smush", + title: "Smush Pro", + description: "Description", +} + +Navigation.argTypes = { + isPro: { + name: "Pro", + control: { + type: "boolean", + }, + }, + action: { + name: "Action buttons", + control: { + type: "boolean", + }, + }, + isMenuDisabled: { + name: "Menu Disabled", + control: { + type: "boolean", + }, + }, + status: { + name: "User Status", + options: ["none", "confirmed", "awaiting", "not-accepted", "not-connected"], + control: { + type: "select", + labels: { + none: "None", + confirmed: "Confirmed", + awaiting: "Awaiting", + "not-accepted": "Not Accepted", + "not-connected": "Not Connected", + }, + }, + }, + plugin: { + name: "Plugin", + options: [ + "smush", + "defender", + "snapshot", + "hummingbird", + "forminator", + "beehive", + "hustle", + "smartcrawl", + "shipper", + "branda", + "blc", + "thc", + "dashboard", + ], + control: { + type: "select", + labels: { + smush: "smush", + defendre: "defender", + snapshot: "snapshot", + hummigbird: "hummingbird", + forminator: "forminator", + beehive: "beehive", + hustle: "hustle", + smartcrawl: "smartcrawl", + shipper: "shipper", + branda: "branda", + blc: "blc", + thc: "thc", + }, + }, + }, + title: { + name: "Title", + control: { + type: "text", + }, + }, + description: { + name: "Description", + control: { + type: "text", + }, + }, +} diff --git a/packages/ui/navigation-wpmudev/stories/navigation.stories.tsx b/packages/ui/navigation-wpmudev/stories/navigation.stories.tsx deleted file mode 100644 index 2383e5da9..000000000 --- a/packages/ui/navigation-wpmudev/stories/navigation.stories.tsx +++ /dev/null @@ -1,408 +0,0 @@ -import React, { createRef, RefObject } from "react" - -// Import required component(s) -import { Navigation as SuiNavigation, NavigationUserProps } from "../src" -import { PluginsSlug } from "@wpmudev/sui-utils" -import { Button } from "@wpmudev/sui-button" -import { Dropdown } from "@wpmudev/sui-dropdown" -import { - Drawer, - DrawerActions, - DrawerBody, - DrawerFooter, - DrawerHeader, -} from "@wpmudev/sui-drawer" -import { MoreFromWPMUDEV } from "@wpmudev/sui-modules" - -// Import documentation main page -import docs from "./navigation.mdx" - -// Configure default options -export default { - title: "SUI/Components/Modules/Navigation", - component: SuiNavigation, - parameters: { - layout: "fullscreen", - docs: { - page: docs, - }, - }, -} - -const _internalDrawer = ({ - toggleRef, - title = "Drawer header", - desc = "", - ...props -}: { - toggleRef: RefObject - title: string - desc: string - [key: string]: any -}) => { - return ( - - - -
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque - rutrum sem eros, sed tempor sapien porta ac. Nullam purus metus. -
-
- -
- - -
-
-
- ) -} - -const _internalDrawerLogo = ({ - toggleRef, - title = "Drawer header", - desc = "", - ...props -}: { - toggleRef: RefObject - title: string - desc: string - [key: string]: any -}) => { - return ( - - -
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque - rutrum sem eros, sed tempor sapien porta ac. Nullam purus metus. -
-
- -
- - -
-
-
- ) -} - -// Build story -export const Navigation = (props: { - isPro: boolean - action: boolean - status: NavigationUserProps["status"] - isMenuDisabled: NavigationUserProps["isMenuDisabled"] - plugin: PluginsSlug - title: string - description: string -}) => { - const ref = createRef() - const refLogoDrawer = createRef() - - const { action, isPro, status, isMenuDisabled, plugin, title, description } = - props - - return ( -
-
- <_internalDrawer - toggleRef={ref} - {...props} - placement="left" - title="Drawer title" - desc="Drawer for body container, it is fixed positioned" - hasContainer={true} - disableShadow={true} - /> - , - ], - mobileActions: [ - , - , - ], - })} - {...(action && - !isPro && { - actions: [ - , - , - ], - mobileActions: [ - -
- -
-
, - ], - })} - > - - -
- <_internalDrawerLogo - key="logo-drawer" - toggleRef={refLogoDrawer} - {...props} - placement="left" - title="Drawer title" - desc="Drawer for body container, it is fixed positioned" - hasContainer={true} - disableShadow={true} - _style={{ - top: "118px", - }} - /> -
-
- ) -} - -Navigation.args = { - isPro: true, - action: true, - isMenuDisabled: false, - status: "confirmed", - plugin: "smush", - title: "Smush Pro", - description: "Description", -} - -Navigation.argTypes = { - isPro: { - name: "Pro", - control: { - type: "boolean", - }, - }, - action: { - name: "Action buttons", - control: { - type: "boolean", - }, - }, - isMenuDisabled: { - name: "Menu Disabled", - control: { - type: "boolean", - }, - }, - status: { - name: "User Status", - options: ["none", "confirmed", "awaiting", "not-accepted", "not-connected"], - control: { - type: "select", - labels: { - none: "None", - confirmed: "Confirmed", - awaiting: "Awaiting", - "not-accepted": "Not Accepted", - "not-connected": "Not Connected", - }, - }, - }, - plugin: { - name: "Plugin", - options: [ - "smush", - "defender", - "snapshot", - "hummingbird", - "forminator", - "beehive", - "hustle", - "smartcrawl", - "shipper", - "branda", - "blc", - "thc", - "dashboard", - ], - control: { - type: "select", - labels: { - smush: "smush", - defendre: "defender", - snapshot: "snapshot", - hummigbird: "hummingbird", - forminator: "forminator", - beehive: "beehive", - hustle: "hustle", - smartcrawl: "smartcrawl", - shipper: "shipper", - branda: "branda", - blc: "blc", - thc: "thc", - }, - }, - }, - title: { - name: "Title", - control: { - type: "text", - }, - }, - description: { - name: "Description", - control: { - type: "text", - }, - }, -} diff --git a/packages/ui/navigation/src/navigation-user.tsx b/packages/ui/navigation/src/navigation-user.tsx index 141a33fdd..146e0ba10 100644 --- a/packages/ui/navigation/src/navigation-user.tsx +++ b/packages/ui/navigation/src/navigation-user.tsx @@ -56,7 +56,7 @@ const NavigationUser: React.FC = ({ } return ( -
+
= ({ ))} -
- {/* Show actions */} - {actions.length > 0 && actions.map((action, index) => action)} - {/* Render the navigation user component */} - {user && } -
+ {(actions.length > 0 || user) && ( +
+ {/* Show actions */} + {actions.length > 0 && actions.map((action, index) => action)} + {/* Render the navigation user component */} + {user && } +
+ )} ) } diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 86a33b0dc..df3694950 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -329,6 +329,26 @@ const PluginsIcons: Record = { }, } +export type CustomIconsSlug = "documentation" | "feedback" | "contact" + +const CustomIcons: Record = { + documentation: { + bg: "#E6EEFF", + color: "#1A1A1A", + icon: "Poll", + }, + feedback: { + bg: "#D3BEF2", + color: "#1A1A1A", + icon: "Tutorials", + }, + contact: { + bg: "#A3DCB5", + color: "#1A1A1A", + icon: "Submit", + }, +} + /** * Break an array into chunks of a specified size * @@ -410,6 +430,7 @@ export { handleOnKeyDown, handleEventDefault, PluginsIcons, + CustomIcons, chunkArray, isValidCSSProperty, _renderHTMLPropsSafely, From 392865a2fe0baea9a47d21a173cce6fff90c51f1 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Wed, 16 Oct 2024 15:23:36 +0530 Subject: [PATCH 14/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20for=20plugins.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .storybook/main.ts | 2 +- .../_wpmudev/_elements/_wpmudev-list.scss | 39 ++ packages/ui/avatar/src/avatar.tsx | 3 +- packages/ui/avatar/src/avatar.types.ts | 6 + .../ui/avatar/src/elements/icon-avatar.tsx | 15 +- packages/ui/drawer/src/drawer-header.tsx | 2 +- .../src/elements/wpmudev-notifications.tsx | 12 +- .../src/elements/wpmudev-user.tsx | 258 ++--------- packages/ui/navigation-wpmudev/src/index.ts | 20 +- .../src/navigation-brand.tsx | 48 -- .../src/navigation-user.tsx | 81 ---- .../src/navigation-wpmudev.tsx | 414 +---------------- .../src/navigation-wpmudev.types.ts | 19 +- .../stories/navigation-wpmudev.stories.tsx | 425 +++++++++++++----- packages/ui/navigation/src/index.ts | 1 + .../ui/navigation/src/navigation-user.tsx | 21 +- .../ui/navigation/src/navigation.types.ts | 17 +- .../navigation/stories/navigation.stories.tsx | 95 +--- 18 files changed, 496 insertions(+), 982 deletions(-) delete mode 100644 packages/ui/navigation-wpmudev/src/navigation-brand.tsx delete mode 100644 packages/ui/navigation-wpmudev/src/navigation-user.tsx diff --git a/.storybook/main.ts b/.storybook/main.ts index 7f8052a0b..7ef5b268b 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -46,7 +46,7 @@ module.exports = { options: {}, }, typescript: { - reactDocgen: "react-docgen-typescript-plugin", + reactDocgen: "none", }, docs: { autodocs: true, diff --git a/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss b/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss index 31403e8b8..20490a9df 100644 --- a/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss +++ b/packages/assets/css/src/scss/_components/_wpmudev/_elements/_wpmudev-list.scss @@ -111,6 +111,12 @@ font-weight: $font-weight-md; align-items: center; } + + .sui-drawer__inner { + @include media(max-width, md) { + width: 100%; + } + } } @include element(help-title) { @@ -315,6 +321,39 @@ } } } + + // User + @include element(user) { + display: flex; + gap: $spacing-lg; + flex-direction: column; + width: 100%; + + @include modifier(details) { + display: flex; + gap: $spacing-lg; + + p { + margin: 0; + } + } + + @include modifier(content) { + flex: 1; + } + } + + @include element(navigation-user) { + .sui-dropdown__popover { + padding: $spacing-lg; + } + } + + @include element(drawer) { + .sui-drawer__footer { + justify-content: flex-start; + } + } } } } diff --git a/packages/ui/avatar/src/avatar.tsx b/packages/ui/avatar/src/avatar.tsx index 789dd3b2c..834d96400 100644 --- a/packages/ui/avatar/src/avatar.tsx +++ b/packages/ui/avatar/src/avatar.tsx @@ -20,6 +20,7 @@ const Avatar: React.FC = ({ status = "none", isSmall = false, className, + icon = "UserAlt", _htmlProps = {}, _style = {}, onClick, @@ -59,7 +60,7 @@ const Avatar: React.FC = ({ return ( {hasImage && } - {!hasImage && } + {!hasImage && } {hasStatus && status !== "none" && } ) diff --git a/packages/ui/avatar/src/avatar.types.ts b/packages/ui/avatar/src/avatar.types.ts index f91b42844..35ebba1aa 100644 --- a/packages/ui/avatar/src/avatar.types.ts +++ b/packages/ui/avatar/src/avatar.types.ts @@ -1,6 +1,7 @@ import { HTMLProps } from "react" import { useStylesTypes } from "@wpmudev/sui-hooks" import { SuiHTMLAttributes, SuiStyleType } from "@wpmudev/sui-utils" +import { IconsNamesType } from "@wpmudev/sui-icons" /** * Represents the properties for an avatar component. @@ -27,6 +28,11 @@ interface AvatarProps * The CSS class name for the avatar. */ className?: string + + /** + * The icon for the avatar. + */ + icon?: IconsNamesType /** * Callback function when click on avatar */ diff --git a/packages/ui/avatar/src/elements/icon-avatar.tsx b/packages/ui/avatar/src/elements/icon-avatar.tsx index 22be11691..755c23bf2 100644 --- a/packages/ui/avatar/src/elements/icon-avatar.tsx +++ b/packages/ui/avatar/src/elements/icon-avatar.tsx @@ -1,10 +1,13 @@ import React, { Fragment } from "react" -import { User, UserAlt } from "@wpmudev/sui-icons" +import Icons, { IconsNamesType, User, UserAlt } from "@wpmudev/sui-icons" // Build "icon avatar" element -const Icon = () => ( - -) +const Icon = ({ iconName }: { iconName: IconsNamesType }) => { + const IconTag = Icons?.[iconName as IconsNamesType] + return ( + + ) +} export { Icon } diff --git a/packages/ui/drawer/src/drawer-header.tsx b/packages/ui/drawer/src/drawer-header.tsx index 7dc61cbcd..78caa0cd2 100644 --- a/packages/ui/drawer/src/drawer-header.tsx +++ b/packages/ui/drawer/src/drawer-header.tsx @@ -42,7 +42,7 @@ const DrawerHeader = ({ isSmall={true} iconOnly={true} onClick={() => { - // onClose() + onClose() action() }} _htmlProps={{ diff --git a/packages/ui/navigation-wpmudev/src/elements/wpmudev-notifications.tsx b/packages/ui/navigation-wpmudev/src/elements/wpmudev-notifications.tsx index f7dc6e346..3131f9ae1 100644 --- a/packages/ui/navigation-wpmudev/src/elements/wpmudev-notifications.tsx +++ b/packages/ui/navigation-wpmudev/src/elements/wpmudev-notifications.tsx @@ -1,22 +1,14 @@ import React, { createRef, useRef } from "react" import { Dropdown, DropdownRefProps } from "@wpmudev/sui-dropdown" -import { Button } from "@wpmudev/sui-button" import { _renderHTMLPropsSafely, generateCN } from "@wpmudev/sui-utils" import { WPMUDEVNotificationProps } from "../navigation-wpmudev.types" -import { - Drawer, - DrawerActions, - DrawerBody, - DrawerFooter, - DrawerHeader, -} from "@wpmudev/sui-drawer" import { Tooltip } from "@wpmudev/sui-tooltip" import { Link } from "@wpmudev/sui-link" const NotificationWPMUDEV: React.FC = ({ label = "What’s new on Smush?", title = "What's new", - notifications, + notifications = [], footerActions = [ Mark all as read @@ -81,7 +73,7 @@ const NotificationWPMUDEV: React.FC = ({ } const NotificationWPMUDEVContent: React.FC = ({ - notifications, + notifications = [], className = "", _htmlProps = {}, _style = {}, diff --git a/packages/ui/navigation-wpmudev/src/elements/wpmudev-user.tsx b/packages/ui/navigation-wpmudev/src/elements/wpmudev-user.tsx index 0822c3b1a..a8255d84c 100644 --- a/packages/ui/navigation-wpmudev/src/elements/wpmudev-user.tsx +++ b/packages/ui/navigation-wpmudev/src/elements/wpmudev-user.tsx @@ -1,233 +1,47 @@ -import React, { createRef } from "react" -import { Dropdown } from "@wpmudev/sui-dropdown" +import React from "react" +import { Avatar } from "@wpmudev/sui-avatar" import { Button } from "@wpmudev/sui-button" -import { - _renderHTMLPropsSafely, - generateCN, - PluginIconTypes, - PluginsIcons, -} from "@wpmudev/sui-utils" -import { IconProps } from "@wpmudev/sui-icon" -import Icons, { IconsNamesType, ExternalLink } from "@wpmudev/sui-icons" -import { WPMUDEVProps } from "./icons/types" -import { UpsellIcon } from "../icons/upsell-icon" -import { - Drawer, - DrawerActions, - DrawerBody, - DrawerHeader, -} from "@wpmudev/sui-drawer" - -const MoreFromWPMUDEV: React.FC = ({ - label = "More from WPMU DEV", - title = "More free plugins from WPMU DEV", - className = "", - plugins = [ - { - plugin: "smush", - title: "Smush", - description: "Best image optimization", - link: "https://www.wpmudev.com", - props: {}, - }, - { - plugin: "forminator", - title: "Forminator", - description: "Best form builder plugin", - link: "https://www.wpmudev.com", - props: {}, - }, - { - plugin: "defender", - title: "Defender", - description: "Best security plugin", - link: "https://www.wpmudev.com", - props: {}, - }, - { - plugin: "hustle", - title: "Hustle", - description: "Best newsletter plugin", - link: "https://www.wpmudev.com", - props: {}, - }, - { - plugin: "hummingbird", - title: "Hummingbird", - description: "Best security plugin", - link: "https://www.wpmudev.com", - props: {}, - }, - { - plugin: "branda", - title: "Branda", - description: "No-code white label plugin", - link: "https://www.wpmudev.com", - props: {}, - }, - { - plugin: "beehive", - title: "Beehive", - description: "Google Analytic dashboards", - link: "https://www.wpmudev.com", - props: {}, - }, - { - plugin: "snapshot", - title: "Snapshot", - description: "WordPress backup plugin", - link: "https://www.wpmudev.com", - props: {}, - }, - { - plugin: "blc", - title: "Broken Link Checker", - description: "Scan broken links", - link: "https://www.wpmudev.com", - props: {}, - }, - ], - upsell = { - title: "Everything you need for WordPress", - description: - "Get all 12 WPMU DEV premium plugins and more starting from just $3/month.", - link: "https://www.wpmudev.com", +import { WPMUDEVUserProps } from "../navigation-wpmudev.types" + +const UserWPMUDEV: React.FC = ({ + title, + description, + avatarProps, + action, + logout = { + show: false, props: {}, }, - filter = [], - _htmlProps = {}, - _style = {}, - ...props }) => { - const drawerRef = createRef() - - const classNames = generateCN( - "sui-wpmudev", - {}, - `sui-wpmudev__dropdown ${className}`, - ) - - const filteredPlugins = plugins.filter( - (pluginItem) => !filter.includes(pluginItem.plugin), - ) - - const dropdownContent = ( -
- {filteredPlugins && ( -
    - {filteredPlugins.map((pluginItem) => { - // Icon for the specified plugin or use a default "Plugin" icon. - const PluginIcon: PluginIconTypes = pluginItem.plugin - ? PluginsIcons?.[pluginItem.plugin] - : { icon: "Plugin" } - - // Dynamically determine the IconTag based on the provided icon prop. - let IconTag: React.ComponentType | null = null - if (!!PluginIcon) { - IconTag = Icons?.[PluginIcon.icon as IconsNamesType] - } - return ( -
  • - -
    - {!!IconTag && } -
    -
    -
    - {pluginItem.title} -
    -

    - {pluginItem.description} -

    -
    -
    -
  • - ) - })} -
- )} - {upsell && ( - - -
-
- {upsell.title} - -
-

{upsell.description}

-
-
- )} -
- ) - - const mobileDrawer = ( - - - {dropdownContent} - - ) - return ( - <> - - {title && ( -
-

{title}

+
+
+ {avatarProps && ( +
+ +
+ )} +
+ {title &&

{title}

} + {description &&

{description}

} +
+ {logout.show && ( +
+
)} - {dropdownContent} - -
- - {mobileDrawer}
- + {action &&
{action}
} +
) } -// Export the MoreFromWPMUDEV component -export { MoreFromWPMUDEV } +export { UserWPMUDEV } diff --git a/packages/ui/navigation-wpmudev/src/index.ts b/packages/ui/navigation-wpmudev/src/index.ts index 4ead1840f..9a469b0d0 100644 --- a/packages/ui/navigation-wpmudev/src/index.ts +++ b/packages/ui/navigation-wpmudev/src/index.ts @@ -1 +1,19 @@ -export { NavigationWPMUDEV } from "./navigation-wpmudev" +import { MoreFromWPMUDEV } from "./elements/wpmudev-button" +import { HelpWPMUDEVContent } from "./elements/wpmudev-help" +import { + NotificationWPMUDEV, + NotificationWPMUDEVContent, +} from "./elements/wpmudev-notifications" +import { WPMUDEVDrawer } from "./elements/wpmudev-drawer" +import { NavigationWrapper } from "./navigation-wpmudev" +import { UserWPMUDEV } from "./elements/wpmudev-user" + +export { + MoreFromWPMUDEV, + HelpWPMUDEVContent, + NotificationWPMUDEV, + NotificationWPMUDEVContent, + WPMUDEVDrawer, + NavigationWrapper, + UserWPMUDEV, +} diff --git a/packages/ui/navigation-wpmudev/src/navigation-brand.tsx b/packages/ui/navigation-wpmudev/src/navigation-brand.tsx deleted file mode 100644 index 6e1003d49..000000000 --- a/packages/ui/navigation-wpmudev/src/navigation-brand.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from "react" - -import { - _renderHTMLPropsSafely, - generateCN, - PluginIconTypes, - PluginsIcons, -} from "@wpmudev/sui-utils" -import { IconProps } from "@wpmudev/sui-icon" -import { NavigationBrandProps } from "./navigation-wpmudev.types" -import Icons, { IconsNamesType } from "@wpmudev/sui-icons" -import { useStyles } from "@wpmudev/sui-hooks" - -const NavigationBrand: React.FC = ({ - plugin, - title = "", - description = "", -}) => { - // Icon for the specified plugin or use a default "Plugin" icon. - const PluginIcon: PluginIconTypes = plugin - ? PluginsIcons?.[plugin] - : { icon: "Plugin" } - - // Dynamically determine the IconTag based on the provided icon prop. - let IconTag: React.ComponentType | null = null - if (!!PluginIcon) { - IconTag = Icons?.[PluginIcon.icon as IconsNamesType] - } - - return ( -
-
- {!!IconTag && } -
-
-

{title}

- {description} -
-
- ) -} - -NavigationBrand.displayName = "NavigationBrand" - -export { NavigationBrand } diff --git a/packages/ui/navigation-wpmudev/src/navigation-user.tsx b/packages/ui/navigation-wpmudev/src/navigation-user.tsx deleted file mode 100644 index 2ade2a7c8..000000000 --- a/packages/ui/navigation-wpmudev/src/navigation-user.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React, { useRef } from "react" - -import { Dropdown, DropdownRefProps } from "@wpmudev/sui-dropdown" -import { Avatar } from "@wpmudev/sui-avatar" - -import { NavigationUserProps } from "./navigation-wpmudev.types" -import { generateCN, isEmpty } from "@wpmudev/sui-utils" - -const NavigationUser: React.FC = ({ - user, - menu, - splitLastItem = false, - isMenuDisabled = false, - status, -}) => { - // Create a ref for the user dropdown button - const userBtnRef = useRef(null) - - // Define the user's avatar button component - const userAvatarBtn = ( - { - // Toggle the user dropdown when the avatar is clicked - userBtnRef?.current?.toggle() - }, - })} - /> - ) - - /** - * Get user block - */ - const getUserBlock = () => { - // Return null if both name and email are missing or empty - if (isEmpty(user?.name ?? "") && isEmpty(user?.email ?? "")) { - return null - } - - // Render otherwise - return ( -
- {!isEmpty(user?.name ?? "") && ( -
{user?.name}
- )} - {!isEmpty(user?.email ?? "") && ( -
{user?.email}
- )} -
- ) - } - - return ( -
- - {getUserBlock()} - -
- ) -} - -NavigationUser.displayName = "NavigationUser" - -export { NavigationUser } diff --git a/packages/ui/navigation-wpmudev/src/navigation-wpmudev.tsx b/packages/ui/navigation-wpmudev/src/navigation-wpmudev.tsx index 0100e7f49..c5f642a4a 100644 --- a/packages/ui/navigation-wpmudev/src/navigation-wpmudev.tsx +++ b/packages/ui/navigation-wpmudev/src/navigation-wpmudev.tsx @@ -1,34 +1,13 @@ -import React, { Children, createRef, RefObject } from "react" -import { Navigation } from "@wpmudev/sui-navigation" +import React from "react" import { _renderHTMLPropsSafely, generateCN } from "@wpmudev/sui-utils" import { useStyles } from "@wpmudev/sui-hooks" -import { Button } from "@wpmudev/sui-button" -import { MoreFromWPMUDEV } from "./elements/wpmudev-button" -import { HelpWPMUDEVContent } from "./elements/wpmudev-help" -import { - NotificationWPMUDEV, - NotificationWPMUDEVContent, -} from "./elements/wpmudev-notifications" -import { - Drawer, - DrawerActions, - DrawerBody, - DrawerFooter, - DrawerHeader, -} from "@wpmudev/sui-drawer" -import { Tooltip } from "@wpmudev/sui-tooltip" -import { WPMUDEVDrawer } from "./elements/wpmudev-drawer" -import { Link } from "@wpmudev/sui-link" // Navigation component -const NavigationWPMUDEV: React.FC = ({ +const NavigationWrapper: React.FC = ({ + children, _htmlProps, _style, }) => { - const ref = createRef() - const drawerRef = createRef() - const notificationRef = createRef() - const { suiInlineClassname } = useStyles(_style) // Generate CSS class names for the navigation component const classNames = generateCN( @@ -37,393 +16,12 @@ const NavigationWPMUDEV: React.FC = ({ suiInlineClassname, ) - const navActions = ( -
- { - drawerRef?.current?.toggle() - }} - > - Help and resources - - - View detail - , - , - ], - }, - { - version: "1.4", - time: "2 hours ago", - title: - "This is the main title of this version release. Make it short make it stand out", - actions: [ - , - ], - }, - { - version: "1.4", - time: "2 hours ago", - title: - "This is the main title of this version release. Make it short make it stand out", - actions: [ - , - ], - }, - { - version: "1.4", - time: "2 hours ago", - title: - "This is the main title of this version release. Make it short make it stand out", - actions: [ - , - ], - }, - { - version: "1.4", - time: "2 hours ago", - title: - "This is the main title of this version release. Make it short make it stand out", - actions: [ - , - ], - }, - ]} - /> -
- ) - - const hamburgerMenu = ( -
    -
  • - -
  • -
  • - -
  • -
- ) - - const drawer = ( - <> - - Upgrade to pro - , - ]} - > - {hamburgerMenu} - - { - drawerRef?.current?.hide() - ref?.current?.open() - }, - }} - > - - - { - notificationRef?.current?.hide() - ref?.current?.open() - }, - }} - footer={[ - - Mark all as read - , - ]} - > - - View detail - , - , - ], - }, - { - version: "1.4", - time: "2 hours ago", - title: - "This is the main title of this version release. Make it short make it stand out", - actions: [ - , - ], - }, - { - version: "1.4", - time: "2 hours ago", - title: - "This is the main title of this version release. Make it short make it stand out", - actions: [ - , - ], - }, - { - version: "1.4", - time: "2 hours ago", - title: - "This is the main title of this version release. Make it short make it stand out", - actions: [ - , - ], - }, - { - version: "1.4", - time: "2 hours ago", - title: - "This is the main title of this version release. Make it short make it stand out", - actions: [ - , - ], - }, - ]} - /> - - - ) - return ( -
- {drawer} - , - , - ]} - > - {navActions} - +
+ {children}
) } // Export the NavigationWPMUDEV component -export { NavigationWPMUDEV } +export { NavigationWrapper } diff --git a/packages/ui/navigation-wpmudev/src/navigation-wpmudev.types.ts b/packages/ui/navigation-wpmudev/src/navigation-wpmudev.types.ts index 506b2821b..c80078b27 100644 --- a/packages/ui/navigation-wpmudev/src/navigation-wpmudev.types.ts +++ b/packages/ui/navigation-wpmudev/src/navigation-wpmudev.types.ts @@ -5,12 +5,14 @@ import { PluginIconTypes, } from "@wpmudev/sui-utils" import { DropdownProps } from "@wpmudev/sui-dropdown" -import { ReactNode, RefObject } from "react" +import { ButtonHTMLAttributes, ReactNode, RefObject } from "react" import { DrawerActions, DrawerHeaderTypes, DrawerTypes, } from "@wpmudev/sui-drawer" +import { AvatarProps } from "@wpmudev/sui-avatar" +import { ButtonProps } from "@wpmudev/sui-button" /** * Represents a plugin's details. @@ -94,9 +96,24 @@ interface WPMUDEVDrawerProps extends DrawerTypes, SuiStyleType { back?: DrawerHeaderTypes["back"] } +/** + * Represents the properties for a WPMUDEV user. + */ +interface WPMUDEVUserProps extends SuiStyleType { + title: string + description?: string + avatarProps?: AvatarProps + action?: ReactNode + logout?: { + show: boolean + props: ButtonProps + } +} + export type { WPMUDEVButtonProps, WPMUDEVHelpProps, WPMUDEVNotificationProps, WPMUDEVDrawerProps, + WPMUDEVUserProps, } diff --git a/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx b/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx index 35fd5b732..1934946c4 100644 --- a/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx +++ b/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx @@ -1,16 +1,25 @@ -import React, { createRef, RefObject } from "react" - -// Import required component(s) -import { NavigationWPMUDEV as SuiNavigation } from "../src" -import { PluginsSlug } from "@wpmudev/sui-utils" - -// Import documentation main page -// import docs from "./navigation.mdx" +import React, { createRef } from "react" +import { Navigation, NavigationUser } from "@wpmudev/sui-navigation" +import { _renderHTMLPropsSafely, generateCN } from "@wpmudev/sui-utils" +import { Button } from "@wpmudev/sui-button" +import { + MoreFromWPMUDEV, + HelpWPMUDEVContent, + NotificationWPMUDEV, + NotificationWPMUDEVContent, + WPMUDEVDrawer, + NavigationWrapper, + UserWPMUDEV, +} from "../src" +import { DrawerActions } from "@wpmudev/sui-drawer" +import { Tooltip } from "@wpmudev/sui-tooltip" +import { Link } from "@wpmudev/sui-link" +import { type } from "../src/navigation-wpmudev.types" // Configure default options export default { title: "SUI/Components/Modules/Navigation WPMUDEV", - component: SuiNavigation, + component: NavigationWrapper, parameters: { layout: "fullscreen", docs: { @@ -18,117 +27,325 @@ export default { }, }, } - -// Build story -export const Navigation = (props: { - isPro: boolean - action: boolean - status: NavigationUserProps["status"] - isMenuDisabled: NavigationUserProps["isMenuDisabled"] - plugin: PluginsSlug - title: string - description: string +export const NavigationStory: React.FC = ({ + isPro = false, + brand = [], + user = [], + notifications = [], + resources = [], }) => { - const { action, isPro, status, isMenuDisabled, plugin, title, description } = - props + const ref = createRef() + const drawerRef = createRef() + const notificationRef = createRef() + + const upgradeButton = ( + + ) + + const navActions = ( +
+ { + drawerRef?.current?.toggle() + }} + > + Help and resources + + +
+ ) + + const hamburgerMenu = ( +
    +
  • + +
  • +
  • + +
  • +
+ ) + + const drawer = ( + <> + { + console.log("logout") + }, + }, + }} + action={ + + } + />, + ] + } + > + {hamburgerMenu} + + + + + + Mark all as read + , + ]} + > + + + + ) return (
- + + {drawer} + , + !isPro && ( + + ), + + + Connect site + + } + /> + , + , + ]} + > + {navActions} + +
) } -Navigation.args = { - isPro: true, - action: true, - isMenuDisabled: false, - status: "confirmed", - plugin: "smush", - title: "Smush Pro", - description: "Description", -} - -Navigation.argTypes = { - isPro: { - name: "Pro", - control: { - type: "boolean", - }, +NavigationStory.args = { + isPro: false, + connected: true, + brand: { + plugin: "smush", + title: "Smush Plugin", + description: "This is a description.", }, - action: { - name: "Action buttons", - control: { - type: "boolean", + user: { + user: { + image: "https://avatars.githubusercontent.com/u/14994452?v=4", + name: "John doe", + email: "john.doe@incsub.com", }, + status: "confirmed", + isMenuDisabled: false, + splitLastItem: true, + menu: [ + { + id: "the-hub", + label: "The Hub", + props: { + icon: "PluginDefender", + }, + }, + { + id: "product-roadmap", + label: "Product Roadmap", + props: { + icon: "PluginSmush", + }, + }, + { + id: "product-roadmap", + label: "Unlock Pro features", + props: { + icon: "PluginSmush", + variation: "smush", + }, + }, + { + id: "logout", + label: "Logout", + props: { + icon: "Exit", + }, + }, + ], }, - isMenuDisabled: { - name: "Menu Disabled", - control: { - type: "boolean", + notifications: [ + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + , + ], }, - }, - status: { - name: "User Status", - options: ["none", "confirmed", "awaiting", "not-accepted", "not-connected"], - control: { - type: "select", - labels: { - none: "None", - confirmed: "Confirmed", - awaiting: "Awaiting", - "not-accepted": "Not Accepted", - "not-connected": "Not Connected", - }, + { + version: "1.4", + time: "2 hours ago", + title: + "This is the main title of this version release. Make it short make it stand out", + actions: [ + , + ], }, - }, - plugin: { - name: "Plugin", - options: [ - "smush", - "defender", - "snapshot", - "hummingbird", - "forminator", - "beehive", - "hustle", - "smartcrawl", - "shipper", - "branda", - "blc", - "thc", - "dashboard", - ], - control: { - type: "select", - labels: { - smush: "smush", - defendre: "defender", - snapshot: "snapshot", - hummigbird: "hummingbird", - forminator: "forminator", - beehive: "beehive", - hustle: "hustle", - smartcrawl: "smartcrawl", - shipper: "shipper", - branda: "branda", - blc: "blc", - thc: "thc", - }, + ], + resources: [ + { + label: + "Instantly Turn Keywords Into SEO Links: This SmartCrawl Tool Automates It For You", + link: "https://wpmudev.com", }, - }, - title: { - name: "Title", - control: { - type: "text", + { + label: "New schema markup for SmartCrawl: Recipe, job posting & more!", + link: "https://wpmudev.com", }, - }, - description: { - name: "Description", - control: { - type: "text", + { + label: + "Target website visitors more effectively with SmartCrawl’s location-based redirects", + link: "https://wpmudev.com", }, - }, + ], } diff --git a/packages/ui/navigation/src/index.ts b/packages/ui/navigation/src/index.ts index 039a63e3b..aaa6d8be9 100644 --- a/packages/ui/navigation/src/index.ts +++ b/packages/ui/navigation/src/index.ts @@ -1,2 +1,3 @@ export { Navigation } from "./navigation" +export { NavigationUser } from "./navigation-user" export type { NavigationProps, NavigationUserProps } from "./navigation.types" diff --git a/packages/ui/navigation/src/navigation-user.tsx b/packages/ui/navigation/src/navigation-user.tsx index 146e0ba10..119d993dc 100644 --- a/packages/ui/navigation/src/navigation-user.tsx +++ b/packages/ui/navigation/src/navigation-user.tsx @@ -4,7 +4,8 @@ import { Dropdown, DropdownRefProps } from "@wpmudev/sui-dropdown" import { Avatar } from "@wpmudev/sui-avatar" import { NavigationUserProps } from "./navigation.types" -import { generateCN, isEmpty } from "@wpmudev/sui-utils" +import { _renderHTMLPropsSafely, generateCN, isEmpty } from "@wpmudev/sui-utils" +import { useStyles } from "@wpmudev/sui-hooks" const NavigationUser: React.FC = ({ user, @@ -12,10 +13,23 @@ const NavigationUser: React.FC = ({ splitLastItem = false, isMenuDisabled = false, status, + children, + className = "", + dropdownProps = {}, + _style = {}, + _htmlProps = {}, }) => { // Create a ref for the user dropdown button const userBtnRef = useRef(null) + const { suiInlineClassname } = useStyles(_style, className) + + const classNames = generateCN( + "sui-navigation__avatar", + {}, + suiInlineClassname, + ) + // Define the user's avatar button component const userAvatarBtn = ( = ({ src: user?.image ?? "", alt: "User Avatar", }} + icon={user?.icon} {...(!isMenuDisabled && { onClick: () => { // Toggle the user dropdown when the avatar is clicked @@ -56,7 +71,7 @@ const NavigationUser: React.FC = ({ } return ( -
+
= ({ className={generateCN("sui-navigation__dropdown", { split: splitLastItem, })} + {...dropdownProps} > {getUserBlock()} + {children}
) diff --git a/packages/ui/navigation/src/navigation.types.ts b/packages/ui/navigation/src/navigation.types.ts index 6ec249177..d04d29f6a 100644 --- a/packages/ui/navigation/src/navigation.types.ts +++ b/packages/ui/navigation/src/navigation.types.ts @@ -3,7 +3,11 @@ */ import { ReactNode, HTMLProps } from "react" -import { DropdownMenuItemProps } from "@wpmudev/sui-dropdown" +import { + DropdownMenuItemProps, + DropdownMenuProps, + DropdownProps, +} from "@wpmudev/sui-dropdown" import { PluginsSlug, @@ -13,6 +17,7 @@ import { import { AvatarProps } from "@wpmudev/sui-avatar" import { useStylesTypes } from "@wpmudev/sui-hooks" +import { IconsNamesType } from "@wpmudev/sui-icons" // Represents the base props for a DropdownMenu component. interface NavigationUserMenuBaseProps { @@ -70,9 +75,11 @@ type NavigationUserType = { * Email address of the user. */ email?: string + + icon?: IconsNamesType } -interface NavigationUserProps { +interface NavigationUserProps extends SuiHTMLAttributes, SuiStyleType { /* * User information. */ @@ -93,6 +100,12 @@ interface NavigationUserProps { * Seperate last item from menu. */ splitLastItem?: boolean + + children: ReactNode + + className: string + + dropdownProps?: DropdownProps } // interface definition for the Navigation diff --git a/packages/ui/navigation/stories/navigation.stories.tsx b/packages/ui/navigation/stories/navigation.stories.tsx index 2383e5da9..ea8c07f02 100644 --- a/packages/ui/navigation/stories/navigation.stories.tsx +++ b/packages/ui/navigation/stories/navigation.stories.tsx @@ -12,7 +12,6 @@ import { DrawerFooter, DrawerHeader, } from "@wpmudev/sui-drawer" -import { MoreFromWPMUDEV } from "@wpmudev/sui-modules" // Import documentation main page import docs from "./navigation.mdx" @@ -29,73 +28,6 @@ export default { }, } -const _internalDrawer = ({ - toggleRef, - title = "Drawer header", - desc = "", - ...props -}: { - toggleRef: RefObject - title: string - desc: string - [key: string]: any -}) => { - return ( - - - -
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque - rutrum sem eros, sed tempor sapien porta ac. Nullam purus metus. -
-
- -
- - -
-
-
- ) -} - -const _internalDrawerLogo = ({ - toggleRef, - title = "Drawer header", - desc = "", - ...props -}: { - toggleRef: RefObject - title: string - desc: string - [key: string]: any -}) => { - return ( - - -
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque - rutrum sem eros, sed tempor sapien porta ac. Nullam purus metus. -
-
- -
- - -
-
-
- ) -} - // Build story export const Navigation = (props: { isPro: boolean @@ -115,15 +47,6 @@ export const Navigation = (props: { return (
- <_internalDrawer - toggleRef={ref} - {...props} - placement="left" - title="Drawer title" - desc="Drawer for body container, it is fixed positioned" - hasContainer={true} - disableShadow={true} - /> , - ], + actions: [], mobileActions: [ , @@ -297,19 +217,6 @@ export const Navigation = (props: { Documentation - <_internalDrawerLogo - key="logo-drawer" - toggleRef={refLogoDrawer} - {...props} - placement="left" - title="Drawer title" - desc="Drawer for body container, it is fixed positioned" - hasContainer={true} - disableShadow={true} - _style={{ - top: "118px", - }} - />
) From c795ce99664beb3727888db9e14932d623561c72 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Wed, 16 Oct 2024 15:25:02 +0530 Subject: [PATCH 15/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20navigation?= =?UTF-8?q?=20component=20for=20plugins.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6ae74ab53..ea6377ef2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14341,6 +14341,10 @@ "resolved": "packages/ui/navigation", "link": true }, + "node_modules/@wpmudev/sui-navigation-wpmudev": { + "resolved": "packages/ui/navigation-wpmudev", + "link": true + }, "node_modules/@wpmudev/sui-notification": { "resolved": "packages/ui/notification", "link": true @@ -39881,7 +39885,7 @@ }, "packages/assets/css": { "name": "@wpmudev/sui-css", - "version": "0.0.2", + "version": "0.0.1", "license": "GPL-2.0" }, "packages/assets/icons": { @@ -39907,7 +39911,7 @@ }, "packages/common/advanced": { "name": "@wpmudev/sui-advanced", - "version": "0.0.2", + "version": "0.0.1", "license": "GPL-2.0", "dependencies": { "@wpmudev/sui-accordion": "^0.0.1", @@ -39916,7 +39920,7 @@ "@wpmudev/sui-builder": "^0.0.1", "@wpmudev/sui-code-editor": "^0.0.1", "@wpmudev/sui-code-snippet": "^0.0.1", - "@wpmudev/sui-color-picker": "^0.0.2", + "@wpmudev/sui-color-picker": "^0.0.1", "@wpmudev/sui-date-picker": "^0.0.1", "@wpmudev/sui-dropdown": "^0.0.1", "@wpmudev/sui-editor-toolbar": "^0.0.1", @@ -39997,6 +40001,7 @@ "@wpmudev/sui-dashboard-widget": "^0.0.1", "@wpmudev/sui-integration": "^0.0.1", "@wpmudev/sui-navigation": "^0.0.1", + "@wpmudev/sui-navigation-wpmudev": "^0.0.1", "@wpmudev/sui-table": "^0.0.1" } }, @@ -40019,7 +40024,7 @@ }, "packages/react": { "name": "@wpmudev/sui-react", - "version": "0.0.10", + "version": "0.0.1", "license": "GPL-2.0", "dependencies": { "@wpmudev/sui-accordion": "^0.0.1", @@ -40033,9 +40038,8 @@ "@wpmudev/sui-checkbox": "^0.0.1", "@wpmudev/sui-code-editor": "^0.0.1", "@wpmudev/sui-code-snippet": "^0.0.1", - "@wpmudev/sui-color-picker": "^0.0.2", + "@wpmudev/sui-color-picker": "^0.0.1", "@wpmudev/sui-config-table": "^0.0.1", - "@wpmudev/sui-css": "^0.0.2", "@wpmudev/sui-dashboard-widget": "^0.0.1", "@wpmudev/sui-date-picker": "^0.0.1", "@wpmudev/sui-dropdown": "^0.0.1", @@ -40047,7 +40051,6 @@ "@wpmudev/sui-grid": "^0.0.1", "@wpmudev/sui-hooks": "^0.0.1", "@wpmudev/sui-icon": "^0.0.1", - "@wpmudev/sui-icons": "^0.0.1", "@wpmudev/sui-input": "^0.0.1", "@wpmudev/sui-integration": "^0.0.1", "@wpmudev/sui-link": "^0.0.1", @@ -40207,7 +40210,7 @@ }, "packages/ui/color-picker": { "name": "@wpmudev/sui-color-picker", - "version": "0.0.2", + "version": "0.0.1", "license": "GPL-2.0", "dependencies": { "@types/react-color": "^3.0.7", @@ -40412,6 +40415,19 @@ "react": "^18.2.0" } }, + "packages/ui/navigation-wpmudev": { + "name": "@wpmudev/sui-navigation-wpmudev", + "version": "0.0.1", + "license": "GPL-2.0", + "dependencies": { + "@wpmudev/sui-avatar": "^0.0.1", + "@wpmudev/sui-dropdown": "^0.0.1", + "@wpmudev/sui-icon": "^0.0.1", + "@wpmudev/sui-icons": "^0.0.1", + "@wpmudev/sui-utils": "^0.0.1", + "react": "^18.2.0" + } + }, "packages/ui/notification": { "name": "@wpmudev/sui-notification", "version": "0.0.1", From 221d5fd2838676f33ec1e35cb5004806884c8c71 Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Wed, 16 Oct 2024 15:56:29 +0530 Subject: [PATCH 16/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20resolved?= =?UTF-8?q?=20tests.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__tests__/navigation.test.tsx | 73 ------------------- .../stories/navigation-wpmudev.stories.tsx | 1 - .../ui/navigation/src/navigation.types.ts | 4 +- 3 files changed, 2 insertions(+), 76 deletions(-) delete mode 100644 packages/ui/navigation-wpmudev/__tests__/navigation.test.tsx diff --git a/packages/ui/navigation-wpmudev/__tests__/navigation.test.tsx b/packages/ui/navigation-wpmudev/__tests__/navigation.test.tsx deleted file mode 100644 index 9740711a1..000000000 --- a/packages/ui/navigation-wpmudev/__tests__/navigation.test.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { Fragment } from "react" -import "@testing-library/jest-dom" -import { screen, render } from "@testing-library/react" -import { a11yTest } from "@wpmudev/sui-utils" -import { Navigation } from "../src" - -describe("@wpmudev/sui-navigation", () => { - const Component = () => ( - ACTIONS list
]} - brand={{ - title: "Smush Pro", - description: "Description for Smush Pro", - }} - user={{ - user: { - image: "https://avatars.githubusercontent.com/u/14994452?v=4", - name: "John doe", - email: "john.doe@incsub.com", - }, - menu: [ - { - id: "the-hub", - label: "The Hub", - props: { - icon: "PluginDefender", - }, - }, - { - id: "product-roadmap", - label: "Product Roadmap", - props: { - icon: "PluginSmush", - }, - }, - { - id: "product-roadmap", - label: "Unlock Pro features", - props: { - icon: "PluginSmush", - variation: "smush", - }, - }, - ], - }} - > - CUSTOM CONTENT - - ) - - beforeEach(() => { - render() - }) - - it("renders correctly", () => { - expect(screen.getByTestId("navigation")).toBeInTheDocument() - }) - - it("brand prop renders correctly", () => { - expect(screen.getByText("Smush Pro")).toBeVisible() - expect(screen.getByText("Description for Smush Pro")).toBeVisible() - }) - - it("user prop renders correctly", () => { - expect(screen.getByText("John doe")).toBeVisible() - expect(screen.getByText("john.doe@incsub.com")).toBeVisible() - }) - - // eslint-disable-next-line jest/expect-expect - it("passes a11y test", async () => { - await a11yTest() - }) -}) diff --git a/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx b/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx index 1934946c4..96389b83b 100644 --- a/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx +++ b/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx @@ -14,7 +14,6 @@ import { import { DrawerActions } from "@wpmudev/sui-drawer" import { Tooltip } from "@wpmudev/sui-tooltip" import { Link } from "@wpmudev/sui-link" -import { type } from "../src/navigation-wpmudev.types" // Configure default options export default { diff --git a/packages/ui/navigation/src/navigation.types.ts b/packages/ui/navigation/src/navigation.types.ts index d04d29f6a..be8552813 100644 --- a/packages/ui/navigation/src/navigation.types.ts +++ b/packages/ui/navigation/src/navigation.types.ts @@ -101,9 +101,9 @@ interface NavigationUserProps extends SuiHTMLAttributes, SuiStyleType { */ splitLastItem?: boolean - children: ReactNode + children?: ReactNode - className: string + className?: string dropdownProps?: DropdownProps } From 0c5733ffefea25826c89a1ee490a6d7c53918c5b Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Wed, 16 Oct 2024 16:13:38 +0530 Subject: [PATCH 17/17] =?UTF-8?q?=E2=9C=A8=20new(navigation):=20resolved?= =?UTF-8?q?=20tests.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../navigation-wpmudev/stories/navigation-wpmudev.stories.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx b/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx index 96389b83b..1e6bc4e79 100644 --- a/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx +++ b/packages/ui/navigation-wpmudev/stories/navigation-wpmudev.stories.tsx @@ -115,9 +115,7 @@ export const NavigationStory: React.FC = ({ logout={{ show: true, props: { - onClick: () => { - console.log("logout") - }, + onClick: () => {}, }, }} action={