Skip to content

Conversation

@millus
Copy link
Collaborator

@millus millus commented Nov 10, 2025

This pull request introduces a new CSS architecture for the @equinor/eds-core-react package, centralizing component styles and updating the build pipeline to output global CSS files. The changes also include the addition of a new Input component (InputNew) based on vanilla CSS and EDS 2.0 tokens, with comprehensive documentation and automated tests. These updates improve maintainability, enable automatic tree-shaking, and reduce bundle size by removing styled-components from the new input implementation.

CSS Architecture & Build System

  • Centralized all component CSS imports in src/index.css, enabling global styles and tree-shaking. Updated documentation in CSS_ARCHITECTURE.md explains the new structure and usage.
  • Modified Rollup config to build and output build/index.css and build/index.min.css using PostCSS and postcss-import, and updated package.json to export these files for consumers. [1] [2] [3] [4]
  • Added the generated CSS files (build/index.css, build/index.min.css) containing EDS 2.0 token-based styles for the Input component and its states. [1] [2]

Input Component (EDS 2.0)

  • Added InputNew component with vanilla CSS styling and EDS 2.0 tokens, supporting dynamic color appearance, density, adornments, and accessibility features.
  • Created Storybook documentation for InputNew, demonstrating usage, migration steps, and key differences from the original Input.
  • Added comprehensive tests for InputNew, covering accessibility, prop handling, adornments, density, and EDS 2.0 token mapping.

Storybook & Miscellaneous

  • Updated Storybook preview configuration to import global component CSS from src/index.css for consistent styling in docs. [1] [2]

@millus millus requested a review from vnys as a code owner November 10, 2025 09:00
Copilot AI review requested due to automatic review settings November 10, 2025 09:00
@millus millus linked an issue Nov 10, 2025 that may be closed by this pull request
@millus millus marked this pull request as draft November 10, 2025 09:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a new version of the Input component that replaces styled-components with vanilla CSS, aligning with the project's modernization efforts towards EDS 2.0. The new component maintains full functional parity with the original while using CSS custom properties for styling.

Key Changes

  • New Input component implementation using vanilla CSS instead of styled-components
  • Complete test coverage matching the original component
  • Comprehensive Storybook documentation and examples
  • Exported as InputNew to allow gradual migration

Reviewed Changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/eds-core-react/src/components/Input/index.ts Exports the new component as InputNew
packages/eds-core-react/src/components/Input/Input.new.types.ts Type definitions for the new Input component
packages/eds-core-react/src/components/Input/Input.new.tsx Main component implementation using vanilla CSS
packages/eds-core-react/src/components/Input/Input.new.test.tsx Comprehensive test suite with accessibility checks
packages/eds-core-react/src/components/Input/Input.new.stories.tsx Storybook stories demonstrating all variants and features
packages/eds-core-react/src/components/Input/Input.new.docs.mdx Documentation with usage examples and migration guide
packages/eds-core-react/src/components/Input/Input.new.css CSS implementation with BEM naming convention
packages/eds-core-react/src/components/Input/__snapshots__/Input.new.test.tsx.snap Jest snapshot for regression testing

@millus millus changed the title feat(eds-core) ✨ Input - new version for EDS 2.0. using new tokens feat(eds-core): ✨ Input - new version for EDS 2.0. using new tokens Nov 10, 2025
@millus millus changed the title feat(eds-core): ✨ Input - new version for EDS 2.0. using new tokens feat(eds-core-react): ✨ Input - new version for EDS 2.0. using new tokens Nov 10, 2025
@millus millus requested a review from Copilot November 12, 2025 11:57
Copilot finished reviewing on behalf of millus November 12, 2025 11:58
@millus millus force-pushed the feat/4194-text-input-update-code-in-eds-core branch from 8629bc0 to 8ea5903 Compare November 12, 2025 12:24
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@millus millus requested a review from Copilot November 13, 2025 08:15
Copilot finished reviewing on behalf of millus November 13, 2025 08:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.

@millus millus requested a review from Copilot November 13, 2025 08:37
Copilot finished reviewing on behalf of millus November 13, 2025 08:41
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

@millus millus force-pushed the feat/4194-text-input-update-code-in-eds-core branch from 3378bbc to 79f9cfc Compare November 14, 2025 09:22
@millus millus requested a review from Copilot November 14, 2025 13:38
Copilot finished reviewing on behalf of millus November 14, 2025 13:42
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 10 comments.

