Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions ui-parts/select/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
"postpack": "rm -rf dist"
},
"dependencies": {
"@atls-ui-parts/theme": "workspace:*",
"@atls-utils/use-select": "workspace:*",
"clsx": "2.1.1",
"framer-motion": "12.23.22",
"rainbow-sprinkles": "1.0.0"
"framer-motion": "12.23.22"
},
"devDependencies": {
"@atls-ui-parts/layout": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ReactNode } from 'react'

import type { SelectProps } from './select.interfaces.js'
import type { SelectProps } from './interfaces.js'

import { clsx } from 'clsx'
import { motion } from 'framer-motion'
Expand All @@ -9,16 +9,20 @@ import { useSelect } from '@atls-utils/use-select'

import { MenuItem } from './item/index.js'
import { baseButtonStyles } from './button/index.js'
import { baseMenuSprinkles } from './menu/index.js'
import { baseMenuStyles } from './menu/index.js'
import { selectAppearances } from './styles/index.js'
import { selectShapes } from './styles/index.js'

export const Select = ({
appearance = selectAppearances.default,
Comment thread
TorinAsakura marked this conversation as resolved.
items,
label,
menuProps: menuPropsProperty,
value,
onChangeValue,
placeholder,
...props
shape = selectShapes.default,
width,
}: SelectProps): ReactNode => {
const {
isOpen,
Expand All @@ -33,30 +37,38 @@ export const Select = ({
onChange: onChangeValue,
})

const { className, style, otherProps } = baseMenuSprinkles(props)
const triggerValue = value || placeholder
const { className, style, ...props } = menuPropsProperty ?? {}
const menuStyle = width === undefined ? style : { width, ...style }

return (
<>
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label {...labelProps}>{label}</label>
<button type='button' {...buttonProps} className={baseButtonStyles}>
{value}
<button
type='button'
{...buttonProps}
className={clsx(baseButtonStyles, appearance.trigger, shape.trigger)}
>
{triggerValue}
</button>
{/* eslint-disable-next-line react/jsx-no-leaked-render */}
{isOpen &&
renderMenu(
<motion.ul
{...otherProps}
className={clsx(baseMenuStyles, String(otherProps?.className || ''), className)}
{...props}
{...menuProps}
style={{ ...style, ...otherProps?.style }}
className={clsx(baseMenuStyles, appearance.menu, shape.menu, className)}
style={menuStyle}
>
{items.map((item, index) => (
<MenuItem
/* eslint-disable-next-line react/no-array-index-key */
key={`${item}-${index}`}
highlighted={index === highlightedIndex}
{...getMenuItemProps(item, index)}
highlightedClassName={appearance.highlightedItem}
className={clsx(appearance.item, shape.item)}
>
{item}
</MenuItem>
Expand Down
1 change: 1 addition & 0 deletions ui-parts/select/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DEFAULT_MENU_WIDTH = 100
5 changes: 3 additions & 2 deletions ui-parts/select/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './button/index.js'
export * from './item/index.js'
export * from './menu/index.js'
export * from './select.component.js'
export type * from './select.interfaces.js'
export * from './component.js'
export * from './styles/index.js'
export type * from './interfaces.js'
31 changes: 31 additions & 0 deletions ui-parts/select/src/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { HTMLMotionProps } from 'framer-motion'
import type { CSSProperties } from 'react'

export interface SelectAppearance {
highlightedItem: string
item: string
menu: string
trigger: string
}

export type SelectAppearanceName = 'default'

export interface SelectShape {
item: string
menu: string
trigger: string
}

export type SelectShapeName = 'default'

export interface SelectProps {
appearance?: SelectAppearance
label: string
value: string
onChangeValue: (nextValue: string) => void
placeholder: string
items: Array<string>
menuProps?: HTMLMotionProps<'ul'>
shape?: SelectShape
width?: CSSProperties['width']
}
28 changes: 28 additions & 0 deletions ui-parts/select/src/item/component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { ReactNode } from 'react'

import type { ItemProps } from './interfaces.js'

import { clsx } from 'clsx'

import { baseItemStyles } from './item.css.js'
import { highlightedMenuItemStyles } from './item.css.js'

export const MenuItem = ({
highlighted,
highlightedClassName,
children,
className,
...props
}: ItemProps): ReactNode => (
<li
{...props}
className={clsx(
baseItemStyles,
highlighted && highlightedMenuItemStyles,
highlighted && highlightedClassName,
className
)}
>
{children}
</li>
)
4 changes: 2 additions & 2 deletions ui-parts/select/src/item/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './item.component.js'
export type * from './item.interfaces.js'
export * from './component.js'
export type * from './interfaces.js'
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import type { LiHTMLAttributes } from 'react'

export interface ItemProps extends LiHTMLAttributes<HTMLLIElement> {
highlighted: boolean
highlightedClassName?: string
}
14 changes: 0 additions & 14 deletions ui-parts/select/src/item/item.component.tsx

This file was deleted.

17 changes: 1 addition & 16 deletions ui-parts/select/src/menu/menu.css.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
import { style } from '@vanilla-extract/css'
import { createRainbowSprinkles } from 'rainbow-sprinkles'
import { defineProperties } from 'rainbow-sprinkles'

const menuComponentProperties = defineProperties({
dynamicProperties: {
width: true,
},
})

export const baseMenuSprinkles = createRainbowSprinkles(menuComponentProperties)

export type BaseMenuSprinkles = Parameters<typeof baseMenuSprinkles>[0]
import { style } from '@vanilla-extract/css'

export const baseMenuStyles = style({
display: 'flex',
Expand All @@ -19,8 +7,5 @@ export const baseMenuStyles = style({
flexDirection: 'column',
outline: 'none',
padding: 0,
width: 100,
height: 'auto',
border: '1px solid black',
borderRadius: 4,
})
9 changes: 0 additions & 9 deletions ui-parts/select/src/select.interfaces.ts

This file was deleted.

2 changes: 1 addition & 1 deletion ui-parts/select/src/select.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Column } from '@atls-ui-parts/layout'
import { Row } from '@atls-ui-parts/layout'
import { Layout } from '@atls-ui-parts/layout'

import { Select } from './select.component.js'
import { Select } from './component.js'

const meta: Meta = {
title: 'Components/Select',
Expand Down
27 changes: 27 additions & 0 deletions ui-parts/select/src/styles/appearance.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { SelectAppearance } from '../interfaces.js'
import type { SelectAppearanceName } from '../interfaces.js'

import { style } from '@vanilla-extract/css'

import { vars } from '@atls-ui-parts/theme'

const itemDefaultAppearanceStyles = style({
color: vars.colors.black,
})

const menuDefaultAppearanceStyles = style({
border: vars.borders.normalBlack,
})

export const appearanceVariant = {
default: {
highlightedItem: '',
item: itemDefaultAppearanceStyles,
menu: menuDefaultAppearanceStyles,
trigger: '',
},
}

export const selectAppearances: Record<SelectAppearanceName, SelectAppearance> = {
default: appearanceVariant.default,
}
2 changes: 2 additions & 0 deletions ui-parts/select/src/styles/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './appearance.css.js'
export * from './shape.css.js'
23 changes: 23 additions & 0 deletions ui-parts/select/src/styles/shape.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { SelectShape } from '../interfaces.js'
import type { SelectShapeName } from '../interfaces.js'

import { style } from '@vanilla-extract/css'

import { vars } from '@atls-ui-parts/theme'

import { DEFAULT_MENU_WIDTH } from '../constants.js'

const menuDefaultShapeStyles = style({
width: DEFAULT_MENU_WIDTH,
borderRadius: vars.radii.f4,
})

export const shapeStyles = {
default: {
item: '',
menu: menuDefaultShapeStyles,
trigger: '',
},
}

export const selectShapes: Record<SelectShapeName, SelectShape> = shapeStyles
1 change: 1 addition & 0 deletions ui-parts/theme/src/tokens/borders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const borders = {
thinLightGray: '0.5px solid rgba(228, 228, 228, 1)',

normalGray: '1px solid rgba(114, 114, 114, 1)',
normalBlack: '1px solid rgba(0, 0, 0, 1)',
normalSilver: '1px solid rgba(224, 224, 224, 1)',
normalCloudyWhite: '1px solid rgba(228, 228, 228, 1)',
normalBlue: '1px solid rgba(65, 109, 223, 1)',
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -887,14 +887,14 @@ __metadata:
resolution: "@atls-ui-parts/select@workspace:ui-parts/select"
dependencies:
"@atls-ui-parts/layout": "workspace:*"
"@atls-ui-parts/theme": "workspace:*"
"@atls-utils/use-select": "workspace:*"
"@storybook/react": "npm:8.6.12"
"@types/react": "npm:19.1.2"
"@vanilla-extract/css": "npm:1.17.1"
"@vanilla-extract/dynamic": "npm:2.1.2"
clsx: "npm:2.1.1"
framer-motion: "npm:12.23.22"
rainbow-sprinkles: "npm:1.0.0"
react: "npm:19.1.0"
react-dom: "npm:19.1.0"
storybook: "npm:8.6.12"
Expand Down
Loading