Skip to content

Commit

Permalink
feat(BrowserMockup): Add Browser mockup (#409)
Browse files Browse the repository at this point in the history
  • Loading branch information
yoshi6jp committed Aug 21, 2023
1 parent d0ad289 commit cb77fe7
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -203,6 +203,7 @@ Use tools like the official <a href="https://daisyui.com/theme-generator/">daisy
<details>
<summary>Mockup:</summary>

- [x] <a href="https://react.daisyui.com/?path=/story/mockup-browser">Browser</a>
- [x] <a href="https://react.daisyui.com/?path=/story/mockup-code">Code</a>
- [x] <a href="https://react.daisyui.com/?path=/story/mockup-phone">Phone</a>
- [x] <a href="https://react.daisyui.com/?path=/story/mockup-window">Window</a>
Expand Down
10 changes: 4 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions src/BrowserMockup/BrowserMockup.stories.tsx
@@ -0,0 +1,41 @@
import React from 'react'
import { StoryFn as Story, Meta } from '@storybook/react'

import BrowserMockup, { BrowserMockupProps } from '.'

export default {
title: 'Mockup/BrowserMockup',
component: BrowserMockup,
parameters: {
controls: { expanded: true },
},
args: {
url: 'https://react.daisyui.com',
className: 'w-full',
},
} as Meta

const Template: Story<BrowserMockupProps> = (args) => (
<BrowserMockup {...args}>Hello!</BrowserMockup>
)

export const Default = Template.bind({})
Default.args = {}

export const WithBackgroundColor = Template.bind({})
WithBackgroundColor.args = {
variant: 'background',
}

export const WithCustomBorderColor = Template.bind({})
WithCustomBorderColor.args = {
className: 'w-full border-primary',
inputClassName: 'border-primary',
}

export const WithCustomBackgroundColor = Template.bind({})
WithCustomBackgroundColor.args = {
variant: 'background',
className: 'bg-warning',
innerClassName: 'bg-info info-content',
}
50 changes: 50 additions & 0 deletions src/BrowserMockup/BrowserMockup.test.tsx
@@ -0,0 +1,50 @@
import React from 'react'
import { render } from '@testing-library/react'
import BrowserMockup from './'

const url = 'https://react.daisyui.com'
describe('BrowserMockup', () => {
it('Should render BrowserMockup', () => {
render(<BrowserMockup url={url} />)
})

it('Should apply url ', () => {
const { container } = render(<BrowserMockup url={url} />)
expect(
container.querySelector('.mockup-browser-toolbar')?.firstChild
).toHaveTextContent(url)
})

it('Should apply additional class names', () => {
const { container } = render(
<BrowserMockup url={url} className="custom-class" />
)
expect(container.firstChild).toHaveClass('custom-class')
})

it('Should apply additional input class names', () => {
const { container } = render(
<BrowserMockup url={url} inputClassName="input-class" />
)
expect(
container.querySelector('.mockup-browser-toolbar')?.firstChild
).toHaveClass('input-class')
})

it('Should forward the ref to the element', () => {
const ref = React.createRef<HTMLDivElement>()
const inputRef = React.createRef<HTMLDivElement>()
const innerRef = React.createRef<HTMLDivElement>()
render(
<BrowserMockup
url={url}
ref={ref}
inputRef={inputRef}
innerRef={innerRef}
/>
)
expect(ref.current).toBeInTheDocument()
expect(inputRef.current).toBeInTheDocument()
expect(innerRef.current).toBeInTheDocument()
})
})
82 changes: 82 additions & 0 deletions src/BrowserMockup/BrowserMockup.tsx
@@ -0,0 +1,82 @@
import React, { forwardRef, ReactNode } from 'react'
import clsx from 'clsx'
import { twMerge } from 'tailwind-merge'

import { IComponentBaseProps } from '../types'

export type BrowserMockupProps = React.HTMLAttributes<HTMLDivElement> &
IComponentBaseProps & {
url: string
variant?: 'border' | 'background'
inputClassName?: string
innerClassName?: string
inputRef?: React.Ref<HTMLDivElement>
innerRef?: React.Ref<HTMLDivElement>
}

const BrowserMockup = forwardRef<HTMLDivElement, BrowserMockupProps>(
(
{
dataTheme,
className,
inputClassName,
innerClassName,
children,
url,
variant = 'border',
inputRef,
innerRef,
...props
},
ref
): JSX.Element => {
const classes = twMerge(
'mockup-browser border',
clsx({
'border-base-300': variant === 'border',
'bg-base-300': variant === 'background',
}),
className
)

const inputClasses = twMerge(
'input',
clsx({
'border-base-300': variant === 'border',
}),
inputClassName
)

const innerClasses = twMerge(
'flex justify-center px-4 py-16 ',
clsx({
'border-t border-base-300': variant === 'border',
'bg-base-200': variant === 'background',
}),
innerClassName
)

return (
<div
aria-label="Browser mockup"
{...props}
data-theme={dataTheme}
className={classes}
ref={ref}
>
<div className="mockup-browser-toolbar">
<div className={inputClasses} ref={inputRef}>
{url}
</div>
</div>
<div className={innerClasses} ref={innerRef}>
{children}
</div>
</div>
)
}
)

BrowserMockup.displayName = 'BrowserMockup'

export default BrowserMockup
3 changes: 3 additions & 0 deletions src/BrowserMockup/index.ts
@@ -0,0 +1,3 @@
import BrowserMockup from './BrowserMockup'
export type { BrowserMockupProps } from './BrowserMockup'
export default BrowserMockup

0 comments on commit cb77fe7

Please sign in to comment.