Skip to content

Commit

Permalink
Add Omnibutton (#938)
Browse files Browse the repository at this point in the history
* Omnibutton

* acc

* mandatory label
  • Loading branch information
dani-moreno authored Dec 4, 2024
1 parent 6a65b4b commit a80c9f7
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 0 deletions.
4 changes: 4 additions & 0 deletions assets/icons/app/question.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
56 changes: 56 additions & 0 deletions lib/experimental/Navigation/Omnibutton/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { Meta, StoryObj } from "@storybook/react"
import { OmniButton } from "."

const meta: Meta<typeof OmniButton> = {
component: OmniButton,
parameters: {
layout: "fullscreen",
},
decorators: [
(Story) => (
<div className="relative h-screen w-screen">
<Story />
</div>
),
],
}

export default meta

type Story = StoryObj<typeof OmniButton>

const mockOptions = [
{
title: "Let's talk",
description: "Contact a specialist by phone.",
href: "#",
target: "_blank",
},
{
title: "Drop us a line",
description: "Send a support request form to our help team.",
href: "#",
target: "_blank",
},
{
title: "Help Center",
href: "#",
target: "_blank",
},
]

export const Default: Story = {
args: {
label: "Help",
options: mockOptions,
hasNewUpdate: false,
},
}

export const WithNewUpdate: Story = {
args: {
label: "Help",
options: mockOptions,
hasNewUpdate: true,
},
}
58 changes: 58 additions & 0 deletions lib/experimental/Navigation/Omnibutton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Icon } from "@/components/Utilities/Icon"
import { Dropdown, DropdownItem } from "@/experimental/Navigation/Dropdown"
import { Question } from "@/icons/app"
import { cn, focusRing } from "@/lib/utils"

interface Option {
title: string
description?: string
href?: string
onClick?: () => void
icon?: string
target?: string
}

interface OmniButtonProps {
label: string
options: Option[]
hasNewUpdate?: boolean
}

// Function to format the options that comes from Factorial for the dropdown
function formatDropdownItems(options: Option[]): DropdownItem[] {
return options
.filter((option) => !!option.title)
.map(({ title, description, href, onClick, target: _ }) => ({
label: title,
description,
href,
onClick,
}))
}

export function OmniButton({ label, options, hasNewUpdate }: OmniButtonProps) {
return (
<div
className="fixed z-10"
style={{
bottom: `calc(8px + env(safe-area-inset-bottom))`,
right: `calc(8px + env(safe-area-inset-right))`,
}}
>
<Dropdown items={formatDropdownItems(options)}>
<button
className={cn(
"relative flex h-6 w-6 items-center justify-center rounded-full bg-f1-background-bold text-f1-foreground-inverse shadow-md transition-all",
focusRing()
)}
aria-label={label}
>
<Icon icon={Question} size="sm" />
{hasNewUpdate && (
<div className="absolute right-0.5 top-0.5 h-1.5 w-1.5 rounded-full bg-f1-background-critical-bold ring-2 ring-f1-background-critical" />
)}
</button>
</Dropdown>
</div>
)
}
6 changes: 6 additions & 0 deletions lib/icons/app/Question.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from "react";
import type { SVGProps } from "react";
import { Ref, forwardRef } from "react";
const SvgQuestion = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" ref={ref} {...props}><path stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" d="M9 9C9 7 10.5 6 12 6C13.5 6 15 7.5 15 9C15 12 12 11.5 12 14" vectorEffect="non-scaling-stroke" /><path stroke="currentColor" strokeLinecap="round" d="M12 17V17.1" vectorEffect="non-scaling-stroke" /></svg>;
const ForwardRef = forwardRef(SvgQuestion);
export default ForwardRef;
1 change: 1 addition & 0 deletions lib/icons/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export { default as Person } from './Person'
export { default as Pin } from './Pin'
export { default as PixBrazil } from './PixBrazil'
export { default as Placeholder } from './Placeholder'
export { default as Question } from './Question'
export { default as Reaction } from './Reaction'
export { default as Receipt } from './Receipt'
export { default as Rocket } from './Rocket'
Expand Down

0 comments on commit a80c9f7

Please sign in to comment.