| Version | Tag | Status | API |
|---|---|---|---|
| v1 | <oc-cinema-v1> |
Stable, allowed for generation | CinemaV1 |
Overview (v1)
Source: ./src/components/cinema/v1/Overview.mdx
Cinema
The cinema component provides a way to display multiple items in a horizontal slide. This component is useful in cases where visual space is limited, and you want to present a series of related content (e.g., images or cards) that the user can navigate through.
Default variation
Story Default:
<oc-cinema-v1 oc-aria-label="cinema of placeholders">
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 9</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 10</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 11</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 12</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 13</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 14</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 15</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 16</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 17</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 18</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 19</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 20</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 21</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 22</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 23</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 24</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 25</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 26</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 27</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 28</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 29</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 30</oc-placeholder-v1>
</oc-cinema-v1>
Configuration
The cinema component is configurable, allowing you to tailor its features and appearance to your specific needs. To explore all the available options and adjust the component, use the component configurator and see the changes affect the component in real-time.
Usage guidelines
Before integrating the cinema component into your project, make sure you have correctly installed the OTTO components package. Look through the variations page for examples of possible component variations. Here, you can discover both common and specific variations that address different use cases.
Info
See the Cinema UX documentation for detailed user experience guidelines.
Accessibility
The cinema component comes with a set of built-in accessibility features to ensure a seamless experience for all users.
Provide an ARIA label
To make the cinema recognizable for screen readers, use the oc-aria-label attribute to provide clear and descriptive context information.
See the general accessibility documentation for guidance on using oc-aria-label, including how it works with link and masked link behavior.
Alternatively, you can surround the component with a <section> (or role="region") element with an ARIA label.
<section aria-label="My cinema section">
<oc-cinema>
<!-- Cinema items here -->
</oc-cinema>
</section>
Events
The cinema component provides events for checking the item visibility and the stage scroll state.
Item visibility changed
The oc-item-visibility-changed event triggers, whenever the stage is scrolled and new items enter the viewport.
The event returns an object that provides an array with all items that are currently visible on the page, their respective index positions in the collection, the scroll direction of the cinema stage,
whether it is currently scrolling or not and the source that triggered the scroll:
myCinema.addEventListener("oc-item-visibility-changed", (event) => {
event.detail; // Returns: { { visibleItems: {elements: HTMLElement[]; indices: number[] }, scrollDirection: "left | right", stageIsScrolling: boolean, scrollSource: "arrows" | "pagination-dots" | "move-method" | "swipe" }
});
For more information on tracking the visibility state of the component itself, see the visibility tracking documentation.
Stage scroll
The oc-stage-scroll event triggers when the stage is being scrolled.
It returns the boolean isScrolling that reflects the current state as well as the source that initiated the scroll:
myCinema.addEventListener("oc-stage-scroll", (event) => {
event.detail; // Returns: { isScrolling: boolean, source: "arrows" | "pagination-dots" | "move-method" | "swipe" }
});
Stage scroll completed
The oc-stage-scroll-completed event triggers when the stage scroll has been completed.
It returns an object that provides an array with all items that are currently visible on the page, their respective index positions in the collection, the scroll direction of the cinema stage
and the source that triggered the scroll:
myCinema.addEventListener("oc-stage-scroll-completed", (event) => {
event.detail; // Returns: { { visibleItems: {elements: HTMLElement[]; indices: number[] }, scrollDirection: "left | right", scrollSource: "arrows" | "pagination-dots" | "move-method" | "swipe" }
});
Sources that initiate the scroll can be:
arrows- When the user interacts via the visual buttons.pagination-dots- When the user interacts via the additional pagination-dots.move-method- When the stage is being scrolled programmatically.swipe- When the user interacts via swipe gestures on smartphones or laptop touchpads.
Configuration (v1)
Source: ./src/components/cinema/v1/Configuration.mdx
Cinema configuration
Configure the cinema component with the controls below and see the changes live in the preview canvas. Click the Show code button within the preview canvas to see the source code for the current component configuration.
Story Default:
<oc-cinema-v1 oc-aria-label="cinema of placeholders">
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 9</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 10</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 11</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 12</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 13</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 14</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 15</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 16</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 17</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 18</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 19</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 20</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 21</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 22</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 23</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 24</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 25</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 26</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 27</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 28</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 29</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 30</oc-placeholder-v1>
</oc-cinema-v1>
Interactive configurator (Storybook controls); every option is listed in the API section of this file.
API v1
Source: ./src/components/cinema/v1/CinemaV1.API.g.mdx
Cinema v1 API
API: <oc-cinema-v1> (CinemaV1)
The Cinema component provides a way to display multiple items in a horizontal slide. This component is useful in cases where visual space is limited, and you want to present a series of related content (e.g., images or cards) that the user can navigate through.
The Cinema component supports navigation through arrow buttons. The position of these buttons can be customized. It also supports ARIA labels for accessibility.
Attributes / properties
| Attribute | Type | Default | Required | Description |
|---|---|---|---|---|
resizing |
"none" | "stretch" | "cut" | "stretch-cut" |
"stretch-cut" |
no | Specifies the resizing behavior of the items in the cinema. The resizing behavior determines - none Items are not resized. - stretch Items are stretched to fill the available space. - cut Items are cut off when they overflow. - stretch-cut Items are stretched to fill the available space, and cut off when they overflow. |
cut |
string |
"0.5" |
no | Sets the cut percentage of the items. Used when the resizing property is set to cut or stretch-cut. |
pagination-dots |
boolean |
false |
no | Whether Pagination Dots should be visible. Pagination dots provide a visual indication of the number of items in the cinema, and which item is currently being viewed. |
hide-skip-link |
boolean |
false |
no | Hides the skip link that allows users to skip the carousel content. Set to true to hide the skip link. |
items-per-page |
string |
no | Sets the desired amount of items per page | |
gap |
string |
"16px" |
no | Sets the gap between items. |
stage-spacing |
string |
"16px" |
no | Sets the spacing on the outer sides of the stage. |
arrow-button-position |
string |
"50%" |
no | Specifies the custom position of the arrow buttons. This can be any valid CSS value for the top property. The arrow buttons are used to navigate through the items in the cinema. |
item-visibility-threshold |
number[] |
no | The custom threshold used for tracking the visibility of the items | |
visible-items |
HTMLElement[] |
no | The amount of current visible items. | |
oc-aria-label |
string |
no | Sets the ARIA label of the cinema section. This label is used by screen readers to provide context to users with visual impairments. The label should describe the overall content or purpose of the cinema. Providing an ARIA label can also be done by adding a surrounding <section> (or role="region") element with an ARIA label. |
Slots
| Slot | Required | Description |
|---|---|---|
default |
yes | Defines the main content of the cinema. This slot should contain a series of items (e.g., images or cards) that you want to present in a cinema format. |
Events
| Event | Detail type | Description |
|---|---|---|
oc-item-visibility-changed |
CustomEvent<ScrollEventDetail> |
Scrolling the cinema triggers the oc-item-visibility-changed event. The event returns an object that provides an array with all items that are currently visible on the page, their respective index positions in the collection, and the scroll direction of the cinema stage |
oc-stage-scroll |
CustomEvent<ScrollEventDetail> |
Scrolling the cinema triggers the oc-stage-scroll event. The event returns a boolean of the current state as well as the source that initiated the scroll. |
oc-stage-scroll-completed |
CustomEvent<ScrollEventDetail> |
Dispatched after stage scroll initiated by user or programmatically has completed. Meaning there is no scrolling of the stage within a defined timeout. The event returns an object that provides an array with all items that are currently visible on the page, their respective index positions in the collection, and the scroll direction of the cinema stage. The event also returns the source that initiated the scroll. |
oc-property-change |
OcCinemaV1Events["oc-property-change"] |
Whenever a property value changes, this event triggers. Use this event to track all property changes within the component. Refer to the Events documentation for more information. |
oc-mount |
{ component: string; } |
Fired when the component is mounted to the DOM. The event is fired when the onMount hook of the component is called by the runtime. |
oc-unmount |
{ component: string; } |
Fired when the component is unmounted from the DOM. The event is fired when the function returned by the onMount hook of the component is called by the runtime. |
Methods
moveTo:(index: number, options?: { source?: "arrows" | "pagination-dots" | undefined; reducedMotion?: boolean | undefined; } | undefined) => voidScrolls cinema elements to the specified page index. The index corresponds to the pages calculated based on the container width and item sizes.
Parameters:
index:number- The index of the page that should be scrolled to.options:{ source?: "arrows" | "pagination-dots" | undefined; reducedMotion?: boolean | undefined; } | undefined- Optional scroll behavior settings.
Returns:
voidExample:
const cinema = document.querySelector("oc-cinema-v1"); cinema.moveTo(2, { reducedMotion: true, source: "pagination-dots" });
CSS custom properties
| Custom property | Default | Description |
|---|---|---|
--arrow-button-position |
50% |
Sets the position of the arrow buttons. |
--cut |
0.5 |
Sets the cut percentage of the items. Used when the resizing property is set to cut or stretch-cut. |
--gap |
16px |
Sets the gap between items. |
--items-per-page |
Sets the desired amount of items per page Works only when resizing-mode is set to stretch-cut or cut |
|
--stage-spacing |
16px |
Sets the spacing on the outer sides of the stage. |
Variations (v1)
Source: ./src/components/cinema/v1/Variations.mdx
Variations
Listed below are the most common variations of the cinema component as well as specific component variations for different use cases.
You can explore all available options using the component configurator, adjust the component to your needs, and see the changes live in a preview canvas.
Default
Story: components-cinema-variations--default · tags: components, cinema, v1
The default configuration with resizing set to stretch-cut.
<oc-cinema-v1 oc-aria-label="cinema of placeholders">
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 9</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 10</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 11</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 12</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 13</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 14</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 15</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 16</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 17</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 18</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 19</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 20</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 21</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 22</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 23</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 24</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 25</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 26</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 27</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 28</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 29</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM 30</oc-placeholder-v1>
</oc-cinema-v1>
3 Items
Story: components-cinema-variations--three-items · tags: components, cinema, v1
The configuration with 3 items. The resizing is set to none. The items are not resized.
Args: defaultSlot=(see snippet), resizing=none
<oc-cinema-v1 oc-aria-label="cinema of placeholders" resizing="none">
<oc-placeholder-v1 style="width: 100px" interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 style="width: 100px" interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 style="width: 100px" interactive="true">ITEM 3</oc-placeholder-v1>
</oc-cinema-v1>
Stretch-Items
Story: components-cinema-variations--stretch-items · tags: components, cinema, v1
The configuration with 3 items. The resizing is set to stretch. The items are stretched to fill the available space.
Args: defaultSlot=(see snippet), resizing=stretch
<oc-cinema-v1 oc-aria-label="cinema of placeholders" resizing="stretch">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
</oc-cinema-v1>
Different Item-Widths
Story: components-cinema-variations--different-item-widths · tags: components, cinema, v1
The configuration with items of different widths. The resizing is set to stretch.
Args: defaultSlot=(see snippet), resizing=stretch
<oc-cinema-v1 oc-aria-label="cinema of placeholders" resizing="stretch">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 85%">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
Custom items per page
Story: components-cinema-variations--custom-items-per-page · tags: components, cinema, v1
The configuration with a set number of items per page.
Args: defaultSlot=(see snippet), items-per-page=7
<oc-cinema-v1 oc-aria-label="cinema of placeholders" items-per-page="7">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
Demo: Custom stage spacing
Story: components-cinema-variations--demo-custom-stage-spacing · tags: components, cinema, v1
Demo showcasing on how stage-spacing can be customized.
<div style="border: 2px dashed lightgray; padding: 16px 0">
<oc-cinema-v1>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
</oc-cinema-v1>
</div>
<div style="display: flex; flex-direction: column; gap: 16px; margin-top: 32px;">
<div style="display: flex; gap: 16px; align-items: center;">
<label for="stage-spacing-slider">Stage Spacing</label>
<input
type="range"
name="stage-spacing-slider"
id="stage-spacing-slider"
min="0"
max="64"
value="16"
/>
<span id="stage-spacing-slider-value">16px</span>
</div>
</div>
<script>
(() => {
const cinema = document.querySelector("oc-cinema-v1");
const stageSpacingSlider = document.getElementById("stage-spacing-slider");
const stageSpacingSliderValue = document.getElementById("stage-spacing-slider-value");
stageSpacingSlider.addEventListener("input", (event) => {
const value = event.target.value + "px";
cinema.style.setProperty("--stage-spacing", value);
stageSpacingSliderValue.textContent = value;
});
})();
</script>
Story source (TypeScript, verbatim from Storybook)
{
name: "Demo: Custom stage spacing",
argTypes: hideControlsBadge(Metadata),
parameters: {
chromatic: {
hideInChromatic: true,
disableSnapshot: true
},
controls: {
disabled: true
}
},
render: () => {
return html`
<div style="border: 2px dashed lightgray; padding: 16px 0">
<oc-cinema-v1>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
</oc-cinema-v1>
</div>
<div style="display: flex; flex-direction: column; gap: 16px; margin-top: 32px;">
<div style="display: flex; gap: 16px; align-items: center;">
<label for="stage-spacing-slider">Stage Spacing</label>
<input
type="range"
name="stage-spacing-slider"
id="stage-spacing-slider"
min="0"
max="64"
value="16"
/>
<span id="stage-spacing-slider-value">16px</span>
</div>
</div>
<script>
(() => {
const cinema = document.querySelector("oc-cinema-v1");
const stageSpacingSlider = document.getElementById("stage-spacing-slider");
const stageSpacingSliderValue = document.getElementById("stage-spacing-slider-value");
stageSpacingSlider.addEventListener("input", (event) => {
const value = event.target.value + "px";
cinema.style.setProperty("--stage-spacing", value);
stageSpacingSliderValue.textContent = value;
});
})();
</script>
`;
}
}
Demo: Move-Method
Story: components-cinema-variations--demo-move-method · tags: components, cinema, v1
Demo showcasing the movement of the stage programmatically.
Args: defaultSlot=(see snippet), pagination-dots=true
<!-- The component-->
<oc-cinema-v1 oc-aria-label="cinema of placeholders" pagination-dots><oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
</oc-cinema-v1>
<br />
<br />
<p>
<oc-button-v1 size="50"> Move stage to page 5 </oc-button-v1>
<br />
<br />
<textarea
style="width: 100%; height: 4rem; resize:none; font-family: Monospace; border:0;"
aria-label="example"
disabled
>
const moveMyCinema = (myCinema) => {
myCinema.moveTo(5);
}
</textarea>
</p>
<br />
<br />
<p>
<oc-button-v1 size="50"> Move stage to page 5 (reduced motion)</oc-button-v1>
<br />
<br />
<textarea
style="width: 100%; height: 4rem; resize:none; font-family: Monospace; border:0;"
aria-label="example"
disabled
>
const moveMyCinema = (myCinema) => {
myCinema.moveTo(5, { reducedMotion: true });
}
</textarea>
</p>
<script>
(() => {
const [moveStage, moveStageReducedMotion] = document.getElementsByTagName("oc-button-v1");
moveStage.addEventListener("click", () => {
document.querySelector("oc-cinema-v1").moveTo(5);
});
moveStageReducedMotion.addEventListener("click", () => {
document.querySelector("oc-cinema-v1").moveTo(5, { reducedMotion: true });
});
})();
</script>
Story source (TypeScript, verbatim from Storybook)
{
name: "Demo: Move-Method",
parameters: {
chromatic: {
hideInChromatic: true,
disableSnapshot: true
}
},
args: {
defaultSlot: `<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
<oc-placeholder-v1 variant="image" width="100%" height="100%" style="height: 300px" interactive="true"></oc-placeholder-v1>
`,
"pagination-dots": true
},
render: ({
defaultSlot,
...props
}) => {
return html`
<!-- The component-->
<oc-cinema-v1 ${spread(props)}>${unsafeHTML(defaultSlot)}</oc-cinema-v1>
<br />
<br />
<p>
<oc-button-v1 size="50"> Move stage to page 5 </oc-button-v1>
<br />
<br />
<textarea
style="width: 100%; height: 4rem; resize:none; font-family: Monospace; border:0;"
aria-label="example"
disabled
>
const moveMyCinema = (myCinema) => {
myCinema.moveTo(5);
}
</textarea>
</p>
<br />
<br />
<p>
<oc-button-v1 size="50"> Move stage to page 5 (reduced motion)</oc-button-v1>
<br />
<br />
<textarea
style="width: 100%; height: 4rem; resize:none; font-family: Monospace; border:0;"
aria-label="example"
disabled
>
const moveMyCinema = (myCinema) => {
myCinema.moveTo(5, { reducedMotion: true });
}
</textarea>
</p>
<script>
(() => {
const [moveStage, moveStageReducedMotion] = document.getElementsByTagName("oc-button-v1");
moveStage.addEventListener("click", () => {
document.querySelector("oc-cinema-v1").moveTo(5);
});
moveStageReducedMotion.addEventListener("click", () => {
document.querySelector("oc-cinema-v1").moveTo(5, { reducedMotion: true });
});
})();
</script>
`;
}
}
Demo: Multiple Cinemas
Story: components-cinema-variations--demo-multiple-cinemas · tags: components, cinema, v1
The configuration with items of different widths. The resizing is set to stretch.
<h1>List of Cinemas</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<oc-cinema-v1
id="cinema-1"
pagination-dots
item-visibility-threshold="[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]"
>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<div style="margin-top: 32px"></div>
<oc-cinema-v1 id="cinema-2" pagination-dots item-visibility-threshold="[0.4, 0.8]">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<div style="margin-top: 32px"></div>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<oc-cinema-v1 id="cinema-3" pagination-dots item-visibility-threshold="[0.3, 0.6, 0.9]">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<div style="margin-top: 32px"></div>
<oc-cinema-v1 id="cinema-4" pagination-dots>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<p>
This cinema element has special tracking attributes (starting with <code>data-tr-v1</code>),
which configure the tracking engine to observe the element by utilizing the provided
threshold values. The element will be tracked when it becomes visible by at least 50% (as
configured). And then tracking engin will first emit an event
<code>tr-become-visible</code> containing the tracking trigger. and then if the event is not
canceled, it will submit the default tracking method <code>submitMiniAction</code> to the
tracking library (bct).
</p>
<p>
you can make the submission visible in the console by enabling the tracking debug mode and
providing a fake implementation (since bct is not enabled in storybook)
</p>
<pre><code>
otto.tracking.submitMiniAction.assignFunction(console.log);
o_global.debug.activate("nexus.otto.tracking", "debug");
</code></pre>
<oc-cinema-v1
id="cinema-5"
pagination-dots
data-tr-v1
data-tr-v1-tr-become-visible.observer='{ "threshold": 0.5 }'
data-tr-v1-tr-become-visible.updates='[{ "featureId": "foo-barid", "status": "works" }]'
>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<oc-cinema-v1 id="cinema-6" pagination-dots item-visibility-threshold="[0.5]">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
Story source (TypeScript, verbatim from Storybook)
{
name: "Demo: Multiple Cinemas",
parameters: {
controls: {
disabled: true
},
chromatic: {
hideInChromatic: true,
disableSnapshot: true
}
},
render: () => {
return html`
<h1>List of Cinemas</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<oc-cinema-v1
id="cinema-1"
pagination-dots
item-visibility-threshold="[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]"
>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<div style="margin-top: 32px"></div>
<oc-cinema-v1 id="cinema-2" pagination-dots item-visibility-threshold="[0.4, 0.8]">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<div style="margin-top: 32px"></div>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<oc-cinema-v1 id="cinema-3" pagination-dots item-visibility-threshold="[0.3, 0.6, 0.9]">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<div style="margin-top: 32px"></div>
<oc-cinema-v1 id="cinema-4" pagination-dots>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<p>
This cinema element has special tracking attributes (starting with <code>data-tr-v1</code>),
which configure the tracking engine to observe the element by utilizing the provided
threshold values. The element will be tracked when it becomes visible by at least 50% (as
configured). And then tracking engin will first emit an event
<code>tr-become-visible</code> containing the tracking trigger. and then if the event is not
canceled, it will submit the default tracking method <code>submitMiniAction</code> to the
tracking library (bct).
</p>
<p>
you can make the submission visible in the console by enabling the tracking debug mode and
providing a fake implementation (since bct is not enabled in storybook)
</p>
<pre><code>
otto.tracking.submitMiniAction.assignFunction(console.log);
o_global.debug.activate("nexus.otto.tracking", "debug");
</code></pre>
<oc-cinema-v1
id="cinema-5"
pagination-dots
data-tr-v1
data-tr-v1-tr-become-visible.observer='{ "threshold": 0.5 }'
data-tr-v1-tr-become-visible.updates='[{ "featureId": "foo-barid", "status": "works" }]'
>
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
<oc-cinema-v1 id="cinema-6" pagination-dots item-visibility-threshold="[0.5]">
<oc-placeholder-v1 interactive="true">ITEM 1</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 1500px">ITEM 2</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 3</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 4</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true" style="width: 100px">ITEM 5</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 6</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 7</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 8</oc-placeholder-v1>
<oc-placeholder-v1 interactive="true">ITEM 9</oc-placeholder-v1>
</oc-cinema-v1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis facilis nobis nisi odit
maiores libero assumenda repudiandae. Repudiandae sapiente odit id. Voluptas dolores
repellendus sit corrupti ab dolor distinctio, expedita id quod suscipit. Saepe culpa libero
laborum vel quos illum officia, fuga corporis dolor excepturi! Excepturi, nobis. Pariatur
itaque voluptas tenetur qui aut eveniet, aliquam numquam quia distinctio dolor ducimus quod
optio quam soluta expedita eligendi quae, ipsa culpa. Praesentium autem impedit,
necessitatibus quos porro cupiditate ipsam eveniet nisi illo. Sequi molestias magnam
exercitationem repudiandae maiores dolor itaque earum necessitatibus facere. Officiis
dolorem, hic modi, maxime sint sapiente, libero quas impedit earum quibusdam rerum minus
atque doloribus! Accusamus impedit rerum ea pariatur sunt ex iure consequatur! Quisquam
maiores doloremque, sit vero, sint a ullam eum possimus dicta voluptatem numquam sequi
eveniet dolorem recusandae ratione odio! Sint reprehenderit earum quas fugit dolorum
laudantium maiores officiis necessitatibus harum? Exercitationem provident dolores soluta.
Rerum minus hic asperiores nesciunt, error quae blanditiis expedita ducimus facere provident
reprehenderit, ex autem tempore praesentium? Culpa blanditiis repellendus earum qui? Atque
dolorem, impedit dignissimos non pariatur blanditiis porro nisi doloribus? Fugit recusandae
qui dignissimos, natus architecto sapiente sunt laudantium tenetur temporibus iste totam
placeat facilis facere quia doloribus.
</p>
`;
}
}
Demo: Device Type Detection
Story: components-cinema-variations--demo-device-type-detection · tags: components, cinema, v1
Demo showing the detected device type and how it affects the cinema navigation arrows. On touch-only devices, arrows are hidden. On hybrid and desktop devices, arrows are shown.
<p>
<strong>Detected device type:</strong> ${deviceType}<br />
<code
>isTouchable: ${pt.isTouchable} · isHybrid: ${pt.isHybrid} · isMouse: ${pt.isMouse}</code
>
</p>
<p>
On <strong>touch-only</strong> devices, navigation arrows are hidden (users swipe
natively).<br />
On <strong>hybrid</strong> and <strong>desktop/mouse</strong> devices, navigation arrows are
visible.
</p>
<oc-cinema-v1 pagination-dots>
${unsafeHTML(Array.from(Array(8), (_, i) => `<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM ${i + 1}</oc-placeholder-v1>`).join(""))}
</oc-cinema-v1>
Story source (TypeScript, verbatim from Storybook)
{
name: "Demo: Device Type Detection",
parameters: {
controls: {
disabled: true
},
chromatic: {
hideInChromatic: true,
disableSnapshot: true
}
},
render: () => {
const pt = pointerType.get();
let deviceType: string;
if (pt.isHybrid) {
deviceType = "Hybrid (touch + pointer)";
} else if (pt.isTouchable) {
deviceType = "Touch only";
} else {
deviceType = "Mouse / Desktop";
}
return html`
<p>
<strong>Detected device type:</strong> ${deviceType}<br />
<code
>isTouchable: ${pt.isTouchable} · isHybrid: ${pt.isHybrid} · isMouse: ${pt.isMouse}</code
>
</p>
<p>
On <strong>touch-only</strong> devices, navigation arrows are hidden (users swipe
natively).<br />
On <strong>hybrid</strong> and <strong>desktop/mouse</strong> devices, navigation arrows are
visible.
</p>
<oc-cinema-v1 pagination-dots>
${unsafeHTML(Array.from(Array(8), (_, i) => `<oc-placeholder-v1 interactive="true" style="width: 205px">ITEM ${i + 1}</oc-placeholder-v1>`).join(""))}
</oc-cinema-v1>
`;
}
}
Interaction tests (CinemaV1.interactions.stories.ts)
Interaction test stories (automated tests, not usage patterns).
Move Cinema
Story: components-cinema-interaction-tests--move-cinema · tags: components, cinema, v1, interactions, play-fn
Args: pagination-dots=true, defaultSlot=(see snippet)
<oc-cinema-v1 style="width: 800px" pagination-dots>
<div tabindex="0" style="background: lightcyan">
Content
</div>
<div tabindex="0" style="background: lightcyan">
Content
</div>
<div tabindex="0" style="background: lightcyan">
Content
</div>
<div tabindex="0" style="background: lightcyan">
Content
</div>
<div tabindex="0" style="background: lightcyan">
Content
</div>
<div tabindex="0" style="background: lightcyan">
Content
</div>
</oc-cinema-v1>
Story source (TypeScript, verbatim from Storybook)
{
args: {
"pagination-dots": true,
defaultSlot: `${new Array(6).fill(`<div tabindex="0" style="background: lightcyan">
Content
</div>
`).join("")}`
},
parameters: {
chromatic: {
disableSnapshot: true
}
},
render(args) {
const {
defaultSlot,
...props
} = args;
return html` <oc-cinema-v1 style="width: 800px" ${spread(props)}>
${unsafeHTML(defaultSlot)}
</oc-cinema-v1>`;
},
play: async ({
canvasElement
}) => {
await macrotasks(10);
const {
paginationDots,
stageElement,
prevButton,
nextButton
} = getSutElements(canvasElement);
await waitFor("initial", async () => {
await expect(stageElement.scrollLeft, "scrollLeft should be correct").toBe(0);
await expect(prevButton, "previous button should not be visible").not.toBeVisible();
await expect(nextButton, "next button should be visible").toBeVisible();
await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([1, 0, 0]);
});
// Perform scroll to the right
await click(nextButton);
await waitFor("scrolled to right", async () => {
await expect(prevButton, "previous button should be visible").toBeVisible();
await expect(nextButton, "next button should be visible").toBeVisible();
await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([0, 1, 0]);
});
// Perform scroll to the right
await click(nextButton);
await waitFor("scrolled to right", async () => {
await expect(prevButton, "previous button should be visible").toBeVisible();
await expect(nextButton, "next button should not be visible").not.toBeVisible();
await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([0, 0, 1]);
});
// Perform scroll to the left
await click(prevButton);
await waitFor("scrolled to left", async () => {
await expect(prevButton, "previous button should be visible").toBeVisible();
await expect(nextButton, "next button should be visible").toBeVisible();
await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([0, 1, 0]);
});
// Perform scroll to the left
await click(prevButton);
await waitFor("scrolled to left", async () => {
await expect(prevButton, "previous button should not be visible").not.toBeVisible();
await expect(nextButton, "next button should be visible").toBeVisible();
await expect(toVisibleArray(paginationDots), "pagination dots should be correct").toEqual([1, 0, 0]);
});
}
}
Move Cinema Without Resizing
Story: components-cinema-interaction-tests--move-cinema-without-resizing · tags: components, cinema, v1, interactions
Args: resizing=none, pagination-dots=true, defaultSlot=(see snippet)
Story source (TypeScript, verbatim from Storybook)
MoveCinemaWithoutResizingStories.MoveCinemaWithoutResizing
Asynchronous Content
Story: components-cinema-interaction-tests--asynchronous-content · tags: components, cinema, v1, interactions, play-fn
<oc-cinema-v1 pagination-dots style="width: 500px"></oc-cinema-v1>
Story source (TypeScript, verbatim from Storybook)
{
render() {
return html` <oc-cinema-v1 pagination-dots style="width: 500px"></oc-cinema-v1>`;
},
play: async ({
canvasElement
}) => {
await macrotasks(10);
const {
cinemaElement
} = getSutElements(canvasElement);
const item = document.createElement("div");
item.innerHTML = "Content";
item.tabIndex = 0;
const items = Array.from({
length: 20
}).map(() => item.cloneNode(true) as HTMLElement);
// eslint-disable-next-line no-restricted-syntax
for (const i of items) {
cinemaElement.append(i);
// eslint-disable-next-line no-await-in-loop
await macrotasks(1);
}
const paginationDots = Array.from(cinemaElement.shadowRoot!.querySelectorAll(".paginationdots__item"));
await expect(paginationDots.length, "pagination dots should be rendered").toBe(20);
await expect(paginationDots[0].classList.contains("paginationdots__item--selected"), "first pagination dot should be selected").toBeTruthy();
await expect(paginationDots.slice(1).some(e => e.classList.contains("paginationdots__item--selected")), "other pagination dots should not be selected").toBeFalsy();
}
}
Pagination With Different Sizes
Story: components-cinema-interaction-tests--pagination-with-different-sizes · tags: components, cinema, v1, interactions, play-fn
<div tabindex="0" style="background: lightcyan; width: ${w}px">
${i + 1}. ${w}px
</div>
Story source (TypeScript, verbatim from Storybook)
{
render() {
const items = (widthes: number[]) => {
return widthes.map((w, i) => html`<div tabindex="0" style="background: lightcyan; width: ${w}px">
${i + 1}. ${w}px
</div>`);
};
return html`
<div data-testid="cinema1">
<h3>Gap=default</h3>
<oc-cinema-v1 pagination-dots style="width: 500px" resizing="none">
${items([124, 157, 131, 219, 84, 92, 317, 160, 142])}
</oc-cinema-v1>
</div>
<div data-testid="cinema2">
<h3>Gap=50px perfect fit 3 items</h3>
<oc-cinema-v1 pagination-dots style="width: 466px" resizing="none" gap="50px">
${items([100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100])}
</oc-cinema-v1>
</div>
<div data-testid="cinema3">
<h3>Gap=50px perfect fit 1 item</h3>
<oc-cinema-v1 pagination-dots style="width: 466px" resizing="none" gap="50px">
${items([400, 400, 400])}
</oc-cinema-v1>
</div>
<style>
div > oc-cinema-v1 {
background: lightcoral;
}
</style>
`;
},
play: async ({
canvasElement
}) => {
await macrotasks(10);
const sut1 = getSutElements(canvasElement.querySelector('[data-testid="cinema1"]')!);
sut1.prevButton.style.display = "none"; // hide buttons for better debugging
sut1.nextButton.style.display = "none"; // hide buttons for better debugging
const sut2 = getSutElements(canvasElement.querySelector('[data-testid="cinema2"]')!);
sut2.prevButton.style.display = "none"; // hide buttons for better debugging
sut2.nextButton.style.display = "none"; // hide buttons for better debugging
const sut3 = getSutElements(canvasElement.querySelector('[data-testid="cinema3"]')!);
sut3.prevButton.style.display = "none"; // hide buttons for better debugging
sut3.nextButton.style.display = "none"; // hide buttons for better debugging
// TEST CINEMA 1
await expect(sut1.paginationDots.length).toBe(4);
await expect(sut1.stageElement.scrollLeft).toBe(0);
await click(sut1.paginationDots[1]);
await waitFor("cinema 1 page 2", async () => {
await expect(sut1.stageElement.scrollLeft).toBeGreaterThanOrEqual(439);
await expect(sut1.stageElement.scrollLeft).toBeLessThanOrEqual(440);
});
await click(sut1.paginationDots[2]);
await waitFor("cinema 1 page 3", async () => {
await expect(sut1.stageElement.scrollLeft).toBeGreaterThanOrEqual(827);
await expect(sut1.stageElement.scrollLeft).toBeLessThanOrEqual(828);
});
await click(sut1.paginationDots[3]);
await waitFor("cinema 1 page 4", async () => {
await expect(sut1.stageElement.scrollLeft === 1086 || sut1.stageElement.scrollLeft === 1070).toBeTruthy();
});
// TEST CINEMA 2
await expect(sut2.paginationDots.length).toBe(6);
await expect(sut2.stageElement.scrollLeft).toBe(0);
await click(sut2.paginationDots[1]);
await waitFor("cinema 2 page 2", async () => {
await expect([416, 433].includes(sut2.stageElement.scrollLeft)).toBeTruthy();
});
await click(sut2.paginationDots[2]);
await waitFor("cinema 2 page 3", async () => {
await expect(sut2.stageElement.scrollLeft).toBe(883);
});
await click(sut2.paginationDots[3]);
await waitFor("cinema 2 page 4", async () => {
await expect(sut2.stageElement.scrollLeft).toBe(1333);
});
// TEST CINEMA 3
await expect(sut3.paginationDots.length).toBe(3);
await expect(sut3.stageElement.scrollLeft).toBe(0);
await click(sut3.paginationDots[1]);
await waitFor("cinema 3 page 2", async () => {
await expect(sut3.stageElement.scrollLeft).toBe(433);
});
await click(sut3.paginationDots[2]);
await waitFor("cinema 3 page 3", async () => {
await expect([850, 866].includes(sut3.stageElement.scrollLeft)).toBeTruthy();
});
}
}