diff --git a/src/components/SistentNavigation/content.js b/src/components/SistentNavigation/content.js index c4c5d560ac9cd..25ddc47c4c024 100644 --- a/src/components/SistentNavigation/content.js +++ b/src/components/SistentNavigation/content.js @@ -45,82 +45,85 @@ export const content = [ { id: 32, link: "/projects/sistent/components/circularprogress/guidance", text: "Circular Progress" }, { id: 33, link: "/projects/sistent/components/circularprogress/code", text: "Circular Progress" }, - { id: 34, link: "/projects/sistent/components/container", text: "Container" }, - { id: 35, link: "/projects/sistent/components/container/guidance", text: "Container" }, - { id: 36, link: "/projects/sistent/components/container/code", text: "Container" }, + { id: 34, link: "/projects/sistent/components/collapse", text: "Collapse" }, + { id: 35, link: "/projects/sistent/components/collapse/guidance", text: "Collapse" }, + { id: 36, link: "/projects/sistent/components/collapse/code", text: "Collapse" }, - { id: 37, link: "/projects/sistent/components/dialog", text: "Dialog" }, - { id: 38, link: "/projects/sistent/components/dialog/guidance", text: "Dialog" }, - { id: 39, link: "/projects/sistent/components/dialog/code", text: "Dialog" }, + { id: 37, link: "/projects/sistent/components/container", text: "Container" }, + { id: 38, link: "/projects/sistent/components/container/guidance", text: "Container" }, + { id: 39, link: "/projects/sistent/components/container/code", text: "Container" }, - { id: 40, link: "/projects/sistent/components/formcontrollabel", text: "FormControlLabel" }, - { id: 41, link: "/projects/sistent/components/formcontrollabel/guidance", text: "FormControlLabel" }, - { id: 42, link: "/projects/sistent/components/formcontrollabel/code", text: "FormControlLabel" }, + { id: 40, link: "/projects/sistent/components/dialog", text: "Dialog" }, + { id: 41, link: "/projects/sistent/components/dialog/guidance", text: "Dialog" }, + { id: 42, link: "/projects/sistent/components/dialog/code", text: "Dialog" }, - { id: 43, link: "/projects/sistent/components/grid", text: "Grid" }, - { id: 44, link: "/projects/sistent/components/grid/guidance", text: "Grid" }, - { id: 45, link: "/projects/sistent/components/grid/code", text: "Grid" }, + { id: 43, link: "/projects/sistent/components/formcontrollabel", text: "FormControlLabel" }, + { id: 44, link: "/projects/sistent/components/formcontrollabel/guidance", text: "FormControlLabel" }, + { id: 45, link: "/projects/sistent/components/formcontrollabel/code", text: "FormControlLabel" }, - { id: 46, link: "/projects/sistent/components/iconbutton", text: "IconButton" }, - { id: 47, link: "/projects/sistent/components/iconbutton/guidance", text: "IconButton" }, - { id: 48, link: "/projects/sistent/components/iconbutton/code", text: "IconButton" }, + { id: 46, link: "/projects/sistent/components/grid", text: "Grid" }, + { id: 47, link: "/projects/sistent/components/grid/guidance", text: "Grid" }, + { id: 48, link: "/projects/sistent/components/grid/code", text: "Grid" }, - { id: 49, link: "/projects/sistent/components/icons", text: "Icons" }, + { id: 49, link: "/projects/sistent/components/iconbutton", text: "IconButton" }, + { id: 50, link: "/projects/sistent/components/iconbutton/guidance", text: "IconButton" }, + { id: 51, link: "/projects/sistent/components/iconbutton/code", text: "IconButton" }, - { id: 50, link: "/projects/sistent/components/link", text: "Link" }, - { id: 51, link: "/projects/sistent/components/link/guidance", text: "Link" }, - { id: 52, link: "/projects/sistent/components/link/code", text: "Link" }, + { id: 52, link: "/projects/sistent/components/icons", text: "Icons" }, - { id: 53, link: "/projects/sistent/components/list", text: "List" }, - { id: 54, link: "/projects/sistent/components/list/guidance", text: "List" }, - { id: 55, link: "/projects/sistent/components/list/code", text: "List" }, + { id: 53, link: "/projects/sistent/components/link", text: "Link" }, + { id: 54, link: "/projects/sistent/components/link/guidance", text: "Link" }, + { id: 55, link: "/projects/sistent/components/link/code", text: "Link" }, - { id: 56, link: "/projects/sistent/components/modal", text: "Modal" }, - { id: 57, link: "/projects/sistent/components/modal/guidance", text: "Modal" }, - { id: 58, link: "/projects/sistent/components/modal/code", text: "Modal" }, + { id: 56, link: "/projects/sistent/components/list", text: "List" }, + { id: 57, link: "/projects/sistent/components/list/guidance", text: "List" }, + { id: 58, link: "/projects/sistent/components/list/code", text: "List" }, - { id: 59, link: "/projects/sistent/components/pagination", text: "Pagination" }, - { id: 60, link: "/projects/sistent/components/pagination/guidance", text: "Pagination" }, - { id: 61, link: "/projects/sistent/components/pagination/code", text: "Pagination" }, + { id: 59, link: "/projects/sistent/components/modal", text: "Modal" }, + { id: 60, link: "/projects/sistent/components/modal/guidance", text: "Modal" }, + { id: 61, link: "/projects/sistent/components/modal/code", text: "Modal" }, - { id: 62, link: "/projects/sistent/components/paper", text: "Paper" }, - { id: 63, link: "/projects/sistent/components/paper/guidance", text: "Paper" }, - { id: 64, link: "/projects/sistent/components/paper/code", text: "Paper" }, + { id: 62, link: "/projects/sistent/components/pagination", text: "Pagination" }, + { id: 63, link: "/projects/sistent/components/pagination/guidance", text: "Pagination" }, + { id: 64, link: "/projects/sistent/components/pagination/code", text: "Pagination" }, - { id: 65, link: "/projects/sistent/components/popper", text: "Popper" }, - { id: 66, link: "/projects/sistent/components/popper/guidance", text: "Popper" }, - { id: 67, link: "/projects/sistent/components/popper/code", text: "Popper" }, + { id: 65, link: "/projects/sistent/components/paper", text: "Paper" }, + { id: 66, link: "/projects/sistent/components/paper/guidance", text: "Paper" }, + { id: 67, link: "/projects/sistent/components/paper/code", text: "Paper" }, - { id: 68, link: "/projects/sistent/components/radiogroup", text: "RadioGroup" }, - { id: 69, link: "/projects/sistent/components/radiogroup/guidance", text: "RadioGroup" }, - { id: 70, link: "/projects/sistent/components/radiogroup/code", text: "RadioGroup" }, + { id: 68, link: "/projects/sistent/components/popper", text: "Popper" }, + { id: 69, link: "/projects/sistent/components/popper/guidance", text: "Popper" }, + { id: 70, link: "/projects/sistent/components/popper/code", text: "Popper" }, - { id: 71, link: "/projects/sistent/components/select", text: "Select" }, - { id: 72, link: "/projects/sistent/components/select/guidance", text: "Select" }, - { id: 73, link: "/projects/sistent/components/select/code", text: "Select" }, + { id: 71, link: "/projects/sistent/components/radiogroup", text: "RadioGroup" }, + { id: 72, link: "/projects/sistent/components/radiogroup/guidance", text: "RadioGroup" }, + { id: 73, link: "/projects/sistent/components/radiogroup/code", text: "RadioGroup" }, - { id: 74, link: "/projects/sistent/components/switch", text: "Switch" }, - { id: 75, link: "/projects/sistent/components/switch/guidance", text: "Switch" }, - { id: 76, link: "/projects/sistent/components/switch/code", text: "Switch" }, + { id: 74, link: "/projects/sistent/components/select", text: "Select" }, + { id: 75, link: "/projects/sistent/components/select/guidance", text: "Select" }, + { id: 76, link: "/projects/sistent/components/select/code", text: "Select" }, - { id: 77, link: "/projects/sistent/components/tabs", text: "Tabs" }, - { id: 78, link: "/projects/sistent/components/tabs/guidance", text: "Tabs" }, - { id: 79, link: "/projects/sistent/components/tabs/code", text: "Tabs" }, + { id: 77, link: "/projects/sistent/components/switch", text: "Switch" }, + { id: 78, link: "/projects/sistent/components/switch/guidance", text: "Switch" }, + { id: 79, link: "/projects/sistent/components/switch/code", text: "Switch" }, - { id: 80, link: "/projects/sistent/components/text-field", text: "Text Field" }, - { id: 81, link: "/projects/sistent/components/text-field/guidance", text: "Text Field" }, - { id: 82, link: "/projects/sistent/components/text-field/code", text: "Text Field" }, + { id: 80, link: "/projects/sistent/components/tabs", text: "Tabs" }, + { id: 81, link: "/projects/sistent/components/tabs/guidance", text: "Tabs" }, + { id: 82, link: "/projects/sistent/components/tabs/code", text: "Tabs" }, - { id: 83, link: "/projects/sistent/components/text-input", text: "Text Input" }, - { id: 84, link: "/projects/sistent/components/text-input/guidance", text: "Text Input" }, - { id: 85, link: "/projects/sistent/components/text-input/code", text: "Text Input" }, + { id: 83, link: "/projects/sistent/components/text-field", text: "Text Field" }, + { id: 84, link: "/projects/sistent/components/text-field/guidance", text: "Text Field" }, + { id: 85, link: "/projects/sistent/components/text-field/code", text: "Text Field" }, - { id: 86, link: "/projects/sistent/components/toolbar", text: "Toolbar" }, - { id: 87, link: "/projects/sistent/components/toolbar/guidance", text: "Toolbar" }, - { id: 88, link: "/projects/sistent/components/toolbar/code", text: "Toolbar" }, + { id: 86, link: "/projects/sistent/components/text-input", text: "Text Input" }, + { id: 87, link: "/projects/sistent/components/text-input/guidance", text: "Text Input" }, + { id: 88, link: "/projects/sistent/components/text-input/code", text: "Text Input" }, - { id: 89, link: "/projects/sistent/components/tooltip", text: "Tooltip" }, - { id: 90, link: "/projects/sistent/components/tooltip/guidance", text: "Tooltip" }, - { id: 91, link: "/projects/sistent/components/tooltip/code", text: "Tooltip" }, + { id: 89, link: "/projects/sistent/components/toolbar", text: "Toolbar" }, + { id: 90, link: "/projects/sistent/components/toolbar/guidance", text: "Toolbar" }, + { id: 91, link: "/projects/sistent/components/toolbar/code", text: "Toolbar" }, + { id: 92, link: "/projects/sistent/components/tooltip", text: "Tooltip" }, + { id: 93, link: "/projects/sistent/components/tooltip/guidance", text: "Tooltip" }, + { id: 94, link: "/projects/sistent/components/tooltip/code", text: "Tooltip" }, ]; diff --git a/src/sections/Projects/Sistent/components/collapse/code.js b/src/sections/Projects/Sistent/components/collapse/code.js new file mode 100644 index 0000000000000..7f434b0de792e --- /dev/null +++ b/src/sections/Projects/Sistent/components/collapse/code.js @@ -0,0 +1,295 @@ +import React, { useState, useMemo } from "react"; +import { Collapse, Button, SistentThemeProvider } from "@sistent/sistent"; +import { SistentLayout } from "../../sistent-layout"; +import TabButton from "../../../../../reusecore/Button"; +import { useStyledDarkMode } from "../../../../../theme/app/useStyledDarkMode"; +import { CodeBlock } from "../button/code-block"; +import { navigate } from "gatsby"; +import { useLocation } from "@reach/router"; + +const TABS = ["Overview", "Guidance", "Code"]; + +const collapseExamples = [ + { + title: "Basic Collapse", + description: "A simple collapsible section that can be toggled with a button click.", + element: ({ isDark }) => { + const [expanded, setExpanded] = useState(false); + return ( + <> + + +
+ This content will be collapsed/expanded with a smooth animation. +
+
+ + ); + }, + code: `import { Collapse, Button } from "@sistent/sistent"; +import { useState } from "react"; + +function BasicCollapse() { + const [expanded, setExpanded] = useState(false); + + return ( + <> + + +
+ Content to be collapsed/expanded +
+
+ + ); +}`, + id: "basic-collapse" + }, + { + title: "Default Expanded", + description: "A collapsible section that starts expanded by default.", + element: ({ isDark }) => { + const [expanded, setExpanded] = useState(true); + return ( + <> + + +
+ This content is expanded by default. Click the button to collapse it. +
+
+ + ); + }, + code: `function DefaultExpanded() { + const [expanded, setExpanded] = useState(true); + + return ( + <> + + +
Content that's expanded by default
+
+ + ); +}`, + id: "default-expanded" + }, + { + title: "Unmount on Exit", + description: "Unmounts the content when collapsed for better performance with large content.", + element: ({ isDark }) => { + const [expanded, setExpanded] = useState(false); + return ( + <> + + +
+ This content will be unmounted when collapsed (check the React DevTools). +
+
+ + ); + }, + code: `function UnmountOnExit() { + const [expanded, setExpanded] = useState(false); + + return ( + <> + + +
Content that unmounts when collapsed
+
+ + ); +}`, + id: "unmount-on-exit" + }, + { + title: "Custom Transition", + description: "Customize the transition duration and easing function.", + element: ({ isDark }) => { + const [expanded, setExpanded] = useState(false); + return ( + <> + + +
+ Notice the different animation speeds when expanding vs collapsing. +
+
+ + ); + }, + code: `function CustomTransition() { + const [expanded, setExpanded] = useState(false); + + return ( + <> + + +
Custom transition content
+
+ + ); +}`, + id: "custom-transition" + } +]; + +const CollapseComponent = () => { + const { isDark } = useStyledDarkMode(); + const location = useLocation(); + + // Determine active tab from URL + const activeTab = useMemo(() => { + const path = location.pathname; + if (path.endsWith("/code")) return "Code"; + if (path.endsWith("/guidance")) return "Guidance"; + return "Overview"; + }, [location.pathname]); + + // Handle tab change + const handleTabChange = (tab) => { + const basePath = "/projects/sistent/components/collapse"; + const newPath = tab === "Overview" ? basePath : `${basePath}/${tab.toLowerCase()}`; + if (location.pathname !== newPath) { + navigate(newPath); + } + }; + + return ( + +
+ +

Collapse

+
+

+ The Collapse component provides a smooth, animated way to show and hide content. + Below are various examples demonstrating its capabilities and usage patterns. +

+ +
+ {TABS.map((tab) => ( + handleTabChange(tab)} + /> + ))} +
+ +
+ {collapseExamples.map((example) => ( +
+

+ {example.title} +

+

+ {example.description} +

+
+ + {example.element({ isDark })} + +
+
+ +
+
+ ))} +
+
+
+ ); +}; + +export default CollapseComponent; \ No newline at end of file diff --git a/src/sections/Projects/Sistent/components/collapse/guidance.js b/src/sections/Projects/Sistent/components/collapse/guidance.js new file mode 100644 index 0000000000000..5cfdcaf82b231 --- /dev/null +++ b/src/sections/Projects/Sistent/components/collapse/guidance.js @@ -0,0 +1,138 @@ +import React from "react"; +import { navigate } from "gatsby"; +import { useLocation } from "@reach/router"; +import { SistentLayout } from "../../sistent-layout"; +import TabButton from "../../../../../reusecore/Button"; + +const Guidance = () => { + const location = useLocation(); + + return ( + +
+

Collapse

+

+ The Collapse component provides a smooth, animated transition for showing and hiding content. + It's an essential UI pattern for managing content density and progressive disclosure of information. +

+ +
+ navigate("/projects/sistent/components/collapse")} + title="Overview" + /> + navigate("/projects/sistent/components/collapse/guidance")} + title="Guidance" + /> + navigate("/projects/sistent/components/collapse/code")} + title="Code" + /> +
+ +
+
+

