diff --git a/apps/docs/src/usages/chips.tsx b/apps/docs/src/usages/chips.tsx
index cf32901..2e56171 100644
--- a/apps/docs/src/usages/chips.tsx
+++ b/apps/docs/src/usages/chips.tsx
@@ -1,126 +1,63 @@
-import { Chip, Icon } from 'actify'
+import { ChipGroup, ChipItem, useListData, type Selection } from 'actify'
-export default () => {
- return (
- <>
-
Assist chips
-
-
-
-
- speaker
-
-
-
-
-
-
-
-
-
-
- Filter chips
-
- console.log(value)}>
-
-
- speaker
-
-
-
-
-
+import React from 'react'
- Input chips
-
-
-
-
- speaker
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+export default () => {
+ const [selected, setSelected] = React.useState(new Set(['Actify']))
+ const list = useListData({
+ initialItems: [
+ { id: 1, name: 'Actify' },
+ { id: 2, name: 'Ngroker' },
+ { id: 3, name: 'Taildoor' },
+ { id: 4, name: 'Hugola' }
+ ]
+ })
- Suggestion chips
-
-
-
-
- speaker
-
-
-
-
-
-
-
-
-
- >
+ return (
+
+
+ Actify
+ Ngroker
+ Taildoor
+ Hugola
+
+
list.remove(...keys)}
+ >
+ {(item) => {item.name}}
+
+
+ Laundry
+ Fitness center
+ Parking
+ Swimming pool
+ Breakfast
+
+
+ Current selection (controlled):{' '}
+ {selected === 'all' ? 'all' : [...selected].join(', ')}
+
+
+
+ Actifyjs
+
+
+ Ngroker
+
+
+ Taildoor
+
+
+ Hugola
+
+
+
)
}
diff --git a/packages/actify/src/components/Chips/AssistChip.tsx b/packages/actify/src/components/Chips/AssistChip.tsx
deleted file mode 100644
index 8dba6ea..0000000
--- a/packages/actify/src/components/Chips/AssistChip.tsx
+++ /dev/null
@@ -1,292 +0,0 @@
-'use client'
-
-import React, { useId } from 'react'
-
-import { ChipProps } from './ChipItem'
-import { Elevation } from './../Elevation'
-import { FocusRing } from './../FocusRing'
-import { Ripple } from './../Ripple'
-import { tv } from 'tailwind-variants'
-
-const root = tv({
- base: [
- '[--container-height:var(--md-assist-chip-container-height,32px)]',
- '[--disabled-label-text-color:var(--md-assist-chip-disabled-label-text-color,var(--md-sys-color-surface))]',
- '[--disabled-label-text-opacity:var(--md-assist-chip-disabled-label-text-opacity,0.38)]',
- '[--elevated-container-color:var(--md-assist-chip-elevated-container-color,var(--md-sys-color-surface-container-low,#f7f2fa))]',
- '[--elevated-container-elevation:var(--md-assist-chip-elevated-container-elevation,1)]',
- '[--elevated-container-shadow-color:var(--md-assist-chip-elevated-container-shadow-color,var(--md-sys-color-shadow,#000))]',
- '[--elevated-disabled-container-color:var(--md-assist-chip-elevated-disabled-container-color,var(--md-sys-color-on-surface,#1d1b20))]',
- '[--elevated-disabled-container-elevation:var(--md-assist-chip-elevated-disabled-container-elevation,0)]',
- '[--elevated-disabled-container-opacity:var(--md-assist-chip-elevated-disabled-container-opacity,0.12)]',
- '[--elevated-focus-container-elevation:var(--md-assist-chip-elevated-focus-container-elevation,1)]',
- '[--elevated-hover-container-elevation:var(--md-assist-chip-elevated-hover-container-elevation,2)]',
- '[--elevated-pressed-container-elevation:var(--md-assist-chip-elevated-pressed-container-elevation,1)]',
- '[--focus-label-text-color:var(--md-assist-chip-focus-label-text-color,var(--md-sys-color-on-surface))]',
- '[--hover-label-text-color:var(--md-assist-chip-hover-label-text-color,var(--md-sys-color-on-surface))]',
- '[--hover-state-layer-color:var(--md-assist-chip-hover-state-layer-color,var(--md-sys-color-on-surface))]',
- '[--hover-state-layer-opacity:var(--md-assist-chip-hover-state-layer-opacity,0.08)]',
- '[--label-text-color:var(--md-assist-chip-label-text-color,var(--md-sys-color-on-surface))]',
- '[--label-text-font:var(--md-assist-chip-label-text-font,var(--md-sys-typescale-label-large-font,var(--md-ref-typeface-plain,Roboto)))]',
- '[--label-text-line-height:var(--md-assist-chip-label-text-line-height,var(--md-sys-typescale-label-large-line-height,1.25rem))]',
- '[--label-text-size:var(--md-assist-chip-label-text-size,var(--md-sys-typescale-label-large-size,0.875rem))]',
- '[--label-text-weight:var(--md-assist-chip-label-text-weight,var(--md-sys-typescale-label-large-weight,var(--md-ref-typeface-weight-medium, 500)))]',
- '[--pressed-label-text-color:var(--md-assist-chip-pressed-label-text-color,var(--md-sys-color-on-surface))]',
- '[--pressed-state-layer-color:var(--md-assist-chip-pressed-state-layer-color,var(--md-sys-color-on-surface))]',
- '[--pressed-state-layer-opacity:var(--md-assist-chip-pressed-state-layer-opacity,0.12)]',
- '[--disabled-outline-color:var(--md-assist-chip-disabled-outline-color,var(--md-sys-color-on-surface))]',
- '[--disabled-outline-opacity:var(--md-assist-chip-disabled-outline-opacity,0.12)]',
- '[--focus-outline-color:var(--md-assist-chip-focus-outline-color,var(--md-sys-color-on-surface))]',
- '[--outline-color:var(--md-assist-chip-outline-color,rgb(var(--md-sys-color-outline)))]',
- '[--outline-width:var(--md-assist-chip-outline-width,1px)]',
- '[--disabled-leading-icon-color:var(--md-assist-chip-disabled-leading-icon-color,var(--md-sys-color-on-surface))]',
- '[--disabled-leading-icon-opacity:var(--md-assist-chip-disabled-leading-icon-opacity,0.38)]',
- '[--focus-leading-icon-color:var(--md-assist-chip-focus-leading-icon-color,var(--md-sys-color-primary))]',
- '[--hover-leading-icon-color:var(--md-assist-chip-hover-leading-icon-color,var(--md-sys-color-primary))]',
- '[--leading-icon-color:var(--md-assist-chip-leading-icon-color,var(--md-sys-color-primary))]',
- '[--icon-size:var(--md-assist-chip-icon-size,18px)]',
- '[--pressed-leading-icon-color:var(--md-assist-chip-pressed-leading-icon-color,var(--md-sys-color-primary))]',
- '[--container-shape-start-start:var(--md-assist-chip-container-shape-start-start,var(--md-assist-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--container-shape-start-end:var(--md-assist-chip-container-shape-start-end,var(--md-assist-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--container-shape-end-end:var(--md-assist-chip-container-shape-end-end,var(--md-assist-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--container-shape-end-start:var(--md-assist-chip-container-shape-end-start,var(--md-assist-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--leading-space:var(--md-assist-chip-leading-space,16px)]',
- '[--trailing-space:var(--md-assist-chip-trailing-space,16px)]',
- '[--icon-label-space:var(--md-assist-chip-icon-label-space,8px)]',
- '[--with-leading-icon-leading-space:var(--md-assist-chip-with-leading-icon-leading-space,8px)]',
- // border
- '[border-start-start-radius:var(--container-shape-start-start)]',
- '[border-start-end-radius:var(--container-shape-start-end)]',
- '[border-end-start-radius:var(--container-shape-end-start)]',
- '[border-end-end-radius:var(--container-shape-end-end)]',
- 'inline-flex',
- 'h-[var(--container-height)]',
- 'cursor-pointer',
- '[-webkit-tap-highlight-color:rgba(0,0,0,0)]',
- '[--md-ripple-hover-color:var(--hover-state-layer-color)]',
- '[--md-ripple-hover-opacity:var(--hover-state-layer-opacity)]',
- '[--md-ripple-pressed-color:var(--pressed-state-layer-color)]',
- '[--md-ripple-pressed-opacity:var(--pressed-state-layer-opacity)]'
- ],
- variants: {
- disabled: {
- true: 'pointer-events-none'
- }
- }
-})
-
-const container = tv({
- base: [
- 'flex',
- 'relative',
- 'size-full',
- 'box-border',
- 'rounded-[inherit]',
- // before
- 'before:rounded-[inherit]',
- 'before:absolute',
- 'before:inset-0',
- 'before:pointer-events-none'
- ],
- variants: {
- disabled: {
- true: 'pointer-events-none',
- false: 'cursor-pointer'
- }
- }
-})
-
-const outline = tv({
- base: [
- 'inset-0',
- 'absolute',
- 'rounded-[inherit]',
- 'pointer-events-none',
- '[border:var(--outline-width)_solid_var(--outline-color)]'
- ],
- variants: {
- disabled: {
- true: [
- '[border-color:var(--disabled-outline-color)]',
- 'opacity-[--disabled-outline-opacity]'
- ]
- }
- }
-})
-
-const action = tv({
- base: [
- 'p-0',
- 'flex',
- 'relative',
- 'no-underline',
- 'outline-none',
- '[border:none]',
- 'items-baseline',
- 'appearance-none',
- '[background:none]',
- 'rounded-[inherit]'
- ],
- variants: {
- primary: {
- true: ['ps-[var(--leading-space)]', 'pe-[var(--trailing-space)]']
- },
- hasIcon: {
- true: ''
- }
- },
- compoundVariants: [
- {
- primary: true,
- hasIcon: true,
- className: 'ps-[var(--with-leading-icon-leading-space)]'
- }
- ]
-})
-
-const icon = tv({
- base: ['z-[1]', 'flex', 'relative', 'self-center', 'fill-current'],
- variants: {
- leading: {
- true: 'text[--leading-icon-color]'
- }
- }
-})
-
-const label = tv({
- base: [
- 'flex',
- 'z-[1]',
- 'h-full',
- 'select-none',
- 'items-center',
- 'text-ellipsis',
- 'whitespace-nowrap',
- 'font-[--label-text-weight]',
- 'text-[--label-text-color]',
- 'leading-[--label-text-line-height]',
- '[font-family:var(--label-text-font)]',
- '[font-size:var(--label-text-size)]'
- ],
- variants: {
- disabled: {
- true: [
- 'text-[--disabled-label-text-color]',
- 'opacity-[--disabled-label-text-opacity]'
- ]
- }
- }
-})
-
-const touch = tv({
- base: [
- 'h-12',
- 'z-[1]',
- 'w-full',
- 'absolute',
- 'inset-[50%_0_0]',
- '-translate-y-1/2'
- ]
-})
-
-const ring = tv({
- base: [
- 'text-primary',
- '[--md-focus-ring-shape-start-start:var(--container-shape-start-start)]',
- '[--md-focus-ring-shape-start-end:var(--container-shape-start-end)]',
- '[--md-focus-ring-shape-end-end:var(--container-shape-end-end)]',
- '[--md-focus-ring-shape-end-start:var(--container-shape-end-start)]'
- ]
-})
-
-interface AssitChipProps extends Omit {}
-
-const AssitChip = (props: AssitChipProps) => {
- const {
- id,
- href,
- target,
- className,
- elevated,
- children,
- disabled = false,
- label: labelString,
- ...rest
- } = props
-
- const chipId = id || `actify-assit-chip${useId()}`
-
- const hasIcon = React.Children.toArray(children).find(
- (child) =>
- // @ts-ignore
- child?.type?.displayName == 'Actify.Icon'
- )
- ? true
- : false
-
- const renderLeadingIcon = () => {
- return (
-
- {hasIcon &&
- React.Children.toArray(children).filter(
- // @ts-ignore
- (child) => child?.type?.displayName == 'Actify.Icon'
- )}
-
- )
- }
-
- const renderPrimaryAction = ({
- href,
- primary
- }: {
- href?: string
- primary: boolean
- }) => {
- return href ? (
-
- {renderLeadingIcon()}
- {labelString}
-
-
- ) : (
-
- )
- }
-
- return (
-
-
- {elevated ? (
-
- ) : (
-
- )}
-
-
- {renderPrimaryAction({ href, primary: true })}
-
-
- )
-}
-
-AssitChip.displayName = 'Actify.AssitChip'
-
-export { AssitChip }
diff --git a/packages/actify/src/components/Chips/Chip.tsx b/packages/actify/src/components/Chips/Chip.tsx
index 585d616..77d863e 100644
--- a/packages/actify/src/components/Chips/Chip.tsx
+++ b/packages/actify/src/components/Chips/Chip.tsx
@@ -1,30 +1,74 @@
-'use client'
+import { AriaTagProps, TagAria, useFocusRing, useTag } from 'react-aria'
-import { Children, cloneElement, isValidElement } from 'react'
-import { ChipProps, ChipProvider } from './ChipContext'
+import { FocusRing } from '../FocusRing'
+import { Icon } from '../Icon'
+import { IconButton } from './../Button'
+import { ListState } from 'react-stately'
+import React from 'react'
+import { Ripple } from '../Ripple'
+import clsx from 'clsx'
+import styles from './chip.module.css'
-import { ChipItem } from './ChipItem'
+interface ChipProps extends AriaTagProps {
+ state: ListState
+}
+
+const Chip = (props: ChipProps) => {
+ let { item, state } = props
+ let ref = React.useRef(null)
+ let { focusProps, isFocusVisible } = useFocusRing({ within: true })
+ let { rowProps, gridCellProps, removeButtonProps, allowsRemoving } = useTag(
+ props,
+ state,
+ ref
+ )
-const Chip = (props: ChipProps) => {
- const { children, ...rest } = props
return (
-
- {Children.map(
- children,
- (child, index) =>
- isValidElement(child) &&
- cloneElement(child, {
- index,
- // @ts-ignore
- ...child.props
- })
- )}
-
+
+
+ {/* outline */}
+
+ {/* focus ring */}
+ {isFocusVisible && }
+ {/* ripple */}
+
+ {/* leading icon */}
+
+
+ check
+
+
+ {item.rendered}
+ {allowsRemoving && (
+
+
+ close
+
+
+ )}
+
+
)
}
-Chip.displayName = 'Actify.Chip'
-
-export default Object.assign(Chip, {
- Item: ChipItem
-})
+export { Chip }
diff --git a/packages/actify/src/components/Chips/ChipContext.tsx b/packages/actify/src/components/Chips/ChipContext.tsx
deleted file mode 100644
index 8b6c8b3..0000000
--- a/packages/actify/src/components/Chips/ChipContext.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-'use client'
-
-import React, { createContext, useContext, useMemo, useState } from 'react'
-
-export interface ChipProps extends React.PropsWithChildren {
- // if there is a selected value, it means a controlled component, need onChange handler
- selected?: number[]
- defaultSelected?: number[]
- onChange?: (value: number[] | []) => void
-}
-
-const ChipContext = createContext({})
-
-interface ChipProviderProps extends React.PropsWithChildren {}
-
-export const ChipProvider = (props: ChipProviderProps) => {
- const { selected, defaultSelected, onChange, children } = props
-
- const isControlled = typeof selected != 'undefined'
- const hasDefaultSelected = typeof defaultSelected != 'undefined'
- const [internalSelected, setInternalSelected] = useState(
- hasDefaultSelected ? defaultSelected : []
- )
- const chipSelected = isControlled ? selected : internalSelected
-
- const handleChange = (event: any) => {
- onChange?.(event)
- if (!isControlled) {
- setInternalSelected(event)
- }
- }
-
- return (
-
- {children}
-
- )
-}
-
-export const useChip = () => {
- const context = useContext(ChipContext)
- if (context == null) {
- throw new Error('Chip components must be wrapped in ')
- }
- return context
-}
diff --git a/packages/actify/src/components/Chips/ChipGroup.tsx b/packages/actify/src/components/Chips/ChipGroup.tsx
new file mode 100644
index 0000000..8998e86
--- /dev/null
+++ b/packages/actify/src/components/Chips/ChipGroup.tsx
@@ -0,0 +1,39 @@
+import type { AriaTagGroupProps } from 'react-aria'
+import { Chip } from './Chip'
+import { Label } from '../Label'
+import React from 'react'
+import styles from './chip-group.module.css'
+import { useListState } from 'react-stately'
+import { useTagGroup } from 'react-aria'
+
+const ChipGroup = (props: AriaTagGroupProps) => {
+ const { label, description, errorMessage } = props
+ const ref = React.useRef(null)
+
+ const state = useListState(props)
+ const { gridProps, labelProps, descriptionProps, errorMessageProps } =
+ useTagGroup(props, state, ref)
+
+ return (
+
+
+
+ {[...state.collection].map((item) => (
+
+ ))}
+
+ {description && (
+
+ {description}
+
+ )}
+ {errorMessage && (
+
+ {errorMessage}
+
+ )}
+
+ )
+}
+
+export { ChipGroup }
diff --git a/packages/actify/src/components/Chips/ChipItem.tsx b/packages/actify/src/components/Chips/ChipItem.tsx
deleted file mode 100644
index c2e99a5..0000000
--- a/packages/actify/src/components/Chips/ChipItem.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-'use client'
-
-import { AssitChip } from './AssistChip'
-import { FilterChip } from './FilterChip'
-import { InputChip } from './InputChip'
-import React from 'react'
-import { SuggestionChip } from './SuggestionChip'
-
-export interface ChipProps extends React.ComponentProps<'div'> {
- index?: number
- href?: string
- label?: string
- elevated?: boolean
- disabled?: boolean
- removable?: boolean
- removeOnly?: boolean
- target?: React.HTMLAttributeAnchorTarget
- type?: 'assit' | 'filter' | 'input' | 'suggestion'
-}
-
-const ChipItem = (props: ChipProps) => {
- const { type = 'assit', ...rest } = props
-
- return (
-
- {type == 'assit' && }
- {type == 'filter' && }
- {type == 'input' && }
- {type == 'suggestion' && }
-
- )
-}
-
-export { ChipItem }
diff --git a/packages/actify/src/components/Chips/FilterChip.tsx b/packages/actify/src/components/Chips/FilterChip.tsx
deleted file mode 100644
index 3b7644c..0000000
--- a/packages/actify/src/components/Chips/FilterChip.tsx
+++ /dev/null
@@ -1,381 +0,0 @@
-'use client'
-
-import React, { useId, useState } from 'react'
-
-import { ChipProps } from './ChipItem'
-import { Elevation } from './../Elevation'
-import { FocusRing } from './../FocusRing'
-import RemoveButton from './RemoveButton'
-import { Ripple } from './../Ripple'
-import { motion } from 'framer-motion'
-import { tv } from 'tailwind-variants'
-import { useChip } from './ChipContext'
-
-const root = tv({
- base: [
- '[--container-height:var(--md-filter-chip-container-height,32px)]',
- '[--disabled-label-text-color:var(--md-filter-chip-disabled-label-text-color,var(--md-sys-color-on-surface))]',
- '[--disabled-label-text-opacity:var(--md-filter-chip-disabled-label-text-opacity,0.38)]',
-
- '[--elevated-container-color:var(--md-filter-chip-elevated-container-color,var(--md-sys-color-surface-container-low,#f7f2fa))]',
- '[--elevated-container-elevation:var(--md-filter-chip-elevated-container-elevation,1)]',
- '[--elevated-container-shadow-color:var(--md-filter-chip-elevated-container-shadow-color,var(--md-sys-color-shadow,#000))]',
- '[--elevated-disabled-container-color:var(--md-filter-chip-elevated-disabled-container-color,var(--md-sys-color-on-surface,#1d1b20))]',
- '[--elevated-disabled-container-elevation:var(--md-filter-chip-elevated-disabled-container-elevation,0)]',
- '[--elevated-disabled-container-opacity:var(--md-filter-chip-elevated-disabled-container-opacity,0.12)]',
- '[--elevated-focus-container-elevation:var(--md-filter-chip-elevated-focus-container-elevation,1)]',
- '[--elevated-hover-container-elevation:var(--md-filter-chip-elevated-hover-container-elevation,2)]',
- '[--elevated-pressed-container-elevation:var(--md-filter-chip-elevated-pressed-container-elevation,1)]',
-
- '[--focus-label-text-color:var(--md-filter-chip-focus-label-text-color,var(--md-sys-color-on-surface))]',
- '[--hover-label-text-color:var(--md-filter-chip-hover-label-text-color,var(--md-sys-color-on-surface))]',
- '[--hover-state-layer-color:var(--md-filter-chip-hover-state-layer-color,var(--md-sys-color-on-surface))]',
- '[--hover-state-layer-opacity:var(--md-filter-chip-hover-state-layer-opacity,0.08)]',
- '[--label-text-color:var(--md-filter-chip-label-text-color,var(--md-sys-color-on-surface))]',
- '[--label-text-font:var(--md-filter-chip-label-text-font,var(--md-sys-typescale-label-large-font,var(--md-ref-typeface-plain,Roboto)))]',
- '[--label-text-line-height:var(--md-filter-chip-label-text-line-height,var(--md-sys-typescale-label-large-line-height,1.25rem))]',
- '[--label-text-size:var(--md-filter-chip-label-text-size,var(--md-sys-typescale-label-large-size,0.875rem))]',
- '[--label-text-weight:var(--md-filter-chip-label-text-weight,var(--md-sys-typescale-label-large-weight,var(--md-ref-typeface-weight-medium, 500)))]',
- '[--pressed-label-text-color:var(--md-filter-chip-pressed-label-text-color,var(--md-sys-color-on-surface))]',
- '[--pressed-state-layer-color:var(--md-filter-chip-pressed-state-layer-color,var(--md-sys-color-on-surface))]',
- '[--pressed-state-layer-opacity:var(--md-filter-chip-pressed-state-layer-opacity,0.12)]',
- '[--disabled-outline-color:var(--md-filter-chip-disabled-outline-color,var(--md-sys-color-on-surface))]',
- '[--disabled-outline-opacity:var(--md-filter-chip-disabled-outline-opacity,0.12)]',
- '[--disabled-trailing-icon-color:var(--md-filter-chip-disabled-trailing-icon-color,var(--md-sys-color-on-surface))]',
- '[--disabled-trailing-icon-opacity:var(--md-filter-chip-disabled-trailing-icon-opacity,0.38)]',
- '[--focus-outline-color:var(--md-filter-chip-focus-outline-color,var(--md-sys-color-on-surface))]',
- '[--outline-color:var(--md-filter-chip-outline-color,rgb(var(--md-sys-color-outline)))]',
- '[--outline-width:var(--md-filter-chip-outline-width,1px)]',
-
- '[--disabled-leading-icon-color:var(--md-filter-chip-disabled-leading-icon-color,var(--md-sys-color-on-surface))]',
- '[--disabled-leading-icon-opacity:var(--md-filter-chip-disabled-leading-icon-opacity,0.38)]',
- '[--focus-leading-icon-color:var(--md-filter-chip-focus-leading-icon-color,var(--md-sys-color-primary))]',
- '[--hover-leading-icon-color:var(--md-filter-chip-hover-leading-icon-color,var(--md-sys-color-primary))]',
- '[--leading-icon-color:var(--md-filter-chip-leading-icon-color,var(--md-sys-color-primary))]',
- '[--icon-size:var(--md-filter-chip-icon-size,18px)]',
- '[--pressed-leading-icon-color:var(--md-filter-chip-pressed-leading-icon-color,var(--md-sys-color-primary))]',
-
- '[--disabled-trailing-icon-color:var(--md-filter-chip-disabled-trailing-icon-color,var(--md-sys-color-on-surface,#1d1b20))]',
- '[--disabled-trailing-icon-opacity:var(--md-filter-chip-disabled-trailing-icon-opacity,0.38)]',
- '[--selected-focus-trailing-icon-color:var(--md-filter-chip-selected-focus-trailing-icon-color,var(--md-sys-color-on-secondary-container,#1d192b))]',
- '[--selected-hover-trailing-icon-color:var(--md-filter-chip-selected-hover-trailing-icon-color,var(--md-sys-color-on-secondary-container,#1d192b))]',
- '[--selected-pressed-trailing-icon-color:var(--md-filter-chip-selected-pressed-trailing-icon-color,var(--md-sys-color-on-secondary-container,#1d192b))]',
- '[--selected-trailing-icon-color:var(--md-filter-chip-selected-trailing-icon-color,var(--md-sys-color-on-secondary-container,#1d192b))]',
- '[--focus-trailing-icon-color:var(--md-filter-chip-focus-trailing-icon-color,var(--md-sys-color-on-surface-variant,#49454f))]',
- '[--hover-trailing-icon-color:var(--md-filter-chip-hover-trailing-icon-color,var(--md-sys-color-on-surface-variant,#49454f))]',
- '[--pressed-trailing-icon-color:var(--md-filter-chip-pressed-trailing-icon-color,var(--md-sys-color-on-surface-variant,#49454f))]',
- '[--trailing-icon-color:var(--md-filter-chip-trailing-icon-color,var(--md-sys-color-on-surface-variant,#49454f))]',
-
- '[--container-shape-start-start:var(--md-filter-chip-container-shape-start-start,var(--md-filter-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--container-shape-start-end:var(--md-filter-chip-container-shape-start-end,var(--md-filter-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--container-shape-end-end:var(--md-filter-chip-container-shape-end-end,var(--md-filter-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--container-shape-end-start:var(--md-filter-chip-container-shape-end-start,var(--md-filter-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--leading-space:var(--md-filter-chip-leading-space,16px)]',
- '[--trailing-space:var(--md-filter-chip-trailing-space,16px)]',
- '[--icon-label-space:var(--md-filter-chip-icon-label-space,8px)]',
- '[--with-leading-icon-leading-space:var(--md-filter-chip-with-leading-icon-leading-space,8px)]',
- '[--with-trailing-icon-trailing-space:var(--md-filter-chip-with-trailing-icon-trailing-space,8px)]',
- // border
- '[border-start-start-radius:var(--container-shape-start-start)]',
- '[border-start-end-radius:var(--container-shape-start-end)]',
- '[border-end-start-radius:var(--container-shape-end-start)]',
- '[border-end-end-radius:var(--container-shape-end-end)]',
- 'inline-flex',
- 'h-[var(--container-height)]',
- 'cursor-pointer',
- '[-webkit-tap-highlight-color:rgba(0,0,0,0)]',
- '[--md-ripple-hover-color:var(--hover-state-layer-color)]',
- '[--md-ripple-hover-opacity:var(--hover-state-layer-opacity)]',
- '[--md-ripple-pressed-color:var(--pressed-state-layer-color)]',
- '[--md-ripple-pressed-opacity:var(--pressed-state-layer-opacity)]',
- '[--selected-outline-width:var(--md-filter-chip-selected-outline-width,0px)]',
- '[--selected-container-color:var(--md-filter-chip-selected-container-color,rgb(var(--md-sys-color-secondary-container)))]',
- '[--selected-leading-icon-color:var(--md-filter-chip-selected-leading-icon-color,var(--md-sys-color-on-secondary-container,#1d192b))]'
- ],
- variants: {
- disabled: {
- true: 'pointer-events-none'
- }
- }
-})
-
-const container = tv({
- base: [
- 'flex',
- 'relative',
- 'size-full',
- 'box-border',
- 'rounded-[inherit]',
- // before
- 'before:rounded-[inherit]',
- 'before:absolute',
- 'before:inset-0',
- 'before:pointer-events-none'
- ],
- variants: {
- disabled: {
- true: 'pointer-events-none',
- false: 'cursor-pointer'
- },
- selected: {
- true: [
- '[--md-ripple-hover-color:var(--selected-hover-state-layer-color)]',
- '[--md-ripple-hover-opacity:var(--selected-hover-state-layer-opacity)]',
- '[--md-ripple-pressed-color:var(--selected-pressed-state-layer-color)]',
- '[--md-ripple-pressed-opacity:var(--selected-pressed-state-layer-opacity)]',
- // before
- 'before:[background:var(--selected-container-color)]'
- ]
- }
- }
-})
-
-const outline = tv({
- base: [
- 'inset-0',
- 'absolute',
- 'rounded-[inherit]',
- 'pointer-events-none',
- '[border:var(--outline-width)_solid_var(--outline-color)]'
- ],
- variants: {
- selected: {
- true: '[border-width:var(--selected-outline-width)]'
- },
- disabled: {
- true: [
- '[border-color:var(--disabled-outline-color)]',
- 'opacity-[--disabled-outline-opacity]'
- ]
- }
- }
-})
-
-const action = tv({
- base: [
- 'p-0',
- 'flex',
- 'relative',
- 'no-underline',
- 'outline-none',
- '[border:none]',
- 'items-baseline',
- 'appearance-none',
- '[background:none]',
- 'rounded-[inherit]'
- ],
- variants: {
- primary: {
- true: ['ps-[var(--leading-space)]', 'pe-[var(--trailing-space)]']
- },
- hasIcon: {
- true: ''
- },
- removable: {
- true: 'pe-0'
- }
- },
- compoundVariants: [
- {
- primary: true,
- hasIcon: true,
- className: 'ps-[var(--with-leading-icon-leading-space)]'
- }
- ]
-})
-
-const icon = tv({
- base: ['z-[1]', 'flex', 'relative', 'self-center', 'fill-current'],
- variants: {
- leading: {
- true: 'text[--leading-icon-color]'
- }
- }
-})
-
-const checkmark = tv({
- base: ['size-[--icon-size]', 'text-[var(--selected-leading-icon-color)]']
-})
-
-const label = tv({
- base: [
- 'flex',
- 'z-[1]',
- 'h-full',
- 'select-none',
- 'items-center',
- 'text-ellipsis',
- 'whitespace-nowrap',
- 'font-[--label-text-weight]',
- 'text-[--label-text-color]',
- 'leading-[--label-text-line-height]',
- '[font-family:var(--label-text-font)]',
- '[font-size:var(--label-text-size)]'
- ],
- variants: {
- disabled: {
- true: [
- 'text-[--disabled-label-text-color]',
- 'opacity-[--disabled-label-text-opacity]'
- ]
- }
- }
-})
-
-const touch = tv({
- base: [
- 'h-12',
- 'z-[1]',
- 'w-full',
- 'absolute',
- 'inset-[50%_0_0]',
- '-translate-y-1/2'
- ]
-})
-
-const ring = tv({
- base: [
- 'text-primary',
- '[--md-focus-ring-shape-start-start:var(--container-shape-start-start)]',
- '[--md-focus-ring-shape-start-end:var(--container-shape-start-end)]',
- '[--md-focus-ring-shape-end-end:var(--container-shape-end-end)]',
- '[--md-focus-ring-shape-end-start:var(--container-shape-end-start)]'
- ]
-})
-
-interface FilterChipProps extends Omit {}
-
-const FilterChip = (props: FilterChipProps) => {
- const {
- id,
- href,
- index,
- target,
- children,
- className,
- elevated = false,
- disabled = false,
- removable = false,
- label: labelString,
- ...rest
- } = props
-
- const chipId = id || `actify-filter-chip${useId()}`
-
- const chip = useChip()
- const [hide, setHide] = useState(false)
- const selected = chip.selected?.includes(index!)
-
- const hasIcon = React.Children.toArray(children).find(
- (child) =>
- // @ts-ignore
- child?.type?.displayName == 'Actify.Icon'
- )
- ? true
- : false
-
- const renderLeadingIcon = () => {
- if (!selected) {
- return (
- hasIcon && (
-
- {React.Children.toArray(children).filter(
- // @ts-ignore
- (child) => child?.type?.displayName == 'Actify.Icon'
- )}
-
- )
- )
- }
- return (
-
-
-
- )
- }
-
- const renderPrimaryAction = ({
- href,
- primary
- }: {
- href?: string
- primary: boolean
- }) => {
- return href ? (
-
- {renderLeadingIcon()}
- {labelString}
-
-
- ) : (
-
- )
- }
-
- const handleClick = () => {
- if (selected) {
- const _index = chip.selected?.findIndex((item) => item == index)
- const _selected = [...chip.selected!]
- _selected.splice(_index as number, 1)
- chip.onChange?.(_selected)
- } else {
- const _selected = [...chip.selected!]
- _selected.push(index!)
- chip.onChange?.(_selected)
- }
- }
-
- if (hide) {
- return null
- }
-
- return (
-
-
- {elevated ? (
-
- ) : (
-
- )}
-
-
- {renderPrimaryAction({ href, primary: true })}
- {removable && (
-
- )}
-
-
- )
-}
-
-FilterChip.displayName = 'Actify.FilterChip'
-
-export { FilterChip }
diff --git a/packages/actify/src/components/Chips/InputChip.tsx b/packages/actify/src/components/Chips/InputChip.tsx
deleted file mode 100644
index 17e6b9a..0000000
--- a/packages/actify/src/components/Chips/InputChip.tsx
+++ /dev/null
@@ -1,339 +0,0 @@
-'use client'
-
-import React, { useId, useState } from 'react'
-
-import { ChipProps } from './ChipItem'
-import { Elevation } from './../Elevation'
-import { FocusRing } from './../FocusRing'
-import RemoveButton from './RemoveButton'
-import { Ripple } from './../Ripple'
-import { tv } from 'tailwind-variants'
-
-const root = tv({
- base: [
- '[--container-height:var(--md-input-chip-container-height,32px)]',
- '[--disabled-label-text-color:var(--md-input-chip-disabled-label-text-color,var(--md-sys-color-on-surface))]',
- '[--disabled-label-text-opacity:var(--md-input-chip-disabled-label-text-opacity,0.38)]',
-
- '[--elevated-container-color:var(--md-input-chip-elevated-container-color,var(--md-sys-color-surface-container-low,#f7f2fa))]',
- '[--elevated-container-elevation:var(--md-input-chip-elevated-container-elevation,1)]',
- '[--elevated-container-shadow-color:var(--md-input-chip-elevated-container-shadow-color,var(--md-sys-color-shadow,#000))]',
- '[--elevated-disabled-container-color:var(--md-input-chip-elevated-disabled-container-color,var(--md-sys-color-on-surface,#1d1b20))]',
- '[--elevated-disabled-container-elevation:var(--md-input-chip-elevated-disabled-container-elevation,0)]',
- '[--elevated-disabled-container-opacity:var(--md-input-chip-elevated-disabled-container-opacity,0.12)]',
- '[--elevated-focus-container-elevation:var(--md-input-chip-elevated-focus-container-elevation,1)]',
- '[--elevated-hover-container-elevation:var(--md-input-chip-elevated-hover-container-elevation,2)]',
- '[--elevated-pressed-container-elevation:var(--md-input-chip-elevated-pressed-container-elevation,1)]',
-
- '[--focus-label-text-color:var(--md-input-chip-focus-label-text-color,var(--md-sys-color-on-surface))]',
- '[--hover-label-text-color:var(--md-input-chip-hover-label-text-color,var(--md-sys-color-on-surface))]',
- '[--hover-state-layer-color:var(--md-input-chip-hover-state-layer-color,var(--md-sys-color-on-surface))]',
- '[--hover-state-layer-opacity:var(--md-input-chip-hover-state-layer-opacity,0.08)]',
- '[--label-text-color:var(--md-input-chip-label-text-color,var(--on-surface))]',
- '[--label-text-font:var(--md-input-chip-label-text-font,var(--md-sys-typescale-label-large-font,var(--md-ref-typeface-plain,Roboto)))]',
- '[--label-text-line-height:var(--md-input-chip-label-text-line-height,var(--md-sys-typescale-label-large-line-height,1.25rem))]',
- '[--label-text-size:var(--md-input-chip-label-text-size,var(--md-sys-typescale-label-large-size,0.875rem))]',
- '[--label-text-weight:var(--md-input-chip-label-text-weight,var(--md-sys-typescale-label-large-weight,var(--md-ref-typeface-weight-medium, 500)))]',
- '[--pressed-label-text-color:var(--md-input-chip-pressed-label-text-color,var(--md-sys-color-on-surface)))]',
- '[--pressed-state-layer-color:var(--md-input-chip-pressed-state-layer-color,var(--md-sys-color-on-surface))]',
- '[--pressed-state-layer-opacity:var(--md-input-chip-pressed-state-layer-opacity,0.12)]',
- '[--disabled-outline-color:var(--md-input-chip-disabled-outline-color,var(--md-sys-color-on-surface))]',
- '[--disabled-outline-opacity:var(--md-input-chip-disabled-outline-opacity,0.12)]',
- '[--disabled-trailing-icon-color:var(--md-filter-chip-disabled-trailing-icon-color,var(--md-sys-color-on-surface))]',
- '[--disabled-trailing-icon-opacity:var(--md-filter-chip-disabled-trailing-icon-opacity,0.38)]',
- '[--focus-outline-color:var(--md-input-chip-focus-outline-color,var(--md-sys-color-on-surface))]',
- '[--outline-color:var(--md-input-chip-outline-color,rgb(var(--md-sys-color-outline)))]',
- '[--outline-width:var(--md-input-chip-outline-width,1px)]',
-
- '[--disabled-leading-icon-color:var(--md-input-chip-disabled-leading-icon-color,var(--md-sys-color-on-surface))]',
- '[--disabled-leading-icon-opacity:var(--md-input-chip-disabled-leading-icon-opacity,0.38)]',
- '[--focus-leading-icon-color:var(--md-input-chip-focus-leading-icon-color,var(--md-sys-color-primary))]',
- '[--hover-leading-icon-color:var(--md-input-chip-hover-leading-icon-color,var(--md-sys-color-primary)]',
- '[--leading-icon-color:var(--md-input-chip-leading-icon-color,var(--md-sys-color-primary))]',
- '[--icon-size:var(--md-input-chip-icon-size,18px)]',
- '[--pressed-leading-icon-color:var(--md-input-chip-pressed-leading-icon-color,var(--md-sys-color-primary))]',
-
- '[--disabled-trailing-icon-color:var(--md-input-chip-disabled-trailing-icon-color,var(--md-sys-color-on-surface,#1d1b20))]',
- '[--disabled-trailing-icon-opacity:var(--md-input-chip-disabled-trailing-icon-opacity,0.38)]',
- '[--selected-focus-trailing-icon-color:var(--md-input-chip-selected-focus-trailing-icon-color,var(--md-sys-color-on-secondary-container,#1d192b))]',
- '[--selected-hover-trailing-icon-color:var(--md-input-chip-selected-hover-trailing-icon-color,var(--md-sys-color-on-secondary-container,#1d192b))]',
- '[--selected-pressed-trailing-icon-color:var(--md-input-chip-selected-pressed-trailing-icon-color,var(--md-sys-color-on-secondary-container,#1d192b))]',
- '[--selected-trailing-icon-color:var(--md-input-chip-selected-trailing-icon-color,var(--md-sys-color-on-secondary-container,#1d192b))]',
- '[--focus-trailing-icon-color:var(--md-input-chip-focus-trailing-icon-color,var(--md-sys-color-on-surface-variant,#49454f))]',
- '[--hover-trailing-icon-color:var(--md-input-chip-hover-trailing-icon-color,var(--md-sys-color-on-surface-variant,#49454f))]',
- '[--pressed-trailing-icon-color:var(--md-input-chip-pressed-trailing-icon-color,var(--md-sys-color-on-surface-variant,#49454f))]',
- '[--trailing-icon-color:var(--md-input-chip-trailing-icon-color,var(--md-sys-color-on-surface-variant,#49454f))]',
-
- '[--container-shape-start-start:var(--md-input-chip-container-shape-start-start,var(--md-input-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--container-shape-start-end:var(--md-input-chip-container-shape-start-end,var(--md-input-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--container-shape-end-end:var(--md-input-chip-container-shape-end-end,var(--md-input-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--container-shape-end-start:var(--md-input-chip-container-shape-end-start,var(--md-input-chip-container-shape,var(--md-sys-shape-corner-small,8px)))]',
- '[--leading-space:var(--md-input-chip-leading-space,16px)]',
- '[--trailing-space:var(--md-input-chip-trailing-space,16px)]',
- '[--icon-label-space:var(--md-input-chip-icon-label-space,8px)]',
- '[--with-leading-icon-leading-space:var(--md-input-chip-with-leading-icon-leading-space,8px)]',
- '[--with-trailing-icon-trailing-space:var(--md-filter-chip-with-trailing-icon-trailing-space,8px)]',
- // border
- '[border-start-start-radius:var(--container-shape-start-start)]',
- '[border-start-end-radius:var(--container-shape-start-end)]',
- '[border-end-start-radius:var(--container-shape-end-start)]',
- '[border-end-end-radius:var(--container-shape-end-end)]',
- 'inline-flex',
- 'h-[var(--container-height)]',
- 'cursor-pointer',
- '[-webkit-tap-highlight-color:rgba(0,0,0,0)]',
- '[--md-ripple-hover-color:var(--hover-state-layer-color)]',
- '[--md-ripple-hover-opacity:var(--hover-state-layer-opacity)]',
- '[--md-ripple-pressed-color:var(--pressed-state-layer-color)]',
- '[--md-ripple-pressed-opacity:var(--pressed-state-layer-opacity)]'
- ],
- variants: {
- disabled: {
- true: 'pointer-events-none'
- }
- }
-})
-
-const container = tv({
- base: [
- 'flex',
- 'relative',
- 'size-full',
- 'box-border',
- 'rounded-[inherit]',
- // before
- 'before:rounded-[inherit]',
- 'before:absolute',
- 'before:inset-0',
- 'before:pointer-events-none'
- ],
- variants: {
- disabled: {
- true: 'pointer-events-none',
- false: 'cursor-pointer'
- }
- }
-})
-
-const outline = tv({
- base: [
- 'inset-0',
- 'absolute',
- 'rounded-[inherit]',
- 'pointer-events-none',
- '[border:var(--outline-width)_solid_var(--outline-color)]'
- ],
- variants: {
- disabled: {
- true: [
- '[border-color:var(--disabled-outline-color)]',
- 'opacity-[--disabled-outline-opacity]'
- ]
- }
- }
-})
-
-const action = tv({
- base: [
- 'p-0',
- 'flex',
- 'relative',
- 'no-underline',
- 'outline-none',
- '[border:none]',
- 'items-baseline',
- 'appearance-none',
- '[background:none]',
- 'rounded-[inherit]'
- ],
- variants: {
- primary: {
- true: ['ps-[var(--leading-space)]', 'pe-[var(--trailing-space)]']
- },
- hasIcon: {
- true: ''
- },
- removable: {
- true: 'pe-0'
- }
- },
- compoundVariants: [
- {
- primary: true,
- hasIcon: true,
- className: 'ps-[var(--with-leading-icon-leading-space)]'
- }
- ]
-})
-
-const icon = tv({
- base: ['z-[1]', 'flex', 'relative', 'self-center', 'fill-current'],
- variants: {
- leading: {
- true: 'text[--leading-icon-color]'
- }
- }
-})
-
-const label = tv({
- base: [
- 'flex',
- 'z-[1]',
- 'h-full',
- 'select-none',
- 'items-center',
- 'text-ellipsis',
- 'whitespace-nowrap',
- 'font-[--label-text-weight]',
- 'text-[--label-text-color]',
- 'leading-[--label-text-line-height]',
- '[font-family:var(--label-text-font)]',
- '[font-size:var(--label-text-size)]'
- ],
- variants: {
- disabled: {
- true: [
- 'text-[--disabled-label-text-color]',
- 'opacity-[--disabled-label-text-opacity]'
- ]
- }
- }
-})
-
-const touch = tv({
- base: [
- 'h-12',
- 'z-[1]',
- 'w-full',
- 'absolute',
- 'inset-[50%_0_0]',
- '-translate-y-1/2'
- ]
-})
-
-const ring = tv({
- base: [
- 'text-primary',
- '[--md-focus-ring-shape-start-start:var(--container-shape-start-start)]',
- '[--md-focus-ring-shape-start-end:var(--container-shape-start-end)]',
- '[--md-focus-ring-shape-end-end:var(--container-shape-end-end)]',
- '[--md-focus-ring-shape-end-start:var(--container-shape-end-start)]'
- ]
-})
-
-interface InputChipProps extends Omit {}
-
-const InputChip = (props: InputChipProps) => {
- const {
- id,
- href,
- index,
- target,
- children,
- className,
- elevated = false,
- disabled = false,
- removable = true,
- removeOnly = false,
- label: content,
- ...rest
- } = props
-
- const chipId = id || `actify-assit-chip${useId()}`
-
- const [hide, setHide] = useState(false)
-
- const hasIcon = React.Children.toArray(children).find(
- (child) =>
- // @ts-ignore
- child?.type?.displayName == 'Actify.Icon'
- )
- ? true
- : false
-
- const renderLeadingIcon = () => {
- return (
- hasIcon && (
-
- {React.Children.toArray(children).filter(
- // @ts-ignore
- (child) => child?.type?.displayName == 'Actify.Icon'
- )}
-
- )
- )
- }
-
- const renderPrimaryAction = ({
- href,
- primary
- }: {
- href?: string
- primary: boolean
- }) => {
- if (href) {
- return (
-
- {renderLeadingIcon()}
- {content}
-
-
- )
- }
-
- if (removeOnly) {
- return (
-
- {renderLeadingIcon()}
- {content}
-
-
- )
- }
-
- return (
-
- )
- }
-
- if (hide) {
- return null
- }
-
- return (
-
-
- {elevated ? (
-
- ) : (
-
- )}
-
-
- {renderPrimaryAction({ href, primary: true })}
- {removable && }
-
-
- )
-}
-
-InputChip.displayName = 'Actify.InputChip'
-
-export { InputChip }
diff --git a/packages/actify/src/components/Chips/RemoveButton.tsx b/packages/actify/src/components/Chips/RemoveButton.tsx
deleted file mode 100644
index f21ed92..0000000
--- a/packages/actify/src/components/Chips/RemoveButton.tsx
+++ /dev/null
@@ -1,96 +0,0 @@
-import React, { useId } from 'react'
-
-import { FocusRing } from './../FocusRing'
-import { Ripple } from './../Ripple'
-import { tv } from 'tailwind-variants'
-
-const action = tv({
- base: [
- 'p-0',
- 'flex',
- 'relative',
- 'no-underline',
- 'outline-none',
- 'items-center',
- 'justify-center',
- '[border:none]',
- 'appearance-none',
- 'rounded-[inherit]',
- '[background:none]',
- 'ps-[--icon-label-space]',
- 'pe-[--with-trailing-icon-trailing-space]'
- ]
-})
-
-const icon = tv({
- base: [
- 'z-[1]',
- 'flex',
- 'relative',
- 'self-center',
- 'fill-current',
- 'size-[--icon-size]',
- 'text-[--trailing-icon-color]'
- ],
- variants: {
- selected: {
- true: ['text-[--selected-trailing-icon-color]']
- },
- disabled: {
- true: [
- 'text-[--disabled-trailing-icon-color]',
- 'opacity-[--disabled-trailing-icon-opacity]'
- ]
- }
- }
-})
-
-const touch = tv({
- base: [
- 'z-[1]',
- 'h-12',
- 'w-full',
- 'absolute',
- 'inset-[50%_0_0]',
- '-translate-y-1/2'
- ]
-})
-
-interface RemoveButtonProps extends React.ComponentProps<'button'> {
- selected?: boolean
- setHide: (hide: boolean) => void
-}
-
-const RemoveButton = (props: RemoveButtonProps) => {
- const { selected, disabled, setHide } = props
- const id = useId()
-
- const handleClick = (e: React.MouseEvent) => {
- e.stopPropagation()
- setHide(true)
- }
- return (
-
- )
-}
-
-export default RemoveButton
diff --git a/packages/actify/src/components/Chips/SuggestionChip.tsx b/packages/actify/src/components/Chips/SuggestionChip.tsx
deleted file mode 100644
index 1e1ea85..0000000
--- a/packages/actify/src/components/Chips/SuggestionChip.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import { AssitChip } from './AssistChip'
-
-export { AssitChip as SuggestionChip }
diff --git a/packages/actify/src/components/Chips/chip-group.module.css b/packages/actify/src/components/Chips/chip-group.module.css
new file mode 100644
index 0000000..35b4f34
--- /dev/null
+++ b/packages/actify/src/components/Chips/chip-group.module.css
@@ -0,0 +1,11 @@
+.chip-group {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+}
+
+.chip-group [role='grid'] {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
diff --git a/packages/actify/src/components/Chips/chip.module.css b/packages/actify/src/components/Chips/chip.module.css
new file mode 100644
index 0000000..ea8ee6c
--- /dev/null
+++ b/packages/actify/src/components/Chips/chip.module.css
@@ -0,0 +1,239 @@
+.chip {
+ --_container-height: var(--md-assist-chip-container-height, 32px);
+ --_disabled-label-text-color: var(
+ --md-assist-chip-disabled-label-text-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_disabled-label-text-opacity: var(
+ --md-assist-chip-disabled-label-text-opacity,
+ 0.38
+ );
+ --_elevated-container-color: var(
+ --md-assist-chip-elevated-container-color,
+ rgb(var(--md-sys-color-surface-container-low))
+ );
+ --_elevated-container-elevation: var(
+ --md-assist-chip-elevated-container-elevation,
+ 1
+ );
+ --_elevated-container-shadow-color: var(
+ --md-assist-chip-elevated-container-shadow-color,
+ rgb(var(--md-sys-color-shadow))
+ );
+ --_elevated-disabled-container-color: var(
+ --md-assist-chip-elevated-disabled-container-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_elevated-disabled-container-elevation: var(
+ --md-assist-chip-elevated-disabled-container-elevation,
+ 0
+ );
+ --_elevated-disabled-container-opacity: var(
+ --md-assist-chip-elevated-disabled-container-opacity,
+ 0.12
+ );
+ --_elevated-focus-container-elevation: var(
+ --md-assist-chip-elevated-focus-container-elevation,
+ 1
+ );
+ --_elevated-hover-container-elevation: var(
+ --md-assist-chip-elevated-hover-container-elevation,
+ 2
+ );
+ --_elevated-pressed-container-elevation: var(
+ --md-assist-chip-elevated-pressed-container-elevation,
+ 1
+ );
+ --_focus-label-text-color: var(
+ --md-assist-chip-focus-label-text-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_hover-label-text-color: var(
+ --md-assist-chip-hover-label-text-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_hover-state-layer-color: var(
+ --md-assist-chip-hover-state-layer-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_hover-state-layer-opacity: var(
+ --md-assist-chip-hover-state-layer-opacity,
+ 0.08
+ );
+ --_label-text-color: var(
+ --md-assist-chip-label-text-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_label-text-font: var(
+ --md-assist-chip-label-text-font,
+ var(
+ --md-sys-typescale-label-large-font,
+ var(--md-ref-typeface-plain, Roboto)
+ )
+ );
+ --_label-text-line-height: var(
+ --md-assist-chip-label-text-line-height,
+ var(--md-sys-typescale-label-large-line-height, 1.25rem)
+ );
+ --_label-text-size: var(
+ --md-assist-chip-label-text-size,
+ var(--md-sys-typescale-label-large-size, 0.875rem)
+ );
+ --_label-text-weight: var(
+ --md-assist-chip-label-text-weight,
+ var(
+ --md-sys-typescale-label-large-weight,
+ var(--md-ref-typeface-weight-medium, 500)
+ )
+ );
+ --_pressed-label-text-color: var(
+ --md-assist-chip-pressed-label-text-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_pressed-state-layer-color: var(
+ --md-assist-chip-pressed-state-layer-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_pressed-state-layer-opacity: var(
+ --md-assist-chip-pressed-state-layer-opacity,
+ 0.12
+ );
+ --_disabled-outline-color: var(
+ --md-assist-chip-disabled-outline-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_disabled-outline-opacity: var(
+ --md-assist-chip-disabled-outline-opacity,
+ 0.12
+ );
+ --_focus-outline-color: var(
+ --md-assist-chip-focus-outline-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_outline-color: var(
+ --md-assist-chip-outline-color,
+ rgb(var(--md-sys-color-outline))
+ );
+ --_outline-width: var(--md-assist-chip-outline-width, 1px);
+ --_selected-container-color: var(
+ --md-filter-chip-selected-container-color,
+ rgb(var(--md-sys-color-secondary-container))
+ );
+ --_selected-outline-width: var(--md-filter-chip-selected-outline-width, 0px);
+ --_selected-label-text-color: var(
+ --md-filter-chip-selected-label-text-color,
+ rgb(var(--md-sys-color-on-secondary-container))
+ );
+ --_disabled-leading-icon-color: var(
+ --md-assist-chip-disabled-leading-icon-color,
+ rgb(var(--md-sys-color-on-surface))
+ );
+ --_disabled-leading-icon-opacity: var(
+ --md-assist-chip-disabled-leading-icon-opacity,
+ 0.38
+ );
+ --_focus-leading-icon-color: var(
+ --md-assist-chip-focus-leading-icon-color,
+ rgb(var(--md-sys-color-primary))
+ );
+ --_hover-leading-icon-color: var(
+ --md-assist-chip-hover-leading-icon-color,
+ rgb(var(--md-sys-color-primary))
+ );
+ --_leading-icon-color: var(
+ --md-assist-chip-leading-icon-color,
+ rgb(var(--md-sys-color-primary))
+ );
+ --_icon-size: var(--md-assist-chip-icon-size, 18px);
+ --_pressed-leading-icon-color: var(
+ --md-assist-chip-pressed-leading-icon-color,
+ rgb(var(--md-sys-color-primary))
+ );
+ --_container-shape-start-start: var(
+ --md-assist-chip-container-shape-start-start,
+ var(--md-assist-chip-container-shape, var(--md-sys-shape-corner-small, 8px))
+ );
+ --_container-shape-start-end: var(
+ --md-assist-chip-container-shape-start-end,
+ var(--md-assist-chip-container-shape, var(--md-sys-shape-corner-small, 8px))
+ );
+ --_container-shape-end-end: var(
+ --md-assist-chip-container-shape-end-end,
+ var(--md-assist-chip-container-shape, var(--md-sys-shape-corner-small, 8px))
+ );
+ --_container-shape-end-start: var(
+ --md-assist-chip-container-shape-end-start,
+ var(--md-assist-chip-container-shape, var(--md-sys-shape-corner-small, 8px))
+ );
+ --_leading-space: var(--md-assist-chip-leading-space, 16px);
+ --_trailing-space: var(--md-assist-chip-trailing-space, 16px);
+ --_icon-label-space: var(--md-assist-chip-icon-label-space, 8px);
+ --_with-leading-icon-leading-space: var(
+ --md-assist-chip-with-leading-icon-leading-space,
+ 8px
+ );
+ --_icon-size: var(--md-filter-chip-icon-size, 18px);
+ outline: none;
+}
+.cell {
+ position: relative;
+ padding-inline-start: var(--_leading-space);
+ padding-inline-end: var(--_trailing-space);
+ border-start-start-radius: var(--_container-shape-start-start);
+ border-start-end-radius: var(--_container-shape-start-end);
+ border-end-start-radius: var(--_container-shape-end-start);
+ border-end-end-radius: var(--_container-shape-end-end);
+ display: inline-flex;
+ align-items: center;
+ height: var(--_container-height);
+ cursor: pointer;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+ --md-ripple-hover-color: var(--_hover-state-layer-color);
+ --md-ripple-hover-opacity: var(--_hover-state-layer-opacity);
+ --md-ripple-pressed-color: var(--_pressed-state-layer-color);
+ --md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity);
+}
+.cell:before {
+ border-radius: inherit;
+ content: '';
+ inset: 0;
+ pointer-events: none;
+ position: absolute;
+}
+[aria-selected='true'] .cell:before {
+ background: var(--_selected-container-color);
+}
+.leading-icon {
+ display: none;
+ padding-inline-end: var(--_icon-label-space);
+}
+[aria-selected='true'] .leading-icon {
+ display: flex;
+ z-index: 1;
+}
+.cell.has-trailing {
+ padding-inline-end: 0;
+}
+.label {
+ z-index: 1;
+ align-items: center;
+ color: var(--_label-text-color);
+ display: flex;
+ font-family: var(--_label-text-font);
+ font-size: var(--_label-text-size);
+ font-weight: var(--_label-text-weight);
+ height: 100%;
+ line-height: var(--_label-text-line-height);
+ overflow: hidden;
+ user-select: none;
+}
+[aria-selected='true'] .label {
+ color: var(--_selected-label-text-color);
+}
+.outline {
+ border: var(--_outline-width) solid var(--_outline-color);
+ border-radius: inherit;
+ inset: 0;
+ pointer-events: none;
+ position: absolute;
+}
diff --git a/packages/actify/src/components/Chips/index.ts b/packages/actify/src/components/Chips/index.ts
index 877198b..0873e26 100644
--- a/packages/actify/src/components/Chips/index.ts
+++ b/packages/actify/src/components/Chips/index.ts
@@ -1 +1,2 @@
-export { default as Chip } from './Chip'
+export { ChipGroup } from './ChipGroup'
+export { useListData, Item as ChipItem, type Selection } from 'react-stately'