@odx/foundation 1.0.0-rc.3 → 1.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/README.md +10 -0
- package/dist/lib/breakpoints.d.ts +49 -49
- package/dist/lib/breakpoints.js +141 -122
- package/dist/lib/format.d.ts +52 -50
- package/dist/lib/format.js +53 -50
- package/dist/lib/localization.d.ts +14 -11
- package/dist/lib/localization.js +15 -15
- package/dist/lib/models.d.ts +5 -39
- package/dist/lib/signals.d.ts +16 -13
- package/dist/lib/signals.js +37 -32
- package/dist/lib/theming.d.ts +16 -13
- package/dist/lib/theming.js +21 -24
- package/dist/lib/utils/shared-media-observer.js +33 -35
- package/dist/main.d.ts +7 -7
- package/dist/main.js +6 -5
- package/dist/styles.css +1069 -1
- package/package.json +15 -17
- package/types/styles.d.ts +3 -0
- package/dist/lib/models.js +0 -34
- package/dist/lib/utils/breakpoint.d.ts +0 -38
- package/dist/lib/utils/breakpoint.js +0 -103
- package/dist/lib/utils/shared-media-observer.d.ts +0 -4
- package/dist/oss-licenses.json +0 -1
package/dist/lib/format.js
CHANGED
|
@@ -1,63 +1,66 @@
|
|
|
1
|
+
//#region src/lib/format.ts
|
|
1
2
|
function parseDate(value) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if (Number.isNaN(date.getTime()) && typeof value === "string") {
|
|
8
|
-
return createDate(Number(value));
|
|
9
|
-
}
|
|
10
|
-
return createDate(date.getTime());
|
|
3
|
+
const createDate = (value) => Number.isNaN(value) ? null : new Date(value);
|
|
4
|
+
if (value instanceof Date) return createDate(value.getTime());
|
|
5
|
+
const date = new Date(value);
|
|
6
|
+
if (Number.isNaN(date.getTime()) && typeof value === "string") return createDate(Number(value));
|
|
7
|
+
return createDate(date.getTime());
|
|
11
8
|
}
|
|
12
9
|
function formatDate(input, options) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
return new Intl.DateTimeFormat(options?.locale, options).format(value);
|
|
10
|
+
const value = parseDate(input);
|
|
11
|
+
if (!value) return "";
|
|
12
|
+
if (options?.dateStyle === "iso8601") return new Intl.DateTimeFormat("sv-SE", { dateStyle: "short" }).format(value);
|
|
13
|
+
return new Intl.DateTimeFormat(options?.locale, options).format(value);
|
|
19
14
|
}
|
|
20
15
|
function formatNumber(input, options) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
options.style = "unit";
|
|
27
|
-
}
|
|
28
|
-
return new Intl.NumberFormat(options?.locale, options).format(value);
|
|
16
|
+
const value = Number(input);
|
|
17
|
+
if (Number.isNaN(value)) return "";
|
|
18
|
+
if (options?.currency) options.style = "currency";
|
|
19
|
+
else if (options?.unit) options.style = "unit";
|
|
20
|
+
return new Intl.NumberFormat(options?.locale, options).format(value);
|
|
29
21
|
}
|
|
30
22
|
function formatList(input, options) {
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
if (input.length === 0) return "";
|
|
24
|
+
return new Intl.ListFormat(options?.locale, options).format(input);
|
|
33
25
|
}
|
|
34
26
|
const TIME_UNIT_MAP = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
27
|
+
second: {
|
|
28
|
+
max: 59e3,
|
|
29
|
+
value: 1e3
|
|
30
|
+
},
|
|
31
|
+
minute: {
|
|
32
|
+
max: 276e4,
|
|
33
|
+
value: 6e4
|
|
34
|
+
},
|
|
35
|
+
hour: {
|
|
36
|
+
max: 72e6,
|
|
37
|
+
value: 36e5
|
|
38
|
+
},
|
|
39
|
+
day: {
|
|
40
|
+
max: 5184e5,
|
|
41
|
+
value: 864e5
|
|
42
|
+
},
|
|
43
|
+
week: {
|
|
44
|
+
max: 24192e5,
|
|
45
|
+
value: 6048e5
|
|
46
|
+
},
|
|
47
|
+
month: {
|
|
48
|
+
max: 28512e6,
|
|
49
|
+
value: 2592e6
|
|
50
|
+
},
|
|
51
|
+
year: {
|
|
52
|
+
max: Number.POSITIVE_INFINITY,
|
|
53
|
+
value: 31536e6
|
|
54
|
+
}
|
|
48
55
|
};
|
|
49
56
|
function formatRelativeTime(input, options) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return new Intl.RelativeTimeFormat(options?.locale, options).format(
|
|
58
|
-
Math.round(relativeTime / unitConfig.value),
|
|
59
|
-
unit
|
|
60
|
-
);
|
|
57
|
+
const startDate = parseDate(options?.start ?? Date.now());
|
|
58
|
+
const value = parseDate(input);
|
|
59
|
+
if (!value || !startDate) return "";
|
|
60
|
+
const relativeTime = value.getTime() - startDate.getTime();
|
|
61
|
+
const minUnit = options?.minUnit && TIME_UNIT_MAP[options.minUnit] || TIME_UNIT_MAP.second;
|
|
62
|
+
const [unit, unitConfig] = Object.entries(TIME_UNIT_MAP).find(([_, { value, max }]) => Math.abs(relativeTime) < max && minUnit.value <= value);
|
|
63
|
+
return new Intl.RelativeTimeFormat(options?.locale, options).format(Math.round(relativeTime / unitConfig.value), unit);
|
|
61
64
|
}
|
|
62
|
-
|
|
65
|
+
//#endregion
|
|
63
66
|
export { formatDate, formatList, formatNumber, formatRelativeTime, parseDate };
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { FormatOptions } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { FormatOptions } from "./format.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/localization.d.ts
|
|
4
|
+
interface LocalizationOptions extends FormatOptions {
|
|
5
|
+
defaultLocale: () => Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier;
|
|
6
|
+
fallbackLanguage: () => Intl.UnicodeBCP47LocaleIdentifier;
|
|
7
|
+
fallbackTranslation: (key: string) => string;
|
|
6
8
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
//#
|
|
9
|
+
declare const LocalizationOptions: (config?: Partial<LocalizationOptions>) => LocalizationOptions;
|
|
10
|
+
declare function setLocalizationOptions(options?: Partial<LocalizationOptions> | null): void;
|
|
11
|
+
declare function getLocalizationOptions(options?: Partial<LocalizationOptions> | null): LocalizationOptions;
|
|
12
|
+
declare function getLocale(localeInput?: Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier | null): Intl.Locale;
|
|
13
|
+
declare function setLocale(localeInput?: Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier | null): void;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { LocalizationOptions, getLocale, getLocalizationOptions, setLocale, setLocalizationOptions };
|
package/dist/lib/localization.js
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { sharedSignal } from
|
|
2
|
-
|
|
1
|
+
import { sharedSignal } from "./signals.js";
|
|
2
|
+
//#region src/lib/localization.ts
|
|
3
3
|
const locale = sharedSignal("locale", null);
|
|
4
4
|
const localizationOptions = sharedSignal("localizationOptions", null);
|
|
5
5
|
const LocalizationOptions = (config) => ({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
defaultLocale: () => navigator.language,
|
|
7
|
+
fallbackLanguage: () => "en",
|
|
8
|
+
fallbackTranslation: (key) => key,
|
|
9
|
+
...config,
|
|
10
|
+
relativeTimeFormatOptions: {
|
|
11
|
+
minUnit: "minute",
|
|
12
|
+
...config?.relativeTimeFormatOptions
|
|
13
|
+
}
|
|
14
14
|
});
|
|
15
15
|
function setLocalizationOptions(options) {
|
|
16
|
-
|
|
16
|
+
localizationOptions.set(getLocalizationOptions(options));
|
|
17
17
|
}
|
|
18
18
|
function getLocalizationOptions(options) {
|
|
19
|
-
|
|
19
|
+
return LocalizationOptions(options ?? localizationOptions.get() ?? {});
|
|
20
20
|
}
|
|
21
21
|
function getLocale(localeInput) {
|
|
22
|
-
|
|
22
|
+
return new Intl.Locale(localeInput || locale.get() || getLocalizationOptions().defaultLocale());
|
|
23
23
|
}
|
|
24
24
|
function setLocale(localeInput) {
|
|
25
|
-
|
|
25
|
+
locale.set(localeInput ? getLocale(localeInput) : null);
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
//#endregion
|
|
28
28
|
export { LocalizationOptions, getLocale, getLocalizationOptions, setLocale, setLocalizationOptions };
|
package/dist/lib/models.d.ts
CHANGED
|
@@ -1,39 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
7
|
-
export type Spacing = (typeof Spacing)[keyof typeof Spacing];
|
|
8
|
-
export declare const Spacing: {
|
|
9
|
-
readonly 0: "0";
|
|
10
|
-
readonly SM: "sm";
|
|
11
|
-
readonly MD: "md";
|
|
12
|
-
readonly LG: "lg";
|
|
13
|
-
};
|
|
14
|
-
export type Justify = (typeof Justify)[keyof typeof Justify];
|
|
15
|
-
export declare const Justify: {
|
|
16
|
-
readonly START: "start";
|
|
17
|
-
readonly END: "end";
|
|
18
|
-
readonly CENTER: "center";
|
|
19
|
-
readonly SPACE_BETWEEN: "space-between";
|
|
20
|
-
readonly SPACE_AROUND: "space-around";
|
|
21
|
-
readonly SPACE_EVENLY: "space-evenly";
|
|
22
|
-
};
|
|
23
|
-
export type Variant = (typeof Variant)[keyof typeof Variant];
|
|
24
|
-
export declare const Variant: {
|
|
25
|
-
readonly NEUTRAL: "neutral";
|
|
26
|
-
readonly PRIMARY: "primary";
|
|
27
|
-
readonly ACCENT: "accent";
|
|
28
|
-
readonly SUCCESS: "success";
|
|
29
|
-
readonly WARNING: "warning";
|
|
30
|
-
readonly DANGER: "danger";
|
|
31
|
-
readonly ACCENT_GHOST: "accent-ghost";
|
|
32
|
-
readonly DANGER_GHOST: "danger-ghost";
|
|
33
|
-
readonly CONFIRMATION: "confirmation";
|
|
34
|
-
readonly SUBTLE: "subtle";
|
|
35
|
-
readonly GHOST: "ghost";
|
|
36
|
-
};
|
|
37
|
-
export type UnitIdentifier = SingleUnitIdentifier | `${SingleUnitIdentifier}-per-${SingleUnitIdentifier}` | (string & {});
|
|
38
|
-
export type SingleUnitIdentifier = 'acre' | 'bit' | 'byte' | 'celsius' | 'centimeter' | 'day' | 'degree' | 'fahrenheit' | 'fluid-ounce' | 'foot' | 'gallon' | 'gigabit' | 'gigabyte' | 'gram' | 'hectare' | 'hour' | 'inch' | 'kilobit' | 'kilobyte' | 'kilogram' | 'kilometer' | 'liter' | 'megabit' | 'megabyte' | 'meter' | 'microsecond' | 'mile' | 'mile-scandinavian' | 'milliliter' | 'millimeter' | 'millisecond' | 'minute' | 'month' | 'nanosecond' | 'ounce' | 'percent' | 'petabyte' | 'pound' | 'second' | 'stone' | 'terabit' | 'terabyte' | 'week' | 'yard' | 'year';
|
|
39
|
-
//# sourceMappingURL=models.d.ts.map
|
|
1
|
+
//#region src/lib/models.d.ts
|
|
2
|
+
type UnitIdentifier = SingleUnitIdentifier | `${SingleUnitIdentifier}-per-${SingleUnitIdentifier}` | (string & {});
|
|
3
|
+
type SingleUnitIdentifier = 'acre' | 'bit' | 'byte' | 'celsius' | 'centimeter' | 'day' | 'degree' | 'fahrenheit' | 'fluid-ounce' | 'foot' | 'gallon' | 'gigabit' | 'gigabyte' | 'gram' | 'hectare' | 'hour' | 'inch' | 'kilobit' | 'kilobyte' | 'kilogram' | 'kilometer' | 'liter' | 'megabit' | 'megabyte' | 'meter' | 'microsecond' | 'mile' | 'mile-scandinavian' | 'milliliter' | 'millimeter' | 'millisecond' | 'minute' | 'month' | 'nanosecond' | 'ounce' | 'percent' | 'petabyte' | 'pound' | 'second' | 'stone' | 'terabit' | 'terabyte' | 'week' | 'yard' | 'year';
|
|
4
|
+
//#endregion
|
|
5
|
+
export { UnitIdentifier };
|
package/dist/lib/signals.d.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
import { Signal
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { Signal } from "signal-polyfill";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/signals.d.ts
|
|
4
|
+
type Signal$1<T> = Signal.State<T> & {
|
|
5
|
+
update: (updateFn: (value: T) => T) => void;
|
|
4
6
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
type SignalOptions<T> = Signal.Options<T> & {
|
|
8
|
+
watched?(): void;
|
|
9
|
+
unwatched?(): void;
|
|
8
10
|
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
type ReadonlySignal<T> = Signal.Computed<T>;
|
|
12
|
+
declare function signal<T>(value: T, options?: SignalOptions<T>): Signal$1<T>;
|
|
11
13
|
/**
|
|
12
14
|
* Creates or retrieves a shared signal stored on the global object. This is useful for signals that need to be shared across multiple modules without explicitly passing them around, such as localization settings or translation records.
|
|
13
15
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
declare function sharedSignal<T>(key: string, ...args: Parameters<typeof signal<T>>): ReturnType<typeof signal<T>>;
|
|
17
|
+
declare function computed<T>(computeFn: () => T, options?: SignalOptions<T>): ReadonlySignal<T>;
|
|
18
|
+
declare function effect(callback: (() => void) | (() => () => void)): () => void;
|
|
17
19
|
declare global {
|
|
18
|
-
|
|
20
|
+
var __ODX_SHARED_SIGNALS__: Record<string, unknown>;
|
|
19
21
|
}
|
|
20
|
-
//#
|
|
22
|
+
//#endregion
|
|
23
|
+
export { ReadonlySignal, Signal$1 as Signal, SignalOptions, computed, effect, sharedSignal, signal };
|
package/dist/lib/signals.js
CHANGED
|
@@ -1,47 +1,52 @@
|
|
|
1
|
-
import { Signal } from
|
|
2
|
-
|
|
1
|
+
import { Signal } from "signal-polyfill";
|
|
2
|
+
//#region src/lib/signals.ts
|
|
3
3
|
function transformOptions(options) {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
if (!options) return;
|
|
5
|
+
return {
|
|
6
|
+
equals: options.equals,
|
|
7
|
+
[Signal.subtle.watched]: options.watched,
|
|
8
|
+
[Signal.subtle.unwatched]: options.unwatched
|
|
9
|
+
};
|
|
6
10
|
}
|
|
7
11
|
function signal(value, options) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
const state = new Signal.State(value, transformOptions(options));
|
|
13
|
+
state.update = (updateFn) => state.set(updateFn(state.get()));
|
|
14
|
+
return state;
|
|
11
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Creates or retrieves a shared signal stored on the global object. This is useful for signals that need to be shared across multiple modules without explicitly passing them around, such as localization settings or translation records.
|
|
18
|
+
*/
|
|
12
19
|
function sharedSignal(key, ...args) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
return globalThis.__ODX_SHARED_SIGNALS__[key];
|
|
20
|
+
if (!(key in globalThis.__ODX_SHARED_SIGNALS__)) globalThis.__ODX_SHARED_SIGNALS__[key] = signal(...args);
|
|
21
|
+
return globalThis.__ODX_SHARED_SIGNALS__[key];
|
|
17
22
|
}
|
|
18
23
|
function computed(computeFn, options) {
|
|
19
|
-
|
|
24
|
+
return new Signal.Computed(computeFn, transformOptions(options));
|
|
20
25
|
}
|
|
21
26
|
let needsEnqueue = true;
|
|
22
27
|
const watcher = new Signal.subtle.Watcher(() => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
if (!needsEnqueue) return;
|
|
29
|
+
needsEnqueue = false;
|
|
30
|
+
queueMicrotask(() => {
|
|
31
|
+
needsEnqueue = true;
|
|
32
|
+
for (const signal of watcher.getPending()) signal.get();
|
|
33
|
+
watcher.watch();
|
|
34
|
+
});
|
|
30
35
|
});
|
|
31
36
|
function effect(callback) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
let cleanup;
|
|
38
|
+
const signal = computed(() => {
|
|
39
|
+
cleanup?.();
|
|
40
|
+
cleanup = callback() || void 0;
|
|
41
|
+
});
|
|
42
|
+
watcher.watch(signal);
|
|
43
|
+
signal.get();
|
|
44
|
+
return () => {
|
|
45
|
+
watcher.unwatch(signal);
|
|
46
|
+
cleanup?.();
|
|
47
|
+
cleanup = void 0;
|
|
48
|
+
};
|
|
44
49
|
}
|
|
45
50
|
globalThis.__ODX_SHARED_SIGNALS__ ||= {};
|
|
46
|
-
|
|
51
|
+
//#endregion
|
|
47
52
|
export { computed, effect, sharedSignal, signal };
|
package/dist/lib/theming.d.ts
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
|
-
import { ThemeConfig } from
|
|
1
|
+
import { ThemeConfig } from "@odx/design-tokens";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/theming.d.ts
|
|
2
4
|
declare global {
|
|
3
|
-
|
|
5
|
+
var __ODX_THEME_ROOT__: HTMLElement;
|
|
4
6
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
declare const userPrefersDarkMode: boolean;
|
|
8
|
+
declare const darkModeIcon = "core::night-mode";
|
|
9
|
+
declare const lightModeIcon = "core::brightness";
|
|
10
|
+
declare function setTheme$1(config: ThemeConfig, root?: HTMLElement): void;
|
|
11
|
+
declare function isDarkModeEnabled(): boolean;
|
|
12
|
+
declare function toggleDarkMode(enabled?: boolean | 'auto', root?: HTMLElement): void;
|
|
13
|
+
interface AttachDarkModeToggleOptions<T extends HTMLElement> {
|
|
14
|
+
update?(host: T, darkModeEnabled: boolean, icon: string): void;
|
|
15
|
+
root?: HTMLElement;
|
|
14
16
|
}
|
|
15
|
-
|
|
16
|
-
//#
|
|
17
|
+
declare function attachDarkModeToggle<T extends HTMLElement>(host: T, options?: AttachDarkModeToggleOptions<T>): () => void;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { AttachDarkModeToggleOptions, attachDarkModeToggle, darkModeIcon, isDarkModeEnabled, lightModeIcon, setTheme$1 as setTheme, toggleDarkMode, userPrefersDarkMode };
|
package/dist/lib/theming.js
CHANGED
|
@@ -1,37 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { effect, sharedSignal } from "./signals.js";
|
|
2
|
+
import { darkModeClass, lightModeClass, setTheme } from "@odx/design-tokens";
|
|
3
|
+
//#region src/lib/theming.ts
|
|
4
4
|
const { matches: userPrefersDarkMode = false } = globalThis.matchMedia?.("(prefers-color-scheme: dark)") ?? {};
|
|
5
5
|
const darkModeIcon = "core::night-mode";
|
|
6
6
|
const lightModeIcon = "core::brightness";
|
|
7
|
-
globalThis.__ODX_THEME_ROOT__ ??= document.
|
|
7
|
+
globalThis.__ODX_THEME_ROOT__ ??= document.documentElement;
|
|
8
8
|
const hasDarkModeClass = globalThis.__ODX_THEME_ROOT__.classList.contains(darkModeClass);
|
|
9
9
|
const hasLightModeClass = globalThis.__ODX_THEME_ROOT__.classList.contains(lightModeClass);
|
|
10
10
|
const darkModeEnabled = sharedSignal("darkModeEnabled", hasDarkModeClass || hasLightModeClass ? hasDarkModeClass : userPrefersDarkMode);
|
|
11
|
-
function setTheme(config, root = globalThis.__ODX_THEME_ROOT__) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
} else {
|
|
17
|
-
darkModeEnabled.set(config.mode === "dark" ? true : !isDarkModeEnabled());
|
|
18
|
-
}
|
|
11
|
+
function setTheme$1(config, root = globalThis.__ODX_THEME_ROOT__) {
|
|
12
|
+
setTheme(config, root);
|
|
13
|
+
if (!config.mode) return;
|
|
14
|
+
if (config.mode === "auto") darkModeEnabled.set(userPrefersDarkMode);
|
|
15
|
+
else darkModeEnabled.set(config.mode === "dark" ? true : !isDarkModeEnabled());
|
|
19
16
|
}
|
|
20
17
|
function isDarkModeEnabled() {
|
|
21
|
-
|
|
18
|
+
return darkModeEnabled.get();
|
|
22
19
|
}
|
|
23
20
|
function toggleDarkMode(enabled, root = globalThis.__ODX_THEME_ROOT__) {
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
enabled ||= !isDarkModeEnabled();
|
|
22
|
+
setTheme$1({ mode: enabled === "auto" ? enabled : enabled ? "dark" : "light" }, root);
|
|
26
23
|
}
|
|
27
24
|
function attachDarkModeToggle(host, options = {}) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
host.addEventListener("click", () => toggleDarkMode(void 0, options.root));
|
|
26
|
+
return effect(() => {
|
|
27
|
+
const darkModeEnabled = isDarkModeEnabled();
|
|
28
|
+
const icon = darkModeEnabled ? lightModeIcon : darkModeIcon;
|
|
29
|
+
host.setAttribute("icon", icon);
|
|
30
|
+
options.update?.(host, darkModeEnabled, icon);
|
|
31
|
+
});
|
|
35
32
|
}
|
|
36
|
-
|
|
37
|
-
export { attachDarkModeToggle, darkModeIcon, isDarkModeEnabled, lightModeIcon, setTheme, toggleDarkMode, userPrefersDarkMode };
|
|
33
|
+
//#endregion
|
|
34
|
+
export { attachDarkModeToggle, darkModeIcon, isDarkModeEnabled, lightModeIcon, setTheme$1 as setTheme, toggleDarkMode, userPrefersDarkMode };
|
|
@@ -1,43 +1,41 @@
|
|
|
1
|
+
//#region src/lib/utils/shared-media-observer.ts
|
|
1
2
|
const mediaQueryRegistry = /* @__PURE__ */ new Map();
|
|
2
3
|
const eventListenerRegistry = /* @__PURE__ */ new Map();
|
|
3
4
|
function handleMediaChange(event) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
listenersArray[i]?.(event);
|
|
10
|
-
}
|
|
5
|
+
const listeners = eventListenerRegistry.get(event.media);
|
|
6
|
+
if (!listeners?.size) return;
|
|
7
|
+
const listenersArray = Array.from(listeners);
|
|
8
|
+
let i = listenersArray.length;
|
|
9
|
+
while (i--) listenersArray[i]?.(event);
|
|
11
10
|
}
|
|
12
11
|
function observeMedia(query, listener) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return () => unobserveMedia(query, listener);
|
|
12
|
+
let listeners = eventListenerRegistry.get(query);
|
|
13
|
+
if (!listeners) {
|
|
14
|
+
listeners = /* @__PURE__ */ new Set();
|
|
15
|
+
eventListenerRegistry.set(query, listeners);
|
|
16
|
+
}
|
|
17
|
+
listeners.add(listener);
|
|
18
|
+
let mediaQueryList = mediaQueryRegistry.get(query);
|
|
19
|
+
if (!mediaQueryList) {
|
|
20
|
+
mediaQueryList = globalThis.matchMedia(query);
|
|
21
|
+
mediaQueryRegistry.set(query, mediaQueryList);
|
|
22
|
+
mediaQueryList.addEventListener("change", handleMediaChange);
|
|
23
|
+
}
|
|
24
|
+
listener(new MediaQueryListEvent("change", {
|
|
25
|
+
media: mediaQueryList.media,
|
|
26
|
+
matches: mediaQueryList.matches
|
|
27
|
+
}));
|
|
28
|
+
return () => unobserveMedia(query, listener);
|
|
31
29
|
}
|
|
32
30
|
function unobserveMedia(query, listener) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
const listeners = eventListenerRegistry.get(query);
|
|
32
|
+
if (!listeners?.delete(listener)) return;
|
|
33
|
+
if (listeners.size > 0) return;
|
|
34
|
+
eventListenerRegistry.delete(query);
|
|
35
|
+
const mediaQueryList = mediaQueryRegistry.get(query);
|
|
36
|
+
if (!mediaQueryList) return;
|
|
37
|
+
mediaQueryList.removeEventListener("change", handleMediaChange);
|
|
38
|
+
mediaQueryRegistry.delete(query);
|
|
41
39
|
}
|
|
42
|
-
|
|
43
|
-
export { observeMedia
|
|
40
|
+
//#endregion
|
|
41
|
+
export { observeMedia };
|
package/dist/main.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { ReadonlySignal, Signal, SignalOptions, computed, effect, sharedSignal, signal } from "./lib/signals.js";
|
|
2
|
+
import { Breakpoint, BreakpointConfig, BreakpointOperator, breakpointAttribute, buildBreakpoint, createBreakpointUpdater, defaultBreakpoints, expandBreakpoints, observeBreakpoint, registeredBreakpoints, setupBreakpoints } from "./lib/breakpoints.js";
|
|
3
|
+
import { UnitIdentifier } from "./lib/models.js";
|
|
4
|
+
import { DateTimeFormatOptions, FormatOptions, ListFormatOptions, NumberFormatOptions, RelativeTimeFormatOptions, formatDate, formatList, formatNumber, formatRelativeTime, parseDate } from "./lib/format.js";
|
|
5
|
+
import { LocalizationOptions, getLocale, getLocalizationOptions, setLocale, setLocalizationOptions } from "./lib/localization.js";
|
|
6
|
+
import { AttachDarkModeToggleOptions, attachDarkModeToggle, darkModeIcon, isDarkModeEnabled, lightModeIcon, setTheme, toggleDarkMode, userPrefersDarkMode } from "./lib/theming.js";
|
|
7
|
+
export { AttachDarkModeToggleOptions, Breakpoint, BreakpointConfig, BreakpointOperator, DateTimeFormatOptions, FormatOptions, ListFormatOptions, LocalizationOptions, NumberFormatOptions, ReadonlySignal, RelativeTimeFormatOptions, Signal, SignalOptions, type UnitIdentifier, attachDarkModeToggle, breakpointAttribute, buildBreakpoint, computed, createBreakpointUpdater, darkModeIcon, defaultBreakpoints, effect, expandBreakpoints, formatDate, formatList, formatNumber, formatRelativeTime, getLocale, getLocalizationOptions, isDarkModeEnabled, lightModeIcon, observeBreakpoint, parseDate, registeredBreakpoints, setLocale, setLocalizationOptions, setTheme, setupBreakpoints, sharedSignal, signal, toggleDarkMode, userPrefersDarkMode };
|
package/dist/main.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { computed, effect, sharedSignal, signal } from "./lib/signals.js";
|
|
2
|
+
import { breakpointAttribute, buildBreakpoint, createBreakpointUpdater, defaultBreakpoints, expandBreakpoints, observeBreakpoint, registeredBreakpoints, setupBreakpoints } from "./lib/breakpoints.js";
|
|
3
|
+
import { formatDate, formatList, formatNumber, formatRelativeTime, parseDate } from "./lib/format.js";
|
|
4
|
+
import { LocalizationOptions, getLocale, getLocalizationOptions, setLocale, setLocalizationOptions } from "./lib/localization.js";
|
|
5
|
+
import { attachDarkModeToggle, darkModeIcon, isDarkModeEnabled, lightModeIcon, setTheme, toggleDarkMode, userPrefersDarkMode } from "./lib/theming.js";
|
|
6
|
+
export { LocalizationOptions, attachDarkModeToggle, breakpointAttribute, buildBreakpoint, computed, createBreakpointUpdater, darkModeIcon, defaultBreakpoints, effect, expandBreakpoints, formatDate, formatList, formatNumber, formatRelativeTime, getLocale, getLocalizationOptions, isDarkModeEnabled, lightModeIcon, observeBreakpoint, parseDate, registeredBreakpoints, setLocale, setLocalizationOptions, setTheme, setupBreakpoints, sharedSignal, signal, toggleDarkMode, userPrefersDarkMode };
|