Skip to content

Commit

Permalink
Merge pull request #648 from WestpacGEL/620-design-system-docs-respon…
Browse files Browse the repository at this point in the history
…sive-demo-page

620 design system docs responsive demo page
  • Loading branch information
samithaf authored Jan 17, 2024
2 parents 02ea2a2 + 33062b0 commit fc1f940
Show file tree
Hide file tree
Showing 20 changed files with 148 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function DesignContent({
...DOCUMENT_RENDERERS,
block: {
...DOCUMENT_RENDERERS.block,
code: props => <Code className="mb-5 mt-4" enableLiveCode={false} {...props} />,
code: props => <Code className="mb-5 mt-4" enableLiveCode={false} showResponsiveDemo {...props} />,
},
}}
componentBlocks={{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { ResponsiveModal } from './responsive-modal.component';
export { type ResponsiveModalProps } from './responsive-modal.types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use client';

import { Grid, GridItem, Modal } from '@westpac/ui';
import { DesktopIcon, GelIcon, PhoneIcon, TabletIcon } from '@westpac/ui/icon';

import { Container } from '@/app/design-system/components';

import { ResponsiveModalProps } from '.';

export function ResponsiveModal({ children, ...props }: ResponsiveModalProps) {
return (
<Modal isDismissable className="bg-light" {...props}>
<Modal.Body className="flex flex-1 flex-col">
<Container className="flex flex-1 flex-col pt-5">
<div className="flex justify-between">
<h2 className="typography-body-7 font-light sm:typography-body-6">Responsive Demo</h2>
<GelIcon color="primary" size="xlarge" />
</div>
<div className="relative mb-3 mt-4 flex justify-center">
<div className="absolute inset-x-0 top-2 flex h-4 w-full items-center justify-between before:h-full before:border-l before:border-l-text after:h-full after:border-l after:border-l-text">
<div className="flex-1 border-t border-t-text" />
</div>
<div className="z-10 flex gap-2 rounded border border-text bg-white px-3 py-2">
<PhoneIcon className="opacity-100 xsl:opacity-50" />
<TabletIcon className="opacity-50 xsl:opacity-100 md:opacity-50" />
<TabletIcon className="rotate-90 opacity-50 md:opacity-100 lg:opacity-50" />
<DesktopIcon className="opacity-50 lg:opacity-100" />
</div>
</div>
<div className="relative flex-1 overflow-auto">
<div className="relative z-10">{children}</div>
<div className="pointer-events-none absolute inset-0 touch-none">
<Grid className="absolute inset-0">
{new Array(12).fill(null).map((_, index) => (
<GridItem key={index} span={1} className="bg-text/5" />
))}
</Grid>
</div>
</div>
</Container>
</Modal.Body>
</Modal>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { ModalProps } from '@westpac/ui';

export type ResponsiveModalProps = ModalProps;
17 changes: 15 additions & 2 deletions apps/site/src/components/code/code.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,28 @@ const LIVE_SCOPE = {
React,
};

export function Code({ children, live, showCode, className, language = 'tsx', enableLiveCode = true }: CodeProps) {
export function Code({
children,
live,
showCode,
showResponsiveDemo = false,
className,
language = 'tsx',
enableLiveCode = true,
}: CodeProps) {
const childrenAsString = children?.toString().trim();

if (!childrenAsString) return null;

if (live) {
return (
<LiveProvider code={childrenAsString} scope={LIVE_SCOPE} language={language}>
<LiveCode showCode={showCode} className={className} enableLiveCode={enableLiveCode} />
<LiveCode
showCode={showCode}
showResponsiveDemo={showResponsiveDemo}
className={className}
enableLiveCode={enableLiveCode}
/>
</LiveProvider>
);
}
Expand Down
1 change: 1 addition & 0 deletions apps/site/src/components/code/code.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export type CodeProps = {
language?: string;
live?: boolean;
showCode?: boolean;
showResponsiveDemo?: boolean;
};
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import { AlertIcon, ArrowRightIcon } from '@westpac/ui/icon';
import { AlertIcon, ArrowRightIcon, NewWindowIcon } from '@westpac/ui/icon';
import copy from 'clipboard-copy';
import { themes } from 'prism-react-renderer';
import { KeyboardEvent, useCallback, useContext, useId, useRef, useState } from 'react';
import { LiveContext, LiveEditor, LivePreview } from 'react-live';
import { useOverlayTriggerState } from 'react-stately';
import { VariantProps } from 'tailwind-variants';

import { ResponsiveModal } from '@/app/design-system/[...component]/components/content-tabs/components/responsive-modal-button';

import { Button } from '../../code.inject-components';

import { styles as liveCodeStyles } from './live-code.styles';
import { LiveCodeProps } from './live-code.types';

export function LiveCode({ showCode = false, enableLiveCode = true, className }: LiveCodeProps) {
export function LiveCode({
showCode = false,
showResponsiveDemo = false,
enableLiveCode = true,
className,
}: LiveCodeProps) {
const liveCodeToggleButton = useRef<HTMLButtonElement>(null);
const live = useContext(LiveContext);

const liveOnChange = live.onChange;
const [localCopy, setLocalCopy] = useState<string>(live.code);
const [isCodeVisible, toggleIsCodeVisible] = useState(showCode);
const responsiveModalState = useOverlayTriggerState({});

const styles = liveCodeStyles({
showResponsiveDemo,
isCodeVisible,
language: live.language as VariantProps<typeof liveCodeStyles>['language'],
});
Expand Down Expand Up @@ -49,6 +61,19 @@ export function LiveCode({ showCode = false, enableLiveCode = true, className }:
return (
<div className={styles.base({ className })}>
<div className={styles.displayWrapper({})}>
{showResponsiveDemo && (
<Button
className="absolute right-2 top-2 z-10"
size="small"
soft
look="faint"
onClick={() => responsiveModalState.open()}
>
<div className="flex items-center gap-1">
<span>Demo</span> <NewWindowIcon size="xsmall" />
</div>
</Button>
)}
{live.error ? (
<div className={styles.error({})}>
<AlertIcon />
Expand Down Expand Up @@ -89,6 +114,9 @@ export function LiveCode({ showCode = false, enableLiveCode = true, className }:
/>
</div>
)}
<ResponsiveModal size="full" onClose={responsiveModalState.close} state={responsiveModalState}>
<LivePreview aria-label="Rendered code snippet example" />
</ResponsiveModal>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { tv } from 'tailwind-variants';
export const styles = tv({
slots: {
base: 'max-w-5xl bg-white p-6 pb-0',
displayWrapper: 'relative -mx-6 -mt-6 border-muted-50 p-6',
displayWrapper: 'relative -mx-6 -mt-6 border-muted-50 px-6',
error: 'flex gap-2 rounded-md bg-danger-10 p-2 text-danger-90',
buttonWrapper: '-mx-6 -mb-6 flex items-center justify-end ',
codeWrapper:
Expand All @@ -19,6 +19,14 @@ export const styles = tv({
displayWrapper: 'p-0',
},
},
showResponsiveDemo: {
true: {
displayWrapper: 'pb-6 pt-9',
},
false: {
displayWrapper: 'py-6',
},
},
isCodeVisible: {
true: {
codeWrapper: 'block',
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export type LiveCodeProps = { className?: string; enableLiveCode?: boolean; showCode?: boolean };
export type LiveCodeProps = {
className?: string;
enableLiveCode?: boolean;
showCode?: boolean;
showResponsiveDemo?: boolean;
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export type CodeProps = {
enableLiveCode?: boolean;
language?: string;
showCode?: boolean;
showResponsiveDemo?: boolean;
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { Overlay, useModalOverlay } from 'react-aria';
import { styles as backdropStyles } from './modal-backdrop.styles.js';
import { type ModalBackdropProps } from './modal-backdrop.types.js';

export function ModalBackdrop({ zIndex = 100, portalContainer, ...props }: ModalBackdropProps) {
export function ModalBackdrop({ zIndex = 100, portalContainer, size, ...props }: ModalBackdropProps) {
const { children, state, className } = props;

const ref = useRef(null);
const styles = backdropStyles({ className });
const styles = backdropStyles({ className, fullscreen: size === 'full' });

const { modalProps, underlayProps } = useModalOverlay(props, state, ref);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,12 @@ export const styles = tv({
base: 'fixed inset-0 z-50 flex animate-fadeIn justify-center overflow-y-auto bg-black/50 p-2',
modal: 'relative top-5 z-10 h-fit w-full animate-fadeInDown',
},
variants: {
fullscreen: {
true: {
modal: 'top-0 flex flex-1 flex-col',
base: 'flex flex-col p-0',
},
},
},
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { type AriaModalOverlayProps } from 'react-aria';
import { type OverlayTriggerState } from 'react-stately';

import { ModalDialogProps } from '../index.js';

export type ModalBackdropProps = {
/**
* Inner part of backdrop
Expand All @@ -14,6 +16,10 @@ export type ModalBackdropProps = {
* Element where backdrop will be placed
*/
portalContainer?: Element;
/**
* size
*/
size?: ModalDialogProps['size'];
/**
* OverlayTriggerState props
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { tv } from 'tailwind-variants';

export const styles = tv({
base: 'px-4 py-3',
base: 'flex-1 overflow-auto px-4 py-3',
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import { type ModalDialogProps } from './modal-dialog.types.js';
export function ModalDialog({ className, body, onClose, size = 'md', ...props }: ModalDialogProps) {
const { children } = props;
const { isFocusVisible, focusProps } = useFocusRing();
const styles = dialogStyles({ className, size, isFocusVisible });
const styles = dialogStyles({ size, isFocusVisible });

const ref = useRef(null);

const { dialogProps, titleProps } = useDialog(props, ref);

return (
<div {...dialogProps} ref={ref} className={styles.base()}>
<div {...dialogProps} ref={ref} className={styles.base({ className })}>
{onClose && (
<button className={styles.close()} onClick={onClose} aria-label="Close modal" {...focusProps}>
<CloseIcon className="block" size="small" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import { tv } from 'tailwind-variants';
export const styles = tv(
{
slots: {
base: 'relative mx-auto max-w-full overflow-hidden rounded bg-white outline-none',
base: 'relative mx-auto flex max-w-full flex-col overflow-hidden rounded bg-white outline-none',
title: 'border-b border-b-heading pb-2 pl-4 pr-5 pt-3 text-lg font-medium',
close: 'absolute right-1 top-1 block p-1',
},
variants: {
size: {
full: {
base: 'max-h-screen w-full flex-1',
},
lg: {
base: 'w-[56.25rem]',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export type ModalDialogProps = {
* Additional className for Dialog
*/
className?: string;
/**
* Full screen
*/
fullscreen?: boolean;
/**
* onClose callback
*/
Expand Down
6 changes: 4 additions & 2 deletions packages/ui/src/components/modal/modal.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import React from 'react';
import { ModalBackdrop, ModalDialog } from './components/index.js';
import { type ModalProps } from './modal.types.js';

export function Modal({ children, title, role, body, size, ...props }: ModalProps) {
export function Modal({ children, title, role, body, size, className, fullscreen, ...props }: ModalProps) {
return (
<ModalBackdrop {...props}>
<ModalBackdrop size={size} {...props}>
<ModalDialog
fullscreen={fullscreen}
onClose={props.isDismissable ? props.state.close : undefined}
title={title}
role={role}
body={body}
size={size}
className={className}
>
{children}
</ModalDialog>
Expand Down
6 changes: 4 additions & 2 deletions packages/ui/src/components/modal/modal.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,20 @@ export const Sizes: Story = {
const stateSM = useOverlayTriggerState({});
const stateMD = useOverlayTriggerState({});
const stateLG = useOverlayTriggerState({});
const stateFull = useOverlayTriggerState({});

const states = useMemo(() => {
return {
sm: stateSM,
md: stateMD,
lg: stateLG,
full: stateFull,
};
}, [stateSM, stateMD, stateLG]);
}, [stateSM, stateMD, stateLG, stateFull]);

return (
<div className="flex gap-2">
{(['sm', 'md', 'lg'] as const).map(size => (
{(['sm', 'md', 'lg', 'full'] as const).map(size => (
<Fragment key={size}>
<Modal {...props} size={size} state={states[size]} title={`Modal ${size}`}>
<Modal.Body>{children}</Modal.Body>
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/modal/modal.types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { type ModalBackdropProps, ModalDialogProps } from './components/index.js';

export type ModalProps = ModalBackdropProps & ModalDialogProps;
export type ModalProps = ModalBackdropProps & ModalDialogProps & { fullscreen?: boolean };

1 comment on commit fc1f940

@vercel
Copy link

@vercel vercel bot commented on fc1f940 Jan 17, 2024

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

gel-next-site – ./apps/site

gel-next-site.vercel.app
gel-next-site-git-main-westpacgel.vercel.app
gel-next-site-westpacgel.vercel.app

Please sign in to comment.