@oscarpalmer/oui 0.27.0 → 0.29.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 (54) hide show
  1. package/dist/css/floatable.css +9 -0
  2. package/dist/js/dialog.d.mts +3 -1
  3. package/dist/js/dialog.mjs +35 -19
  4. package/dist/js/{draggable-zszaW1qS.d.mts → draggable-fIYXd8eO.d.mts} +3 -3
  5. package/dist/js/floatable/floatable.embedded.d.mts +2 -2
  6. package/dist/js/floatable/floatable.embedded.mjs +17 -16
  7. package/dist/js/floatable/floatable.standalone.d.mts +1 -1
  8. package/dist/js/{floatable.embedded-YxGwzgbE.d.mts → floatable.embedded-DUR8bQBK.d.mts} +1 -2
  9. package/dist/js/focus-trap/focus-trap.embedded.mjs +6 -5
  10. package/dist/js/index.d.mts +4 -3
  11. package/dist/js/index.mjs +6 -2
  12. package/dist/js/internal/attributable.mjs +3 -4
  13. package/dist/js/internal/draggable.d.mts +1 -1
  14. package/dist/js/internal/draggable.mjs +12 -9
  15. package/dist/js/internal/navigable.d.mts +32 -0
  16. package/dist/js/internal/navigable.mjs +107 -0
  17. package/dist/js/menu.d.mts +1 -0
  18. package/dist/js/menu.mjs +168 -0
  19. package/dist/js/movable/movable.embedded.d.mts +1 -1
  20. package/dist/js/movable/movable.embedded.mjs +8 -13
  21. package/dist/js/movable/movable.standalone.d.mts +1 -1
  22. package/dist/js/popover.d.mts +1 -1
  23. package/dist/js/popover.mjs +27 -12
  24. package/dist/js/resizable/resizable.embedded.d.mts +2 -0
  25. package/dist/js/resizable/resizable.embedded.mjs +191 -0
  26. package/dist/js/resizable/resizable.standalone.d.mts +2 -0
  27. package/dist/js/resizable/resizable.standalone.mjs +2 -0
  28. package/dist/js/resizable.embedded-CXrUVPzR.d.mts +35 -0
  29. package/dist/js/sortable/sortable.embedded.d.mts +1 -1
  30. package/dist/js/sortable/sortable.embedded.mjs +15 -13
  31. package/dist/js/sortable/sortable.standalone.d.mts +1 -1
  32. package/dist/js/splitter.mjs +30 -26
  33. package/dist/js/toolbar.mjs +12 -88
  34. package/dist/js/tooltip.d.mts +1 -1
  35. package/dist/js/tooltip.mjs +12 -17
  36. package/package.json +11 -3
  37. package/src/css/floatable.scss +9 -0
  38. package/src/css/form.scss +6 -6
  39. package/src/js/dialog.ts +50 -24
  40. package/src/js/floatable/floatable.embedded.ts +19 -18
  41. package/src/js/focus-trap/focus-trap.embedded.ts +6 -5
  42. package/src/js/index.ts +3 -1
  43. package/src/js/internal/attributable.ts +3 -5
  44. package/src/js/internal/draggable.ts +13 -10
  45. package/src/js/internal/navigable.ts +247 -0
  46. package/src/js/menu.ts +345 -0
  47. package/src/js/movable/movable.embedded.ts +10 -13
  48. package/src/js/popover.ts +41 -15
  49. package/src/js/resizable/resizable.embedded.ts +390 -0
  50. package/src/js/resizable/resizable.standalone.ts +5 -0
  51. package/src/js/sortable/sortable.embedded.ts +17 -22
  52. package/src/js/splitter.ts +41 -36
  53. package/src/js/toolbar.ts +27 -178
  54. package/src/js/tooltip.ts +18 -30
