@odx/foundation 1.0.0-beta.99 → 1.0.0-rc.0
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 +335 -0
- package/README.md +61 -29
- package/dist/lib/breakpoints.d.ts +61 -0
- package/dist/lib/breakpoints.js +139 -0
- package/dist/lib/format.d.ts +58 -0
- package/dist/lib/format.js +63 -0
- package/dist/lib/localization.d.ts +12 -0
- package/dist/lib/localization.js +28 -0
- package/dist/lib/models.d.ts +39 -0
- package/dist/lib/models.js +34 -0
- package/dist/lib/signals.d.ts +20 -0
- package/dist/lib/signals.js +47 -0
- package/dist/lib/theming.d.ts +18 -0
- package/dist/lib/theming.js +38 -0
- package/dist/lib/utils/breakpoint.d.ts +38 -0
- package/dist/lib/utils/breakpoint.js +103 -0
- package/dist/lib/utils/shared-media-observer.d.ts +4 -0
- package/dist/lib/utils/shared-media-observer.js +43 -0
- package/dist/main.d.ts +7 -0
- package/dist/main.js +5 -1227
- package/dist/oss-licenses.json +1 -0
- package/dist/styles.css +1 -1
- package/package.json +27 -50
- package/dist/_virtual_class-decorator-runtime.js +0 -13
- package/dist/components/accordion/accordion.d.ts +0 -25
- package/dist/components/accordion-item/accordion-item.d.ts +0 -26
- package/dist/components/accordion-panel/accordion-panel.d.ts +0 -13
- package/dist/components/action-button/action-button.d.ts +0 -27
- package/dist/components/anchor-navigation/anchor-navigation.d.ts +0 -21
- package/dist/components/anchor-navigation/anchor-observer.d.ts +0 -11
- package/dist/components/anchor-navigation/index.d.ts +0 -3
- package/dist/components/area-header/area-header.d.ts +0 -21
- package/dist/components/avatar/avatar.d.ts +0 -36
- package/dist/components/avatar-group/avatar-group.d.ts +0 -15
- package/dist/components/badge/badge.d.ts +0 -24
- package/dist/components/breadcrumbs/breadcrumbs-item.d.ts +0 -17
- package/dist/components/breadcrumbs/breadcrumbs.d.ts +0 -21
- package/dist/components/breadcrumbs/index.d.ts +0 -3
- package/dist/components/button/button.d.ts +0 -54
- package/dist/components/button-group/button-group.d.ts +0 -20
- package/dist/components/card/card.d.ts +0 -15
- package/dist/components/checkbox/checkbox.d.ts +0 -14
- package/dist/components/checkbox-group/checkbox-group.d.ts +0 -19
- package/dist/components/chip/chip.d.ts +0 -31
- package/dist/components/circular-progress-bar/circular-progress-bar.d.ts +0 -49
- package/dist/components/combobox/autocomplete.d.ts +0 -23
- package/dist/components/content-box/content-box.d.ts +0 -11
- package/dist/components/dropdown/dropdown.d.ts +0 -25
- package/dist/components/form-field/form-field.d.ts +0 -16
- package/dist/components/format/base-format.d.ts +0 -13
- package/dist/components/format/format-bytes.d.ts +0 -13
- package/dist/components/format/format-date.d.ts +0 -14
- package/dist/components/format/format-number.d.ts +0 -20
- package/dist/components/format/index.d.ts +0 -6
- package/dist/components/format/relative-time.d.ts +0 -21
- package/dist/components/header/header-actions.d.ts +0 -10
- package/dist/components/header/header.d.ts +0 -14
- package/dist/components/header/index.d.ts +0 -3
- package/dist/components/headline/headline.d.ts +0 -22
- package/dist/components/highlight/highlight.d.ts +0 -23
- package/dist/components/icon-button/icon-button.d.ts +0 -14
- package/dist/components/image/image.d.ts +0 -34
- package/dist/components/inline-message/inline-message.d.ts +0 -28
- package/dist/components/input/input.d.ts +0 -27
- package/dist/components/kpi/kpi.d.ts +0 -36
- package/dist/components/line-clamp/line-clamp.d.ts +0 -12
- package/dist/components/link/link.d.ts +0 -11
- package/dist/components/list/list.d.ts +0 -15
- package/dist/components/list-item/list-item.d.ts +0 -26
- package/dist/components/loader.d.ts +0 -2
- package/dist/components/loading-overlay/loading-overlay.d.ts +0 -20
- package/dist/components/loading-spinner/loading-spinner.d.ts +0 -12
- package/dist/components/logo/logo.d.ts +0 -21
- package/dist/components/main-menu/index.d.ts +0 -6
- package/dist/components/main-menu/main-menu-button.d.ts +0 -12
- package/dist/components/main-menu/main-menu-link.d.ts +0 -9
- package/dist/components/main-menu/main-menu-subtitle.d.ts +0 -12
- package/dist/components/main-menu/main-menu-title.d.ts +0 -12
- package/dist/components/main-menu/main-menu.d.ts +0 -17
- package/dist/components/main.d.ts +0 -72
- package/dist/components/menu/index.d.ts +0 -3
- package/dist/components/menu/menu-label.d.ts +0 -9
- package/dist/components/menu/menu.d.ts +0 -21
- package/dist/components/menu-item/menu-item.d.ts +0 -14
- package/dist/components/modal/modal.d.ts +0 -37
- package/dist/components/navigation-item/navigation-item.d.ts +0 -22
- package/dist/components/option/option.d.ts +0 -11
- package/dist/components/page/page.d.ts +0 -27
- package/dist/components/page-layout/page-layout.d.ts +0 -11
- package/dist/components/pagination/pagination.d.ts +0 -32
- package/dist/components/popover/popover-host.d.ts +0 -35
- package/dist/components/popover/popover-observer.d.ts +0 -11
- package/dist/components/popover/popover.d.ts +0 -13
- package/dist/components/progress-bar/progress-bar.d.ts +0 -30
- package/dist/components/radio-button/radio-button.d.ts +0 -13
- package/dist/components/radio-group/radio-group.d.ts +0 -16
- package/dist/components/rail-navigation/rail-navigation.d.ts +0 -19
- package/dist/components/search-bar/index.d.ts +0 -3
- package/dist/components/search-bar/search-bar.d.ts +0 -33
- package/dist/components/search-bar/search-bar.events.d.ts +0 -7
- package/dist/components/select/select.d.ts +0 -26
- package/dist/components/separator/separator.d.ts +0 -21
- package/dist/components/skeleton/skeleton.d.ts +0 -31
- package/dist/components/slider/index.d.ts +0 -5
- package/dist/components/slider/slider-handle.d.ts +0 -28
- package/dist/components/slider/slider-marks.d.ts +0 -16
- package/dist/components/slider/slider.d.ts +0 -26
- package/dist/components/slider/slider.models.d.ts +0 -29
- package/dist/components/spacer/spacer.d.ts +0 -13
- package/dist/components/spinbox/spinbox.d.ts +0 -23
- package/dist/components/stack/stack.d.ts +0 -38
- package/dist/components/status/status.d.ts +0 -23
- package/dist/components/switch/switch.d.ts +0 -12
- package/dist/components/table/index.d.ts +0 -9
- package/dist/components/table/table-body.d.ts +0 -12
- package/dist/components/table/table-cell.d.ts +0 -12
- package/dist/components/table/table-checkbox-cell.d.ts +0 -19
- package/dist/components/table/table-header-cell.d.ts +0 -13
- package/dist/components/table/table-header.d.ts +0 -14
- package/dist/components/table/table-row.d.ts +0 -20
- package/dist/components/table/table.d.ts +0 -20
- package/dist/components/table/table.models.d.ts +0 -10
- package/dist/components/text/text.d.ts +0 -33
- package/dist/components/title/title.d.ts +0 -22
- package/dist/components/toast/toast.d.ts +0 -24
- package/dist/components/toggle-button/toggle-button.d.ts +0 -13
- package/dist/components/toggle-button-group/toggle-button-group.d.ts +0 -10
- package/dist/components/toggle-content/toggle-content.d.ts +0 -12
- package/dist/components/tooltip/tooltip.d.ts +0 -37
- package/dist/components/translate/translate.d.ts +0 -16
- package/dist/components/visually-hidden/visually-hidden.d.ts +0 -11
- package/dist/components.js +0 -4493
- package/dist/i18n/config.d.ts +0 -32
- package/dist/i18n/format.d.ts +0 -6
- package/dist/i18n/is-localized.d.ts +0 -15
- package/dist/i18n/localization.d.ts +0 -5
- package/dist/i18n/main.d.ts +0 -7
- package/dist/i18n/models.d.ts +0 -7
- package/dist/i18n/translate.d.ts +0 -11
- package/dist/i18n.js +0 -145
- package/dist/lib/control/checkbox-form-control.d.ts +0 -16
- package/dist/lib/control/checkbox-group-form-control.d.ts +0 -23
- package/dist/lib/control/form-control.d.ts +0 -30
- package/dist/lib/control/listbox-form-control.d.ts +0 -26
- package/dist/lib/control/number-form-control.d.ts +0 -13
- package/dist/lib/control/option-control.d.ts +0 -24
- package/dist/lib/control/radio-group-form-control.d.ts +0 -22
- package/dist/lib/controllers/active-descendants-controller.d.ts +0 -29
- package/dist/lib/controllers/drag.controller.d.ts +0 -19
- package/dist/lib/controllers/expandable-controller.d.ts +0 -17
- package/dist/lib/custom-element.d.ts +0 -16
- package/dist/lib/interactive/interactive-element.d.ts +0 -23
- package/dist/lib/interactive/interactive-link.d.ts +0 -21
- package/dist/lib/main.d.ts +0 -28
- package/dist/lib/mixins/can-be-disabled.d.ts +0 -7
- package/dist/lib/mixins/can-be-expanded.d.ts +0 -10
- package/dist/lib/mixins/is-draggable.d.ts +0 -16
- package/dist/lib/models/drag-event.d.ts +0 -9
- package/dist/lib/models/placement.d.ts +0 -17
- package/dist/lib/models/shape.d.ts +0 -7
- package/dist/lib/models/size.d.ts +0 -11
- package/dist/lib/models/variant.d.ts +0 -12
- package/dist/lib/utils/compute-popover-placement.d.ts +0 -14
- package/dist/lib/utils/dom.d.ts +0 -27
- package/dist/lib/utils/get-unique-id.d.ts +0 -19
- package/dist/lib/utils/lit.d.ts +0 -4
- package/dist/lib/utils/shared-resize-observer.d.ts +0 -11
- package/dist/lib/utils/types.d.ts +0 -60
- package/dist/loader.js +0 -7
- package/dist/vendor.js +0 -1982
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { UnitIdentifier } from './models.js';
|
|
2
|
+
export interface FormatOptions {
|
|
3
|
+
dateTimeFormatOptions?: DateTimeFormatOptions;
|
|
4
|
+
numberFormatOptions?: NumberFormatOptions;
|
|
5
|
+
listFormatOptions?: ListFormatOptions;
|
|
6
|
+
relativeTimeFormatOptions?: RelativeTimeFormatOptions;
|
|
7
|
+
}
|
|
8
|
+
interface BaseFormatOptions {
|
|
9
|
+
locale?: Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier;
|
|
10
|
+
}
|
|
11
|
+
export interface DateTimeFormatOptions extends Omit<Intl.DateTimeFormatOptions, 'dateStyle'>, BaseFormatOptions {
|
|
12
|
+
dateStyle?: 'iso8601' | Intl.DateTimeFormatOptions['dateStyle'];
|
|
13
|
+
}
|
|
14
|
+
export declare function parseDate(value: number | string | Date): Date | null;
|
|
15
|
+
export declare function formatDate(input: number | string | Date, options?: DateTimeFormatOptions): string;
|
|
16
|
+
export interface NumberFormatOptions extends Intl.NumberFormatOptions, BaseFormatOptions {
|
|
17
|
+
unit?: UnitIdentifier;
|
|
18
|
+
}
|
|
19
|
+
export declare function formatNumber(input: number | string, options?: NumberFormatOptions): string;
|
|
20
|
+
export interface ListFormatOptions extends Intl.ListFormatOptions, BaseFormatOptions {
|
|
21
|
+
}
|
|
22
|
+
export declare function formatList(input: string[], options?: ListFormatOptions): string;
|
|
23
|
+
declare const TIME_UNIT_MAP: {
|
|
24
|
+
readonly second: {
|
|
25
|
+
readonly max: 59000;
|
|
26
|
+
readonly value: 1000;
|
|
27
|
+
};
|
|
28
|
+
readonly minute: {
|
|
29
|
+
readonly max: 2760000;
|
|
30
|
+
readonly value: 60000;
|
|
31
|
+
};
|
|
32
|
+
readonly hour: {
|
|
33
|
+
readonly max: 72000000;
|
|
34
|
+
readonly value: 3600000;
|
|
35
|
+
};
|
|
36
|
+
readonly day: {
|
|
37
|
+
readonly max: 518400000;
|
|
38
|
+
readonly value: 86400000;
|
|
39
|
+
};
|
|
40
|
+
readonly week: {
|
|
41
|
+
readonly max: 2419200000;
|
|
42
|
+
readonly value: 604800000;
|
|
43
|
+
};
|
|
44
|
+
readonly month: {
|
|
45
|
+
readonly max: 28512000000;
|
|
46
|
+
readonly value: 2592000000;
|
|
47
|
+
};
|
|
48
|
+
readonly year: {
|
|
49
|
+
readonly max: number;
|
|
50
|
+
readonly value: 31536000000;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export interface RelativeTimeFormatOptions extends Intl.RelativeTimeFormatOptions, BaseFormatOptions {
|
|
54
|
+
minUnit?: keyof typeof TIME_UNIT_MAP;
|
|
55
|
+
}
|
|
56
|
+
export declare function formatRelativeTime(input: number | string | Date, options?: RelativeTimeFormatOptions): string;
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
function parseDate(value) {
|
|
2
|
+
const createDate = (value2) => Number.isNaN(value2) ? null : new Date(value2);
|
|
3
|
+
if (value instanceof Date) {
|
|
4
|
+
return createDate(value.getTime());
|
|
5
|
+
}
|
|
6
|
+
const date = new Date(value);
|
|
7
|
+
if (Number.isNaN(date.getTime()) && typeof value === "string") {
|
|
8
|
+
return createDate(Number(value));
|
|
9
|
+
}
|
|
10
|
+
return createDate(date.getTime());
|
|
11
|
+
}
|
|
12
|
+
function formatDate(input, options) {
|
|
13
|
+
const value = parseDate(input);
|
|
14
|
+
if (!value) return "";
|
|
15
|
+
if (options?.dateStyle === "iso8601") {
|
|
16
|
+
return new Intl.DateTimeFormat("sv-SE", { dateStyle: "short" }).format(value);
|
|
17
|
+
}
|
|
18
|
+
return new Intl.DateTimeFormat(options?.locale, options).format(value);
|
|
19
|
+
}
|
|
20
|
+
function formatNumber(input, options) {
|
|
21
|
+
const value = Number(input);
|
|
22
|
+
if (Number.isNaN(value)) return "";
|
|
23
|
+
if (options?.currency) {
|
|
24
|
+
options.style = "currency";
|
|
25
|
+
} else if (options?.unit) {
|
|
26
|
+
options.style = "unit";
|
|
27
|
+
}
|
|
28
|
+
return new Intl.NumberFormat(options?.locale, options).format(value);
|
|
29
|
+
}
|
|
30
|
+
function formatList(input, options) {
|
|
31
|
+
if (input.length === 0) return "";
|
|
32
|
+
return new Intl.ListFormat(options?.locale, options).format(input);
|
|
33
|
+
}
|
|
34
|
+
const TIME_UNIT_MAP = {
|
|
35
|
+
second: { max: 59e3, value: 1e3 },
|
|
36
|
+
// max 59 seconds
|
|
37
|
+
minute: { max: 276e4, value: 6e4 },
|
|
38
|
+
// max 46 minutes
|
|
39
|
+
hour: { max: 72e6, value: 36e5 },
|
|
40
|
+
// max 20 hours
|
|
41
|
+
day: { max: 5184e5, value: 864e5 },
|
|
42
|
+
// max 6 days
|
|
43
|
+
week: { max: 24192e5, value: 6048e5 },
|
|
44
|
+
// max 28 days
|
|
45
|
+
month: { max: 28512e6, value: 2592e6 },
|
|
46
|
+
// max 11 months
|
|
47
|
+
year: { max: Number.POSITIVE_INFINITY, value: 31536e6 }
|
|
48
|
+
};
|
|
49
|
+
function formatRelativeTime(input, options) {
|
|
50
|
+
const value = parseDate(input);
|
|
51
|
+
if (!value) return "";
|
|
52
|
+
const relativeTime = value.getTime() - Date.now();
|
|
53
|
+
const minUnit = options?.minUnit && TIME_UNIT_MAP[options.minUnit] || TIME_UNIT_MAP.second;
|
|
54
|
+
const [unit, unitConfig] = Object.entries(TIME_UNIT_MAP).find(
|
|
55
|
+
([_, { value: value2, max }]) => Math.abs(relativeTime) < max && minUnit.value <= value2
|
|
56
|
+
);
|
|
57
|
+
return new Intl.RelativeTimeFormat(options?.locale, options).format(
|
|
58
|
+
Math.round(relativeTime / unitConfig.value),
|
|
59
|
+
unit
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { formatDate, formatList, formatNumber, formatRelativeTime, parseDate };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FormatOptions } from './format.js';
|
|
2
|
+
export interface LocalizationOptions extends FormatOptions {
|
|
3
|
+
defaultLocale: () => Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier;
|
|
4
|
+
fallbackLanguage: () => Intl.UnicodeBCP47LocaleIdentifier;
|
|
5
|
+
fallbackTranslation: (key: string) => string;
|
|
6
|
+
}
|
|
7
|
+
export declare const LocalizationOptions: (config?: Partial<LocalizationOptions>) => LocalizationOptions;
|
|
8
|
+
export declare function setLocalizationOptions(options?: Partial<LocalizationOptions> | null): void;
|
|
9
|
+
export declare function getLocalizationOptions(options?: Partial<LocalizationOptions> | null): LocalizationOptions;
|
|
10
|
+
export declare function getLocale(localeInput?: Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier | null): Intl.Locale;
|
|
11
|
+
export declare function setLocale(localeInput?: Intl.Locale | Intl.UnicodeBCP47LocaleIdentifier | null): void;
|
|
12
|
+
//# sourceMappingURL=localization.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { sharedSignal } from './signals.js';
|
|
2
|
+
|
|
3
|
+
const locale = sharedSignal("locale", null);
|
|
4
|
+
const localizationOptions = sharedSignal("localizationOptions", null);
|
|
5
|
+
const LocalizationOptions = (config) => ({
|
|
6
|
+
defaultLocale: () => navigator.language,
|
|
7
|
+
fallbackLanguage: () => "en",
|
|
8
|
+
fallbackTranslation: (key) => key,
|
|
9
|
+
...config,
|
|
10
|
+
relativeTimeFormatOptions: {
|
|
11
|
+
minUnit: "minute",
|
|
12
|
+
...config?.relativeTimeFormatOptions
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
function setLocalizationOptions(options) {
|
|
16
|
+
localizationOptions.set(getLocalizationOptions(options));
|
|
17
|
+
}
|
|
18
|
+
function getLocalizationOptions(options) {
|
|
19
|
+
return LocalizationOptions(options ?? localizationOptions.get() ?? {});
|
|
20
|
+
}
|
|
21
|
+
function getLocale(localeInput) {
|
|
22
|
+
return new Intl.Locale(localeInput || locale.get() || getLocalizationOptions().defaultLocale());
|
|
23
|
+
}
|
|
24
|
+
function setLocale(localeInput) {
|
|
25
|
+
locale.set(localeInput ? getLocale(localeInput) : null);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { LocalizationOptions, getLocale, getLocalizationOptions, setLocale, setLocalizationOptions };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type Alignment = (typeof Alignment)[keyof typeof Alignment];
|
|
2
|
+
export declare const Alignment: {
|
|
3
|
+
readonly START: "start";
|
|
4
|
+
readonly CENTER: "center";
|
|
5
|
+
readonly END: "end";
|
|
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
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const Alignment = {
|
|
2
|
+
START: "start",
|
|
3
|
+
CENTER: "center",
|
|
4
|
+
END: "end"
|
|
5
|
+
};
|
|
6
|
+
const Spacing = {
|
|
7
|
+
0: "0",
|
|
8
|
+
SM: "sm",
|
|
9
|
+
MD: "md",
|
|
10
|
+
LG: "lg"
|
|
11
|
+
};
|
|
12
|
+
const Justify = {
|
|
13
|
+
START: "start",
|
|
14
|
+
END: "end",
|
|
15
|
+
CENTER: "center",
|
|
16
|
+
SPACE_BETWEEN: "space-between",
|
|
17
|
+
SPACE_AROUND: "space-around",
|
|
18
|
+
SPACE_EVENLY: "space-evenly"
|
|
19
|
+
};
|
|
20
|
+
const Variant = {
|
|
21
|
+
NEUTRAL: "neutral",
|
|
22
|
+
PRIMARY: "primary",
|
|
23
|
+
ACCENT: "accent",
|
|
24
|
+
SUCCESS: "success",
|
|
25
|
+
WARNING: "warning",
|
|
26
|
+
DANGER: "danger",
|
|
27
|
+
ACCENT_GHOST: "accent-ghost",
|
|
28
|
+
DANGER_GHOST: "danger-ghost",
|
|
29
|
+
CONFIRMATION: "confirmation",
|
|
30
|
+
SUBTLE: "subtle",
|
|
31
|
+
GHOST: "ghost"
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { Alignment, Justify, Spacing, Variant };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Signal as NativeSignal } from 'signal-polyfill';
|
|
2
|
+
export type Signal<T> = NativeSignal.State<T> & {
|
|
3
|
+
update: (updateFn: (value: T) => T) => void;
|
|
4
|
+
};
|
|
5
|
+
export type SignalOptions<T> = NativeSignal.Options<T> & {
|
|
6
|
+
watched?(): void;
|
|
7
|
+
unwatched?(): void;
|
|
8
|
+
};
|
|
9
|
+
export type ReadonlySignal<T> = NativeSignal.Computed<T>;
|
|
10
|
+
export declare function signal<T>(value: T, options?: SignalOptions<T>): Signal<T>;
|
|
11
|
+
/**
|
|
12
|
+
* 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
|
+
*/
|
|
14
|
+
export declare function sharedSignal<T>(key: string, ...args: Parameters<typeof signal<T>>): ReturnType<typeof signal<T>>;
|
|
15
|
+
export declare function computed<T>(computeFn: () => T, options?: SignalOptions<T>): ReadonlySignal<T>;
|
|
16
|
+
export declare function effect(callback: (() => void) | (() => () => void)): () => void;
|
|
17
|
+
declare global {
|
|
18
|
+
var __ODX_SHARED_SIGNALS__: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=signals.d.ts.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Signal } from 'signal-polyfill';
|
|
2
|
+
|
|
3
|
+
function transformOptions(options) {
|
|
4
|
+
if (!options) return;
|
|
5
|
+
return { equals: options.equals, [Signal.subtle.watched]: options.watched, [Signal.subtle.unwatched]: options.unwatched };
|
|
6
|
+
}
|
|
7
|
+
function signal(value, options) {
|
|
8
|
+
const state = new Signal.State(value, transformOptions(options));
|
|
9
|
+
state.update = (updateFn) => state.set(updateFn(state.get()));
|
|
10
|
+
return state;
|
|
11
|
+
}
|
|
12
|
+
function sharedSignal(key, ...args) {
|
|
13
|
+
if (!(key in globalThis.__ODX_SHARED_SIGNALS__)) {
|
|
14
|
+
globalThis.__ODX_SHARED_SIGNALS__[key] = signal(...args);
|
|
15
|
+
}
|
|
16
|
+
return globalThis.__ODX_SHARED_SIGNALS__[key];
|
|
17
|
+
}
|
|
18
|
+
function computed(computeFn, options) {
|
|
19
|
+
return new Signal.Computed(computeFn, transformOptions(options));
|
|
20
|
+
}
|
|
21
|
+
let needsEnqueue = true;
|
|
22
|
+
const watcher = new Signal.subtle.Watcher(() => {
|
|
23
|
+
if (!needsEnqueue) return;
|
|
24
|
+
needsEnqueue = false;
|
|
25
|
+
queueMicrotask(() => {
|
|
26
|
+
needsEnqueue = true;
|
|
27
|
+
for (const signal2 of watcher.getPending()) signal2.get();
|
|
28
|
+
watcher.watch();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
function effect(callback) {
|
|
32
|
+
let cleanup;
|
|
33
|
+
const signal2 = computed(() => {
|
|
34
|
+
cleanup?.();
|
|
35
|
+
cleanup = callback() || void 0;
|
|
36
|
+
});
|
|
37
|
+
watcher.watch(signal2);
|
|
38
|
+
signal2.get();
|
|
39
|
+
return () => {
|
|
40
|
+
watcher.unwatch(signal2);
|
|
41
|
+
cleanup?.();
|
|
42
|
+
cleanup = void 0;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
globalThis.__ODX_SHARED_SIGNALS__ ||= {};
|
|
46
|
+
|
|
47
|
+
export { computed, effect, sharedSignal, signal };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ThemeConfig } from '@odx/design-tokens';
|
|
2
|
+
import { ReadonlySignal } from './signals.js';
|
|
3
|
+
declare global {
|
|
4
|
+
var odxDarkModeEnabled: ReadonlySignal<boolean> | undefined;
|
|
5
|
+
var __ODX_THEME_ROOT__: HTMLElement;
|
|
6
|
+
}
|
|
7
|
+
export declare const userPrefersDarkMode: boolean;
|
|
8
|
+
export declare const darkModeIcon = "core::night-mode";
|
|
9
|
+
export declare const lightModeIcon = "core::brightness";
|
|
10
|
+
export declare function setTheme(config: ThemeConfig, root?: HTMLElement): void;
|
|
11
|
+
export declare function isDarkModeEnabled(): boolean;
|
|
12
|
+
export declare function toggleDarkMode(enabled?: boolean | 'auto', root?: HTMLElement): void;
|
|
13
|
+
export interface AttachDarkModeToggleOptions<T extends HTMLElement> {
|
|
14
|
+
update?(host: T, darkModeEnabled: boolean, icon: string): void;
|
|
15
|
+
root?: HTMLElement;
|
|
16
|
+
}
|
|
17
|
+
export declare function attachDarkModeToggle<T extends HTMLElement>(host: T, options?: AttachDarkModeToggleOptions<T>): () => void;
|
|
18
|
+
//# sourceMappingURL=theming.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { darkModeClass, lightModeClass, setTheme as setTheme$1 } from '@odx/design-tokens';
|
|
2
|
+
import { sharedSignal, effect } from './signals.js';
|
|
3
|
+
|
|
4
|
+
const { matches: userPrefersDarkMode = false } = globalThis.matchMedia?.("(prefers-color-scheme: dark)") ?? {};
|
|
5
|
+
const darkModeIcon = "core::night-mode";
|
|
6
|
+
const lightModeIcon = "core::brightness";
|
|
7
|
+
const hasDarkModeClass = document.documentElement.classList.contains(darkModeClass);
|
|
8
|
+
const hasLightModeClass = document.documentElement.classList.contains(lightModeClass);
|
|
9
|
+
const darkModeEnabled = sharedSignal("darkModeEnabled", hasDarkModeClass || hasLightModeClass ? hasDarkModeClass : userPrefersDarkMode);
|
|
10
|
+
globalThis.__ODX_THEME_ROOT__ ??= document.documentElement;
|
|
11
|
+
function setTheme(config, root = globalThis.__ODX_THEME_ROOT__) {
|
|
12
|
+
setTheme$1(config, root);
|
|
13
|
+
if (config.mode === "auto") {
|
|
14
|
+
darkModeEnabled.set(userPrefersDarkMode);
|
|
15
|
+
} else {
|
|
16
|
+
darkModeEnabled.set(config.mode === "dark" ? true : !isDarkModeEnabled());
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function isDarkModeEnabled() {
|
|
20
|
+
return darkModeEnabled.get();
|
|
21
|
+
}
|
|
22
|
+
function toggleDarkMode(enabled, root = globalThis.__ODX_THEME_ROOT__) {
|
|
23
|
+
if (enabled === "auto") {
|
|
24
|
+
setTheme({ mode: enabled }, root);
|
|
25
|
+
} else {
|
|
26
|
+
setTheme({ mode: enabled ? "dark" : "light" }, root);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function attachDarkModeToggle(host, options = {}) {
|
|
30
|
+
host.addEventListener("click", () => toggleDarkMode(void 0, options.root));
|
|
31
|
+
return effect(() => {
|
|
32
|
+
const darkModeEnabled2 = isDarkModeEnabled();
|
|
33
|
+
host.setAttribute("icon", darkModeEnabled2 ? darkModeIcon : lightModeIcon);
|
|
34
|
+
options.update?.(host, darkModeEnabled2, darkModeEnabled2 ? darkModeIcon : lightModeIcon);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { attachDarkModeToggle, darkModeIcon, isDarkModeEnabled, lightModeIcon, setTheme, toggleDarkMode, userPrefersDarkMode };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Signal } from '../signals.js';
|
|
2
|
+
declare global {
|
|
3
|
+
namespace ODX.Breakpoints {
|
|
4
|
+
interface Config {
|
|
5
|
+
sm: true;
|
|
6
|
+
md: true;
|
|
7
|
+
lg: true;
|
|
8
|
+
xl: true;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
type FilteredKeys<T extends object> = {
|
|
13
|
+
[K in keyof T as T[K] extends true ? K : never]: T[K];
|
|
14
|
+
};
|
|
15
|
+
export type BreakpointOperator = '<' | '<=' | '>=' | '>';
|
|
16
|
+
export interface BreakpointConfig {
|
|
17
|
+
name: keyof FilteredKeys<ODX.Breakpoints.Config>;
|
|
18
|
+
min: number;
|
|
19
|
+
max: number;
|
|
20
|
+
customQuery?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface Breakpoint extends BreakpointConfig {
|
|
23
|
+
id: BreakpointConfig['name'] | `${BreakpointOperator}${BreakpointConfig['name']}`;
|
|
24
|
+
query: string;
|
|
25
|
+
operator?: BreakpointOperator;
|
|
26
|
+
}
|
|
27
|
+
export declare const registeredBreakpoints: ReadonlyMap<Breakpoint['id'], Breakpoint>;
|
|
28
|
+
export declare const breakpointAttribute = "odx-breakpoint";
|
|
29
|
+
export declare function buildBreakpoint(breakpoint: BreakpointConfig, operator?: BreakpointOperator): Breakpoint;
|
|
30
|
+
export declare function expandBreakpoints(...breakpoints: BreakpointConfig[]): Breakpoint[];
|
|
31
|
+
export declare function observeBreakpoint(id: Breakpoint['id'], initialValue?: boolean): Signal<Breakpoint & {
|
|
32
|
+
matches: boolean;
|
|
33
|
+
}>;
|
|
34
|
+
export declare function createBreakpointUpdater(breakpoints: Breakpoint[], update?: (target: HTMLElement, change: Breakpoint & {
|
|
35
|
+
matches: boolean;
|
|
36
|
+
}) => void): () => void;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=breakpoint.d.ts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { signal } from '../signals.js';
|
|
2
|
+
import { observeMedia } from './shared-media-observer.js';
|
|
3
|
+
|
|
4
|
+
const operators = ["<", "<=", ">=", ">"];
|
|
5
|
+
const registeredBreakpoints = /* @__PURE__ */ new Map();
|
|
6
|
+
const breakpointAttribute = "odx-breakpoint";
|
|
7
|
+
function buildBreakpoint(breakpoint, operator) {
|
|
8
|
+
const id = operator ? `${operator}${breakpoint.name}` : breakpoint.name;
|
|
9
|
+
let query = `(min-width: ${breakpoint.min}px) and (max-width: ${breakpoint.max}px)`;
|
|
10
|
+
switch (operator) {
|
|
11
|
+
case "<":
|
|
12
|
+
query = `(max-width: ${breakpoint.min - 0.02}px)`;
|
|
13
|
+
break;
|
|
14
|
+
case "<=":
|
|
15
|
+
query = `(max-width: ${breakpoint.max}px)`;
|
|
16
|
+
break;
|
|
17
|
+
case ">=":
|
|
18
|
+
query = `(min-width: ${breakpoint.min}px)`;
|
|
19
|
+
break;
|
|
20
|
+
case ">":
|
|
21
|
+
query = `(min-width: ${breakpoint.max + 0.02}px)`;
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
return { ...breakpoint, id, operator, query: [query, breakpoint.customQuery].filter(Boolean).join(" and ") };
|
|
25
|
+
}
|
|
26
|
+
function expandBreakpoints(...breakpoints) {
|
|
27
|
+
return breakpoints.flatMap((breakpoint) => [void 0, ...operators].map((operator) => buildBreakpoint(breakpoint, operator)));
|
|
28
|
+
}
|
|
29
|
+
function observeBreakpoint(id, initialValue = false) {
|
|
30
|
+
const breakpoint = registeredBreakpoints.get(id);
|
|
31
|
+
let unobserveMedia;
|
|
32
|
+
const state = signal(
|
|
33
|
+
{ ...breakpoint, matches: initialValue },
|
|
34
|
+
{
|
|
35
|
+
watched() {
|
|
36
|
+
if (!breakpoint) return;
|
|
37
|
+
unobserveMedia = observeMedia(breakpoint.query, ({ matches }) => {
|
|
38
|
+
state.set({ ...breakpoint, matches });
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
unwatched() {
|
|
42
|
+
unobserveMedia?.();
|
|
43
|
+
unobserveMedia = void 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
return state;
|
|
48
|
+
}
|
|
49
|
+
function createBreakpointUpdater(breakpoints, update) {
|
|
50
|
+
for (const breakpoint of breakpoints) {
|
|
51
|
+
registeredBreakpoints.set(breakpoint.id, breakpoint);
|
|
52
|
+
}
|
|
53
|
+
const breakpointCache = /* @__PURE__ */ new WeakMap();
|
|
54
|
+
const breakpointObservers = breakpoints.map((breakpoint) => observeBreakpoint(breakpoint.id, false));
|
|
55
|
+
return () => {
|
|
56
|
+
const elements = document.querySelectorAll(`[${breakpointAttribute}]`);
|
|
57
|
+
const changes = breakpointObservers.reduce(
|
|
58
|
+
(breakpoints2, breakpoint) => {
|
|
59
|
+
breakpoints2[breakpoint.get().id] = breakpoint.get();
|
|
60
|
+
return breakpoints2;
|
|
61
|
+
},
|
|
62
|
+
{}
|
|
63
|
+
);
|
|
64
|
+
let i = elements.length;
|
|
65
|
+
while (i--) {
|
|
66
|
+
const element = elements[i];
|
|
67
|
+
const change = changes[element.getAttribute(breakpointAttribute) || ""];
|
|
68
|
+
if (!change || change.matches === breakpointCache.get(element)) continue;
|
|
69
|
+
breakpointCache.set(element, change.matches);
|
|
70
|
+
updateHostElement(element, change.matches);
|
|
71
|
+
update?.(element, change);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function updateHostElement(host, active) {
|
|
76
|
+
const attributeName = "data-odx-breakpoint-slot";
|
|
77
|
+
const classNames = host.getAttribute("odx-breakpoint-class");
|
|
78
|
+
if (classNames) {
|
|
79
|
+
for (const className of classNames.split(" ")) {
|
|
80
|
+
host.classList.toggle(className, active);
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
host.hidden = !active;
|
|
85
|
+
let initialSlot = host.getAttribute(attributeName);
|
|
86
|
+
if (initialSlot == null) {
|
|
87
|
+
initialSlot = host.slot;
|
|
88
|
+
host.setAttribute(attributeName, initialSlot);
|
|
89
|
+
}
|
|
90
|
+
if (active) {
|
|
91
|
+
host.removeAttribute(attributeName);
|
|
92
|
+
if (initialSlot === "") {
|
|
93
|
+
host.removeAttribute("slot");
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
host.slot = "";
|
|
97
|
+
host.slot = initialSlot;
|
|
98
|
+
} else {
|
|
99
|
+
host.slot = "_odx_breakpoint_hidden";
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { breakpointAttribute, buildBreakpoint, createBreakpointUpdater, expandBreakpoints, observeBreakpoint, registeredBreakpoints };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type MediaObserverEventListener = (event: MediaQueryListEvent) => void;
|
|
2
|
+
export declare function observeMedia(query: string, listener: MediaObserverEventListener): () => void;
|
|
3
|
+
export declare function unobserveMedia(query: string, listener: MediaObserverEventListener): void;
|
|
4
|
+
//# sourceMappingURL=shared-media-observer.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const mediaQueryRegistry = /* @__PURE__ */ new Map();
|
|
2
|
+
const eventListenerRegistry = /* @__PURE__ */ new Map();
|
|
3
|
+
function handleMediaChange(event) {
|
|
4
|
+
const listeners = eventListenerRegistry.get(event.media);
|
|
5
|
+
if (!listeners?.size) return;
|
|
6
|
+
const listenersArray = Array.from(listeners);
|
|
7
|
+
let i = listenersArray.length;
|
|
8
|
+
while (i--) {
|
|
9
|
+
listenersArray[i]?.(event);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function observeMedia(query, listener) {
|
|
13
|
+
let listeners = eventListenerRegistry.get(query);
|
|
14
|
+
if (!listeners) {
|
|
15
|
+
listeners = /* @__PURE__ */ new Set();
|
|
16
|
+
eventListenerRegistry.set(query, listeners);
|
|
17
|
+
}
|
|
18
|
+
listeners.add(listener);
|
|
19
|
+
let mediaQueryList = mediaQueryRegistry.get(query);
|
|
20
|
+
if (!mediaQueryList) {
|
|
21
|
+
mediaQueryList = globalThis.matchMedia(query);
|
|
22
|
+
mediaQueryRegistry.set(query, mediaQueryList);
|
|
23
|
+
mediaQueryList.addEventListener("change", handleMediaChange);
|
|
24
|
+
}
|
|
25
|
+
const initialEvent = new MediaQueryListEvent("change", {
|
|
26
|
+
media: mediaQueryList.media,
|
|
27
|
+
matches: mediaQueryList.matches
|
|
28
|
+
});
|
|
29
|
+
listener(initialEvent);
|
|
30
|
+
return () => unobserveMedia(query, listener);
|
|
31
|
+
}
|
|
32
|
+
function unobserveMedia(query, listener) {
|
|
33
|
+
const listeners = eventListenerRegistry.get(query);
|
|
34
|
+
if (!listeners?.delete(listener)) return;
|
|
35
|
+
if (listeners.size > 0) return;
|
|
36
|
+
eventListenerRegistry.delete(query);
|
|
37
|
+
const mediaQueryList = mediaQueryRegistry.get(query);
|
|
38
|
+
if (!mediaQueryList) return;
|
|
39
|
+
mediaQueryList.removeEventListener("change", handleMediaChange);
|
|
40
|
+
mediaQueryRegistry.delete(query);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { observeMedia, unobserveMedia };
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './lib/breakpoints.js';
|
|
2
|
+
export * from './lib/format.js';
|
|
3
|
+
export * from './lib/localization.js';
|
|
4
|
+
export type { UnitIdentifier } from './lib/models.js';
|
|
5
|
+
export * from './lib/signals.js';
|
|
6
|
+
export * from './lib/theming.js';
|
|
7
|
+
//# sourceMappingURL=main.d.ts.map
|