Skip to content

Commit

Permalink
feat(FluidTimePicker): add FluidTimePicker variant (#12603)
Browse files Browse the repository at this point in the history
* feat(FluidTimePicker): scaffold out react files

* feat(FluidTimePicker): scaffold sass files, fix FluidSelect outline

* feat(FluidTimePicker): implement error state

* style(FluidTimePicker): work on invalid styles

* style(FluidTimePicker): add warning styles, fix playground story

* test(FluidTimePicker): update tests

* refactor(FluidTimePicker): remove single element invalid styles

* test(FluidTimePicker): update tests, snapshots

* style(Fluid): update Fluid skeleton styles

* test(e2e): add e2e tests for FluidTimePicker

* style(FluidTimePicker): fix invalid state

* chore(storybook): clean up storybook a11y issues

Co-authored-by: Alison Joseph <alison.joseph@us.ibm.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
3 people committed Nov 30, 2022
1 parent 43e6216 commit b77359f
Show file tree
Hide file tree
Showing 28 changed files with 1,034 additions and 34 deletions.
37 changes: 37 additions & 0 deletions e2e/components/FluidTimePicker/FluidTextInput-test.e2e.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright IBM Corp. 2016, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

const { expect, test } = require('@playwright/test');
const { themes } = require('../../test-utils/env');
const { snapshotStory, visitStory } = require('../../test-utils/storybook');

test.describe('FluidTimePicker', () => {
themes.forEach((theme) => {
test.describe(theme, () => {
test('fluid text input @vrt', async ({ page }) => {
await snapshotStory(page, {
component: 'FluidTimePicker',
id: 'experimental-unstable-fluidtimepicker--default',
theme,
});
});
});
});

test('accessibility-checker @avt', async ({ page }) => {
await visitStory(page, {
component: 'FluidTimePicker',
id: 'experimental-unstable-fluidtimepicker--default',
globals: {
theme: 'white',
},
});
await expect(page).toHaveNoACViolations('FluidTimePicker');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Code generated by carbon-components-react. DO NOT EDIT.
//
// Copyright IBM Corp. 2018, 2018
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

@forward '@carbon/styles/scss/components/fluid-time-picker/fluid-time-picker';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Code generated by carbon-components-react. DO NOT EDIT.
//
// Copyright IBM Corp. 2018, 2018
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

@forward '@carbon/styles/scss/components/fluid-time-picker';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Code generated by carbon-components. DO NOT EDIT.
//
// Copyright IBM Corp. 2018, 2018
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

@forward '@carbon/styles/scss/components/fluid-time-picker/fluid-time-picker';
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Code generated by carbon-components. DO NOT EDIT.
//
// Copyright IBM Corp. 2018, 2018
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

@forward '@carbon/styles/scss/components/fluid-time-picker';
69 changes: 69 additions & 0 deletions packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10026,6 +10026,75 @@ Map {
},
},
},
"unstable__FluidTimePicker" => Object {
"$$typeof": Symbol(react.forward_ref),
"propTypes": Object {
"children": Object {
"type": "node",
},
"className": Object {
"type": "string",
},
"disabled": Object {
"type": "bool",
},
"invalid": Object {
"type": "bool",
},
"invalidText": Object {
"type": "node",
},
"labelText": Object {
"isRequired": true,
"type": "node",
},
"warn": Object {
"type": "bool",
},
"warnText": Object {
"type": "node",
},
},
"render": [Function],
},
"unstable__FluidTimePickerSelect" => Object {
"$$typeof": Symbol(react.forward_ref),
"propTypes": Object {
"children": Object {
"type": "node",
},
"className": Object {
"type": "string",
},
"defaultValue": Object {
"type": "any",
},
"disabled": Object {
"type": "bool",
},
"id": Object {
"isRequired": true,
"type": "string",
},
"labelText": Object {
"type": "node",
},
"onChange": Object {
"type": "func",
},
},
"render": [Function],
},
"unstable__FluidTimePickerSkeleton" => Object {
"propTypes": Object {
"className": Object {
"type": "string",
},
"isOnlyTwo": Object {
"type": "bool",
},
},
},
"unstable_useContextMenu" => Object {},
"unstable_useFeatureFlag" => Object {},
"unstable_useFeatureFlags" => Object {},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Code generated by @carbon/react. DO NOT EDIT.
//
// Copyright IBM Corp. 2018, 2018
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

@forward '@carbon/styles/scss/components/fluid-time-picker/fluid-time-picker';
9 changes: 9 additions & 0 deletions packages/react/scss/components/fluid-time-picker/_index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Code generated by @carbon/react. DO NOT EDIT.
//
// Copyright IBM Corp. 2018, 2018
//
// This source code is licensed under the Apache-2.0 license found in the
// LICENSE file in the root directory of this source tree.
//

@forward '@carbon/styles/scss/components/fluid-time-picker';
3 changes: 3 additions & 0 deletions packages/react/src/__tests__/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ describe('Carbon Components React', () => {
"unstable__FluidTextAreaSkeleton",
"unstable__FluidTextInput",
"unstable__FluidTextInputSkeleton",
"unstable__FluidTimePicker",
"unstable__FluidTimePickerSelect",
"unstable__FluidTimePickerSkeleton",
"unstable_useContextMenu",
"unstable_useFeatureFlag",
"unstable_useFeatureFlags",
Expand Down
17 changes: 17 additions & 0 deletions packages/react/src/components/FluidForm/FluidForm.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import SelectItem from '../SelectItem';
import SelectItemGroup from '../SelectItemGroup';
import FluidTextInput from '../FluidTextInput';
import FluidTextArea from '../FluidTextArea';
import FluidTimePicker from '../FluidTimePicker';
import FluidTimePickerSelect from '../FluidTimePickerSelect';
import ModalWrapper from '../ModalWrapper';

const additionalProps = {
Expand Down Expand Up @@ -51,6 +53,21 @@ export const Default = () => (
<>
<FluidForm {...additionalProps}>
<div style={{ display: 'flex' }}>
<FluidTimePicker
id="time-picker-1"
labelText="Time"
placeholder="hh:mm">
<FluidTimePickerSelect id="select-1" labelText="Clock">
<SelectItem value="am" text="AM" />
<SelectItem value="pm" text="PM" />
</FluidTimePickerSelect>
<FluidTimePickerSelect id="select-2" labelText="Timezone">
<SelectItem value="et" text="Eastern Time (ET)" />
<SelectItem value="ct" text="Central Time (CT)" />
<SelectItem value="mt" text="Mountain Time (MT)" />
<SelectItem value="pt" text="Pacific Time (PT)" />
</FluidTimePickerSelect>
</FluidTimePicker>
<FluidDatePicker datePickerType="range">
<FluidDatePickerInput
id="date-picker-input-id-start"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Copyright IBM Corp. 2022
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import PropTypes from 'prop-types';
import React from 'react';
import cx from 'classnames';
import { usePrefix } from '../../internal/usePrefix';
import { FluidTextInputSkeleton } from '../FluidTextInput';
import { FluidSelectSkeleton } from '../FluidSelect';

const FluidTimePickerSkeleton = ({ className, isOnlyTwo, ...rest }) => {
const prefix = usePrefix();
const wrapperClasses = cx(
className,
`${prefix}--time-picker--fluid--skeleton`,
{
[`${prefix}--time-picker--equal-width`]: isOnlyTwo,
}
);

return (
<div className={wrapperClasses} {...rest}>
<FluidTextInputSkeleton />
<FluidSelectSkeleton />
{!isOnlyTwo ? <FluidSelectSkeleton /> : null}
</div>
);
};

FluidTimePickerSkeleton.propTypes = {
/**
* Specify an optional className to add.
*/
className: PropTypes.string,

/**
* Specify if there are only two TimePicker elements
*/
isOnlyTwo: PropTypes.bool,
};

export default FluidTimePickerSkeleton;
121 changes: 121 additions & 0 deletions packages/react/src/components/FluidTimePicker/FluidTimePicker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/**
* Copyright IBM Corp. 2022
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import PropTypes from 'prop-types';
import React from 'react';
import classnames from 'classnames';
import FluidTextInput from '../FluidTextInput';
import { usePrefix } from '../../internal/usePrefix';
import { WarningFilled, WarningAltFilled } from '@carbon/icons-react';

const FluidTimePicker = React.forwardRef(function FluidTimePicker(
{
className,
children,
disabled,
invalid,
invalidText,
warn,
warnText,
...other
},
ref
) {
const prefix = usePrefix();

const classNames = classnames(className, {
[`${prefix}--time-picker--fluid`]: true,
[`${prefix}--time-picker--equal-width`]: children?.length !== 2,
[`${prefix}--time-picker--fluid--disabled`]: disabled,
[`${prefix}--time-picker--fluid--invalid`]: invalid,
[`${prefix}--time-picker--fluid--warning`]: warn,
});

const errorText = () => {
if (invalid) {
return invalidText;
}
if (warn) {
return warnText;
}
};

const error = invalid || warn;

return (
<div className={classNames}>
<div className={`${prefix}--time-picker--fluid__wrapper`}>
<div className={`${prefix}--time-picker__input`}>
<FluidTextInput disabled={disabled} ref={ref} {...other} />
</div>
{disabled
? React.Children.toArray(children).map((child) => {
return React.cloneElement(child, { disabled });
})
: children}
</div>
{error && <hr className={`${prefix}--time-picker__divider`} />}
{error && (
<div className={`${prefix}--form-requirement`}>{errorText()}</div>
)}
{error && invalid ? (
<WarningFilled
className={`${prefix}--time-picker__icon ${prefix}--time-picker__icon--invalid`}
/>
) : (
<WarningAltFilled
className={`${prefix}--time-picker__icon ${prefix}--time-picker__icon--warn`}
/>
)}
</div>
);
});

FluidTimePicker.propTypes = {
/**
* The child node(s)
*/
children: PropTypes.node,

/**
* Specify an optional className to be applied to the outer FluidTimePicker wrapper
*/
className: PropTypes.string,

/**
* Specify whether the `<input>` should be disabled
*/
disabled: PropTypes.bool,

/**
* Specify whether or not the control is invalid
*/
invalid: PropTypes.bool,

/**
* Provide the text that is displayed when the control is in error state
*/
invalidText: PropTypes.node,

/**
* Provide the text that will be read by a screen reader when visiting this
* control
*/
labelText: PropTypes.node.isRequired,

/**
* Specify whether the control is currently in warning state
*/
warn: PropTypes.bool,

/**
* Provide the text that is displayed when the control is in warning state
*/
warnText: PropTypes.node,
};

export default FluidTimePicker;
Loading

0 comments on commit b77359f

Please sign in to comment.