@oscarpalmer/oui 0.19.0 → 0.21.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 (63) hide show
  1. package/dist/css/a11y.css +0 -1
  2. package/dist/css/form.css +0 -1
  3. package/dist/css/popover.css +22 -0
  4. package/dist/css/reset.css +8 -8
  5. package/dist/css/table.css +1 -1
  6. package/dist/css/tooltip.css +43 -0
  7. package/dist/js/focus-trap/embedded.d.mts +26 -0
  8. package/dist/js/focus-trap/{embedded.js → embedded.mjs} +11 -9
  9. package/dist/js/focus-trap/standalone.d.mts +1 -0
  10. package/dist/js/focus-trap/{standalone.js → standalone.mjs} +5 -2
  11. package/dist/js/index.d.mts +4 -0
  12. package/dist/js/index.mjs +7 -0
  13. package/dist/js/internal/attributable.d.mts +4 -0
  14. package/dist/js/{attributable.full.js → internal/attributable.mjs} +8 -1
  15. package/dist/js/internal/draggable.d.mts +2 -0
  16. package/dist/js/internal/draggable.mjs +212 -0
  17. package/dist/js/internal/floatable.d.mts +26 -0
  18. package/dist/js/{floatable.js → internal/floatable.mjs} +73 -50
  19. package/dist/js/movable-BEo2LbUI.d.mts +101 -0
  20. package/dist/js/movable.d.mts +2 -0
  21. package/dist/js/movable.mjs +152 -0
  22. package/dist/js/popover.d.mts +20 -0
  23. package/dist/js/{popover.js → popover.mjs} +10 -8
  24. package/dist/js/sortable.d.mts +2 -0
  25. package/dist/js/sortable.mjs +243 -0
  26. package/dist/js/splitter.d.mts +25 -0
  27. package/dist/js/{splitter.js → splitter.mjs} +62 -60
  28. package/dist/js/tooltip.d.mts +4 -0
  29. package/dist/js/{tooltip.js → tooltip.mjs} +22 -20
  30. package/package.json +66 -69
  31. package/src/css/mixins.scss +30 -1
  32. package/src/css/popover.scss +6 -1
  33. package/src/css/reset.scss +4 -4
  34. package/src/css/table.scss +1 -1
  35. package/src/css/tooltip.scss +55 -1
  36. package/src/js/focus-trap/embedded.ts +4 -10
  37. package/src/js/focus-trap/standalone.ts +1 -1
  38. package/src/js/index.ts +3 -1
  39. package/src/js/{attributable.ts → internal/attributable.ts} +11 -1
  40. package/src/js/internal/draggable.ts +515 -0
  41. package/src/js/{floatable.ts → internal/floatable.ts} +141 -63
  42. package/src/js/movable.ts +260 -0
  43. package/src/js/popover.ts +1 -1
  44. package/src/js/sortable.ts +467 -0
  45. package/src/js/splitter.ts +3 -9
  46. package/src/js/tooltip.ts +11 -9
  47. package/dist/js/attributable.js +0 -36
  48. package/dist/js/floatable.full.js +0 -398
  49. package/dist/js/focus-trap/embedded.full.js +0 -408
  50. package/dist/js/focus-trap/standalone.full.js +0 -447
  51. package/dist/js/index.js +0 -5
  52. package/dist/js/oui.full.js +0 -1573
  53. package/dist/js/popover.full.js +0 -760
  54. package/dist/js/splitter.full.js +0 -769
  55. package/dist/js/tooltip.full.js +0 -613
  56. package/types/attributable.d.ts +0 -1
  57. package/types/floatable.d.ts +0 -24
  58. package/types/focus-trap/embedded.d.ts +0 -24
  59. package/types/focus-trap/standalone.d.ts +0 -1
  60. package/types/index.d.ts +0 -4
  61. package/types/popover.d.ts +0 -17
  62. package/types/splitter.d.ts +0 -23
  63. package/types/tooltip.d.ts +0 -2
