1.4.15 • Published 5 years ago

fh-components v1.4.15

Weekly downloads
62
License
ISC
Repository
github
Last release
5 years ago

Reusable components and directives for Vue. Designed for Vuehaus, but most components work in regular Vue apps.

fh-components saves you the trouble of rewriting common components like images, video players, svgs, and several other elements. If you're looking at writing a custom component in Vuehaus, check if one already exists here first - and if it doesn't, feel free to contribute!

Table of Contents

  1. Installation
  2. Components
    1. a-div
    2. count-up
    3. flex-text
    4. hamburger-button
    5. image-loader
    6. load-on-view
    7. mailing-list
    8. responsive-image
    9. reveal-footer
    10. scroll-to
    11. slide-show
    12. split-text
    13. sticky-wrap
    14. text-typer
    15. transition-fade
    16. transition-slide-toggle
    17. video-stage
    18. velocity-animate
    19. wp-content
    20. wp-menu
  3. Directives
    1. animated
    2. draggable
    3. full-height
    4. in-view
    5. interact
    6. keydown
    7. reverse-hover
  4. Mixins
    1. Idle
    2. Infinite Scroll
    3. Pack
    4. Rect
    5. Sequence
    6. WaitFor
  5. Plugins
  6. Animations
    1. Sequential Fade
  7. Transitions
    1. Slide-Toggle
  8. Testing
  9. Contributing
    1. Prep
    2. New Components
    3. Documentation
    4. Tests

Installation

npm install fh-components --save

When you register components:

import ComponentName from 'fh-components/component-name'

// Global in main.js...
Vue.component('component-name', ComponentName)

// ...or local to a .vue file...
export default {
    components: {
        'component-name': ComponentName
    }
}

// ...or a global component one-liner (no `import` statement needed)
Vue.component('component-name', require('fh-components/component-name'))

Components

a-div

<a-div :href="myString">Link text</a-div>

Safe way to render internal, external, or missing links.

StandaloneEnhanced by VuehausSSR Capable

Props

NameTypeDefaultDescription
force-newBooleanfalseWhether the link should always open in a new window.
hrefStringemptyURL to link to. Handles same-origin URLs with router-link, external URLs with a, and falsey values with the replace-with tag.
new-windowBooleantrueIf component renders as an <a> tag, open in a new window.
replace-withString'div'If the href isn't a link, render contents inside this tag instead.

Classes

NameConditionsNotes
anchor-divAlways
a-${ replace-with }AlwaysSubstitutes with the replace-with tag name.

Notes

  • Renders content in a <router-to> tag if href starts with / or includes the same location.origin.
  • Renders content in an <a> tag if href is a truthy value not starting with /.
  • Renders content in a given tag (replace-with, default div) if href is falsey.

count-up

<count-up :to="1000" :duration="1000" ref="count"/>

<button @click="$refs.count.running = true">Start Counting</button>

Count up to a specified number over a period of time. Requires Popmotion (npm install popmotion if this component throws errors).

StandaloneEnhanced by VuehausSSR Capable

Props

NameTypeDefaultDescription
appearBooleanfalseWhether or not to start counting on mounted.
delayNumber0How long to delay before starting the count.
durationNumber700How long, in ms, to count up to to.
from[String, Number]0Number to start at.
to[String, Number]100Number to count up to.

Classes

NameConditionsNotes
count-upAlways

Notes

  • Set running to true to start counting. running will automatically be set back to false when complete.

flex-text

hamburger-button

<hamburger-button/>

<hamburger-button>
    <svg-image src="custom-hamburger.svg" />
</hamburger-button>

Lightweight hamburger SVG with open and closed states. Requires Vuehaus.

StandaloneEnhanced by VuehausSSR Capable

Classes

NameConditionsNotes
hamburgerAlways
activatedwhen $store.state.menuOpened is true

Notes

  • Calls Vuehaus's 'OPEN_MENU' or 'CLOSE_MENU' when clicked, depending on current activated state. Will also update correctly when menu is opened or closed elsewhere.
  • Default slot is a three-line hamburger icon that changes to an "X" when activated. The user can replace this with their own svg using the svg-image component.

image-loader

<image-loader :images="arrayOfImagesToLoad"/>

This component will, given a list of serialized images, preload those images. Will handle Vuehaus image objects or image URL strings. All images are set to display: none.

StandaloneEnhanced by VuehausSSR Capable

Props

NameTypeDefaultDescription
imagesArray[]Array of serialized images or URL strings to load.
sizeStringfullWordPress name for image size to load.

load-on-view

<load-on-view
    :url="urlToFetchWhenInView"
    @data="handleAnyData"
    @text="handleTextResponse"
    @json="handleJsonResponse"
    @error="handleError"/>

This component will keep track of its own scroll position, and when it enters the viewport will send a fetch request to a provided URL, emitting any resulting error or data through events. This is most useful for "infinite-scroll" functionality, where you feed pagination URLs into this component and use the resulting request data.

StandaloneEnhanced by VuehausSSR Capable

Props

