@odx/foundation 1.0.0-beta.234 → 1.0.0-beta.236

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.
@@ -16,7 +16,7 @@ export declare const defaultBreakpoints: {
16
16
  readonly max: 1199.98;
17
17
  };
18
18
  };
19
- export default function setupBreakpoints(breakpointsConfig?: BreakpointConfig[], root?: HTMLElement): () => void;
19
+ export default function setupBreakpoints(breakpointsConfig?: BreakpointConfig[]): () => void;
20
20
  export * from './models.js';
21
21
  export * from './plugins.js';
22
22
  export * from './utils.js';
@@ -1,10 +1,10 @@
1
1
  import { Signal } from '@preact/signals-core';
2
- import { Breakpoint, BreakpointChange, BreakpointConfig, BreakpointOperator, BreakpointPlugin } from './models.js';
2
+ import { Breakpoint, BreakpointChange, BreakpointConfig, BreakpointOperator } from './models.js';
3
3
  export declare const breakpointDirective: import('../utils/main.js').StringAttributeDirective<"odx-breakpoint">;
4
4
  export declare function buildBreakpoint(breakpoint: BreakpointConfig, operator?: BreakpointOperator): Breakpoint;
5
- export declare function createBreakpointHandler(plugins: BreakpointPlugin[], targets: HTMLElement[]): (change: BreakpointChange) => void;
6
- export declare function expandBreakpoints(...breakpoints: BreakpointConfig[]): Record<string, Breakpoint>;
5
+ export declare function expandBreakpoints(...breakpoints: BreakpointConfig[]): Breakpoint[];
7
6
  export declare function observeBreakpoint(breakpoint: Breakpoint, initialValue?: boolean): Signal<Breakpoint & {
8
7
  matches: boolean;
9
8
  }>;
9
+ export declare function createBreakpointDirectiveUpdater(breakpoints: Breakpoint[], update: (target: HTMLElement, change: BreakpointChange) => void): () => void;
10
10
  //# sourceMappingURL=utils.d.ts.map
@@ -1,6 +1,5 @@
1
+ import { signal, effect } from '@preact/signals-core';
1
2
  import { stringAttributeDirective, observeMedia } from '@odx/foundation/utils';
2
- import { signal } from '@preact/signals-core';
3
- import { k as keyBy, g as groupBy } from './vendor.js';
4
3
 
5
4
  const BreakpointHideTargetPlugin = (target, change) => {
6
5
  target.hidden = !change.matches;
@@ -34,23 +33,10 @@ function buildBreakpoint(breakpoint, operator) {
34
33
  query = `(min-width: ${breakpoint.max + 0.02}px)`;
35
34
  break;
36
35
  }
37
- query = [query, breakpoint.customQuery].filter(Boolean).join(" and ");
38
- return { ...breakpoint, id, operator, query };
39
- }
40
- function createBreakpointHandler(plugins, targets) {
41
- return (change) => {
42
- for (const plugin of plugins) {
43
- for (const target of targets) {
44
- plugin(target, change);
45
- }
46
- }
47
- };
36
+ return { ...breakpoint, id, operator, query: [query, breakpoint.customQuery].filter(Boolean).join(" and ") };
48
37
  }
49
38
  function expandBreakpoints(...breakpoints) {
50
- const expandBreakpoints2 = breakpoints.flatMap(
51
- (breakpoint) => [void 0, ...operators].map((operator) => buildBreakpoint(breakpoint, operator))
52
- );
53
- return keyBy(expandBreakpoints2, (breakpoint) => breakpoint.id);
39
+ return breakpoints.flatMap((breakpoint) => [void 0, ...operators].map((operator) => buildBreakpoint(breakpoint, operator)));
54
40
  }
55
41
  function observeBreakpoint(breakpoint, initialValue = false) {
56
42
  let unobserveMedia;
@@ -68,38 +54,61 @@ function observeBreakpoint(breakpoint, initialValue = false) {
68
54
  }
69
55
  );