Best Practices

+
    +
  • + Clear Triggers: Always use clear, descriptive labels for collapse triggers that indicate the action and content. +
  • +
  • + Progressive Disclosure: Use collapse to hide secondary content or advanced options that aren't immediately needed. +
  • +
  • + Performance: For large content, consider using unmountOnExit to improve performance by unmounting content when collapsed. +
  • +
  • + Animation Timing: Adjust the timeout prop to match your application's animation speed for a cohesive feel. +
  • +
  • + Consistent Behavior: Maintain consistent behavior across your application - don't mix different animation patterns for similar interactions. +
  • +
+ +
+ +
+

Accessibility Considerations

+
    +
  • + Keyboard Navigation: Ensure the collapse trigger is keyboard accessible and can be activated with both Enter and Space keys. +
  • +
  • + ARIA Attributes: The component automatically handles aria-expanded and aria-controls attributes. +
  • +
  • + Focus Management: Consider managing focus when content is expanded/collapsed, especially for screen reader users. +
  • +
  • + Screen Reader Announcements: Use aria-live regions to announce state changes to screen reader users. +
  • +
+ +
+ +
+

When to Use

+
    +
  • FAQs and help sections
  • +
  • Forms with optional or advanced fields
  • +
  • Content that can be toggled on/off
  • +
  • Accordion interfaces
  • +
  • Mobile navigation menus
  • +
