Skip to content

Commit

Permalink
Merge pull request #566 from ably/component-focus-fix
Browse files Browse the repository at this point in the history
[WEB-4122] Fix component focus behaviour, add theming to Accordion
  • Loading branch information
jamiehenson authored Dec 4, 2024
2 parents 1a36dd8 + f0cf003 commit a0ad31e
Show file tree
Hide file tree
Showing 17 changed files with 91 additions and 108 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ably/ui",
"version": "15.1.0",
"version": "15.1.1",
"description": "Home of the Ably design system library ([design.ably.com](https://design.ably.com)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.",
"repository": {
"type": "git",
Expand Down
8 changes: 5 additions & 3 deletions src/core/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,14 @@ const AccordionRow = ({
<AccordionTrigger
onClick={onClick}
className={cn({
"flex w-full group/accordion-trigger py-16 ui-text-p1 font-bold text-left items-center gap-12 transition-colors":
"flex w-full group/accordion-trigger py-16 ui-text-p1 font-bold text-left items-center gap-12 transition-colors focus:outline-none":
true,
"px-16 mb-16 rounded-lg": isNonTransparentTheme(theme),
"rounded-none": !isNonTransparentTheme(theme),
"pointer-events-none focus:outline-none": isStaticTheme(theme),
"focus:outline-gui-blue-focus": !isStaticTheme(theme),
"pointer-events-none focus-visible:outline-none":
isStaticTheme(theme),
"focus-visible:outline-4 focus-visible:outline-offset-0 focus-visible:outline-gui-blue-focus":
!isStaticTheme(theme),
"sticky top-0": sticky,
[`${bg} ${hoverBg} ${text}`]: !(selectable && isOpen),
[`${selectableBg} ${selectableText}`]: selectable && isOpen,
Expand Down
15 changes: 8 additions & 7 deletions src/core/Accordion/Accordion.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { accordionThemes } from "./types";
const loremText =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin scelerisque congue risus id lobortis. Vivamus blandit dolor at ultricies cursus. Phasellus pharetra nunc erat, quis porttitor mauris faucibus in. Donec feugiat dapibus orci et blandit. Duis eleifend accumsan est nec euismod. Proin imperdiet malesuada lacus, a aliquam eros aliquet nec. Sed eu dolor finibus, sodales nisl a, egestas mi. In semper interdum lacinia. Duis malesuada diam quis purus blandit, sit amet imperdiet neque accumsan. Morbi viverra vitae risus ut pellentesque. Praesent ac blandit augue. Aliquam purus lectus, lacinia in semper vitae, dictum eu felis. Donec vel pulvinar eros, id facilisis neque. Aenean odio arcu, accumsan vel est in, lobortis rhoncus ligula. Pellentesque sit amet odio velit.";

const lorem = <p className="mb-16">{loremText}</p>;
const lorem = (
<p className="mb-16 text-neutral-1300 dark:text-neutral-000">{loremText}</p>
);

const textarea = (
<textarea
Expand Down Expand Up @@ -53,12 +55,11 @@ const AccordionPresentation = ({ data, options }: AccordionProps) => (
{accordionThemes
.filter((theme) => !theme.toLowerCase().includes("static"))
.map((theme) => (
<div
key={theme}
className={`p-16 rounded-lg ${theme.includes("dark") ? "bg-neutral-1300" : ""}`}
>
<div key={theme} className={"p-16 rounded-lg"}>
<p
className={`ui-text-p3 mb-16 text-center font-mono ${theme.includes("dark") ? "text-neutral-000" : ""}`}
className={
"ui-text-p3 mb-16 text-center text-neutral-1300 dark:text-neutral-000 font-mono"
}
>
{theme}
</p>
Expand Down Expand Up @@ -208,7 +209,7 @@ export const StaticAndFullyOpen = {
docs: {
description: {
story:
"Setting `fullyOpen` on options will set all sections to be open by default. This is useful for static themes (usable with the `static` and `darkStatic` theme values).",
"Setting `fullyOpen` on options will set all sections to be open by default. This is useful for static themes (usable with the `static` theme).",
},
},
},
Expand Down
23 changes: 8 additions & 15 deletions src/core/Accordion/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ReactNode } from "react";
import { IconName, IconSize } from "../Icon/types";
import { ColorClass } from "../styles/colors/types";
import { ColorThemeSet } from "../styles/colors/types";

/**
* Represents the data structure for an Accordion component.
Expand Down Expand Up @@ -39,14 +39,7 @@ export type AccordionIcons = {
};
};

export const accordionThemes = [
"dark",
"light",
"transparent",
"darkTransparent",
"static",
"darkStatic",
] as const;
export const accordionThemes = ["default", "transparent", "static"] as const;

export type AccordionTheme = (typeof accordionThemes)[number];

Expand All @@ -57,32 +50,32 @@ export type AccordionThemeColors = {
/**
* Background color class for the accordion.
*/
bg: ColorClass;
bg: ColorThemeSet;

/**
* Background color when the accordion item is hovered.
*/
hoverBg: string;
hoverBg: ColorThemeSet;

/**
* Text color class for the accordion.
*/
text: ColorClass;
text: ColorThemeSet;

/**
* Color class for the toggle icon of the accordion.
*/
toggleIconColor: ColorClass;
toggleIconColor: ColorThemeSet;

/**
* Optional background color class for selectable accordion items.
*/
selectableBg?: ColorClass;
selectableBg?: ColorThemeSet;

/**
* Optional text color class for selectable accordion items.
*/
selectableText?: ColorClass;
selectableText?: ColorThemeSet;

/**
* Optional border color for the accordion.
Expand Down
65 changes: 21 additions & 44 deletions src/core/Accordion/utils.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,33 @@
import { AccordionTheme, AccordionThemeColors } from "./types";

export const themeClasses: Record<AccordionTheme, AccordionThemeColors> = {
dark: {
bg: "bg-neutral-1200",
hoverBg: "hover:bg-neutral-1100",
text: "text-white",
toggleIconColor: "text-orange-600",
selectableBg: "bg-neutral-300",
selectableText: "text-neutral-1300",
},
light: {
bg: "bg-neutral-200",
hoverBg: "hover:bg-neutral-300",
text: "text-neutral-1300",
toggleIconColor: "text-neutral-1000",
selectableBg: "bg-neutral-1200",
selectableText: "text-white",
default: {
bg: "bg-neutral-200 dark:bg-neutral-1100",
hoverBg: "hover:bg-neutral-300 dark:hover:bg-neutral-1100",
text: "text-neutral-1300 dark:text-white",
toggleIconColor: "text-neutral-1000 dark:text-orange-600",
selectableBg: "bg-neutral-1200 dark:bg-neutral-300",
selectableText: "text-neutral-000 dark:text-neutral-1300",
},
transparent: {
bg: "bg-transparent",
hoverBg: "hover:bg-transparent",
text: "text-neutral-1000",
toggleIconColor: "text-dark-grey",
border: "border-neutral-500 border-b last:border-none",
},
darkTransparent: {
bg: "bg-transparent",
hoverBg: "hover:bg-transparent",
text: "text-neutral-000",
toggleIconColor: "text-orange-600",
border: "border-neutral-900 border-b last:border-none",
bg: "bg-transparent dark:bg-transparent",
hoverBg: "hover:bg-transparent dark:hover:bg-transparent",
text: "text-neutral-1000 dark:text-neutral-000",
toggleIconColor: "text-dark-grey dark:text-orange-600",
border:
"border-neutral-500 border-b last:border-none dark:border-neutral-900",
},
static: {
bg: "bg-neutral-200",
hoverBg: "hover:bg-neutral-200",
text: "text-neutral-1300",
toggleIconColor: "text-neutral-200",
selectableBg: "bg-neutral-1200",
selectableText: "text-white",
},
darkStatic: {
bg: "bg-neutral-1200",
hoverBg: "hover:bg-neutral-1200",
text: "text-white",
toggleIconColor: "text-neutral-1200",
selectableBg: "bg-neutral-1200",
selectableText: "text-neutral-1300",
bg: "bg-neutral-200 dark:bg-neutral-1200",
hoverBg: "hover:bg-neutral-200 dark:hover:bg-neutral-1200",
text: "text-neutral-1300 dark:text-white",
toggleIconColor: "text-neutral-200 dark:text-neutral-1200",
selectableBg: "bg-neutral-1200 dark:bg-neutral-1200",
selectableText: "text-white dark:text-neutral-1300",
},
};

export const isNonTransparentTheme = (theme: AccordionTheme) =>
!["transparent", "darkTransparent"].includes(theme);
theme !== "transparent";

export const isStaticTheme = (theme: AccordionTheme) =>
["static", "darkStatic"].includes(theme);
export const isStaticTheme = (theme: AccordionTheme) => theme === "static";
25 changes: 20 additions & 5 deletions src/core/FeaturedLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { CSSProperties, ReactNode } from "react";

import Icon from "./Icon";
import { ColorClass, ColorThemeSet } from "./styles/colors/types";
import cn from "./utils/cn";

type FeaturedLinkProps = {
url: string;
Expand Down Expand Up @@ -54,9 +55,17 @@ const FeaturedLink = ({
return (
<a
{...(onClick ? {} : { href: url })}
className={`font-sans font-bold block ${disabled ? "text-gui-unavailable pointer-events-none" : "text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus"} group/featured-link ui-${textSize} ${
flush ? "" : "py-8"
} ${additionalCSS}`}
className={cn(
"font-sans font-bold block group/featured-link",
{ "text-gui-unavailable pointer-events-none": disabled },
{
"text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus":
!disabled,
},
{ "py-8": !flush },
`ui-${textSize}`,
additionalCSS,
)}
style={
{
"--featured-link-icon-size": `var(${textSize.replace(
Expand All @@ -74,7 +83,10 @@ const FeaturedLink = ({
name="icon-gui-link-arrow"
size={`calc(var(--featured-link-icon-size) * 1.25)`}
color={iconColor}
additionalCSS={`align-middle mr-8 relative -top-1 -right-4 transition-[right] ${disabled ? "" : "group-hover/featured-link:right-0"} transform rotate-180`}
additionalCSS={cn(
"align-middle mr-8 relative -top-1 -right-4 transition-[right] transform rotate-180",
{ "group-hover/featured-link:right-0": !disabled },
)}
/>
{children}
</>
Expand All @@ -85,7 +97,10 @@ const FeaturedLink = ({
name="icon-gui-link-arrow"
size={`calc(var(--featured-link-icon-size) * 1.25)`}
color={iconColor}
additionalCSS={`align-middle ml-8 relative -top-1 -left-4 transition-[left] ${disabled ? "" : "group-hover/featured-link:left-0"}`}
additionalCSS={cn(
"align-middle ml-8 relative -top-1 -left-4 transition-[left]",
{ "group-hover/featured-link:left-0": !disabled },
)}
/>
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

exports[`Components/Featured Link Default smoke-test 1`] = `
<a href="#"
class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group/featured-link ui-text-p2 py-8 "
class="font-sans font-bold block group/featured-link text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus py-8 ui-text-p2"
style="--featured-link-icon-size: var(--fs-p2);"
>
Featured link
Expand All @@ -17,7 +17,7 @@ exports[`Components/Featured Link Default smoke-test 1`] = `
exports[`Components/Featured Link Disabled smoke-test 1`] = `
<a href="#"
class="font-sans font-bold block text-gui-unavailable pointer-events-none group/featured-link ui-text-p2 py-8 "
class="font-sans font-bold block group/featured-link text-gui-unavailable pointer-events-none py-8 ui-text-p2"
style="--featured-link-icon-size: var(--fs-p2);"
>
Featured link
Expand All @@ -32,7 +32,7 @@ exports[`Components/Featured Link Disabled smoke-test 1`] = `
exports[`Components/Featured Link Large smoke-test 1`] = `
<a href="#"
class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group/featured-link ui-text-p1 py-8 "
class="font-sans font-bold block group/featured-link text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus py-8 ui-text-p1"
style="--featured-link-icon-size: var(--fs-p1);"
>
Featured link
Expand All @@ -47,7 +47,7 @@ exports[`Components/Featured Link Large smoke-test 1`] = `
exports[`Components/Featured Link Pink smoke-test 1`] = `
<a href="#"
class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group/featured-link ui-text-p2 py-8 text-pink-800"
class="font-sans font-bold block group/featured-link hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus py-8 ui-text-p2 text-pink-800"
style="--featured-link-icon-size: var(--fs-p2);"
>
Featured link
Expand All @@ -62,10 +62,10 @@ exports[`Components/Featured Link Pink smoke-test 1`] = `
exports[`Components/Featured Link Reverse smoke-test 1`] = `
<a href="#"
class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group/featured-link ui-text-p2 py-8 "
class="font-sans font-bold block group/featured-link text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus py-8 ui-text-p2"
style="--featured-link-icon-size: var(--fs-p2);"
>
<svg class="align-middle mr-8 relative -top-1 -right-4 transition-[right] group-hover/featured-link:right-0 transform rotate-180"
<svg class="align-middle mr-8 relative -top-1 -right-4 transition-[right] transform rotate-180 group-hover/featured-link:right-0"
style="width: calc(var(--featured-link-icon-size) * 1.25); height: calc(var(--featured-link-icon-size) * 1.25);"
>
<use xlink:href="#sprite-icon-gui-link-arrow">
Expand All @@ -77,7 +77,7 @@ exports[`Components/Featured Link Reverse smoke-test 1`] = `
exports[`Components/Featured Link Small smoke-test 1`] = `
<a href="#"
class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group/featured-link ui-text-p3 py-8 "
class="font-sans font-bold block group/featured-link text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus py-8 ui-text-p3"
style="--featured-link-icon-size: var(--fs-p3);"
>
Featured link
Expand Down
2 changes: 1 addition & 1 deletion src/core/MeganavItemsMobile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const MeganavItemsMobile = ({
/>
<button
type="button"
className="absolute top-12 right-16 p-0 focus:outline-gui-focus m-0 md:hidden invisible"
className="absolute top-12 right-16 p-0 focus:outline-none focus-visible:outline-gui-focus m-0 md:hidden invisible"
data-id="meganav-search-input-clear"
>
<Icon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ exports[`Components/Product Tile SelectedProductTiles smoke-test 1`] = `
Low-level APIs to build any realtime experience
</p>
<a href="/docs/products/channels"
class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group/featured-link ui-text-p2 py-8 ui-btn-secondary bg-transparent hover:bg-transparent w-full hover:text-neutral-1300 mt-8 text-center inline-block text-neutral-000 dark:text-neutral-1300"
class="font-sans font-bold group/featured-link focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus py-8 ui-text-p2 ui-btn-secondary bg-transparent hover:bg-transparent w-full hover:text-neutral-1300 mt-8 text-center inline-block text-neutral-000 dark:text-neutral-1300"
style="--featured-link-icon-size: var(--fs-p2);"
>
View docs
Expand Down Expand Up @@ -303,7 +303,7 @@ exports[`Components/Product Tile SelectedProductTiles smoke-test 1`] = `
Create collaborative environments in a few lines of code
</p>
<a href="/docs/products/spaces"
class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group/featured-link ui-text-p2 py-8 ui-btn-secondary bg-transparent hover:bg-transparent w-full hover:text-neutral-1300 mt-8 text-center inline-block text-neutral-000 dark:text-neutral-1300"
class="font-sans font-bold group/featured-link focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus py-8 ui-text-p2 ui-btn-secondary bg-transparent hover:bg-transparent w-full hover:text-neutral-1300 mt-8 text-center inline-block text-neutral-000 dark:text-neutral-1300"
style="--featured-link-icon-size: var(--fs-p2);"
>
Explore
Expand Down Expand Up @@ -373,7 +373,7 @@ exports[`Components/Product Tile SelectedProductTiles smoke-test 1`] = `
Simple APIs to build realtime tracking applications
</p>
<a href="/docs/products/asset-tracking"
class="font-sans font-bold block text-gui-default hover:text-gui-hover focus:text-gui-focus focus:outline-gui-focus group/featured-link ui-text-p2 py-8 ui-btn-secondary bg-transparent hover:bg-transparent w-full hover:text-neutral-1300 mt-8 text-center inline-block text-neutral-000 dark:text-neutral-1300"
class="font-sans font-bold group/featured-link focus:text-gui-focus focus:outline-none focus-visible:outline-gui-focus py-8 ui-text-p2 ui-btn-secondary bg-transparent hover:bg-transparent w-full hover:text-neutral-1300 mt-8 text-center inline-block text-neutral-000 dark:text-neutral-1300"
style="--featured-link-icon-size: var(--fs-p2);"
>
Explore
Expand Down
2 changes: 1 addition & 1 deletion src/core/TabMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const TabMenu: React.FC<TabMenuProps> = ({
<Tabs.Trigger
key={`tab-${index}`}
className={cn(
"lg:px-24 md:px-20 px-16 py-16 ui-text-menu1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-unavailable dark:disabled:text-gui-unavailable-dark disabled:cursor-not-allowed",
"lg:px-24 md:px-20 px-16 py-16 ui-text-menu1 font-bold data-[state=active]:text-neutral-1300 text-neutral-1000 dark:data-[state=active]:text-neutral-000 dark:text-neutral-300 focus:outline-none focus-visible:outline-gui-focus transition-colors hover:text-neutral-1300 dark:hover:text-neutral-000 active:text-neutral-900 dark:active:text-neutral-400 disabled:text-gui-unavailable dark:disabled:text-gui-unavailable-dark disabled:cursor-not-allowed",
{ "flex-1": flexibleTabWidth },
{ "h-full": flexibleTabHeight },
tabClassName,
Expand Down
2 changes: 1 addition & 1 deletion src/core/Toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const Toggle: React.FC<ToggleProps> = ({ id, label, className, ...props }) => {
<div className="flex items-center">
<Switch.Root
className={cn(
"p-0 h-32 w-[56px] bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-unavailable data-[disabled]:cursor-not-allowed data-[state=checked]:bg-orange-600 focus:outline-gui-focus",
"p-0 h-32 w-[56px] bg-neutral-600 rounded-full relative inline-block transition-colors data-[disabled]:bg-gui-unavailable data-[disabled]:cursor-not-allowed data-[state=checked]:bg-orange-600 focus:outline-none focus-visible:outline-offset-0 focus-visible:outline-4 focus-visible:outline-gui-focus",
className,
)}
id={id}
Expand Down
Loading

0 comments on commit a0ad31e

Please sign in to comment.