NameTypeDefaultDescription
urlString''Target URL to send a fetch request to once the component is in view.
repeatUrlBooleanfalseIf set to false, load-on-view will not send the next request until the provided URL changes.
fetchConfigObject{ credentials: 'same-origin' }An configuration object to be used with the fetch request.

Events

NameSignatureDescription
data(response)Fired whenever a fetch request is completed and returns a 2xx status code
error(err)Fired whenever an error occurs during the fetch request, or when the request returns a non-2xx status
on-text(textData)Fired when a fetch is completed and the contentType of the response is text
on-json(jsonData)Fired when a fetch is completed and the contentType of the response is json
on-buffer(arrayBuffer)Fired when a fetch is completed and the contentType of the response is neither text nor json

Classes

NameConditionsNotes
load-on-viewAlways

mailing-list

<mailing-list
    submit-text="Sign Up"
    placeholder="Your email address"
    :action-url="actionUrl"
    :token="token"/>

Flexible newsletter signup component. Supports Mailchimp and Madmimi.

StandaloneEnhanced by VuehausSSR Capable

Props

NameTypeDefaultDescription
providerStringmailchimpNewsletter service provider. Either mailchimp or madmimi.
actionUrlStringnone (required)Action URL for signup form.
tokenStringnone (required)API token.
successMessageStringThank You!Message to show to user on successful signup
submitTextStringSubscribeText on 'submit signup' button
placeholderStringEmail AddressPlaceholder text for email address input
transitionNameStringnewsletter-submitName for transition wrapping mailing-list element
delayNumber5000Time in ms to wait before firing cookieCreated event
cookieLengthNumber30Time in days until cookie expires

Slots

NameLocation
topFirst element in mailing list wrapper, before any inputs
labelLabel for email input element. Default: <label for="mailing_list_email">Email</label>
before-formWrapped by transition, appears before input form (hidden after form submitted successfully)
after-formWrapped by transition, appears after input form (hidden after form submitted successfully)
successAppears after successful submission and successMessage prop
errorAppears after form if error detected. Not wrapper by transition element.
bottomLast element in mailing list wrapper. After all inputs and transition wrap.

Events

NameSignatureDescription
addressSubmitted{ success: Boolean, errorMessage: String }Fires when an email address is submitted
cookieCreatednullFired when a cookie is created. (Designed to trigger overlay activation)

Classes

NameConditionsNotes
fh-mailing-listAlways
loadingIf mailing list request has been submitted
state-${ state }AlwaysEither state-success, state-error, or state-none, depending on submission state
provider-${ provider }AlwaysEither provider-mailchimp or provider-madmimi
emptyIf the email input field is empty

Notes

  • Element to build out common mailing list signups.
  • Requires an action URL and an API token.
    • Mailchimp: The action URL is the value of the action attribute on the form element in the form builder, and the API token is the value of the name attribute on the input wrapped by the left: -5000px div.
  • Waits delay ms, then fires the cookieCreated event and creates a cookie that prevents firing that event again for cookieLength days.

responsive-image

<responsive-image :src="sourceUrl" :object="serializedRestEasyObject"/>

Creates and fades in an image. Adds a placeholder for the image with a given background-color to prevent content jumping when the image loads.

StandaloneEnhanced by VuehausSSR Capable

Props

NameTypeDefaultDescription
aspectString, Number''Aspect ratio of desired image, as a percentage. aspect="56.25" would evaluate to a 56.25% aspect ratio. Calculated from height and width if not explicitly stated.
colorString'transparent'Background placeholder color. Any CSS-compatible color is valid.
fill-spaceBooleanfalseWhen true, position absolutely and force the image to take up all available space; when false, use the image's natural aspect ratio.
fitString'cover'Object-fit value for the image - cover or contain.
heightString, Number''Natural image height in pixels.
htmlString''Desired element as an HTML string. Provides all the sizing, fade-in, etc. benefits of a regular responsive-image.
objectObject{}Serialized Rest-Easy attachment. Fills out the rest of these props automatically except fit.
posterString''URL to poster for video. If false, no poster used; if blank, defaults to the parsed image source.
respect-maxBooleanfalseWhether the image will have a max-width and max-height based on its natural dimensions.
sizeString'full'WordPress image size.
srcString''Same functionality as <img src="...">.
video-srcString''An optional video URL if the component should display a looping video rather than an image.
volumeNumber0Controls the volume when rendering a video. If set to 0 (or not set) the video will be muted and will be able to autoplay.
widthString, Number''Natural image width in pixels.

Slots

NameLocation
DefaultContent inside of image-padding, after image.

Classes

NameConditionsNotes
fill-spaceif fill-space prop is set to true
fit-${fit}AlwaysEither fit-cover or fit-contain, depending on the fit prop.
has-videoif videoSrc is truthy
loadingImage hasn't finished loading
responsive-imageAlways
rsp-image-moduleAlways

Notes

  • If you add a link to an .mp4 video in the "Alt" field in WordPress, this element will create and render a video, using the provided image as the poster (see "Poster" under "Attributes" here).
  • Also works when object is set to an Advanced Custom Fields image array. Only provides fullscreen size and image alt in this case.
  • Works with Focushaus, if installed, to set a custom focal point for an image. Defaults to standard browser behavior, focal point in the center of the image.

reveal-footer