package/package.json CHANGED
@@ -1,90 +1,87 @@
1
1
  {
2
+ "name": "@oscarpalmer/oui",
3
+ "version": "0.21.0",
4
+ "description": "Styles, components, and utilities for building websites and applications.",
5
+ "keywords": [
6
+ "css",
7
+ "design",
8
+ "framework",
9
+ "library",
10
+ "scss",
11
+ "style",
12
+ "stylesheet",
13
+ "utility"
14
+ ],
15
+ "license": "MIT",
2
16
  "author": {
3
17
  "name": "Oscar Palmér",
4
18
  "url": "https://oscarpalmer.se"
5
19
  },
6
- "dependencies": {
7
- "@oscarpalmer/atoms": "^0.124",
8
- "@oscarpalmer/toretto": "^0.34"
9
- },
10
- "description": "Styles, components, and utilities for building websites and applications.",
11
- "devDependencies": {
12
- "@types/node": "^25",
13
- "@vitest/coverage-istanbul": "^4",
14
- "autoprefixer": "^10.4",
15
- "jsdom": "^27.4",
16
- "oxfmt": "^0.21",
17
- "oxlint": "^1.36",
18
- "postcss-cli": "^11",
19
- "postcss-input-range": "^6",
20
- "postcss-scss": "^4",
21
- "rolldown": "1.0.0-beta.57",
22
- "sass": "^1.97",
23
- "stylelint": "^16.26",
24
- "stylelint-config-standard-scss": "^16",
25
- "tslib": "^2.8",
26
- "typescript": "^5.9",
27
- "vite": "8.0.0-beta.5",
28
- "vitest": "^4"
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/oscarpalmer/oui.git"
29
23
  },
24
+ "files": [
25
+ "dist",
26
+ "src"
27
+ ],
28
+ "type": "module",
29
+ "module": "dist/js/index.mjs",
30
+ "types": "dist/js/index.d.mts",
30
31
  "exports": {
31
32
  ".": {
32
- "types": "./types/index.d.ts",
33
- "default": "./dist/js/index.js"
33
+ "types": "./dist/js/index.d.mts",
34
+ "default": "./dist/js/index.mjs"
34
35
  },
35
36
  "./focus-trap": {
36
- "types": "./types/focus-trap/standalone.d.ts",
37
- "default": "./dist/js/focus-trap/standalone.js"
37
+ "types": "./dist/js/focus-trap/standalone.d.mts",
38
+ "default": "./dist/js/focus-trap/standalone.mjs"
38
39
  },
39
40
  "./popover": {
40
- "types": "./types/popover.d.ts",
41
- "default": "./dist/js/popover.js"
41
+ "types": "./dist/js/popover.d.mts",
42
+ "default": "./dist/js/popover.mjs"
42
43
  },
43
44
  "./splitter": {
44
- "types": "./types/splitter.d.ts",
45
- "default": "./dist/js/splitter.js"
45
+ "types": "./dist/js/splitter.d.mts",
46
+ "default": "./dist/js/splitter.mjs"
46
47
  },
47
48
  "./tooltip": {
48
- "types": "./types/tooltip.d.ts",
49
- "default": "./dist/js/tooltip.js"
49
+ "types": "./dist/js/tooltip.d.mts",
50
+ "default": "./dist/js/tooltip.mjs"
50
51
  }
51
52
  },
52
- "files": [
53
- "dist",
54
- "src",
55
- "types"
56
- ],
57
- "keywords": [
58
- "css",
59
- "scss",
60
- "design",
61
- "framework",
62
- "library",
63
- "style",
64
- "stylesheet",
65
- "utility"
66
- ],
67
- "license": "MIT",
68
- "module": "dist/js/index.js",
69
- "name": "@oscarpalmer/oui",
70
- "repository": {
71
- "type": "git",
72
- "url": "git+https://github.com/oscarpalmer/oui.git"
73
- },
74
53
  "scripts": {
75
- "build": "npm run clean && npm run build:js && npm run build:css",
76
- "build:css": "npm run build:postcss && npx sass ./postcss:./dist/css --no-source-map",
77
- "build:postcss": "npx postcss ./src/css/*.scss -d ./postcss -u autoprefixer postcss-input-range --parser postcss-scss",
78
- "build:js": "npm run clean && npx vite build && npm run rolldown:build && npx tsc",
79
- "clean": "rm -rf ./dist && rm -rf ./types && rm -f ./tsconfig.tsbuildinfo",
80
- "rolldown:build": "npx rolldown -c",
81
- "rolldown:watch": "npx rolldown -c ./rolldown.config.js --watch",
82
- "test": "npx vitest --coverage",
83
- "watch:css": "npx sass ./postcss:./dist/css --no-source-map --watch",
84
- "watch:postcss": "npx postcss ./src/css/*.scss -d ./postcss -u autoprefixer postcss-input-range --parser postcss-scss --watch",
85
- "watch:js": "npx vite build --watch"
54
+ "build": "vp run clean && vp pack && vp run css:build",
55
+ "clean": "rm -rf ./dist && rm -rf ./postcss",
56
+ "css:build": "vp run postcss:build && vpx sass ./postcss:./dist/css --no-source-map",
57
+ "css:watch": "vpx sass ./postcss:./dist/css --no-source-map --watch",
58
+ "postcss:build": "vpx postcss ./src/css/*.scss -d ./postcss -u autoprefixer postcss-input-range --parser postcss-scss",
59
+ "postcss:watch": "vpx postcss ./src/css/*.scss -d ./postcss -u autoprefixer postcss-input-range --parser postcss-scss --watch",
60
+ "test": "vpx vitest --coverage",
61
+ "tsdown": "vpx tsdown -c ./tsdown.config.ts --watch",
62
+ "watch": "vp run clean && concurrently \"php -S localhost:3000\" \"vp run postcss:watch\" \"vp run css:watch\" \"vp run tsdown\""
86
63
  },
87
- "type": "module",
88
- "types": "types/index.d.ts",
89
- "version": "0.19.0"
64
+ "dependencies": {
65
+ "@oscarpalmer/atoms": "^0.187.2",
66
+ "@oscarpalmer/toretto": "^0.46"
67
+ },
68
+ "devDependencies": {
69
+ "@oxlint/plugins": "^1.67",
70
+ "@vitest/coverage-istanbul": "^4.1",
71
+ "autoprefixer": "^10.5",
72
+ "concurrently": "^9.2",
73
+ "jsdom": "^29.1",
74
+ "postcss-cli": "^11",
75
+ "postcss-input-range": "^6",
76
+ "postcss-scss": "^4",
77
+ "sass": "^1.100",
78
+ "stylelint": "^17.11",
79
+ "stylelint-config-standard-scss": "^17",
80
+ "tsdown": "^0.22",
81
+ "typescript": "^6",
82
+ "vite": "npm:@voidzero-dev/vite-plus-core@latest",
83
+ "vite-plus": "latest",
84
+ "vitest": "npm:@voidzero-dev/vite-plus-test@latest"
85
+ },
86
+ "packageManager": "npm@11.12.1"
90
87
  }
