Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StreamGallery: Initial implementation #30597

Merged
merged 40 commits into from
Oct 29, 2020
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
11a2759
Add Storybook samples
caroqliu Oct 8, 2020
c6e18b1
Prototype Preact StreamGallery
caroqliu Oct 9, 2020
b9d27a2
Prototype AMP component
caroqliu Oct 9, 2020
3d4029b
Allow stream gallery to import from base carousel
caroqliu Oct 9, 2020
831f6c7
Add unit tests
caroqliu Oct 9, 2020
4fab2a3
Merge branch 'master' into bento-stream-gallery
caroqliu Oct 21, 2020
03853c2
Remove slideAlign for now
caroqliu Oct 21, 2020
1862235
Sync with latest BaseCarousel changes
caroqliu Oct 22, 2020
849ebf8
Use ResizeObserver
caroqliu Oct 22, 2020
f27e8a9
Update comment note
caroqliu Oct 22, 2020
6102a03
Merge branch 'master' into bento-stream-gallery
caroqliu Oct 22, 2020
9b8d64a
Shrink arrow JSX
caroqliu Oct 22, 2020
00f6c73
Do not export `Controls`
caroqliu Oct 22, 2020
7285f9c
Update tests
caroqliu Oct 22, 2020
cf0930c
Add guard in Scroller class
caroqliu Oct 22, 2020
25dce60
Update test for third slide being rendered
caroqliu Oct 22, 2020
9315507
Disallow infinity maxWidth value
caroqliu Oct 22, 2020
6483732
Guard for ResizeObserver testing error
caroqliu Oct 22, 2020
b2a7356
Clean up logic
caroqliu Oct 22, 2020
94090fd
Add AMP CSS and test
caroqliu Oct 22, 2020
2563d3c
Rename `width` to `containerWidth`
caroqliu Oct 26, 2020
b47e32d
Use ResizeObserver entry to measure container
caroqliu Oct 26, 2020
f521a67
Reset window.onerror
caroqliu Oct 26, 2020
8b8f48b
Remove after hook for now
caroqliu Oct 26, 2020
6f18b2f
Update dependency checks
caroqliu Oct 26, 2020
6f3a94e
Use ref from scroller
caroqliu Oct 26, 2020
c86ede2
Prefer ?? to ||
caroqliu Oct 26, 2020
ecc510d
Reset window.onerror
caroqliu Oct 26, 2020
a2698c2
Return the ref.current.node as the root element
caroqliu Oct 27, 2020
5f50c78
Inline JSX
caroqliu Oct 27, 2020
20541ef
Use the ResizeObserver from the local window
caroqliu Oct 27, 2020
7e05092
Guard for ref.current
caroqliu Oct 27, 2020
c75625d
Move styles to classes
caroqliu Oct 27, 2020
d848411
getVisibleCount should return visibleCount
caroqliu Oct 27, 2020
c4e76c7
Scroller node not needed
caroqliu Oct 27, 2020
0722084
Fix types
caroqliu Oct 27, 2020
40b17a2
Merge branch 'master' into bento-stream-gallery
caroqliu Oct 27, 2020
277516d
Update dependency allowlist
caroqliu Oct 27, 2020
0e338ad
Resolve extraSpace class
caroqliu Oct 27, 2020
d722069
Destructure props in function body
caroqliu Oct 28, 2020
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
6 changes: 6 additions & 0 deletions build-system/compile/bundles.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -977,6 +977,12 @@ exports.extensionBundles = [
options: {hasCss: true},
type: TYPES.MISC,
},
{
name: 'amp-stream-gallery',
version: '1.0',
latestVersion: '0.1',
type: TYPES.MISC,
},
{
name: 'amp-selector',
version: ['0.1', '1.0'],
Expand Down
2 changes: 2 additions & 0 deletions build-system/test-configs/dep-check-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ exports.rules = [
'extensions/amp-stream-gallery/0.1/amp-stream-gallery.js->extensions/amp-base-carousel/0.1/carousel-events.js',
'extensions/amp-stream-gallery/0.1/amp-stream-gallery.js->extensions/amp-base-carousel/0.1/child-layout-manager.js',
'extensions/amp-stream-gallery/0.1/amp-stream-gallery.js->extensions/amp-base-carousel/0.1/responsive-attributes.js',
'extensions/amp-stream-gallery/1.0/stream-gallery.js->extensions/amp-base-carousel/1.0/base-carousel.js',
'extensions/amp-stream-gallery/1.0/stream-gallery.js->extensions/amp-base-carousel/1.0/base-carousel.jss.js',

// Facebook components
'extensions/amp-facebook-page/0.1/amp-facebook-page.js->extensions/amp-facebook/0.1/facebook-loader.js',
Expand Down
3 changes: 3 additions & 0 deletions extensions/amp-base-carousel/1.0/scroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ function ScrollerWithRef(
// intermediary renders will interupt scroll and cause jank.
const updateCurrentIndex = () => {
const container = containerRef.current;
if (!container) {
return;
}
const slideWidth = container./* OK */ offsetWidth / visibleCount;
scrollOffset.current =
container./* OK */ scrollLeft - offsetRef.current * slideWidth;
Expand Down
84 changes: 84 additions & 0 deletions extensions/amp-stream-gallery/1.0/amp-stream-gallery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {CSS as CAROUSEL_CSS} from '../../amp-base-carousel/1.0/base-carousel.jss';
import {CSS as GALLERY_CSS} from './stream-gallery.jss';
import {PreactBaseElement} from '../../../src/preact/base-element';
import {StreamGallery} from './stream-gallery';
import {isExperimentOn} from '../../../src/experiments';
import {isLayoutSizeDefined} from '../../../src/layout';
import {userAssert} from '../../../src/log';

/** @const {string} */
const TAG = 'amp-stream-gallery';

class AmpStreamGallery extends PreactBaseElement {
/** @override */
isLayoutSupported(layout) {
userAssert(
isExperimentOn(this.win, 'amp-stream-gallery-bento'),
'expected amp-stream-gallery-bento experiment to be enabled'
);
return isLayoutSizeDefined(layout);
}
}

/** @override */
AmpStreamGallery['Component'] = StreamGallery;

/** @override */
AmpStreamGallery['layoutSizeDefined'] = true;

/** @override */
AmpStreamGallery['children'] = {
'arrowPrev': {
name: 'arrowPrev',
selector: '[slot="prev-arrow"]',
single: true,
},
'arrowNext': {
name: 'arrowNext',
selector: '[slot="next-arrow"]',
single: true,
},
'children': {
name: 'children',
selector: '*', // This should be last as catch-all.
single: false,
},
};

/** @override */
AmpStreamGallery['props'] = {
'extraSpace': {attr: 'extra-space', type: 'string'},
'insetArrowVisibility': {attr: 'inset-arrow-visibility', type: 'string'},
'loop': {attr: 'loop', type: 'boolean'},
'minItemWidth': {attr: 'min-item-width', type: 'number'},
'maxItemWidth': {attr: 'max-item-width', type: 'number'},
'maxVisibleCount': {attr: 'max-visible-count', type: 'number'},
'minVisibleCount': {attr: 'min-visible-count', type: 'number'},
'outsetArrows': {attr: 'outset-arrows', type: 'boolean'},
'peek': {attr: 'peek', type: 'number'},
'slideAlign': {attr: 'slide-align', type: 'string'},
'snap': {attr: 'snap', type: 'boolean'},
};

/** @override */
AmpStreamGallery['shadowCss'] = GALLERY_CSS + CAROUSEL_CSS;

AMP.extension(TAG, '1.0', (AMP) => {
AMP.registerElement(TAG, AmpStreamGallery);
});
90 changes: 90 additions & 0 deletions extensions/amp-stream-gallery/1.0/storybook/Basic.amp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as Preact from '../../../../src/preact';
import {boolean, number, select, withKnobs} from '@storybook/addon-knobs';
import {withA11y} from '@storybook/addon-a11y';
import {withAmp} from '@ampproject/storybook-addon';

const INSET_ARROW_VISIBILITY = ['auto', 'always', 'never'];

export default {
title: 'amp-stream-gallery-1_0',
decorators: [withKnobs, withA11y, withAmp],

parameters: {
extensions: [{name: 'amp-stream-gallery', version: '1.0'}],

experiments: ['amp-stream-gallery-bento', 'amp-stream-carousel-bento'],
},
};

export const Default = () => {
const slideCount = number('slide count', 15, {min: 3, max: 99});
const extraSpace = boolean('extra space around?', true);
const insetArrowVisibility = select(
'inset arrow visibility',
INSET_ARROW_VISIBILITY
);
const loop = boolean('loop', true);
const snap = boolean('snap', true);
const slideAlign = select('slide align', ['start', 'center']);
const minItemWidth = number('min item width', 130, {min: 1});
const maxItemWidth = number('max item width', 180, {min: 1});
const minVisibleCount = number('min visible count', 2.5, {min: 1});
const maxVisibleCount = number('max visible count', 5, {min: 1});
const peek = number('peek', 0, {min: 1});
const outsetArrows = boolean('outset arrows', true);
const colorIncrement = Math.floor(255 / (slideCount + 1));
return (
<amp-stream-gallery
width="735"
height="225"
layout="responsive"
extra-space={extraSpace}
inset-arrow-visibility={insetArrowVisibility}
loop={loop}
min-item-width={minItemWidth}
max-item-width={maxItemWidth}
min-visible-count={minVisibleCount}
max-visible-count={maxVisibleCount}
outset-arrows={outsetArrows}
peek={peek}
slide-align={slideAlign}
snap={snap}
>
{Array.from({length: slideCount}, (x, i) => {
const v = colorIncrement * (i + 1);
return (
<amp-layout width="245" height="225" layout="flex-item">
<svg viewBox="0 0 440 225">
<rect
style={{fill: `rgb(${v}, 100, 100)`}}
width="440"
height="225"
/>
Sorry, your browser does not support inline SVG.
</svg>
</amp-layout>
);
})}
</amp-stream-gallery>
);
};

Default.story = {
name: 'default',
};
80 changes: 80 additions & 0 deletions extensions/amp-stream-gallery/1.0/storybook/Basic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Copyright 2020 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as Preact from '../../../../src/preact';
import {StreamGallery} from '../stream-gallery';
import {boolean, number, select, withKnobs} from '@storybook/addon-knobs';
import {withA11y} from '@storybook/addon-a11y';

const INSET_ARROW_VISIBILITY = ['auto', 'always', 'never'];

export default {
title: 'StreamGallery',
component: StreamGallery,
decorators: [withA11y, withKnobs],
};

export const _default = () => {
const width = number('width', 735);
const height = number('height', 225);
const slideCount = number('slide count', 5, {min: 0, max: 99});
const extraSpace = boolean('extra space around?', true);
const insetArrowVisibility = select(
'inset arrow visibility',
INSET_ARROW_VISIBILITY
);
const loop = boolean('loop', true);
const snap = boolean('snap', true);
const slideAlign = select('slide align', ['start', 'center']);
const minItemWidth = number('min item width', 130, {min: 1});
const maxItemWidth = number('max item width', 180, {min: 1});
const minVisibleCount = number('min visible count', 3, {min: 1});
const maxVisibleCount = number('max visible count', 5, {min: 1});
const peek = number('peek', 0, {min: 1});
const outsetArrows = boolean('outset arrows', true);
const colorIncrement = Math.floor(255 / (slideCount + 1));
return (
<>
<StreamGallery
extraSpace={extraSpace ? 'around' : ''}
insetArrowVisibility={insetArrowVisibility}
loop={loop}
slideAlign={slideAlign}
snap={snap}
outsetArrows={outsetArrows}
minItemWidth={minItemWidth}
maxItemWidth={maxItemWidth}
minVisibleCount={minVisibleCount}
maxVisibleCount={maxVisibleCount}
peek={peek}
style={{width, height}}
>
{Array.from({length: slideCount}, (_, i) => {
const v = colorIncrement * (i + 1);
return (
<div
style={{
backgroundColor: `rgb(${v}, 100, 100)`,
width,
height,
}}
></div>
);
})}
</StreamGallery>
</>
);
};
Loading