<reveal-footer>
    <footer>I'm the footer content.</footer>
</reveal-footer>

A component that reveals the section at the bottom of a page. Like the footer on the Funkhaus site.

StandaloneEnhanced by VuehausSSR Capable

Slots

NameLocation
Default

Classes

NameConditionsNotes
reveal-footerAlways
footer-wrapAlways

Notes

  • Adds a slot wrapped with an empty div footer-wrap, preceded by an empty div that expands to match the footer-wrap height. footer-wrap is position: fixed and has right, bottom, and left set to 0.

scroll-to

<scroll-to target=".scroll-target">Scroll to Target</scroll-to>

Wrap this component around any element to add "scroll-to" functionality, where the window is scrolled to a target element when the wrapped element is clicked.

StandaloneEnhanced by VuehausSSR Capable

Props

NameTypeDefaultDescription
targetString/Objectscroll-targetTarget element to scroll to. This can be the name of a $ref, a CSS selector, or a DOM element.
durationNumber1000The duration of the scroll animation in ms.
easingStringinOutQuadThe animation easing to use. See ease for all valid options.
offsetNumber0Number of pixels to offset the scroll target by. Can be positive or negative.
debugBooleanfalseWhether or not to display debug information on click.

Slots

NameLocation
DefaultContent to be wrapped by scroll-to button

Events

NameSignatureDescription
complete()Fires when the page has finished scrolling to the target. Fired immediately if target is not found.

Classes

NameConditionsNotes
scroll-toAlways

slide-show

<slide-show :slides="[1, 2, 3, 4]">
    <div class="slide" slot="slide" slot-scope="args">
        {{ args }}
    </div>
</slide-show>

This component creates a basic slideshow element that will cycle through a list of items that you provide.

Requires:

  • An array of slides that will serve as the source for the individual slides
  • A slide slot describing the format of an individual slide
StandaloneEnhanced by VuehausSSR Capable

The simplest possible slide-show looks like this:

<slide-show :slides="[1, 2, 3]">

    <div slot="slide" slot-scope="{ slide }">

        <!-- This will create a slideshow of the numbers 1, 2, and 3, as specified in the "slides" prop-->
        {{ slide }}

    </div>

</slide-show>

See the slots section for more information.

Props

NameTypeDefaultDescription
slidesArray[]Array of items to be iterated over and turned into slides.
autoBooleantrueControls if slideshow should auto-advance.
swipeBooleantrueControls if left/right swipe should be enabled
loopBooleantrueIf true, slideshow will loop from last item back to first on automatic playthroughs
manual-loopBooleanfalseIf true, slideshow will loop from last item back to first on automatic and manual slide changes
infiniteBooleantrueIf true, slideshow will do a next style transition when looping from last to first and vice versa.
intervalNumber4000Time between auto slide transitions.
delayNumber500Time to delay before initiating auto slide interval.
indexNumber/ObjectnullUsed to manually control the current active slide of the slideshow. This prop can be bidirectionally bound using the sync modifier - <slide-show :index.sync="myLocalIndex"/> will keep myLocalIndex up to date and reflect updates immediately if changed. Note that the value will also wrap correctly if under 0 or over the total slide number.
paginationBooleantrueControls if pagination elements should be rendered or not.
localKeyboardBooleanfalseIf true, slideshow will bind keyboard listeners to the slideshow DOM element. If false, keyboard events will be bound to window.
nextKeyNumber39Keycode for which key will trigger the next action. Default is the right arrow.
prevKeyNumber37Keycode for which key will trigger the prev action. Default is the left arrow.
cssBooleantrueControls if the transition should use CSS classes or not. Use this when overriding the default transition using the provided javascript hooks.
can-controlBooleantrueControls whether or not the user has any manual control over this slideshow progression.
force-transitionString''Tell the slideshow to use this transition name instead of the default next and prev classes. Useful if the transition will not change depending on slideshow direction.
slide-wrapStringdivThe element to wrap each individual slide in. Required to use the transition correctly.
enterFunction(element, done, direction)nullThe enter function for the JS transition. Only runs if css is set to false. done is a function that must be called when transition completes; direction will either be prev or next depending on the slideshow direction.
leaveFunction(element, done, direction)nullThe leave function for the JS transition. Only runs if css is set to false. done is a function that must be called when transition completes; direction will either be prev or next depending on the slideshow direction.
startingSlideNumber0Zero-based index of starting slide.

Classes

  • fh-slideshow
  • transitioning: Active when slideshow is mid transition
  • first-slide: Active when the current index is the first slide
  • last-slide: Active when the current index is the last slide

Common Tasks

To use a transition other than the built-in one (for example, a fade transition):

<slide-show
    force-transition="fade">
    ...
</slide-show>

Slots

In order to use this component, you'll have to utilize the Scoped Slots feature of vue components. This component has 4 available slots, and 2 of them are scoped.

slide: Template for a single slide element

This is the most important slot. It allows you to provide a template to the component telling it how to render each slide item you provided through the slides prop. The slot accepts 2 arguments, slide and index. slide holds the data of whatever item is being iterated over, and index is the current item's index. Here's a simple example usage:

<slide-show :slides="pages">
    <div class="slide" slot="slide" slot-scope="args">
        <responsive-image :object="args.slide.featuredAttachment" />
    </div>
</slide-show>

In this example the slot is being fed all provided arguments through the args object. The single property on the args object will be slide, which carries the value of a single page. In this example an image object is being provided to a responsive-image, but you can use any data from the slide object within this slot to render your template.

pagination-item: Template for a single pagination item in the slideshow

This is the second scoped slot, it's used to define a template that the component will use when rendering the pagination. It also supports a single argument, slide. Building on the last example:

<slide-show :slides="pages">
    <!-- ... -->
    <span slot="pagination-item" slot-scope="args">{{ args.slide.title }}</span>
</slide-show>

This would render a list of pagination items, each with the title of the page inside. Pagination elements are automatically given event listeners to trigger their corresponding slides when clicked, and the currently active pagination item is given the class active.

nav-next: Element to be used as the next trigger

This is a non-scoped slot that will render an element to be used as the next trigger when clicked. The component will automatically add the click listeners to this component. Example Usage:

<slide-show :slides="pages">
    <!-- ... -->
    <svg-image src="arrow-right.svg" slot="nav-next" />
</slide-show>

nav-prev: Element to be used as the prev trigger

This non-scoped slot functions exactly the same as nav-next, but triggers the previous action.

before: Element(s) to go within the slideshow just before the slide slot

This non-scoped slot allows you to add extra content into the slideshow that does not affect the functionality of the core elements.

default: Element(s) to go within the slideshow, after all other slots.

This non-scoped slot is the default and allows you to add extra content into the slideshow that does not affect the functionality of the core elements.

Transitions

By default, there is a simple css slide transition being applied to the slideshow. It has the name fh-slide-${ direction }, with direction being either next or prev depending on which way the slideshow is going. For simple transitions it's easy to override the default. For example, if you wanted to take the existing transition but change the speed to 3s you might do this:

.fh-slideshow.fh-slide-next-enter-active,
.fh-slideshow.fh-slide-next-leave-active,
.fh-slideshow.fh-slide-prev-enter-active,
.fh-slideshow.fh-slide-prev-leave-active {
    transition-duration: 3s;
}

If css transitions alone are not enough for the effect you want, you can opt to use js hooks instead. The full set of js transition events are available to the main slide-show component, so you can pass them as props there and use javascript to create your effects. Keep in mind that when doing this you will want to set the css prop to false so that the transition element is forced into js mode.

split-text

Props

  • elements: String or Array, default span. Wrap each resulting line in this element with classes line and line-{ line number }. If elements is an array, split-text will wrap each line in its respective element, using the last element for any extra lines.
  • separator: String or Array, default ' &#8211; '. Splits text by this separator. If set to an array, find the first separator that results in a split string and use that one.
  • pieces: Number or Array, default -1. Only include these zero-indexed pieces of the split text. If set to -1 (default), include the full split text.
  • text: String, default empty. Text to split.
  • wrapper: String, default span. Element wrapping rendered lines.

Notes

  • Splits given text according to a given separator. Useful for formatting titles, for example - Title - More Title Information will render as <span>Title</span><span>More Title Information</span>.
  • Contains two slots, named before and after, that render their content before and after the split text.

sticky-wrap

<sticky-wrap>
    <h2>I'm stuck content</h2>
    <p>I'll be stuck too</p>
</sticky-wrap>

Mimics position: sticky using a wrapper element and translation. Sticks an element to the top of the screen without breaking page flow. Place content to be stuck inside the main slot

StandaloneEnhanced by VuehausSSR Capable

Props

NameTypeDefaultDescription
wrapperStringdivElement that wraps the entire component.
marginNumber/String0Distance in pixels to pad the top of the sticky element.
maxNumber/String-1The maximum distance this element will be able to translate.

Classes

NameConditionsNotes
sticky-wrapAlways

text-typer

Props

  • wrapper: String, default span. Wrapper element for the typed text.
  • html: String, default ''. HTML to be typed out.
  • minTime: Number, default 2. Minimum number of ms to pass between keystrokes.
  • maxtime: Number, default 5. Maximum number of ms to pass between keystrokes.

Classes

  • text-typer

Notes

  • Element to create a text typing effect that preserves HTML tags.
  • Uses a naive tag splitter that just detects for the presence of < or > characters.

transition-fade

Classes

Notes

  • Fades the contained element over 0.4 seconds.

transition-slide-toggle

Notes

  • Velocity.js match of jQuery's slideToggle method, wrapped in a Vue transition.

velocity-animate

Props

  • reset: Boolean, default true. Whether or not the changed elements should have their inline styles reset after the animation complete.
  • sequence: Array, default []. Sequence to run on appear.
  • wrapper: String, default div. Element in which to wrap the enclosed content.

Classes

  • velocity-animate

Notes

  • A component to ease creating multi-step Velocity transitions. The sequence refers to a Velocity sequence, first introduced in the UI pack. Instead of raw elements, the e property should contain the ref of the desired element. For example:
<template>
    <velocity-animate :sequence="sequence">
        <h2 ref="title">I'm here!</h2>

        <h3 ref="subtitle">So am I!</h3>

        <p ref="body">I'm the body</p>
    </velocity-animate>