@millus millus requested a review from Copilot November 18, 2025 11:44
Copilot finished reviewing on behalf of millus November 18, 2025 11:49
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.

export const OverrideBackground: StoryFn<InputProps> = (args) => {
return (
<InputNew
style={{ '--eds-color-bg-input': '#fff' } as React.CSSProperties}
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSS variable --eds-color-bg-input being overridden here doesn't match the actual CSS variable used in input.new.css. The component uses --eds-color-bg-surface (line 10 of input.new.css) for the background color. This should be changed to '--eds-color-bg-surface': '#fff' to actually affect the input background.

Suggested change
style={{ '--eds-color-bg-input': '#fff' } as React.CSSProperties}
style={{ '--eds-color-bg-surface': '#fff' } as React.CSSProperties}

Copilot uses AI. Check for mistakes.
@millus millus requested a review from Copilot November 21, 2025 09:51
Copilot finished reviewing on behalf of millus November 21, 2025 09:57
@millus millus force-pushed the feat/4194-text-input-update-code-in-eds-core branch from d861b52 to dcba3db Compare November 21, 2025 09:58
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 10 comments.

Comment on lines 304 to 307
<Input
style={{ '--eds-color-bg-input': '#fff' } as React.CSSProperties}
{...args}
/>
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Input component is missing an accessible label. Add a Label component with matching htmlFor and id, or add an aria-label attribute to ensure screen reader users can identify the purpose of the input.

Suggested change
<Input
style={{ '--eds-color-bg-input': '#fff' } as React.CSSProperties}
{...args}
/>
<>
<Label htmlFor="input-next-override-background" label="Override background" />
<Input
id="input-next-override-background"
style={{ '--eds-color-bg-input': '#fff' } as React.CSSProperties}
{...args}
/>
</>

Copilot uses AI. Check for mistakes.
Comment on lines 75 to 82
<div
{...leftAdornmentsProps}
ref={setLeftAdornmentsRef}
className="eds-adornment eds-adornment--left"
data-color-appearance="neutral"
>
{leftAdornments}
</div>
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The leftAdornmentsProps are spread before setting className, ref, and data-color-appearance, which allows consumers to override these critical attributes and potentially break the component's styling and functionality. Spread leftAdornmentsProps after setting the required attributes, or destructure and exclude className, ref, and data-color-appearance from the spread.

Copilot uses AI. Check for mistakes.
Comment on lines +169 to +181
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-3"
type="date"
defaultValue="Input text"
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using type="date" with defaultValue="Input text" is invalid. Date inputs require a value in the format yyyy-MM-dd (e.g., "2023-01-15"). Either change the type to "text" or use a valid date format for the defaultValue.

Suggested change
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-3"
type="date"
defaultValue="Input text"
defaultValue="2023-01-15"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="2023-01-15"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-3"
type="date"
defaultValue="2023-01-15"

Copilot uses AI. Check for mistakes.
Comment on lines +165 to +177
</Button>
<Input
id="input-next-icons-1"
type="date"
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Input field is missing an accessible label. Add either a <Label> component with matching htmlFor, or an aria-label attribute to ensure screen reader users can identify the purpose of the input.

Suggested change
</Button>
<Input
id="input-next-icons-1"
type="date"
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
</Button>
<Label htmlFor="input-next-icons-1">Date input with left icon</Label>
<Input
id="input-next-icons-1"
type="date"
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Label htmlFor="input-next-icons-2">Date input with right icon</Label>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Label htmlFor="input-next-icons-3">Date input with both icons</Label>

Copilot uses AI. Check for mistakes.
Comment on lines +165 to +177
</Button>
<Input
id="input-next-icons-1"
type="date"
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Input field is missing an accessible label. Add either a <Label> component with matching htmlFor, or an aria-label attribute to ensure screen reader users can identify the purpose of the input.

Suggested change
</Button>
<Input
id="input-next-icons-1"
type="date"
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
</Button>
<Label htmlFor="input-next-icons-1">Date input with left icon</Label>
<Input
id="input-next-icons-1"
type="date"
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Label htmlFor="input-next-icons-2">Date input with right icon</Label>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Label htmlFor="input-next-icons-3">Date input with both icons</Label>

Copilot uses AI. Check for mistakes.
Comment on lines +178 to +184
<Input
id="input-next-icons-3"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Input field is missing an accessible label. Add either a <Label> component with matching htmlFor, or an aria-label attribute to ensure screen reader users can identify the purpose of the input.

Copilot uses AI. Check for mistakes.
}

export const Casted: StoryFn<InputProps> = (args) => {
return <Input as="textarea" {...args} />
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The textarea (casted Input) is missing an accessible label. Add a Label component with matching htmlFor and id, or add an aria-label attribute to ensure screen reader users can identify the purpose of the textarea.

Suggested change
return <Input as="textarea" {...args} />
return (
<>
<Label htmlFor="input-next-casted-textarea" label="Textarea" />
<Input as="textarea" id="input-next-casted-textarea" {...args} />
</>
)

Copilot uses AI. Check for mistakes.
Comment on lines 96 to 103
<div
{...rightAdornmentsProps}
ref={setRightAdornmentsRef}
className="eds-adornment eds-adornment--right"
data-color-appearance="neutral"
>
{rightAdornments}
</div>
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rightAdornmentsProps are spread before setting className, ref, and data-color-appearance, which allows consumers to override these critical attributes and potentially break the component's styling and functionality. Spread rightAdornmentsProps after setting the required attributes, or destructure and exclude className, ref, and data-color-appearance from the spread.

Copilot uses AI. Check for mistakes.
Comment on lines +169 to +181
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-3"
type="date"
defaultValue="Input text"
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using type="date" with defaultValue="Input text" is invalid. Date inputs require a value in the format yyyy-MM-dd (e.g., "2023-01-15"). Either change the type to "text" or use a valid date format for the defaultValue.

Suggested change
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-3"
type="date"
defaultValue="Input text"
defaultValue="2023-01-15"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="2023-01-15"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-3"
type="date"
defaultValue="2023-01-15"

Copilot uses AI. Check for mistakes.
Comment on lines +169 to +181
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-3"
type="date"
defaultValue="Input text"
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using type="date" with defaultValue="Input text" is invalid. Date inputs require a value in the format yyyy-MM-dd (e.g., "2023-01-15"). Either change the type to "text" or use a valid date format for the defaultValue.

Suggested change
defaultValue="Input text"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="Input text"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-3"
type="date"
defaultValue="Input text"
defaultValue="2023-01-15"
leftAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-2"
type="date"
defaultValue="2023-01-15"
rightAdornments={icon && <Icon name="done" title="Done" />}
/>
<Input
id="input-next-icons-3"
type="date"
defaultValue="2023-01-15"

Copilot uses AI. Check for mistakes.
Step 1 of EDS 2.0 migration for Input component:

- Remove styled-components dependencies
- Create Input.css with @layer eds-components wrapper
- Add eds- namespace prefix to all class names (.eds-input, .eds-field, .eds-adornment)
- Add support for 'as' prop to enable Textarea polymorphism
- Convert tests from toHaveStyleRule to toHaveStyle for inline styles
- Update snapshots for new class names

All functionality preserved:
- ✅ Token-based styling with density support
- ✅ Variants (default, error, warning, success)
- ✅ Disabled and read-only states
- ✅ Left/right adornments with dynamic width
- ✅ Textarea component working with multiline/rowsMax
- ✅ All 57 tests passing across Input, TextField, Search, Autocomplete

CSS protection layers:
- eds- namespace prevents class name collisions
- @layer eds-components gives consumers cascade control
- Scoped selectors (.eds-input .eds-field) prevent style leaking
- Migrated Input component from styled-components to vanilla CSS
- Exported as InputNew to enable gradual migration
- Full feature parity with original Input component
- All 13 tests passing
- Storybook stories match original exactly

Key changes:
- Uses CSS custom properties instead of styled-components
- @layer eds-components for proper CSS layering
- BEM naming convention with eds- prefix
- Disabled placeholder maintains darker color (rgba(111, 111, 111, 1))
- Disabled value text uses lighter color (rgba(190, 190, 190, 1))
- WebKit-specific fixes for disabled inputs
- Supports all variants, states, adornments, and textarea casting

This is Step 1 of the EDS 2.0 Input migration. Step 2 will migrate
to the new EDS 2.0 color token system.
- Migrate from Input.tokens.ts to EDS 2.0 dynamic tokens
- Use data-color-appearance for semantic color switching
- Fixed spacing: XS size + stretched proportions + LG font (16px)
- Respect parent data-density attribute (spacious/comfortable)
- Simplified props: removed unused data attribute props
- Updated tests to use Testing Library best practices (24 tests passing)
- Removed eslint-disable comments from tests
- Updated documentation with EDS 2.0 token usage examples
- Cleaned up stories: removed SelectableSpacing and ColorAppearances
- Component now uses align-items: center instead of fixed height

BREAKING CHANGE: Removed leftAdornmentsWidth and rightAdornmentsWidth props.
Adornment widths are now calculated automatically.
- Create centralized styles.css file to prevent duplicate CSS imports
- Import styles.css in main index.ts entry point
- Remove CSS import from Input.new.tsx component file
- Add styles.css export to package.json exports
- Update Storybook preview to import global styles
- Add CSS_ARCHITECTURE.md documentation
- Fix lab package jest config to transform style-inject module

Benefits:
- No duplicate CSS when users import components
- Single CSS bundle improves performance
- Easier maintenance with centralized CSS imports
- Automatic tree-shaking support
- Change list markers from asterisks to hyphens per markdown guidelines
- Fix typo: Accessiblity -> Accessibility in stories and docs
- Update CSS import to use lowercase filename (input.new.css)
- Add leftAdornmentsWidth/rightAdornmentsWidth props for manual width control
- Remove data-testid from public API (follows original Input pattern)
- Simplify testing by using .parentElement like original Input
- Add documentation about performance optimization with manual widths
- All 27 tests passing
- Add leftAdornmentsWidth/rightAdornmentsWidth props for manual width control
- Remove data-testid from public API (follows original Input pattern)
- Simplify testing by using .parentElement like original Input
- Add documentation about performance optimization with manual widths
- All 27 tests passing
…actor to invalid prop

- Replace box-shadow underline with 1px border + rounded corners
- Implement 2px focus ring using outline with -2px offset (no layout shift)
- Use squished line-height for better vertical text centering
- Fix hover to exclude disabled and readonly states
- Ensure text always uses strong color (not affected by validation state)
- Force adornments to neutral appearance
- Force disabled inputs to neutral appearance with subtle text

BREAKING: Refactor variant to invalid prop
- Remove success and warning variants (only error/invalid remains)
- Change API from variant="error" to invalid (boolean)
- More semantic and aligns with HTML5 form validation
- Prepares for future ValidationMessage component architecture

- Add comprehensive Light & Dark Mode story
- Update all stories, documentation, and tests
- Rename "Variants" to "Validation States" throughout
- Add three Rollup configurations for JS and CSS builds
- Output formatted CSS to build/styles.css (3.5KB)
- Output minified CSS to build/styles.min.css (2.1KB)
- Use postcss-import to bundle @import statements
- Clean separation: CSS in build/, JS/TS in dist/
- Export both CSS versions in package.json
- Update CSS_ARCHITECTURE.md with concise documentation
- No new dependencies (uses existing postcss packages)
- Rename src/styles.css to src/index.css for better naming convention
- Rename build outputs: styles.css → index.css, styles.min.css → index.min.css
- Update package.json exports to use index.css naming
- Update all import references in src/index.ts and .storybook/preview.mjs
- Update rollup.config.js to build index.css files
- Update CSS_ARCHITECTURE.md documentation
- Rebuild CSS files with new naming
…put component

- Create src/components/next/ folder structure for EDS 2.0 components
- Add dual entry points: index.ts (stable) and index.next.ts (next)
- Configure subpath exports for @equinor/eds-core-react/next
- Migrate Input component to next/ folder with vanilla CSS
- Set up centralized CSS bundling in index.css
- Add Next (EDS 2.0) section in Storybook with Introduction
- Update rollup config for dual builds
- Configure Storybook ordering to show Introduction first
- Remove old Input.new files
- Update CSS_ARCHITECTURE.md documentation
@millus millus force-pushed the feat/4194-text-input-update-code-in-eds-core branch from dcba3db to 91b0d34 Compare November 26, 2025 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text Input - Update code in eds-core

3 participants