Package Exports
- ars-web-components
- ars-web-components/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (ars-web-components) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
ARS Web Components
A collection of reusable web components built with vanilla JavaScript and ES modules.
๐ Live Demo
Check out the live demo.
Alternative: Download the repository and open index.html in a local web server.
Features
- ๐ฏ Pure JavaScript: No framework dependencies, works with any modern web project
- ๐จ CSS-friendly: Components are styling-agnostic, use your own CSS classes
- โก ES Modules: Modern module system with proper imports/exports
- ๐ง Interactive Effects: Built-in pressed effects and animations
- ๐ฑ Touch Support: Full mobile and desktop interaction support
- ๐งช Functional Architecture: Pure functions and functional programming principles for better testability
- ๐ Proper Encapsulation: Private methods and static utilities for clean API design
- ๐ค Mixin Coordination: Smart pointer coordination system for multiple gesture mixins
- ๐ Mobile Scroll Management: Intelligent scroll prevention during gesture interactions
Architecture
Functional Programming Design
ARS Web Components uses functional programming principles while maintaining the class structure required by the Custom Elements API:
- Pure Functions: Utility functions are extracted as pure functions for better testability
- Private Methods: Internal logic uses proper private methods (
#methodName) for encapsulation - Static Utilities: Helper functions are organized as private static methods (
static #methodName) - Public API: Only methods meant to be called externally are exposed as public static methods
Method Organization
class MyComponent extends HTMLElement {
// Public static methods - meant to be called from outside
static get observedAttributes() {
return ["attr1", "attr2"];
}
// Private static methods - internal utilities
static #validateInput(input) {
/* validation logic */
}
static #createElement(tag, props) {
/* element creation */
}
// Private instance methods - internal component logic
#handleClick() {
/* click handling */
}
#updateDisplay() {
/* display updates */
}
// Public instance methods - component API
publicMethod() {
/* public functionality */
}
}Installation
npm install ars-web-componentsUsage
Method 1: ES Module Import (Recommended)
import { ArsCalendar } from "ars-web-components";Method 2: Direct Script Import
For projects that need to load components directly without bundling:
<script type="module" src="./node_modules/ars-web-components/index.js"></script>Components
ArsCalendar
Interactive calendar component with full customization support.
<ars-calendar
id="myCalendar"
localized_abbreviated_days='["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]'
localized_months='["January","February","March",...,"December"]'
localized_today="Today"
css-vars='{"ars-calendar-bg": "#f0f0f0", "ars-calendar-header-bg": "#333"}'
></ars-calendar>Attributes:
localized_abbreviated_days: JSON array of localized day abbreviationslocalized_months: JSON array of localized month nameslocalized_today: Localized text for "Today" buttoncustom-css: Custom CSS string to add to component stylescss-vars: JSON object of CSS custom properties for theming
Methods:
addEvent(event): Add an event to the calendarremoveEvent(event): Remove an event from the calendarchangeEvent(date, newText, newColor): Modify an existing eventselectDate(day, month, year): Programmatically select a datesetSelectedDateToToday(): Select today's datesetCustomTemplate(templateFunction): Provide custom HTML templatesetCSSVars(cssVarsObject): Set CSS variables programmaticallygetCSSVars(): Get current CSS variables
Events:
ars-calendar:daySelected: Fired when a date is selected
CSS Customization:
The calendar supports extensive theming through CSS variables:
ars-calendar {
--ars-calendar-bg: #ffffff;
--ars-calendar-shadow: 0px 3px 3px rgba(0, 0, 0, 0.25);
--ars-calendar-border-radius: 5px;
--ars-calendar-header-bg: linear-gradient(to bottom, #b32b0c, #cd310d);
--ars-calendar-header-height: 34px;
--ars-calendar-header-color: #fff;
--ars-calendar-cell-width: 30px;
--ars-calendar-cell-height: 30px;
/* ... and many more */
}ArsDialog
Modal dialog component for user interactions. Supports custom content, styling with backdrop management, and both confirmation and notification modes.
// Open a dialog with confirmation buttons and custom content
const result = await ArsDialog.dialog(
`<form><label>Name: <input id='name'></label></form>`,
"Dialog Title"
);
if (result) {
const name = result.querySelector("#name").value;
// ...
}
// Show a notification dialog
await ArsDialog.notify("Operation complete!", "Success");Attributes:
custom-css: Custom CSS string to add to dialog stylescss-vars: JSON object of CSS custom properties for theming
Methods:
setCSSVars(cssVarsObject): Set CSS variables programmaticallygetCSSVars(): Get current CSS variables
Styling & Theming:
- Dialog supports extensive theming via CSS variables (see
ars-dialog-css.js) - Form elements (
input,select,textarea) are styled by default, even for light DOM content injected as HTML - Content area is fully responsive and prevents overflow
Light DOM Form Styling:
If you inject form elements as raw HTML (light DOM) into the dialog, ARS Dialog will automatically inject a <style> tag with form element CSS into the content area, ensuring consistent styling for input, select, and textarea.
Events:
- Dialog returns the content DOM element (for confirmation dialogs) or
null/falseif cancelled
Example:
const result = await ArsDialog.dialog('<input id="myInput">', "Enter Value");
if (result) {
alert(result.querySelector("#myInput").value);
}ArsColorSelect
Color picker component with improved UI and UX.
<ars-color-select id="myColorPicker" color="Blue"></ars-color-select>Features:
- Modern, touch-friendly color palette with grid layout
- Color blocks have a border, shadow, and animated hover effect
- Palette overlay can be dismissed by clicking outside the color blocks
- Emits
ars-color-select:changeevent with{ id, color }detail - Easy integration: update any text or UI in response to color changes
Usage Example:
<span id="selectedColorText">Press the element below to change its color.</span>
<ars-color-select id="colorSelect1"></ars-color-select>
<script>
const colorSelect = document.getElementById("colorSelect1");
const colorText = document.getElementById("selectedColorText");
colorSelect.addEventListener("ars-color-select:change", (e) => {
colorText.textContent = `Selected Color: ${e.detail.color}`;
});
</script>Attributes:
color: Initial color (optional). If not provided, a random color is selected.
Events:
ars-color-select:change: Fired when a color is selected or changed.
ArsPage & ArsPageController
Component-based router and navigation controls for web applications, using the new remote-call API for inter-component communication.
ArsPage
<ars-page id="my-router" default-page="home">
<div id="home">Home page content</div>
<div id="about">About page content</div>
<div id="contact">Contact page content</div>
</ars-page>Attributes:
default-page: The page to show initiallyremote-call-id: (optional) For remote-call targeting
ArsPageController
<ars-page-controller
target-page="my-router"
navigation-type="buttons"
></ars-page-controller>Attributes:
target-page: The ID of thears-pagecomponent to controlnavigation-type:buttons,tabs, ordropdown(default:buttons)show-current: Whether to highlight the current page (default:true)
Features:
- Component-based routing
- Multiple navigation types (buttons, tabs, dropdown)
- Remote method calling (uses the new remote-call API)
- Event-driven architecture
- Easy to integrate
Mixins
ARS Web Components includes a collection of reusable mixins that can be applied to any web component to add specific functionality.
PressedEffect Mixin
Adds pressed animation effects to components with solid background colors.
import { PressedEffectMixin } from "ars-web-components";
class MyButton extends PressedEffectMixin(HTMLElement) {
constructor() {
super();
// Your component logic
}
}Features:
- Automatic color detection from background
- Smooth pressed animation effects
- Works with solid background colors
- Touch and mouse support
Demo: http://localhost:8080/mixins/pressed-effect-mixin/demo/
Localized Mixin
Provides localization capabilities for components with dynamic language switching.
import { LocalizedMixin } from "ars-web-components";
class LocalizedComponent extends LocalizedMixin(HTMLElement) {
constructor() {
super();
this.setLocalizedText({
en: "Hello World",
es: "Hola Mundo",
fr: "Bonjour le Monde",
});
}
}Features:
- Dynamic language switching
- Text localization support
- Event-driven updates
- Mock localization system for testing
Demo: http://localhost:8080/mixins/localized-mixin/demo/
RemoteCall Mixin
Enables inter-component communication through method calls and event dispatching using only component IDs. The remote-call-id attribute is no longer required or supported.
import {
RemoteCallCallerMixin,
RemoteCallReceiverMixin,
} from "ars-web-components";
// Receiver component (must have an id!)
class MyReceiver extends RemoteCallReceiverMixin(HTMLElement) {
constructor() {
super();
this.id = "my-receiver"; // REQUIRED
this.exposeMethod("greet", (name) => `Hello ${name}!");
}
}
// Caller component
class MyCaller extends RemoteCallCallerMixin(HTMLElement) {
callRemoteGreet() {
this._callRemote("my-receiver", "greet", "World");
}
}Important: Components using these mixins must have a unique id attribute.
Features:
- Component ID-based targeting (no more remote-call-id)
- Method call with parameters
- Error handling and validation
- Real-time logging
- Support for multiple receiver instances
Demo: http://localhost:8080/mixins/remote-call-mixin/demo/
ShowIfPropertyTrue Mixin
Conditionally shows/hides components based on property values.
import { ShowIfPropertyTrueMixin } from "ars-web-components";
class ConditionalComponent extends ShowIfPropertyTrueMixin(HTMLElement) {
constructor() {
super();
this.showIfPropertyTrue("visible", true);
}
}Demo: http://localhost:8080/mixins/show-if-property-true-mixin/demo/
Swipeable Mixin
Adds swipe gesture support to components.
import { SwipeableMixin } from "ars-web-components";
class SwipeableComponent extends SwipeableMixin(HTMLElement) {
constructor() {
super();
this.onSwipeLeft = () => console.log("Swiped left!");
this.onSwipeRight = () => console.log("Swiped right!");
}
}Features:
- Swipe detection with customizable distance and time thresholds
- Direction detection (left, right, up, down)
- Configurable via
min-swipe-distanceandmax-swipe-timeattributes - Works seamlessly with other mixins using PointerCoordinator
- Order-independent: Can be nested in any order with other gesture mixins
Demo: http://localhost:8080/mixins/swipeable-mixin/demo/
Draggable Mixin
Adds drag gesture detection to components with customizable thresholds and real-time feedback.
import { DraggableMixin } from "ars-web-components";
class DraggableComponent extends DraggableMixin(HTMLElement) {
constructor() {
super();
this.addEventListener('dragstart', (e) => console.log('Drag started:', e.detail));
this.addEventListener('dragmove', (e) => console.log('Dragging:', e.detail));
this.addEventListener('dragend', (e) => console.log('Drag ended:', e.detail));
}
}Features:
- Drag start, move, and end events with detailed coordinate data
- Direction detection (left, right, up, down) with distance tracking
- Configurable drag threshold via
drag-thresholdattribute - Real-time drag feedback with
dragmoveevents - Works seamlessly with other mixins using PointerCoordinator
- Order-independent: Can be nested in any order with other gesture mixins
Demo: http://localhost:8080/mixins/draggable-mixin/demo/
Roll Mixin
Adds roll animation effects to components.
import { RollMixin } from "ars-web-components";
class RollableComponent extends RollMixin(HTMLElement) {
constructor() {
super();
this.onRollStart = () => console.log("Roll started!");
this.onRollEnd = () => console.log("Roll ended!");
}
}Demo: http://localhost:8080/mixins/roll-mixin/demo/
Mixin Coordination
ARS Web Components includes a sophisticated coordination system that allows multiple gesture mixins to work together seamlessly on the same element.
PointerCoordinator
The PointerCoordinator manages pointer captures and event redispatching to prevent conflicts between multiple mixins:
import { PointerCoordinator } from "ars-web-components";
// Check if scrolling is currently prevented
if (PointerCoordinator.isScrollPrevented()) {
console.log('Scroll prevention is active');
}
// Check if an element has captured a specific pointer
if (PointerCoordinator.hasPointerCapture(element, pointerId)) {
console.log('Element has captured this pointer');
}
// Get debug information
const debugInfo = PointerCoordinator.getDebugInfo();
console.log('Active captures:', debugInfo.totalCaptures);Features:
- Prevents conflicts when multiple mixins try to capture the same pointer
- Smart scroll prevention that only activates during active gestures
- Event redispatching system to prevent infinite loops
- Early gesture detection for responsive touch interactions
- Debug tools and status monitoring for development
- Order-independent coordination: Works regardless of mixin nesting order
Using Multiple Mixins Together
You can combine multiple gesture mixins on the same element in any order:
<!-- DraggableMixin as parent, SwipeableMixin as child -->
<draggable-mixin drag-threshold="10">
<swipeable-mixin min-swipe-distance="30" max-swipe-time="800">
<div>Drag for movement, swipe for quick actions</div>
</swipeable-mixin>
</draggable-mixin>
<!-- SwipeableMixin as parent, DraggableMixin as child -->
<swipeable-mixin min-swipe-distance="30" max-swipe-time="800">
<draggable-mixin drag-threshold="10">
<div>Swipe for quick actions, drag for movement</div>
</draggable-mixin>
</swipeable-mixin>In both examples:
- Dragging will trigger drag events
- Quick swipes will trigger swipe events
- Both mixins coordinate through PointerCoordinator
- Scroll prevention only activates when gestures are detected
- Order-independent: Works regardless of which mixin is parent/child
Show If Property True Mixin
This mixin allows you to show or hide a custom element based on a boolean property, attribute, or data attribute. It is ideal for toggling the visibility of UI elements in a declarative way.
Usage Example
<!-- Toggle the bar by changing the isVisible property -->
<conditional-element class="bar" show-if-property="isVisible"
>isVisible Bar</conditional-element
>import { ShowIfPropertyTrueMixin } from "./mixins/show-if-property-true-mixin/show-if-property-true-mixin.js";
class ConditionalElement extends ShowIfPropertyTrueMixin(HTMLElement) {}
customElements.define("conditional-element", ConditionalElement);
// Toggle visibility
const el = document.querySelector("conditional-element");
el.isVisible = true; // shows the bar
el.isVisible = false; // hides the barkeep-space-when-hidden Attribute
Add the keep-space-when-hidden attribute to keep the element's space in the layout when hidden (uses visibility: hidden instead of display: none).
<conditional-element
class="bar"
show-if-property="isVisible"
keep-space-when-hidden
>
isVisible Bar
</conditional-element>Development
Quick Start
Start the development server with all component demos:
cd ars-web-components
npm install
npm startThis will:
- Start an HTTP server on port 8080
- Open your browser automatically
- Display a demo of the available components and mixins
Eperimenting with Components and mixins
Once the server is running, you can access:
- Main Demo Gallery: http://localhost:8080/
- Individual Components:
- ars-calendar: http://localhost:8080/components/ars-calendar/demo/
- ars-dialog: http://localhost:8080/components/ars-dialog/demo/
Co-development Setup
For projects that need to develop alongside ars-web-components, you can set up symlinks:
# In your project's node_modules
ln -s ../../../../ars-web-components ars-web-components-devAvailable Exports
Check index.js in the package root for all available imports:
export { ArsCalendar } from "./components/ars-calendar/ars-calendar.js";
export { ArsColorSelect } from "./components/ars-color-select/ars-color-select.js";
export { ArsDialog } from "./components/ars-dialog/ars-dialog.js";
export { ArsPageController } from "./components/ars-page/ars-page-controller.js";
export { ArsPage } from "./components/ars-page/ars-page.js";
export { WebComponentBase } from "./components/web-component-base/web-component-base.js";
// Mixins
export { LocalizedMixin } from "./mixins/localized-mixin/localized-mixin.js";
export { PressedEffectMixin } from "./mixins/pressed-effect-mixin/pressed-effect-mixin.js";
export { RemoteCallCallerMixin } from "./mixins/remote-call-mixin/remote-call-caller-mixin.js";
export { RemoteCallReceiverMixin } from "./mixins/remote-call-mixin/remote-call-receiver-mixin.js";
export { RollMixin } from "./mixins/roll-mixin/roll-mixin.js";
export { ShowIfPropertyTrueMixin } from "./mixins/show-if-property-true-mixin/show-if-property-true-mixin.js";
export { SwipeableMixin } from "./mixins/swipeable-mixin/swipeable-mixin.js";
export { DraggableMixin } from "./mixins/draggable-mixin/draggable-mixin.js";Requirements
- Modern browser with ES module support
arslibdependency (automatically installed)
License
MIT