</template>

<script>
export default {
    computed: {
        sequence(){
            return [
                { e: 'title', p: { opacity: [1, 0] } },
                { e: 'subtitle', p: { opacity: [1, 0] } },
                { e: 'body', p: { translateX: [0, '-100%'] }, o: { sequenceQueue: false } }
            ]
        }
    }
}
</script>

This will make the h2 fade in, then the h3 fade in and p tag slide in from the left.

  • velocity-animate also allows you to set initial states of elements by forcefeeding starting values. See this section of the Velocity docs for details. Instead of just animating from the second value to the first, velocity-animate sets the element's desired property to the second value from the start of the animation.

video-stage

Props

  • src: String, default ''. The source of the video to embed. This can either be a full iframe code, or for Vimeo videos can just be a permalink to the video.
  • autoplay: Boolean, default true. Controls whether the component should attempt to autoplay the video. Only vimeo videos support autoplay at the moment.
  • autoOffsets: Boolean, default true. If set to true, the components will attempt to automatically calculate a fitToParent offset based on the dimensions of any slot elements provided.
  • paused: Boolean, default false. If set to true, the player will pause; if false, the player will play.
  • muted: Boolean, default false. If set to true, Vimeo player will start muted.
  • is-responsive: Boolean, default false. If set to true the video will behave like fitVids, pushing down content on the page according to its natural aspect ratio rather than filling the available space.

Slots

  • before: Renders directly before the element that holds the iframe.
  • after: Renders directly after the element that holds the iframe.

Notes

  • This component uses fitToParent to automatically scale and center the iframe within the dimensions of the nearest positioned parent element. Example usage: <video-stage src="https://vimeo.com/123456789" @ended="goToNextPage" />.

Events

  • Events are only supported for Vimeo-based videos.
  • ended: fires once the video has reached the end.
  • play: fires any time the video begins playback
  • pause: fires any time the video is paused
  • width: fires any time the video is resized by fitToParent. Value is the new width in pixels.
  • height: fires any time the video is resized by fitToParent. Value is the new height in pixels.
  • error: fires if there is an error during calculation. Value will be the error object that was triggered.

wp-content

Props

  • html: String, default ''. HTML that can function as a Vue template. The component will dynamically compile the contents, and inject the results into the vue component tree.
  • unwrap: Array, default ['p > img', 'p > iframe']. Array of CSS selectors describing elements to unwrap from their parent nodes. (WordPress automatically wraps newlines in <p> tags, so this is a useful feature to remove standalone media from those <p> tags.)
  • fitvids: Boolean, default true. When set to true, the component will run fitvids on all content inside.
  • replace: Array, default []. Array of objects containing:

    • selector - String with CSS selector for elements to replace
    • callback - Function describing what to replace old element with. Accepts one argument referring to the old element; should return a String or Node with the element's replacement.

    This feature lets you replace items in wp-content. For example:

    <wp-content :html="contentHtml" :replace="[ { selector: 'img', callback: el => `<p>Image with source ${ el.src }</p>` } ]"

    This setting would replace all img tags with a p containing the text 'Image with source element's source'. Useful for modifying wp-content HTML before it is rendered on the DOM.

Classes

  • wp-content-placeholder: only present when no html template is provided
  • wp-content-rendered: only present when an html template was provided and successfully rendered

Notes

  • This was built to allow components to be used with the the contents of a Wordpress post. It's very effective for that purpose, but more generally can be used to compile any dynamically loaded template and render it into the component tree. Be aware that this should only ever be used when the template going into the html prop is trusted.

wp-menu

Vuehaus-specific component to build WordPress menus. Uses the wp-menu-item component internally.

Props

NameTypeDefaultDescription
slugString''The WordPress slug of the menu to use.
nameString'Main Menu'The WordPress name of the menu to use.
forceRouterLinkBooleanfalseWhether or not this wp-menu should force the use of router-links instead of a tags.

Classes

  • menu
  • ${ slug }: Either the slug prop or a kebab-cased version of the name prop, whichever is available.

Slots

This component comes with an optional scoped slot that will allow you to override the default markup for a single menu item.

menu-item: Template for single menu item within component

This slot accepts 2 arguments, menuItem, which carries the serialized object of the single item that is being iterated over, and index, which carries the index of the current menu item. Here is an example of how you might use it to add an arrow icon next to the name of each element in the menu:

<wp-menu name="Main Menu">
    <li slot="menu-item" slot-scope="{ menuItem, index }">
        <router-link :to="menuItem.relativePath">
            <svg-image src="arrow.svg" />
            <span>{{ index }}. </span>
            <span v-html="menuItem.title" />
        </router-link>
    </li>
</wp-menu>

Directives

Directives are declared as attributes. Remember to prefix v- to the directive name (so full-height becomes v-full-height)!

To use fh-components directives in your Vue app:

import directiveName from 'fh-components/v-directive-name'
Vue.directive('directive-name', directiveName)

To pass arguments to directives:

<my-component v-my-directive="{ key: 'value' }"/>

Directives may also have "modifiers" to go with them. Modifiers can be used like this:

