`4px solid ${t?.colors?.accent}`,
+ },
+ ':hover': {
+ backgroundColor: 'shadow',
+ },
+ },
}}
onClick={() => responsive && setCollapsed(true)}
>
diff --git a/ui/app-components/src/SkipLinks/SkipLinks.tsx b/ui/app-components/src/SkipLinks/SkipLinks.tsx
new file mode 100644
index 000000000..cc542398b
--- /dev/null
+++ b/ui/app-components/src/SkipLinks/SkipLinks.tsx
@@ -0,0 +1,73 @@
+/** @jsx jsx */
+import { FC } from 'react';
+import { jsx, Flex, LinkProps, SxStyleProp, Theme } from 'theme-ui';
+
+const skipNavStyles: SxStyleProp = {
+ border: (t: Theme) => `1px solid ${t.colors?.primary}`,
+ clip: `react(0 0 0 0)`,
+ width: '0.01em',
+ height: '0.01em',
+ whiteSpace: 'nowrap',
+ padding: 0,
+ overflow: `hidden`,
+ position: `absolute`,
+ flexDirection: 'column',
+ '&:focus-within': {
+ padding: 3,
+ position: `fixed`,
+ top: `50px`,
+ left: `15px`,
+ backgroundColor: `background`,
+ zIndex: 15,
+ width: `auto`,
+ height: `auto`,
+ clip: `auto`,
+ textDecoration: `none`,
+ },
+};
+export interface SkiLinksItemOwnProps {
+ /**
+ * target's id property, without the # char
+ */
+ target: string;
+ /**
+ * text message to be displayed
+ */
+ text: string;
+}
+
+export type SkiLinksItemProps = SkiLinksItemOwnProps & LinkProps;
+
+/**
+ * single skip link anchor item
+ */
+export const SkiLinksItem: FC
= ({
+ target,
+ text,
+ ...rest
+}) => (
+
+ {text}
+
+);
+
+export interface SkipLinksProps {
+ items: SkiLinksItemProps[];
+}
+
+/**
+ * list of anchor elements to skip to
+ *
+ */
+
+export const SkipLinks: FC = ({ items }) => (
+
+ {items.map((item, idx) => (
+
+ ))}
+
+);
diff --git a/ui/app-components/src/SkipLinks/index.ts b/ui/app-components/src/SkipLinks/index.ts
new file mode 100644
index 000000000..02ab199e1
--- /dev/null
+++ b/ui/app-components/src/SkipLinks/index.ts
@@ -0,0 +1 @@
+export * from './SkipLinks';
diff --git a/ui/app-components/src/index.ts b/ui/app-components/src/index.ts
index 8077e31b0..1e895c9e7 100644
--- a/ui/app-components/src/index.ts
+++ b/ui/app-components/src/index.ts
@@ -4,3 +4,4 @@ export * from './Keyboard';
export * from './Link';
export * from './Navmenu';
export * from './Sidebar';
+export * from './SkipLinks';
diff --git a/ui/app/src/App/App.tsx b/ui/app/src/App/App.tsx
new file mode 100644
index 000000000..13442babc
--- /dev/null
+++ b/ui/app/src/App/App.tsx
@@ -0,0 +1,53 @@
+/** @jsx jsx */
+import { FC, Fragment } from 'react';
+import { jsx, Flex } from 'theme-ui';
+import {
+ SkipLinks,
+ SkiLinksItemProps,
+} from '@component-controls/app-components';
+import { useStoryContext } from '@component-controls/blocks';
+import { SEO } from '../SEO';
+import { Header } from '../Header';
+import { Page, PagesConfig } from '../Page';
+import { Footer } from '../Footer';
+
+export interface AppProps {
+ title?: string;
+ pagesFn: PagesConfig;
+}
+export const App: FC = ({ title, pagesFn }) => {
+ const { doc } = useStoryContext({ id: '.' });
+ const items: SkiLinksItemProps[] = [
+ {
+ target: 'content',
+ text: 'skip to main content',
+ },
+ ];
+ if (!doc || !doc.fullPage) {
+ items.push({
+ target: 'sidebar',
+ text: 'skip to navigation sidebar',
+ });
+ items.push({
+ target: 'contextbar',
+ text: 'skip to context sidebar',
+ });
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/ui/app/src/App/index.ts b/ui/app/src/App/index.ts
new file mode 100644
index 000000000..ac7ba3b3a
--- /dev/null
+++ b/ui/app/src/App/index.ts
@@ -0,0 +1 @@
+export * from './App';
diff --git a/integrations/gatsby-theme-stories/src/components/Footer.tsx b/ui/app/src/Footer/Footer.tsx
similarity index 58%
rename from integrations/gatsby-theme-stories/src/components/Footer.tsx
rename to ui/app/src/Footer/Footer.tsx
index 7c6e83120..d2ca569bb 100644
--- a/integrations/gatsby-theme-stories/src/components/Footer.tsx
+++ b/ui/app/src/Footer/Footer.tsx
@@ -1,7 +1,13 @@
/** @jsx jsx */
+import { FC, useContext } from 'react';
import { Text, Flex, Link, jsx } from 'theme-ui';
+import { BlockContext } from '@component-controls/blocks';
+
+export const Footer: FC = () => {
+ const { storeProvider } = useContext(BlockContext);
+ const config = storeProvider.config;
+ const { author, siteUrl, siteDescription } = config?.options || {};
-export const Footer = () => {
return (
{
a: { color: `text` },
}}
>
-
- component controls
+
+ {author}
diff --git a/ui/app/src/Footer/index.ts b/ui/app/src/Footer/index.ts
new file mode 100644
index 000000000..ddcc5a9cd
--- /dev/null
+++ b/ui/app/src/Footer/index.ts
@@ -0,0 +1 @@
+export * from './Footer';
diff --git a/ui/app/src/Page/Page.tsx b/ui/app/src/Page/Page.tsx
index a25368973..6144d7519 100644
--- a/ui/app/src/Page/Page.tsx
+++ b/ui/app/src/Page/Page.tsx
@@ -1,10 +1,12 @@
/** @jsx jsx */
-import { FC, ReactNode, Fragment, useRef } from 'react';
-import { jsx, Container } from 'theme-ui';
+import { FC, ReactNode, useRef } from 'react';
+import { jsx, Container, Flex } from 'theme-ui';
import * as qs from 'qs';
import { Tabs, Tab, TabList, TabPanel } from '@component-controls/components';
import { PageContainer, useStoryContext } from '@component-controls/blocks';
+
import { SideContext } from '../SideContext';
+import { Sidebar } from '../Sidebar';
export interface PageConfig {
key: string;
title: string;
@@ -28,8 +30,9 @@ export const BasePage: FC = ({ pagesFn }) => {
0,
);
return (
-
-
+
+
+
= ({ pagesFn }) => {
-
+
);
};
export const Page: FC = props => {
const { doc } = useStoryContext({ id: '.' });
if (doc && doc.fullPage && doc.MDXPage) {
- return ;
+ return ;
}
return ;
};
diff --git a/ui/app/src/SideContext/SideContext.tsx b/ui/app/src/SideContext/SideContext.tsx
index 66469170e..4ef48dce9 100644
--- a/ui/app/src/SideContext/SideContext.tsx
+++ b/ui/app/src/SideContext/SideContext.tsx
@@ -61,7 +61,7 @@ export const SideContext: FC = ({ pageRef }) => {
{({ SidebarClose, SidebarToggle, collapsed, responsive }) => (
-
+
{responsive && (
@@ -76,6 +76,9 @@ export const SideContext: FC = ({ pageRef }) => {
{items?.map((el, index) => (
= ({
- docPath,
- title: propsTitle,
-}) => {
+export const SidebarBase: FC = ({ title: propsTitle }) => {
const { doc } = useStoryContext({ id: '.' });
if (doc && doc.fullPage) {
return null;
@@ -96,6 +89,7 @@ export const SidebarBase: FC = ({
borderRight: (t: Theme) => `1px solid ${t.colors?.shadow}`,
}}
width={300}
+ id="sidebar"
>
{responsive && (
@@ -114,7 +108,7 @@ export const SidebarBase: FC = ({
/>
diff --git a/ui/app/src/index.ts b/ui/app/src/index.ts
index f61495b35..ee0490163 100644
--- a/ui/app/src/index.ts
+++ b/ui/app/src/index.ts
@@ -1,3 +1,5 @@
+export * from './App';
+export * from './Footer';
export * from './Header';
export * from './Page';
export * from './SEO';
diff --git a/ui/blocks/src/PageContainer/PageContainer.tsx b/ui/blocks/src/PageContainer/PageContainer.tsx
index 0649b0fcb..f26e9f8fe 100644
--- a/ui/blocks/src/PageContainer/PageContainer.tsx
+++ b/ui/blocks/src/PageContainer/PageContainer.tsx
@@ -1,7 +1,7 @@
/* eslint-disable react/display-name */
/** @jsx jsx */
import { FC, useEffect, forwardRef } from 'react';
-import { jsx, Box } from 'theme-ui';
+import { jsx, Box, BoxProps } from 'theme-ui';
import { MDXProvider, MDXProviderComponents } from '@mdx-js/react';
import { markdownComponents } from '@component-controls/components';
@@ -34,9 +34,9 @@ export interface PageContainerProps {
* If the page is an MDX page, will display the MDX components.
* Otherwise, the page elements are passed as children
*/
-export const PageContainer: FC = forwardRef(
+export const PageContainer: FC = forwardRef(
(
- { children, components = {}, maxWidth, padding = 4 },
+ { children, components = {}, maxWidth, padding = 4, ...rest },
ref: React.Ref,
) => {
useEffect(() => {
@@ -75,6 +75,7 @@ export const PageContainer: FC = forwardRef(
fontFamily: 'body',
width: '100%',
}}
+ {...rest}
>
= ({
{title}
);
- //workaround for storybook iframe url
- const url =
- (typeof window !== 'undefined' && window.location !== window.parent.location
- ? document.referrer
- : typeof document !== 'undefined' && document.location.href) || '';
return (
= ({
visibility: 'visible',
},
}}
- href={`${url.split('#')[0]}#${blockId}`}
+ href={pageLink(blockId)}
data-title={title}
>
diff --git a/ui/components/src/BlockContainer/index.ts b/ui/components/src/BlockContainer/index.ts
index 6e13be755..0a1be860b 100644
--- a/ui/components/src/BlockContainer/index.ts
+++ b/ui/components/src/BlockContainer/index.ts
@@ -1 +1,2 @@
export * from './BlockContainer';
+export * from './pageLink';
diff --git a/ui/components/src/BlockContainer/pageLink.ts b/ui/components/src/BlockContainer/pageLink.ts
new file mode 100644
index 000000000..bc92b09bc
--- /dev/null
+++ b/ui/components/src/BlockContainer/pageLink.ts
@@ -0,0 +1,7 @@
+export const pageLink = (id: string) => {
+ const url =
+ (typeof window !== 'undefined' && window.location !== window.parent.location
+ ? document.referrer
+ : typeof document !== 'undefined' && document.location.href) || '';
+ return `${url.split('#')[0]}#${id}`;
+};