@@ -51,6 +51,36 @@
51
51
  border-radius: 0.5em;
52
52
  }
53
53
 
54
+ @mixin floatable() {
55
+ @include shadow-overlay;
56
+
57
+ --margin-left: 0;
58
+ --margin-top: 0;
59
+
60
+ margin: var(--margin-top, 0) 0 0 var(--margin-left, 0);
61
+ pointer-events: all !important;
62
+
63
+ &[position^='above'],
64
+ &[position^='top'] {
65
+ --margin-top: -0.5rem;
66
+ }
67
+
68
+ &[position^='below'],
69
+ &[position^='bottom'] {
70
+ --margin-top: 0.5rem;
71
+ }
72
+
73
+ &[position^='end'],
74
+ &[position^='right'] {
75
+ --margin-left: 0.5rem;
76
+ }
77
+
78
+ &[position^='left'],
79
+ &[position^='start'] {
80
+ --margin-left: -0.5rem;
81
+ }
82
+ }
83
+
54
84
  @mixin shadow($color: rgb(0 0 0 / 5%), $inset: transparent) {
55
85
  box-shadow:
56
86
  inset 0 1px 0 0 $inset,
@@ -83,7 +113,6 @@
83
113
  width: 1px !important;
84
114
  height: 1px !important;
85
115
  padding: 0 !important;
86
- clip: rect(1px, 1px 1px, 1px) !important;
87
116
  clip-path: inset(50%) !important;
88
117
  overflow: hidden !important;
89
118
  border: 0 !important;
@@ -1,13 +1,18 @@
1
1
  @use 'mixins.scss' as mixins;
2
2
 
3
3
  :where([oui-popover-content]) {
4
- @include mixins.shadow-overlay;
4
+ @include mixins.floatable;
5
5
 
6
6
  padding: 1rem;
7
+ overscroll-behavior: contain;
7
8
  background-color: var(--oui-absolute);
8
9
  border-radius: 0.5rem;
9
10
 
10
11
  &:focus {
11
12
  outline: none;
12
13
  }
14
+
15
+ * {
16
+ overscroll-behavior: contain;
17
+ }
13
18
  }
@@ -54,7 +54,7 @@
54
54
  /** Prevent text size inflation (e.g., after orientation change) [AB][RE][SE] */
55
55
  text-size-adjust: none;
56
56
  tab-size: 4;
57
- word-break: break-word;
57
+ overflow-wrap: break-word;
58
58
  }