<my-component v-my-directive.example />

animated

Notes:

  • Applies a class to an element on hover or focus. Only removes that class when an animation is finished with its current iteration. See this pen for an example - the arrows will always finish their bounce animations.
  • Must be more than 1 animation iteration to remove class correctly.
  • Accepts one argument, the class name to apply. Default animating.
  • Recommended use:
<template>
    <router-link
        v-animated
        class="link"
        to="/">I'll animate!</router-link>
</template>

<style lang="scss">

.link.animating {
    // must be more than one iteration - this won't work:
    animation: my-animation 1s 1;
    // but this will:
    animation: my-animation 1s infinite;
}

@keyframes my-animation {
    // your keyframes...
}

</style>

coverup

Not supported! Note that the v-coverup directive is very buggy on Safari and Firefox and probably won't be fixed any time soon.

Notes:

  • Sticks the bottom edge of an element to the bottom edge of the screen. Like position: sticky, but keeps the element stuck.
  • Jittery in Firefox and Safari. Works in Chrome.

draggable

Notes

  • Gives the user access to mousedowm/move/up events and deltas.
  • User needs to full functionality in arguments - directive just handles communicating data to those events.

Arguments

  • dragStart: Function, default null. Called when the user clicks on an element. Takes two arguments, the event itself and an object with the clientX and clientY properties in x and y.
  • drag: Function, default null. Called when the user clicks on an element. Takes two arguments, the event itself and an object with:
    • lastPos: the clientX and clientY properties in x and y
    • delta: the change in pixels between this frame and the previous in x and y.
    • totalDelta: the change in pixels of the drag from start to the current frame, in x and y.
  • dragStop: Function, default null. Called when the user releases a click on an element. Takes two arguments, the event itself and an object with:
    • lastPos: the clientX and clientY properties in x and y
    • totalDelta: the change in pixels of the drag from start to finish, in x and y.

full-height

Notes:

  • Sizes the element to 100% of the window height. Replacement for the occasionally buggy 100vh css value.

Modifiers

  • min: If provided, directive will use the min-height css property rather than height.

in-view

Arguments

  • above: String, default above-view. Class when element is above the viewport.
  • below: String, default below-view. Class when element is below the viewport.
  • left: String, default left-of-view. Class when element is left of viewport.
  • right: String, default right-of-view. Class when element is right of viewport.
  • inView: String, default in-view. Class when element is within the viewport.
  • onEnter: Function, default null. Method to call when an element enters view from anywhere. Accepts one argument, the element that has entered the viewport.
  • onEnterAbove: Function, default null. Method to call when an element enters view from the top of the screen. Accepts one argument, the element that has entered the viewport.
  • onEnterBelow: Function, default null. Method to call when an element enters view from below the screen. Accepts one argument, the element that has entered the viewport.
  • onEnterLeft: Function, default null. Method to call when an element enters view from left of the screen. Accepts one argument, the element that has entered the viewport.
  • onEnterRight: Function, default null. Method to call when an element enters view from right of the screen. Accepts one argument, the element that has entered the viewport.
  • onLeave: Function, default null. Method to call when an element leaves view from anywhere. Accepts one argument, the element that has ;eft the viewport.
  • onLeaveAbove: Function, default null. Method to call when an element leaves view, going above the screen. Accepts one argument, the element that has left the viewport.
  • onLeaveBelow: Function, default null. Method to call when an element leaves view, going below the screen. Accepts one argument, the element that has left the viewport.
  • onLeaveLeft: Function, default null. Method to call when an element leaves view, going left of the screen. Accepts one argument, the element that has left the viewport.
  • onLeaveRight: Function, default null. Method to call when an element leaves view, going right of screen. Accepts one argument, the element that has left the viewport.

Modifiers

  • appear: If set, events and classes will be calculated on insertion.

Notes

  • Applies classes to an element based on its viewport visibility.
  • Can also fire callbacks when an element has entered or left the viewport.

interact

Arguments

You can pass either a function or an object to v-interact. If you pass a function, that function will act as the callback parameter below.

If you pass an object, your available parameters are:

  • callback: Function, default () => {}. Callback to fire when any event triggers.
  • events: Array of objects, default { mouseenter: callback, focus: callback } or { mouseleave: callback, blur: callback }, depending on whether the end modifier exists (see below). The keys in this object are event types, the values are the functions to call on those events.

Modifiers

  • end - Consolidates mouseleave and blur instead of mouseenter and focus.

Notes

  • Event consolidator that handles both mouseenter/focus and mouseleave/blur.
  • v-interact funnels multiple events into one callback and/or event. It's designed to consolidate mouseenter/focus and mouseleave/blur, but it can be used with any set of events.
  • Example:

    <!-- method defined in Vue instance - receives event as argument -->
    <router-link v-interact="startInteract">
    
    <!-- method defined in Vue instance with additional argument -->
    <router-link v-for="(link, i) in links) v-interact="evt => startInteract(evt, i)">
    
    <!-- mouseleave/blur event -->
    <router-link v-interact.end="endInteract">
    
    <!-- custom events -->
    <router-link v-interact="{ events: { mousedown: clicked, mouseup: clicked } }">

