Skip to content

Commit 32bc1f7

Browse files
committed
refactor(docs): localise presentational components (Badge/Button/LinkButton/FeaturedLink/Status) (DX-1128)
Vendor Badge, Button, LinkButton, FeaturedLink and Status locally, off @ably/ui/core. Their icon props (leftIcon/rightIcon, iconBefore/iconAfter) now take a ReactNode rather than an icon name string: callers pass a Heroicon component or an Ably glyph <Icon> directly, and the component sizes it via a slot. This drops the name->component indirection so Heroicons tree-shake, and matches the glyphs-only local Icon. Also fixes a 'noopenner' rel typo in FeaturedLink and points Footer's (feature-flagged) feedback icons at Heroicons.
1 parent 6803b67 commit 32bc1f7

22 files changed

Lines changed: 870 additions & 40 deletions

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
"react-medium-image-zoom": "^5.4.1",
9999
"react-select": "^5.7.0",
100100
"remark-gfm": "^1.0.0",
101+
"swr": "^2.4.0",
101102
"tailwind-merge": "^2.5.5",
102103
"typescript": "^4.6.3",
103104
"use-keyboard-shortcut": "^1.1.6",

src/components/Examples/ExamplesFilter.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ import React, { ChangeEvent, Dispatch, SetStateAction, useCallback, useEffect, u
22
import ReactDOM from 'react-dom';
33
import { Input } from 'src/components/ui/Input';
44
import { products } from '../../data/examples';
5-
import Button from '@ably/ui/core/Button';
5+
import Button from 'src/components/ui/Button';
66
import cn from 'src/utilities/cn';
7-
import Badge from '@ably/ui/core/Badge';
7+
import Badge from 'src/components/ui/Badge';
88
import ExamplesCheckbox from './ExamplesCheckbox';
99
import { SelectedFilters } from './ExamplesContent';
1010
import { useOnClickOutside } from 'src/hooks/use-on-click-outside';
1111
import { navigate } from 'gatsby';
1212
import { ProductName } from '@ably/ui/core/ProductTile/data';
13-
import { MagnifyingGlassIcon, XMarkIcon } from '@heroicons/react/24/outline';
13+
import { AdjustmentsHorizontalIcon, MagnifyingGlassIcon, XMarkIcon } from '@heroicons/react/24/outline';
1414

1515
const ExamplesFilter = ({
1616
selected,
@@ -130,7 +130,7 @@ const ExamplesFilter = ({
130130
<Button
131131
className="flex sm:hidden mt-4 w-full"
132132
variant="secondary"
133-
leftIcon="icon-gui-adjustments-horizontal-outline"
133+
leftIcon={<AdjustmentsHorizontalIcon aria-hidden />}
134134
onClick={() => setExpandFilterMenu(true)}
135135
>
136136
Filter

src/components/Examples/ExamplesGrid.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useCallback } from 'react';
2-
import Badge from '@ably/ui/core/Badge';
2+
import Badge from 'src/components/ui/Badge';
33
import Icon from 'src/components/Icon';
44
import { IconName } from 'src/components/Icon/types';
55
import { ProductName, products as dataProducts } from '@ably/ui/core/ProductTile/data';

src/components/Examples/ExamplesNoResults.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Badge from '@ably/ui/core/Badge';
1+
import Badge from 'src/components/ui/Badge';
22
import { Link } from 'gatsby';
33

44
const ExamplesNoResults = () => {

src/components/Homepage/Changelog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { useStaticQuery } from 'gatsby';
22
import { graphql } from 'gatsby';
33
import { Key } from 'react';
4-
import Badge from '@ably/ui/core/Badge';
5-
import FeaturedLink from '@ably/ui/core/FeaturedLink';
4+
import Badge from 'src/components/ui/Badge';
5+
import FeaturedLink from 'src/components/ui/FeaturedLink';
66
import Link from '../Link';
77

88
interface ChangelogFeedItemNode {

src/components/Homepage/ExamplesSection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ExamplesSectionData } from 'src/data/content/types';
22
import { getImageFromList, ImageProps } from 'src/components/Image';
33
import { Image } from 'src/components/Image';
4-
import FeaturedLink from '@ably/ui/core/FeaturedLink';
4+
import FeaturedLink from 'src/components/ui/FeaturedLink';
55

66
export const ExamplesSection = ({ section, images }: { section: ExamplesSectionData; images: ImageProps[] }) => {
77
const imageUrl = getImageFromList(images, section.image);

src/components/Icon/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
// Permissive on purpose: covers the static glyph names and the dynamic
22
// `icon-tech-${language}` usages without enumerating every glyph.
33
export type IconName = `icon-${string}`;
4+
5+
export type IconSize = `${number}px` | `${number}em` | `${number}rem` | `calc(${string})`;

src/components/Layout/Footer.tsx

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
1-
import React, { useEffect, useMemo, useState } from 'react';
1+
import React, { ComponentType, SVGProps, useEffect, useMemo, useState } from 'react';
22
import { useLocation } from '@reach/router';
33
import Icon from 'src/components/Icon';
44
import { IconName } from 'src/components/Icon/types';
5-
import Status, { StatusUrl } from '@ably/ui/core/Status';
5+
import Status, { StatusUrl } from 'src/components/ui/Status';
66
import cn from 'src/utilities/cn';
77
import type { PageContextType } from './Layout';
88
import { useLayoutContext } from 'src/contexts/layout-context';
9-
import Button from '@ably/ui/core/Button';
9+
import Button from 'src/components/ui/Button';
10+
import { HandRaisedIcon, HandThumbDownIcon, HandThumbUpIcon } from '@heroicons/react/24/outline';
11+
import {
12+
HandRaisedIcon as HandRaisedSolidIcon,
13+
HandThumbDownIcon as HandThumbDownSolidIcon,
14+
HandThumbUpIcon as HandThumbUpSolidIcon,
15+
} from '@heroicons/react/24/solid';
1016

1117
const ENABLE_FEEDBACK = false;
1218

1319
type FeedbackMode = 'yes' | 'no' | 'feedback';
1420

1521
type FeedbackButton = {
1622
label: string;
17-
monoIcon: IconName;
18-
colorIcon: IconName;
23+
monoIcon: ComponentType<SVGProps<SVGSVGElement>>;
24+
colorIcon: ComponentType<SVGProps<SVGSVGElement>>;
1925
placeholder: string;
2026
description?: string;
2127
};
@@ -65,22 +71,22 @@ const socialLinks: { key: string; icon: IconName; link: string }[] = [
6571
const feedbackButtons: Record<FeedbackMode, FeedbackButton> = {
6672
yes: {
6773
label: 'Yes',
68-
monoIcon: 'icon-gui-hand-thumb-up-outline',
69-
colorIcon: 'icon-gui-hand-thumb-up-solid',
74+
monoIcon: HandThumbUpIcon,
75+
colorIcon: HandThumbUpSolidIcon,
7076
description: 'Great! Thanks for letting us know, what are we doing well?',
7177
placeholder: 'Optional feedback.',
7278
},
7379
no: {
7480
label: 'No',
75-
monoIcon: 'icon-gui-hand-thumb-down-outline',
76-
colorIcon: 'icon-gui-hand-thumb-down-solid',
81+
monoIcon: HandThumbDownIcon,
82+
colorIcon: HandThumbDownSolidIcon,
7783
description: 'Yikes! Thanks for letting us know, what can we do better?',
7884
placeholder: 'Optional feedback.',
7985
},
8086
feedback: {
8187
label: 'I have feedback',
82-
monoIcon: 'icon-gui-hand-raised-outline',
83-
colorIcon: 'icon-gui-hand-raised-solid',
88+
monoIcon: HandRaisedIcon,
89+
colorIcon: HandRaisedSolidIcon,
8490
placeholder: 'What would you like to say?',
8591
},
8692
};
@@ -189,6 +195,8 @@ const Footer: React.FC<{ pageContext: PageContextType }> = ({ pageContext }) =>
189195
<div className="flex items-center gap-6">
190196
{Object.entries(feedbackButtons).map(([key, button]) => {
191197
const isActive = feedbackMode === key;
198+
const ColorIcon = button.colorIcon;
199+
const MonoIcon = button.monoIcon;
192200

193201
return (
194202
<button
@@ -198,22 +206,19 @@ const Footer: React.FC<{ pageContext: PageContextType }> = ({ pageContext }) =>
198206
setFeedbackMode(key as FeedbackMode);
199207
}}
200208
>
201-
<Icon
202-
name={button.colorIcon}
203-
size="20px"
204-
additionalCSS="transition-colors"
205-
color={
209+
<ColorIcon
210+
aria-hidden
211+
className={cn(
212+
'size-5 transition-colors',
206213
isActive
207214
? 'text-orange-600'
208-
: 'hidden group-hover/feedback-button:block text-neutral-1300 dark:text-neutral-000'
209-
}
215+
: 'hidden group-hover/feedback-button:block text-neutral-1300 dark:text-neutral-000',
216+
)}
210217
/>
211218
{!isActive && (
212-
<Icon
213-
name={button.monoIcon}
214-
size="20px"
215-
additionalCSS="transition-colors"
216-
color="text-neutral-900 dark:text-neutral-400 group-hover/feedback-button:hidden"
219+
<MonoIcon
220+
aria-hidden
221+
className="size-5 transition-colors text-neutral-900 dark:text-neutral-400 group-hover/feedback-button:hidden"
217222
/>
218223
)}
219224
<span

src/components/Layout/Header.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jest.mock('src/components/Icon', () => {
2323
return MockIcon;
2424
});
2525

26-
jest.mock('@ably/ui/core/LinkButton', () => {
26+
jest.mock('src/components/ui/LinkButton', () => {
2727
const MockButton: React.FC<{ children: React.ReactNode }> = ({ children }) => <button>{children}</button>;
2828
MockButton.displayName = 'MockButton';
2929
return MockButton;

src/components/Layout/Header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { throttle } from 'es-toolkit/compat';
77
import cn from 'src/utilities/cn';
88
import Icon from 'src/components/Icon';
99
import TabMenu from '@ably/ui/core/TabMenu';
10-
import Logo from '@ably/ui/core/images/logo/ably-logo.svg';
10+
import Logo from 'src/images/ably-logo.svg';
1111
import { track } from '@ably/ui/core/insights';
1212
import { componentMaxHeight, HEADER_BOTTOM_MARGIN, HEADER_HEIGHT } from 'src/utilities/heights';
1313
import LeftSidebar from './LeftSidebar';

0 commit comments

Comments
 (0)