Aether JS AetherJS

Installation

AetherJS is a dependency-free JavaScript library that can be easily integrated into modern web projects. Follow the steps below to include and initialize it in your project.


01 Installation

Download the aether.js file to your project and include it in your page.

index.html
<script src="/assets/js/aether.js"></script>

02 Initialization

There are two ways to initialize the library: Automatic and Manual

Automatic Initialization

If you want to use the default settings, you don't need to write any JavaScript code. Simply add the data-aether-auto attribute to the body tag.

index.html
<body data-aether-auto>
    ...
</body>

Manual Initialization

If you want to customize the settings, do not use the data-aether-auto attribute. Instead, call the AetherUI.init() function with your own settings object after the script file.

index.html
<script> 
    AetherUI.init({
        prefix: 'aether',
        hiddenClass: 'hidden',
        blockScrollClass: 'overflow-hidden',
        themeStorageKey: 'theme',
        syncUrl: true,
        debug: true,
        domRefreshDebounce: 150,
        resizeDebounce: 300,      
    });
</script>

03 Configuration

The configuration object passed to the AetherUI.init(config) method determines the global behavior of the library. Default values and descriptions are below:

Option Type Default Description
prefix String "aether" Sets the prefix for all data attributes. If set to "test", data-test-target will be used instead of data-aether-target.
hiddenClass String "hidden" CSS class used to hide elements. Can be set to "d-none" for Bootstrap users.
blockScrollClass String "overflow-hidden" Class added to the body tag to prevent scrolling when a modal is open.
themeStorageKey String "theme" Determines the localStorage key used to store the selected theme (dark/light).
syncUrl Boolean true Controls whether to add a hash (#id) to the browser URL when a Tab or Modal is opened (Deep Linking).
debug Boolean true Development mode. If true, logs detailed error and status messages to the console. Recommended to be false in production.
domRefreshDebounce Number 150 Trigger delay for the MutationObserver watching DOM changes (in ms).
resizeDebounce Number 300 Determines how often calculations are performed when the screen is resized (in ms).

04 Important Notice

It is recommended to use the following CSS variables when testing all example codes in the documentation.

main.css
@custom-variant dark (&:where(.dark, .dark *));

@theme {
    /*----------Raw Materials----------*/
    --aether-50: #fafafa;
    --aether-100: #f4f4f5;
    --aether-200: #e4e4e7;
    --aether-300: #d4d4d8;
    --aether-400: #a1a1aa;
    --aether-500: #71717a;
    --aether-600: #52525b;
    --aether-700: #3f3f46;
    --aether-800: #27272a;
    --aether-900: #18181b;
    --aether-950: #121215;

    --accent: #2563eb;
    --accent-interactive: #3b82f6;

    --static-white: #ffffff;
    --static-black: #000000;
}

/*----------Light Theme----------*/
:root {
    /* bg */
    --bg-primary: var(--aether-50);
    --bg-primary-interactive: var(--aether-100);
    --bg-secondary: var(--static-white);
    --bg-secondary-interactive: var(--aether-50);
    --bg-tertiary: var(--aether-100);
    --bg-tertiary-interactive: var(--aether-200);
    --bg-accent: var(--accent);
    --bg-accent-interactive: var(--accent-interactive);

    /* fg */
    --fg-primary: var(--aether-900);
    --fg-primary-interactive: var(--static-black);
    --fg-secondary: var(--aether-600);
    --fg-secondary-interactive: var(--aether-800);
    --fg-tertiary: var(--aether-400);
    --fg-tertiary-interactive: var(--aether-600);
    --fg-inverse: var(--static-white);
    --fg-inverse-interactive: var(--aether-200);
    --fg-accent: var(--accent);
    --fg-accent-interactive: var(--accent-interactive);

    /* border */
    --border-primary: var(--aether-200);
    --border-primary-interactive: var(--aether-300);
    --border-accent: var(--accent);
    --border-accent-interactive: var(--accent-interactive);

    /* code */
    --code-tag: #be185d; 
    --code-prop: #334155;
    --code-value: #0369a1;
    --code-text: #0f172a; 
    --code-accent: #7e22ce;
    --code-muted: #64748b; 
}

/*----------Dark Theme----------*/
:root.dark {
    /* bg */
    --bg-primary: var(--aether-950);
    --bg-primary-interactive: var(--aether-900);
    --bg-secondary: var(--aether-900);
    --bg-secondary-interactive: var(--aether-800);
    --bg-tertiary: var(--aether-800);
    --bg-tertiary-interactive: var(--aether-700);
    --bg-accent: var(--accent);
    --bg-accent-interactive: var(--accent-interactive);

    /* fg */
    --fg-primary: var(--aether-50);
    --fg-primary-interactive: var(--static-white);
    --fg-secondary: var(--aether-400);
    --fg-secondary-interactive: var(--aether-200);
    --fg-tertiary: var(--aether-500);
    --fg-tertiary-interactive: var(--aether-300);
    --fg-inverse: var(--aether-950);
    --fg-inverse-interactive: var(--static-black);
    --fg-accent: var(--accent);
    --fg-accent-interactive: var(--accent-interactive);

    /* border */
    --border-primary: var(--aether-800);
    --border-primary-interactive: var(--aether-700);
    --border-accent: var(--accent);
    --border-accent-interactive: var(--accent-interactive);

    /* code */
    --code-tag: #ff63aa; 
    --code-prop: #ced8e6;
    --code-value: #7dd3fc;
    --code-text: #f4f4f5;
    --code-accent: #d946ef;
    --code-muted: #94a3b8;
}

/*----------Tailwind Mapping----------*/
@theme {
    /* bg */
    --background-color-primary: var(--bg-primary);
    --background-color-primary-interactive: var(--bg-primary-interactive);
    --background-color-secondary: var(--bg-secondary);
    --background-color-secondary-interactive: var(--bg-secondary-interactive);
    --background-color-tertiary: var(--bg-tertiary);
    --background-color-tertiary-interactive: var(--bg-tertiary-interactive);
    --background-color-accent: var(--bg-accent);
    --background-color-accent-interactive: var(--bg-accent-interactive);

    /* fg */
    --text-color-primary: var(--fg-primary);
    --text-color-primary-interactive: var(--fg-primary-interactive);
    --text-color-secondary: var(--fg-secondary);
    --text-color-secondary-interactive: var(--fg-secondary-interactive);
    --text-color-tertiary: var(--fg-tertiary);
    --text-color-tertiary-interactive: var(--fg-tertiary-interactive);
    --text-color-inverse: var(--fg-inverse);
    --text-color-inverse-interactive: var(--fg-inverse-interactive);
    --text-color-accent: var(--fg-accent);
    --text-color-accent-interactive: var(--fg-accent-interactive);

    /* border */
    --border-color-primary: var(--border-primary);
    --border-color-primary-interactive: var(--border-primary-interactive);
    --border-color-accent: var(--border-accent);
    --border-color-accent-interactive: var(--border-accent-interactive);

    /* code */
    --background-color-code-tag: var(--code-tag);
    --background-color-code-prop: var(--code-prop);
    --background-color-code-value: var(--code-value);
    --background-color-code-text: var(--code-text);
    --background-color-code-accent: var(--code-accent);
    --background-color-code-muted: var(--code-muted);

    --text-color-code-tag: var(--code-tag);
    --text-color-code-prop: var(--code-prop);
    --text-color-code-value: var(--code-value);
    --text-color-code-text: var(--code-text);
    --text-color-code-accent: var(--code-accent);
    --text-color-code-muted: var(--code-muted);
}