Skip to content

Commit

Permalink
Merge pull request #441 from davidjerleke/feature/#440
Browse files Browse the repository at this point in the history
Add `slides` & `container` options
  • Loading branch information
davidjerleke committed Mar 8, 2023
2 parents 7adff31 + cf9354f commit c51f6ff
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 48 deletions.
82 changes: 48 additions & 34 deletions packages/embla-carousel-docs/src/content/pages/api/options.mdx
Expand Up @@ -135,40 +135,54 @@ Default: <BrandSecondaryText>`true`</BrandSecondaryText>

Setting this to `false` will not activate or deactivate the carousel. Useful when used together with the [breakpoints](/api/options/#breakpoints) option to toggle the carousel active/inactive depending on media queries.

### axis

Type: <BrandPrimaryText>`string`</BrandPrimaryText>
Default: <BrandSecondaryText>`x`</BrandSecondaryText>

Choose scroll axis between `x` and `y`. Remember to stack your slides horizontally or vertically using CSS to match this option.

### align

Type: <BrandPrimaryText>`string | number`</BrandPrimaryText>
Default: <BrandSecondaryText>`center`</BrandSecondaryText>

Align the slides relative to the carousel viewport. Use one of the predefined alignments `start`, `center` or `end`. Alternatively, provide a number between `0 - 1` to align the slides, where **0.5 equals 50%**.

### axis

Type: <BrandPrimaryText>`string`</BrandPrimaryText>
Default: <BrandSecondaryText>`x`</BrandSecondaryText>

Choose scroll axis between `x` and `y`. Remember to stack your slides horizontally or vertically using CSS to match this option.

### breakpoints

Type: <BrandPrimaryText>`EmblaOptionsType`</BrandPrimaryText>
Default: <BrandSecondaryText>`{}`</BrandSecondaryText>

An object with options that will be applied for a given breakpoint by overriding the options at the root level. Example: `'(min-width: 768px)': { loop: false }`. Note: If multiple queries match, they will be merged. And when breakpoint options clash, the last one in the list has precedence.

### container

Type: <BrandPrimaryText>`string | HTMLElement | null`</BrandPrimaryText>
Default: <BrandSecondaryText>`null`</BrandSecondaryText>

Enables choosing a custom container element which holds the slides. By **default**, Embla will choose the **first direct child element** of the **root element**. Provide either a valid `CSS selector string` or a `HTML element`.

### containScroll

Type: <BrandPrimaryText>`string`</BrandPrimaryText>
Default: <BrandSecondaryText>`''`</BrandSecondaryText>

Clear leading and trailing empty space that causes excessive scrolling. Use `trimSnaps` to only use snap points that trigger scrolling or `keepSnaps` to keep them.

### direction

Type: <BrandPrimaryText>`string`</BrandPrimaryText>
Default: <BrandSecondaryText>`ltr`</BrandSecondaryText>

Choose content direction between `ltr` and `rtl`. Please note that when using `rtl`, the content direction also has to be set to RTL, either by using the [HTML dir attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir) or the [CSS direction](https://developer.mozilla.org/en-US/docs/Web/CSS/direction) property.

### slidesToScroll
### dragFree

Type: <BrandPrimaryText>`string | number`</BrandPrimaryText>
Default: <BrandSecondaryText>`1`</BrandSecondaryText>
Type: <BrandPrimaryText>`boolean`</BrandPrimaryText>
Default: <BrandSecondaryText>`false`</BrandSecondaryText>

Group slides together. Drag interactions, dot navigation, and previous/next buttons are mapped to group slides into the given number, which has to be an integer. Set it to `auto` if you want Embla to group slides automatically.
Enables momentum scrolling. The speed and duration of the continued scrolling is proportional to how vigorous the drag gesture is.

### draggable

Expand All @@ -177,12 +191,12 @@ Default: <BrandSecondaryText>`true`</BrandSecondaryText>

Enables for scrolling the carousel with mouse and touch interactions.

### dragFree
### inViewThreshold

Type: <BrandPrimaryText>`boolean`</BrandPrimaryText>
Default: <BrandSecondaryText>`false`</BrandSecondaryText>
Type: <BrandPrimaryText>`number`</BrandPrimaryText>
Default: <BrandSecondaryText>`0`</BrandSecondaryText>

Enables momentum scrolling. The speed and duration of the continued scrolling is proportional to how vigorous the drag gesture is.
Choose a fraction representing the percentage portion of a slide that needs to be visible in order to be considered in view. For example, **0.5 equals 50%**.

### loop

Expand All @@ -191,39 +205,39 @@ Default: <BrandSecondaryText>`false`</BrandSecondaryText>

Enables infinite looping. Automatically falls back to false if slide content isn't enough to loop. Embla will apply `translateX` or `translateY` to the slides that need to change position in order to create the loop effect.

### speed
### skipSnaps

Type: <BrandPrimaryText>`number`</BrandPrimaryText>
Default: <BrandSecondaryText>`10`</BrandSecondaryText>
Type: <BrandPrimaryText>`boolean`</BrandPrimaryText>
Default: <BrandSecondaryText>`false`</BrandSecondaryText>

Adjust scroll speed when triggered by any of the API methods. Higher numbers enables faster scrolling. Drag interactions are not affected because speed is then determined by the drag force. Only values between `1`-`20` are recommended.
Allow the carousel to skip scroll snaps if it's dragged vigorously. Note that this option will be ignored if the [dragFree](/api/options/#dragfree) option is set to `true`.

**Note:** The speed option is actually controlling the magnitude of the attraction force to the target (where the carousel is headed). This is because Embla uses a simple physics simulation when scrolling instead of transitions.
### slides

### startIndex
Type: <BrandPrimaryText>`string | HTMLElement[] | NodeListOf<HTMLElement> | null`</BrandPrimaryText>
Default: <BrandSecondaryText>`null`</BrandSecondaryText>

Type: <BrandPrimaryText>`number`</BrandPrimaryText>
Default: <BrandSecondaryText>`0`</BrandSecondaryText>
Enables using custom slide elements. By **default**, Embla will choose all **direct child elements** of its [container](/api/options/#container). Provide either a valid `CSS selector string` or a `nodeList/array` containing `HTML elements`.

Set the initial scroll snap to the given number. First snap index starts at 0. Please note that this is not necessarily equal to the number of slides when used together with the [slidesToScroll](/api/options/#slidestoscroll) option.
### slidesToScroll

### containScroll
Type: <BrandPrimaryText>`string | number`</BrandPrimaryText>
Default: <BrandSecondaryText>`1`</BrandSecondaryText>

Type: <BrandPrimaryText>`string`</BrandPrimaryText>
Default: <BrandSecondaryText>`''`</BrandSecondaryText>
Group slides together. Drag interactions, dot navigation, and previous/next buttons are mapped to group slides into the given number, which has to be an integer. Set it to `auto` if you want Embla to group slides automatically.

Clear leading and trailing empty space that causes excessive scrolling. Use `trimSnaps` to only use snap points that trigger scrolling or `keepSnaps` to keep them.
### speed

### skipSnaps
Type: <BrandPrimaryText>`number`</BrandPrimaryText>
Default: <BrandSecondaryText>`10`</BrandSecondaryText>

Type: <BrandPrimaryText>`boolean`</BrandPrimaryText>
Default: <BrandSecondaryText>`false`</BrandSecondaryText>
Adjust scroll speed when triggered by any of the API methods. Higher numbers enables faster scrolling. Drag interactions are not affected because speed is then determined by the drag force. Only values between `1`-`20` are recommended.

Allow the carousel to skip scroll snaps if it's dragged vigorously. Note that this option will be ignored if the [dragFree](/api/options/#dragfree) option is set to `true`.
**Note:** The speed option is actually controlling the magnitude of the attraction force to the target (where the carousel is headed). This is because Embla uses a simple physics simulation when scrolling instead of transitions.

### inViewThreshold
### startIndex

Type: <BrandPrimaryText>`number`</BrandPrimaryText>
Default: <BrandSecondaryText>`0`</BrandSecondaryText>

Choose a fraction representing the percentage portion of a slide that needs to be visible in order to be considered in view. For example, **0.5 equals 50%**.
Set the initial scroll snap to the given number. First snap index starts at 0. Please note that this is not necessarily equal to the number of slides when used together with the [slidesToScroll](/api/options/#slidestoscroll) option.
4 changes: 4 additions & 0 deletions packages/embla-carousel/src/components/Options.ts
Expand Up @@ -18,6 +18,8 @@ export type CreateOptionsType<Type extends LooseOptionsType> = Type & {
export type OptionsType = CreateOptionsType<{
align: AlignmentOptionType
axis: AxisOptionType
container: string | HTMLElement | null
slides: string | HTMLElement[] | NodeListOf<HTMLElement> | null
containScroll: ScrollContainOptionType
direction: DirectionOptionType
slidesToScroll: SlidesToScrollOptionType
Expand All @@ -33,6 +35,8 @@ export type OptionsType = CreateOptionsType<{
export const defaultOptions: OptionsType = {
align: 'center',
axis: 'x',
container: null,
slides: null,
containScroll: '',
direction: 'ltr',
slidesToScroll: 1,
Expand Down
29 changes: 15 additions & 14 deletions packages/embla-carousel/src/components/index.ts
Expand Up @@ -5,12 +5,7 @@ import { defaultOptions, EmblaOptionsType } from './Options'
import { OptionsHandler } from './OptionsHandler'
import { PluginsHandler } from './PluginsHandler'
import { EmblaPluginsType, EmblaPluginType } from './Plugins'

export type EmblaNodesType = {
root: HTMLElement
container?: HTMLElement
slides?: HTMLElement[]
}
import { isString } from './utils'

export type EmblaCarouselType = {
canScrollNext: () => boolean
Expand All @@ -37,7 +32,7 @@ export type EmblaCarouselType = {
}

function EmblaCarousel(
nodes: HTMLElement | EmblaNodesType,
root: HTMLElement,
userOptions?: EmblaOptionsType,
userPlugins?: EmblaPluginType[],
): EmblaCarouselType {
Expand All @@ -58,28 +53,34 @@ function EmblaCarousel(
let pluginList: EmblaPluginType[] = []
let pluginApis: EmblaPluginsType
let rootSize = 0
let root: HTMLElement
let container: HTMLElement
let slides: HTMLElement[]

function storeElements(): void {
const providedContainer = 'container' in nodes && nodes.container
const providedSlides = 'slides' in nodes && nodes.slides
const { container: userContainer, slides: userSlides } = options

root = 'root' in nodes ? nodes.root : nodes
container = providedContainer || <HTMLElement>root.children[0]
slides = providedSlides || [].slice.call(container.children)
const customContainer = isString(userContainer)
? root.querySelector(userContainer)
: userContainer
container = <HTMLElement>(customContainer || root.children[0])

const customSlides = isString(userSlides)
? container.querySelectorAll(userSlides)
: userSlides
slides = <HTMLElement[]>[].slice.call(customSlides || container.children)
}

function activate(
withOptions?: EmblaOptionsType,
withPlugins?: EmblaPluginType[],
): void {
if (destroyed) return
storeElements()

optionsBase = optionsHandler.merge(optionsBase, withOptions)
options = optionsHandler.atMedia(optionsBase)

storeElements()

engine = Engine(root, container, slides, options, eventHandler)
rootSize = engine.axis.measureSize(root.getBoundingClientRect())

Expand Down
4 changes: 4 additions & 0 deletions packages/embla-carousel/src/components/utils.ts
Expand Up @@ -12,6 +12,10 @@ export function isNumber(subject: unknown): subject is number {
return typeof subject === 'number'
}

export function isString(subject: unknown): subject is string {
return typeof subject === 'string'
}

export function isObject(subject: unknown): subject is Record<string, unknown> {
return Object.prototype.toString.call(subject) === '[object Object]'
}
Expand Down

0 comments on commit c51f6ff

Please sign in to comment.