Skip to content

Commit

Permalink
2.1.3 release
Browse files Browse the repository at this point in the history
  • Loading branch information
JayCanuck committed Mar 7, 2022
2 parents dcea488 + 3218fa6 commit 8807cb1
Show file tree
Hide file tree
Showing 102 changed files with 8,299 additions and 8,958 deletions.
23 changes: 18 additions & 5 deletions Alert/Alert.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import kind from '@enact/core/kind';
import {mapAndFilterChildren} from '@enact/core/util';
import IdProvider from '@enact/ui/internal/IdProvider';
import Layout, {Cell} from '@enact/ui/Layout';
import ri from '@enact/ui/resolution';
import Slottable from '@enact/ui/Slottable';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import {Children} from 'react';

Expand Down Expand Up @@ -167,15 +169,26 @@ const AlertBase = kind({
noTitle: (type === 'fullscreen') && !title
},
type
)
),
overflow: ({buttons}) => {
if (typeof window !== 'undefined' && buttons) {
const contentWidth = ri.scale(1200); // If you will change this value, please change @sand-alert-overlay-content-width too.
const buttonsWidth = ri.scale(540 + 126); // If you will change this value, please change @sand-button-min-width + @sand-alert-overlay-buttons-margin too.

return window.innerWidth < contentWidth + buttonsWidth;
}

return false;
}
},

