Skip to content

Commit

Permalink
add touch-target comp.
Browse files Browse the repository at this point in the history
  • Loading branch information
irsyadadl committed Sep 11, 2024
1 parent 2ed4cd1 commit 497d6ca
Show file tree
Hide file tree
Showing 19 changed files with 128 additions and 39 deletions.
4 changes: 3 additions & 1 deletion components/doc-composed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ export function DocComposed({
<Card.Title className="sm:text-lg text-base line-clamp-1 font-medium">
{item.title}
</Card.Title>
<Card.Description className="line-clamp-2">{item.description}</Card.Description>
<Card.Description className="line-clamp-2 sm:text-sm text-xs">
{item.description}
</Card.Description>
</Card.Header>
</Card>
</Grid.Item>
Expand Down
5 changes: 4 additions & 1 deletion components/ui/aside.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { tv } from "tailwind-variants"
import { Button } from "./button"
import { cr, useMediaQuery } from "./primitive"
import { Sheet } from "./sheet"
import { TouchTarget } from "./touch-target"

const aside = tv({
slots: {
Expand Down Expand Up @@ -187,7 +188,9 @@ const Item = <T extends object>({
<div className="flex items-center gap-2">
<>
{Icon && <Icon className="shrink-0 size-4" />}
{typeof children === "function" ? children(values) : children}
<TouchTarget>
{typeof children === "function" ? children(values) : children}
</TouchTarget>
{props.badge && (
<div className="bdx h-[1.30rem] px-1 rounded-md text-muted-fg text-xs font-medium ring-1 ring-fg/20 grid place-content-center w-auto inset-y-1/2 -translate-y-1/2 absolute right-1.5 bg-fg/[0.02] dark:bg-fg/10">
{props.badge}
Expand Down
9 changes: 2 additions & 7 deletions components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { tv } from "tailwind-variants"

import { cr, focusButtonStyles } from "./primitive"
import { TouchTarget } from "./touch-target"

const buttonStyles = tv(
{
Expand Down Expand Up @@ -145,13 +146,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
)}
>
{cr(children, (children) => (
<>
<span
className="absolute left-1/2 top-1/2 size-[max(100%,2.75rem)] -translate-x-1/2 -translate-y-1/2 [@media(pointer:fine)]:hidden"
aria-hidden="true"
/>
{children}
</>
<TouchTarget>{children}</TouchTarget>
))}
</ButtonPrimitive>
)
Expand Down
26 changes: 21 additions & 5 deletions components/ui/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@ import * as React from "react"

import { IconX } from "justd-icons"
import {
Button as ButtonPrimitive,
type ButtonProps as ButtonPrimitiveProps,
Dialog as DialogPrimitive,
type DialogProps as DialogPrimitiveProps,
OverlayTriggerStateContext
} from "react-aria-components"
import { tv } from "tailwind-variants"

import type { ButtonProps } from "./button"
import { Button } from "./button"
import { Button, type ButtonProps } from "./button"
import type { HeadingProps } from "./heading"
import { Heading } from "./heading"
import { useMediaQuery } from "./primitive"
import { cr, useMediaQuery } from "./primitive"
import { TouchTarget } from "./touch-target"

const dialogStyles = tv({
slots: {
Expand Down Expand Up @@ -46,6 +48,14 @@ type DialogHeaderProps = React.HTMLAttributes<HTMLDivElement> & {
description?: string
}

const Trigger = (props: ButtonPrimitiveProps) => (
<ButtonPrimitive {...props}>
{cr(props.children, (children) => (
<TouchTarget>{children}</TouchTarget>
))}
</ButtonPrimitive>
)

const Header = ({ className, ...props }: DialogHeaderProps) => {
const headerRef = React.useRef<HTMLHeadingElement>(null)

Expand Down Expand Up @@ -124,10 +134,15 @@ const Footer = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) =
)
}

const Close = ({ className, ...props }: ButtonProps) => {
const Close = ({ className, appearance = "outline", ...props }: ButtonProps) => {
const state = React.useContext(OverlayTriggerStateContext)!
return (
<Button className={className} appearance="outline" onPress={() => state.close()} {...props} />
<Button
className={className}
appearance={appearance}
onPress={() => state.close()}
{...props}
/>
)
}

Expand Down Expand Up @@ -161,6 +176,7 @@ const CloseIndicator = ({ className, ...props }: CloseButtonIndicatorProps) => {
) : null
}

Dialog.Trigger = Trigger
Dialog.Header = Header
Dialog.Title = Title
Dialog.Description = Description
Expand Down
4 changes: 2 additions & 2 deletions components/ui/drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
useTransform
} from "framer-motion"
import type { DialogProps } from "react-aria-components"
import { Button, type ButtonProps, Modal, ModalOverlay } from "react-aria-components"
import { type ButtonProps, Modal, ModalOverlay } from "react-aria-components"
import { twJoin } from "tailwind-merge"

import { Dialog } from "./dialog"
Expand Down Expand Up @@ -186,7 +186,7 @@ const DrawerPrimitive = (props: DrawerPrimitiveProps) => {
const DrawerTrigger = (props: ButtonProps) => {
const { openDrawer } = useDrawerContext()

return <Button onPress={openDrawer} {...props} />
return <Dialog.Trigger onPress={openDrawer} {...props} />
}

interface DrawerProps {
Expand Down
1 change: 1 addition & 0 deletions components/ui/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './primitive';
export * from './touch-target';
export * from './aside';
export * from './accordion';
export * from './note';
Expand Down
11 changes: 8 additions & 3 deletions components/ui/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import { Link as LinkPrimitive, type LinkProps as LinkPrimitiveProps } from "rea
import { tv } from "tailwind-variants"

import { cr } from "./primitive"
import { TouchTarget } from "./touch-target"

const linkStyles = tv({
base: "forced-colors:outline-[Highlight] focus-visible:outline-2 outline outline-offset-2 disabled:focus-visible:outline-0 outline-0 outline-primary rounded disabled:opacity-60 forced-colors:disabled:text-[GrayText] border-transparent transition-colors disabled:cursor-default",
base: "forced-colors:outline-[Highlight] relative focus-visible:outline-2 outline outline-offset-2 disabled:focus-visible:outline-0 outline-0 outline-primary rounded disabled:opacity-60 forced-colors:disabled:text-[GrayText] border-transparent transition-colors disabled:cursor-default",
variants: {
intent: {
unstyled: "text-fg",
unstyled: "text-current",
primary: "text-primary hover:text-primary/80 forced-colors:disabled:text-[GrayText]",
danger: "text-danger hover:text-danger/80 forced-colors:disabled:text-[GrayText]",
"lad/primary":
Expand All @@ -34,7 +35,11 @@ const Link = ({ className, ...props }: LinkProps) => {
className={cr(className, (className, ...renderProps) =>
linkStyles({ ...renderProps, intent: props.intent, className })
)}
/>
>
<TouchTarget>
<>{props.children}</>
</TouchTarget>
</LinkPrimitive>
)
}

Expand Down
15 changes: 9 additions & 6 deletions components/ui/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { DropdownItemDetails, dropdownItemStyles, DropdownSection } from "./drop
import { Keyboard } from "./keyboard"
import { Popover } from "./popover"
import { cn, cr } from "./primitive"
import { TouchTarget } from "./touch-target"

interface MenuContextProps {
respectScreen: boolean
Expand All @@ -41,9 +42,7 @@ interface MenuProps extends MenuTriggerPrimitiveProps {
const Menu = ({ respectScreen = true, ...props }: MenuProps) => {
return (
<MenuContext.Provider value={{ respectScreen }}>
<MenuTriggerPrimitive {...props}>
<>{props.children}</>
</MenuTriggerPrimitive>
<MenuTriggerPrimitive {...props}>{props.children}</MenuTriggerPrimitive>
</MenuContext.Provider>
)
}
Expand All @@ -59,7 +58,7 @@ const menuStyles = tv({
menu: "z32kk max-h-[calc(var(--visual-viewport-height)-10rem)] sm:max-h-[inherit] overflow-auto rounded-xl p-1 outline outline-0 [clip-path:inset(0_0_0_0_round_calc(var(--radius)-2px))]",
popover: "z-50 min-w-40 p-0 outline-none shadow-sm",
trigger: [
"inline text-left focus:outline-none focus-visible:ring-1 focus-visible:ring-primary-500 pressed:outline-none"
"inline relative text-left focus:outline-none focus-visible:ring-1 focus-visible:ring-primary-500 pressed:outline-none"
]
}
})
Expand All @@ -71,7 +70,11 @@ interface MenuTriggerProps extends ButtonProps {
}

const Trigger = ({ className, ...props }: MenuTriggerProps) => (
<Button className={trigger({ className })} {...props} />
<Button className={trigger({ className })} {...props}>
{cr(props.children, (children) => (
<TouchTarget>{children}</TouchTarget>
))}
</Button>
)

interface MenuContentProps<T>
Expand Down Expand Up @@ -196,4 +199,4 @@ Menu.Trigger = Trigger
Menu.ItemDetails = DropdownItemDetails
Menu.Submenu = SubMenu

export { Menu, type MenuItemProps, type MenuContentProps }
export { Menu, type MenuContentProps }
3 changes: 1 addition & 2 deletions components/ui/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type {
ModalOverlayProps as ModalOverlayPrimitiveProps
} from "react-aria-components"
import {
Button as ButtonPrimitive,
type DialogProps,
DialogTrigger as DialogTriggerPrimitive,
Modal as ModalPrimitive,
Expand Down Expand Up @@ -140,7 +139,7 @@ const ModalContent = ({
)
}

Modal.Trigger = ButtonPrimitive
Modal.Trigger = Dialog.Trigger
Modal.Header = Dialog.Header
Modal.Title = Dialog.Title
Modal.Description = Dialog.Description
Expand Down
3 changes: 1 addition & 2 deletions components/ui/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import * as React from "react"

import type { ModalOverlayProps } from "react-aria-components"
import {
Button,
type DialogProps,
DialogTrigger as DialogTriggerPrimitive,
Modal,
Expand Down Expand Up @@ -182,7 +181,7 @@ const Picker = ({ children, className, ...props }: PopoverProps) => {
}

Popover.Primitive = PopoverPrimitive
Popover.Trigger = Button
Popover.Trigger = Dialog.Trigger
Popover.Close = Dialog.Close
Popover.Content = Content
Popover.Description = Dialog.Description
Expand Down
3 changes: 1 addition & 2 deletions components/ui/sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import * as React from "react"

import type { DialogTriggerProps, Modal } from "react-aria-components"
import {
Button,
type DialogProps,
DialogTrigger as DialogTriggerPrimitive,
Modal as ModalPrimitive,
Expand Down Expand Up @@ -149,7 +148,7 @@ const SheetContent = ({
)
}

Sheet.Trigger = Button
Sheet.Trigger = Dialog.Trigger
Sheet.Footer = Dialog.Footer
Sheet.Content = SheetContent
Sheet.Header = Dialog.Header
Expand Down
10 changes: 9 additions & 1 deletion components/ui/show-more.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
"use client"

import * as React from "react"

import { cr } from "@/components/ui/primitive"
import { TouchTarget } from "@/components/ui/touch-target"
import { Text, ToggleButton } from "react-aria-components"
import { tv } from "tailwind-variants"

Expand Down Expand Up @@ -49,7 +53,11 @@ const ShowMore = ({
<ToggleButton
{...props}
className={buttonStyles({ shape: "circle", appearance: "outline", size: "small" })}
/>
>
{cr(props.children, (children) => (
<TouchTarget>{children}</TouchTarget>
))}
</ToggleButton>
) : (
<Text slot="description">{props.text}</Text>
)}
Expand Down
15 changes: 10 additions & 5 deletions components/ui/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { tv } from "tailwind-variants"

import { Checkbox } from "./checkbox"
import { cn } from "./primitive"
import { TouchTarget } from "./touch-target"

const table = tv({
slots: {
Expand Down Expand Up @@ -77,9 +78,11 @@ const TableColumn = ({ children, className, ...props }: TableColumnProps) => (
<>
{children}
{allowsSorting && (
<span className={cellIcon({ className: isHovered ? "bg-secondary-fg/10" : "" })}>
<IconChevronLgDown className={sortDirection === "ascending" ? "rotate-180" : ""} />
</span>
<TouchTarget>
<span className={cellIcon({ className: isHovered ? "bg-secondary-fg/10" : "" })}>
<IconChevronLgDown className={sortDirection === "ascending" ? "rotate-180" : ""} />
</span>
</TouchTarget>
)}
</>
</div>
Expand Down Expand Up @@ -129,10 +132,12 @@ const TableRow = <T extends object>({
{allowsDragging && (
<Cell className="ring-primary pr-0 group cursor-grab dragging:cursor-grabbing">
<Button
className="bg-transparent pl-3.5 py-1.5 text-muted-fg pressed:text-fg"
className="relative bg-transparent pl-3.5 py-1.5 text-muted-fg pressed:text-fg"
slot="drag"
>
<IconHamburger />
<TouchTarget>
<IconHamburger />
</TouchTarget>
</Button>
</Cell>
)}
Expand Down
11 changes: 9 additions & 2 deletions components/ui/toggle.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
"use client"

import * as React from "react"

import { ToggleButton as ToggleButtonPrimitive, ToggleButtonProps } from "react-aria-components"
import { tv, VariantProps } from "tailwind-variants"

import { cr, focusButtonStyles } from "./primitive"
import { TouchTarget } from "./touch-target"

const toggleStyles = tv({
extend: focusButtonStyles,
base: [
"inline-flex items-center bg-transparent justify-center border border-transparent rounded-lg text-sm font-medium ring-offset-bg transition-colors",
"inline-flex relative items-center bg-transparent justify-center border border-transparent rounded-lg text-sm font-medium ring-offset-bg transition-colors",
"hover:bg-muted hover:text-muted-fg"
],
variants: {
Expand Down Expand Up @@ -54,7 +57,11 @@ const Toggle = ({ className, ...props }: ToggleProps) => {
className
})
)}
/>
>
{cr(props.children, (children) => (
<TouchTarget>{children}</TouchTarget>
))}
</ToggleButtonPrimitive>
)
}

Expand Down
15 changes: 15 additions & 0 deletions components/ui/touch-target.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from "react"

const TouchTarget = ({ children }: { children: React.ReactNode }) => {
return (
<>
<span
className="absolute left-1/2 top-1/2 size-[max(100%,2.75rem)] -translate-x-1/2 -translate-y-1/2 [@media(pointer:fine)]:hidden"
aria-hidden="true"
/>
{children}
</>
)
}

export { TouchTarget }
3 changes: 3 additions & 0 deletions resources/content/docs/components/buttons/button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ A button lets peeps do stuff with clicks, presses, taps, and keystrokes.
## Installation
<InstallCommand isAdd items={['button']}/>

## Composed Components
<Composed components={['touch-target']}/>

## Manual Installation

<InstallCommand isInstall isManual items={['react-aria-components']}/>
Expand Down
2 changes: 2 additions & 0 deletions resources/content/docs/components/buttons/toggle.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ A toggle button lets folks flip a choice on or off, like switching between two v
## Installation
<InstallCommand isAdd items={['toggle']}/>

## Composed Components
<Composed components={['touch-target']}/>

## Manual Installation
<InstallCommand isInstall isManual items={['react-aria-components']}/>
Expand Down
Loading

0 comments on commit 497d6ca

Please sign in to comment.