Skip to content

Commit

Permalink
feat(DrawerList): add hyphenation prop for hyphens when text wraps ac…
Browse files Browse the repository at this point in the history
…ross multiple lines
  • Loading branch information
langz committed Jan 22, 2025
1 parent e47cc51 commit d9560d3
Show file tree
Hide file tree
Showing 15 changed files with 344 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,26 @@ export const DrawerListExampleDefault = () => (
</Wrapper>
)

export const DrawerListExampleHyphenationAuto = () => (
<Wrapper>
<ComponentBox data-visual-test="drawer-list-hyphenation-auto">
<DrawerList
skip_portal
opened
hyphenation="auto"
prevent_close
data={[
'They may be very large, like pneumonoultramicroscopicsilicovolcanoconiosis, a 45-letter hippopotomonstrosesquipedalian word for black lung disease.',
'The longest word in the Oxford English Dictionary is the 45-letter pneumonoultramicroscopicsilicovolcanoconiosis, which refers to a form of lung disease.',
'According to the Oxford English Dictionary the longest word in the language is pneumonoultramicroscopicsilicovolcanoconiosis, with 45 letters.',
'Well-known for its extreme length, 45 letters, is pneumonoultramicroscopicsilicovolcanoconiosis This is the longest solidly-spelled word in the dictionary.',
]}
observer_element=".dnb-live-preview" // prevents direction to change when scrolling in this example
/>
</ComponentBox>
</Wrapper>
)

