@oscarpalmer/oui 0.29.0 → 0.30.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.
Files changed (46) hide show
  1. package/dist/css/combobox.css +26 -0
  2. package/dist/js/combobox.d.mts +27 -0
  3. package/dist/js/combobox.mjs +474 -0
  4. package/dist/js/dialog.d.mts +4 -3
  5. package/dist/js/dialog.mjs +1 -1
  6. package/dist/js/{draggable-fIYXd8eO.d.mts → draggable-a6w0J1OD.d.mts} +1 -2
  7. package/dist/js/floatable/floatable.embedded.d.mts +1 -1
  8. package/dist/js/floatable/floatable.embedded.mjs +2 -2
  9. package/dist/js/floatable/floatable.standalone.d.mts +1 -1
  10. package/dist/js/{floatable.embedded-DUR8bQBK.d.mts → floatable.embedded-Bct4U5Dm.d.mts} +0 -1
  11. package/dist/js/focus-trap/focus-trap.embedded.mjs +13 -8
  12. package/dist/js/index.d.mts +9 -4
  13. package/dist/js/index.mjs +2 -1
  14. package/dist/js/internal/draggable.d.mts +1 -1
  15. package/dist/js/internal/draggable.mjs +24 -15
  16. package/dist/js/internal/navigable.d.mts +0 -1
  17. package/dist/js/internal/navigable.mjs +4 -3
  18. package/dist/js/menu.mjs +1 -1
  19. package/dist/js/movable/movable.embedded.d.mts +1 -1
  20. package/dist/js/movable/movable.embedded.mjs +3 -4
  21. package/dist/js/movable/movable.standalone.d.mts +1 -1
  22. package/dist/js/popover.d.mts +1 -2
  23. package/dist/js/popover.mjs +2 -2
  24. package/dist/js/resizable/resizable.embedded.d.mts +1 -1
  25. package/dist/js/resizable/resizable.embedded.mjs +47 -19
  26. package/dist/js/resizable/resizable.standalone.d.mts +1 -1
  27. package/dist/js/{resizable.embedded-CXrUVPzR.d.mts → resizable.embedded-3qoR0Bjm.d.mts} +0 -1
  28. package/dist/js/sortable/sortable.embedded.d.mts +1 -1
  29. package/dist/js/sortable/sortable.embedded.mjs +11 -15
  30. package/dist/js/sortable/sortable.standalone.d.mts +1 -1
  31. package/dist/js/splitter.d.mts +2 -2
  32. package/dist/js/splitter.mjs +11 -11
  33. package/dist/js/tooltip.d.mts +1 -2
  34. package/dist/js/tooltip.mjs +3 -3
  35. package/package.json +6 -2
  36. package/src/css/combobox.scss +26 -0
  37. package/src/js/combobox.ts +917 -0
  38. package/src/js/focus-trap/focus-trap.embedded.ts +22 -10
  39. package/src/js/index.ts +1 -0
  40. package/src/js/internal/draggable.ts +37 -29
  41. package/src/js/internal/navigable.ts +5 -1
  42. package/src/js/movable/movable.embedded.ts +1 -3
  43. package/src/js/popover.ts +1 -1
  44. package/src/js/resizable/resizable.embedded.ts +68 -18
  45. package/src/js/sortable/sortable.embedded.ts +7 -15
  46. package/src/js/splitter.ts +37 -23
@@ -1,25 +1,24 @@
1
- import { getPosition, on } from "@oscarpalmer/toretto/event";
2
- import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
3
- import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
4
- import { setStyle, setStyles, toggleStyles } from "@oscarpalmer/toretto/style";
5
1
  import { clamp } from "@oscarpalmer/atoms/number";
2
+ import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
3
+ import { dispatch, getPosition, on } from "@oscarpalmer/toretto/event";
6
4
  import { findAncestor } from "@oscarpalmer/toretto/find";
5
+ import { setStyle, setStyles, toggleStyles } from "@oscarpalmer/toretto/style";
6
+ import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
7
7
  import supportsTouch from "@oscarpalmer/toretto/touch";
8
8
  //#region src/js/internal/draggable.ts
