Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
36 changes: 35 additions & 1 deletion src/components/ActionButton/ActionButton.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
## General

The Action Button is used to trigger actions like editing, etc.
It is responsive and on mobile devices only the icon is shown (unless you add the fixed property to always show the label)

It is responsive and on mobile devices only the icon is shown (unless you add the fixed property to always show the label).


## States
It consists of three states, depending on the cursor's distance to the click-area:

* Default: The label is hidden and only the icon is displayed
* Approximation: If the cursor is over a containing element (or near the button) the icon's base and the label appear
* Hover: When the cursor directly approaches the click-area the base will expand and include the label. Also the label and the icon will come closer.

## Types

Different types help the user to differentiate between important and less important actions.
- **Default**: Any possible actions
- **Primary**: Actions with a clear intention
- **Constructive**: Communicates that something is created through this action.
- **Destructive**: Communicates that something is removed, deleted or destroyed through this action.

## Additional modifiers

On Tablet and Mobile Devices the action button is always displayed as the "Standalone with Base" variant to increase and show the click-area. If the standalone version cannot satisfactory represent the action it can be assisted with the label ("Fixed Label") depending on the context.

- **fixed**: ensures that the label is always shown
- **standalone**: hides the label
- **base**: always shows the base


```js
Expand Down Expand Up @@ -56,6 +83,13 @@ const rows = [
destructive: <ActionButton iconRight="remove-outline" buttonType="destructive" label="Label" />,
confirmative: <ActionButton iconRight="refresh" buttonType="confirmative" label="Label" />,
},
{
id: 'Fixed Label with Base',
default: <ActionButton iconRight="edit" buttonType="default" label="Label" fixed base />,
primary: <ActionButton iconRight="add-outline" buttonType="primary" label="Label" fixed base />,
destructive: <ActionButton iconRight="remove-outline" buttonType="destructive" label="Label" fixed base />,
confirmative: <ActionButton iconRight="refresh" buttonType="confirmative" label="Label" fixed base />,
},
];

<CardTable
Expand Down
24 changes: 12 additions & 12 deletions src/components/Avatar/Avatar.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import React from 'react';
import { oneOf, string } from 'prop-types';
import classnames from 'classnames';
import { pascalize } from 'humps';
import * as olt from '@lightelligence/styles';

import {
AVATAR_TYPE_USER,
AVATAR_TYPE_TENANT,
AVATAR_SIZE_LARGE,
AVATAR_SIZE_MEDIUM,
} from '../../constants';

export const Avatar = ({ type, size, name, className, ...props }) => {
export const Avatar = ({ type, size, name, color, className, ...props }) => {
const shortName = name.substr(0, 1);

return (
<i
{...props}
className={classnames(
olt.Avatar,
size === AVATAR_SIZE_LARGE && olt.AvatarLarge,
size === 'm' && olt.AvatarMedium,
size === 'l' && olt.AvatarLarge,
type === 'tenant' ? olt.AvatarTenant : olt.AvatarUser,
color &&
(olt[`uColor${pascalize(color)}`] || olt[`Icon${pascalize(color)}`]),
className,
)}
>
Expand All @@ -31,11 +28,14 @@ export const Avatar = ({ type, size, name, className, ...props }) => {
Avatar.propTypes = {
name: string.isRequired,
className: string,
size: oneOf([AVATAR_SIZE_MEDIUM, AVATAR_SIZE_LARGE]),
type: oneOf([AVATAR_TYPE_USER, AVATAR_TYPE_TENANT]).isRequired,
color: string,
size: oneOf(['s', 'm', 'l']),
type: oneOf(['user', 'tenant']),
};

Avatar.defaultProps = {
className: null,
size: AVATAR_SIZE_MEDIUM,
size: 'm',
color: null,
type: 'user',
};
43 changes: 38 additions & 5 deletions src/components/Avatar/Avatar.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,45 @@ Avatar for User **Jim**

```js
import { Avatar } from '@lightelligence/react';
<Avatar type="user" name="Jim"></Avatar>
<Avatar name="Jim" />
```

Large Size
# Size

```js
import { Avatar } from '@lightelligence/react';
<Avatar type="user" name="Jim" size="l"></Avatar>
```
import { Avatar, FloatingList } from '@lightelligence/react';
<FloatingList>
<Avatar name="Jim" size="s" />
<Avatar name="Jim" size="m" />
<Avatar name="Jim" size="l" />
</FloatingList>
```