+ +
+ +
+

When to Consider Something Else

+
    +
  • For simple show/hide without animation, consider conditional rendering
  • +
  • For modal dialogs or overlays, use the Dialog component instead
  • +
  • For tabbed interfaces, consider using the Tabs component
  • +
+ +
+ +
+

Performance Optimization

+
    +
  • Use unmountOnExit for better performance with large content
  • +
  • Consider code-splitting for complex content within collapsible sections
  • +
  • Memoize the content if it includes expensive computations
  • +
+ +
+ +
+

Common Patterns

+
    +
  • Accordion: Multiple collapsible sections where only one can be open at a time
  • +
  • Expandable Cards: Cards with a summary that can be expanded for more details
  • +
  • Progressive Disclosure: Show advanced options or additional information on demand
  • +
  • Mobile Navigation: Collapsible menus for mobile views
  • +
+
+
+
+
+ ); +}; + +export default Guidance; \ No newline at end of file diff --git a/src/sections/Projects/Sistent/components/collapse/index.js b/src/sections/Projects/Sistent/components/collapse/index.js new file mode 100644 index 0000000000000..b3a620ba84f45 --- /dev/null +++ b/src/sections/Projects/Sistent/components/collapse/index.js @@ -0,0 +1,129 @@ +import React, { useState, useMemo } from "react"; +import { navigate } from "gatsby"; +import { useLocation } from "@reach/router"; +import { SistentThemeProvider, Collapse, Button } from "@sistent/sistent"; +import TabButton from "../../../../../reusecore/Button"; +import { SistentLayout } from "../../sistent-layout"; +import { Row } from "../../../../../reusecore/Layout"; +import { useStyledDarkMode } from "../../../../../theme/app/useStyledDarkMode"; + +const SistentCollapse = () => { + const location = useLocation(); + const { isDark } = useStyledDarkMode(); + const [expanded, setExpanded] = useState(false); + const [expanded2, setExpanded2] = useState(true); + + // Memoize the active tab to prevent unnecessary re-renders + const activeTab = useMemo(() => { + const path = location.pathname; + if (path.endsWith("/code")) return "code"; + if (path.endsWith("/guidance")) return "guidance"; + return "overview"; + }, [location.pathname]); + + // Handle tab change + const handleTabChange = (tab) => { + const basePath = "/projects/sistent/components/collapse"; + const newPath = tab === "overview" ? basePath : `${basePath}/${tab}`; + if (location.pathname !== newPath) { + navigate(newPath); + } + }; + + return ( + +
+ +

Collapse

+
+

+ The Collapse component allows you to create collapsible content areas that can be toggled to show or hide content. It's commonly used for FAQs, accordions, and other UI elements where space needs to be managed efficiently. +

+ +
+ handleTabChange("overview")} + title="Overview" + /> + handleTabChange("guidance")} + title="Guidance" + /> + handleTabChange("code")} + title="Code" + /> +
+ +
+