9
9
  var OuiDraggable = class {
10
10
  #destroyed = false;
11
- #name;
12
11
  #state;
13
12
  get element() {
14
13
  return this.#state.element;
15
14
  }
16
15
  constructor(name, event, attribute, element, options, extras) {
17
- this.#name = name;
18
16
  this.#state = {
19
17
  ...extras,
20
18
  attribute,
21
19
  element,
22
20
  event,
21
+ name,
23
22
  options,
24
23
  horizontal: true,
25
24
  vertical: true,
@@ -34,7 +33,7 @@ var OuiDraggable = class {
34
33
  setAttribute(element, attribute, "");
35
34
  let states = globals.states.get(element);
36
35
  states ??= {};
37
- states[this.#name] = this.#state;
36
+ states[this.#state.name] = this.#state;
38
37
  globals.states.set(element, states);
39
38
  }
40
39
  destroy() {
@@ -52,6 +51,12 @@ function addDraggable(element, options) {
52
51
  instances[this.property] ??= new this.constructor(element, options);
53
52
  return instances[this.property];
54
53
  }
54
+ function cancelDrag(item) {
55
+ if (item == null) return;
56
+ item.state.options.drag.onCancel?.(globals, item);
57
+ dispatch(item.state.element, `${item.state.name}:cancel`, { detail: { element: item.state.options.getOrigin() } });
58
+ reset();
59
+ }
55
60
  function destroyInstance(instance, state) {
56
61
  unsetContainer({
57
62
  instance,
@@ -87,10 +92,7 @@ function getNextPosition(item, position) {
87
92
  };
88
93
  }
89
94
  function onKeydown(event) {
90
- if (current == null || event.key !== KEY_ESCAPE) return;
91
- current.state.options.drag.onCancel?.(globals, current);
92
- current.state.element.dispatchEvent(new CustomEvent(`${current.state.event}:cancel`, { detail: { element: current.state.options.getOrigin() } }));
93
- reset();
95
+ if (current != null && event.key === KEY_ESCAPE) cancelDrag(current);
94
96
  }
95
97
  function onPointerdown(event) {
96
98
  if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || (supportsTouch.value ? event.type === "mousedown" : event.type === "touchstart" || event.button !== 0)) return;
@@ -128,16 +130,16 @@ function onPointerdown(event) {
128
130
  };
129
131
  globals.offset = item.state.options.position.getOffset(globals, item, element, position);
130
132
  globals.original = item.state.options.position.getOriginal(globals, item, position);
131
- const begin = new CustomEvent(`${item.state.event}:begin`, {
133
+ const dispatch = new CustomEvent(`${item.state.name}:begin`, {
132
134
  detail: {
133
135
  element,
134
136
  position: { ...globals.original }
135
137
  },
136
138
  cancelable: true
137
139
  });
138
- item.state.element.dispatchEvent(begin);
140
+ item.state.element.dispatchEvent(dispatch);
139
141
  setTimeout(() => {
140
- if (begin.defaultPrevented) {
142
+ if (dispatch.defaultPrevented) {
141
143
  item.state.options.drag.onCancel?.(globals, item);
142
144
  reset();
143
145
  return;
@@ -163,7 +165,14 @@ function onPointermove(event) {
163
165
  calculated: next,
164
166
  original: position
165
167
  });
166
- current.state.element.dispatchEvent(new CustomEvent(`${current.state.event}:move`, { detail }));
168
+ const dispatch = new CustomEvent(`${current.state.name}:move`, {
169
+ detail,
170
+ cancelable: true
171
+ });
172
+ current.state.element.dispatchEvent(dispatch);
173
+ setTimeout(() => {
174
+ if (dispatch.defaultPrevented) cancelDrag(current);
175
+ });
167
176
  }
168
177
  function onPointerup(event) {
169
178
  current?.state.options.drag.onEnd?.(event, globals, current, reset);
@@ -1,5 +1,4 @@
1
1
  import { AriaRole, RemovableEventListener } from "@oscarpalmer/toretto/models";
2
-
3
2
  //#region src/js/internal/navigable.d.ts
4
3
  declare class OuiNavigable {
5
4
  active: OuiNavigableActive;
@@ -1,8 +1,8 @@
1
- import { getAria, setRole } from "@oscarpalmer/toretto/aria";
2
- import { on } from "@oscarpalmer/toretto/event";
3
- import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
4
1
  import { clamp } from "@oscarpalmer/atoms/number";
2
+ import { getAria, setRole } from "@oscarpalmer/toretto/aria";
3
+ import { dispatch, on } from "@oscarpalmer/toretto/event";
5
4
  import { findAncestor } from "@oscarpalmer/toretto/find";
5
+ import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
6
6
  //#region src/js/internal/navigable.ts
7
7
  var OuiNavigable = class {
8
8
  active = { index: 0 };
@@ -88,6 +88,7 @@ function updateNavigableFocus(navigable, focus, items) {
88
88
  for (let index = 0; index < length; index += 1) updated[index].tabIndex = index === navigable.active.index ? 0 : -1;
89
89
  navigable.active.element ??= updated[navigable.active.index];
90
90
  if (focus) navigable.active.element?.focus();
91
+ dispatch(navigable.active.element, "navigable:change", { detail: { ...navigable.active } });
91
92
  }
92
93
  const KEYS_ABSOLUTE = /* @__PURE__ */ new Set(["End", "Home"]);
93
94
  const KEYS_ACTIVATE = /* @__PURE__ */ new Set(["Enter", " "]);
package/dist/js/menu.mjs CHANGED
@@ -2,8 +2,8 @@ import { createEmbeddedFloatable, getOnBeforeToggleListener } from "./floatable/
2
2
  import { attributable } from "./internal/attributable.mjs";
3
3
  import { NAVIGABLE_KEYS_HORIZONTAL, NAVIGABLE_KEYS_VERTICAL, getNavigable, updateNavigableFocus } from "./internal/navigable.mjs";
4
4
  import { setAria, setRole } from "@oscarpalmer/toretto/aria";
5
- import { on } from "@oscarpalmer/toretto/event";
6
5
  import { setAttribute } from "@oscarpalmer/toretto/attribute";
6
+ import { on } from "@oscarpalmer/toretto/event";
7
7
  import { findAncestor } from "@oscarpalmer/toretto/find";
8
8
  //#region src/js/menu.ts
9
9
  var OuiMenu = class {
@@ -1,2 +1,2 @@
1
- import { g as createMovable, h as OuiMovable, m as ATTRIBUTE_MOVABLE_HANDLE, p as ATTRIBUTE_MOVABLE } from "../draggable-fIYXd8eO.mjs";
1
+ import { g as createMovable, h as OuiMovable, m as ATTRIBUTE_MOVABLE_HANDLE, p as ATTRIBUTE_MOVABLE } from "../draggable-a6w0J1OD.mjs";
2
2
  export { ATTRIBUTE_MOVABLE, ATTRIBUTE_MOVABLE_HANDLE, OuiMovable, createMovable };
@@ -1,9 +1,9 @@
1
1
  import { attributable } from "../internal/attributable.mjs";
2
2
  import { OuiDraggable, addDraggable, getDraggableStates, removeDraggable } from "../internal/draggable.mjs";
3
- import { getPosition, on } from "@oscarpalmer/toretto/event";
4
3
  import { setAttribute } from "@oscarpalmer/toretto/attribute";
5
- import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
4
+ import { getPosition, on } from "@oscarpalmer/toretto/event";
6
5
  import { getStyles, setStyle, setStyles } from "@oscarpalmer/toretto/style";
6
+ import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
7
7
  //#region src/js/movable/movable.embedded.ts
8
8
  var OuiMovable = class extends OuiDraggable {
9
9
  #element;
@@ -110,7 +110,7 @@ function onEnd(event, globals, item, reset) {
110
110
  }
111
111
  const container = state.container?.getBoundingClientRect();
112
112
  if (container != null) setOffset(state, container);
113
- const end = new CustomEvent(EVENT_END, {
113
+ const end = new CustomEvent("movable:end", {
114
114
  detail: {
115
115
  from: { ...globals.original },
116
116
  to: getPosition(event)
@@ -162,7 +162,6 @@ const ATTRIBUTE_DIRECTION = `${ATTRIBUTE_MOVABLE}-direction`;
162
162
  const ATTRIBUTE_MOVABLE_HANDLE = `${ATTRIBUTE_MOVABLE}-handle`;
163
163
  const ATTRIBUTE_MOVING = `${ATTRIBUTE_MOVABLE}-moving`;
164
164
  const CONTAINERS = /* @__PURE__ */ new Map();
165
- const EVENT_END = "move:end";
166
165
  const MESSAGE = "The element must be an instance of HTMLElement or SVGElement";
167
166
  const MOVED = /* @__PURE__ */ new Set();
168
167
  const SELECTOR_HANDLE = `[${ATTRIBUTE_MOVABLE_HANDLE}]`;
@@ -1,2 +1,2 @@
1
- import { g as createMovable, h as OuiMovable, t as CreateOuiDraggableOptions } from "../draggable-fIYXd8eO.mjs";
1
+ import { g as createMovable, h as OuiMovable, t as CreateOuiDraggableOptions } from "../draggable-a6w0J1OD.mjs";
2
2
  export { type CreateOuiDraggableOptions as CreateOuiMovableOptions, type OuiMovable, createMovable };
@@ -1,7 +1,6 @@
1
- import { r as OuiFloatable } from "./floatable.embedded-DUR8bQBK.mjs";
1
+ import { r as OuiFloatable } from "./floatable.embedded-Bct4U5Dm.mjs";
2
2
  import { i as OuiFocusTrap } from "./focus-trap.embedded-DR8NpZfr.mjs";
3
3
  import { RemovableEventListener } from "@oscarpalmer/toretto/models";
4
-
5
4
  //#region src/js/popover.d.ts
6
5
  declare class OuiPopover {
7
6
  #private;
@@ -2,8 +2,8 @@ import { createEmbeddedFloatable, getOnBeforeToggleListener } from "./floatable/
2
2
  import { attributable } from "./internal/attributable.mjs";
3
3
  import { createFocusTrap } from "./focus-trap/focus-trap.embedded.mjs";
4
4
  import { getAria, setAria } from "@oscarpalmer/toretto/aria";
5
- import { on } from "@oscarpalmer/toretto/event";
6
5
  import { setAttribute } from "@oscarpalmer/toretto/attribute";
6
+ import { on } from "@oscarpalmer/toretto/event";
7
7
  import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
8
8
  //#region src/js/popover.ts
9
9
  var OuiPopover = class {
@@ -110,7 +110,7 @@ function removePopover(element) {
110
110
  const ATTRIBUTE = "oui-popover";
111
111
  const ATTRIBUTE_OPEN = `${ATTRIBUTE}-open`;
112
112
  const options = {
113
- attribute: `${ATTRIBUTE}position`,
113
+ attribute: `${ATTRIBUTE}-position`,
114
114
  position: "below-start",
115
115
  reusable: false
116
116
  };
@@ -1,2 +1,2 @@
1
- import { a as createResizable, i as RESIZABLE_ATTRIBUTE_HANDLE, n as OuiResizable, r as RESIZABLE_ATTRIBUTE, t as CreateOuiResizableOptions } from "../resizable.embedded-CXrUVPzR.mjs";
1
+ import { a as createResizable, i as RESIZABLE_ATTRIBUTE_HANDLE, n as OuiResizable, r as RESIZABLE_ATTRIBUTE, t as CreateOuiResizableOptions } from "../resizable.embedded-3qoR0Bjm.mjs";
2
2
  export { CreateOuiResizableOptions, OuiResizable, RESIZABLE_ATTRIBUTE, RESIZABLE_ATTRIBUTE_HANDLE, createResizable };
@@ -1,11 +1,11 @@
1
1
  import { attributable } from "../internal/attributable.mjs";
2
- import { getPosition, on } from "@oscarpalmer/toretto/event";
3
- import { isPlainObject } from "@oscarpalmer/atoms/is";
4
- import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
5
- import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
6
- import { setStyles, toggleStyles } from "@oscarpalmer/toretto/style";
7
2
  import { getNumber } from "@oscarpalmer/atoms/number";
3
+ import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
4
+ import { dispatch, getPosition, on } from "@oscarpalmer/toretto/event";
8
5
  import { findAncestor } from "@oscarpalmer/toretto/find";
6
+ import { setStyles, toggleStyles } from "@oscarpalmer/toretto/style";
7
+ import { isPlainObject } from "@oscarpalmer/atoms/is";
8
+ import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
9
9
  import supportsTouch from "@oscarpalmer/toretto/touch";
10
10
  //#region src/js/resizable/resizable.embedded.ts
11
11
  var OuiResizable = class {
@@ -43,6 +43,15 @@ function addResizable(element, options) {
43
43
  }
44
44
  return item?.instance;
45
45
  }
46
+ function cancelResize(item) {
47
+ if (item == null) return;
48
+ setStyles(item.state.element, {
49
+ height: `${item.state.height}px`,
50
+ width: `${item.state.width}px`
51
+ });
52
+ resetResizable();
53
+ dispatch(item.state.element, "resizable:cancel");
54
+ }
46
55
  /**
47
56
  * Creates _(or retrieves)_ a _OuiResizable_ instance for an element
48
57
  *
@@ -112,12 +121,7 @@ function getXAndY(first, second) {
112
121
  return [xAsNumber, yAsNumber];
113
122
  }
114
123
  function onKeydown(event) {
115
- if (current == null || event.key !== "Escape") return;
116
- setStyles(current.state.element, {
117
- height: `${current.state.height}px`,
118
- width: `${current.state.width}px`
119
- });
120
- resetResizable();
124
+ if (current != null && event.key === "Escape") cancelResize(current);
121
125
  }
122
126
  function onPointerdown(event) {
123
127
  if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || (supportsTouch.value ? event.type === "mousedown" : event.type === "touchstart" || event.button !== 0)) return;
@@ -127,10 +131,15 @@ function onPointerdown(event) {
127
131
  const position = getPosition(event);
128
132
  if (stored == null || position == null) return;
129
133
  if (supportsTouch.value) event.preventDefault();
130
- current = stored;
131
- start = position;
132
- current.state.styles.set();
133
- styleToggler.set();
134
+ const dispatch = new CustomEvent("resizable:begin", { cancelable: true });
135
+ element.dispatchEvent(dispatch);
136
+ setTimeout(() => {
137
+ if (dispatch.defaultPrevented) return;
138
+ current = stored;
139
+ start = position;
140
+ current.state.styles.set();
141
+ styleToggler.set();
142
+ });
134
143
  }
135
144
  function onPointermove(event) {
136
145
  if (current == null) return;
@@ -142,13 +151,32 @@ function onPointermove(event) {
142
151
  height,
143
152
  width
144
153
  });
154
+ const dispatch = new CustomEvent("resizable:resize", {
155
+ cancelable: true,
156
+ detail: {
157
+ height,
158
+ width
159
+ }
160
+ });
161
+ current.state.element.dispatchEvent(dispatch);
162
+ setTimeout(() => {
163
+ if (dispatch.defaultPrevented) cancelResize(current);
164
+ });
145
165
  }
146
166
  function onPointerup() {
147
167
  if (current == null) return;
148
- const { height, width } = current.state.element.getBoundingClientRect();
149
- current.state.height = height;
150
- current.state.width = width;
151
- resetResizable();
168
+ const dispatch = new CustomEvent("resizable:end", { cancelable: true });
169
+ current.state.element.dispatchEvent(dispatch);
170
+ setTimeout(() => {
171
+ if (current == null || dispatch.defaultPrevented) {
172
+ cancelResize(current);
173
+ return;
174
+ }
175
+ const { height, width } = current.state.element.getBoundingClientRect();
176
+ current.state.height = height;
177
+ current.state.width = width;
178
+ resetResizable();
179
+ });
152
180
  }
153
181
  function removeResizable(element) {
154
182
  items.get(element)?.instance.destroy();
@@ -1,2 +1,2 @@
1
- import { a as createResizable, n as OuiResizable, t as CreateOuiResizableOptions } from "../resizable.embedded-CXrUVPzR.mjs";
1
+ import { a as createResizable, n as OuiResizable, t as CreateOuiResizableOptions } from "../resizable.embedded-3qoR0Bjm.mjs";
2
2
  export { type CreateOuiResizableOptions, type OuiResizable, createResizable as createOuiResizable };
@@ -1,5 +1,4 @@
1
1
  import { StyleToggler } from "@oscarpalmer/toretto/style";
2
-
3
2
  //#region src/js/resizable/resizable.embedded.d.ts
4
3
  type CreateOuiResizableOptions = {
5
4
  maximumHeight?: number;
@@ -1,2 +1,2 @@
1
- import { d as OuiSortable, f as createSortable } from "../draggable-fIYXd8eO.mjs";
1
+ import { d as OuiSortable, f as createSortable } from "../draggable-a6w0J1OD.mjs";
2
2
  export { OuiSortable, createSortable };
@@ -1,11 +1,11 @@
1
1
  import { attributable } from "../internal/attributable.mjs";
2
2
  import { OuiDraggable, addDraggable, getDraggableStates, removeDraggable } from "../internal/draggable.mjs";
3
- import { getPosition } from "@oscarpalmer/toretto/event";
4
3
  import { getAttribute, setAttribute, setAttributes } from "@oscarpalmer/toretto/attribute";
5
- import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
6
- import { setStyle } from "@oscarpalmer/toretto/style";
7
- import { findAncestor, getElementFromPosition } from "@oscarpalmer/toretto/find";
8
4
  import { createElement } from "@oscarpalmer/toretto/create";
5
+ import { getPosition } from "@oscarpalmer/toretto/event";
6
+ import { findAncestor, getElementFromPosition } from "@oscarpalmer/toretto/find";
7
+ import { setStyle } from "@oscarpalmer/toretto/style";
8
+ import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
9
9
  //#region src/js/sortable/sortable.embedded.ts
10
10
  var OuiSortable = class extends OuiDraggable {
11
11
  constructor(element, options) {
@@ -43,8 +43,8 @@ function afterEnd(insert, from, events, elements, position, valid) {
43
43
  if (position == null) return;
44
44
  const { height, top } = elements.target.getBoundingClientRect();
45
45
  let insertion;
46
- if (position.y < top + height / 2) insertion = INSERT_BEFORE;
47
- else insertion = INSERT_AFTER;
46
+ if (position.y < top + height / 2) insertion = "beforebegin";
47
+ else insertion = "afterend";
48
48
  elements.target?.insertAdjacentElement(insertion, elements.origin);
49
49
  document.body.removeAttribute(ATTRIBUTE_ACTIVE);
50
50
  }
@@ -130,8 +130,8 @@ function onEnd(event, globals, item, reset) {
130
130
  bubbles: false,
131
131
  cancelable: true
132
132
  };
133
- const fromEvent = new CustomEvent(EVENT_END, options);
134
- const toEvent = new CustomEvent(EVENT_END, options);
133
+ const fromEvent = new CustomEvent("sortable:end", options);
134
+ const toEvent = new CustomEvent("sortable:end", options);
135
135
  item.instance.element.dispatchEvent(fromEvent);
136
136
  if (item.instance !== toInstance) toInstance?.element.dispatchEvent(toEvent);
137
137
  setTimeout(() => {
@@ -165,10 +165,10 @@ function onMove(event, globals, item, position) {
165
165
  let place;
166
166
  if (position.calculated.y < top + height / 2) {
167
167
  place = "before";
168
- toElement.insertAdjacentElement(INSERT_BEFORE, placeholder);
168
+ toElement.insertAdjacentElement("beforebegin", placeholder);
169
169
  } else {
170
170
  place = "after";
171
- toElement.insertAdjacentElement(INSERT_AFTER, placeholder);
171
+ toElement.insertAdjacentElement("afterend", placeholder);
172
172
  }
173
173
  setAttribute(placeholder, ATTRIBUTE_PLACEHOLDER_POSITION, place);
174
174
  } else placeholder.remove();
@@ -193,7 +193,7 @@ function setPlaceholder(state, item, origin) {
193
193
  const element = getDragPlaceholder();
194
194
  placeholder.drag.default.innerHTML = "";
195
195
  updatePlaceholder(item, element);
196
- const event = new CustomEvent(EVENT_PLACEHOLDER, {
196
+ const event = new CustomEvent("sortable:placeholder", {
197
197
  cancelable: true,
198
198
  detail: {
199
199
  origin,
@@ -248,10 +248,6 @@ const ATTRIBUTE_PLACEHOLDER_DRAG = `${ATTRIBUTE}-placeholder-drag`;
248
248
  const ATTRIBUTE_PLACEHOLDER_POSITION = `${ATTRIBUTE}-placeholder-position`;
249
249
  const ATTRIBUTE_VERTICAL = `${ATTRIBUTE}-vertical`;
250
250
  const CONTAINERS = /* @__PURE__ */ new Map();
251
- const EVENT_END = "sort:end";
252
- const EVENT_PLACEHOLDER = "sort:placeholder";
253
- const INSERT_AFTER = "afterend";
254
- const INSERT_BEFORE = "beforebegin";
255
251
  const MESSAGE = "The element must be an instance of HTMLElement or SVGElement";
256
252
  const SELECTOR = `[${ATTRIBUTE}]`;
257
253
  const SELECTOR_ITEM = `[${ATTRIBUTE}] > *`;
@@ -1,2 +1,2 @@
1
- import { d as OuiSortable, f as createSortable, t as CreateOuiDraggableOptions } from "../draggable-fIYXd8eO.mjs";
1
+ import { d as OuiSortable, f as createSortable, t as CreateOuiDraggableOptions } from "../draggable-a6w0J1OD.mjs";
2
2
  export { type CreateOuiDraggableOptions as CreateOuiSortableOptions, type OuiSortable, createSortable };
@@ -1,7 +1,7 @@
1
1
  //#region src/js/splitter.d.ts
2
2
  declare global {
3
3
  interface HTMLElementTagNameMap {
4
- [SELECTOR]: OuiSplitterElement;
4
+ [TAGNAME]: OuiSplitterElement;
5
5
  }
6
6
  }
7
7
  declare class OuiSplitterElement extends HTMLElement {
@@ -44,6 +44,6 @@ declare class OuiSplitterElement extends HTMLElement {
44
44
  disconnectedCallback(): void;
45
45
  attributeChangedCallback(name: string): void;
46
46
  }
47
- declare const SELECTOR = "oui-splitter";
47
+ declare const TAGNAME = "oui-splitter";
48
48
  //#endregion
49
49
  export { OuiSplitterElement };
@@ -1,10 +1,10 @@
1
+ import { clamp } from "@oscarpalmer/atoms/number";
1
2
  import { setAria } from "@oscarpalmer/toretto/aria";
2
- import { getPosition, on } from "@oscarpalmer/toretto/event";
3
- import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
4
3
  import { getAttribute, setAttribute } from "@oscarpalmer/toretto/attribute";
5
- import { setStyle, toggleStyles } from "@oscarpalmer/toretto/style";
6
- import { clamp } from "@oscarpalmer/atoms/number";
4
+ import { getPosition, on } from "@oscarpalmer/toretto/event";
7
5
  import { findAncestor } from "@oscarpalmer/toretto/find";
6
+ import { setStyle, toggleStyles } from "@oscarpalmer/toretto/style";
7
+ import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
8
8
  import supportsTouch from "@oscarpalmer/toretto/touch";
9
9
  import { round } from "@oscarpalmer/atoms/math";
10
10
  //#region src/js/splitter.ts
@@ -281,11 +281,11 @@ function setSize(splitter, size, previous) {
281
281
  setStyle(splitter.element, "--oui-splitter-size", `${size}`);
282
282
  setAriaValue(splitter);
283
283
  }
284
- const SELECTOR = "oui-splitter";
285
- const ATTRIBUTE_ACTIVE = `${SELECTOR}-active`;
286
- const ATTRIBUTE_HANDLE = `${SELECTOR}-handle`;
287
- const ATTRIBUTE_HORIZONTAL = `${SELECTOR}-horizontal`;
288
- const ATTRIBUTE_SEPARATOR = `${SELECTOR}-separator`;
284
+ const TAGNAME = "oui-splitter";
285
+ const ATTRIBUTE_ACTIVE = `${TAGNAME}-active`;
286
+ const ATTRIBUTE_HANDLE = `${TAGNAME}-handle`;
287
+ const ATTRIBUTE_HORIZONTAL = `${TAGNAME}-horizontal`;
288
+ const ATTRIBUTE_SEPARATOR = `${TAGNAME}-separator`;
289
289
  const KEYS_ABSOLUTE = /* @__PURE__ */ new Set(["End", "Home"]);
290
290
  const KEYS_HORIZONTAL = /* @__PURE__ */ new Set(["ArrowDown", "ArrowUp"]);
291
291
  const KEYS_NEGATIVE = /* @__PURE__ */ new Set(["ArrowLeft", "ArrowUp"]);
@@ -296,7 +296,7 @@ const KEYS_ALL = /* @__PURE__ */ new Set([
296
296
  ...KEYS_VERTICAL
297
297
  ]);
298
298
  const MAPPED_ELEMENTS = /* @__PURE__ */ new WeakMap();
299
- const MESSAGE = `<${SELECTOR}> must have exactly two panels.`;
299
+ const MESSAGE = `<${TAGNAME}> must have exactly two panels.`;
300
300
  const METHODS_CONNECT = ["delete", "set"];
301
301
  const METHODS_OBSERVE = ["unobserve", "observe"];
302
302
  const NAVIGATION_MAXIMUM_PERCENTAGE = .9;
@@ -314,12 +314,12 @@ const VALUE_DECIMALS = 6;
314
314
  let index = 0;
315
315
  let frame;
316
316
  let splitter;
317
- customElements.define(SELECTOR, OuiSplitterElement);
318
317
  on(document, "keydown", onKeydown);
319
318
  on(document, "mousedown", onPointerdown);
320
319
  on(document, "pointermove", onPointermove);
321
320
  on(document, "pointerup", onPointerup);
322
321
  on(document, "touchcancel", onPointerup);
323
322
  on(document, "touchstart", onPointerdown, { passive: false });
323
+ customElements.define(TAGNAME, OuiSplitterElement);
324
324
  //#endregion
325
325
  export { OuiSplitterElement };
@@ -1,5 +1,4 @@
1
- import { r as OuiFloatable } from "./floatable.embedded-DUR8bQBK.mjs";
2
-
1
+ import { r as OuiFloatable } from "./floatable.embedded-Bct4U5Dm.mjs";
3
2
  //#region src/js/tooltip.d.ts
4
3
  declare class OuiTooltip {
5
4
  #private;
@@ -1,11 +1,11 @@
1
1
  import { createEmbeddedFloatable } from "./floatable/floatable.embedded.mjs";
2
2
  import { attributable } from "./internal/attributable.mjs";
3
3
  import { getAria } from "@oscarpalmer/toretto/aria";
4
- import { on } from "@oscarpalmer/toretto/event";
5
- import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
6
4
  import { setAttribute } from "@oscarpalmer/toretto/attribute";
7
- import { findAncestor } from "@oscarpalmer/toretto/find";
8
5
  import { createElement } from "@oscarpalmer/toretto/create";
6
+ import { on } from "@oscarpalmer/toretto/event";
7
+ import { findAncestor } from "@oscarpalmer/toretto/find";
8
+ import { isNullableOrWhitespace } from "@oscarpalmer/atoms/is";
9
9
  //#region src/js/tooltip.ts
10
10
  var OuiTooltip = class {
11
11
  #state;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/oui",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
4
4
  "description": "Styles, components, and utilities for building websites and applications.",
5
5
  "keywords": [
6
6
  "css",
@@ -33,6 +33,10 @@
33
33
  "types": "./dist/js/index.d.mts",
34
34
  "default": "./dist/js/index.mjs"
35
35
  },
36
+ "./combobox": {
37
+ "types": "./dist/js/combobox.d.mts",
38
+ "default": "./dist/js/combobox.mjs"
39
+ },
36
40
  "./dialog": {
37
41
  "types": "./dist/js/dialog.d.mts",
38
42
  "default": "./dist/js/dialog.mjs"
@@ -94,7 +98,7 @@
94
98
  "@oscarpalmer/toretto": "^0.47.3"
95
99
  },
96
100
  "devDependencies": {
97
- "@oxlint/plugins": "^1.73",
101
+ "@oxlint/plugins": "^1.74",
98
102
  "@vitest/coverage-istanbul": "^4.1",
99
103
  "autoprefixer": "^10.5",
100
104
  "concurrently": "^10",
@@ -0,0 +1,26 @@
1
+ /*! https://github.com/oscarpalmer/oui */
2
+
3
+ @use './mixins.scss' as mixins;
4
+
5
+ :where([oui-combobox-content]) {
6
+ @include mixins.shadow-overlay;
7
+
8
+ width: fit-content;
9
+ height: fit-content;
10
+ max-width: max(25vw, 32rem);
11
+ max-height: max(25vh, 32rem);
12
+ min-width: var(--oui-combobox-width, auto);
13
+ flex-flow: column nowrap;
14
+
15
+ &:popover-open {
16
+ display: flex !important;
17
+ }
18
+ }
19
+
20
+ :where([oui-combobox-list]) {
21
+ overflow: auto;
22
+ }
23
+
24
+ :where([oui-combobox-option]) {
25
+ cursor: pointer;
26
+ }