# Colors

The Avatar can be rendered with any of the defined colors.

```jsx
import { Avatar, FloatingList } from '@lightelligence/react';
<FloatingList>
<Avatar name="1" size="s" color="primary" />
<Avatar name="2" size="s" color="secondary" />
<Avatar name="E" size="s" color="error" />
<Avatar name="S" size="s" color="success" />
<Avatar name="I" size="s" color="info" />
<Avatar name="W" size="s" color="warning" />
<Avatar name="D" size="s" color="dark" />
</FloatingList>
```

# Presets

There are two presets `User`and `Tenant` that can be used for the avatar.

```jsx
import { Avatar, FloatingList } from '@lightelligence/react';
<FloatingList>
<Avatar type="user" name="U" />
<Avatar type="tenant" name="T" />
</FloatingList>
```
9 changes: 3 additions & 6 deletions src/components/Avatar/Avatar.test.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
import { render } from '@testing-library/react';
import React from 'react';
import { Avatar } from './Avatar';
import { AVATAR_TYPE_TENANT, AVATAR_TYPE_USER } from '../../constants';

describe('Avatar', () => {
it('contains first letter of the name', () => {
const name = 'testName';
const { queryByText } = render(
<Avatar name={name} type={AVATAR_TYPE_USER} />,
);
const { queryByText } = render(<Avatar name={name} />);
expect(queryByText(name[0])).not.toBeNull();
expect(queryByText(name)).toBeNull();
});

it('respects type', () => {
const name = 'testName';
const { queryByText, rerender } = render(
<Avatar name={name} type={AVATAR_TYPE_TENANT} size="l" />,
<Avatar name={name} type="tenant" size="l" />,
);
let icon = queryByText(name[0]);
// check if the class name contains 'tenant' but not 'user'
expect(icon.className).toEqual(expect.stringContaining('tenant'));
expect(icon.className).toEqual(expect.not.stringContaining('user'));

// rerender with different type and check if the class name contains 'user' but not 'tenant'
rerender(<Avatar name={name} type={AVATAR_TYPE_USER} size="l" />);
rerender(<Avatar name={name} type="user" size="l" />);
icon = queryByText(name[0]);
expect(icon.className).toEqual(expect.not.stringContaining('tenant'));
expect(icon.className).toEqual(expect.stringContaining('user'));
Expand Down
3 changes: 3 additions & 0 deletions src/components/Dialog/Dialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Use the *Dialog* Component to render a modal dialog.

The dialog changes to full screen on mobile and tablet devices.


```js
import { Dialog, Button, Paragraph } from '@lightelligence/react';
initialState = { dialogOpen: false};
Expand Down
44 changes: 24 additions & 20 deletions src/components/Filter/Filter.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
### Example
## General

You can use the Filter component to show a dropdown that opens a filter popup and displays an additional number representing the number of filters selected.

You can add any component inside the filter as child. E.g. a list of filters with an apply and reset button.


```jsx

import { Checkbox } from '@lightelligence/react';
import useOnClickOutside from 'use-onclickoutside';

Expand All @@ -12,23 +18,21 @@ const count = filters.filter((value) => !!value).length;
const ref = React.useRef(null);

useOnClickOutside(ref, () => setOpen(false));

<div style={{ paddingBottom: '120px' }}>
<Filter
ref={ref}
label="Filter"
bubbleText={count.toString()}
onClick={() => setOpen(!open)}
open={open}
>
<div className="olt-u-padding16">
<Checkbox checked={deviceTypeFilter} onChange={setDeviceTypeFilter}>
Device Type
</Checkbox>
<Checkbox checked={deviceNameFilter} onChange={setDeviceNameFilter}>
Device Name
</Checkbox>
</div>
</Filter>
</div>;
<Filter
ref={ref}
label="Filter"
bubbleText={count.toString()}
onClick={() => setOpen(!open)}
open={open}
>
<div className="olt-u-padding16">
<Checkbox checked={deviceTypeFilter} onChange={setDeviceTypeFilter}>
Device Type
</Checkbox>
<Checkbox checked={deviceNameFilter} onChange={setDeviceNameFilter}>
Device Name
</Checkbox>
</div>
</Filter>
;
```
Loading