Skip to content

Commit

Permalink
Merge pull request #199 from lumapps/feat/textfield-after
Browse files Browse the repository at this point in the history
feat(textfield-enhancements): Text field enhancements
  • Loading branch information
matmkian authored Oct 25, 2019
2 parents d213138 + 59f700f commit d13372b
Show file tree
Hide file tree
Showing 30 changed files with 822 additions and 298 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.react.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Text field enhancements (`chips`, `onFocus`, `onBlur`, `textfieldRef`, `inputRef` props) [#199](https://github.com/lumapps/design-system/pull/199)

### Changed

- Fix stroke-width property on react progress bar.
Expand Down
32 changes: 30 additions & 2 deletions demo/react/doc/product/components/chip.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
```javascript import
import { useState } from 'react';
import { Chip, Icon, Size } from 'LumX';
import { Chip, ChipGroup, Icon, Size } from 'LumX';
import { mdiEmail, mdiClose, mdiCloseCircle, mdiMenuDown, mdiFilterVariant } from 'LumX/icons';
```

Expand Down Expand Up @@ -140,6 +140,34 @@ Use small when space is a constraint, as in areas like text fields, selects, dro
};
```

# Properties
# Properties

<PropTable component="Chip" />


# Chip Group

```javascript jsx withThemeSwitcher
(theme) => {
return (
<ChipGroup>
<Chip theme={theme} size={Size.s}>
Default
</Chip>
<Chip theme={theme} size={Size.s} before={<Icon icon={mdiEmail} size={Size.xxs} />}>
Rich
</Chip>
<Chip theme={theme} size={Size.s} after={<Icon icon={mdiClose} size={Size.xxs} />}>
Dismissible
</Chip>
</ChipGroup>
);
};
```

# Properties

<PropTable component="ChipGroup" />

<PropTable component="Chip" />

57 changes: 48 additions & 9 deletions demo/react/doc/product/components/text-field.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
```javascript import
import { ReactElement, useState } from 'react';
import { TextField, Theme } from 'LumX';
import { mdiMagnify } from 'LumX/icons';
import { Chip, ChipGroup, TextField, Theme, IconButton, Emphasis, Size } from 'LumX';
import { mdiMagnify, mdiClose } from 'LumX/icons';
```

# Text field
Expand Down Expand Up @@ -50,7 +50,7 @@ There are three states: _disabled_, _valid_, and _invalid_.

## Options

There are three options: _helper text_, _placeholder_ and _icon_.
There are five options: _helper text_, _placeholder_, _icon_, _is clearable_ and _with chips_.

### Helper text

Expand Down Expand Up @@ -90,33 +90,72 @@ There are three options: _helper text_, _placeholder_ and _icon_.
};
```

### Text Area
### Clearable

```javascript jsx withThemeSwitcher disableGrid
(theme) => {
const [value, setValue] = useState('');

return <TextField label="Textfield label" value={value} onChange={setValue} theme={theme} type="textarea" />;
return <TextField isClearable value={value} onChange={setValue} theme={theme} />;
};
```

### Valid Text Area
### With Chips

```javascript jsx withThemeSwitcher disableGrid
(theme) => {
const [value, setValue] = useState('');

return <TextField label="Textfield label" value={value} onChange={setValue} theme={theme} type="textarea" isValid />;
return (
<TextField
value={value}
onChange={setValue}
theme={theme}
chips={
<ChipGroup>
<Chip size={Size.s}>
First
</Chip>
<Chip size={Size.s}>
Second
</Chip>
<Chip size={Size.s}>
Third
</Chip>
</ChipGroup>
}
/>
);
};
```

### Error Text Area
### Text Area

```javascript jsx withThemeSwitcher disableGrid
(theme) => {
const [value, setValue] = useState('');

return <TextField label="Textfield label" value={value} onChange={setValue} theme={theme} type="textarea" hasError />;
return <TextField label="Textfield label" value={value} onChange={setValue} theme={theme} type="textarea" />;
};
```

### Valid

```javascript jsx withThemeSwitcher disableGrid
(theme) => {
const [value, setValue] = useState('Valid value');

return <TextField label="Textfield label" value={value} onChange={setValue} isValid theme={theme} type="textarea" />;
};
```

### Invalid

```javascript jsx withThemeSwitcher disableGrid
(theme) => {
const [value, setValue] = useState('Invalid value');

return <TextField label="Textfield label" value={value} onChange={setValue} hasError theme={theme} type="textarea" />;
};
```

