Compare commits

..
Author SHA1 Message Date
marko 30b60ec408 test: this should skip steps
Signed-off-by: markoburcul <marko@status.im>
2024-10-17 12:13:03 +02:00
Marko Burčul 51d61895a4 jenkinsfile: revert check for changed files (#622)
Signed-off-by: markoburcul <marko@status.im>
2024-10-17 12:07:19 +02:00
Felicio Mununga 7f611bd199 Update README.md (#615) 2024-10-17 10:49:49 +02:00
github-actions[bot]andgithub-actions[bot] <github-actions[bot]@users.noreply.github.com> 1b05730c3d Release (#618)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-16 12:20:30 +02:00
pavel bf143681ff add type="account" to <ContextTag /> (#619)
* u

* Create lemon-houses-develop.md
2024-10-16 10:55:24 +02:00
marcelines e9979fdad2 fix <Button /> icon only colors (#616)
* f: adds compound variants for missing cases

* f: changeset
2024-10-15 21:50:24 +02:00
Marko Burčul f1fa827d42 jenkinsfile: filter stage execution based on path (#613)
Signed-off-by: markoburcul <marko@status.im>
2024-10-11 16:55:32 +02:00
github-actions[bot]andgithub-actions[bot] <github-actions[bot]@users.noreply.github.com> b7be3d762b Release (#610)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-11 14:19:49 +02:00
pavel 7f21132f0c fix <Shortcut /> (#609)
* f

* f

* Create early-apes-judge.md
2024-10-11 13:32:32 +02:00
github-actions[bot]andgithub-actions[bot] <github-actions[bot]@users.noreply.github.com> d48508b162 Release (#606)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-11 11:43:43 +02:00
Felicio Mununga 3ad28eaeb6 chore: add changeset (#605) 2024-10-11 11:36:10 +02:00
Felicio Mununga a87d6260d7 chore: Remove flex-1 class from button component (#602) 2024-10-11 11:26:30 +02:00
Marko Burčul 6286027559 jenkinsfile: fix paths for all steps (#597)
* jenkinsfile: fix paths for all steps

Use newest jenkins lib tag which adds the entryPoint as an argument to the nix shell function.

Referenced issue: https://github.com/status-im/status-web/issues/590

Signed-off-by: markoburcul <marko@status.im>
2024-10-10 17:47:34 +02:00
github-actions[bot]andgithub-actions[bot] <github-actions[bot]@users.noreply.github.com> 6bf4d487f3 Release (#599)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-10 16:15:51 +02:00
pavel a3f9252b90 fix blur button icon color (#598)
* add

* f

* f

* Create serious-carpets-promise.md
2024-10-10 16:04:16 +02:00
github-actions[bot]andgithub-actions[bot] <github-actions[bot]@users.noreply.github.com> aeee77e9b8 Release (#596)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-10 12:40:35 +02:00
Felicio Mununga 8f1980eaa7 Update tailwind.config.ts (#595)
* Update tailwind.config.ts

* Update tailwind.config.ts

* Create poor-coats-behave.md
2024-10-10 12:32:11 +02:00
github-actions[bot]andgithub-actions[bot] <github-actions[bot]@users.noreply.github.com> 8cf67b1419 Release (#593)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-10 07:25:34 +02:00
Jakub Kotula 15c9640ae1 Switch icon button from aria button to regular button (#592)
* f icon button

* f press

* Create hungry-bulldogs-glow.md

* f type

* f types
2024-10-09 17:49:16 +02:00
github-actions[bot]andgithub-actions[bot] <github-actions[bot]@users.noreply.github.com> a0a107126b Release (#585)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-04 22:03:43 +02:00
Jakub Kotula 4e53b3e6ef Fix tag and tabs (#584) 2024-10-03 22:27:25 +02:00
006d57f7d1 add apps/connector (#589)
* add `apps/connector`

---------

Co-authored-by: Jakub Kotula <520927+jkbktl@users.noreply.github.com>
Co-authored-by: Felicio Mununga <felicio@users.noreply.github.com>
Co-authored-by: pavel <14926950+prichodko@users.noreply.github.com>
Co-authored-by: marcelines <marcio@status.im>
2024-10-03 12:06:54 +02:00
23 changed files with 391 additions and 131 deletions
-5
View File
@@ -1,5 +0,0 @@
---
"@status-im/components": patch
---
fix `<DropdowMenu.SubTrigger />` expanded state
-5
View File
@@ -1,5 +0,0 @@
---
"@status-im/components": patch
---
add `<DropdownMenu.Label />`
-5
View File
@@ -1,5 +0,0 @@
---
"@status-im/components": patch
---
add dark grey dropdown button
-5
View File
@@ -1,5 +0,0 @@
---
"@status-im/components": patch
---
fix `<Button />` text alignment
-5
View File
@@ -1,5 +0,0 @@
---
"@status-im/components": patch
---
Add `<Switch />` and `<DropdownMenu.SwitchItem />`
+2 -6
View File
@@ -9,10 +9,6 @@
],
"tailwindCSS.experimental.classRegex": [
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"],
"clsx\\(([^)]*)\\)"
],
"files.associations": {
"*.css": "tailwindcss"
}
["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
]
}
+8 -8
View File
@@ -6,16 +6,16 @@ This monorepo contains packages for building web applications in the Status ecos
## Packages
| Name | `npm` | Description |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`@status-im/components`](./packages/components) | [![npm version](https://img.shields.io/npm/v/@status-im/components)](https://www.npmjs.com/package/@status-im/components) | Component library built with Radix UI, React Aria, Tailwind CSS. |
| [`@status-im/js`](./packages/status-js) | [![npm version](https://img.shields.io/npm/v/@status-im/js)](https://www.npmjs.com/package/@status-im/js) | Libary for Waku protocol integration and blockchain interactions. |
| [`@status-im/icons`](./packages/icons) | [![npm version](https://img.shields.io/npm/v/@status-im/icons)](https://www.npmjs.com/package/@status-im/icons) | Auto-generated icon library based on our [design system](https://www.figma.com/design/qLLuMLfpGxK9OfpIavwsmK/Iconset?node-id=3239-987&node-type=frame&t=0h8iIiZ3Sf0g4MRV-11). |
| [`@status-im/colors`](./packages/colors) | [![npm version](https://img.shields.io/npm/v/@status-im/colors.svg)](https://www.npmjs.com/package/@status-im/colors) | Auto-generated color palette based on our [design system](https://www.figma.com/design/v98g9ZiaSHYUdKWrbFg9eM/Foundations?node-id=619-5995&node-type=canvas&m=dev). |
| [`@status-im/eslint-config`](./packages/eslint-config) | | Shared ESLint configuration for consistent code style across projects. |
| Name | `npm` | Description |
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`@status-im/components`](./packages/components) | [![npm version](https://img.shields.io/npm/v/@status-im/components)](https://www.npmjs.com/package/@status-im/components) | Component library built with Radix UI, React Aria, Tailwind CSS. |
| [`@status-im/js`](./packages/status-js) | [![npm version](https://img.shields.io/npm/v/@status-im/js)](https://www.npmjs.com/package/@status-im/js) | Libary for Waku protocol integration and blockchain interactions. |
| [`@status-im/icons`](./packages/icons) | [![npm version](https://img.shields.io/npm/v/@status-im/icons)](https://www.npmjs.com/package/@status-im/icons) | Auto-generated icon library based on our [design system](https://www.figma.com/design/qLLuMLfpGxK9OfpIavwsmK/Iconset?node-id=3239-987&node-type=frame&t=0h8iIiZ3Sf0g4MRV-11). |
| [`@status-im/colors`](./packages/colors) | [![npm version](https://img.shields.io/npm/v/@status-im/colors.svg)](https://www.npmjs.com/package/@status-im/colors) | Auto-generated color palette based on our [design system](https://www.figma.com/design/v98g9ZiaSHYUdKWrbFg9eM/Foundations?node-id=619-5995&node-type=canvas&m=dev). |
| [`@status-im/eslint-config`](./packages/eslint-config) | [![npm version](https://img.shields.io/npm/v/@status-im/eslint-config.svg)](https://www.npmjs.com/package/@status-im/eslint-config) | Shared ESLint configuration for consistent code style across projects. |
## Apps
test
| Name | Description |
| -------------------------------------- | ----------------------------------------------------------------------------- |
| [`./apps/connector`](./apps/connector) | Status Desktop Wallet extended to decentralised applications in your browser. |
+85 -21
View File
@@ -1,5 +1,7 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.9.11'
def changesDetected = false
pipeline {
agent { label 'linux' }
@@ -27,47 +29,109 @@ pipeline {
}
stages {
stage('Check Changed Files') {
when {
changeset pattern: "apps/connector/**", comparator: "GLOB"
}
steps {
script {
changesDetected = true
}
}
}
stage('Install') {
steps { script {
nix.shell('yarn install --frozen-lockfile', pure: false)
} }
when {
expression { changesDetected }
}
steps {
dir("${env.WORKSPACE}/apps/connector") {
script {
nix.shell(
'yarn install --frozen-lockfile',
pure: false,
entryPoint: "${env.WORKSPACE}/apps/connector/shell.nix"
)
}
}
}
}
stage('Build') {
steps { script {
nix.shell('yarn build:chrome', pure: false)
} }
when {
expression { changesDetected }
}
steps {
dir("${env.WORKSPACE}/apps/connector") {
script {
nix.shell(
'yarn build:chrome',
pure: false,
entryPoint: "${env.WORKSPACE}/apps/connector/shell.nix"
)
}
}
}
}
stage('Zip') {
when {
expression { changesDetected }
}
steps {
zip(
zipFile: env.ZIP_NAME,
dir: 'build/chrome-mv3-prod',
archive: false,
)
dir("${env.WORKSPACE}/apps/connector") {
zip(
zipFile: env.ZIP_NAME,
dir: 'build/chrome-mv3-prod',
archive: false,
)
}
}
}
stage('Archive') {
when {
expression { changesDetected }
}
steps {
archiveArtifacts(
artifacts: env.ZIP_NAME,
fingerprint: true,
)
dir("${env.WORKSPACE}/apps/connector") {
archiveArtifacts(
artifacts: env.ZIP_NAME,
fingerprint: true,
)
}
}
}
stage('Upload') {
steps { script {
env.PKG_URL = s5cmd.upload(env.ZIP_NAME)
} }
when {
expression { changesDetected }
}
steps {
dir("${env.WORKSPACE}/apps/connector") {
script {
env.PKG_URL = s5cmd.upload(env.ZIP_NAME)
}
}
}
}
}
post {
success { script { github.notifyPR(true) } }
failure { script { github.notifyPR(false) } }
success {
script {
if(changesDetected) {
github.notifyPR(true)
}
}
}
failure {
script {
if(changesDetected) {
github.notifyPR(false)
}
}
}
cleanup { cleanWs() }
}
}
+3 -2
View File
@@ -1,11 +1,12 @@
{
"name": "status-browser-extension",
"name": "connector",
"version": "0.0.1",
"license": "MPL-2.0",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/status-im/status-browser-extension.git"
"url": "https://github.com/status-im/status-web.git",
"directory": "apps/connector"
},
"scripts": {
"dev:chrome": "plasmo dev --target=chrome-mv3",
+48
View File
@@ -1,5 +1,53 @@
# @status-im/components
## 1.0.7
### Patch Changes
- e9979fd: updates icon color for missing compound variants
- bf14368: add `type="account"` to `<ContextTag />`
## 1.0.6
### Patch Changes
- 7f21132: fix `<Shortcut />`icon prop and symbol centering
## 1.0.5
### Patch Changes
- 3ad28ea: chore: Remove flex-1 class from button component (#602)
## 1.0.4
### Patch Changes
- a3f9252: fix `<Button />` icon color for blur variant
## 1.0.3
### Patch Changes
- 8f1980e: Update fontSize in tailwind.config.ts
## 1.0.2
### Patch Changes
- 15c9640: Switch icon button from aria button to regular button
## 1.0.1
### Patch Changes
- 447cce7: fix `<DropdowMenu.SubTrigger />` expanded state
- 1ce026c: add `<DropdownMenu.Label />`
- 4e53b3e: Fix tag and tabs
- 273db4e: add dark grey dropdown button
- 4452f05: fix `<Button />` text alignment
- 433558a: Add `<Switch />` and `<DropdownMenu.SwitchItem />`
## 1.0.0
### Major Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@status-im/components",
"version": "1.0.0",
"version": "1.0.7",
"license": "MPL-2.0",
"sideEffects": [
"*.css"
@@ -1,3 +1,7 @@
import { Fragment } from 'react'
import { PlaceholderIcon } from '@status-im/icons/20'
import { Button } from './button'
import type { Meta, StoryObj } from '@storybook/react'
@@ -51,7 +55,22 @@ const meta: Meta<
).map(variant => (
<div key={variant} className="flex items-center gap-4">
{(['40', '32', '24'] as const).map(size => (
<Button key={size} {...args} variant={variant} size={size} />
<Fragment key={size}>
<Button {...args} variant={variant} size={size} />
{/* With icon */}
<Button
{...args}
size={size}
variant={variant}
iconBefore={<PlaceholderIcon />}
/>
<Button
aria-label="Button with icon only"
size={size}
variant={variant}
icon={<PlaceholderIcon />}
/>
</Fragment>
))}
</div>
))}
+38 -6
View File
@@ -14,7 +14,7 @@ type Variants = VariantProps<typeof styles>
type Props = {
size?: Variants['size']
variant?: Variants['variant']
onPress?: () => void
onPress?: (event: React.MouseEvent<HTMLButtonElement>) => void
} & (
| {
children: React.ReactNode
@@ -76,7 +76,7 @@ function Button(
{iconBefore}
</span>
)}
<span className="flex-1 whitespace-nowrap">{children}</span>
<span className="whitespace-nowrap">{children}</span>
{iconAfter && (
<span className={iconStyles({ size, placement: 'after', variant })}>
{iconAfter}
@@ -143,16 +143,18 @@ const iconStyles = cva({
variant: {
primary: ['text-blur-white/70'],
positive: ['text-blur-white/70'],
grey: ['text-neutral-50'],
darkGrey: [
grey: [
'text-neutral-50',
'blur:text-neutral-80/40',
'dark:text-neutral-40',
'blur:dark:text-neutral-80/40',
'blur:dark:text-white-40',
],
darkGrey: ['text-neutral-40'],
outline: [
'text-neutral-50',
'blur:text-neutral-80/40',
'dark:text-neutral-40',
'blur:dark:text-neutral-80/40',
'blur:dark:text-white-40',
],
ghost: ['text-neutral-50'],
danger: ['text-blur-white/70'],
@@ -191,11 +193,41 @@ const iconStyles = cva({
placement: 'after',
className: '-mr-0.5',
},
{
variant: 'grey',
iconOnly: true,
className: '!text-neutral-100 dark:!text-white-100',
},
{
variant: 'outline',
iconOnly: true,
className: '!text-neutral-100 dark:!text-white-100',
},
{
variant: 'darkGrey',
iconOnly: true,
className: '!text-neutral-100 dark:!text-white-100',
},
{
variant: 'ghost',
iconOnly: true,
className: '!text-neutral-100 dark:!text-white-100',
},
{
variant: 'primary',
iconOnly: true,
className: '!text-white-100',
},
{
variant: 'positive',
iconOnly: true,
className: '!text-white-100',
},
{
variant: 'danger',
iconOnly: true,
className: '!text-white-100',
},
],
})
@@ -45,6 +45,7 @@ const ContextTagVariant = (props: Props) => {
/>
}
/>
<ContextTag {...props} type="account" label="Account name" emoji="🐷" />
<ContextTag
{...props}
type="icon"
@@ -3,6 +3,8 @@ import { cloneElement, forwardRef } from 'react'
import { cva, cx } from 'cva'
import { match } from 'ts-pattern'
import { Avatar } from '../avatar'
import type { IconElement } from '../types'
import type { VariantProps } from 'cva'
@@ -15,10 +17,10 @@ type Props = {
| { type: 'community'; label: string; icon: IconElement }
| { type: 'token'; label: string; icon: IconElement }
| { type: 'network'; label: string; icon: IconElement }
| { type: 'account'; label: string; emoji: string }
| { type: 'icon'; label: string; icon: IconElement }
)
// | { type: 'user'; user: { name: string; src: string } }
// | { type: 'account'; account: { name: string; emoji: string } }
// | {
// type: 'group'
// group: {
@@ -36,7 +38,7 @@ type Props = {
const baseStyles = cva({
base: [
'inline-flex w-fit cursor-default items-center rounded-full',
'inline-flex w-fit cursor-default items-center',
'font-medium text-neutral-100 dark:text-white-100',
'bg-neutral-10 blur:bg-neutral-80/5 dark:bg-neutral-90 blur:dark:bg-white-5',
],
@@ -50,6 +52,13 @@ const baseStyles = cva({
selected: {
true: 'border border-customisation-50',
},
rounded: {
'8': 'rounded-8',
full: 'rounded-full',
},
},
defaultVariants: {
rounded: 'full',
},
})
@@ -116,6 +125,23 @@ const ContextTag = (props: Props, ref: React.Ref<HTMLDivElement>) => {
</div>
)
})
.with({ type: 'account' }, ({ label, emoji }) => {
return (
<div {...rest} ref={ref} className={baseStyles({ size, rounded: '8' })}>
<span className={iconStyles({ size, rounded: '6', offset: size })}>
<Avatar
type="account"
size={match(size)
.with('32', () => '28' as const)
.otherwise(() => '20' as const)}
name={label}
emoji={emoji}
/>
</span>
<span>{label}</span>
</div>
)
})
.with({ type: 'icon' }, ({ icon, label }) => {
return (
<div {...rest} ref={ref} className={baseStyles({ size })}>
@@ -1,4 +1,5 @@
import { BoldIcon } from '@status-im/icons/20'
import { action } from '@storybook/addon-actions'
import { IconButton } from './icon-button'
@@ -10,7 +11,13 @@ const sizes = ['40', '32', '24'] as const
const renderVariant = (variant: string) => (props: any) => (
<div className="flex items-center gap-4">
{sizes.map(size => (
<IconButton {...props} key={size} variant={variant} icon={BoldIcon} />
<IconButton
{...props}
key={size}
variant={variant}
icon={<BoldIcon />}
onPress={action('press')}
/>
))}
</div>
)
@@ -19,7 +26,7 @@ const meta = {
component: IconButton,
title: 'Components/Icon Button',
args: {
isDisabled: false,
disabled: false,
},
parameters: {
@@ -3,27 +3,36 @@
import { forwardRef } from 'react'
import { cva } from 'cva'
import { Button as AriaButton } from 'react-aria-components'
import type { IconElement } from '../types'
import type { VariantProps } from 'cva'
import type { Ref } from 'react'
import type { ButtonProps as AriaButtonProps } from 'react-aria-components'
type Variants = VariantProps<typeof styles>
type Props = AriaButtonProps & {
type Props = {
variant?: Variants['variant']
icon: IconElement
onPress?: (event: React.MouseEvent<HTMLButtonElement>) => void
}
const IconButton = (props: Props, ref: Ref<HTMLButtonElement>) => {
const { variant = 'default', icon, ...buttonProps } = props
type ButtonProps = Omit<React.ComponentPropsWithoutRef<'button'>, 'children'>
const IconButton = (
props: Props & ButtonProps,
ref: Ref<HTMLButtonElement>,
) => {
const { variant = 'default', onPress: onClick, icon, ...buttonProps } = props
return (
<AriaButton {...buttonProps} ref={ref} className={styles({ variant })}>
<button
{...buttonProps}
onClick={onClick}
ref={ref}
className={styles({ variant })}
>
{icon}
</AriaButton>
</button>
)
}
@@ -37,16 +46,16 @@ const styles = cva({
variants: {
variant: {
default: [
'border-transparent bg-neutral-10 text-neutral-50 hover:bg-neutral-20 pressed:border-neutral-20 pressed:bg-neutral-10 pressed:text-neutral-100',
'dark:bg-neutral-90 dark:text-neutral-40 dark:hover:bg-neutral-80 dark:pressed:border-neutral-60 dark:pressed:bg-neutral-80/70 dark:pressed:text-white-100',
'border-transparent bg-neutral-10 text-neutral-50 active:border-neutral-20 active:bg-neutral-10 active:text-neutral-100 hover:bg-neutral-20',
'dark:bg-neutral-90 dark:text-neutral-40 dark:active:border-neutral-60 dark:active:bg-neutral-80/70 dark:active:text-white-100 dark:hover:bg-neutral-80',
],
outline: [
'border-neutral-30 text-neutral-50 hover:border-neutral-40 pressed:border-neutral-20 pressed:bg-neutral-10 pressed:text-neutral-100',
'dark:border-neutral-70 dark:text-neutral-40 dark:hover:bg-neutral-60 dark:pressed:border-neutral-60 dark:pressed:bg-neutral-80/70 dark:pressed:text-white-100',
'border-neutral-30 text-neutral-50 active:border-neutral-20 active:bg-neutral-10 active:text-neutral-100 hover:border-neutral-40',
'dark:border-neutral-70 dark:text-neutral-40 dark:active:border-neutral-60 dark:active:bg-neutral-80/70 dark:active:text-white-100 dark:hover:bg-neutral-60',
],
ghost: [
'border-transparent text-neutral-50 hover:bg-neutral-10 pressed:border-neutral-20 pressed:bg-neutral-10 pressed:text-neutral-100',
'dark:text-neutral-40 dark:hover:bg-neutral-80/70 dark:pressed:border-neutral-60 dark:pressed:bg-neutral-80/70 dark:pressed:text-white-100',
'border-transparent text-neutral-50 active:border-neutral-20 active:bg-neutral-10 active:text-neutral-100 hover:bg-neutral-10',
'dark:text-neutral-40 dark:active:border-neutral-60 dark:active:bg-neutral-80/70 dark:active:text-white-100 dark:hover:bg-neutral-80/70',
],
},
},
@@ -9,7 +9,7 @@ const variants = ['primary', 'secondary', 'gray'] as const
// eslint-disable-next-line react/display-name
const renderVariant = (variant: (typeof variants)[number]) => (props: any) => (
<div className="flex items-center gap-2">
<Shortcut {...props} variant={variant} icon={CommandIcon} />
<Shortcut {...props} variant={variant} icon={<CommandIcon />} />
<Shortcut {...props} variant={variant} symbol="K" />
</div>
)
@@ -1,13 +1,14 @@
import { forwardRef } from 'react'
import { cloneElement, forwardRef } from 'react'
import { match, P } from 'ts-pattern'
import { cva } from '../utils/variants'
import type { IconElement } from '../types'
import type { VariantProps } from '../utils/variants'
const styles = cva({
base: 'flex size-4 flex-shrink-0 items-center justify-center rounded-6 border',
base: 'grid size-4 flex-shrink-0 place-items-center rounded-6 border',
variants: {
variant: {
primary: [
@@ -32,7 +33,7 @@ const styles = cva({
type Props = VariantProps<typeof styles> &
(
| {
icon: React.ComponentType<React.SVGProps<SVGSVGElement>>
icon: IconElement
symbol?: never
}
| {
@@ -42,15 +43,17 @@ type Props = VariantProps<typeof styles> &
)
const Shortcut = (props: Props, ref: React.Ref<HTMLDivElement>) => {
const { variant = 'primary', ...rest } = props
const { variant = 'primary' } = props
return (
<div className={styles({ variant })} ref={ref} {...rest}>
<div className={styles({ variant })} ref={ref}>
{match(props)
.with({ symbol: P.string }, ({ symbol }) => (
<span className="text-11 font-medium">{symbol}</span>
))
.with({ icon: P._ }, ({ icon: Icon }) => <Icon className="size-3" />)
.with({ icon: P._ }, ({ icon }) =>
cloneElement(icon, { className: 'size-3' }),
)
.exhaustive()}
</div>
)
+1 -1
View File
@@ -101,7 +101,7 @@ Trigger.displayName = Tabs.Trigger.displayName
const tabStyles = cva({
base: [
'group inline-flex items-center gap-1 whitespace-nowrap',
'disabled:pointer-events-none disabled:opacity-[.3]',
'disabled:opacity-[.3]',
],
variants: {
variant: {
+8 -6
View File
@@ -1,15 +1,17 @@
import { PlaceholderIcon } from '@status-im/icons/20'
import { action } from '@storybook/addon-actions'
import { Tag } from './tag'
import type { Meta, StoryObj } from '@storybook/react'
const meta = {
const meta: Meta<typeof Tag> = {
component: Tag,
title: 'Components/Tag',
args: {
label: 'Tag',
disabled: false,
selected: false,
icon: <PlaceholderIcon />,
iconPlacement: 'left',
},
@@ -24,17 +26,17 @@ const meta = {
render: props => (
<div className="flex flex-col items-start gap-4">
<Tag {...props} />
<Tag {...props} selected />
<Tag {...props} disabled />
<Tag {...props} onPress={action('pressed')} selected />
<Tag {...props} onPress={action('pressed')} disabled />
<Tag {...props} size="24" />
<Tag {...props} size="24" selected />
<Tag {...props} size="24" disabled />
<Tag {...props} size="24" onPress={action('pressed')} selected />
<Tag {...props} size="24" onPress={action('pressed')} disabled />
<Tag {...props} icon={undefined} />
<Tag {...props} label={undefined} />
<Tag {...props} iconPlacement="right" />
</div>
),
} satisfies Meta<typeof Tag>
}
type Story = StoryObj<typeof Tag>
+51 -22
View File
@@ -8,52 +8,83 @@ import type { Ref } from 'react'
type Variants = VariantProps<typeof styles>
type Props = React.ComponentProps<'button'> & {
type Props = {
size?: Variants['size']
label?: string
icon?: IconElement
iconPlacement?: 'left' | 'right'
selected?: boolean
onPress?: () => void
}
const Tag = (props: Props, ref: Ref<HTMLButtonElement>) => {
type ButtonProps = {
onPress: (event: React.MouseEvent<HTMLButtonElement>) => void
selected?: boolean
disabled?: boolean
} & Omit<React.ComponentPropsWithoutRef<'button'>, 'children'>
type DivProps = Omit<React.ComponentPropsWithoutRef<'div'>, 'children'>
function Tag(
props: Props & (ButtonProps | DivProps),
ref: Ref<HTMLButtonElement | HTMLDivElement>,
) {
const {
size = '32',
icon,
iconPlacement = 'left',
label,
selected = false,
disabled = false,
onPress: onClick,
...buttonProps
...rest
} = props
const iconOnly = Boolean(icon && !label)
return (
<button
onClick={onClick}
{...buttonProps}
disabled={disabled}
ref={ref}
data-selected={selected}
className={styles({ size, selected, disabled, iconOnly })}
>
const content = (
<>
{icon && iconPlacement === 'left' && (
<span className={iconStyles({ size, placement: 'left', iconOnly })}>
{cloneElement(icon)}
</span>
)}
{label && <span className="flex-1 whitespace-nowrap">{label}</span>}
{icon && iconPlacement === 'right' && (
<span className={iconStyles({ size, placement: 'right', iconOnly })}>
{cloneElement(icon)}
</span>
)}
</button>
</>
)
if ('onPress' in props) {
const { selected, disabled, ...buttonProps } = props as ButtonProps
return (
<button
{...buttonProps}
onClick={props.onPress}
ref={ref as Ref<HTMLButtonElement>}
data-selected={selected ? selected : undefined}
className={styles({
size,
selected,
disabled,
iconOnly,
})}
>
{content}
</button>
)
}
return (
<div
{...(rest as DivProps)}
ref={ref as Ref<HTMLDivElement>}
className={styles({
size,
iconOnly,
})}
>
{content}
</div>
)
}
@@ -62,8 +93,6 @@ const styles = cva({
'inline-flex shrink-0 items-center justify-center gap-1 border border-neutral-20 font-medium transition-all hover:border-neutral-30',
'outline-none focus:outline-none focus-visible:ring-2 focus-visible:ring-customisation-50 focus-visible:ring-offset-2',
'disabled:cursor-default disabled:opacity-[.3]',
// dark
'dark:border-neutral-80 dark:text-white-100 dark:hover:border-neutral-60',
],
variants: {
+56 -8
View File
@@ -34,14 +34,62 @@ export default {
},
fontSize: {
88: ['5.5rem', { lineHeight: '5.25rem', letterSpacing: '-0.1155rem' }],
64: ['4rem', { lineHeight: '4.25rem', letterSpacing: '-0.08rem' }],
40: ['2.5rem', { lineHeight: '2.75rem', letterSpacing: '-0.05rem' }],
27: ['1.6875rem', { lineHeight: '2rem', letterSpacing: '0rem' }],
19: ['1.1875rem', { lineHeight: '1.75rem', letterSpacing: '0rem' }],
15: ['0.9375rem', { lineHeight: '1.36rem', letterSpacing: '0rem' }],
13: ['0.8125rem', { lineHeight: '1.1375rem', letterSpacing: '0rem' }],
11: ['0.6875rem', { lineHeight: '1', letterSpacing: '0rem' }],
88: [
'5.5rem',
{
lineHeight: '5.25rem',
letterSpacing: '-0.1155rem',
},
],
64: [
'4rem',
{
lineHeight: '4.25rem',
letterSpacing: '-0.08rem',
},
],
40: [
'2.5rem',
{
lineHeight: '2.75rem',
letterSpacing: '-0.05rem',
},
],
27: [
'1.6875rem',
{
lineHeight: '2rem',
letterSpacing: '-0.0354375rem',
},
],
19: [
'1.1875rem',
{
lineHeight: '1.75rem',
letterSpacing: '-0.019rem',
},
],
15: [
'0.9375rem',
{
lineHeight: '1.359375rem',
letterSpacing: '-0.0084375rem',
},
],
13: [
'0.8125rem',
{
lineHeight: '1.1375rem',
letterSpacing: '-0.0024375rem',
},
],
11: [
'0.6875rem',
{
lineHeight: '0.97625rem',
letterSpacing: '-0.0034375rem',
},
],
},
opacity: {},