chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-button
|
||||
position: relative
|
||||
display: inline-block
|
||||
font-size: var(--a-font-size-md)
|
||||
line-height: var(--a-line-height-md)
|
||||
font-weight: var(--a-font-weight-semi-bold)
|
||||
border-radius: var(--a-border-radius-md)
|
||||
height: var(--a-button-size-md)
|
||||
border: none
|
||||
cursor: pointer
|
||||
padding: 0 var(--a-space-lg)
|
||||
box-shadow: 0 0 10px 2px transparent
|
||||
transition: opacity var(--a-transition-duration-main) var(--a-transition-timing-main), transform var(--a-transition-duration-main), background-color var(--a-transition-duration-main) var(--a-transition-timing-main), border-color var(--a-transition-duration-main) var(--a-transition-timing-main), color var(--a-transition-duration-main) var(--a-transition-timing-main), box-shadow var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&:hover:not(&--disabled, &--loading)
|
||||
transform: scale3d(1.01, 1.01, 1.01)
|
||||
&:active:not(&--disabled, &--loading)
|
||||
transform: scale3d(.96, .96, .96)
|
||||
|
||||
&--primary
|
||||
color: var(--a-color-text)
|
||||
background-color: var(--a-color-accent)
|
||||
&:hover:not(.aurora-button--disabled, .aurora-button--loading)
|
||||
background-color: var(--a-color-accent-hover)
|
||||
|
||||
&--secondary
|
||||
background-color: transparent
|
||||
color: var(--a-color-accent)
|
||||
border: 1px solid var(--a-color-accent)
|
||||
&:hover:not(.aurora-button--disabled, .aurora-button--loading), &:hover:not(.aurora-button--disabled, .aurora-button--loading) .aurora-icon
|
||||
border-color: var(--a-color-accent-hover)
|
||||
color: var(--a-color-accent-hover)
|
||||
.aurora-icon
|
||||
color: var(--a-color-accent)
|
||||
|
||||
&--danger
|
||||
background-color: var(--a-color-background-danger)
|
||||
color: var(--a-color-text-danger)
|
||||
&:hover:not(.aurora-button--disabled, .aurora-button--loading)
|
||||
background-color: var(--a-color-danger-hover)
|
||||
|
||||
&--light
|
||||
background-color: transparent
|
||||
color: var(--a-color-accent)
|
||||
&:hover:not(.aurora-button--disabled, .aurora-button--loading), &:hover:not(.aurora-button--disabled, .aurora-button--loading) .aurora-icon
|
||||
color: var(--a-color-accent-hover)
|
||||
.aurora-icon
|
||||
color: var(--a-color-accent)
|
||||
|
||||
&--disabled
|
||||
opacity: var(--a-opacity-disabled)
|
||||
cursor: not-allowed
|
||||
|
||||
&--loading
|
||||
opacity: var(--a-opacity-disabled)
|
||||
cursor: wait
|
||||
|
||||
.aurora-loader
|
||||
&::before, &::after
|
||||
background-color: var(--a-color-white)
|
||||
@@ -0,0 +1,114 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
import { Flexbox, Icon, Loader } from '../..'
|
||||
|
||||
import './button.sass'
|
||||
|
||||
interface ButtonOnClickData {
|
||||
name: string | undefined
|
||||
value: string | number | undefined
|
||||
}
|
||||
|
||||
export interface ButtonProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children?: any
|
||||
// children?: React.ReactNode
|
||||
type?: 'button' | 'submit'
|
||||
iconName?: string
|
||||
iconPosition?: 'left' | 'right'
|
||||
secondary?: boolean
|
||||
danger?: boolean
|
||||
light?: boolean
|
||||
disabled?: boolean
|
||||
loading?: boolean
|
||||
name?: string
|
||||
value?: string | number | undefined
|
||||
onClick?: (data: ButtonOnClickData) => void
|
||||
}
|
||||
|
||||
export function Button({
|
||||
children,
|
||||
type = 'button',
|
||||
iconName,
|
||||
iconPosition = 'left',
|
||||
secondary,
|
||||
danger,
|
||||
light,
|
||||
disabled,
|
||||
loading,
|
||||
name,
|
||||
value,
|
||||
onClick
|
||||
}: ButtonProps) {
|
||||
let variant = 'primary'
|
||||
|
||||
if (secondary) {
|
||||
variant = 'secondary'
|
||||
} else if (danger) {
|
||||
variant = 'danger'
|
||||
} else if (light) {
|
||||
variant = 'light'
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
key={`aurora-button_${generateKeyId()}`}
|
||||
type={type}
|
||||
name={name}
|
||||
value={value}
|
||||
className={classNames('aurora-button', {
|
||||
'aurora-button--disabled': disabled,
|
||||
'aurora-button--loading': loading,
|
||||
[`aurora-button--${variant}`]: variant
|
||||
})}
|
||||
disabled={disabled || loading}
|
||||
onClick={(event) => {
|
||||
if (type !== 'button') {
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
const data = {
|
||||
name,
|
||||
value
|
||||
}
|
||||
|
||||
if (onClick) {
|
||||
onClick(data)
|
||||
}
|
||||
}}
|
||||
>
|
||||
{loading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<>
|
||||
{iconName && iconPosition === 'left' && (
|
||||
<Flexbox
|
||||
flexDirection="row"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
gap="xs"
|
||||
>
|
||||
<Icon iconName={iconName} type="line" />
|
||||
{children}
|
||||
</Flexbox>
|
||||
)}
|
||||
{iconName && iconPosition === 'right' && (
|
||||
<Flexbox
|
||||
flexDirection="row"
|
||||
justifyContent="center"
|
||||
alignItems="center"
|
||||
gap="xs"
|
||||
>
|
||||
{children}
|
||||
<Icon iconName={iconName} type="line" />
|
||||
</Flexbox>
|
||||
)}
|
||||
{!iconName && children}
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './button'
|
||||
@@ -0,0 +1,12 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-card
|
||||
position: relative
|
||||
display: inline-block
|
||||
width: auto
|
||||
padding: var(--a-space-md)
|
||||
background-color: var(--a-color-background-surface-secondary)
|
||||
border-radius: var(--a-border-radius-md)
|
||||
|
||||
&--full-width
|
||||
width: 100%
|
||||
@@ -0,0 +1,25 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './card.sass'
|
||||
|
||||
export interface CardProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
// children: React.ReactNode
|
||||
fullWidth?: boolean
|
||||
}
|
||||
|
||||
export function Card({ children, fullWidth }: CardProps) {
|
||||
return (
|
||||
<div
|
||||
key={`aurora-card_${generateKeyId()}`}
|
||||
className={classNames('aurora-card', {
|
||||
'aurora-card--full-width': fullWidth
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './card'
|
||||
@@ -0,0 +1,39 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-checkbox
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: var(--a-space-sm)
|
||||
cursor: pointer
|
||||
&[data-disabled]
|
||||
cursor: not-allowed
|
||||
|
||||
.aurora-checkbox-placeholder
|
||||
width: var(--a-checkbox-radio-size)
|
||||
height: var(--a-checkbox-radio-size)
|
||||
|
||||
.aurora-checkbox-control
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
width: var(--a-checkbox-radio-size)
|
||||
height: var(--a-checkbox-radio-size)
|
||||
border-radius: var(--a-border-radius-xs)
|
||||
border: 1px solid var(--a-color-input-border)
|
||||
background-color: var(--a-color-input-background)
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main), border-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
|
||||
&[data-hover]:not([data-state="checked"])
|
||||
border-color: var(--a-color-input-border-hover)
|
||||
background-color: var(--a-color-input-background-hover)
|
||||
&[data-state="checked"]
|
||||
border-color: transparent
|
||||
background-color: var(--a-color-input-border-focus)
|
||||
&[data-disabled]
|
||||
opacity: var(--a-opacity-disabled)
|
||||
|
||||
.aurora-checkbox-label
|
||||
color: var(--a-color-text)
|
||||
font-size: var(--a-font-size-md)
|
||||
&[data-disabled]
|
||||
opacity: var(--a-opacity-disabled)
|
||||
@@ -0,0 +1,74 @@
|
||||
import { useState } from 'react'
|
||||
import {
|
||||
Checkbox as ArkCheckbox,
|
||||
type CheckboxCheckedChangeDetails,
|
||||
type CheckboxRootProps as ArkCheckboxProps
|
||||
} from '@ark-ui/react/checkbox'
|
||||
|
||||
import { Icon } from '../icon'
|
||||
|
||||
import './checkbox.sass'
|
||||
|
||||
interface CheckboxOnChangeData {
|
||||
name: string
|
||||
value: string | undefined
|
||||
isChecked: boolean
|
||||
}
|
||||
|
||||
export interface CheckboxProps
|
||||
extends Pick<
|
||||
ArkCheckboxProps,
|
||||
'value' | 'checked' | 'disabled' | 'required'
|
||||
> {
|
||||
name: string
|
||||
label?: string
|
||||
onChange?: (data: CheckboxOnChangeData) => void
|
||||
}
|
||||
|
||||
export function Checkbox({
|
||||
name,
|
||||
label,
|
||||
checked,
|
||||
value,
|
||||
disabled,
|
||||
required,
|
||||
onChange
|
||||
}: CheckboxProps) {
|
||||
const [isChecked, setIsChecked] = useState(checked)
|
||||
|
||||
return (
|
||||
<ArkCheckbox.Root
|
||||
className="aurora-checkbox"
|
||||
name={name}
|
||||
value={value}
|
||||
checked={isChecked}
|
||||
disabled={disabled}
|
||||
required={required}
|
||||
onCheckedChange={(event: CheckboxCheckedChangeDetails) => {
|
||||
setIsChecked(event.checked as boolean)
|
||||
|
||||
const data = {
|
||||
name,
|
||||
value,
|
||||
isChecked: !!event.checked
|
||||
}
|
||||
|
||||
if (onChange) {
|
||||
onChange(data)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ArkCheckbox.HiddenInput />
|
||||
<ArkCheckbox.Control className="aurora-checkbox-control">
|
||||
{isChecked ? (
|
||||
<Icon iconName="check" size="sm" animated />
|
||||
) : (
|
||||
<div className="aurora-checkbox-placeholder" />
|
||||
)}
|
||||
</ArkCheckbox.Control>
|
||||
<ArkCheckbox.Label className="aurora-checkbox-label">
|
||||
{label}
|
||||
</ArkCheckbox.Label>
|
||||
</ArkCheckbox.Root>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './checkbox'
|
||||
@@ -0,0 +1,28 @@
|
||||
.aurora-circular-progress
|
||||
position: relative
|
||||
|
||||
&--sm
|
||||
width: 64px
|
||||
height: 64px
|
||||
&--md
|
||||
width: 128px
|
||||
height: 128px
|
||||
&--lg
|
||||
width: 256px
|
||||
height: 256px
|
||||
|
||||
path
|
||||
transition: stroke-dashoffset var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&:nth-child(1)
|
||||
stroke: var(--a-color-background-surface-secondary)
|
||||
stroke-width: 32px
|
||||
&:nth-child(2)
|
||||
stroke: var(--a-color-accent)
|
||||
stroke-width: 12px
|
||||
stroke-linecap: round
|
||||
|
||||
.aurora-circular-progress-content
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: 50%
|
||||
transform: translate(-50%, -50%)
|
||||
@@ -0,0 +1,41 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './circular-progress.sass'
|
||||
|
||||
export interface CircularProgressProps {
|
||||
value: number
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children?: any
|
||||
// children?: React.ReactNode
|
||||
size?: 'sm' | 'md' | 'lg'
|
||||
}
|
||||
|
||||
export function CircularProgress({
|
||||
value,
|
||||
children,
|
||||
size = 'md'
|
||||
}: CircularProgressProps) {
|
||||
const total = 100
|
||||
|
||||
return (
|
||||
<div
|
||||
key={`aurora-circular-progress_${generateKeyId()}`}
|
||||
className={classNames('aurora-circular-progress', {
|
||||
[`aurora-circular-progress--${size}`]: size
|
||||
})}
|
||||
>
|
||||
<svg viewBox="0 0 276 276" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M138 16C154.021 16 169.886 19.1556 184.687 25.2867C199.489 31.4178 212.938 40.4042 224.267 51.733C235.596 63.0617 244.582 76.5109 250.713 91.3126C256.844 106.114 260 121.979 260 138C260 154.021 256.844 169.886 250.713 184.687C244.582 199.489 235.596 212.938 224.267 224.267C212.938 235.596 199.489 244.582 184.687 250.713C169.886 256.844 154.021 260 138 260C121.979 260 106.114 256.844 91.3126 250.713C76.5109 244.582 63.0617 235.596 51.7329 224.267C40.4042 212.938 31.4177 199.489 25.2867 184.687C19.1556 169.886 16 154.021 16 138C16 121.979 19.1556 106.114 25.2867 91.3126C31.4178 76.5108 40.4043 63.0617 51.733 51.7329C63.0618 40.4042 76.511 31.4177 91.3127 25.2867C106.114 19.1556 121.979 16 138 16L138 16Z" />
|
||||
<path
|
||||
pathLength={total}
|
||||
strokeDasharray={total}
|
||||
strokeDashoffset={total - value}
|
||||
d="M138 16C154.021 16 169.886 19.1556 184.687 25.2867C199.489 31.4178 212.938 40.4042 224.267 51.733C235.596 63.0617 244.582 76.5109 250.713 91.3126C256.844 106.114 260 121.979 260 138C260 154.021 256.844 169.886 250.713 184.687C244.582 199.489 235.596 212.938 224.267 224.267C212.938 235.596 199.489 244.582 184.687 250.713C169.886 256.844 154.021 260 138 260C121.979 260 106.114 256.844 91.3126 250.713C76.5109 244.582 63.0617 235.596 51.7329 224.267C40.4042 212.938 31.4177 199.489 25.2867 184.687C19.1556 169.886 16 154.021 16 138C16 121.979 19.1556 106.114 25.2867 91.3126C31.4178 76.5108 40.4043 63.0617 51.733 51.7329C63.0618 40.4042 76.511 31.4177 91.3127 25.2867C106.114 19.1556 121.979 16 138 16L138 16Z"
|
||||
/>
|
||||
</svg>
|
||||
<div className="aurora-circular-progress-content">{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './circular-progress'
|
||||
@@ -0,0 +1,92 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-flexbox
|
||||
position: relative
|
||||
display: flex
|
||||
flex-direction: column
|
||||
height: 100%
|
||||
|
||||
&--padding
|
||||
padding: var(--a-space-xl) var(--a-space-md)
|
||||
&--padding-x
|
||||
padding-left: var(--a-space-md)
|
||||
padding-right: var(--a-space-md)
|
||||
&--padding-y
|
||||
padding-top: var(--a-space-xl)
|
||||
padding-bottom: var(--a-space-xl)
|
||||
|
||||
&--full-width
|
||||
width: 100%
|
||||
|
||||
&--flex
|
||||
display: flex
|
||||
&--inline-flex
|
||||
display: inline-flex
|
||||
|
||||
&--row
|
||||
flex-direction: row
|
||||
&--row-reverse
|
||||
flex-direction: row-reverse
|
||||
&--column
|
||||
flex-direction: column
|
||||
&--column-reverse
|
||||
flex-direction: column-reverse
|
||||
|
||||
&--align-flex-start
|
||||
align-items: flex-start
|
||||
&--align-center
|
||||
align-items: center
|
||||
&--align-flex-end
|
||||
align-items: flex-end
|
||||
&--align-stretch
|
||||
align-items: stretch
|
||||
&--align-baseline
|
||||
align-items: baseline
|
||||
|
||||
&--justify-flex-start
|
||||
justify-content: flex-start
|
||||
&--justify-center
|
||||
justify-content: center
|
||||
&--justify-flex-end
|
||||
justify-content: flex-end
|
||||
&--justify-space-between
|
||||
justify-content: space-between
|
||||
&--justify-space-around
|
||||
justify-content: space-around
|
||||
&--justify-space-evenly
|
||||
justify-content: space-evenly
|
||||
&--justify-stretch
|
||||
justify-content: stretch
|
||||
|
||||
&--gap-xs
|
||||
gap: var(--a-space-xs)
|
||||
&--gap-sm
|
||||
gap: var(--a-space-sm)
|
||||
&--gap-md
|
||||
gap: var(--a-space-md)
|
||||
&--gap-lg
|
||||
gap: var(--a-space-lg)
|
||||
&--gap-xl
|
||||
gap: var(--a-space-xl)
|
||||
|
||||
&--row-gap-xs
|
||||
row-gap: var(--a-space-xs)
|
||||
&--row-gap-sm
|
||||
row-gap: var(--a-space-sm)
|
||||
&--row-gap-md
|
||||
row-gap: var(--a-space-md)
|
||||
&--row-gap-lg
|
||||
row-gap: var(--a-space-lg)
|
||||
&--row-gap-xl
|
||||
row-gap: var(--a-space-xl)
|
||||
|
||||
&--column-gap-xs
|
||||
column-gap: var(--a-space-xs)
|
||||
&--column-gap-sm
|
||||
column-gap: var(--a-space-sm)
|
||||
&--column-gap-md
|
||||
column-gap: var(--a-space-md)
|
||||
&--column-gap-lg
|
||||
column-gap: var(--a-space-lg)
|
||||
&--column-gap-xl
|
||||
column-gap: var(--a-space-xl)
|
||||
@@ -0,0 +1,66 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { type Size } from '../../lib/types'
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './flexbox.sass'
|
||||
|
||||
export interface FlexboxProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
// children: React.ReactNode
|
||||
fullWidth?: boolean
|
||||
display?: 'flex' | 'inline-flex'
|
||||
alignItems?: 'center' | 'flex-start' | 'flex-end' | 'baseline' | 'stretch'
|
||||
justifyContent?:
|
||||
| 'center'
|
||||
| 'flex-start'
|
||||
| 'flex-end'
|
||||
| 'space-between'
|
||||
| 'space-around'
|
||||
| 'space-evenly'
|
||||
| 'stretch'
|
||||
flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse'
|
||||
gap?: Size
|
||||
rowGap?: Size
|
||||
columnGap?: Size
|
||||
padding?: boolean
|
||||
paddingX?: boolean
|
||||
paddingY?: boolean
|
||||
}
|
||||
|
||||
export function Flexbox({
|
||||
children,
|
||||
fullWidth,
|
||||
display,
|
||||
alignItems,
|
||||
justifyContent,
|
||||
flexDirection,
|
||||
gap,
|
||||
rowGap,
|
||||
columnGap,
|
||||
padding,
|
||||
paddingX,
|
||||
paddingY
|
||||
}: FlexboxProps) {
|
||||
return (
|
||||
<div
|
||||
key={`aurora-flexbox_${generateKeyId()}`}
|
||||
className={classNames('aurora-flexbox', {
|
||||
'aurora-flexbox--full-width': fullWidth,
|
||||
'aurora-flexbox--padding': padding,
|
||||
'aurora-flexbox--padding-x': paddingX,
|
||||
'aurora-flexbox--padding-y': paddingY,
|
||||
[`aurora-flexbox--${display}`]: display,
|
||||
[`aurora-flexbox--align-${alignItems}`]: alignItems,
|
||||
[`aurora-flexbox--justify-${justifyContent}`]: justifyContent,
|
||||
[`aurora-flexbox--${flexDirection}`]: flexDirection,
|
||||
[`aurora-flexbox--gap-${gap}`]: gap,
|
||||
[`aurora-flexbox--row-gap-${rowGap}`]: rowGap,
|
||||
[`aurora-flexbox--column-gap-${columnGap}`]: columnGap
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './flexbox'
|
||||
@@ -0,0 +1,4 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-form
|
||||
position: relative
|
||||
@@ -0,0 +1,51 @@
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './form.sass'
|
||||
|
||||
export interface FormProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children?: any
|
||||
// children?: React.ReactNode
|
||||
onSubmit: (data: Record<string, unknown>) => void
|
||||
}
|
||||
|
||||
export function Form({ children, onSubmit }: FormProps) {
|
||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault()
|
||||
|
||||
const form = event.currentTarget
|
||||
const formData = new FormData(form)
|
||||
const data: Record<string, unknown> = {}
|
||||
|
||||
for (const [key, value] of formData.entries()) {
|
||||
if (data[key] && key.endsWith('[]')) {
|
||||
if (Array.isArray(data[key])) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
;(data[key] as []).push(value)
|
||||
} else {
|
||||
data[key] = [data[key], value]
|
||||
}
|
||||
} else {
|
||||
if (key.endsWith('[]')) {
|
||||
data[key] = [value]
|
||||
} else {
|
||||
data[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit(data)
|
||||
}
|
||||
|
||||
return (
|
||||
<form
|
||||
autoComplete="off"
|
||||
className="aurora-form"
|
||||
onSubmit={handleSubmit}
|
||||
key={`aurora-form_${generateKeyId()}`}
|
||||
>
|
||||
{children}
|
||||
</form>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './form'
|
||||
@@ -0,0 +1,70 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-icon-button
|
||||
position: relative
|
||||
width: var(--a-button-size-md)
|
||||
height: var(--a-button-size-md)
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
padding: 0
|
||||
text-align: center
|
||||
&.aurora-button:hover:not(.aurora-button--disabled, .aurora-button--loading)
|
||||
transform: scale3d(1.03, 1.03, 1.03)
|
||||
&.aurora-button:active:not(.aurora-button--disabled, .aurora-button--loading)
|
||||
transform: scale3d(.96, .96, .96)
|
||||
&.aurora-button.aurora-button--light:hover:not(.aurora-button--disabled, .aurora-button--loading)
|
||||
transform: scale3d(1.06, 1.06, 1.06)
|
||||
&.aurora-button.aurora-button--light:active:not(.aurora-button--disabled, .aurora-button--loading)
|
||||
transform: scale3d(.96, .96, .96)
|
||||
|
||||
&--square
|
||||
width: var(--a-button-size-md)
|
||||
height: var(--a-button-size-md)
|
||||
border-radius: var(--a-border-radius-md)
|
||||
&--circle
|
||||
width: var(--a-button-size-md)
|
||||
height: var(--a-button-size-md)
|
||||
border-radius: 50%
|
||||
|
||||
&--xs
|
||||
width: 22px
|
||||
height: 22px
|
||||
&--sm
|
||||
width: 30px
|
||||
height: 30px
|
||||
&--md
|
||||
width: var(--a-button-size-md)
|
||||
height: var(--a-button-size-md)
|
||||
&--lg
|
||||
width: 56px
|
||||
height: 56px
|
||||
&--xl
|
||||
width: 96px
|
||||
height: 96px
|
||||
&--xxl
|
||||
width: 164px
|
||||
height: 164px
|
||||
|
||||
&.aurora-button--light .aurora-icon
|
||||
color: var(--a-color-text)
|
||||
|
||||
&.aurora-button--secondary:hover, &.aurora-button--light:hover
|
||||
background-color: transparent
|
||||
|
||||
|
||||
&.aurora-button--light:hover .aurora-icon
|
||||
color: var(--a-color-text)
|
||||
|
||||
&.aurora-button--light.aurora-button--secondary
|
||||
background-color: transparent
|
||||
border: none
|
||||
.aurora-icon
|
||||
color: var(--a-color-white-secondary)
|
||||
&:hover:not(.aurora-button--disabled, .aurora-button--loading) .aurora-icon
|
||||
color: var(--a-color-text)
|
||||
&:hover.aurora-icon-button--activated .aurora-icon
|
||||
color: var(--a-color-accent)
|
||||
|
||||
&.aurora-button--light.aurora-icon-button--activated .aurora-icon
|
||||
color: var(--a-color-accent)
|
||||
@@ -0,0 +1,113 @@
|
||||
import { useState } from 'react'
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { Icon, Loader } from '../..'
|
||||
import { type IconProps } from '../icon'
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './icon-button.sass'
|
||||
|
||||
interface IconButtonOnClickData {
|
||||
name: string | undefined
|
||||
value: string | number | undefined
|
||||
isActivated: boolean
|
||||
}
|
||||
|
||||
export interface IconButtonProps {
|
||||
iconName: string
|
||||
name?: string
|
||||
value?: string | number | undefined
|
||||
type?: 'button' | 'submit'
|
||||
iconType?: IconProps['type']
|
||||
size?: IconProps['size']
|
||||
shape?: IconProps['bgShape']
|
||||
activated?: boolean
|
||||
secondary?: boolean
|
||||
danger?: boolean
|
||||
light?: boolean
|
||||
disabled?: boolean
|
||||
loading?: boolean
|
||||
onClick?: (data: IconButtonOnClickData) => void
|
||||
}
|
||||
|
||||
export function IconButton({
|
||||
iconName,
|
||||
name,
|
||||
value,
|
||||
type = 'button',
|
||||
iconType = 'line',
|
||||
size,
|
||||
shape,
|
||||
activated,
|
||||
secondary,
|
||||
danger,
|
||||
light,
|
||||
disabled,
|
||||
loading,
|
||||
onClick
|
||||
}: IconButtonProps) {
|
||||
const [isActivated, setIsActivated] = useState(activated || false)
|
||||
|
||||
let variant = 'primary'
|
||||
|
||||
if (danger) {
|
||||
variant = 'danger'
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
key={`aurora-icon-button_${generateKeyId()}`}
|
||||
type={type}
|
||||
name={name}
|
||||
value={value}
|
||||
className={classNames('aurora-icon-button aurora-button', {
|
||||
'aurora-button--secondary': secondary,
|
||||
'aurora-button--light': light,
|
||||
'aurora-button--disabled': disabled,
|
||||
'aurora-button--loading': loading,
|
||||
'aurora-icon-button--activated': isActivated,
|
||||
[`aurora-button--${variant}`]: variant,
|
||||
[`aurora-icon-button--${size}`]: size,
|
||||
[`aurora-icon-button--${shape}`]: shape
|
||||
})}
|
||||
disabled={disabled || loading}
|
||||
onClick={(event) => {
|
||||
if (type !== 'button') {
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
if (onClick) {
|
||||
const data = {
|
||||
name,
|
||||
value
|
||||
}
|
||||
|
||||
if (typeof activated === 'undefined') {
|
||||
onClick({
|
||||
...data,
|
||||
isActivated: false
|
||||
})
|
||||
} else {
|
||||
const newActivatedState = !isActivated
|
||||
|
||||
setIsActivated(newActivatedState)
|
||||
onClick({
|
||||
...data,
|
||||
isActivated: newActivatedState
|
||||
})
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
{loading ? (
|
||||
<Loader />
|
||||
) : (
|
||||
<>
|
||||
<Icon type={iconType} iconName={iconName} size={size} />
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './icon-button'
|
||||
@@ -0,0 +1,115 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-icon
|
||||
position: relative
|
||||
display: inline-flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
border-radius: var(--a-border-radius-xs)
|
||||
color: var(--a-color-white)
|
||||
font-size: var(--a-font-size-md)
|
||||
background-color: transparent
|
||||
padding: var(--a-space-xs)
|
||||
transition: opacity var(--a-transition-duration-main) var(--a-transition-timing-main), color var(--a-transition-duration-main) var(--a-transition-timing-main), background-color var(--a-transition-duration-main) var(--a-transition-timing-main), transform var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
|
||||
&--animated
|
||||
opacity: 0
|
||||
animation: aurora-animation-fade-in var(--a-transition-duration-main) var(--a-transition-timing-main) var(--a-transition-duration-main) forwards
|
||||
|
||||
&--xs
|
||||
width: 12px
|
||||
height: 12px
|
||||
font-size: var(--a-font-size-xs)
|
||||
border-radius: var(--a-border-radius-xs)
|
||||
&--sm
|
||||
width: 20px
|
||||
height: 20px
|
||||
font-size: var(--a-font-size-sm)
|
||||
border-radius: var(--a-border-radius-xs)
|
||||
&--md
|
||||
width: 28px
|
||||
height: 28px
|
||||
font-size: var(--a-font-size-md)
|
||||
border-radius: var(--a-border-radius-xs)
|
||||
&--lg
|
||||
width: 56px
|
||||
height: 56px
|
||||
font-size: var(--a-font-size-lg)
|
||||
border-radius: var(--a-border-radius-md)
|
||||
&--xl
|
||||
width: 96px
|
||||
height: 96px
|
||||
font-size: var(--a-font-size-xl)
|
||||
border-radius: var(--a-border-radius-md)
|
||||
&--xxl
|
||||
width: 128px
|
||||
height: 128px
|
||||
font-size: var(--a-font-size-xxl)
|
||||
border-radius: var(--a-border-radius-md)
|
||||
|
||||
&--square
|
||||
border-radius: var(--a-border-radius-xs)
|
||||
&--circle
|
||||
border-radius: var(--a-border-radius-circle)
|
||||
|
||||
&--white
|
||||
color: var(--a-color-white)
|
||||
&--transparent-white
|
||||
color: var(--a-color-transparent-white)
|
||||
&--black
|
||||
color: var(--a-color-black)
|
||||
&--blue
|
||||
color: var(--a-color-blue)
|
||||
&--secondary-blue
|
||||
color: var(--a-color-secondary-blue)
|
||||
&--transparent-blue
|
||||
color: var(--a-color-transparent-blue)
|
||||
&--red
|
||||
color: var(--a-color-red)
|
||||
&--secondary-red
|
||||
color: var(--a-color-secondary-red)
|
||||
&--transparent-red
|
||||
color: var(--a-color-transparent-red)
|
||||
&--green
|
||||
color: var(--a-color-green)
|
||||
&--secondary-green
|
||||
color: var(--a-color-secondary-green)
|
||||
&--transparent-green
|
||||
color: var(--a-color-transparent-green)
|
||||
&--yellow
|
||||
color: var(--a-color-yellow)
|
||||
&--secondary-yellow
|
||||
color: var(--a-color-secondary-yellow)
|
||||
&--transparent-yellow
|
||||
color: var(--a-color-transparent-yellow)
|
||||
|
||||
&--bg-white
|
||||
background-color: var(--a-color-white)
|
||||
&--bg-transparent-white
|
||||
background-color: var(--a-color-transparent-white)
|
||||
&--bg-black
|
||||
background-color: var(--a-color-black)
|
||||
&--bg-blue
|
||||
background-color: var(--a-color-blue)
|
||||
&--bg-secondary-blue
|
||||
background-color: var(--a-color-secondary-blue)
|
||||
&--bg-transparent-blue
|
||||
background-color: var(--a-color-transparent-blue)
|
||||
&--bg-red
|
||||
background-color: var(--a-color-red)
|
||||
&--bg-secondary-red
|
||||
background-color: var(--a-color-secondary-red)
|
||||
&--bg-transparent-red
|
||||
background-color: var(--a-color-transparent-red)
|
||||
&--bg-green
|
||||
background-color: var(--a-color-green)
|
||||
&--bg-secondary-green
|
||||
background-color: var(--a-color-secondary-green)
|
||||
&--bg-transparent-green
|
||||
background-color: var(--a-color-transparent-green)
|
||||
&--bg-yellow
|
||||
background-color: var(--a-color-yellow)
|
||||
&--bg-secondary-yellow
|
||||
background-color: var(--a-color-secondary-yellow)
|
||||
&--bg-transparent-yellow
|
||||
background-color: var(--a-color-transparent-yellow)
|
||||
@@ -0,0 +1,75 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import type { Color, Size, IconType } from '../../lib/types'
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './icon.sass'
|
||||
|
||||
export interface IconProps {
|
||||
iconName?: string
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
svg?: any
|
||||
// svg?: React.ReactNode
|
||||
type?: IconType
|
||||
color?: Color
|
||||
size?: Size | 'xxl'
|
||||
bgShape?: 'square' | 'circle'
|
||||
bgColor?: Color
|
||||
animated?: boolean
|
||||
}
|
||||
|
||||
const REMIX_SIZE_MAPPING = {
|
||||
xs: 'xs',
|
||||
sm: 'sm',
|
||||
md: '1x',
|
||||
lg: 'lg',
|
||||
xl: 'xl',
|
||||
xxl: '2x'
|
||||
}
|
||||
const REMIX_ICON_TYPE_SUFFIXES = ['-line', '-fill']
|
||||
|
||||
/**
|
||||
* @see https://remixicon.com/
|
||||
*/
|
||||
export function Icon({
|
||||
iconName,
|
||||
svg,
|
||||
type = 'line',
|
||||
color,
|
||||
size = 'md',
|
||||
bgShape,
|
||||
bgColor,
|
||||
animated
|
||||
}: IconProps) {
|
||||
let iconClassName = `ri-${iconName}`
|
||||
const hasExplicitTypeSuffix = REMIX_ICON_TYPE_SUFFIXES.some((suffix) =>
|
||||
iconName?.endsWith(suffix)
|
||||
)
|
||||
|
||||
if (type && type !== 'notype' && !hasExplicitTypeSuffix) {
|
||||
iconClassName = `${iconClassName}-${type}`
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
key={`aurora-icon_${generateKeyId()}`}
|
||||
className={classNames('aurora-icon', {
|
||||
[`aurora-icon--${size}`]: size,
|
||||
[`aurora-icon--${bgShape}`]: bgShape,
|
||||
[`aurora-icon--bg-${bgColor}`]: bgColor,
|
||||
[`aurora-icon--${color}`]: color,
|
||||
'aurora-icon--animated': animated
|
||||
})}
|
||||
>
|
||||
{svg ? (
|
||||
svg
|
||||
) : (
|
||||
<i
|
||||
className={classNames(iconClassName, {
|
||||
[`ri-${REMIX_SIZE_MAPPING[size]}`]: size
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './icon'
|
||||
@@ -0,0 +1,76 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-image
|
||||
position: relative
|
||||
border-radius: var(--a-border-radius-md)
|
||||
background-repeat: no-repeat
|
||||
background-size: cover
|
||||
background-position: center center
|
||||
|
||||
&--overlay
|
||||
&::before
|
||||
content: ''
|
||||
position: absolute
|
||||
width: 100%
|
||||
height: 100%
|
||||
background-color: rgba(0, 0, 0, .2)
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&:hover
|
||||
&::before
|
||||
background-color: rgba(0, 0, 0, 0)
|
||||
|
||||
&--gradient
|
||||
&::after
|
||||
content: ''
|
||||
position: absolute
|
||||
top: auto
|
||||
bottom: 0
|
||||
width: 100%
|
||||
height: 64px
|
||||
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--a-color-background-surface))
|
||||
&--gradient-top
|
||||
&::after
|
||||
top: 0
|
||||
bottom: auto
|
||||
background-image: linear-gradient(to top, rgba(0, 0, 0, 0), var(--a-color-background-surface))
|
||||
&--gradient-bottom
|
||||
&::after
|
||||
top: auto
|
||||
bottom: 0
|
||||
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), var(--a-color-background-surface))
|
||||
&--gradient-left
|
||||
&::after
|
||||
left: 0
|
||||
top: 0
|
||||
bottom: 0
|
||||
width: 64px
|
||||
height: 100%
|
||||
background-image: linear-gradient(to left, rgba(0, 0, 0, 0), var(--a-color-background-surface))
|
||||
&--gradient-right
|
||||
&::after
|
||||
right: 0
|
||||
top: 0
|
||||
bottom: 0
|
||||
width: 64px
|
||||
height: 100%
|
||||
background-image: linear-gradient(to right, rgba(0, 0, 0, 0), var(--a-color-background-surface))
|
||||
|
||||
&--cover
|
||||
background-size: cover
|
||||
&--contain
|
||||
background-size: contain
|
||||
|
||||
&--square
|
||||
border-radius: var(--a-border-radius-md)
|
||||
&--circle
|
||||
border-radius: var(--a-border-radius-circle)
|
||||
|
||||
&--blue-border
|
||||
border: 1px solid var(--a-color-blue)
|
||||
&--white-border
|
||||
border: 1px solid var(--a-color-white)
|
||||
|
||||
&--radius-top
|
||||
border-radius: var(--a-border-radius-md) var(--a-border-radius-md) 0 0
|
||||
&--radius-bottom
|
||||
border-radius: 0 0 var(--a-border-radius-md) var(--a-border-radius-md)
|
||||
@@ -0,0 +1,54 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './image.sass'
|
||||
|
||||
export interface ImageProps {
|
||||
src: string
|
||||
width?: number | string
|
||||
height?: number | string
|
||||
shape?: 'circle' | 'square'
|
||||
borderColor?: 'white' | 'blue'
|
||||
backgroundSize?: 'cover' | 'contain'
|
||||
radiusTop?: boolean
|
||||
radiusBottom?: boolean
|
||||
overlay?: boolean
|
||||
gradient?: boolean
|
||||
gradientPosition?: 'top' | 'bottom' | 'left' | 'right'
|
||||
}
|
||||
|
||||
export function Image({
|
||||
src,
|
||||
width,
|
||||
height,
|
||||
shape,
|
||||
borderColor,
|
||||
backgroundSize,
|
||||
radiusTop,
|
||||
radiusBottom,
|
||||
overlay,
|
||||
gradient,
|
||||
gradientPosition
|
||||
}: ImageProps) {
|
||||
return (
|
||||
<div
|
||||
key={`aurora-image_${generateKeyId()}`}
|
||||
className={classNames('aurora-image', {
|
||||
[`aurora-image--${shape}`]: shape,
|
||||
[`aurora-image--${borderColor}-border`]: borderColor,
|
||||
[`aurora-image--${backgroundSize}`]: backgroundSize,
|
||||
[`aurora-image--gradient-${gradientPosition}`]: gradientPosition,
|
||||
'aurora-image--radius-top': radiusTop,
|
||||
'aurora-image--radius-bottom': radiusBottom,
|
||||
'aurora-image--overlay': overlay,
|
||||
'aurora-image--gradient': gradient
|
||||
})}
|
||||
style={{
|
||||
width,
|
||||
height,
|
||||
backgroundImage: `url(${src})`
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './image'
|
||||
@@ -0,0 +1 @@
|
||||
export * from './input'
|
||||
@@ -0,0 +1,87 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-input-container
|
||||
--a-icon-container-width: calc(var(--a-input-size-md) + var(--a-space-sm))
|
||||
|
||||
position: relative
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
.aurora-input
|
||||
position: relative
|
||||
display: inline-block
|
||||
color: var(--a-color-text)
|
||||
background-color: var(--a-color-input-background)
|
||||
font-size: var(--a-font-size-md)
|
||||
border: 1px solid var(--a-color-input-border)
|
||||
border-radius: var(--a-border-radius-md)
|
||||
height: var(--a-input-size-md)
|
||||
padding: 0 var(--a-space-md)
|
||||
width: 100%
|
||||
outline: none
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main), border-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&::-webkit-calendar-picker-indicator
|
||||
cursor: pointer
|
||||
background-color: var(--a-color-grey-blue-dark)
|
||||
border-radius: var(--a-border-radius-xs)
|
||||
&:hover
|
||||
border-color: var(--a-color-input-border-hover)
|
||||
background-color: var(--a-color-input-background-hover)
|
||||
&:hover:not([disabled]) ~ .aurora-input-icon-container
|
||||
border-color: var(--a-color-input-border-hover)
|
||||
&:focus
|
||||
border-color: var(--a-color-input-border-focus)
|
||||
background-color: var(--a-color-input-background-hover)
|
||||
&:focus:not([disabled])
|
||||
&~ .aurora-input-icon-container
|
||||
border-color: var(--a-color-input-border-focus)
|
||||
i
|
||||
color: var(--a-color-accent)
|
||||
&:placeholder-shown ~ .aurora-input-icon-container i
|
||||
color: var(--color-secondary-white)
|
||||
|
||||
&--multiline
|
||||
height: calc(var(--a-input-size-md) * 2)
|
||||
padding: var(--a-space-sm) var(--a-space-md)
|
||||
resize: vertical
|
||||
min-height: calc(var(--a-input-size-md) * 2)
|
||||
max-height: 512px
|
||||
&~ .aurora-input-icon-container
|
||||
height: 100%
|
||||
|
||||
&--disabled, &--disabled:hover
|
||||
opacity: var(--a-opacity-disabled)
|
||||
color: inherit
|
||||
background-color: var(--a-color-input-background)
|
||||
border-color: var(--a-color-input-border)
|
||||
cursor: not-allowed
|
||||
&--disabled ~ .aurora-input-icon-container
|
||||
opacity: var(--a-opacity-disabled)
|
||||
i
|
||||
color: inherit
|
||||
opacity: var(--a-opacity-disabled)
|
||||
|
||||
&--with-icon
|
||||
padding-left: calc(var(--a-icon-container-width) + var(--a-space-md))
|
||||
|
||||
.aurora-input-icon-container
|
||||
position: absolute
|
||||
left: 0
|
||||
top: 0
|
||||
bottom: 0
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
color: var(--a-color-text)
|
||||
pointer-events: none
|
||||
border-right: 1px solid var(--a-color-input-border)
|
||||
width: var(--a-icon-container-width)
|
||||
height: var(--a-input-size-md)
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main), border-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
i
|
||||
color: var(--a-color-text)
|
||||
transition: color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
|
||||
.aurora-input-hint-container
|
||||
padding-left: var(--a-space-md)
|
||||
margin-top: var(--a-space-xs)
|
||||
@@ -0,0 +1,167 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { Text, Icon } from '../..'
|
||||
import type { IconProps } from '../icon'
|
||||
|
||||
import './input.sass'
|
||||
|
||||
export interface InputProps {
|
||||
name: string
|
||||
placeholder: string
|
||||
required?: boolean
|
||||
value?: string
|
||||
type?:
|
||||
| 'text'
|
||||
| 'password'
|
||||
| 'email'
|
||||
| 'tel'
|
||||
| 'url'
|
||||
| 'number'
|
||||
| 'date'
|
||||
| 'time'
|
||||
| 'datetime-local'
|
||||
| 'month'
|
||||
| 'week'
|
||||
| 'color'
|
||||
iconName?: string
|
||||
iconSVG?: IconProps['svg']
|
||||
iconType?: IconProps['type']
|
||||
iconSize?: IconProps['size']
|
||||
hint?: string
|
||||
disabled?: boolean
|
||||
height?: number | 'auto'
|
||||
minLength?: number
|
||||
maxLength?: number
|
||||
min?: number
|
||||
max?: number
|
||||
step?: number
|
||||
pattern?: string
|
||||
multiline?: boolean
|
||||
autofocus?: boolean
|
||||
onFocus?: () => void
|
||||
onBlur?: () => void
|
||||
onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void
|
||||
inputRef?: React.Ref<HTMLInputElement | HTMLTextAreaElement>
|
||||
onChange?: (value: string) => void
|
||||
}
|
||||
|
||||
export function Input({
|
||||
name,
|
||||
placeholder,
|
||||
required = false,
|
||||
type = 'text',
|
||||
iconName,
|
||||
iconSVG,
|
||||
iconType = 'fill',
|
||||
iconSize = 'md',
|
||||
hint,
|
||||
value,
|
||||
disabled,
|
||||
height = 'auto',
|
||||
minLength,
|
||||
maxLength,
|
||||
pattern,
|
||||
multiline,
|
||||
autofocus,
|
||||
onFocus,
|
||||
onBlur,
|
||||
onKeyDown,
|
||||
inputRef,
|
||||
onChange
|
||||
}: InputProps) {
|
||||
const [inputValue, setInputValue] = useState(value || '')
|
||||
|
||||
useEffect(() => {
|
||||
setInputValue(value || '')
|
||||
}, [value])
|
||||
|
||||
if (!multiline) {
|
||||
if (!maxLength) {
|
||||
maxLength = 64
|
||||
}
|
||||
|
||||
if (height !== 'auto') {
|
||||
height = 'auto'
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="aurora-input-container">
|
||||
{multiline ? (
|
||||
<textarea
|
||||
name={name}
|
||||
placeholder={placeholder}
|
||||
required={required}
|
||||
value={inputValue}
|
||||
disabled={disabled}
|
||||
autoFocus={autofocus}
|
||||
minLength={minLength}
|
||||
maxLength={maxLength}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
onKeyDown={onKeyDown}
|
||||
ref={inputRef as React.Ref<HTMLTextAreaElement>}
|
||||
onChange={(e) => {
|
||||
setInputValue(e.target.value)
|
||||
|
||||
if (onChange) {
|
||||
onChange(e.target.value)
|
||||
}
|
||||
}}
|
||||
style={{ height }}
|
||||
className={classNames('aurora-input', {
|
||||
'aurora-input--multiline': true,
|
||||
'aurora-input--disabled': disabled,
|
||||
'aurora-input--with-icon': !!iconName || !!iconSVG
|
||||
})}
|
||||
/>
|
||||
) : (
|
||||
<input
|
||||
type={type}
|
||||
name={name}
|
||||
placeholder={placeholder}
|
||||
required={required}
|
||||
value={inputValue}
|
||||
disabled={disabled}
|
||||
autoFocus={autofocus}
|
||||
minLength={minLength}
|
||||
maxLength={maxLength}
|
||||
pattern={pattern}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
onKeyDown={onKeyDown}
|
||||
ref={inputRef as React.Ref<HTMLInputElement>}
|
||||
onChange={(e) => {
|
||||
setInputValue(e.target.value)
|
||||
|
||||
if (onChange) {
|
||||
onChange(e.target.value)
|
||||
}
|
||||
}}
|
||||
className={classNames('aurora-input', {
|
||||
'aurora-input--disabled': disabled,
|
||||
'aurora-input--with-icon': !!iconName || !!iconSVG
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
{(iconName || iconSVG) && (
|
||||
<div className="aurora-input-icon-container">
|
||||
<Icon
|
||||
iconName={iconName}
|
||||
svg={iconSVG}
|
||||
type={iconType}
|
||||
size={iconSize}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{hint && (
|
||||
<div className="aurora-input-hint-container">
|
||||
<Text fontSize="xs" tertiary>
|
||||
{hint}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './link'
|
||||
@@ -0,0 +1,14 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-link
|
||||
display: inline-block
|
||||
position: relative
|
||||
text-decoration: none
|
||||
transition: color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&:hover
|
||||
text-decoration: 1px underline var(--a-color-accent)
|
||||
.aurora-text, .aurora-icon
|
||||
color: var(--a-color-accent-hover)
|
||||
|
||||
.aurora-text, .aurora-icon
|
||||
color: var(--a-color-accent)
|
||||
@@ -0,0 +1,28 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { Text } from '../..'
|
||||
import { type Size } from '../../lib/types'
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './link.sass'
|
||||
|
||||
export interface LinkProps {
|
||||
href: string
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
// children: React.ReactNode
|
||||
fontSize?: Size
|
||||
}
|
||||
|
||||
export function Link({ href, children, fontSize }: LinkProps) {
|
||||
return (
|
||||
<a
|
||||
className={classNames('aurora-link')}
|
||||
href={href}
|
||||
target="_blank"
|
||||
key={`aurora-link_${generateKeyId()}`}
|
||||
>
|
||||
<Text fontSize={fontSize}>{children}</Text>
|
||||
</a>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './list'
|
||||
export * from './list-header'
|
||||
export * from './list-item'
|
||||
@@ -0,0 +1 @@
|
||||
export * from './list-header'
|
||||
@@ -0,0 +1,24 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { Text } from '../../..'
|
||||
import { generateKeyId } from '../../../lib/utils'
|
||||
|
||||
export interface ListHeaderProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
// children: React.ReactNode
|
||||
align?: 'left' | 'center'
|
||||
}
|
||||
|
||||
export function ListHeader({ children, align }: ListHeaderProps) {
|
||||
return (
|
||||
<div
|
||||
key={`aurora-list-header_${generateKeyId()}`}
|
||||
className={classNames('aurora-list-header', {
|
||||
[`aurora-list-header--${align}`]: align
|
||||
})}
|
||||
>
|
||||
<Text fontWeight="semi-bold">{children}</Text>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './list-item'
|
||||
@@ -0,0 +1,75 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { generateKeyId } from '../../../lib/utils'
|
||||
import { Icon } from '../../..'
|
||||
|
||||
interface ListItemOnClickData {
|
||||
name: string | undefined
|
||||
value: string | number | undefined
|
||||
}
|
||||
|
||||
export interface ListItemProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
// children: React.ReactNode
|
||||
align?: 'left' | 'center'
|
||||
name?: string
|
||||
value?: string | number | undefined
|
||||
selected?: boolean
|
||||
onClick?: (data: ListItemOnClickData) => void
|
||||
}
|
||||
|
||||
export function ListItem({
|
||||
children,
|
||||
align,
|
||||
name,
|
||||
value,
|
||||
selected,
|
||||
onClick
|
||||
}: ListItemProps) {
|
||||
let isClickable = false
|
||||
|
||||
if (onClick) {
|
||||
isClickable = true
|
||||
}
|
||||
|
||||
return (
|
||||
<li
|
||||
key={`aurora-list-item_${generateKeyId()}`}
|
||||
data-aurora-name={name}
|
||||
value={value}
|
||||
className={classNames('aurora-list-item', {
|
||||
'aurora-list-item--clickable': isClickable,
|
||||
'aurora-list-item--selected': selected,
|
||||
[`aurora-list-item--${align}`]: align
|
||||
})}
|
||||
onClick={(event) => {
|
||||
if (!isClickable) {
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
const data = {
|
||||
name,
|
||||
value
|
||||
}
|
||||
|
||||
if (onClick) {
|
||||
onClick(data)
|
||||
}
|
||||
}}
|
||||
>
|
||||
{isClickable ? (
|
||||
<>
|
||||
{children}
|
||||
<div className="aurora-list-item-clickable-icon">
|
||||
<Icon iconName="arrow-right-double" />
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './list'
|
||||
@@ -0,0 +1,57 @@
|
||||
@use '../../../styles/main.sass' as *
|
||||
|
||||
.aurora-list
|
||||
position: relative
|
||||
display: flex
|
||||
flex-direction: column
|
||||
.aurora-list-item:last-child
|
||||
border-bottom: none
|
||||
|
||||
.aurora-list-header
|
||||
position: relative
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: flex-start
|
||||
width: 100%
|
||||
text-align: left
|
||||
padding: var(--a-space-lg) var(--a-space-md)
|
||||
border-bottom: 1px solid var(--a-color-separator)
|
||||
|
||||
&--left
|
||||
justify-content: flex-start
|
||||
&--center
|
||||
justify-content: center
|
||||
|
||||
.aurora-list-item
|
||||
position: relative
|
||||
display: flex
|
||||
font-size: var(--a-font-size-md)
|
||||
justify-content: flex-start
|
||||
padding: var(--a-space-md)
|
||||
border-bottom: 1px solid var(--a-color-separator)
|
||||
background-color: transparent
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&:hover
|
||||
background-color: var(--a-color-black)
|
||||
|
||||
&--selected
|
||||
background-color: var(--a-color-black)
|
||||
|
||||
&--left
|
||||
justify-content: flex-start
|
||||
&--center
|
||||
justify-content: center
|
||||
|
||||
&--clickable
|
||||
cursor: pointer
|
||||
&:hover .aurora-list-item-clickable-icon .aurora-icon
|
||||
color: var(--a-color-accent)
|
||||
|
||||
.aurora-list-item-clickable-icon
|
||||
align-self: center
|
||||
position: absolute
|
||||
right: var(--a-space-md)
|
||||
cursor: pointer
|
||||
z-index: 1
|
||||
.aurora-icon
|
||||
color: var(--a-color-grey-blue)
|
||||
@@ -0,0 +1,17 @@
|
||||
import { generateKeyId } from '../../../lib/utils'
|
||||
|
||||
import './list.sass'
|
||||
|
||||
export interface ListProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
// children: React.ReactNode
|
||||
}
|
||||
|
||||
export function List({ children }: ListProps) {
|
||||
return (
|
||||
<ul className="aurora-list" key={`aurora-list_${generateKeyId()}`}>
|
||||
{children}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './loader'
|
||||
@@ -0,0 +1,29 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-loader
|
||||
width: var(--a-loader-size-md)
|
||||
height: var(--a-loader-size-md)
|
||||
display: inline-block
|
||||
position: relative
|
||||
&::before, &::after
|
||||
content: ''
|
||||
box-sizing: border-box
|
||||
width: var(--a-loader-size-md)
|
||||
height: var(--a-loader-size-md)
|
||||
border-radius: 50%
|
||||
background-color: var(--a-color-accent)
|
||||
position: absolute
|
||||
left: 0
|
||||
top: 0
|
||||
animation: aurora-animation-loader 1s linear infinite
|
||||
&::after
|
||||
opacity: 0
|
||||
animation-delay: .4s
|
||||
|
||||
@keyframes aurora-animation-loader
|
||||
0%
|
||||
transform: scale(0)
|
||||
opacity: 1
|
||||
100%
|
||||
transform: scale(1)
|
||||
opacity: 0
|
||||
@@ -0,0 +1,20 @@
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './loader.sass'
|
||||
|
||||
// interface Props {
|
||||
// size?: 'sm' | 'md'
|
||||
// }
|
||||
|
||||
export type LoaderProps = Record<string, never>
|
||||
|
||||
export function Loader(): React.JSX.Element {
|
||||
return (
|
||||
<span className="aurora-loader" key={`aurora-loader_${generateKeyId()}`} />
|
||||
/*<span
|
||||
className={classNames('aurora-loader', {
|
||||
[`aurora-loader--${size}`]: size
|
||||
})}
|
||||
/>*/
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './progress'
|
||||
@@ -0,0 +1,34 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-progress
|
||||
position: relative
|
||||
display: flex
|
||||
align-items: flex-end
|
||||
border-radius: var(--a-border-radius-pill)
|
||||
background-color: var(--a-color-background-surface-secondary)
|
||||
|
||||
&--horizontal
|
||||
width: 100%
|
||||
&.aurora-progress--sm
|
||||
height: 9px
|
||||
&.aurora-progress--md
|
||||
height: 18px
|
||||
&.aurora-progress--lg
|
||||
height: 24px
|
||||
.aurora-progress-value
|
||||
height: 100%
|
||||
|
||||
&--vertical
|
||||
height: 100%
|
||||
&.aurora-progress--sm
|
||||
width: 9px
|
||||
&.aurora-progress--md
|
||||
width: 18px
|
||||
&.aurora-progress--lg
|
||||
width: 24px
|
||||
.aurora-progress-value
|
||||
width: 100%
|
||||
|
||||
.aurora-progress-value
|
||||
border-radius: var(--a-border-radius-pill)
|
||||
background-color: var(--a-color-accent)
|
||||
@@ -0,0 +1,34 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './progress.sass'
|
||||
|
||||
export interface ProgressProps {
|
||||
value: number
|
||||
orientation?: 'horizontal' | 'vertical'
|
||||
size?: 'sm' | 'md' | 'lg'
|
||||
}
|
||||
|
||||
export function Progress({
|
||||
value,
|
||||
orientation = 'horizontal',
|
||||
size = 'md'
|
||||
}: ProgressProps) {
|
||||
return (
|
||||
<div
|
||||
key={`aurora-progress_${generateKeyId()}`}
|
||||
className={classNames('aurora-progress', {
|
||||
[`aurora-progress--${orientation}`]: orientation,
|
||||
[`aurora-progress--${size}`]: size
|
||||
})}
|
||||
>
|
||||
<div
|
||||
className="aurora-progress-value"
|
||||
style={{
|
||||
[orientation === 'horizontal' ? 'width' : 'height']: `${value}%`
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './radio'
|
||||
export * from './radio-group'
|
||||
@@ -0,0 +1 @@
|
||||
export * from './radio-group'
|
||||
@@ -0,0 +1,50 @@
|
||||
@use '../../../styles/main.sass' as *
|
||||
|
||||
.aurora-radio-group
|
||||
&[data-disabled]
|
||||
cursor: not-allowed
|
||||
|
||||
.aurora-radio
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: var(--a-space-sm)
|
||||
cursor: pointer
|
||||
&[data-disabled]
|
||||
cursor: not-allowed
|
||||
|
||||
.aurora-radio-control
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
width: var(--a-checkbox-radio-size)
|
||||
height: var(--a-checkbox-radio-size)
|
||||
border-radius: var(--a-border-radius-circle)
|
||||
border: 1px solid var(--a-color-input-border)
|
||||
background-color: var(--a-color-input-background)
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main), border-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&[data-hover]:not([data-state="checked"])
|
||||
border-color: var(--a-color-input-border-hover)
|
||||
background-color: var(--a-color-input-background-hover)
|
||||
&[data-state="checked"]
|
||||
border-color: transparent
|
||||
background-color: var(--a-color-input-border-focus)
|
||||
&::after
|
||||
opacity: 1
|
||||
transform: scale3d(.5, .5, .5)
|
||||
&::after
|
||||
content: ''
|
||||
width: 16px
|
||||
height: 16px
|
||||
border-radius: var(--a-border-radius-circle)
|
||||
background-color: var(--a-color-white)
|
||||
opacity: 0
|
||||
transition: opacity .3s var(--a-transition-timing-main), transform .3s var(--a-transition-timing-main)
|
||||
&[data-disabled]
|
||||
opacity: var(--a-opacity-disabled)
|
||||
|
||||
.aurora-radio-label
|
||||
color: var(--a-color-text)
|
||||
font-size: var(--a-font-size-md)
|
||||
&[data-disabled]
|
||||
opacity: var(--a-opacity-disabled)
|
||||
color: inherit
|
||||
@@ -0,0 +1,53 @@
|
||||
import {
|
||||
RadioGroup as ArkRadioGroup,
|
||||
type RadioGroupRootProps as ArkRadioGroupProps,
|
||||
type RadioGroupValueChangeDetails
|
||||
} from '@ark-ui/react/radio-group'
|
||||
|
||||
import './radio-group.sass'
|
||||
|
||||
interface RadioGroupOnChangeData {
|
||||
name: string
|
||||
value: string | number | undefined
|
||||
}
|
||||
|
||||
export interface RadioGroupProps
|
||||
extends Pick<
|
||||
ArkRadioGroupProps,
|
||||
'value' | 'children' | 'defaultValue' | 'disabled'
|
||||
> {
|
||||
name: string
|
||||
onChange?: (data: RadioGroupOnChangeData) => void
|
||||
}
|
||||
|
||||
export function RadioGroup({
|
||||
name,
|
||||
value,
|
||||
children,
|
||||
defaultValue,
|
||||
disabled,
|
||||
onChange
|
||||
}: RadioGroupProps) {
|
||||
return (
|
||||
<ArkRadioGroup.Root
|
||||
className="aurora-radio-group"
|
||||
name={name}
|
||||
defaultValue={defaultValue}
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
onValueChange={(event: RadioGroupValueChangeDetails) => {
|
||||
const data = {
|
||||
name,
|
||||
value: event.value
|
||||
}
|
||||
|
||||
if (onChange) {
|
||||
onChange(data)
|
||||
}
|
||||
}}
|
||||
orientation="horizontal"
|
||||
>
|
||||
{children}
|
||||
</ArkRadioGroup.Root>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './radio'
|
||||
@@ -0,0 +1,24 @@
|
||||
import {
|
||||
RadioGroup,
|
||||
type RadioGroupItemProps as ArkRadioProps
|
||||
} from '@ark-ui/react/radio-group'
|
||||
|
||||
export interface RadioProps extends Pick<ArkRadioProps, 'value' | 'disabled'> {
|
||||
label: string
|
||||
}
|
||||
|
||||
export function Radio({ label, value, disabled }: RadioProps) {
|
||||
return (
|
||||
<RadioGroup.Item
|
||||
className="aurora-radio"
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
>
|
||||
<RadioGroup.ItemHiddenInput />
|
||||
<RadioGroup.ItemControl className="aurora-radio-control" />
|
||||
<RadioGroup.ItemText className="aurora-radio-label">
|
||||
{label}
|
||||
</RadioGroup.ItemText>
|
||||
</RadioGroup.Item>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './range-slider'
|
||||
@@ -0,0 +1,70 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-range-slider
|
||||
--a-track-height: 10px
|
||||
|
||||
.aurora-range-slider-control
|
||||
display: flex
|
||||
align-items: center
|
||||
cursor: pointer
|
||||
width: 100%
|
||||
&[data-disabled]
|
||||
cursor: not-allowed
|
||||
opacity: var(--a-opacity-disabled)
|
||||
&:hover:not([data-disabled])
|
||||
.aurora-range-slider-thumb
|
||||
width: calc(var(--a-track-height) * 2.3)
|
||||
height: calc(var(--a-track-height) * 2.3)
|
||||
.aurora-range-slider-track
|
||||
background-color: var(--a-color-background-surface-secondary-hover)
|
||||
|
||||
.aurora-range-slider-track
|
||||
background-color: var(--a-color-background-surface-secondary)
|
||||
border-radius: var(--a-border-radius-pill)
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
|
||||
.aurora-range-slider-range
|
||||
background-color: var(--a-color-accent)
|
||||
border-radius: var(--a-border-radius-pill)
|
||||
|
||||
.aurora-range-slider-thumb
|
||||
position: relative
|
||||
outline: none
|
||||
width: calc(var(--a-track-height) * 2)
|
||||
height: calc(var(--a-track-height) * 2)
|
||||
border-radius: var(--a-border-radius-circle)
|
||||
background-color: var(--a-color-accent)
|
||||
transition: width var(--a-transition-duration-main) var(--a-transition-timing-main), height var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
|
||||
&--hidden-thumb
|
||||
&:hover .aurora-range-slider-thumb
|
||||
opacity: 1
|
||||
.aurora-range-slider-thumb
|
||||
opacity: 0
|
||||
|
||||
&[data-orientation="horizontal"]
|
||||
.aurora-range-slider-control
|
||||
flex-direction: row
|
||||
width: 100%
|
||||
height: var(--a-track-height)
|
||||
.aurora-range-slider-range
|
||||
height: var(--a-track-height)
|
||||
.aurora-range-slider-track
|
||||
width: 100%
|
||||
height: var(--a-track-height)
|
||||
.aurora-range-slider-thumb
|
||||
margin-top: 1px
|
||||
|
||||
&[data-orientation="vertical"]
|
||||
height: 100%
|
||||
.aurora-range-slider-control
|
||||
flex-direction: column
|
||||
width: var(--a-track-height)
|
||||
height: 100%
|
||||
.aurora-range-slider-range
|
||||
width: var(--a-track-height)
|
||||
.aurora-range-slider-track
|
||||
width: var(--a-track-height)
|
||||
height: 100%
|
||||
.aurora-range-slider-thumb
|
||||
margin-left: 1px
|
||||
@@ -0,0 +1,114 @@
|
||||
import { useState } from 'react'
|
||||
import classNames from 'clsx'
|
||||
import {
|
||||
Slider,
|
||||
type SliderRootProps as ArkSliderProps,
|
||||
type SliderValueChangeDetails
|
||||
} from '@ark-ui/react/slider'
|
||||
|
||||
import './range-slider.sass'
|
||||
|
||||
interface RangeSliderOnChangeData {
|
||||
name: string
|
||||
value: string | number | undefined
|
||||
}
|
||||
|
||||
export interface RangeSliderProps
|
||||
extends Pick<
|
||||
ArkSliderProps,
|
||||
| 'max'
|
||||
| 'min'
|
||||
| 'step'
|
||||
| 'disabled'
|
||||
| 'orientation'
|
||||
> {
|
||||
name: string
|
||||
value?: number | number[]
|
||||
defaultValue?: number | number[]
|
||||
width?: number | string
|
||||
height?: number | string
|
||||
hiddenThumb?: boolean
|
||||
onChange?: (data: RangeSliderOnChangeData) => void
|
||||
}
|
||||
|
||||
function normalizeValue(value?: number | number[]): number[] | undefined {
|
||||
if (typeof value === 'undefined') {
|
||||
return undefined
|
||||
}
|
||||
|
||||
return Array.isArray(value) ? value : [value]
|
||||
}
|
||||
|
||||
export function RangeSlider({
|
||||
name,
|
||||
width,
|
||||
height,
|
||||
value,
|
||||
defaultValue,
|
||||
max = 100,
|
||||
min = 0,
|
||||
step = 1,
|
||||
disabled,
|
||||
orientation = 'horizontal',
|
||||
hiddenThumb,
|
||||
onChange
|
||||
}: RangeSliderProps) {
|
||||
const [newValue, setNewValue] = useState(normalizeValue(value ?? defaultValue))
|
||||
const normalizedValue = normalizeValue(value)
|
||||
const normalizedDefaultValue = normalizeValue(defaultValue)
|
||||
const currentValue = normalizedValue ?? newValue ?? normalizedDefaultValue
|
||||
const currentScalarValue = currentValue?.[0] ?? min
|
||||
const valueInPercent =
|
||||
Number((((currentScalarValue - min) / (max - min)) * 100).toFixed(2))
|
||||
|
||||
return (
|
||||
<div
|
||||
className="aurora-range-slider-container"
|
||||
style={{
|
||||
width,
|
||||
height
|
||||
}}
|
||||
>
|
||||
<Slider.Root
|
||||
className={classNames('aurora-range-slider', {
|
||||
'aurora-range-slider--hidden-thumb': hiddenThumb
|
||||
})}
|
||||
name={name}
|
||||
value={normalizedValue}
|
||||
defaultValue={normalizedDefaultValue}
|
||||
max={max}
|
||||
min={min}
|
||||
step={step}
|
||||
disabled={disabled}
|
||||
orientation={orientation}
|
||||
onValueChange={(event: SliderValueChangeDetails) => {
|
||||
setNewValue(event.value)
|
||||
|
||||
const data = {
|
||||
name,
|
||||
value: event.value[0]
|
||||
}
|
||||
|
||||
if (onChange) {
|
||||
onChange(data)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Slider.Control className="aurora-range-slider-control">
|
||||
<Slider.Track className="aurora-range-slider-track">
|
||||
<Slider.Range
|
||||
className="aurora-range-slider-range"
|
||||
style={{
|
||||
[orientation === 'horizontal' ? 'width' : 'height']:
|
||||
`${valueInPercent}%`
|
||||
}}
|
||||
/>
|
||||
</Slider.Track>
|
||||
<Slider.Thumb className="aurora-range-slider-thumb" index={0}>
|
||||
<Slider.HiddenInput />
|
||||
</Slider.Thumb>
|
||||
</Slider.Control>
|
||||
</Slider.Root>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './scroll-container'
|
||||
@@ -0,0 +1,31 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-scroll-container
|
||||
position: relative
|
||||
width: 100%
|
||||
padding: var(--a-space-sm) 0
|
||||
|
||||
.aurora-scroll-container-mask
|
||||
position: absolute
|
||||
pointer-events: none
|
||||
|
||||
&--horizontal .aurora-scroll-container-mask
|
||||
top: 0
|
||||
right: 0
|
||||
width: 50px
|
||||
height: 100%
|
||||
background: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3), var(--a-color-background-surface))
|
||||
&--vertical .aurora-scroll-container-mask
|
||||
position: absolute
|
||||
content: ''
|
||||
bottom: 0
|
||||
left: 0
|
||||
right: 0
|
||||
width: 100%
|
||||
height: 50px
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .3), var(--a-color-background-surface))
|
||||
|
||||
.aurora-scroll-container-scrollview
|
||||
height: 100%
|
||||
overflow-y: auto
|
||||
overflow-x: auto
|
||||
@@ -0,0 +1,34 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import './scroll-container.sass'
|
||||
|
||||
export interface ScrollContainerProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
orientation?: 'vertical' | 'horizontal'
|
||||
width?: number | string
|
||||
height?: number | string
|
||||
}
|
||||
|
||||
export function ScrollContainer({
|
||||
children,
|
||||
orientation = 'horizontal',
|
||||
width,
|
||||
height
|
||||
}: ScrollContainerProps) {
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'aurora-scroll-container',
|
||||
`aurora-scroll-container--${orientation}`
|
||||
)}
|
||||
style={{
|
||||
width,
|
||||
height
|
||||
}}
|
||||
>
|
||||
<div className="aurora-scroll-container-scrollview">{children}</div>
|
||||
<div className="aurora-scroll-container-mask" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './select'
|
||||
export * from './select-option'
|
||||
@@ -0,0 +1 @@
|
||||
export * from './select-option'
|
||||
@@ -0,0 +1,28 @@
|
||||
import {
|
||||
Select as ArkSelect
|
||||
} from '@ark-ui/react/select'
|
||||
|
||||
export interface SelectOptionProps {
|
||||
disabled?: boolean
|
||||
label: string
|
||||
value: string
|
||||
}
|
||||
|
||||
export function SelectOption({
|
||||
label,
|
||||
value,
|
||||
disabled = false
|
||||
}: SelectOptionProps) {
|
||||
return (
|
||||
<ArkSelect.Item
|
||||
className="aurora-select-option"
|
||||
item={{
|
||||
label,
|
||||
value,
|
||||
disabled
|
||||
}}
|
||||
>
|
||||
<ArkSelect.ItemText>{label}</ArkSelect.ItemText>
|
||||
</ArkSelect.Item>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './select'
|
||||
@@ -0,0 +1,77 @@
|
||||
@use '../../../styles/main.sass' as *
|
||||
|
||||
.aurora-select-trigger
|
||||
position: relative
|
||||
display: inline-block
|
||||
cursor: pointer
|
||||
color: var(--a-color-text-placeholder)
|
||||
text-align: left
|
||||
background-color: var(--a-color-input-background)
|
||||
font-size: var(--a-font-size-md)
|
||||
border: 1px solid var(--a-color-input-border)
|
||||
border-radius: var(--a-border-radius-md)
|
||||
height: var(--a-input-size-md)
|
||||
padding: 0 var(--a-space-md)
|
||||
padding-right: 0
|
||||
width: 100%
|
||||
outline: none
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main), border-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&:hover
|
||||
border-color: var(--a-color-input-border-hover)
|
||||
background-color: var(--a-color-input-background-hover)
|
||||
&--selected
|
||||
color: var(--a-color-text)
|
||||
&[data-expanded]
|
||||
border-color: var(--a-color-input-border-focus)
|
||||
background-color: var(--a-color-input-background-hover)
|
||||
&:not([disabled])
|
||||
.aurora-icon
|
||||
color: var(--a-color-accent)
|
||||
transform: rotate(-180deg)
|
||||
&[disabled], &[disabled]:hover
|
||||
border-color: inherit
|
||||
background-color: inherit
|
||||
opacity: var(--a-opacity-disabled)
|
||||
cursor: not-allowed
|
||||
&-placeholder-container
|
||||
position: relative
|
||||
overflow: hidden
|
||||
white-space: nowrap
|
||||
text-overflow: ellipsis
|
||||
width: 100%
|
||||
&-icon-container
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 50px
|
||||
|
||||
.aurora-icon
|
||||
color: var(--color-secondary-white)
|
||||
|
||||
.aurora-select-content
|
||||
position: relative
|
||||
width: var(--reference-width)
|
||||
background-color: var(--a-color-background-surface)
|
||||
border: 1px solid var(--a-color-separator)
|
||||
border-radius: var(--a-border-radius-md)
|
||||
cursor: pointer
|
||||
|
||||
.aurora-select-option
|
||||
font-size: var(--a-font-size-md)
|
||||
line-height: var(--a-line-height-md)
|
||||
color: var(--a-color-text-secondary)
|
||||
padding: var(--a-space-md)
|
||||
border-bottom: 1px solid var(--a-color-separator)
|
||||
background-color: transparent
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&:hover
|
||||
background-color: var(--a-color-black)
|
||||
&[data-disabled]
|
||||
color: rgba(245, 245, 247, var(--a-opacity-disabled))
|
||||
cursor: not-allowed
|
||||
&:hover
|
||||
background-color: inherit
|
||||
&[data-selected]
|
||||
color: var(--a-color-text)
|
||||
&:last-child
|
||||
border-bottom: none
|
||||
@@ -0,0 +1,124 @@
|
||||
import { Children, isValidElement, useState, type ReactNode } from 'react'
|
||||
import { Portal } from '@ark-ui/react/portal'
|
||||
import {
|
||||
Select as ArkSelect,
|
||||
createListCollection
|
||||
} from '@ark-ui/react/select'
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { Flexbox, Icon } from '../../..'
|
||||
import { type SelectOptionProps } from '../select-option'
|
||||
|
||||
import './select.sass'
|
||||
|
||||
interface Option {
|
||||
label: string
|
||||
value: string
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
interface SelectOnChangeData {
|
||||
name: string
|
||||
value: string | number | undefined
|
||||
label?: string
|
||||
}
|
||||
|
||||
export interface SelectProps {
|
||||
name: string
|
||||
selectedOption?: Option
|
||||
defaultValue?: string
|
||||
disabled?: boolean
|
||||
placeholder: string
|
||||
children: ReactNode
|
||||
onChange?: (data: SelectOnChangeData) => void
|
||||
}
|
||||
|
||||
export function Select({
|
||||
name,
|
||||
placeholder,
|
||||
children,
|
||||
selectedOption,
|
||||
defaultValue,
|
||||
disabled,
|
||||
onChange
|
||||
}: SelectProps) {
|
||||
const [currentValue, setCurrentValue] = useState(
|
||||
selectedOption?.value ?? defaultValue
|
||||
)
|
||||
const options = Children.toArray(children).flatMap((child) => {
|
||||
if (!isValidElement<SelectOptionProps>(child)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const { label, value, disabled } = child.props
|
||||
|
||||
return [
|
||||
{
|
||||
label,
|
||||
value,
|
||||
disabled
|
||||
}
|
||||
]
|
||||
})
|
||||
const collection = createListCollection<Option>({
|
||||
items: options,
|
||||
itemToString: (item) => item.label,
|
||||
itemToValue: (item) => item.value,
|
||||
isItemDisabled: (item) => !!item.disabled
|
||||
})
|
||||
const selectedValue = selectedOption?.value
|
||||
const hasSelectedValue = Boolean(selectedValue ?? currentValue)
|
||||
|
||||
return (
|
||||
<ArkSelect.Root
|
||||
collection={collection}
|
||||
closeOnSelect
|
||||
value={selectedValue ? [selectedValue] : undefined}
|
||||
defaultValue={defaultValue ? [defaultValue] : undefined}
|
||||
disabled={disabled}
|
||||
name={name}
|
||||
onValueChange={(event) => {
|
||||
const nextSelectedOption = event.items[0]
|
||||
|
||||
setCurrentValue(nextSelectedOption?.value)
|
||||
|
||||
const data = {
|
||||
name,
|
||||
label: nextSelectedOption?.label,
|
||||
value: nextSelectedOption?.value
|
||||
}
|
||||
|
||||
if (onChange) {
|
||||
onChange(data)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ArkSelect.HiddenSelect />
|
||||
<ArkSelect.Trigger
|
||||
className={classNames('aurora-select-trigger', {
|
||||
'aurora-select-trigger--selected': hasSelectedValue
|
||||
})}
|
||||
>
|
||||
<Flexbox
|
||||
flexDirection="row"
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<div className="aurora-select-trigger-placeholder-container">
|
||||
<ArkSelect.ValueText placeholder={placeholder} />
|
||||
</div>
|
||||
<div className="aurora-select-trigger-icon-container">
|
||||
<Icon iconName="arrow-down-s" />
|
||||
</div>
|
||||
</Flexbox>
|
||||
</ArkSelect.Trigger>
|
||||
<Portal>
|
||||
<ArkSelect.Positioner>
|
||||
<ArkSelect.Content className="aurora-select-content">
|
||||
{children}
|
||||
</ArkSelect.Content>
|
||||
</ArkSelect.Positioner>
|
||||
</Portal>
|
||||
</ArkSelect.Root>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './status'
|
||||
@@ -0,0 +1,63 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-status
|
||||
position: relative
|
||||
display: inline-block
|
||||
border-radius: var(--a-border-radius-pill)
|
||||
font-size: var(--a-font-size-xs)
|
||||
padding: var(--a-space-xs) var(--a-space-sm)
|
||||
cursor: default
|
||||
color: var(--a-color-text)
|
||||
background-color: var(--a-color-transparent-white)
|
||||
border: 1px solid var(--a-color-transparent-white)
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main), border-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&:hover
|
||||
background-color: var(--a-color-transparent-white-hover)
|
||||
border-color: var(--a-color-transparent-white-hover)
|
||||
i
|
||||
font-style: normal
|
||||
|
||||
*
|
||||
cursor: default
|
||||
|
||||
.aurora-icon
|
||||
width: auto
|
||||
height: auto
|
||||
padding: 0
|
||||
|
||||
&--blue
|
||||
color: var(--a-color-blue)
|
||||
background-color: var(--a-color-transparent-blue)
|
||||
border-color: var(--a-color-transparent-blue)
|
||||
&:hover
|
||||
background-color: var(--a-color-transparent-blue-hover)
|
||||
border-color: var(--a-color-transparent-blue-hover)
|
||||
.aurora-icon
|
||||
color: var(--a-color-blue)
|
||||
&--green
|
||||
color: var(--a-color-green)
|
||||
background-color: var(--a-color-transparent-green)
|
||||
border-color: var(--a-color-transparent-green)
|
||||
&:hover
|
||||
background-color: var(--a-color-transparent-green-hover)
|
||||
border-color: var(--a-color-transparent-green-hover)
|
||||
.aurora-icon
|
||||
color: var(--a-color-green)
|
||||
&--yellow
|
||||
color: var(--a-color-yellow)
|
||||
background-color: var(--a-color-transparent-yellow)
|
||||
border-color: var(--a-color-transparent-yellow)
|
||||
&:hover
|
||||
background-color: var(--a-color-transparent-yellow-hover)
|
||||
border-color: var(--a-color-transparent-yellow-hover)
|
||||
.aurora-icon
|
||||
color: var(--a-color-yellow)
|
||||
&--red
|
||||
color: var(--a-color-red)
|
||||
background-color: var(--a-color-transparent-red)
|
||||
border-color: var(--a-color-transparent-red)
|
||||
&:hover
|
||||
background-color: var(--a-color-transparent-red-hover)
|
||||
border-color: var(--a-color-transparent-red-hover)
|
||||
.aurora-icon
|
||||
color: var(--a-color-red)
|
||||
@@ -0,0 +1,45 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import type { IconType } from '../../lib/types'
|
||||
import { Icon, Flexbox } from '../..'
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './status.sass'
|
||||
|
||||
export interface StatusProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
color?: 'blue' | 'green' | 'red' | 'yellow'
|
||||
iconName?: string
|
||||
iconType?: IconType
|
||||
}
|
||||
|
||||
export function Status({
|
||||
children,
|
||||
color,
|
||||
iconName,
|
||||
iconType = 'line'
|
||||
}: StatusProps) {
|
||||
return (
|
||||
<div
|
||||
key={`aurora-status_${generateKeyId()}`}
|
||||
className={classNames('aurora-status', {
|
||||
[`aurora-status--${color}`]: color
|
||||
})}
|
||||
>
|
||||
{iconName ? (
|
||||
<Flexbox
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
flexDirection="row"
|
||||
gap="xs"
|
||||
>
|
||||
<Icon iconName={iconName} type={iconType} size="sm" />
|
||||
<i>{children}</i>
|
||||
</Flexbox>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './switch'
|
||||
@@ -0,0 +1,48 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-switch
|
||||
--a-switch-width: 44px
|
||||
--a-thumb-size: 20px
|
||||
|
||||
position: relative
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: var(--a-space-sm)
|
||||
cursor: pointer
|
||||
&[data-disabled]
|
||||
cursor: not-allowed
|
||||
opacity: var(--a-opacity-disabled)
|
||||
&:hover:not([data-state="checked"], [data-disabled]) .aurora-switch-control
|
||||
background-color: var(--a-color-background-surface-secondary-hover)
|
||||
|
||||
.aurora-switch-control
|
||||
position: relative
|
||||
display: flex
|
||||
align-items: center
|
||||
border-radius: var(--a-border-radius-pill)
|
||||
background-color: var(--a-color-background-surface-secondary)
|
||||
width: var(--a-switch-width)
|
||||
height: 22px
|
||||
transition: background-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&[data-state="checked"]
|
||||
background-color: var(--a-color-accent)
|
||||
|
||||
.aurora-switch-thumb
|
||||
display: block
|
||||
position: relative
|
||||
left: 2px
|
||||
width: var(--a-thumb-size)
|
||||
height: var(--a-thumb-size)
|
||||
border-radius: var(--a-border-radius-circle)
|
||||
border: 1px solid var(--a-color-input-border)
|
||||
background-color: var(--a-color-background-surface)
|
||||
transition: transform var(--a-transition-duration-main) var(--a-transition-timing-main), border-color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&[data-state="checked"]
|
||||
border-color: transparent
|
||||
transform: translateX(calc(var(--a-switch-width) - var(--a-thumb-size) - 4px))
|
||||
|
||||
.aurora-switch-label
|
||||
color: var(--a-color-text)
|
||||
font-size: var(--a-font-size-md)
|
||||
&[data-disabled]
|
||||
color: inherit
|
||||
@@ -0,0 +1,63 @@
|
||||
import { useState } from 'react'
|
||||
import {
|
||||
Switch as ArkSwitch,
|
||||
type SwitchCheckedChangeDetails,
|
||||
type SwitchRootProps as ArkSwitchProps
|
||||
} from '@ark-ui/react/switch'
|
||||
|
||||
import './switch.sass'
|
||||
|
||||
interface SwitchOnChangeData {
|
||||
name: string
|
||||
value: string | number | undefined
|
||||
isSwitched: boolean
|
||||
}
|
||||
|
||||
export interface SwitchProps
|
||||
extends Pick<ArkSwitchProps, 'value' | 'checked' | 'disabled' | 'required'> {
|
||||
name: string
|
||||
label?: string
|
||||
onChange?: (data: SwitchOnChangeData) => void
|
||||
}
|
||||
|
||||
export function Switch({
|
||||
name,
|
||||
label,
|
||||
checked,
|
||||
value,
|
||||
disabled,
|
||||
required,
|
||||
onChange
|
||||
}: SwitchProps) {
|
||||
const [isChecked, setIsChecked] = useState(checked)
|
||||
|
||||
return (
|
||||
<ArkSwitch.Root
|
||||
className="aurora-switch"
|
||||
name={name}
|
||||
value={value}
|
||||
checked={isChecked}
|
||||
disabled={disabled}
|
||||
required={required}
|
||||
onCheckedChange={(event: SwitchCheckedChangeDetails) => {
|
||||
setIsChecked(event.checked)
|
||||
|
||||
const data = {
|
||||
name,
|
||||
value,
|
||||
isSwitched: event.checked
|
||||
}
|
||||
|
||||
if (onChange) {
|
||||
onChange(data)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ArkSwitch.HiddenInput />
|
||||
<ArkSwitch.Control className="aurora-switch-control">
|
||||
<ArkSwitch.Thumb className="aurora-switch-thumb" />
|
||||
</ArkSwitch.Control>
|
||||
<ArkSwitch.Label className="aurora-switch-label">{label}</ArkSwitch.Label>
|
||||
</ArkSwitch.Root>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './tab'
|
||||
export * from './tab-content'
|
||||
export * from './tab-group'
|
||||
export * from './tab-list'
|
||||
@@ -0,0 +1 @@
|
||||
export * from './tab-content'
|
||||
@@ -0,0 +1,23 @@
|
||||
import {
|
||||
Tabs,
|
||||
type TabContentProps as ArkTabContentProps
|
||||
} from '@ark-ui/react/tabs'
|
||||
|
||||
import { generateKeyId } from '../../../lib/utils'
|
||||
|
||||
export type TabContentProps = Pick<ArkTabContentProps, 'children' | 'value'>
|
||||
|
||||
export function TabContent({
|
||||
children,
|
||||
value
|
||||
}: TabContentProps): React.JSX.Element {
|
||||
return (
|
||||
<Tabs.Content
|
||||
key={`aurora-tab-content_${generateKeyId()}`}
|
||||
className="aurora-tab-content"
|
||||
value={value}
|
||||
>
|
||||
{children}
|
||||
</Tabs.Content>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './tab-group'
|
||||
@@ -0,0 +1,38 @@
|
||||
@use '../../../styles/main.sass' as *
|
||||
|
||||
.aurora-tab-group
|
||||
.aurora-tab
|
||||
color: var(--a-color-text)
|
||||
font-size: var(--a-font-size-md)
|
||||
cursor: pointer
|
||||
background-color: transparent
|
||||
border: none
|
||||
margin-right: var(--a-space-md)
|
||||
padding: 0
|
||||
padding-bottom: var(--a-space-xs)
|
||||
transition: color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
&:hover, &[data-selected]
|
||||
color: var(--a-color-accent)
|
||||
&[disabled]
|
||||
opacity: var(--a-opacity-disabled)
|
||||
cursor: not-allowed
|
||||
color: inherit
|
||||
&--sm .aurora-tab
|
||||
font-size: var(--a-font-size-sm)
|
||||
&--md .aurora-tab
|
||||
font-size: var(--a-font-size-md)
|
||||
&--lg .aurora-tab
|
||||
font-size: var(--a-font-size-lg)
|
||||
|
||||
.aurora-tab-indicator-container
|
||||
display: grid
|
||||
|
||||
.aurora-tab-indicator
|
||||
justify-self: center
|
||||
width: 6px
|
||||
height: 6px
|
||||
border-radius: var(--a-border-radius-circle)
|
||||
background-color: var(--a-color-accent)
|
||||
|
||||
.aurora-tab-content
|
||||
margin-top: var(--a-space-md)
|
||||
@@ -0,0 +1,37 @@
|
||||
import classNames from 'clsx'
|
||||
import {
|
||||
Tabs,
|
||||
type TabsRootProps as ArkTabsProps,
|
||||
type TabsValueChangeDetails
|
||||
} from '@ark-ui/react/tabs'
|
||||
|
||||
import { generateKeyId } from '../../../lib/utils'
|
||||
|
||||
import './tab-group.sass'
|
||||
|
||||
export interface TabGroupProps
|
||||
extends Pick<ArkTabsProps, 'children' | 'defaultValue'> {
|
||||
size?: 'sm' | 'md' | 'lg'
|
||||
onChange?: (details: TabsValueChangeDetails) => void
|
||||
}
|
||||
|
||||
export function TabGroup({
|
||||
children,
|
||||
defaultValue,
|
||||
onChange,
|
||||
size
|
||||
}: TabGroupProps) {
|
||||
return (
|
||||
<Tabs.Root
|
||||
key={`aurora-tab-group_${generateKeyId()}`}
|
||||
className={classNames('aurora-tab-group', {
|
||||
[`aurora-tab-group--${size}`]: size
|
||||
})}
|
||||
defaultValue={defaultValue}
|
||||
onValueChange={onChange}
|
||||
orientation="horizontal"
|
||||
>
|
||||
{children}
|
||||
</Tabs.Root>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './tab-list'
|
||||
@@ -0,0 +1,22 @@
|
||||
import {
|
||||
Tabs,
|
||||
type TabListProps as ArkTabListProps
|
||||
} from '@ark-ui/react/tabs'
|
||||
|
||||
import { generateKeyId } from '../../../lib/utils'
|
||||
|
||||
export type TabListProps = Pick<ArkTabListProps, 'children'>
|
||||
|
||||
export function TabList({ children }: TabListProps): React.JSX.Element {
|
||||
return (
|
||||
<Tabs.List
|
||||
key={`aurora-tab-list_${generateKeyId()}`}
|
||||
className="aurora-tab-list"
|
||||
>
|
||||
{children}
|
||||
<Tabs.Indicator className="aurora-tab-indicator-container">
|
||||
<div className="aurora-tab-indicator" />
|
||||
</Tabs.Indicator>
|
||||
</Tabs.List>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './tab'
|
||||
@@ -0,0 +1,28 @@
|
||||
import {
|
||||
Tabs,
|
||||
type TabTriggerProps as ArkTabTriggerProps
|
||||
} from '@ark-ui/react/tabs'
|
||||
|
||||
import { generateKeyId } from '../../../lib/utils'
|
||||
|
||||
export type TabProps = Pick<
|
||||
ArkTabTriggerProps,
|
||||
'children' | 'value' | 'disabled'
|
||||
>
|
||||
|
||||
export function Tab({
|
||||
children,
|
||||
value,
|
||||
disabled
|
||||
}: TabProps): React.JSX.Element {
|
||||
return (
|
||||
<Tabs.Trigger
|
||||
key={`aurora-tab_${generateKeyId()}`}
|
||||
className="aurora-tab"
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
>
|
||||
{children}
|
||||
</Tabs.Trigger>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './text'
|
||||
@@ -0,0 +1,42 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-text
|
||||
font-size: var(--a-font-size-md)
|
||||
font-weight: var(--a-font-weight-regular)
|
||||
line-height: var(--a-line-height-md)
|
||||
color: var(--a-color-text)
|
||||
text-align: left
|
||||
transition: color var(--a-transition-duration-main) var(--a-transition-timing-main)
|
||||
|
||||
&--left
|
||||
text-align: left
|
||||
&--center
|
||||
text-align: center
|
||||
&--right
|
||||
text-align: right
|
||||
|
||||
&--secondary
|
||||
color: var(--a-color-text-secondary)
|
||||
&--tertiary
|
||||
color: var(--a-color-text-tertiary)
|
||||
|
||||
&--xs
|
||||
font-size: var(--a-font-size-xs)
|
||||
line-height: var(--a-line-height-xs)
|
||||
&--sm
|
||||
font-size: var(--a-font-size-sm)
|
||||
line-height: var(--a-line-height-sm)
|
||||
&--md
|
||||
font-size: var(--a-font-size-md)
|
||||
line-height: var(--a-line-height-md)
|
||||
&--lg
|
||||
font-size: var(--a-font-size-lg)
|
||||
line-height: var(--a-line-height-lg)
|
||||
&--xl
|
||||
font-size: var(--a-font-size-xl)
|
||||
line-height: var(--a-line-height-xl)
|
||||
|
||||
&--regular
|
||||
font-weight: var(--a-font-weight-regular)
|
||||
&--semi-bold
|
||||
font-weight: var(--a-font-weight-semi-bold)
|
||||
@@ -0,0 +1,49 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import type { Size } from '../../lib/types'
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './text.sass'
|
||||
|
||||
/*const FONT_SIZES = {
|
||||
XS: 'xs',
|
||||
SM: 'sm',
|
||||
MD: 'md',
|
||||
LG: 'lg',
|
||||
XL: 'xl'
|
||||
} as const*/
|
||||
|
||||
export interface TextProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
// fontSize?: typeof FONT_SIZES[keyof typeof FONT_SIZES]
|
||||
fontSize?: Size
|
||||
fontWeight?: 'regular' | 'semi-bold'
|
||||
secondary?: boolean
|
||||
tertiary?: boolean
|
||||
textAlign?: 'left' | 'center' | 'right'
|
||||
}
|
||||
|
||||
export function Text({
|
||||
children,
|
||||
fontSize,
|
||||
fontWeight,
|
||||
secondary,
|
||||
tertiary,
|
||||
textAlign
|
||||
}: TextProps): React.JSX.Element {
|
||||
return (
|
||||
<p
|
||||
key={`aurora-text_${generateKeyId()}`}
|
||||
className={classNames('aurora-text', {
|
||||
'aurora-text--secondary': secondary,
|
||||
'aurora-text--tertiary': tertiary,
|
||||
[`aurora-text--${textAlign}`]: textAlign,
|
||||
[`aurora-text--${fontSize}`]: fontSize,
|
||||
[`aurora-text--${fontWeight}`]: fontWeight
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './widget-wrapper'
|
||||
@@ -0,0 +1,23 @@
|
||||
@use '../../styles/main.sass' as *
|
||||
|
||||
.aurora-widget-wrapper
|
||||
position: relative
|
||||
display: inline-block
|
||||
height: auto
|
||||
border-radius: var(--a-border-radius-md)
|
||||
padding: var(--a-space-xl) var(--a-space-md)
|
||||
width: var(--a-widget-width)
|
||||
background: linear-gradient(var(--a-color-background-surface), var(--a-color-background-surface)) padding-box, linear-gradient(135deg, rgba(28, 117, 219, 0.4) 0%, rgba(237, 41, 122, 0.2) 100%) border-box
|
||||
border: 1px solid transparent
|
||||
overflow-x: auto
|
||||
|
||||
&--no-padding
|
||||
padding: 0
|
||||
&--padding-top
|
||||
padding-top: var(--a-space-xl)
|
||||
&--padding-bottom
|
||||
padding-bottom: var(--a-space-xl)
|
||||
&--padding-left
|
||||
padding-left: var(--a-space-md)
|
||||
&--padding-right
|
||||
padding-right: var(--a-space-md)
|
||||
@@ -0,0 +1,39 @@
|
||||
import classNames from 'clsx'
|
||||
|
||||
import { generateKeyId } from '../../lib/utils'
|
||||
|
||||
import './widget-wrapper.sass'
|
||||
|
||||
export interface WidgetWrapperProps {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
children: any
|
||||
noPadding?: boolean
|
||||
paddingTop?: boolean
|
||||
paddingBottom?: boolean
|
||||
paddingLeft?: boolean
|
||||
paddingRight?: boolean
|
||||
}
|
||||
|
||||
export function WidgetWrapper({
|
||||
children,
|
||||
noPadding,
|
||||
paddingTop,
|
||||
paddingBottom,
|
||||
paddingLeft,
|
||||
paddingRight
|
||||
}: WidgetWrapperProps) {
|
||||
return (
|
||||
<div
|
||||
key={`aurora-widget-wrapper_${generateKeyId()}`}
|
||||
className={classNames('aurora-widget-wrapper', {
|
||||
'aurora-widget-wrapper--no-padding': noPadding,
|
||||
'aurora-widget-wrapper--padding-top': paddingTop,
|
||||
'aurora-widget-wrapper--padding-bottom': paddingBottom,
|
||||
'aurora-widget-wrapper--padding-left': paddingLeft,
|
||||
'aurora-widget-wrapper--padding-right': paddingRight
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user