@@ -0,0 +1,168 @@
1
+ import { createEmbeddedFloatable, getOnBeforeToggleListener } from "./floatable/floatable.embedded.mjs";
2
+ import { attributable } from "./internal/attributable.mjs";
3
+ import { NAVIGABLE_KEYS_HORIZONTAL, NAVIGABLE_KEYS_VERTICAL, getNavigable, updateNavigableFocus } from "./internal/navigable.mjs";
4
+ import { setAria, setRole } from "@oscarpalmer/toretto/aria";
5
+ import { on } from "@oscarpalmer/toretto/event";
6
+ import { setAttribute } from "@oscarpalmer/toretto/attribute";
7
+ import { findAncestor } from "@oscarpalmer/toretto/find";
8
+ //#region src/js/menu.ts
9
+ var OuiMenu = class {
10
+ content;
11
+ element;
12
+ floatable;
13
+ navigable;
14
+ toggle;
15
+ get open() {
16
+ return this.floatable.open;
17
+ }
18
+ constructor(element, navigable) {
19
+ this.element = element;
20
+ this.navigable = navigable;
21
+ this.content = navigable.element;
22
+ this.toggle = element.querySelector(SELECTOR_MENU_TOGGLE);
23
+ this.floatable = createEmbeddedFloatable(this.toggle, this.content, {
24
+ attribute: ATTRIBUTE_MENU_POSITION,
25
+ position: findAncestor(element.parentElement, SELECTOR_MENU_CONTENT) == null ? "below-start" : "end-top",
26
+ reusable: false
27
+ });
28
+ this.navigable.listeners.push(getOnBeforeToggleListener(this.content), on(this.content, "click", (event) => {
29
+ event.stopPropagation();
30
+ if (findAncestor(event, SELECTOR_MENU_TOGGLE) != null) return;
31
+ const elements = document.querySelectorAll(SELECTOR_MENU_CONTENT);
32
+ for (const element of elements) menus.get(element)?.floatable.hide();
33
+ const menu = menus.get(elements[0]);
34
+ if (menu != null && event.pointerId === -1) updateNavigableFocus(menu.navigable, true);
35
+ }), on(this.content, "toggle", (event) => {
36
+ const expanded = event.newState === "open";
37
+ if (expanded) {
38
+ this.floatable?.update();
39
+ updateNavigableFocus(this.navigable, true);
40
+ }
41
+ setAria(this.toggle, "expanded", expanded);
42
+ }));
43
+ this.floatable.update();
44
+ initializeMenu(this);
45
+ updateNavigableFocus(this.navigable, false);
46
+ }
47
+ destroy() {
48
+ this.floatable.destroy();
49
+ this.navigable.destroy();
50
+ this.floatable = void 0;
51
+ this.navigable = void 0;
52
+ }
53
+ };
54
+ var OuiMenubar = class {
55
+ element;
56
+ navigable;
57
+ constructor(element, navigable) {
58
+ this.element = element;
59
+ this.navigable = navigable;
60
+ updateNavigableFocus(this.navigable, false);
61
+ }
62
+ destroy() {
63
+ this.navigable.destroy();
64
+ this.navigable = void 0;
65
+ }
66
+ };
67
+ function addInstance(instances, ctor, element, content, options) {
68
+ if (!instances.has(content)) instances.set(content, new ctor(element, getNavigable(content, {
69
+ ...options,
70
+ onDeactivate,
71
+ onPreventNavigation,
72
+ onShouldActivate,
73
+ onShouldDeactivate
74
+ })));
75
+ }
76
+ function addMenu(element) {
77
+ const content = element.querySelector(SELECTOR_MENU_CONTENT);
78
+ const toggle = element.querySelector(SELECTOR_MENU_TOGGLE);
79
+ if (content != null && toggle != null) addInstance(menus, OuiMenu, element, content, {
80
+ selector: SELECTOR_MENU_ITEM,
81
+ vertical: true
82
+ });
83
+ }
84
+ function addMenubar(element) {
85
+ addInstance(menubars, OuiMenubar, element, element, {
86
+ role: "menubar",
87
+ selector: SELECTOR_MENUBAR_ITEM,
88
+ vertical: false
89
+ });
90
+ }
91
+ function getId(element, value) {
92
+ let { id } = element;
93
+ if (id == null || id.trim().length === 0) {
94
+ id = value == null ? `oui_menu_${++index}` : `${value}_toggle`;
95
+ element.id = id;
96
+ }
97
+ return id;
98
+ }
99
+ function initializeMenu(menu) {
100
+ const id = getId(menu.content);
101
+ setAttribute(menu.toggle, "popovertarget", id);
102
+ setAria(menu.toggle, {
103
+ controls: id,
104
+ expanded: "false",
105
+ haspopup: "menu"
106
+ });
107
+ setAttribute(menu.content, "tabindex", "-1");
108
+ setRole(menu.content, "menu");
109
+ }
110
+ function onDeactivate(_, navigable) {
111
+ const menu = menus.get(navigable.element);
112
+ if (menu == null) return;
113
+ menu.floatable.hide();
114
+ const element = findAncestor(menu.element.parentElement, SELECTORS);
115
+ if (element == null) return;
116
+ const instance = menubars.get(element) ?? menus.get(element);
117
+ if (instance != null) updateNavigableFocus(instance.navigable, true);
118
+ }
119
+ function onPreventNavigation(_, navigable) {
120
+ return findAncestor((menubars.get(navigable.element) ?? menus.get(navigable.element))?.element.parentElement, SELECTORS) != null;
121
+ }
122
+ function onShouldActivate(event, navigable) {
123
+ let activate = false;
124
+ if (menubars.has(navigable.element)) activate = navigable.orientation === "horizontal" ? NAVIGABLE_KEYS_VERTICAL.has(event.key) : NAVIGABLE_KEYS_HORIZONTAL.has(event.key);
125
+ else if (menus.has(navigable.element)) activate = navigable.orientation === "horizontal" ? NAVIGABLE_KEYS_VERTICAL.has(event.key) : event.key === "ArrowRight";
126
+ if (activate) {
127
+ const target = event.target instanceof HTMLElement && event.target.matches(SELECTOR_MENU_TOGGLE) ? event.target : void 0;
128
+ if (target == null) activate = false;
129
+ else target.click();
130
+ }
131
+ return activate;
132
+ }
133
+ function onShouldDeactivate(event, navigable) {
134
+ if (menubars.has(navigable.element)) return;
135
+ const menu = menus.get(navigable.element);
136
+ if (menu == null) return;
137
+ const horizontal = navigable.orientation === "horizontal";
138
+ const altKey = horizontal ? "ArrowDown" : "ArrowRight";
139
+ const baseKey = horizontal ? "ArrowUp" : "ArrowLeft";
140
+ if (event.key === baseKey) return findAncestor(menu.element.parentElement, SELECTOR_MENU_CONTENT) != null;
141
+ if (event.key === altKey && event.target instanceof HTMLElement && !event.target.hasAttribute("popovertarget")) return false;
142
+ }
143
+ function removeInstance(instances, element) {
144
+ instances.get(element)?.destroy();
145
+ instances.delete(element);
146
+ }
147
+ function removeMenu(element) {
148
+ removeInstance(menus, element);
149
+ }
150
+ function removeMenubar(element) {
151
+ removeInstance(menubars, element);
152
+ }
153
+ const ATTRIBUTE_MENU = "oui-menu";
154
+ const ATTRIBUTE_MENU_POSITION = "oui-menu-position";
155
+ const ATTRIBUTE_MENUBAR = "oui-menubar";
156
+ const SELECTOR_MENUBAR = `[${ATTRIBUTE_MENUBAR}]`;
157
+ const SELECTOR_MENUBAR_ITEM = `:scope > [${ATTRIBUTE_MENUBAR}-item], :scope > * > [${ATTRIBUTE_MENUBAR}-item]`;
158
+ const SELECTOR_MENU_CONTENT = `[${ATTRIBUTE_MENU}-content]`;
159
+ const SELECTOR_MENU_ITEM = `:scope > [${ATTRIBUTE_MENU}-item], :scope > * > [${ATTRIBUTE_MENU}-item]`;
160
+ const SELECTOR_MENU_TOGGLE = `[${ATTRIBUTE_MENU}-toggle]`;
161
+ const SELECTORS = `${SELECTOR_MENUBAR}, ${SELECTOR_MENU_CONTENT}`;
162
+ const menubars = /* @__PURE__ */ new WeakMap();
163
+ const menus = /* @__PURE__ */ new WeakMap();
164
+ let index = 0;
165
+ attributable(ATTRIBUTE_MENU, addMenu, removeMenu);
166
+ attributable(ATTRIBUTE_MENUBAR, addMenubar, removeMenubar);
167
+ //#endregion
168
+ export {};
@@ -1,2 +1,2 @@
1
- import { g as createMovable, h as OuiMovable, m as ATTRIBUTE_MOVABLE_HANDLE, p as ATTRIBUTE_MOVABLE } from "../draggable-zszaW1qS.mjs";
1
+ import { g as createMovable, h as OuiMovable, m as ATTRIBUTE_MOVABLE_HANDLE, p as ATTRIBUTE_MOVABLE } from "../draggable-fIYXd8eO.mjs";
2
2
  export { ATTRIBUTE_MOVABLE, ATTRIBUTE_MOVABLE_HANDLE, OuiMovable, createMovable };