+ The Collapse component provides a smooth, animated way to show and hide content. It's particularly useful for creating space-efficient interfaces and progressive disclosure of information. +

+ +
+

Basic Collapse

+

+ A simple collapsible section that can be toggled with a button click. +

+ + + + +
+ This content will be collapsed/expanded with a smooth animation. + You can put any content here, including other React components. +
+
+
+
+ +
+ +
+

Default Expanded

+

+ A collapsible section that starts expanded by default. +

+ + + + +
+ This content is expanded by default. Click the button to collapse it. +
+
+
+
+
+
+
+
+ ); +}; + +export default SistentCollapse; \ No newline at end of file diff --git a/src/sections/Projects/Sistent/components/content.js b/src/sections/Projects/Sistent/components/content.js index 028e6a20eeef1..1540835f5e342 100644 --- a/src/sections/Projects/Sistent/components/content.js +++ b/src/sections/Projects/Sistent/components/content.js @@ -217,7 +217,14 @@ const componentsData = [ "src": "/chip", }, { - id: 29, + "id": 29, + "name": "Collapse", + "description": "The Collapse component is used to create expandable/collapsible content sections. It smoothly animates the height of its children from zero to full height when expanded.", + "url": "/projects/sistent/components/collapse", + "src": "/collapse", + }, + { + id: 30, name: "IconButton", description: "IconButton provides an interactive button component that displays only an icon, ideal for compact UIs where space is limited and actions are easily recognizable through iconography.", url: "/projects/sistent/components/iconbutton",