keydown

Modifiers

  • esc - Only run callback on esc keydown.
  • up - Only run callback on up arrow keydown.
  • right - Only run callback on right arrow keydown.
  • down - Only run callback on down arrow keydown.
  • left - Only run callback on left arrow keydown.

Notes

Bind a global keydown listener to this component. Listener is created and destroyed with the component. For example, to implement an esc key toggle on a menu:

<menu-component v-keydown.esc="() => $store.commit('TOGGLE_MENU')"/>

Note that the value must be an arrow function or a reference to a method in the Vue instance. These should work:

<menu-component v-keydown.esc="toggleMenu"/>
<menu-component v-keydown.esc="() => toggleMenu(false)"/>

But this won't:

<menu-component v-keydown.esc="toggleMenu()"/>

reverse-hover

Arguments

  • containerActivatedClass: String, default rh-active-within. When a triggering component is hovered over or focused, the target element will have this class added to it.
  • elActivatedClass: String, default rh-active. A triggering component that is hovered over or focused will have this class added to it.
  • processedClass: String, default rh-processed. Triggering components will have this class added to them. (Usually left alone - mainly for internal directive use.)
  • selectors: Array or String, default ['a']. All children of the target element that match this selector will become triggering components, reverse-hover listeners attached.

Notes

  • Allows for a "reverse hover" effect, where hovering over one element of a set affects all elements of a set. For example:
<ul class="container" v-reverse-hover>
    <li v-for="url in links">
        <a class="link" :href="url">Link to {{ url }}</a>
    </li>
</ul>
.container.rh-active-within {
    background-color: #ccc;
}
.rh-active-within .link:not(.rh-active) {
    opacity: 0.5;
}
.link.rh-active {
    font-weight: 700;
}

When hovering/focusing over any .link element, the .container will receive the rh-active-within class (giving it a gray background) and all non-hovered/focused .links will be reduced to 0.5 opacity. The element that triggered the reverse-hover (the original hovered/focused .link) will have its font-weight set to 700.

  • You can set the class names yourself by passing an object:
<ul v-reverse-hover="{ containerActivatedClass: 'container-activated' /* etc... */ }">
  • You can also choose which selectors will act as triggers:
<ul v-reverse-hover="{ selectors: ['a', 'button'] /* <a> and <button> tags will trigger the reverse-hover */ }">

Mixins

To use an fh-component mixin:

import mixin from 'fh-components/mixins/mixin-name'

export default {
    mixins: [mixin]
}

Mixins define component properties, lifecycle hooks, data, and more to save you time when writing new components.

idle

Adds

NameTypeDescription
idleBooleanWhether or not the component is idle.
idleDelayNumberHow long, in ms, to wait before marking as idle

Notes

Fires an event after a given number of ms. For example:

<template>
    <img src="img.png" v-show="idle">
</template>

<script>
import idle from 'fh-components/mixins/idle.js'

export default {
    mixins: [idle]
}
</script>

This will hide the image after 5 seconds of inactivity and show it again when the user scrolls or moves the mouse.

infiniteScroll

A very easy-to-use infinite scroll mixin for Vuehaus.

Adds

NameTypeDescription
nextUrlstringURL containing next batch of posts.
gridArrayArray of Rest-Easy serialized posts, representing the full list of posts to display.

Notes

Requires load-on-view. Use like this:

<template>
    <main class="archive">

        <div class="post-grid">
            <div
                class="post-block"
                v-for="(post, i) in grid"
                :key="i">
                <!-- Your post-block templating here - eg: -->
                <h2 v-html="post.title"/>
            </div>

            <load-on-view
                :url="nextUrl"
                @data="loadNext"/>

    </main>
</template>

<script>
import infiniteScroll from 'fh-components/mixins/infiniteScroll'

export default {
    mixins: [infiniteScroll]
}
</script>

nextUrl will update as long as there are more pages to display, and grid will stay populated with all posts loaded so far.

rect

Adds

NameTypeDescription
clientRectObjectObject describing element dimensions.
setRectFunctionUpdate clientRect. Called internally. Can be called manually to force an update.
rectThrottleNumberms throttle before firing scroll and resize events. Default 150.

pack

Like Masonry but more lightweight and based on CSS grid.

Adds

NameTypeDescription
transformsArray of stringsArray of pixel lengths to offset each packed block.
containerHeightStringHeight of the container element in pixels.
packFunctionRecalculate the packing values. Requires one argument, the container element.

Notes

  • Best used with waitFor so that content is rendered before sizes are calculated.
  • Set each block to translate up by its corresponding transforms value to create a Masonry-style, tightly-packed grid.
  • It's a good idea to watch the window width in a debounce function and rerun pack when it changes.
  • Known bugs:
    • Sometimes, child content wrapped in a flexbox won't calculate height correctly. To solve, wrap the flexbox in a container div.
    • Sometimes when watching the window.innerWidth directly, the sizes and transforms don't calculate correctly. To solve, debounce or throttle the window width watcher.

Example:

<template>

    <section :style="{ height: containerHeight }" ref="container">
        <repeated-block
            v-for="(block, i) in ..."
            :key="i"
            :style="{transform: transforms[i]}"/>
    </section>