export const DrawerListExampleDisabled = () => (
<Wrapper>
<ComponentBox data-visual-test="drawer-list-disabled">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ The following is an overview of all the types that the `data` prop accepts. (The
// The visual content that is shown in one DrawerList item.
// An array can be used to define multiple lines.
type CONTENT = string | React.Node | (string | React.Node)[]
// Defines how words should be hyphenated when text of an item wraps across multiple lines, see https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens.
type HYPHENATION = 'none' | 'manual' | 'auto';

// An array item
type ARRAY_OBJECT = {
Expand All @@ -103,6 +105,7 @@ type ARRAY_OBJECT = {
selectedKey?: string | number
selected_value?: string | React.Node
suffix_value?: string | React.Node
hyphenation?: HYPHENATION
}

// `data` as an array. A list of "ARRAY_OBJECT" types is preferred,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
DrawerListExampleDisabled,
DrawerListExampleSingleItem,
DrawerListExampleMarkup,
DrawerListExampleHyphenationAuto,
} from 'Docs/uilib/components/fragments/drawer-list/Examples'

## Demos
Expand Down Expand Up @@ -38,3 +39,7 @@ import {
**NB:** By using this method you lose currently a lot of the core functionality like keyboard support and other accessibility features.

<DrawerListExampleMarkup />

### DrawerList using hyphenation auto

<DrawerListExampleHyphenationAuto />
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ export default class Autocomplete extends React.PureComponent {
keep_open: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
opened: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
disabled: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
hyphenation: PropTypes.oneOf(['none', 'auto', 'manual']),
stretch: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
skeleton: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
portal_class: PropTypes.string,
Expand Down Expand Up @@ -320,6 +321,7 @@ export default class Autocomplete extends React.PureComponent {
keep_open: false,
opened: null,
disabled: null,
hyphenation: null,
stretch: null,
skeleton: null,
portal_class: null,
Expand Down Expand Up @@ -1788,6 +1790,7 @@ class AutocompleteInstance extends React.PureComponent {
input_ref, // eslint-disable-line
className,
disabled,
hyphenation,
stretch,
skeleton,
triangle_position,
Expand Down Expand Up @@ -2080,6 +2083,7 @@ class AutocompleteInstance extends React.PureComponent {
align_drawer={align_autocomplete}
fixed_position={fixed_position}
disabled={disabled}
hyphenation={hyphenation}
max_height={max_height}
direction={direction}
size={size}
Expand Down
4 changes: 4 additions & 0 deletions packages/dnb-eufemia/src/components/dropdown/Dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ export default class Dropdown extends React.PureComponent {
keep_open: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
opened: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
disabled: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
hyphenation: PropTypes.oneOf(['none', 'auto', 'manual']),
stretch: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
skeleton: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),

Expand Down Expand Up @@ -216,6 +217,7 @@ export default class Dropdown extends React.PureComponent {
keep_open: false,
opened: false,
disabled: null,
hyphenation: null,
stretch: null,
skeleton: null,

Expand Down Expand Up @@ -458,6 +460,7 @@ class DropdownInstance extends React.PureComponent {
default_value,
className,
disabled,
hyphenation,
stretch,
skeleton,
variant,
Expand Down Expand Up @@ -673,6 +676,7 @@ class DropdownInstance extends React.PureComponent {
fixed_position={fixed_position}
enable_body_lock={enable_body_lock}
disabled={disabled}
hyphenation={hyphenation}
max_height={max_height}
direction={direction}
size={size}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import type { SpacingProps } from '../../shared/types';
export type DrawerListDirection = 'auto' | 'top' | 'bottom';
export type DrawerListHyphenation = 'none' | 'manual' | 'auto';
export type DrawerListSize = 'default' | 'small' | 'medium' | 'large';
export type DrawerListAlignDrawer = 'left' | 'right';
export type DrawerListOptionsRender =
Expand Down Expand Up @@ -75,6 +76,10 @@ export interface DrawerListProps {
* Defines the direction of how the drawer-list shows the options list. Can be 'bottom' or 'top'. Defaults to 'auto'.
*/
direction?: DrawerListDirection;
/**
* Defines how words should be hyphenated when text of an item wraps across multiple lines. Can be `none`, `manual` or `auto`. For further information, see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens).
*/
hyphenation?: DrawerListHyphenation;
size?: DrawerListSize;
/**
* Defines the minimum height (in `rem`) of the options list.
Expand Down Expand Up @@ -201,6 +206,10 @@ export type DrawerListItemProps = {
*/
value: string;
}) => void;
/**
* Defines how words should be hyphenated when text of an item wraps across multiple lines. Can be `none`, `manual` or `auto`. For further information, see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens).
*/
hyphenation?: DrawerListHyphenation;
};
export type DrawerListAllProps = DrawerListProps &
SpacingProps &
Expand Down
50 changes: 42 additions & 8 deletions packages/dnb-eufemia/src/fragments/drawer-list/DrawerList.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ class DrawerListInstance extends React.PureComponent {
list_class,
ignore_events,
options_render,
hyphenation,
className,
cache_hash: _cache_hash, // eslint-disable-line
wrapper_element: _wrapper_element, // eslint-disable-line
Expand Down Expand Up @@ -325,7 +326,11 @@ class DrawerListInstance extends React.PureComponent {
}

return (
<DrawerList.Item key={hash} {...liParams}>
<DrawerList.Item
key={hash}
hyphenation={hyphenation || dataItem.hyphenation}
{...liParams}
>
{dataItem}
</DrawerList.Item>
)
Expand Down Expand Up @@ -456,6 +461,7 @@ DrawerList.Options.propTypes = {
DrawerList.Item = React.forwardRef((props, ref) => {
const {
role = 'option', // eslint-disable-line
hyphenation = null, // eslint-disable-line
hash = '', // eslint-disable-line
children, // eslint-disable-line
className = null, // eslint-disable-line
Expand Down Expand Up @@ -502,7 +508,9 @@ DrawerList.Item = React.forwardRef((props, ref) => {
return (
<li {...params} {...rest} ref={ref} key={'li' + hash}>
<span className="dnb-drawer-list__option__inner">
<ItemContent hash={hash}>{children}</ItemContent>
<ItemContent hash={hash} hyphenation={hyphenation}>
{children}
</ItemContent>
</span>
</li>
)
Expand All @@ -511,6 +519,7 @@ DrawerList.Item.displayName = 'DrawerList.Item'
DrawerList.Item.propTypes = {
role: PropTypes.string,
hash: PropTypes.string,
hyphenation: PropTypes.oneOf(['none', 'auto', 'manual']),
children: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func,
Expand All @@ -524,13 +533,18 @@ DrawerList.Item.propTypes = {
disabled: PropTypes.bool,
}

export function ItemContent({ hash = '', children = undefined }) {
export function ItemContent({
hash = '',
children = undefined,
hyphenation = null,
}) {
let content = null

if (Array.isArray(children.content || children)) {
content = (children.content || children).map((item, n) => (
<DrawerListOptionItem
key={hash + n}
hyphenation={hyphenation}
className={`item-nr-${n + 1}`} // "item-nr" is used by CSS
>
{children.render ? children.render(item, hash + n) : item}
Expand All @@ -541,19 +555,28 @@ export function ItemContent({ hash = '', children = undefined }) {
? children.render(children.content, hash, children)
: children.content
if (content) {
content = <DrawerListOptionItem>{content}</DrawerListOptionItem>
content = (
<DrawerListOptionItem hyphenation={hyphenation}>
{content}
</DrawerListOptionItem>
)
}
} else {
content = children && (
<DrawerListOptionItem>{children}</DrawerListOptionItem>
<DrawerListOptionItem hyphenation={hyphenation}>
{children}
</DrawerListOptionItem>
)
}

return Object.prototype.hasOwnProperty.call(children, 'suffix_value') ? (
<>
{content}

<DrawerListOptionItem className="dnb-drawer-list__option__suffix">
<DrawerListOptionItem
className="dnb-drawer-list__option__suffix"
hyphenation={hyphenation}
>
{children.suffix_value}
</DrawerListOptionItem>
</>
Expand All @@ -569,20 +592,31 @@ ItemContent.propTypes = {
function DrawerListOptionItem({
children = undefined,
className = null,
hyphenation = null,
...props
}) {
return (
<span
className={classnames(['dnb-drawer-list__option__item', className])}
className={classnames([
'dnb-drawer-list__option__item',
hyphenation &&
`dnb-drawer-list__option__item--hyphenation-${hyphenation}`,
className,
])}
{...props}
>
{children}
</span>
)
}

DrawerList.HorizontalItem = ({ className = null, ...props }) => (
DrawerList.HorizontalItem = ({
className = null,
hyphenation = null,
...props
}) => (
<DrawerListOptionItem
hyphenation={hyphenation}
className={classnames([
'dnb-drawer-list__option__item--horizontal',
className,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ export const DrawerListProperties: PropertiesTableProps = {
type: 'boolean',
status: 'optional',
},
hyphenation: {
doc: 'Defines how words should be hyphenated when text of an item wraps across multiple lines. Can be `none`, `manual` or `auto`. For further information, see [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens).',
type: 'string',
status: 'optional',
},
no_scroll_animation: {
doc: 'To disable scrolling animation.',
type: 'boolean',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,15 @@ describe.each(['ui', 'sbanken'])('DrawerList for %s', (themeName) => {
})
expect(screenshot).toMatchImageSnapshot()
})

it('have to match the hyphenation auto option', async () => {
const screenshot = await makeScreenshot({
style: {
width: '14rem',
'padding-top': '3rem',
},
selector: '[data-visual-test="drawer-list-hyphenation-auto"]',
})
expect(screenshot).toMatchImageSnapshot()
})
})
Loading

0 comments on commit d9560d3

Please sign in to comment.