59
59
 
60
60
  :where(body) {
@@ -104,7 +104,7 @@
104
104
  summary
105
105
  ) {
106
106
  /** Correct the inability to style clickable types in iOS [HR][RS][SE] */
107
- appearance: button;
107
+ appearance: auto;
108
108
  /** Ditto */
109
109
  cursor: pointer;
110
110
  }
@@ -171,7 +171,7 @@
171
171
  }
172
172
 
173
173
  :where(small, sub, sup) {
174
- font-size: 0.875rem;
174
+ font-size: 0.875em;
175
175
  }
176
176
 
177
177
  :where(sub, sup) {
@@ -271,7 +271,7 @@
271
271
 
272
272
  ::file-selector-button {
273
273
  /** Correct the inability to style upload buttons in iOS and Safari [RS][SE] */
274
- appearance: button;
274
+ appearance: auto;
275
275
  color: inherit;
276
276
  font: inherit;
277
277
  line-height: 1.25;
@@ -9,10 +9,10 @@
9
9
  :where(&_wrapper) {
10
10
  max-height: 32em;
11
11
  overflow: auto;
12
+ overscroll-behavior: contain;
12
13
  border: 1px solid var(--oui-gray-3);
13
14
  border-radius: 0.25em;
14
15
  position: relative;
15
- overscroll-behavior-y: none;
16
16
  }
17
17
 
18
18
  :where(& caption) {
@@ -29,7 +29,7 @@
29
29
  }
30
30
 
31
31
  :where([oui-tooltip-content]) {
32
- @include mixins.shadow-overlay;
32
+ @include mixins.floatable;
33
33
 
34
34
  max-width: 48ch;
35
35
  padding: 0.75em 1em;
@@ -39,6 +39,60 @@
39
39
  font-size: 0.875rem;
40
40
  transition: opacity 0.125s ease-in-out;
41
41
  transition-delay: 0s;
42
+
43
+ &::after {
44
+ content: '';
45
+ opacity: 0;
46
+ position: absolute;
47
+ }
48
+
49
+ &[position^='above'],
50
+ &[position^='below'],
51
+ &[position^='bottom'],
52
+ &[position^='top'] {
53
+ &::after {
54
+ width: 100%;
55
+ height: 0.5rem;
56
+ }
57
+ }
58
+
59
+ &[position^='above'],
60
+ &[position^='top'] {
61
+ &::after {
62
+ inset: 100% 0 0;
63
+ }
64
+ }
65
+
66
+ &[position^='below'],
67
+ &[position^='bottom'] {
68
+ &::after {
69
+ inset: -5rem 0 0;
70
+ }
71
+ }
72
+
73
+ &[position^='end'],
74
+ &[position^='left'],
75
+ &[position^='right'],
76
+ &[position^='start'] {
77
+ &::after {
78
+ width: 0.5rem;
79
+ height: 100%;
80
+ }
81
+ }
82
+
83
+ &[position^='end'],
84
+ &[position^='right'] {
85
+ &::after {
86
+ inset: 0 0 0 -0.5rem;
87
+ }
88
+ }
89
+
90
+ &[position^='left'],
91
+ &[position^='start'] {
92
+ &::after {
93
+ inset: 0 0 0 100%;
94
+ }
95
+ }
42
96
  }
43
97
 
44
98
  :where([oui-tooltip-content][oui-tooltip-content-active]) {
@@ -83,7 +83,7 @@ export function createFocusTrap(element: HTMLElement, options?: Options): FocusT
83
83
  }
84
84
 
85
85
  function onEscape(event: KeyboardEvent): void {
86
- let element = findAncestor(event.target as HTMLElement, ATTRIBUTE_SELECTOR) as HTMLElement;
86
+ let element = findAncestor(event, ATTRIBUTE_SELECTOR) as HTMLElement;
87
87
 
88
88
  let focusTrap = FOCUSTRAPS_ALL.get(element);
89
89
 
@@ -112,9 +112,7 @@ function onEscape(event: KeyboardEvent): void {
112
112
  }
113
113
 
114
114
  function onFocusIn(event: Event): void {
115
- const focusTrap = FOCUSTRAPS_ALL.get(
116
- findAncestor(event.target as HTMLElement, ATTRIBUTE_SELECTOR) as HTMLElement,
117
- );
115
+ const focusTrap = FOCUSTRAPS_ALL.get(findAncestor(event, ATTRIBUTE_SELECTOR) as HTMLElement);
118
116
 
119
117
  lastTarget = focusTrap == null ? undefined : (event.target as HTMLElement);
120
118
  }
@@ -136,11 +134,7 @@ function onKeydown(event: KeyboardEvent): void {
136
134
 
137
135
  function onPointerdown(event: MouseEvent | TouchEvent): void {
138
136
  const lastFocusTrap = findAncestor(lastTarget as HTMLElement, ATTRIBUTE_SELECTOR) as HTMLElement;
139
-
140
- const nextFocusTrap = findAncestor(
141
- event.target as HTMLElement,
142
- ATTRIBUTE_SELECTOR,
143
- ) as HTMLElement;
137
+ const nextFocusTrap = findAncestor(event, ATTRIBUTE_SELECTOR) as HTMLElement;
144
138
 
145
139
  if (lastFocusTrap != null && nextFocusTrap !== lastFocusTrap) {
146
140
  if (FOCUSTRAPS_ALL.get(lastFocusTrap)?.contain ?? false) {
@@ -162,7 +156,7 @@ function onPointerdown(event: MouseEvent | TouchEvent): void {
162
156
  }
163
157
 
164
158
  function onTab(event: KeyboardEvent): void {
165
- const element = findAncestor(event.target as HTMLElement, ATTRIBUTE_SELECTOR) as HTMLElement;
159
+ const element = findAncestor(event, ATTRIBUTE_SELECTOR) as HTMLElement;
166
160
 
167
161
  const focusTrap = FOCUSTRAPS_ALL.get(element);
168
162
 
@@ -1,4 +1,4 @@
1
- import {attributable} from '../attributable';
1
+ import {attributable} from '../internal/attributable';
2
2
  import {createFocusTrap, FOCUS_TRAP_SELECTOR, FOCUSTRAPS_ALL} from './embedded';
3
3
 
4
4
  function removeFocusTraps(element: HTMLElement): void {
package/src/js/index.ts CHANGED
@@ -1,4 +1,6 @@
1
- export * from './focus-trap/standalone';
1
+ import './focus-trap/standalone';
2
+ import './movable';
2
3
  export * from './popover';
4
+ import './sortable';
3
5
  export * from './splitter';
4
6
  export * from './tooltip';
@@ -49,6 +49,10 @@ function handleAdded(
49
49
  if (element.hasAttribute(attribute)) {
50
50
  add(element);
51
51
  }
52
+
53
+ if (element.hasChildNodes()) {
54
+ handleAdded(attribute, element.childNodes, add);
55
+ }
52
56
  }
53
57
  }
54
58
 
@@ -58,6 +62,12 @@ function handleRemoved(nodes: Node[] | NodeList, remove: (element: HTMLElement)
58
62
  const {length} = elements;
59
63
 
60
64
  for (let index = 0; index < length; index += 1) {
61
- remove(elements[index]);
65
+ const element = elements[index];
66
+
67
+ remove(element);
68
+
69
+ if (element.hasChildNodes()) {
70
+ handleRemoved(element.childNodes, remove);
71
+ }
62
72
  }
63
73
  }