</template>

<script>
import waitFor from 'fh-components/mixins/waitFor'
import pack from 'fh-components/mixins/pack'

export default {
    mixins: [waitFor, pack],
    mounted() {
        // pack when the grid is ready to render
        // (this.pack will receive this.$refs.container from waitFor)
        this.waitFor('$refs.container', this.pack)
    },
    watch: {
        // assuming a debounced/throttled window width value on the root element
        '$root.winWidth'() {
            // pack when the window width changes
            this.pack(this.$refs.container)
        }
    }
}

</script>

<style>
/* The container element must used display: grid! */
/* Other than that, row/column gaps, templates, and breakpoints will work correctly */

.container {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-column-gap: 80px;
}

@media 'only screen and (min-width: 1800px)' {
    .container {
        grid-template-columns: repeat(4, 1fr);
    }
}

@media 'only screen and (max-width: 750px)' {
    .container {
        grid-template-columns: repeat(1, 1fr);
    }
}

</style>

sequence

Increment a number over a time period. Useful for sequential fading on work grids, for example.

Adds

NameTypeDescription
sequenceStepNumber, default 0Current step of the sequence.
sequenceMaxNumber, default 100Maximum number for the sequence to count to.
sequenceStepLengthNumber, default 300ms between each sequenceStep increment
sequenceInitialDelayNumber, default 0ms to
1.4.15

5 years ago

1.4.14

5 years ago

1.4.13

5 years ago

1.4.12

5 years ago

1.4.11

5 years ago

1.4.10

5 years ago

1.4.9

5 years ago

1.4.8

5 years ago

1.4.7

6 years ago

1.4.5

6 years ago

1.4.3

6 years ago

1.4.2

6 years ago

1.4.1

6 years ago

1.3.12

6 years ago

1.3.11

6 years ago

1.3.10

6 years ago

1.3.9

6 years ago

1.3.8

6 years ago

1.3.7

6 years ago

1.3.6

6 years ago

1.3.5

6 years ago

1.3.4

6 years ago

1.3.3

6 years ago

1.3.2

6 years ago

1.3.1

6 years ago

1.3.0

6 years ago

1.2.99

6 years ago

1.2.98

6 years ago

1.2.97

6 years ago

1.2.96

6 years ago

1.2.95

6 years ago

1.2.94

6 years ago

1.2.93

6 years ago

1.2.92

6 years ago

1.2.91

6 years ago

1.2.90

6 years ago

1.2.89

6 years ago

1.2.88

6 years ago

1.2.87

6 years ago

1.2.86

6 years ago

1.2.85

6 years ago

1.2.84

6 years ago

1.2.83

6 years ago

1.2.82

6 years ago

1.2.81

6 years ago

1.2.80

6 years ago

1.2.79

6 years ago

1.2.78

6 years ago

1.2.77

6 years ago

1.2.76

6 years ago

1.2.75

6 years ago

1.2.74

6 years ago

1.2.73

6 years ago

1.2.72

6 years ago

1.2.71

6 years ago

1.2.70

6 years ago

1.2.69

6 years ago

1.2.67

6 years ago

1.2.66

6 years ago

1.2.65

6 years ago

1.2.64

6 years ago

1.2.63

6 years ago

1.2.62

6 years ago

1.2.61

6 years ago

1.2.59

6 years ago

1.2.58

6 years ago

1.2.57

6 years ago

1.2.56

6 years ago

1.2.55

6 years ago

1.2.54

6 years ago

1.2.53

6 years ago

1.2.52

6 years ago

1.2.51

6 years ago

1.2.50

6 years ago

1.2.49

6 years ago

1.2.48

6 years ago

1.2.47

6 years ago

1.2.46

6 years ago

1.2.45

6 years ago

1.2.44

6 years ago

1.2.43

6 years ago

1.2.42

6 years ago

1.2.41

6 years ago

1.2.40

6 years ago

1.2.39

6 years ago

1.2.38

6 years ago

1.2.37

6 years ago

1.2.36

6 years ago

1.2.35

6 years ago

1.2.34

6 years ago

1.2.33

6 years ago

1.2.32

6 years ago

1.2.31

6 years ago

1.2.30

6 years ago

1.2.29

6 years ago

1.2.28

6 years ago

1.2.27

6 years ago

1.2.26

6 years ago

1.2.25

6 years ago

1.2.24

6 years ago

1.2.23

6 years ago

1.2.22

6 years ago

1.2.21

6 years ago

1.2.20

6 years ago

1.2.19

6 years ago

1.2.18

6 years ago

1.2.17

6 years ago

1.2.16

6 years ago

1.2.15

6 years ago

1.2.14

6 years ago

1.2.13

6 years ago

1.2.12

6 years ago

1.2.11

6 years ago

1.2.1

6 years ago

1.2.0

6 years ago

1.1.8

6 years ago

1.1.7

6 years ago

1.1.6

6 years ago

1.1.5

6 years ago

1.1.4

6 years ago

1.1.3

6 years ago

1.1.2

6 years ago

1.1.1

6 years ago

1.1.0

6 years ago

1.0.0

7 years ago