-
Notifications
You must be signed in to change notification settings - Fork 70
feat(eds-core-react): ✨ Input - new version for EDS 2.0. using new tokens #4219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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
InputNewto 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 |
packages/eds-core-react/src/components/Input/Input.new.types.ts
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.stories.tsx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.docs.mdx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.types.ts
Outdated
Show resolved
Hide resolved
8629bc0 to
8ea5903
Compare
There was a problem hiding this 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.
There was a problem hiding this 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.
packages/eds-core-react/src/components/Input/Input.new.docs.mdx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.stories.tsx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.docs.mdx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.docs.mdx
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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.
packages/eds-core-react/src/components/Input/Input.new.docs.mdx
Outdated
Show resolved
Hide resolved
3378bbc to
79f9cfc
Compare
There was a problem hiding this 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.
packages/eds-core-react/src/components/Input/Input.new.docs.mdx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.stories.tsx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.stories.tsx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.docs.mdx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.stories.tsx
Outdated
Show resolved
Hide resolved
packages/eds-core-react/src/components/Input/Input.new.stories.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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.
packages/eds-core-react/src/components/Input/Input.new.docs.mdx
Outdated
Show resolved
Hide resolved
| export const OverrideBackground: StoryFn<InputProps> = (args) => { | ||
| return ( | ||
| <InputNew | ||
| style={{ '--eds-color-bg-input': '#fff' } as React.CSSProperties} |
Copilot
AI
Nov 18, 2025
There was a problem hiding this comment.
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.
| style={{ '--eds-color-bg-input': '#fff' } as React.CSSProperties} | |
| style={{ '--eds-color-bg-surface': '#fff' } as React.CSSProperties} |
d861b52 to
dcba3db
Compare
There was a problem hiding this 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.
| <Input | ||
| style={{ '--eds-color-bg-input': '#fff' } as React.CSSProperties} | ||
| {...args} | ||
| /> |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| <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} | |
| /> | |
| </> |
| <div | ||
| {...leftAdornmentsProps} | ||
| ref={setLeftAdornmentsRef} | ||
| className="eds-adornment eds-adornment--left" | ||
| data-color-appearance="neutral" | ||
| > | ||
| {leftAdornments} | ||
| </div> |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| 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" |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| 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" |
| </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" />} | ||
| /> |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| </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> |
| </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" />} | ||
| /> |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| </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> |
| <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" />} | ||
| /> |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| } | ||
|
|
||
| export const Casted: StoryFn<InputProps> = (args) => { | ||
| return <Input as="textarea" {...args} /> |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| return <Input as="textarea" {...args} /> | |
| return ( | |
| <> | |
| <Label htmlFor="input-next-casted-textarea" label="Textarea" /> | |
| <Input as="textarea" id="input-next-casted-textarea" {...args} /> | |
| </> | |
| ) |
| <div | ||
| {...rightAdornmentsProps} | ||
| ref={setRightAdornmentsRef} | ||
| className="eds-adornment eds-adornment--right" | ||
| data-color-appearance="neutral" | ||
| > | ||
| {rightAdornments} | ||
| </div> |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| 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" |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| 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" |
| 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" |
Copilot
AI
Nov 21, 2025
There was a problem hiding this comment.
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.
| 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" |
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
This reverts commit d4e3b42.
- 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
…ndation.css reference
…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
dcba3db to
91b0d34
Compare
…ing variables from eds-tokens
…to align with Figma EDS 2.0 design
…inherit parent color appearance while keeping text neutral
This pull request introduces a new CSS architecture for the
@equinor/eds-core-reactpackage, 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
src/index.css, enabling global styles and tree-shaking. Updated documentation inCSS_ARCHITECTURE.mdexplains the new structure and usage.build/index.cssandbuild/index.min.cssusing PostCSS andpostcss-import, and updatedpackage.jsonto export these files for consumers. [1] [2] [3] [4]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)
InputNewcomponent with vanilla CSS styling and EDS 2.0 tokens, supporting dynamic color appearance, density, adornments, and accessibility features.InputNew, demonstrating usage, migration steps, and key differences from the original Input.InputNew, covering accessibility, prop handling, adornments, density, and EDS 2.0 token mapping.Storybook & Miscellaneous
src/index.cssfor consistent styling in docs. [1] [2]