[website] Add Jobs page (#433)
* add jobs route * implement jobs page * imlement jobs detail page * remove vertical padding from feature list * fix field * fix button pressing * fix feature list * fix tag --------- Co-authored-by: Jakub Kotula <520927+jkbktl@users.noreply.github.com>
This commit is contained in:
parent
6dd97428c7
commit
cadab15871
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
|
@ -7,7 +7,7 @@ import type { illustrations } from '@/config/illustrations'
|
|||
type Item = {
|
||||
title: string
|
||||
description: string
|
||||
image: (typeof illustrations)[keyof typeof illustrations]
|
||||
icon: (typeof illustrations)[keyof typeof illustrations]
|
||||
}
|
||||
|
||||
type Props = {
|
||||
|
@ -18,15 +18,15 @@ type Props = {
|
|||
export const FeatureList = (props: Props) => {
|
||||
const { list, dark = false } = props
|
||||
return (
|
||||
<div className="container pb-24 pt-12 lg:m-auto lg:gap-10">
|
||||
<div className="container lg:m-auto lg:gap-10">
|
||||
<div className="grid grid-cols-1 gap-12 sm:grid-cols-2 lg:-ml-10 lg:grid-cols-3">
|
||||
{list.map(({ title, image, description }, i) => (
|
||||
{list.map(({ title, icon, description }, i) => (
|
||||
<div key={title} className="flex flex-col">
|
||||
<Image {...image} alt={image.alt} className="mb-4 ml-10" />
|
||||
<Image {...icon} alt={icon.alt} className="mb-4 ml-10" />
|
||||
<div
|
||||
className={cx(
|
||||
'flex flex-col border-dashed lg:border-l-[1px] lg:pl-10',
|
||||
(i === 0 || i === 3) && 'lg:border-l-0',
|
||||
'flex flex-col border-dashed lg:pl-10',
|
||||
i % 3 === 0 ? 'lg:border-l-0' : 'lg:border-l-[1px]',
|
||||
dark ? 'border-l-neutral-70' : 'border-l-neutral-30'
|
||||
)}
|
||||
>
|
||||
|
|
|
@ -38,7 +38,7 @@ export const ROUTES = {
|
|||
{ name: 'Blog', href: '/blog' },
|
||||
{ name: 'Translations', href: '/' },
|
||||
// { name: 'Community groups', href: '/' },
|
||||
{ name: 'Jobs', href: '/' },
|
||||
{ name: 'Jobs', href: '/jobs' },
|
||||
],
|
||||
Developers: [
|
||||
{ name: 'Repos', href: 'https://github.com/status-im' },
|
||||
|
|
|
@ -35,37 +35,37 @@ const FEATURE_LIST = [
|
|||
title: 'Decentralized',
|
||||
description:
|
||||
'Communities are literally powered by their members running the Status Desktop app.',
|
||||
image: illustrations.doge,
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'Permissionless',
|
||||
description:
|
||||
'Nobody can stop you creating a community, because nobody controls Status’ p2p network.',
|
||||
image: illustrations.mushroom,
|
||||
icon: illustrations.mushroom,
|
||||
},
|
||||
{
|
||||
title: 'Self-sovereign',
|
||||
description:
|
||||
'Each community can set it’s own rules, whatever they are. And is responsible for it’s own actions. ',
|
||||
image: illustrations.hand,
|
||||
icon: illustrations.hand,
|
||||
},
|
||||
{
|
||||
title: '100% Free to use',
|
||||
description:
|
||||
'No paid tier. No artificially imposed limits. No commission charged on community token sales.',
|
||||
image: illustrations.duck,
|
||||
icon: illustrations.duck,
|
||||
},
|
||||
{
|
||||
title: '100% Open source',
|
||||
description:
|
||||
'Status itself is a community project. Anyone can build, contribute to and fork it’s source code.',
|
||||
image: illustrations.flower,
|
||||
icon: illustrations.flower,
|
||||
},
|
||||
{
|
||||
title: '100% Freedom',
|
||||
description:
|
||||
'Status’s mission is to protect free speech, uphold human rights and defend privacy.',
|
||||
image: illustrations.megaphone,
|
||||
icon: illustrations.megaphone,
|
||||
},
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
import { Button, Tag, Text } from '@status-im/components'
|
||||
import { cx } from 'class-variance-authority'
|
||||
|
||||
import { Breadcrumbs } from '@/components/breadcrumbs'
|
||||
import { AppLayout, Content } from '@/layouts/app-layout'
|
||||
|
||||
import type { BreadcrumbsProps } from '@/components/breadcrumbs'
|
||||
import type { GetStaticPaths, GetStaticProps, Page } from 'next'
|
||||
import type React from 'react'
|
||||
|
||||
type Params = { slug: string }
|
||||
|
||||
const SLUG = 'senior-react-native-ui-developer'
|
||||
|
||||
export const getStaticPaths: GetStaticPaths<Params> = async () => {
|
||||
return {
|
||||
paths: [
|
||||
{
|
||||
params: {
|
||||
slug: SLUG,
|
||||
},
|
||||
},
|
||||
],
|
||||
fallback: false,
|
||||
}
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps<Props, Params> = async () => {
|
||||
// root
|
||||
const breadcrumbs = [
|
||||
{
|
||||
label: 'Jobs',
|
||||
// TODO: typesafe
|
||||
href: '/jobs',
|
||||
},
|
||||
{
|
||||
label: 'Senior React Native UI Developer',
|
||||
href: `/jobs/${SLUG}`,
|
||||
},
|
||||
]
|
||||
|
||||
return {
|
||||
props: {
|
||||
breadcrumbs,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type Props = {
|
||||
breadcrumbs: BreadcrumbsProps['items']
|
||||
}
|
||||
|
||||
const JobsDetailPage: Page<Props> = props => {
|
||||
const { breadcrumbs } = props
|
||||
|
||||
return (
|
||||
<Content>
|
||||
<Breadcrumbs items={breadcrumbs} />
|
||||
|
||||
<div className="mx-auto max-w-[742px] px-5">
|
||||
<div className="flex flex-col items-start gap-4 pb-6 pt-12 lg:pt-20">
|
||||
<Tag size={24} label="Mobile" />
|
||||
<h1 className="text-40 lg:text-64">
|
||||
Senior React Native UI Developer
|
||||
</h1>
|
||||
<Text size={19} color="$neutral-50">
|
||||
Full time, Remote (Worldwide)
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
{/* CONTENT */}
|
||||
<div className="pb-12 pt-6 lg:pb-20">
|
||||
<Text size={19}>
|
||||
The role We’re growing our mobile development team. Join us in
|
||||
building a fully decentralized, censorship resistant, privacy first
|
||||
group chat platform that leverages the Ethereum blockchain to enable
|
||||
individuals and groups worldwide to communicate and transact with
|
||||
one another freely without restriction. Status is looking for an UI
|
||||
Engineer to join our mobile development team who will work closely
|
||||
with Design to transform UI specifications into beautiful, smooth,
|
||||
performant and near pixel perfect interactive interfaces. The ideal
|
||||
person will be comfortable working on features end-to-end, has an
|
||||
eye for design and visual detail, enjoys working with designers as
|
||||
well as developers, and who can transform reused UI patterns such as
|
||||
list items into reusable UI components.
|
||||
<br />
|
||||
<br />
|
||||
The ideal candidate will love finessing UI implementations to the
|
||||
highest levels of quality and will care deeply about things like
|
||||
code cleanliness, reusability, maintainability, performance, and UI
|
||||
layout accuracy - as well as doing whatever needed to create a
|
||||
best-in-class user experience for Status’s users. Willingness to
|
||||
both learn and share your knowledge with others,
|
||||
product-orientation, and making sure all team members are aligned
|
||||
when developing new features, will make you successful in the role.
|
||||
Status is a fast-paced, flat organization, working on cutting edge
|
||||
blockchain and decentralized messaging technologies in a dynamic
|
||||
landscape. We look forward to meeting you!
|
||||
</Text>
|
||||
|
||||
<Text size={19}>
|
||||
The role We’re growing our mobile development team. Join us in
|
||||
building a fully decentralized, censorship resistant, privacy first
|
||||
group chat platform that leverages the Ethereum blockchain to enable
|
||||
individuals and groups worldwide to communicate and transact with
|
||||
one another freely without restriction. Status is looking for an UI
|
||||
Engineer to join our mobile development team who will work closely
|
||||
with Design to transform UI specifications into beautiful, smooth,
|
||||
performant and near pixel perfect interactive interfaces. The ideal
|
||||
person will be comfortable working on features end-to-end, has an
|
||||
eye for design and visual detail, enjoys working with designers as
|
||||
well as developers, and who can transform reused UI patterns such as
|
||||
list items into reusable UI components.
|
||||
<br />
|
||||
<br />
|
||||
The ideal candidate will love finessing UI implementations to the
|
||||
highest levels of quality and will care deeply about things like
|
||||
code cleanliness, reusability, maintainability, performance, and UI
|
||||
layout accuracy - as well as doing whatever needed to create a
|
||||
best-in-class user experience for Status’s users. Willingness to
|
||||
both learn and share your knowledge with others,
|
||||
product-orientation, and making sure all team members are aligned
|
||||
when developing new features, will make you successful in the role.
|
||||
Status is a fast-paced, flat organization, working on cutting edge
|
||||
blockchain and decentralized messaging technologies in a dynamic
|
||||
landscape. We look forward to meeting you!
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
{/* FOOTER */}
|
||||
<div
|
||||
className={cx(
|
||||
'border-dashed-default -mx-5 flex flex-col items-start gap-4 border-t px-5 pb-24 pt-6',
|
||||
'md:mx-0 md:flex-row md:items-center md:justify-between md:px-0 md:pb-40'
|
||||
)}
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
<Text size={19} weight="semibold">
|
||||
Apply for this job
|
||||
</Text>
|
||||
<Text size={15}>Submit your application here</Text>
|
||||
</div>
|
||||
<Button size={32}>Apply now</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Content>
|
||||
)
|
||||
}
|
||||
|
||||
JobsDetailPage.getLayout = function getLayout(page) {
|
||||
return <AppLayout>{page}</AppLayout>
|
||||
}
|
||||
|
||||
export default JobsDetailPage
|
|
@ -0,0 +1,276 @@
|
|||
import { useRef } from 'react'
|
||||
|
||||
// import codexImage from '@assets/jobs/codex.png'
|
||||
import logosImage from '@assets/jobs/logos.png'
|
||||
// import nimbusImage from '@assets/jobs/nimbus.png'
|
||||
// import vacImage from '@assets/jobs/vac.png'
|
||||
// import wakuImage from '@assets/jobs/waku.png'
|
||||
import { Button, Tag, Text } from '@status-im/components'
|
||||
import { ArrowDownIcon, ArrowRightIcon, ExternalIcon } from '@status-im/icons'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { FeatureList } from '@/components/feature-list'
|
||||
import { illustrations } from '@/config/illustrations'
|
||||
import { AppLayout, Content } from '@/layouts/app-layout'
|
||||
|
||||
import type { Page } from 'next'
|
||||
|
||||
// TODO FIX PHOTOS
|
||||
// TODO FIX FEATURE LIST
|
||||
// TODO ADD CIRCLES
|
||||
// TODO CONNECT TO GREENHOUSE API (https://developers.greenhouse.io/job-board.html#retrieve-job-board)
|
||||
|
||||
const OPEN_JOBS = 82
|
||||
|
||||
const JobsPage: Page = () => {
|
||||
const openRolesRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const handleScrollToOpenings = () => {
|
||||
openRolesRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
||||
}
|
||||
|
||||
return (
|
||||
<Content>
|
||||
<div className="container flex flex-col items-start pb-6 pt-16 lg:pb-20 lg:pt-40">
|
||||
<div className="mb-4">
|
||||
<Tag size={32} label="Jobs" />
|
||||
</div>
|
||||
<h1 className="mb-6 text-48 lg:mb-8 lg:text-88">
|
||||
Join the
|
||||
<br />
|
||||
decentralized
|
||||
<br />
|
||||
movement
|
||||
</h1>
|
||||
|
||||
<div className="flex w-full max-w-[462px] flex-col justify-between gap-3 rounded-2xl border border-dashed border-neutral-80/20 p-3 md:flex-row md:gap-10 lg:items-center lg:p-2 lg:pl-3">
|
||||
<div className="flex flex-col">
|
||||
<Text size={13} weight="semibold">
|
||||
We’re hiring!
|
||||
</Text>
|
||||
<Text size={13}>{OPEN_JOBS} remote openings</Text>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
iconAfter={<ArrowDownIcon size={20} />}
|
||||
onPress={handleScrollToOpenings}
|
||||
>
|
||||
View openings
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* PHOTOS */}
|
||||
<div className="container grid grid-cols-2 gap-4 pb-12 pt-6 lg:pb-20 lg:pt-10">
|
||||
<img
|
||||
src="https://images.pexels.com/photos/16972528/pexels-photo-16972528/free-photo-of-sea-flight-bird-beach.jpeg?auto=compress&cs=tinysrgb&w=750&h=750&dpr=2"
|
||||
className="aspect-square rounded-3xl object-cover"
|
||||
/>
|
||||
<div className="grid grid-rows-2 gap-4">
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<img
|
||||
src="https://images.pexels.com/photos/17162015/pexels-photo-17162015/free-photo-of-street-field-school-park.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2"
|
||||
className="aspect-square rounded-3xl object-cover"
|
||||
/>
|
||||
<img
|
||||
src="https://images.pexels.com/photos/17162015/pexels-photo-17162015/free-photo-of-street-field-school-park.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2"
|
||||
className="aspect-square rounded-3xl object-cover"
|
||||
/>
|
||||
</div>
|
||||
<img
|
||||
src="https://images.pexels.com/photos/17162015/pexels-photo-17162015/free-photo-of-street-field-school-park.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2"
|
||||
className="aspect-[2.060] rounded-3xl object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section className="border-b border-dashed border-neutral-80/20 pb-24 pt-12 lg:pb-40 lg:pt-20">
|
||||
<div className="mx-auto max-w-[740px] px-5">
|
||||
<Text size={19}>
|
||||
Status strives to develop open source software that can be used as a
|
||||
secure communication tool that upholds human rights. We are building
|
||||
the tools and infrastructure for the advancement of a secure,
|
||||
private, and open web3. Our core software, Status, is an open
|
||||
source, Ethereum-based software that gives users the power to chat,
|
||||
transact, and access a revolutionary world of DApps on the
|
||||
decentralized web. With the high level goals of preserving the right
|
||||
to privacy, protecting messages from third parties, and safely
|
||||
sending, storing and receiving cryptocurrencies with you being the
|
||||
only one who holds the keys to your funds, Status is providing the
|
||||
tools and infrastructure to facilitate the creation of communities,
|
||||
where anyone is welcome to create, join and contribute.
|
||||
<br />
|
||||
<br />
|
||||
150+ passionate individuals (known as core-contributors) work
|
||||
together all around the world to facilitate Status’ mission. We care
|
||||
deeply about our mission, so we have created an environment which
|
||||
allows core-contributors to complete their work with freedom and
|
||||
flexibility. We regularly survey the core contributors to gather
|
||||
insights on their satisfaction with contributing to Status & the
|
||||
most common answers regarding why they’re satisfied are: our
|
||||
mission, values, flexibility, friendly environment, non-corporate
|
||||
culture and our entrepreneurial spirit.
|
||||
</Text>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="border-b border-dashed border-neutral-80/20 py-24 lg:py-40">
|
||||
<div className="container mb-12 lg:mb-20">
|
||||
<h2 className="text-40 lg:text-64">Perks and benefits</h2>
|
||||
</div>
|
||||
<FeatureList list={PERKS} />
|
||||
</div>
|
||||
|
||||
<div className="container py-24 lg:py-40" ref={openRolesRef}>
|
||||
<div className="mb-12 lg:mb-20">
|
||||
<h2 className="text-40 lg:text-64">Open roles</h2>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-12 lg:gap-16">
|
||||
{/* JOB GROUPS */}
|
||||
{[1, 2, 3].map(i => (
|
||||
<div
|
||||
key={i}
|
||||
className="border-b border-dashed border-neutral-80/20"
|
||||
>
|
||||
<div>
|
||||
<h3 className="mb-3 text-27">Design</h3>
|
||||
</div>
|
||||
<div className="divide-y divide-dashed divide-neutral-80/20">
|
||||
{[
|
||||
'Product designer',
|
||||
'Visual designer',
|
||||
'Motion designer',
|
||||
'Illustrator',
|
||||
].map(position => (
|
||||
// TODO: discuss hover state
|
||||
<Link
|
||||
href="/jobs/senior-react-native-ui-developer"
|
||||
key={position}
|
||||
className="flex items-center justify-between py-5"
|
||||
>
|
||||
<Text size={19} weight="semibold">
|
||||
{position}
|
||||
</Text>
|
||||
<div className="flex items-center gap-6">
|
||||
<Text size={19}>Full-time</Text>
|
||||
<Button
|
||||
variant="outline"
|
||||
size={40}
|
||||
icon={<ArrowRightIcon size={20} />}
|
||||
/>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* TODO FIX TEXTURE */}
|
||||
<div className="rounded-[40px] bg-[#F5F6FD]">
|
||||
<div className="container py-24 lg:py-40">
|
||||
<div className="mb-20">
|
||||
<h3 className="text-40">
|
||||
Open roles
|
||||
<br />
|
||||
in our network
|
||||
</h3>
|
||||
</div>
|
||||
<div className="grid gap-12">
|
||||
{['Logos', 'Codex', 'Waku', 'Nimbus', 'Vac'].map(name => (
|
||||
<div key={name} className="grid gap-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<Image
|
||||
src={logosImage}
|
||||
width={24}
|
||||
height={24}
|
||||
alt={`${name} logo`}
|
||||
/>
|
||||
<Text size={19} weight="semibold">
|
||||
{name}
|
||||
</Text>
|
||||
</div>
|
||||
{[1, 2, 3, 4, 5, 6].map(i => (
|
||||
<Link
|
||||
key={i}
|
||||
href="https://google.com"
|
||||
className="group flex items-center"
|
||||
>
|
||||
<Text size={15} weight="medium">
|
||||
Protocol Research Engineer
|
||||
</Text>
|
||||
<ExternalIcon
|
||||
size={16}
|
||||
className="transition-transform group-hover:translate-x-[2px] group-hover:translate-y-[-2px]"
|
||||
/>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Content>
|
||||
)
|
||||
}
|
||||
|
||||
const PERKS = [
|
||||
{
|
||||
title: 'Fully remote',
|
||||
description: 'Work from wherever you want, whenever you want. ',
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'Unlimited vacation',
|
||||
description:
|
||||
'Take all the time off you need. We need you in your best self.',
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'Paid team offsites',
|
||||
description: 'We meet at least once a year somewhere across the world. ',
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'Hardware stipend',
|
||||
description: 'Need a laptop to work? We got you covered.',
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'Co-working stipend',
|
||||
description:
|
||||
'We offer a $250 stipend for you to work from a co-working space.',
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'Get paid in crypto',
|
||||
description: 'We offer to pay salaries in SNT, ETH, USDC or fiat.',
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'SNT Bonus',
|
||||
description: 'We reward hard work and longevity with a bonus in SNT. ',
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'Referral fee',
|
||||
description:
|
||||
'We offer a $5000 SNT referral fee so bring your friends aboard.',
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'Headspace subscription',
|
||||
description:
|
||||
'Take care of your mind with a premium headspace account, for free.',
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
]
|
||||
|
||||
JobsPage.getLayout = function getLayout(page) {
|
||||
return <AppLayout>{page}</AppLayout>
|
||||
}
|
||||
|
||||
export default JobsPage
|
|
@ -132,36 +132,36 @@ const FEATURE_LIST = [
|
|||
title: 'Top tier security',
|
||||
description:
|
||||
'Our hardware security successfully passed Common Criteria EAL6+ certification ',
|
||||
image: illustrations.doge,
|
||||
icon: illustrations.doge,
|
||||
},
|
||||
{
|
||||
title: 'Keys stored in the card',
|
||||
description:
|
||||
'It’s impossible for Status or any government to extract your private keys from keycard',
|
||||
image: illustrations.mushroom,
|
||||
icon: illustrations.mushroom,
|
||||
},
|
||||
{
|
||||
title: 'Feature 3',
|
||||
description:
|
||||
'Here will say something more about security and how kc is revolutionary when it comes to security',
|
||||
image: illustrations.hand,
|
||||
icon: illustrations.hand,
|
||||
},
|
||||
{
|
||||
title: 'Mobile friendly',
|
||||
description:
|
||||
'Keycard is using NFC which is natively embedded in all mobile phones',
|
||||
image: illustrations.duck,
|
||||
icon: illustrations.duck,
|
||||
},
|
||||
{
|
||||
title: 'No need to charge',
|
||||
description: 'Keycard has no battery so it’s always ready to go.',
|
||||
image: illustrations.flower,
|
||||
icon: illustrations.flower,
|
||||
},
|
||||
{
|
||||
title: 'Easy to carry around',
|
||||
description:
|
||||
'Its credit card form factor is small and convenient to fit in any wallet.',
|
||||
image: illustrations.megaphone,
|
||||
icon: illustrations.megaphone,
|
||||
},
|
||||
]
|
||||
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
.container {
|
||||
@apply mx-auto max-w-[1504px] px-5 lg:px-40;
|
||||
}
|
||||
.border-dashed-default {
|
||||
@apply border-dashed border-neutral-80/20;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes gradient {
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import { cloneElement, forwardRef } from 'react'
|
||||
|
||||
import { styled } from '@tamagui/core'
|
||||
import { Pressable } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
|
||||
import { Text } from '../text'
|
||||
|
||||
import type { TextProps } from '../text'
|
||||
import type { GetVariants, MapVariant, PressableProps } from '../types'
|
||||
import type { Ref } from 'react'
|
||||
import type { View } from 'react-native'
|
||||
|
||||
type Variants = GetVariants<typeof Base>
|
||||
|
||||
|
@ -94,10 +93,9 @@ const _Button = forwardRef(Button)
|
|||
export { _Button as Button }
|
||||
export type { Props as ButtonProps }
|
||||
|
||||
const Base = styled(Pressable, {
|
||||
tag: 'button',
|
||||
const Base = styled(View, {
|
||||
name: 'Button',
|
||||
accessibilityRole: 'button',
|
||||
role: 'button',
|
||||
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
|
|
|
@ -2,7 +2,7 @@ import { forwardRef } from 'react'
|
|||
|
||||
import { ArrowDownIcon, MentionIcon } from '@status-im/icons'
|
||||
import { styled } from '@tamagui/core'
|
||||
import { Pressable } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
|
||||
import { Shadow } from '../shadow'
|
||||
import { Text } from '../text'
|
||||
|
@ -10,7 +10,6 @@ import { Text } from '../text'
|
|||
import type { GetVariants, PressableProps } from '../types'
|
||||
import type { ColorTokens } from '@tamagui/core'
|
||||
import type { Ref } from 'react'
|
||||
import type { View } from 'react-native'
|
||||
|
||||
type Variants = GetVariants<typeof Button>
|
||||
|
||||
|
@ -50,10 +49,9 @@ const _DynamicButton = forwardRef(DynamicButton)
|
|||
export { _DynamicButton as DynamicButton }
|
||||
export type { Props as DynamicButtonProps }
|
||||
|
||||
const Button = styled(Pressable, {
|
||||
const Button = styled(View, {
|
||||
name: 'DynamicButton',
|
||||
tag: 'button',
|
||||
accessibilityRole: 'button',
|
||||
role: 'button',
|
||||
|
||||
cursor: 'pointer',
|
||||
userSelect: 'none',
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { useState } from 'react'
|
||||
|
||||
import type { PressableProps } from '../types'
|
||||
import type { MouseEvent } from 'react-native'
|
||||
import type { ColorTokens } from 'tamagui'
|
||||
|
||||
type Config = {
|
||||
|
@ -49,20 +48,20 @@ export const usePressableColors = (
|
|||
return {
|
||||
color: styles[key],
|
||||
pressableProps: {
|
||||
onHoverIn: event => {
|
||||
props.onHoverIn?.(event as unknown as MouseEvent)
|
||||
onHoverIn: (...args) => {
|
||||
props.onHoverIn?.(...args)
|
||||
setHovered(true)
|
||||
},
|
||||
onHoverOut: event => {
|
||||
props.onHoverOut?.(event as unknown as MouseEvent)
|
||||
onHoverOut: (...args) => {
|
||||
props.onHoverOut?.(...args)
|
||||
setHovered(false)
|
||||
},
|
||||
onPressIn: event => {
|
||||
props.onPressIn?.(event)
|
||||
onPressIn: (...args) => {
|
||||
props.onPressIn?.(...args)
|
||||
setPressed(true)
|
||||
},
|
||||
onPressOut: event => {
|
||||
props.onPressOut?.(event)
|
||||
onPressOut: (...args) => {
|
||||
props.onPressOut?.(...args)
|
||||
setPressed(false)
|
||||
},
|
||||
} as const,
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import { cloneElement, forwardRef } from 'react'
|
||||
|
||||
import { Pressable } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { styled } from 'tamagui'
|
||||
|
||||
import { usePressableColors } from '../hooks/use-pressable-colors'
|
||||
|
||||
import type { GetVariants, PressableProps } from '../types'
|
||||
import type { Ref } from 'react'
|
||||
import type { View } from 'react-native'
|
||||
|
||||
type Variants = GetVariants<typeof Base>
|
||||
|
||||
|
@ -63,10 +62,9 @@ const _IconButton = forwardRef(IconButton)
|
|||
export { _IconButton as IconButton }
|
||||
export type { Props as IconButtonProps }
|
||||
|
||||
const Base = styled(Pressable, {
|
||||
const Base = styled(View, {
|
||||
name: 'IconButton',
|
||||
tag: 'button',
|
||||
accessibilityRole: 'button',
|
||||
role: 'button',
|
||||
|
||||
cursor: 'pointer',
|
||||
userSelect: 'none',
|
||||
|
|
|
@ -106,7 +106,6 @@ const _Input = (props: Props, ref: Ref<TextInput>) => {
|
|||
{Boolean(onClear) && !!value && (
|
||||
<Stack
|
||||
role="button"
|
||||
accessibilityRole="button"
|
||||
pr={4}
|
||||
onPress={onClear}
|
||||
cursor="pointer"
|
||||
|
|
|
@ -10,14 +10,13 @@ import {
|
|||
ThumbsUpIcon,
|
||||
} from '@status-im/icons'
|
||||
import { styled } from '@tamagui/core'
|
||||
import { Pressable } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
|
||||
import { Text } from '../text'
|
||||
|
||||
import type { ReactionType } from '../messages/types'
|
||||
import type { PressableProps } from '../types'
|
||||
import type { Ref } from 'react'
|
||||
import type { View } from 'react-native'
|
||||
|
||||
export const REACTIONS_ICONS = {
|
||||
love: LoveIcon,
|
||||
|
@ -63,10 +62,9 @@ const _ReactButton = forwardRef(ReactButton)
|
|||
export { _ReactButton as ReactButton }
|
||||
export type { Props as ReactButtonProps }
|
||||
|
||||
const Button = styled(Pressable, {
|
||||
const Button = styled(View, {
|
||||
name: 'ReactButton',
|
||||
tag: 'button',
|
||||
accessibilityRole: 'button',
|
||||
role: 'button',
|
||||
|
||||
cursor: 'pointer',
|
||||
userSelect: 'none',
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Children, cloneElement, forwardRef } from 'react'
|
|||
|
||||
import { Content, List, Root, Trigger } from '@radix-ui/react-tabs'
|
||||
import { Stack } from '@tamagui/web'
|
||||
import { Pressable } from 'react-native'
|
||||
import { View } from 'react-native'
|
||||
import { styled } from 'tamagui'
|
||||
|
||||
import { Counter } from '../counter'
|
||||
|
@ -12,7 +12,6 @@ import { Text } from '../text'
|
|||
import type { TextProps } from '../text'
|
||||
import type { GetVariants } from '../types'
|
||||
import type { Ref } from 'react'
|
||||
import type { View } from 'react-native'
|
||||
|
||||
type Variants = GetVariants<typeof TriggerBase>
|
||||
|
||||
|
@ -117,8 +116,9 @@ Tabs.Content = Content
|
|||
export { Tabs }
|
||||
export type { Props as TabsProps }
|
||||
|
||||
const TriggerBase = styled(Pressable, {
|
||||
tag: 'button',
|
||||
const TriggerBase = styled(View, {
|
||||
name: 'Trigger',
|
||||
role: 'button',
|
||||
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { createElement } from 'react'
|
||||
|
||||
import { Stack, styled } from '@tamagui/core'
|
||||
import { styled } from '@tamagui/core'
|
||||
import { View } from 'react-native'
|
||||
|
||||
import { Text } from '../text'
|
||||
import { getCustomStyles } from './get-custom-styles'
|
||||
|
@ -9,6 +10,7 @@ import type { TextProps } from '../text'
|
|||
import type { IconProps } from '@status-im/icons'
|
||||
import type { ColorTokens } from '@tamagui/core'
|
||||
import type { ComponentType } from 'react'
|
||||
import type { PressableProps } from 'react-native'
|
||||
|
||||
type Props = {
|
||||
size: 32 | 24
|
||||
|
@ -16,7 +18,7 @@ type Props = {
|
|||
label?: string
|
||||
selected?: boolean
|
||||
disabled?: boolean
|
||||
onPress?: () => void
|
||||
onPress?: PressableProps['onPress']
|
||||
color?: ColorTokens | `#${string}`
|
||||
}
|
||||
|
||||
|
@ -54,8 +56,11 @@ const Tag = (props: Props) => {
|
|||
selected={selected}
|
||||
disabled={disabled}
|
||||
iconOnly={Boolean(icon && !label)}
|
||||
onPress={() => onPress?.()}
|
||||
{...getCustomStyles(props)}
|
||||
{...(onPress && {
|
||||
role: 'button',
|
||||
onPress,
|
||||
})}
|
||||
>
|
||||
{renderIcon()}
|
||||
{label && (
|
||||
|
@ -70,11 +75,10 @@ const Tag = (props: Props) => {
|
|||
export { Tag }
|
||||
export type { Props as TagProps }
|
||||
|
||||
const Base = styled(Stack, {
|
||||
tag: 'tag',
|
||||
const Base = styled(View, {
|
||||
name: 'Tag',
|
||||
accessibilityRole: 'button',
|
||||
|
||||
userSelect: 'none',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
|
@ -85,7 +89,6 @@ const Base = styled(Stack, {
|
|||
backgroundColor: '$white-100',
|
||||
|
||||
animation: 'fast',
|
||||
cursor: 'pointer',
|
||||
|
||||
hoverStyle: {
|
||||
borderColor: '$neutral-30',
|
||||
|
|
|
@ -8,12 +8,12 @@ import type {
|
|||
import type { PressableProps as NativePressableProps } from 'react-native'
|
||||
|
||||
type PressableProps = {
|
||||
onHoverIn?: Exclude<NativePressableProps['onHoverIn'], null>
|
||||
onHoverOut?: NativePressableProps['onHoverOut']
|
||||
onPress?: NativePressableProps['onPress']
|
||||
onPressIn?: NativePressableProps['onPressIn']
|
||||
onPressOut?: NativePressableProps['onPressOut']
|
||||
onLongPress?: NativePressableProps['onLongPress']
|
||||
onHoverIn?: VoidFunction
|
||||
onHoverOut?: VoidFunction
|
||||
onPress?: VoidFunction
|
||||
onPressIn?: VoidFunction
|
||||
onPressOut?: VoidFunction
|
||||
onLongPress?: VoidFunction
|
||||
delayHoverIn?: NativePressableProps['delayHoverIn']
|
||||
delayHoverOut?: NativePressableProps['delayHoverOut']
|
||||
delayLongPress?: NativePressableProps['delayLongPress']
|
||||
|
|
Loading…
Reference in New Issue