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: 2 additions & 0 deletions .changeset/quiet-pans-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
10 changes: 9 additions & 1 deletion packages/swingset/src/lib/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import {
import {
Default,
Disabled as InputDisabled,
Ghost as InputGhost,
Invalid,
meta as inputMeta,
Sizes as InputSizes,
Expand Down Expand Up @@ -261,7 +262,14 @@ const bannerModule: StoryModule = {

const buttonModule: StoryModule = { meta: buttonMeta, Primary, Sizes, Disabled };

const inputModule: StoryModule = { meta: inputMeta, Default, Sizes: InputSizes, Disabled: InputDisabled, Invalid };
const inputModule: StoryModule = {
meta: inputMeta,
Default,
Sizes: InputSizes,
Disabled: InputDisabled,
Invalid,
Ghost: InputGhost,
};

const popoverComponentModule: StoryModule = {
meta: popoverComponentMeta,
Expand Down
9 changes: 9 additions & 0 deletions packages/swingset/src/stories/input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,12 @@ The snippet below reflects the props selected in the table above — change a pr
name='Invalid'
storyModule={InputStories}
/>

### Ghost

The ghost variant keeps the input behavior and sizing while allowing a parent composition to provide the field chrome.

<Story
name='Ghost'
storyModule={InputStories}
/>
14 changes: 13 additions & 1 deletion packages/swingset/src/stories/input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ export { default as __source } from './input.stories?raw';

export const meta: StoryMeta = {
group: 'Components',
status: 'stable',
status: 'wip',
title: 'Input',
source: 'packages/ui/src/mosaic/components/input/input.tsx',
styles: {
_variants: {
size: { sm: {}, md: {}, lg: {} },
variant: { default: {}, ghost: {} },
},
_defaultVariants: {
size: 'md',
variant: 'default',
},
},
};
Expand Down Expand Up @@ -76,3 +78,13 @@ export function Invalid(props: Record<string, unknown>) {
/>
);
}

export function Ghost(props: Record<string, unknown>) {
return (
<Input
{...knobsAsProps(props)}
variant='ghost'
placeholder='Enter text…'
/>
);
}
2 changes: 1 addition & 1 deletion packages/ui/src/mosaic/components/input/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { Input } from './input';
export type { InputProps } from './input';
export type { InputProps, InputVariant } from './input';
8 changes: 8 additions & 0 deletions packages/ui/src/mosaic/components/input/input.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ export const styles = stylex.create({
color: colorVars['--cl-color-input-placeholder'],
},
},
ghost: {
borderRadius: 0,
borderStyle: 'none',
borderWidth: 0,
outline: 'none',
Comment thread
austincalvelage marked this conversation as resolved.
backgroundColor: 'transparent',
boxShadow: 'none',
},
});

export const sizes = stylex.create({
Expand Down
14 changes: 14 additions & 0 deletions packages/ui/src/mosaic/components/input/input.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@ describe('Mosaic Input', () => {
expect(screen.getByRole('textbox', { name: 'Name' })).toHaveAttribute('data-size', size);
});

it('reflects the ghost variant', () => {
render(
<Input
variant='ghost'
aria-label='Search'
/>,
);

const input = screen.getByRole('textbox', { name: 'Search' });
expect(input).toHaveClass('cl-input');
expect(input).toHaveAttribute('data-variant', 'ghost');
expect(input).not.toHaveFocus();
});

it('reflects and forwards the disabled state', () => {
render(
<Input
Expand Down
17 changes: 15 additions & 2 deletions packages/ui/src/mosaic/components/input/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ import { reset } from '../../utils/reset.styles';
import { useOptionalFieldControlProps } from '../field/field.context';
import { sizes, styles } from './input.styles';

/** `default` provides field chrome; `ghost` keeps input sizing while its container provides chrome and focus styling. */
export type InputVariant = 'default' | 'ghost';

export interface InputProps extends Omit<MosaicComponentProps<'input'>, 'size'> {
size?: 'sm' | 'md' | 'lg';
/** Removes field chrome so a parent composition can provide it. @default 'default' */
variant?: InputVariant;
}

export const Input = React.forwardRef<HTMLInputElement, InputProps>(function MosaicInput(
{
size = 'md',
variant = 'default',
disabled: disabledProp,
required: requiredProp,
render,
Expand Down Expand Up @@ -52,8 +58,15 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(function Mos
'aria-labelledby': fieldProps?.['aria-labelledby'] ?? ariaLabelledBy,
'aria-describedby': fieldProps?.['aria-describedby'] ?? ariaDescribedBy,
...mergeStyleProps(
themeProps('input', { size, disabled }),
stylex.props(reset.base, inputStyles.base, styles.base, sizes[size], disabled && inputStyles.disabled),
themeProps('input', { size, variant, disabled }),
stylex.props(
reset.base,
styles.base,
sizes[size],
variant === 'default' && inputStyles.base,
variant === 'ghost' && styles.ghost,
variant === 'default' && disabled && inputStyles.disabled,
),
className,
style,
),
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/mosaic/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export type { HeadingProps } from '../components/heading';
export { Icon, IconFrame } from '../components/icon';
export type { IconFrameProps, IconProps } from '../components/icon';
export { Input } from '../components/input';
export type { InputProps } from '../components/input';
export type { InputProps, InputVariant } from '../components/input';
export { Item } from '../components/item';
export type { ItemProps } from '../components/item';
export { Menu } from '../components/menu';
Expand Down
Loading