@@ -1,16 +1,15 @@
1
1
  import { attributable } from "../internal/attributable.mjs";
2
2
  import { OuiDraggable, addDraggable, getDraggableStates, removeDraggable } from "../internal/draggable.mjs";
3
3
  import { getPosition, on } from "@oscarpalmer/toretto/event";
4
+ import { setAttribute } from "@oscarpalmer/toretto/attribute";
4
5
  import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
6
+ import { getStyles, setStyle, setStyles } from "@oscarpalmer/toretto/style";
5
7
  //#region src/js/movable/movable.embedded.ts
6
8
  var OuiMovable = class extends OuiDraggable {
7
9
  #element;
8
10
  #style;
9
11
  constructor(element, options) {
10
- const style = {
11
- inset: element.style.inset,
12
- position: element.style.position
13
- };
12
+ const style = getStyles(element, ["inset", "position"]);
14
13
  super("movable", "move", ATTRIBUTE_MOVABLE, element, {
15
14
  container: {
16
15
  attribute: ATTRIBUTE_CONTAINER,
@@ -52,8 +51,7 @@ var OuiMovable = class extends OuiDraggable {
52
51
  */
53
52
  destroy() {
54
53
  MOVED.delete(this);
55
- this.#element.style.inset = this.#style.inset;
56
- this.#element.style.position = this.#style.position;
54
+ setStyles(this.#element, this.#style);
57
55
  this.#element = void 0;
58
56
  this.#style = void 0;
59
57
  super.destroy();
@@ -98,11 +96,8 @@ function onCancel(globals, item) {
98
96
  x: 0,
99
97
  y: 0
100
98
  };
101
- if (moved) element.style.inset = `${y}px auto auto ${x}px`;
102
- else {
103
- element.style.position = style.position;
104
- element.style.inset = style.inset;
105
- }
99
+ if (moved) setStyle(element, "inset", `${y}px auto auto ${x}px`);
100
+ else setStyles(element, style);
106
101
  element.removeAttribute(ATTRIBUTE_MOVING);
107
102
  }
108
103
  function onEnd(event, globals, item, reset) {
@@ -129,7 +124,7 @@ function onEnd(event, globals, item, reset) {
129
124
  });
130
125
  }
131
126
  function onMove(_, globals, __, position) {
132
- globals.element?.node.setAttribute(ATTRIBUTE_MOVING, "");
127
+ setAttribute(globals.element?.node, ATTRIBUTE_MOVING, "");
133
128
  return {
134
129
  from: { ...globals.original },
135
130
  to: { ...position.calculated }
@@ -153,7 +148,7 @@ function reposition(movable) {
153
148
  const container = state.container.getBoundingClientRect();
154
149
  const x = container.left + (state.offset?.x ?? 0);
155
150
  const y = container.top + (state.offset?.y ?? 0);
156
- state.element.style.inset = `${y}px auto auto ${x}px`;
151
+ setStyle(state.element, "inset", `${y}px auto auto ${x}px`);
157
152
  }
158
153
  function setOffset(state, container) {
159
154
  state.offset = {};
@@ -1,2 +1,2 @@
1
- import { g as createMovable, h as OuiMovable, t as CreateOuiDraggableOptions } from "../draggable-zszaW1qS.mjs";
1
+ import { g as createMovable, h as OuiMovable, t as CreateOuiDraggableOptions } from "../draggable-fIYXd8eO.mjs";
2
2
  export { type CreateOuiDraggableOptions as CreateOuiMovableOptions, type OuiMovable, createMovable };
@@ -1,4 +1,4 @@
1
- import { i as OuiFloatable } from "./floatable.embedded-YxGwzgbE.mjs";
1
+ import { r as OuiFloatable } from "./floatable.embedded-DUR8bQBK.mjs";
2
2
  import { i as OuiFocusTrap } from "./focus-trap.embedded-DR8NpZfr.mjs";
3
3
  import { RemovableEventListener } from "@oscarpalmer/toretto/models";
4
4
 
@@ -1,7 +1,9 @@
1
1
  import { createEmbeddedFloatable, getOnBeforeToggleListener } from "./floatable/floatable.embedded.mjs";
2
2
  import { attributable } from "./internal/attributable.mjs";
3
3
  import { createFocusTrap } from "./focus-trap/focus-trap.embedded.mjs";
4
+ import { getAria, setAria } from "@oscarpalmer/toretto/aria";
4
5
  import { on } from "@oscarpalmer/toretto/event";
6
+ import { setAttribute } from "@oscarpalmer/toretto/attribute";
5
7
  import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
6
8
  //#region src/js/popover.ts
7
9
  var OuiPopover = class {
@@ -18,6 +20,7 @@ var OuiPopover = class {
18
20
  }
19
21
  constructor(state) {
20
22
  this.#state = state;
23
+ initialize(state);
21
24
  this.#state.floatable.update();
22
25
  }
23
26
  /**
@@ -49,6 +52,14 @@ function destroyPopover(state) {
49
52
  state.listeners = void 0;
50
53
  state.popover = void 0;
51
54
  }
55
+ function getId(element, value) {
56
+ let { id } = element;
57
+ if (id == null || id.trim().length === 0) {
58
+ id = value == null ? `oui_popover_${++index}` : `${value}_toggle`;
59
+ element.id = id;
60
+ }
61
+ return id;
62
+ }
52
63
  /**
53
64
  * Get the _OuiPopover_ for an element
54
65
  *
@@ -63,23 +74,30 @@ function getState(anchor, content) {
63
74
  anchor,
64
75
  content,
65
76
  floatable: createEmbeddedFloatable(anchor, content, options),
66
- focusTrap: content.getAttribute(ARIA_MODAL) === TRUE ? createFocusTrap(content, { noescape: true }) : void 0,
67
- listeners: [getOnBeforeToggleListener(content), on(content, EVENT_TOGGLE, (event) => {
68
- if (event.newState === STATE_OPEN) {
77
+ focusTrap: getAria(content, "modal") === "true" ? createFocusTrap(content, { noescape: true }) : void 0,
78
+ listeners: [getOnBeforeToggleListener(content), on(content, "toggle", (event) => {
79
+ const expanded = event.newState === "open";
80
+ if (expanded) {
69
81
  ignoreFocus = false;
70
82
  state.floatable?.update();
71
- content.setAttribute(ATTRIBUTE_OPEN, "");
72
83
  content.focus();
73
- } else {
74
- content.removeAttribute(ATTRIBUTE_OPEN);
75
- if (!ignoreFocus) anchor?.focus();
76
- }
84
+ } else if (!ignoreFocus) anchor?.focus();
85
+ setAria(anchor, "expanded", expanded);
86
+ setAttribute(content, ATTRIBUTE_OPEN, expanded ? "" : void 0);
77
87
  })],
78
88
  popover: void 0
79
89
  };
80
90
  state.popover = new OuiPopover(state);
81
91
  return state;
82
92
  }
93
+ function initialize(state) {
94
+ const id = getId(state.content);
95
+ setAria(state.anchor, {
96
+ controls: id,
97
+ expanded: "false"
98
+ });
99
+ if ((getAria(state.content, "label") ?? getAria(state.content, "labelledby")) == null) setAria(state.content, "labelledby", getId(state.anchor, id));
100
+ }
83
101
  function onPointerdown() {
84
102
  ignoreFocus = true;
85
103
  }
@@ -90,11 +108,7 @@ function removePopover(element) {
90
108
  states.delete(element);
91
109
  }
92
110
  const ATTRIBUTE = "oui-popover";
93
- const ARIA_MODAL = "aria-modal";
94
111
  const ATTRIBUTE_OPEN = `${ATTRIBUTE}-open`;
95
- const EVENT_TOGGLE = "toggle";
96
- const STATE_OPEN = "open";
97
- const TRUE = "true";
98
112
  const options = {
99
113
  attribute: `${ATTRIBUTE}position`,
100
114
  position: "below-start",
@@ -102,6 +116,7 @@ const options = {
102
116
  };
103
117
  const states = /* @__PURE__ */ new WeakMap();
104
118
  let ignoreFocus = false;
119
+ let index = 0;
105
120
  on(document, "pointerdown", onPointerdown, { capture: true });
106
121
  attributable(ATTRIBUTE, addPopover, removePopover);
107
122
  //#endregion
@@ -0,0 +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";
2
+ export { CreateOuiResizableOptions, OuiResizable, RESIZABLE_ATTRIBUTE, RESIZABLE_ATTRIBUTE_HANDLE, createResizable };
@@ -0,0 +1,191 @@
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
+ import { getNumber } from "@oscarpalmer/atoms/number";
8
+ import { findAncestor } from "@oscarpalmer/toretto/find";
9
+ import supportsTouch from "@oscarpalmer/toretto/touch";
10
+ //#region src/js/resizable/resizable.embedded.ts
11
+ var OuiResizable = class {
12
+ #state;
13
+ constructor(state) {
14
+ this.#state = state;
15
+ }
16
+ destroy() {
17
+ destroyResizable(this.#state);
18
+ }
19
+ set() {
20
+ const [width, height] = getAndSetDimensions(this.#state.element, this.#state.options);
21
+ console.log("set", width, height);
22
+ this.#state.width = width;
23
+ this.#state.height = height;
24
+ }
25
+ reset() {
26
+ setStyles(this.#state.element, {
27
+ height: "",
28
+ width: ""
29
+ });
30
+ }
31
+ };
32
+ function addResizable(element, options) {
33
+ let item = items.get(element);
34
+ if (item == null) {
35
+ const handle = element.querySelector(SELECTOR_HANDLE_SCOPED);
36
+ if (!isHTMLOrSVGElement(handle)) return;
37
+ const state = getState(element, handle, options);
38
+ item = {
39
+ instance: new OuiResizable(state),
40
+ state
41
+ };
42
+ items.set(element, item);
43
+ }
44
+ return item?.instance;
45
+ }
46
+ /**
47
+ * Creates _(or retrieves)_ a _OuiResizable_ instance for an element
48
+ *
49
+ * @param element Element to make resizable
50
+ * @returns _OuiResizable_ instance
51
+ */
52
+ function createResizable(element, options) {
53
+ if (!isHTMLOrSVGElement(element)) throw new TypeError(MESSAGE_ELEMENT);
54
+ if (!isHTMLOrSVGElement(element.querySelector(SELECTOR_HANDLE_SCOPED))) throw new Error(MESSAGE_HANDLE);
55
+ return addResizable(element, options ?? {});
56
+ }
57
+ function destroyResizable(state) {
58
+ state.element = void 0;
59
+ state.handle = void 0;
60
+ }
61
+ function getAndSetDimensions(element, options, input) {
62
+ let { height, width } = input ?? element.getBoundingClientRect();
63
+ if (options.maximumWidth > -1 && width > options.maximumWidth) width = options.maximumWidth;
64
+ else if (options.minimumWidth > -1 && width < options.minimumWidth) width = options.minimumWidth;
65
+ if (options.maximumHeight > -1 && height > options.maximumHeight) height = options.maximumHeight;
66
+ else if (options.minimumHeight > -1 && height < options.minimumHeight) height = options.minimumHeight;
67
+ if (element.checkVisibility()) setStyles(element, {
68
+ height: `${height}px`,
69
+ width: `${width}px`
70
+ });
71
+ return [width, height];
72
+ }
73
+ function getProperties(element, widthProperty, heightProperty) {
74
+ const computed = getComputedStyle(element);
75
+ return [computed[widthProperty], computed[heightProperty]];
76
+ }
77
+ function getRestrictions(maximum, minimum) {
78
+ const [maximumWidth, maximumHeight] = getXAndY.apply(null, typeof maximum === "string" ? [maximum] : maximum);
79
+ const [minimumWidth, minimumHeight] = getXAndY.apply(null, typeof minimum === "string" ? [minimum] : minimum);
80
+ if (maximumWidth > -1 && minimumWidth > -1 && maximumWidth <= minimumWidth) throw new Error(MESSAGE_WIDTH);
81
+ if (maximumHeight > -1 && minimumHeight > -1 && maximumHeight <= minimumHeight) throw new Error(MESSAGE_HEIGHT);
82
+ return {
83
+ maximumHeight,
84
+ maximumWidth,
85
+ minimumHeight,
86
+ minimumWidth
87
+ };
88
+ }
89
+ function getState(element, handle, input) {
90
+ setAttribute(element, RESIZABLE_ATTRIBUTE, "");
91
+ const options = getValidOptions(element, input);
92
+ const [width, height] = getAndSetDimensions(element, options);
93
+ return {
94
+ element,
95
+ handle,
96
+ height,
97
+ options,
98
+ width,
99
+ styles: toggleStyles(element, styles)
100
+ };
101
+ }
102
+ function getValidOptions(element, input) {
103
+ const original = isPlainObject(input) ? input : {};
104
+ return { ...getRestrictions(input == null ? getAttribute(element, ATTRIBUTE_MAXIMUM) ?? getProperties(element, "maxWidth", "maxHeight") : [original.maximumWidth, original.maximumHeight], input == null ? getAttribute(element, ATTRIBUTE_MINIMUM) ?? getProperties(element, "minWidth", "minHeight") : [original.minimumWidth, original.minimumHeight]) };
105
+ }
106
+ function getXAndY(first, second) {
107
+ const [x, y] = typeof first === "string" && second == null ? first.split(",") : [first, second];
108
+ let xAsNumber = typeof x === "string" ? Number.parseFloat(x) : getNumber(x);
109
+ let yAsNumber = typeof y === "string" ? Number.parseFloat(y) : getNumber(y);
110
+ if (Number.isNaN(xAsNumber) || xAsNumber <= 0) xAsNumber = -1;
111
+ if (Number.isNaN(yAsNumber) || yAsNumber <= 0) yAsNumber = -1;
112
+ return [xAsNumber, yAsNumber];
113
+ }
114
+ 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();
121
+ }
122
+ function onPointerdown(event) {
123
+ if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey || (supportsTouch.value ? event.type === "mousedown" : event.type === "touchstart" || event.button !== 0)) return;
124
+ const handle = findAncestor(event, SELECTOR_HANDLE);
125
+ const element = handle && findAncestor(handle, SELECTOR);
126
+ const stored = element && items.get(element);
127
+ const position = getPosition(event);
128
+ if (stored == null || position == null) return;
129
+ if (supportsTouch.value) event.preventDefault();
130
+ current = stored;
131
+ start = position;
132
+ current.state.styles.set();
133
+ styleToggler.set();
134
+ }
135
+ function onPointermove(event) {
136
+ if (current == null) return;
137
+ const { x, y } = getPosition(event) ?? {};
138
+ if (x == null || y == null) return;
139
+ const width = current.state.width + (x - (start?.x ?? 0));
140
+ const height = current.state.height + (y - (start?.y ?? 0));
141
+ getAndSetDimensions(current.state.element, current.state.options, {
142
+ height,
143
+ width
144
+ });
145
+ }
146
+ function onPointerup() {
147
+ if (current == null) return;
148
+ const { height, width } = current.state.element.getBoundingClientRect();
149
+ current.state.height = height;
150
+ current.state.width = width;
151
+ resetResizable();
152
+ }
153
+ function removeResizable(element) {
154
+ items.get(element)?.instance.destroy();
155
+ items.delete(element);
156
+ }
157
+ function resetResizable() {
158
+ current?.state.styles.remove();
159
+ styleToggler.remove();
160
+ current = void 0;
161
+ start = void 0;
162
+ }
163
+ const RESIZABLE_ATTRIBUTE = "oui-resizable";
164
+ const RESIZABLE_ATTRIBUTE_HANDLE = `${RESIZABLE_ATTRIBUTE}-handle`;
165
+ const ATTRIBUTE_MAXIMUM = `${RESIZABLE_ATTRIBUTE}-maximum`;
166
+ const ATTRIBUTE_MINIMUM = `${RESIZABLE_ATTRIBUTE}-minimum`;
167
+ const MESSAGE_ELEMENT = "The element must be an instance of HTMLElement or SVGElement";
168
+ const MESSAGE_HEIGHT = "The maximum height must be greater than the minimum height";
169
+ const MESSAGE_HANDLE = `The element must contain a child with the attribute "${RESIZABLE_ATTRIBUTE_HANDLE}"`;
170
+ const MESSAGE_WIDTH = "The maximum width must be greater than the minimum width";
171
+ const SELECTOR = `[${RESIZABLE_ATTRIBUTE}]`;
172
+ const SELECTOR_HANDLE = `[${RESIZABLE_ATTRIBUTE_HANDLE}]`;
173
+ const SELECTOR_HANDLE_SCOPED = `:scope > ${SELECTOR_HANDLE}`;
174
+ const items = /* @__PURE__ */ new WeakMap();
175
+ const styles = {
176
+ touchAction: "none",
177
+ userSelect: "none",
178
+ webkitUserSelect: "none"
179
+ };
180
+ const styleToggler = toggleStyles(document.body, styles);
181
+ let current;
182
+ let start;
183
+ on(document, "keydown", onKeydown);
184
+ on(document, "mousedown", onPointerdown);
185
+ on(document, "pointermove", onPointermove);
186
+ on(document, "pointerup", onPointerup);
187
+ on(document, "touchcancel", onPointerup);
188
+ on(document, "touchstart", onPointerdown, { passive: false });
189
+ attributable(RESIZABLE_ATTRIBUTE, addResizable, removeResizable);
190
+ //#endregion
191
+ export { OuiResizable, RESIZABLE_ATTRIBUTE, RESIZABLE_ATTRIBUTE_HANDLE, createResizable };
@@ -0,0 +1,2 @@
1
+ import { a as createResizable, n as OuiResizable, t as CreateOuiResizableOptions } from "../resizable.embedded-CXrUVPzR.mjs";
2
+ export { type CreateOuiResizableOptions, type OuiResizable, createResizable as createOuiResizable };
@@ -0,0 +1,2 @@
1
+ import { createResizable } from "./resizable.embedded.mjs";
2
+ export { createResizable as createOuiResizable };
@@ -0,0 +1,35 @@
1
+ import { StyleToggler } from "@oscarpalmer/toretto/style";
2
+
3
+ //#region src/js/resizable/resizable.embedded.d.ts
4
+ type CreateOuiResizableOptions = {
5
+ maximumHeight?: number;
6
+ maximumWidth?: number;
7
+ minimumHeight?: number;
8
+ minimumWidth?: number;
9
+ };
10
+ declare class OuiResizable {
11
+ #private;
12
+ constructor(state: OuiResizableState);
13
+ destroy(): void;
14
+ set(): void;
15
+ reset(): void;
16
+ }
17
+ type OuiResizableState = {
18
+ element: HTMLElement;
19
+ handle: HTMLElement;
20
+ height: number;
21
+ options: Required<CreateOuiResizableOptions>;
22
+ styles: StyleToggler;
23
+ width: number;
24
+ };
25
+ /**
26
+ * Creates _(or retrieves)_ a _OuiResizable_ instance for an element
27
+ *
28
+ * @param element Element to make resizable
29
+ * @returns _OuiResizable_ instance
30
+ */
31
+ declare function createResizable(element: HTMLElement, options?: CreateOuiResizableOptions): OuiResizable;
32
+ declare const RESIZABLE_ATTRIBUTE = "oui-resizable";
33
+ declare const RESIZABLE_ATTRIBUTE_HANDLE = "oui-resizable-handle";
34
+ //#endregion
35
+ export { createResizable as a, RESIZABLE_ATTRIBUTE_HANDLE as i, OuiResizable as n, RESIZABLE_ATTRIBUTE as r, CreateOuiResizableOptions as t };
@@ -1,2 +1,2 @@
1
- import { d as OuiSortable, f as createSortable } from "../draggable-zszaW1qS.mjs";
1
+ import { d as OuiSortable, f as createSortable } from "../draggable-fIYXd8eO.mjs";
2
2
  export { OuiSortable, createSortable };
@@ -1,7 +1,9 @@
1
1
  import { attributable } from "../internal/attributable.mjs";
2
2
  import { OuiDraggable, addDraggable, getDraggableStates, removeDraggable } from "../internal/draggable.mjs";
3
3
  import { getPosition } from "@oscarpalmer/toretto/event";
4
+ import { getAttribute, setAttribute, setAttributes } from "@oscarpalmer/toretto/attribute";
4
5
  import { isHTMLOrSVGElement } from "@oscarpalmer/toretto/is";
6
+ import { setStyle } from "@oscarpalmer/toretto/style";
5
7
  import { findAncestor, getElementFromPosition } from "@oscarpalmer/toretto/find";
6
8
  import { createElement } from "@oscarpalmer/toretto/create";
7
9
  //#region src/js/sortable/sortable.embedded.ts
@@ -26,7 +28,7 @@ var OuiSortable = class extends OuiDraggable {
26
28
  },
27
29
  getDragged: getDragPlaceholder,
28
30
  getOrigin: () => (getDraggableStates(element)?.sortable)?.origin
29
- }, { connections: element.getAttribute(ATTRIBUTE_CONNECTIONS) });
31
+ }, { connections: getAttribute(element, ATTRIBUTE_CONNECTIONS) });
30
32
  }
31
33
  };
32
34
  function afterEnd(insert, from, events, elements, position, valid) {
@@ -72,15 +74,15 @@ function getOriginalPosition(_, __, position) {
72
74
  }
73
75
  function getPositionPlaceholder(item) {
74
76
  placeholder.position ??= createElement("div");
75
- placeholder.position.setAttribute(ATTRIBUTE_PLACEHOLDER_POSITION, "");
76
- if (item.state.origin != null) placeholder.position.style.setProperty("--placeholder-height", `${item.state.origin.getBoundingClientRect().height}px`);
77
+ setAttribute(placeholder.position, ATTRIBUTE_PLACEHOLDER_POSITION, "");
78
+ if (item.state.origin != null) setStyle(placeholder.position, "--placeholder-height", `${item.state.origin.getBoundingClientRect().height}px`);
77
79
  return placeholder.position;
78
80
  }
79
81
  function onBegin(_, globals, item, element) {
80
82
  item.state.origin = element;
81
83
  setPlaceholder(globals, item, element);
82
- element.setAttribute(ATTRIBUTE_ORIGIN, "");
83
- document.body.setAttribute(ATTRIBUTE_ACTIVE, "");
84
+ setAttribute(element, ATTRIBUTE_ORIGIN, "");
85
+ setAttribute(document.body, ATTRIBUTE_ACTIVE, "");
84
86
  }
85
87
  function onCancel(_, item) {
86
88
  item.state.origin?.removeAttribute(ATTRIBUTE_ORIGIN);
@@ -96,7 +98,7 @@ function onEnd(event, globals, item, reset) {
96
98
  };
97
99
  const target = getElementFromPosition(position)[0];
98
100
  let element = findAncestor(target, SELECTOR_ITEM);
99
- if (element?.hasAttribute(ATTRIBUTE_PLACEHOLDER_POSITION)) if (element.getAttribute(ATTRIBUTE_PLACEHOLDER_POSITION) === "after") element = element.previousElementSibling;
101
+ if (element?.hasAttribute(ATTRIBUTE_PLACEHOLDER_POSITION)) if (getAttribute(element, ATTRIBUTE_PLACEHOLDER_POSITION) === "after") element = element.previousElementSibling;
100
102
  else element = element.nextElementSibling;
101
103
  let insert = "insert";
102
104
  let toInstance;
@@ -168,7 +170,7 @@ function onMove(event, globals, item, position) {
168
170
  place = "after";
169
171
  toElement.insertAdjacentElement(INSERT_AFTER, placeholder);
170
172
  }
171
- placeholder.setAttribute(ATTRIBUTE_PLACEHOLDER_POSITION, place);
173
+ setAttribute(placeholder, ATTRIBUTE_PLACEHOLDER_POSITION, place);
172
174
  } else placeholder.remove();
173
175
  return {
174
176
  from: {
@@ -216,14 +218,14 @@ function setPlaceholder(state, item, origin) {
216
218
  });
217
219
  }
218
220
  function updatePlaceholder(item, element) {
219
- element.style.position = "fixed";
220
- element.setAttribute(ATTRIBUTE_PLACEHOLDER_DRAG, "");
221
+ setAttribute(element, ATTRIBUTE_PLACEHOLDER_DRAG, "");
222
+ setStyle(element, "position", "fixed");
221
223
  const state = getDraggableStates(item.state.element)?.sortable;
222
224
  if (state == null) return;
223
- if (state.horizontal) element.setAttribute(ATTRIBUTE_HORIZONTAL, "");
224
- else element.removeAttribute(ATTRIBUTE_HORIZONTAL);
225
- if (state.vertical) element.setAttribute(ATTRIBUTE_VERTICAL, "");
226
- else element.removeAttribute(ATTRIBUTE_VERTICAL);
225
+ setAttributes(element, {
226
+ [ATTRIBUTE_HORIZONTAL]: state.horizontal ? "" : void 0,
227
+ [ATTRIBUTE_VERTICAL]: state.vertical ? "" : void 0
228
+ });
227
229
  }
228
230
  function validatePosition(_, from, to, position) {
229
231
  let valid = true;
@@ -1,2 +1,2 @@
1
- import { d as OuiSortable, f as createSortable, t as CreateOuiDraggableOptions } from "../draggable-zszaW1qS.mjs";
1
+ import { d as OuiSortable, f as createSortable, t as CreateOuiDraggableOptions } from "../draggable-fIYXd8eO.mjs";
2
2
  export { type CreateOuiDraggableOptions as CreateOuiSortableOptions, type OuiSortable, createSortable };