render: ({buttons, contentComponent, children, id, image, title, type, ...rest}) => {
render: ({buttons, contentComponent, children, id, image, overflow, title, type, ...rest}) => {
const fullscreen = (type === 'fullscreen');
const position = (type === 'overlay' ? 'bottom' : type);
const layoutOrientation = (fullscreen ? 'vertical' : 'horizontal');
const showTitle = (fullscreen && title);
const ariaLabelledBy = (showTitle ? `${id}_title ` : '') + `${id}_content ${id}_buttons`;
const layoutOrientation = (fullscreen || overflow ? 'vertical' : 'horizontal');

return (
<div aria-owns={id} className={css.alertWrapper}>
<Popup
Expand All @@ -189,11 +202,11 @@ const AlertBase = kind({
<Layout align="center center" orientation={layoutOrientation}>
{image ? <Cell shrink className={css.alertImage}>{image}</Cell> : null}
{showTitle ? <Cell shrink><Heading size="title" alignment="center" className={css.title} id={`${id}_title`}>{title}</Heading></Cell> : null}
<Cell shrink align={fullscreen ? 'center' : ''} component={contentComponent} className={css.content} id={`${id}_content`}>
<Cell shrink align={fullscreen || overflow ? 'center' : ''} component={contentComponent} className={classnames(css.content, overflow ? null : css.full)} id={`${id}_content`}>
{children}
</Cell>
{buttons ?
<Cell align={fullscreen ? '' : 'end'} shrink className={css.buttonContainer}>
<Cell align={fullscreen || overflow ? '' : 'end'} shrink className={classnames(css.buttonContainer, overflow ? null : css.full)}>
<Layout align="center" orientation="vertical" id={`${id}_buttons`}>
{buttons}
</Layout>
Expand Down
22 changes: 14 additions & 8 deletions Alert/Alert.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -62,29 +62,35 @@

.buttonContainer {
box-sizing: border-box;
margin: @sand-alert-overlay-buttons-margin;
.margin-start-end(
.extract(@sand-alert-overlay-buttons-margin, left)[],
.extract(@sand-alert-overlay-buttons-margin, right)[]
);

// Every buttonCell after the first one
.buttonCell + .buttonCell {
margin-top: @sand-alert-overlay-button-spacing;
}

&.full {
margin: @sand-alert-overlay-buttons-margin;
.margin-start-end(
.extract(@sand-alert-overlay-buttons-margin, left)[],
.extract(@sand-alert-overlay-buttons-margin, right)[]
);
}
}

.content {
.sand-alert-overlay-content();
width: @sand-alert-overlay-content-width;
.margin-start-end(@sand-alert-overlay-image-text-gap, @sand-alert-overlay-text-button-gap);
margin-bottom: 0;

:global(.enact-locale-ja) &,
:global(.enact-locale-zh) & {
overflow-wrap: normal;
word-break: normal;
}

&.full {
width: @sand-alert-overlay-content-width;
.margin-start-end(@sand-alert-overlay-image-text-gap, @sand-alert-overlay-text-button-gap);
margin-bottom: 0;
}
}

&.noImage {
Expand Down
4 changes: 4 additions & 0 deletions BodyText/BodyText.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
.enact-locale-tallglyph({
font-size: @sand-tallglyph-body-small-font-size;
});

.sand-locale-non-latin({
font-size: @sand-non-latin-body-small-font-size;
});
}

.enact-locale-rtl({
Expand Down
27 changes: 26 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,38 @@

The following is a curated list of changes in the Enact sandstone module, newest changes on the top.

## [2.1.3] - 2022-03-07

- Updated to use `forwardCustom` and add `type` when forwarding custom events

### Added

- `sandstone/Picker` and `sandstone/RangePicker` prop `changedBy` to provide a way to control with left and right keys in horizontal joined Picker
- `sandstone/VideoPlayer` prop `backButtonAriaLabel`
- `sandstone/VideoPlayer` prop `onBack` to provide a way to exit video player via touch

### Changed

- `sandstone/Scroller` and `sandstone/VirtualList` to show overscroll effect when flicking

### Fixed

- `sandstone/Alert` layout for overlay type when screen width is narrow
- `sandstone/BodyText` font-size for size `small` and RTL locale
- `sandstone/Input.InputField` size 'small' line-height to center text vertically
- `sandstone/Input` to show title and keypad properly when `type` is `number` and screen width is narrow
- `sandstone/Picker` horizontal joined behavior going to the next item by touch
- `sandstone/Scroller` to scroll correctly on Android Chrome 85 or higher in RTL locales
- `sandstone/VirtualList` to scroll properly by hover after changing `dataSize` when `hoverToScroll` is `true`

## [2.1.2] - 2021-12-22

- Fixed samples build issue
- Fixed samples build issue

## [2.1.1] - 2021-12-22

### Added

- `sandstone/VideoPlayer` props `onWillFastForward`, `onWillJumpBackward`, `onWillJumpForward`, `onWillPause`, `onWillPlay`, and `onWillRewind`

### Fixed
Expand Down
15 changes: 10 additions & 5 deletions ContextualPopupDecorator/ContextualPopupDecorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import ApiDecorator from '@enact/core/internal/ApiDecorator';
import {on, off} from '@enact/core/dispatcher';
import {handle, forProp, forKey, forward, stop} from '@enact/core/handle';
import {handle, forProp, forKey, forward, forwardCustom, stop} from '@enact/core/handle';
import hoc from '@enact/core/hoc';
import EnactPropTypes from '@enact/core/internal/prop-types';
import {extractAriaProps} from '@enact/core/util';
Expand Down Expand Up @@ -601,7 +601,7 @@ const Decorator = hoc(defaultConfig, (config, Wrapped) => {
forKey('enter'),
() => Spotlight.getCurrent() === this.state.activator,
stop,
forward('onClose')
forwardCustom('onClose')
);

handleOpen = (ev) => {
Expand All @@ -622,6 +622,10 @@ const Decorator = hoc(defaultConfig, (config, Wrapped) => {
});
};

handleDismiss = () => {
forwardCustom('onClose')({}, this.props);
};

handleDirectionalKey (ev) {
// prevent default page scrolling
ev.preventDefault();
Expand Down Expand Up @@ -666,7 +670,7 @@ const Decorator = hoc(defaultConfig, (config, Wrapped) => {

// if focus moves outside the popup's container, issue the `onClose` event
if (Spotlight.move(direction) && !this.containerNode.contains(Spotlight.getCurrent())) {
forward('onClose', ev, this.props);
forwardCustom('onClose')(null, this.props);
}
};

Expand All @@ -693,7 +697,7 @@ const Decorator = hoc(defaultConfig, (config, Wrapped) => {
};

render () {
const {'data-webos-voice-exclusive': voiceExclusive, popupComponent: PopupComponent, popupClassName, noAutoDismiss, open, onClose, offset, popupProps, skin, spotlightRestrict, ...rest} = this.props;
const {'data-webos-voice-exclusive': voiceExclusive, popupComponent: PopupComponent, popupClassName, noAutoDismiss, open, offset, popupProps, skin, spotlightRestrict, ...rest} = this.props;
const idFloatLayer = `${this.id}_floatLayer`;
let scrimType = rest.scrimType;
delete rest.scrimType;
Expand All @@ -718,6 +722,7 @@ const Decorator = hoc(defaultConfig, (config, Wrapped) => {
}

delete rest.direction;
delete rest.onClose;
delete rest.onOpen;
delete rest.popupSpotlightId;
delete rest.rtl;
Expand All @@ -731,7 +736,7 @@ const Decorator = hoc(defaultConfig, (config, Wrapped) => {
id={idFloatLayer}
noAutoDismiss={noAutoDismiss}
onClose={this.handleClose}
onDismiss={onClose}
onDismiss={this.handleDismiss}
onOpen={this.handleOpen}
open={open}
scrimType={scrimType}
Expand Down
29 changes: 27 additions & 2 deletions ContextualPopupDecorator/tests/ContextualPopupDecorator-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,27 @@ import Button from '../../Button';
const ContextualButton = ContextualPopupDecorator(Button);

describe('ContextualPopupDecorator Specs', () => {
test('should emit onClose event when clicking on contextual button', () => {
test('should emit onOpen event with type when opening', () => {
const handleOpen = jest.fn();
const Root = FloatingLayerDecorator('div');
const message = 'goodbye';
render(
<Root>
<ContextualButton onOpen={handleOpen} open popupComponent={() => message}>
Hello
</ContextualButton>
</Root>
);

const expected = 1;
const expectedType = {type: 'onOpen'};
const actual = handleOpen.mock.calls.length && handleOpen.mock.calls[0][0];

expect(handleOpen).toHaveBeenCalledTimes(expected);
expect(actual).toMatchObject(expectedType);
});

test('should emit onClose event with type when clicking on contextual button', () => {
const handleClose = jest.fn();
const Root = FloatingLayerDecorator('div');
const message = 'goodbye';
Expand All @@ -24,7 +44,12 @@ describe('ContextualPopupDecorator Specs', () => {

userEvent.click(contextualButton);

expect(handleClose).toHaveBeenCalled();
const expected = 1;
const expectedType = {type: 'onClose'};
const actual = handleClose.mock.calls.length && handleClose.mock.calls[0][0];

expect(handleClose).toHaveBeenCalledTimes(expected);
expect(actual).toMatchObject(expectedType);
});

test('should render component into FloatingLayer if open', () => {
Expand Down
49 changes: 47 additions & 2 deletions DatePicker/tests/DatePicker-specs.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,68 @@
import ilib from 'ilib';
import '@testing-library/jest-dom';
import {render, screen} from '@testing-library/react';
import {fireEvent, render, screen} from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import DatePicker, {dateToLocaleString} from '../DatePicker';

// Note: Tests pass 'locale' because there's no I18nDecorator to provide a value via context and
// otherwise, nothing renders in the label.
describe('DatePicker', () => {
test('should emit an onChange event when changing a component picker', () => {
test('should emit an onChange event with type when changing a component picker', () => {
const handleChange = jest.fn();
render(<DatePicker onChange={handleChange} value={new Date(2000, 6, 15)} locale="en-US" />);
const monthPickerUp = screen.getAllByText('▲')[0];

userEvent.click(monthPickerUp);

const expected = 1;
const expectedType = {type: 'onChange'};
const actual = handleChange.mock.calls.length && handleChange.mock.calls[0][0];

expect(handleChange).toBeCalledTimes(expected);
expect(actual).toMatchObject(expectedType);
});

test('should fire onComplete event with type when enter key pressed from the last picker', () => {
const handleComplete = jest.fn();
render(<DatePicker onComplete={handleComplete} value={new Date(2000, 6, 15)} locale="en-US" />);
const year = screen.getByLabelText('2000 year change a value with up down button');

year.focus();
fireEvent.keyDown(year, {which: 13, keyCode: 13, code: 13});

const expected = {type: 'onComplete'};
const actual = handleComplete.mock.calls.length && handleComplete.mock.calls[0][0];

expect(actual).toMatchObject(expected);
});

test('should fire onSpotlightLeft event with type when spotlight is leaving via left key', () => {
const handleSpotlight = jest.fn();
render(<DatePicker onSpotlightLeft={handleSpotlight} value={new Date(2000, 6, 15)} locale="en-US" />);
const month = screen.getByLabelText('7 month change a value with up down button');

month.focus();
fireEvent.keyDown(month, {which: 37, keyCode: 37, code: 37});

const expected = {type: 'onSpotlightLeft'};
const actual = handleSpotlight.mock.calls.length && handleSpotlight.mock.calls[0][0];

expect(actual).toMatchObject(expected);
});

test('should fire onSpotlightRight event with type when spotlight is leaving via right key', () => {
const handleSpotlight = jest.fn();
render(<DatePicker onSpotlightRight={handleSpotlight} value={new Date(2000, 6, 15)} locale="en-US" />);
const year = screen.getByLabelText('2000 year change a value with up down button');

year.focus();
fireEvent.keyDown(year, {which: 39, keyCode: 39, code: 39});

const expected = {type: 'onSpotlightRight'};
const actual = handleSpotlight.mock.calls.length && handleSpotlight.mock.calls[0][0];

expect(actual).toMatchObject(expected);
});

test('should accept a JavaScript Date for its value prop', () => {
Expand Down
3 changes: 1 addition & 2 deletions DayPicker/DaySelectorDecorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {Component} from 'react';

import $L from '../internal/$L';

const forwardSelect = forward('onSelect');
const SELECTED_DAY_TYPES = {
EVERY_DAY: 0,
EVERY_WEEKDAY: 1,
Expand Down Expand Up @@ -275,7 +274,7 @@ const DaySelectorDecorator = hoc((config, Wrapped) => {
selected = generalizeSelected(selected, state);
const content = getSelectedDayString(selected, '', dayNameLength);

forwardSelect({selected, content}, this.props);
forward('onSelect', {type: 'onSelect', selected, content}, this.props);
};

render () {
Expand Down
4 changes: 2 additions & 2 deletions DayPicker/tests/DayPicker-specs.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ describe('DayPicker', () => {
expect(selectedDay).toHaveClass(expected);
});

test('should emit an onSelect event when selecting days', () => {
test('should emit an onSelect event with `onSelect` type when selecting days', () => {
const handleSelect = jest.fn();
render(<DayPicker onSelect={handleSelect} />);
const item = screen.getAllByRole('checkbox')[2];

userEvent.click(item);

expect(handleSelect).toHaveBeenCalled();
expect(handleSelect).toHaveBeenCalledWith({content: 'Mon', selected: [1], type: 'onSelect'});
});

test('should include `content` in onSelect event payload which respects dayNameLength', () => {
Expand Down
4 changes: 2 additions & 2 deletions Dropdown/Dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/

import EnactPropTypes from '@enact/core/internal/prop-types';
import {handle, forward, forProp, not} from '@enact/core/handle';
import {handle, forward, forwardCustom, forProp, not} from '@enact/core/handle';
import kind from '@enact/core/kind';
import {extractAriaProps} from '@enact/core/util';
import {I18nContextDecorator} from '@enact/i18n/I18nDecorator';
Expand Down Expand Up @@ -250,7 +250,7 @@ const DropdownBase = kind({

handlers: {
onSelect: handle(
forward('onSelect'),
forwardCustom('onSelect', (ev) => (ev)),
forward('onClose')
),
onOpen: handle(
Expand Down
Loading

0 comments on commit 8807cb1

Please sign in to comment.