70
56
  }
71
-
72
- function unsubscribeAll(subscriptions) {
73
- for (const unsubscribe of subscriptions) {
74
- unsubscribe();
75
- subscriptions.delete(unsubscribe);
76
- }
57
+ function createBreakpointDirectiveUpdater(breakpoints, update) {
58
+ const breakpointObservers = breakpoints.map((breakpoint) => observeBreakpoint(breakpoint));
59
+ return () => {
60
+ const results = breakpointObservers.reduce(
61
+ (breakpoints2, { value }) => {
62
+ breakpoints2[value.id] = value;
63
+ return breakpoints2;
64
+ },
65
+ {}
66
+ );
67
+ const directives = document.querySelectorAll(breakpointDirective.selector);
68
+ let i = directives.length;
69
+ while (i--) {
70
+ const directive = directives[i];
71
+ const result = results[breakpointDirective.value(directive) ?? ""];
72
+ if (!result) continue;
73
+ update(directive, result);
74
+ }
75
+ };
77
76
  }
77
+
78
78
  const defaultBreakpoints = {
79
79
  mobile: { id: "mobile", min: 0, max: 575.98 },
80
80
  tablet: { id: "tablet", min: 576, max: 991.98 },
81
81
  desktop: { id: "desktop", min: 992, max: 1199.98 }
82
82
  };
83
- function setupBreakpoints(breakpointsConfig = [], root = document.documentElement) {
83
+ function setupBreakpoints(breakpointsConfig = []) {
84
84
  const breakpoints = expandBreakpoints(...Object.values(defaultBreakpoints), ...breakpointsConfig);
85
85
  const plugins = [BreakpointHideTargetPlugin, BreakpointClassNamePlugin];
86
- const subscriptions = /* @__PURE__ */ new Set();
87
- const observer = new MutationObserver((mutations) => {
88
- if (mutations.length === 0) return;
89
- const breakpointDirectives = Array.from(document.querySelectorAll(breakpointDirective.selector));
90
- unsubscribeAll(subscriptions);
91
- const breakpointTargets = groupBy(breakpointDirectives, (host) => breakpointDirective.value(host) ?? "");
92
- for (const [breakpointId, targets] of Object.entries(breakpointTargets)) {
93
- const breakpoint = breakpoints[breakpointId];
94
- if (!breakpoint) continue;
95
- subscriptions.add(observeBreakpoint(breakpoint).subscribe(createBreakpointHandler(plugins, targets)));
86
+ const directiveUpdater = createBreakpointDirectiveUpdater(breakpoints, (target, change) => {
87
+ for (const plugin of plugins) {
88
+ plugin(target, change);
96
89
  }
97
90
  });
98
- observer.observe(root, { subtree: true, childList: true, attributes: true, attributeFilter: [breakpointDirective.attribute] });
99
- return () => {
100
- unsubscribeAll(subscriptions);
101
- observer.disconnect();
91
+ let mutationObserver;
92
+ let unobserveBreakpoints = () => {
102
93
  };
94
+ function initBreakpoints() {
95
+ destroyBreakpoints();
96
+ mutationObserver = new MutationObserver(directiveUpdater);
97
+ unobserveBreakpoints = effect(directiveUpdater);
98
+ mutationObserver.observe(document.documentElement, {
99
+ attributes: true,
100
+ subtree: true,
101
+ childList: true,
102
+ attributeFilter: [breakpointDirective.attribute]
103
+ });
104
+ }
105
+ function destroyBreakpoints() {
106
+ unobserveBreakpoints();
107
+ mutationObserver?.disconnect();
108
+ globalThis.removeEventListener("DOMContentLoaded", initBreakpoints);
109
+ }
110
+ globalThis.addEventListener("DOMContentLoaded", initBreakpoints);
111
+ return destroyBreakpoints;
103
112
  }
104
113
 
105
- export { BreakpointClassNamePlugin, BreakpointHideTargetPlugin, breakpointDirective, buildBreakpoint, createBreakpointHandler, setupBreakpoints as default, defaultBreakpoints, expandBreakpoints, observeBreakpoint };
114
+ export { BreakpointClassNamePlugin, BreakpointHideTargetPlugin, breakpointDirective, buildBreakpoint, createBreakpointDirectiveUpdater, setupBreakpoints as default, defaultBreakpoints, expandBreakpoints, observeBreakpoint };
@@ -1,9 +1,9 @@
1
1
  import { _ as __decorateClass } from './_virtual_class-decorator-runtime.js';
2
2
  import { CustomElement, customElement, CanBeExpanded, InteractiveControlElement, Alignment, ControlSize, ExpandableItemManager, Size, Variant, LinkControlElement, activeDirective, CanBeDisabled, Placement, OptionControl, ControlElement, OptionType, FormAssociated, ActiveDescendantsController, Shape, CheckboxControl, CheckboxControlGroup, DialogElement, WithPresets, RadioGroupControl, CanBeCollapsed, ListboxControl, IsDraggable, NumberFormControl, dragActiveDirective, DragController } from '@odx/foundation';
3
- import { getUniqueId, toAriaBooleanAttribute, getAssignedElements, booleanAttributeDirective, optionalAttr, interactionResponse, getElementFromEvent, observeElementResize, unobserveElementResize, toPx, enableMotion, findClosestDocument, commandDirective, addGlobalEventListener, waitForAnimations, removeGlobalEventListener, getKeyInfo, clickedOutside, setFocusable, optionalSlot, parseDate, supportsHover, forwardEvent, isToggleOpen } from '@odx/foundation/utils';
3
+ import { getUniqueId, toAriaBooleanAttribute, getAssignedElements, booleanAttributeDirective, optionalAttr, interactionResponse, getElementFromEvent, observeElementResize, unobserveElementResize, toPx, enableMotion, findClosestDocument, commandDirective, addGlobalEventListener, waitForAnimations, removeGlobalEventListener, getKeyInfo, clickedOutside, setFocusable, optionalSlot, parseDate, supportsHover, forwardEvent } from '@odx/foundation/utils';
4
4
  import { html, isServer, unsafeCSS, css, nothing } from 'lit';
5
5
  import { property, query, state } from 'lit/decorators.js';
6
- import { p as pick, R as RovingTabindexController, e, c as computePosition, o as offset, s as shift, f as flip, a as size, b as arrow, h as hide, d as autoUpdate, t as throttle, r as round, i as debounce } from './vendor.js';
6
+ import { p as pick, R as RovingTabindexController, e, c as computePosition, o as offset, s as shift, f as flip, a as size, b as arrow, h as hide, d as autoUpdate, r as round, g as debounce } from './vendor.js';
7
7
  import { when } from 'lit/directives/when.js';
8
8
  import { OdxIconElement } from '@odx/icons';
9
9
  import { IsLocalized } from '@odx/foundation/i18n';
@@ -948,7 +948,9 @@ const _PopoverHost = class _PopoverHost extends CanBeDisabled(CustomElement) {
948
948
  this.#handleReferenceKeydown = (event) => {
949
949
  const shouldHide = this.hasOpenPopover(this.referenceElement) && getKeyInfo(event).escape;
950
950
  if (event.defaultPrevented || !shouldHide) return;
951
+ event.preventDefault();
951
952
  event.stopPropagation();
953
+ this.hidePopover();
952
954
  };
953
955
  if (!isServer) {
954
956
  this.addEventListener("toggle", this.#handleToggle);
@@ -1015,10 +1017,7 @@ const _PopoverHost = class _PopoverHost extends CanBeDisabled(CustomElement) {
1015
1017
  this.#positionUpdater = autoUpdate(
1016
1018
  this.referenceElement,
1017
1019
  this,
1018
- throttle(
1019
- () => this.referenceElement && computePopoverPlacement(this.referenceElement, this, this.popoverPlacementOptions),
1020
- 1e3 / this.fpsLimit
1021
- )
1020
+ () => this.referenceElement && computePopoverPlacement(this.referenceElement, this, this.popoverPlacementOptions)
1022
1021
  );
1023
1022
  }
1024
1023
  hidePopover() {
@@ -1264,7 +1263,7 @@ __decorateClass([
1264
1263
  ], _OdxHighlight.prototype, "variant", 2);
1265
1264
  let OdxHighlight = _OdxHighlight;
1266
1265
 
1267
- const styles$15 = "@layer base{:host{content-visibility:auto}odx-checkbox{padding:0}.label{flex:auto}.indicator{--size:var(--odx-control-addon-size-sm);margin-inline:var(--odx-spacing-12)}:host(:focus-visible){outline:var(--odx-focus-ring-outer);outline-offset:var(--odx-focus-ring-offset)}}@layer state{:host([readonly]){pointer-events:none}:host([odx-active]:not([readonly])){--_color-background:var(--odx-color-background-transparent-pressed)}:host([selected]){--_color-background:var(--odx-color-background-transparent-selected);--_color-background-hover:var(--odx-color-background-transparent-selected-hover);--_color-background-pressed:var(--odx-color-background-transparent-selected-hover)}:host([selected][odx-active]:not([readonly])){--_color-background:var(--odx-color-background-transparent-selected-hover)}}";
1266
+ const styles$15 = "@layer base{:host{content-visibility:auto;contain:size}odx-checkbox{padding:0}.label{flex:auto}.indicator{--size:var(--odx-control-addon-size-sm);margin-inline:var(--odx-spacing-12)}:host(:focus-visible){outline:var(--odx-focus-ring-outer);outline-offset:var(--odx-focus-ring-offset)}}@layer state{:host([readonly]){pointer-events:none}:host([odx-active]:not([readonly])){--_color-background:var(--odx-color-background-transparent-pressed)}:host([selected]){--_color-background:var(--odx-color-background-transparent-selected);--_color-background-hover:var(--odx-color-background-transparent-selected-hover);--_color-background-pressed:var(--odx-color-background-transparent-selected-hover)}:host([selected][odx-active]:not([readonly])){--_color-background:var(--odx-color-background-transparent-selected-hover)}}";
1268
1267
 
1269
1268
  class OdxOption extends OptionControl(ControlElement) {
1270
1269
  static {
@@ -1293,7 +1292,7 @@ const _OdxAutocomplete = class _OdxAutocomplete extends FormAssociated(CustomEle
1293
1292
  this.activeDescendants = new ActiveDescendantsController(this, {
1294
1293
  getItems: () => this.options,
1295
1294
  onChange: (_, option, firstChange) => {
1296
- option?.scrollIntoView();
1295
+ option?.scrollIntoView({ block: "nearest", behavior: "instant" });
1297
1296
  if (!option || firstChange || option.selected) return;
1298
1297
  option?.activate();
1299
1298
  }
@@ -3642,11 +3641,7 @@ const _OdxSelect = class _OdxSelect extends ListboxControl {
3642
3641
  this.requestUpdate("value");
3643
3642
  };
3644
3643
  this.#handleDropdownToggle = (event) => {
3645
- this.dropdownOpen = isToggleOpen(event);
3646
- if (!isToggleOpen(event)) return;
3647
- const [selectedOption] = this.getSelectedOptions();
3648
- if (!selectedOption) return;
3649
- selectedOption.scrollIntoView({ behavior: "instant" });
3644
+ this.dropdownOpen = event.newState === "open";
3650
3645
  };
3651
3646
  this.#handleBlur = () => {
3652
3647
  this.dropdown.hidePopover();
package/dist/i18n.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { signal, computed } from '@preact/signals-core';
2
- import { j as flattenObject, e } from './vendor.js';
2
+ import { i as flattenObject, e } from './vendor.js';
3
3
  import { parseDate } from '@odx/foundation/utils';
4
4
  import { _ as __decorateClass } from './_virtual_class-decorator-runtime.js';
5
5
  import 'lit/html.js';
package/dist/main.js CHANGED
@@ -589,7 +589,9 @@ class ListboxControl extends FormAssociated(
589
589
  this.activeDescendants = new ActiveDescendantsController(this, {
590
590
  getItems: () => this.getOptions(),
591
591
  onChange: (_, option) => {
592
- const canAutoSelect = this.autoSelect && !this.multiple && option && !option.selected && this.canSelect(option);
592
+ if (!option) return;
593
+ const canAutoSelect = this.autoSelect && !this.multiple && !option.selected && this.canSelect(option);
594
+ option.scrollIntoView({ block: "nearest", behavior: "instant" });
593
595
  if (!canAutoSelect) return;
594
596
  this.toggleOption(option, true);
595
597
  }
@@ -29,7 +29,6 @@ export declare function createCustomEvent<Payload = never, const T extends strin
29
29
  dispatch(target: HTMLElement, eventInit?: CustomEventInit<Payload>): boolean;
30
30
  };
31
31
  export declare function createToggleEvent(oldState: boolean, newState: boolean, eventInit?: EventInit): ToggleEvent;
32
- export declare function isToggleOpen(event: ToggleEvent): boolean;
33
32
  export declare function clickedOutside(event: Event, element?: Element | null, allowSelf?: boolean): boolean;
34
33
  export declare function forwardEvent(target: HTMLElement, eventInit?: EventInit): EventListener;
35
34
  export declare function getElementFromEvent<T = HTMLElement>(event: Event, filterFn: (node: HTMLElement) => boolean): T | undefined;
package/dist/utils.js CHANGED
@@ -139,9 +139,6 @@ function createToggleEvent(oldState, newState, eventInit) {
139
139
  newState: newState ? "open" : "closed"
140
140
  });
141
141
  }
142
- function isToggleOpen(event) {
143
- return event.newState === "open";
144
- }
145
142
  function clickedOutside(event, element, allowSelf = false) {
146
143
  if (!element?.isConnected) return true;
147
144
  return !getElementFromEvent(event, (node) => node === element) && (allowSelf || event.target !== element);
@@ -352,4 +349,4 @@ function resetUniqueId(key) {
352
349
  }
353
350
  }
354
351
 
355
- export { InvokerCommandEvent, addGlobalEventListener, booleanAttributeDirective, clickedOutside, commandDirective, createCustomEvent, createToggleEvent, disableMotion, enableMotion, findClosestDocument, forwardEvent, getAssignedElements, getElementFromEvent, getKeyInfo, getUniqueId, interactionResponse, isToggleOpen, observeElementResize, observeMedia, optionalAttr, optionalSlot, parseDate, querySlotSelector, removeGlobalEventListener, resetUniqueId, setFocusable, stringAttributeDirective, supportsHover, toAriaBooleanAttribute, toPx, unobserveElementResize, unobserveMedia, waitForAnimations };
352
+ export { InvokerCommandEvent, addGlobalEventListener, booleanAttributeDirective, clickedOutside, commandDirective, createCustomEvent, createToggleEvent, disableMotion, enableMotion, findClosestDocument, forwardEvent, getAssignedElements, getElementFromEvent, getKeyInfo, getUniqueId, interactionResponse, observeElementResize, observeMedia, optionalAttr, optionalSlot, parseDate, querySlotSelector, removeGlobalEventListener, resetUniqueId, setFocusable, stringAttributeDirective, supportsHover, toAriaBooleanAttribute, toPx, unobserveElementResize, unobserveMedia, waitForAnimations };
package/dist/vendor.js CHANGED
@@ -3,29 +3,6 @@ import 'lit/html.js';
3
3
  import { directive } from 'lit/directive.js';
4
4
  import { AsyncDirective } from 'lit/async-directive.js';
5
5
 
6
- function groupBy(arr, getKeyFromItem) {
7
- const result = {};
8
- for (let i = 0; i < arr.length; i++) {
9
- const item = arr[i];
10
- const key = getKeyFromItem(item);
11
- if (!Object.hasOwn(result, key)) {
12
- result[key] = [];
13
- }
14
- result[key].push(item);
15
- }
16
- return result;
17
- }
18
-
19
- function keyBy(arr, getKeyFromItem) {
20
- const result = {};
21
- for (let i = 0; i < arr.length; i++) {
22
- const item = arr[i];
23
- const key = getKeyFromItem(item);
24
- result[key] = item;
25
- }
26
- return result;
27
- }
28
-
29
6
  function minBy(items, getValue) {
30
7
  if (items.length === 0) {
31
8
  return undefined;
@@ -1899,6 +1876,14 @@ const computePosition = (reference, floating, options) => {
1899
1876
  });
1900
1877
  };
1901
1878
 
1879
+ function round(value, precision = 0) {
1880
+ if (!Number.isInteger(precision)) {
1881
+ throw new Error('Precision must be an integer.');
1882
+ }
1883
+ const multiplier = Math.pow(10, precision);
1884
+ return Math.round(value * multiplier) / multiplier;
1885
+ }
1886
+
1902
1887
  function debounce(func, debounceMs, { signal, edges } = {}) {
1903
1888
  let pendingThis = undefined;
1904
1889
  let pendingArgs = null;
@@ -1980,12 +1965,4 @@ function throttle(func, throttleMs, { signal, edges = ['leading', 'trailing'] }
1980
1965
  return throttled;
1981
1966
  }
1982
1967
 
1983
- function round(value, precision = 0) {
1984
- if (!Number.isInteger(precision)) {
1985
- throw new Error('Precision must be an integer.');
1986
- }
1987
- const multiplier = Math.pow(10, precision);
1988
- return Math.round(value * multiplier) / multiplier;
1989
- }
1990
-
1991
- export { RovingTabindexController as R, size as a, arrow as b, computePosition as c, autoUpdate as d, e, flip as f, groupBy as g, hide as h, debounce as i, flattenObject as j, keyBy as k, minBy as m, offset as o, pick as p, round as r, shift as s, throttle as t, uniqBy as u };
1968
+ export { RovingTabindexController as R, size as a, arrow as b, computePosition as c, autoUpdate as d, e, flip as f, debounce as g, hide as h, flattenObject as i, minBy as m, offset as o, pick as p, round as r, shift as s, throttle as t, uniqBy as u };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@odx/foundation",
3
3
  "displayName": "ODX Design System Foundation",
4
4
  "description": "A library of Web Component building blocks for ODX",
5
- "version": "1.0.0-beta.234",
5
+ "version": "1.0.0-beta.236",
6
6
  "author": "Drägerwerk AG & Co.KGaA",
7
7
  "license": "SEE LICENSE IN LICENSE",
8
8
  "homepage": "https://odx.draeger.com",
@@ -28,15 +28,15 @@
28
28
  "@lit-labs/preact-signals": "1.0.3",
29
29
  "@lit-labs/rollup-plugin-minify-html-literals": "0.1.0",
30
30
  "@odx/icons": "4.0.0-rc.49",
31
- "@spectrum-web-components/reactive-controllers": "1.8.0",
31
+ "@spectrum-web-components/reactive-controllers": "1.9.0",
32
32
  "es-toolkit": "1.40.0",
33
33
  "sass-embedded": "1.93.2",
34
34
  "stylelint": "16.25.0",
35
35
  "@odx-internal/config-stylelint": "0.0.0",
36
36
  "@odx-internal/config-typescript": "0.0.0",
37
37
  "@odx-internal/config-vite": "0.0.0",
38
- "@odx/design-tokens": "2.2.0",
39
- "@odx-internal/utils-storybook": "0.0.0"
38
+ "@odx-internal/utils-storybook": "0.0.0",
39
+ "@odx/design-tokens": "2.2.0"
40
40
  },
41
41
  "sideEffects": [
42
42
  "dist/components-loader.js",