Expand Down
1 change: 1 addition & 0 deletions src/angularjs.index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import './components/button/angularjs/button_directive';
import './components/button/angularjs/button-group_directive';
import './components/checkbox/angularjs/checkbox_directive';
import './components/chip/angularjs/chip_directive';
import './components/chip/angularjs/chip-group_directive';
import './components/comment-block/angularjs/comment-block_directive';
import './components/dialog/angularjs/dialog_directive';
import './components/dialog/angularjs/dialog_service';
Expand Down
2 changes: 1 addition & 1 deletion src/components/button/style/lumapps/_mixins.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
}
} @else if $variant == 'variant-icon' {
width: map-get($lumx-sizes, $size);
border-radius: 50%;
border-radius: $lumx-button-variant-icon-border-radius;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/components/button/style/lumapps/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ $lumx-button-icon-sizes: (
'm': map-get($lumx-sizes, 'xs'),
's': map-get($lumx-sizes, 'xxs')
) !default;

$lumx-button-variant-icon-border-radius: $lumx-theme-border-radius !default;
2 changes: 2 additions & 0 deletions src/components/button/style/material/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ $lumx-button-text-sizes: (

$lumx-button-text-weight: 500;
$lumx-button-text-transform: uppercase;

$lumx-button-variant-icon-border-radius: 50%;
82 changes: 82 additions & 0 deletions src/components/chip/angularjs/chip-group_directive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { CSS_PREFIX } from 'LumX/core/constants';
import { COMPONENT_PREFIX, MODULE_NAME } from 'LumX/angularjs/constants/common_constants';

/////////////////////////////

function ChipGroupController() {
'ngInject';

// eslint-disable-next-line consistent-this
const lumx = this;

/////////////////////////////
// //
// Private attributes //
// //
/////////////////////////////

/**
* The default props.
*
* @type {Object}
* @constant
* @readonly
*/
const _DEFAULT_PROPS = {
align: 'left',
};

/////////////////////////////
// //
// Public functions //
// //
/////////////////////////////

/**
* Get button classes.
*
* @return {Array} The list of button classes.
*/
function getClasses() {
const classes = [];

if (angular.isDefined(lumx.align) && lumx.align) {
classes.push(`${CSS_PREFIX}-chip-group--align-${lumx.align}`);
} else {
classes.push(`${CSS_PREFIX}-chip-group--align-${_DEFAULT_PROPS.align}`);
}

return classes;
}

/////////////////////////////

lumx.getClasses = getClasses;
}

/////////////////////////////

function ChipGroupDirective() {
'ngInject';

return {
bindToController: true,
controller: ChipGroupController,
controllerAs: 'lumx',
replace: true,
restrict: 'E',
scope: {
align: '@?lumxAlign',
},
template: `<div class="${CSS_PREFIX}-chip-group" ng-class="lumx.getClasses()" ng-transclude></div>`,
transclude: true,
};
}

/////////////////////////////

angular.module(`${MODULE_NAME}.chip`).directive(`${COMPONENT_PREFIX}ChipGroup`, ChipGroupDirective);

/////////////////////////////

export { ChipGroupDirective };
38 changes: 38 additions & 0 deletions src/components/chip/react/ChipGroup.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { shallow } from 'enzyme';
import React from 'react';

import { ICommonSetup } from 'LumX/core/testing/utils.test';
import { Chip } from './Chip';
import { ChipGroup, ChipGroupProps } from './ChipGroup';

interface ISetup extends ICommonSetup {}

/**
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
*
* @param propOverrides An object that will extend the default properties.
* @return An object with some shortcuts to elements or data required in tests.
*/
const setup = (propOverrides: Partial<ChipGroupProps> = {}): ISetup => {
const props = {
children: [<Chip key="1">Chip 1</Chip>, <Chip key="2">Chip 2</Chip>, <Chip key="3">Chip 3</Chip>],
...propOverrides,
};

const wrapper = shallow(<ChipGroup {...props} />);

return {
props,
wrapper,
};
};

describe('<ChipGroup />', () => {
// 1. Test render via snapshot (default state of component).
describe('Snapshot', () => {
it('should render correctly Chip Group component', () => {
const { wrapper } = setup();
expect(wrapper).toMatchSnapshot();
});
});
});
82 changes: 82 additions & 0 deletions src/components/chip/react/ChipGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { ReactElement } from 'react';

import classNames from 'classnames';

import { COMPONENT_PREFIX } from 'LumX/core/react/constants';

import { IGenericProps, getRootClassName } from 'LumX/core/react/utils';
import { handleBasicClasses } from 'LumX/core/utils';

/////////////////////////////

/**
* Defines the props of the component.
*/
interface IChipGroupProps extends IGenericProps {
/** Children of the ChipGroup. This should be a list of Chips */
children: React.ReactNode;

/** Chip group alignment */
align?: string;
}
type ChipGroupProps = IChipGroupProps;

/////////////////////////////

/**
* Define the types of the default props.
*/
interface IDefaultPropsType extends Partial<ChipGroupProps> {}

/////////////////////////////
// //
// Public attributes //
// //
/////////////////////////////

/**
* The default value of props.
*/
const DEFAULT_PROPS: IDefaultPropsType = {
align: 'left',
};

/**
* The display name of the component.
*/
const COMPONENT_NAME = `${COMPONENT_PREFIX}ChipGroup`;

/**
* The default class name and classes prefix for this component.
*/
const CLASSNAME: string = getRootClassName(COMPONENT_NAME);

/////////////////////////////

/**
* Displays a list of Chips in a grouped fashion.
* @return The Chip Group component.
*/
const ChipGroup: React.FC<IChipGroupProps> = ({
className,
align = DEFAULT_PROPS.align,
children,
...props
}: ChipGroupProps): ReactElement => {
const chipGroupClassName = handleBasicClasses({
align,
prefix: CLASSNAME,
});

return (
<div className={classNames(className, chipGroupClassName)} {...props}>
{children}
</div>
);
};

ChipGroup.displayName = COMPONENT_NAME;

/////////////////////////////

export { CLASSNAME, ChipGroup, ChipGroupProps };
Loading

0 comments on commit d13372b

Please sign in to comment.