Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adds app switcher lab component #2416

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

michaeltamaki-okta
Copy link
Contributor

@michaeltamaki-okta michaeltamaki-okta commented Nov 15, 2024

OKTA-825118

Summary

feat: adds app switcher lab component

Building out the presentation layer of the "App Switcher" https://odyssey.okta.design/latest/components/app-switcher/design-mla5Wn5G (now called "Nav Rail").
Figma: https://www.figma.com/design/zh7A9gjaDlI50Hctdvd1OB/Odyssey-Components?node-id=22141-142254&node-type=frame&t=Qc7MjiWUFNtOh9Vd-0
Playground: https://6485e4e33982ca4977fff8d81ef98f680e713a9c.ods.dev/?path=/docs/labs-components-appswitcher--docs

Component checklist

Code structure

  • Organize code using a modular component architecture.
  • Use semantic HTML for clear and meaningful structure.
  • Break down complex components into smaller, reusable parts.

Accessibility implementation

  • Apply ARIA attributes to indicate roles and relationships.
  • Test focus management and ensure interactive elements are keyboard accessible.
  • Provide visual alternatives for auditory elements.

Internationalization (i18n) implementation

  • Separate any text content from the component's code for translation.
  • Test RTL support in Storybook
Screenshot 2024-11-18 at 8 44 24 AM

Cross-browser compatibility

  • Ensure consistent behavior and appearance across browsers.

Chrome

Screenshot 2024-11-15 at 10 14 34 AM Screenshot 2024-11-15 at 10 14 45 AM

Safari

Screenshot 2024-11-15 at 10 15 13 AM Screenshot 2024-11-15 at 10 15 21 AM

Firefox

Screenshot 2024-11-15 at 10 17 37 AM Screenshot 2024-11-15 at 10 17 43 AM

Documentation

  • Include code snippets, demos, and examples for various use cases.
  • Provide guidance on customization and handling special cases.

Finalize code

  • Interaction designers, UI eng and visual designers need to review that the Storybook code matches the intended Figma design
  • Interaction designers need to confirm Storybook code matches Supernova
  • Interaction and visual designers merge Figma and code at the same time
  • Share updates to the #design-system-team

QA

  • Include necessary unit tests to continuously verify component functionality
  • Screen reader test error/success states or message
  • Test edge cases and error scenarios to validate robustness

Testing and validation

  • Share work in Craft to get feedback from the Odyssey team
  • Share work to get feedback from pillar design captains or product designers in #design-team as customer feedback is essential to help us validate our assumptions, identify pain points, and improve our user experience

import { memo } from "react";

const OktaAuraSvgComponent = styled("svg")(() => ({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied over from the other PR
@bryancunningham-okta #2415 (comment)

@michaeltamaki-okta I think we can use the svg that currently lives in the SideNav folder. We can just wrap it in a styled component and apply these sizes to it. Rather than duplicate the SVG with a different size.

The SVG in the SideNav folder isn't being used (at least as far as I can tell), so I actually moved it to the NavRail folder here.

}),
);

const NavRailAppImgComponent = styled("img")(() => ({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from the other PR @bryancunningham-okta #2415 (comment)

IMHO, It would be great if we could render the SVGs inline, rather than using images here

The plan is to load the SVGs from monolith/CDN (https://github.com/atko-eng/okta-ui/pull/8012 https://github.com/atko-eng/okta-core/pull/103856). The pros of this approach is that any app icon changes/additions/removals don't require an Odyssey version bump since it all comes from the backend. The downside is that we can't do inline SVGs like you suggested.

Copy link
Contributor Author

@michaeltamaki-okta michaeltamaki-okta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added notes from meeting with @KevinGhadyani-Okta

const renderAppIconLink = useCallback(
(muiProps: MuiPropsContextType) => {
return (
<NavRailAppLinkComponent
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add aria-current

>
<OktaAura />
</NavRailOktaAuraWrapperComponent>
{appIcons.map((appIcon) => (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add nav (Add to the NavRail wrapper), ul (Add a wrapper over all the apps), li (Add to NavRailApp component)

shouldForwardProp: (prop) => prop !== "odysseyDesignTokens",
})(({ odysseyDesignTokens }: { odysseyDesignTokens: DesignTokens }) => ({
width: "100%",
height: NAV_RAIL_WIDTH,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See if we can import a shared value between top nav

Comment on lines 22 to 23
const APP_SIDE_LENGTH = "36px";
const APP_ICON_SIDE_LENGTH = "32px";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to rem

const NAV_RAIL_WIDTH = "64px";

export type NavRailProps = {
appIcons?: Omit<NavRailAppProps, "selectedAppName">[];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer using Pick instead of Omit

Comment on lines 88 to 89
(muiProps: MuiPropsContextType) => {
return (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implicit return

>
<NavRailAppImgComponent
src={isSelected ? appIconSelectedUrl : appIconDefaultUrl}
alt="" // Tell screen reader to ignore the image; the Tooltip describes the link
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

role=presentation


const NAV_RAIL_WIDTH = "64px";

export type NavRailProps = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add visibilityState = invisible | loading | loaded

How should we handle the loading state?

Skeleton

  • Enduser: Skeleton shows, then disappears (pop in during load)
  • Admin: Skeleton shows, then gets populated

No Skeleton ✅

  • Enduser: Skeleton does not show, then disappears
  • Admin: Skeleton does not show, then nav rail pops in
  • Could we mitigate this via storing in local storage to prevent pop in? Would pop in the first load, but would not pop in after that.
  • Also consider that this is just for the MVP where it is only shown for the admin. In the future, when it is shown to all users, we could switch to skeleton.

Full screen loading screen (prevents pop in)

  • Would block showing the app until we get the data. Unacceptable to downstream teams.

Keep side nav the same width regardless of app switcher

  • No, would break design assumptions

play: async ({ canvasElement, step }: PlaywrightProps<NavRailProps>) => {
const canvas = within(canvasElement);

await step("Nav rail successfully loads", async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shows all items

play: async ({ canvasElement, step }: PlaywrightProps<NavRailProps>) => {
const canvas = within(canvasElement);

await step("Nav rail does not load", async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hides when no items

@michaeltamaki-okta michaeltamaki-okta changed the title feat: adds nav rail lab component feat: adds app switcher lab component Nov 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant