-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature(FDS-342): Input time field (#267)
* Input time * Input time Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- Loading branch information
1 parent
a95b3d6
commit e3cb177
Showing
10 changed files
with
282 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
title: DataTime | ||
propTable: DataTime.js | ||
type: 'module' | ||
public: false | ||
--- | ||
|
||
A data module to display **string** values, it renders a input of type **time**. | ||
|
||
### Sandbox | ||
|
||
Feel free to play around with the following code: | ||
|
||
```jsx | ||
<ModuleSandbox | ||
isEditing={true} | ||
record={{ | ||
id: 1, | ||
time: '13:30', | ||
}} | ||
> | ||
<DataTime attribute='time' isEditable={true} label='Schedule' value='13:30' /> | ||
</ModuleSandbox> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React from 'react'; | ||
import DataTime from './DataTime'; | ||
import ModuleSandbox from '../ModuleSandbox'; | ||
|
||
const DataTimeSandbox = ({ isEditing, ...rest }) => ( | ||
<ModuleSandbox isEditing={isEditing}> | ||
<DataTime {...rest} /> | ||
</ModuleSandbox> | ||
); | ||
|
||
const timeValue = '13:30'; | ||
|
||
const displayProps = { | ||
label: 'Display', | ||
value: timeValue, | ||
}; | ||
|
||
const editingProps = { | ||
isEditing: true, | ||
label: 'Editing', | ||
value: timeValue, | ||
}; | ||
|
||
// These can be used in tests | ||
export { displayProps, editingProps }; | ||
|
||
export default { | ||
display: <DataTimeSandbox {...displayProps} />, | ||
displayNoLabel: <DataTimeSandbox {...displayProps} isLabeled={false} />, | ||
editing: <DataTimeSandbox {...editingProps} />, | ||
editingNoLabel: <DataTimeSandbox {...editingProps} isLabeled={false} />, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React, { useContext } from 'react'; | ||
import { Input } from 'reakit/Input'; | ||
import pt from 'prop-types'; | ||
import { ModuleContext } from '../context'; | ||
import styles from '../DataModule.module.scss'; | ||
|
||
import ModuleErrorBoundary from '../ModuleErrorBoundary'; | ||
import getAccessibleLabelSetters from '../helpers'; | ||
|
||
const propTypes = { | ||
/** A module can have an Attribute, which will be used as form field name */ | ||
attribute: pt.string, | ||
/** A Module can be defined to not present an editing state */ | ||
isEditable: pt.bool, | ||
/** Presents the input without a label. NOT USER CONFIGURABLE */ | ||
isLabeled: pt.bool, | ||
/** A Module needs to have a unique label relative to its context */ | ||
label: pt.string, | ||
/** A Module can have a value */ | ||
value: pt.string, | ||
}; | ||
|
||
const DataTime = ({ | ||
attribute, | ||
isEditable = true, | ||
isLabeled = true, | ||
label, | ||
value, | ||
...rest | ||
}) => { | ||
const { isEditing, formMethods } = useContext(ModuleContext); | ||
const { setAriaLabel, setHtmlFor } = getAccessibleLabelSetters( | ||
isLabeled, | ||
label | ||
); | ||
|
||
const renderEditing = ( | ||
<label htmlFor={setHtmlFor}> | ||
{label && isLabeled && <span className={styles.LabelText}>{label}</span>} | ||
<Input | ||
{...rest} | ||
aria-label={setAriaLabel} | ||
className={styles.Time} | ||
defaultValue={value} | ||
id={label} | ||
name={attribute || label} | ||
ref={formMethods?.register} | ||
type='time' | ||
/> | ||
</label> | ||
); | ||
|
||
const renderDisplay = ( | ||
<span> | ||
{label && isLabeled && <span className={styles.LabelText}>{label}</span>} | ||
<span aria-label={label} className={styles.Time} {...rest}> | ||
{value} | ||
</span> | ||
</span> | ||
); | ||
|
||
// Do not render an editable input if the module is not editable | ||
return ( | ||
<ModuleErrorBoundary> | ||
<div className={styles.Time}> | ||
{isEditing && isEditable ? renderEditing : renderDisplay} | ||
</div> | ||
</ModuleErrorBoundary> | ||
); | ||
}; | ||
|
||
DataTime.propTypes = propTypes; | ||
|
||
export default DataTime; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { fireEvent, render, screen } from '@testing-library/react'; | ||
|
||
import cosmosFixtures, { displayProps, editingProps } from './DataTime.fixture'; | ||
|
||
const { display, editing, displayNoLabel, editingNoLabel } = cosmosFixtures; | ||
|
||
describe('DataTime', () => { | ||
// without ModuleSandbox will render the property information into a span | ||
|
||
describe('display', () => { | ||
// We need a place to store the view for snapshot testing. This is not required when we are using `screen` directly from RTL. | ||
let view; | ||
|
||
beforeEach(() => { | ||
// Set the render container to our `view` so it is in scope for the snapshot test | ||
view = render(display).container; | ||
}); | ||
|
||
test('snapshot', () => { | ||
expect(view).toMatchSnapshot(); | ||
}); | ||
|
||
test('renders a <span> by default', () => { | ||
const input = screen.getByLabelText(displayProps.label); | ||
// Make sure the actual DOM element is not render an input | ||
expect(input.tagName).toMatch('SPAN'); | ||
// Make sure the dom element that has our aria-label is the input | ||
expect(input.classList.contains('Time')).toBe(true); | ||
}); | ||
}); | ||
|
||
describe('editing', () => { | ||
// We need a place to store the view for snapshot testing. This is not required when we are using `screen` directly from RTL. | ||
let view; | ||
|
||
beforeEach(() => { | ||
// Set the render container to our `view` so it is in scope for the snapshot test | ||
view = render(editing).container; | ||
}); | ||
|
||
test('snapshot', () => { | ||
expect(view).toMatchSnapshot(); | ||
}); | ||
|
||
test('renders a <input email> by default', () => { | ||
const input = screen.getByLabelText(editingProps.label); | ||
// Check that we also use the correct type | ||
expect(input).toHaveAttribute('type', 'time'); | ||
}); | ||
|
||
test('change value', () => { | ||
const newTime = '14:50'; | ||
const input = screen.getByLabelText(editingProps.label); | ||
fireEvent.change(input, { target: { value: newTime } }); | ||
expect(input).toHaveValue(newTime); | ||
}); | ||
}); | ||
|
||
describe('accessibility', () => { | ||
test('editing', () => { | ||
render(editing); | ||
|
||
const input = screen.getByLabelText(editingProps.label); | ||
// The label tag is the parent wrapper | ||
const label = input.closest('label'); | ||
|
||
// Test is written this way to make sure we know that both values need to be the same. | ||
const linkedLabelValue = editingProps.label; | ||
|
||
// Verify label for attribute has linked value | ||
expect(label).toHaveAttribute( | ||
'for', | ||
expect.stringContaining(linkedLabelValue) | ||
); | ||
// Verify input id attribute has linked value | ||
expect(input).toHaveAttribute( | ||
'id', | ||
expect.stringContaining(linkedLabelValue) | ||
); | ||
// Check that the input does NOT have an aria-label defined because there is a label tag | ||
expect(input).not.toHaveAttribute('aria-label'); | ||
}); | ||
|
||
test('display no label', () => { | ||
// Make sure that the input is still accessible with label text even when we are not showing a label tag in tables | ||
render(displayNoLabel); | ||
const input = screen.getByLabelText(displayProps.label); | ||
expect(input).toBeDefined(); | ||
}); | ||
|
||
test('editing no label', () => { | ||
// Make sure that the input is still accessible with label text even when we are not showing a label tag in tables | ||
render(editingNoLabel); | ||
const input = screen.getByLabelText(editingProps.label); | ||
expect(input).toBeDefined(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`DataTime display snapshot 1`] = ` | ||
<div> | ||
<div | ||
class="Time" | ||
> | ||
<span> | ||
<span | ||
class="LabelText" | ||
> | ||
Display | ||
</span> | ||
<span | ||
aria-label="Display" | ||
class="Time" | ||
> | ||
13:30 | ||
</span> | ||
</span> | ||
</div> | ||
</div> | ||
`; | ||
|
||
exports[`DataTime editing snapshot 1`] = ` | ||
<div> | ||
<div | ||
class="Time" | ||
> | ||
<label | ||
for="Editing" | ||
> | ||
<span | ||
class="LabelText" | ||
> | ||
Editing | ||
</span> | ||
<input | ||
class="Time" | ||
id="Editing" | ||
name="Editing" | ||
type="time" | ||
value="13:30" | ||
/> | ||
</label> | ||
</div> | ||
</div> | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from './DataTime'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters