@oscarpalmer/oui 0.29.1 → 0.31.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 (51) hide show
  1. package/dist/css/badge.css +4 -4
  2. package/dist/css/combobox.css +165 -0
  3. package/dist/css/form.css +18 -14
  4. package/dist/js/combobox.d.mts +91 -0
  5. package/dist/js/combobox.mjs +797 -0
  6. package/dist/js/dialog.d.mts +4 -3
  7. package/dist/js/dialog.mjs +1 -1
  8. package/dist/js/{draggable-fIYXd8eO.d.mts → draggable-a6w0J1OD.d.mts} +1 -2
  9. package/dist/js/floatable/floatable.embedded.d.mts +1 -1
  10. package/dist/js/floatable/floatable.embedded.mjs +2 -2
  11. package/dist/js/floatable/floatable.standalone.d.mts +1 -1
  12. package/dist/js/{floatable.embedded-DUR8bQBK.d.mts → floatable.embedded-Bct4U5Dm.d.mts} +0 -1
  13. package/dist/js/focus-trap/focus-trap.embedded.mjs +13 -9
  14. package/dist/js/index.d.mts +9 -4
  15. package/dist/js/index.mjs +2 -1
  16. package/dist/js/internal/draggable.d.mts +1 -1
  17. package/dist/js/internal/draggable.mjs +22 -21
  18. package/dist/js/internal/navigable.d.mts +0 -1
  19. package/dist/js/internal/navigable.mjs +4 -3
  20. package/dist/js/menu.mjs +5 -2
  21. package/dist/js/movable/movable.embedded.d.mts +1 -1
  22. package/dist/js/movable/movable.embedded.mjs +7 -12
  23. package/dist/js/movable/movable.standalone.d.mts +1 -1
  24. package/dist/js/popover.d.mts +1 -2
  25. package/dist/js/popover.mjs +1 -1
  26. package/dist/js/resizable/resizable.embedded.d.mts +1 -1
  27. package/dist/js/resizable/resizable.embedded.mjs +41 -20
  28. package/dist/js/resizable/resizable.standalone.d.mts +1 -1
  29. package/dist/js/{resizable.embedded-CXrUVPzR.d.mts → resizable.embedded-3qoR0Bjm.d.mts} +0 -1
  30. package/dist/js/sortable/sortable.embedded.d.mts +1 -1
  31. package/dist/js/sortable/sortable.embedded.mjs +28 -37
  32. package/dist/js/sortable/sortable.standalone.d.mts +1 -1
  33. package/dist/js/splitter.d.mts +2 -2
  34. package/dist/js/splitter.mjs +11 -11
  35. package/dist/js/tooltip.d.mts +1 -2
  36. package/dist/js/tooltip.mjs +3 -3
  37. package/package.json +7 -3
  38. package/src/css/badge.scss +1 -18
  39. package/src/css/combobox.scss +137 -0
  40. package/src/css/form.scss +18 -80
  41. package/src/css/mixins.scss +86 -0
  42. package/src/js/combobox.ts +1479 -0
  43. package/src/js/focus-trap/focus-trap.embedded.ts +19 -11
  44. package/src/js/index.ts +1 -0
  45. package/src/js/internal/draggable.ts +33 -31
  46. package/src/js/internal/navigable.ts +5 -1
  47. package/src/js/menu.ts +5 -2
  48. package/src/js/movable/movable.embedded.ts +3 -8
  49. package/src/js/resizable/resizable.embedded.ts +57 -20
  50. package/src/js/sortable/sortable.embedded.ts +21 -26
  51. package/src/js/splitter.ts +37 -23
@@ -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.1",
3
+ "version": "0.31.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"
@@ -91,10 +95,10 @@
91
95
  },
92
96
  "dependencies": {
93
97
  "@oscarpalmer/atoms": "^0.188.1",
94
- "@oscarpalmer/toretto": "^0.47.3"
98
+ "@oscarpalmer/toretto": "^0.48.0"
95
99
  },
96
100
  "devDependencies": {
97
- "@oxlint/plugins": "^1.73",
101
+ "@oxlint/plugins": "^1.75",
98
102
  "@vitest/coverage-istanbul": "^4.1",
99
103
  "autoprefixer": "^10.5",
100
104
  "concurrently": "^10",
@@ -4,24 +4,7 @@
4
4
 
5
5
  .oui {
6
6
  :where(&-pill, &-tag) {
7
- --oui-shadow-mixed: color-mix(
8
- in oklab,
9
- var(--oui-shadow, var(--oui-gray-6)),
10
- transparent 92.5%
11
- );
12
-
13
- @include mixins.shadow(var(--oui-shadow-mixed));
14
-
15
- display: inline-flex;
16
- flex-flow: row nowrap;
17
- gap: 0.5em;
18
- background-color: color-mix(
19
- in oklab,
20
- var(--oui-background, var(--oui-gray-0)),
21
- transparent 25%
22
- );
23
- color: var(--oui-foreground, var(--oui-gray-8));
24
- line-height: 1.25;
7
+ @include mixins.badge;
25
8
  }
26
9
 
27
10
  :where(&-pill) {
@@ -0,0 +1,137 @@
1
+ /*! https://github.com/oscarpalmer/oui */
2
+
3
+ @use './mixins.scss' as mixins;
4
+
5
+ [oui-combobox-anchor] {
6
+ :where(&) {
7
+ @include mixins.input;
8
+
9
+ --oui-background-value: var(--oui-absolute);
10
+
11
+ padding: 0.5em 2em .5em 0.75em;
12
+ border-radius: 0.25em;
13
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='4'%3E%3Cpath d='M4 0h6L7 4'/%3E%3C/svg%3E");
14
+ background-position: right .5em center;
15
+ background-repeat: no-repeat;
16
+ background-size: 1em;
17
+ }
18
+
19
+ :where(&:not([disabled], [readonly], [aria-disabled='true' i]):focus),
20
+ :where([oui-combobox]:focus-within &:not([disabled], [readonly], [aria-disabled='true' i])) {
21
+ @include mixins.input-focus;
22
+ }
23
+
24
+ @media (hover: hover) {
25
+ :where(:not([disabled], [readonly], [aria-disabled='true' i]) &:hover) {
26
+ @include mixins.input-hover;
27
+ }
28
+ }
29
+
30
+ :where(:is([disabled], [readonly], [aria-disabled='true' i]) &) {
31
+ --oui-foreground-percentage: 25%;
32
+
33
+ font-style: italic;
34
+ }
35
+
36
+ :where(:is([disabled], [readonly], [aria-disabled='true' i]) &:focus) {
37
+ --oui-outline-percentage: 75%;
38
+ }
39
+
40
+ :where(:is([disabled], [aria-disabled='true' i]) &) {
41
+ --oui-background-percentage: 50%;
42
+ }
43
+ }
44
+
45
+ :where([oui-combobox-content]) {
46
+ @include mixins.floatable;
47
+ @include mixins.shadow-overlay;
48
+
49
+ width: fit-content;
50
+ height: fit-content;
51
+ max-width: max(25vw, 32rem);
52
+ max-height: max(25vh, 32rem);
53
+ min-width: var(--oui-combobox-width, auto);
54
+ flex-flow: column nowrap;
55
+ border-radius: 0.25em;
56
+
57
+ &:popover-open {
58
+ display: flex !important;
59
+ }
60
+ }
61
+
62
+ :where([oui-combobox-empty]) {
63
+ padding: 1em;
64
+ text-align: center;
65
+ font-style: italic;
66
+ }
67
+
68
+ :where([oui-combobox-list]) {
69
+ overflow: auto;
70
+ }
71
+
72
+ [oui-combobox-option] {
73
+ :where(&) {
74
+ padding: 0.5em 0.75em;
75
+ outline: 4px solid transparent;
76
+ outline-offset: -4px;
77
+ line-height: 1.25;
78
+ cursor: pointer;
79
+ transition: .125s ease-in-out;
80
+ }
81
+
82
+ :where(&[aria-selected='true' i]) {
83
+ background-color: var(--oui-blue-3);
84
+ color: var(--oui-blue-9);
85
+ }
86
+
87
+ :where(oui-combobox[multiple] &[aria-selected='true' i])::before {
88
+ content: '✓';
89
+ margin: 0 0.75em 0 0;
90
+ }
91
+
92
+ :where(oui-combobox:not([disabled], [readonly], [aria-disabled='true' i]) &) {
93
+ @media (hover: hover) {
94
+ :where(&:hover) {
95
+ background-color: var(--oui-blue-1);
96
+ color: var(--oui-blue-8);
97
+ }
98
+ }
99
+ }
100
+ }
101
+
102
+ :where([oui-combobox-option-active]) {
103
+ background-color: var(--oui-blue-1);
104
+ outline-color: var(--oui-blue-4);
105
+ color: var(--oui-blue-8);
106
+ }
107
+
108
+ :where([oui-combobox-selection]) {
109
+ max-height: 8rem;
110
+ display: flex;
111
+ padding: .5em;
112
+ margin: -.5em -.5em -.5em -.75em;
113
+ flex-flow: row wrap;
114
+ gap: 0.5em;
115
+ overflow: auto;
116
+ list-style: none;
117
+ }
118
+
119
+ [oui-combobox-selection-item] {
120
+ :where(&) {
121
+ @include mixins.badge;
122
+
123
+ border-radius: 3em;
124
+ padding: 0.5em 1em;
125
+ gap: .75em;
126
+ font-size: .875em;
127
+ transition: .125s ease-in-out;
128
+ }
129
+
130
+ @media (hover: hover) {
131
+ :where(oui-combobox:not([disabled], [readonly], [aria-disabled='true' i]) &:hover) {
132
+ --oui-background: var(--oui-red-0);
133
+ --oui-foreground: var(--oui-red-8);
134
+ --oui-shadow: var(--oui-red-6);
135
+ }
136
+ }
137
+ }
package/src/css/form.scss CHANGED
@@ -2,70 +2,6 @@
2
2
 
3
3
  @use 'mixins.scss' as mixins;
4
4
 
5
- @mixin focus() {
6
- --oui-border-value: var(--oui-blue-5);
7
- --oui-foreground-value: inherit;
8
- --oui-outline-percentage: 75%;
9
- --oui-outline-value: var(--oui-blue-6);
10
- }
11
-
12
- @mixin hover() {
13
- --oui-border-value: var(--oui-blue-4);
14
- --oui-foreground-percentage: 0%;
15
- --oui-foreground-value: inherit;
16
- --oui-outline-percentage: 90%;
17
- --oui-outline-value: var(--oui-blue-6);
18
- }
19
-
20
- @mixin input {
21
- --oui-background-percentage: 0%;
22
- --oui-foreground-percentage: 0%;
23
-
24
- @include outlined;
25
-
26
- background-color: color-mix(
27
- in oklab,
28
- var(--oui-background-value),
29
- transparent var(--oui-background-percentage)
30
- );
31
- border: 1px solid var(--oui-border-value, var(--oui-gray-3));
32
- box-shadow: inset 0 2px 4px -1px var(--oui-gray-3);
33
- color: color-mix(
34
- in oklab,
35
- var(--oui-foreground-value, inherit),
36
- transparent var(--oui-foreground-percentage)
37
- );
38
- -webkit-text-fill-color: color-mix(
39
- in oklab,
40
- var(--oui-foreground-value, inherit),
41
- transparent var(--oui-foreground-percentage)
42
- );
43
- }
44
-
45
- @mixin invalid() {
46
- --oui-border-value: var(--oui-red-5);
47
- --oui-foreground-value: var(--oui-red-9);
48
- --oui-outline-percentage: 82.5%;
49
- --oui-outline-value: var(--oui-red-6);
50
- }
51
-
52
- @mixin outlined {
53
- --oui-outline-percentage: 100%;
54
- --oui-outline-value: var(--oui-blue-6);
55
-
56
- outline: 4px solid
57
- color-mix(in oklab, var(--oui-outline-value), transparent var(--oui-outline-percentage));
58
- outline-offset: 0;
59
- transition: 0.125s ease-in-out;
60
- }
61
-
62
- @mixin valid() {
63
- --oui-border-value: var(--oui-green-5);
64
- --oui-foreground-value: var(--oui-green-9);
65
- --oui-outline-percentage: 82.5%;
66
- --oui-outline-value: var(--oui-green-6);
67
- }
68
-
69
5
  :where(.oui-fieldset) {
70
6
  padding: 1em;
71
7
  border: 1px solid var(--oui-gray-3);
@@ -78,7 +14,7 @@
78
14
  }
79
15
 
80
16
  :where(&:not([type='range' i])) {
81
- @include input;
17
+ @include mixins.input;
82
18
 
83
19
  padding: 0.5em 0.75em;
84
20
  border-radius: 0.25em;
@@ -135,7 +71,7 @@
135
71
  outline: none;
136
72
 
137
73
  &::range-track {
138
- @include input;
74
+ @include mixins.input;
139
75
 
140
76
  appearance: none;
141
77
  width: 100%;
@@ -148,7 +84,7 @@
148
84
  --oui-background-percentage: 0%;
149
85
  --oui-background-value: var(--oui-blue-6);
150
86
 
151
- @include outlined;
87
+ @include mixins.input-outlined;
152
88
 
153
89
  appearance: none;
154
90
  width: 1.25em;
@@ -177,7 +113,7 @@
177
113
  [aria-invalid='true' i]
178
114
  )
179
115
  ) {
180
- @include invalid;
116
+ @include mixins.input-invalid;
181
117
 
182
118
  &::file-selector-button {
183
119
  --oui-background-value: var(--oui-red-2);
@@ -190,7 +126,7 @@
190
126
  }
191
127
 
192
128
  &::range-track {
193
- @include invalid;
129
+ @include mixins.input-invalid;
194
130
  }
195
131
 
196
132
  & > option:checked {
@@ -205,7 +141,7 @@
205
141
  [aria-invalid='false' i]
206
142
  )
207
143
  ) {
208
- @include valid;
144
+ @include mixins.input-valid;
209
145
 
210
146
  &::file-selector-button {
211
147
  --oui-background-value: var(--oui-green-2);
@@ -214,7 +150,7 @@
214
150
  }
215
151
 
216
152
  &::range-track {
217
- @include valid;
153
+ @include mixins.input-valid;
218
154
  }
219
155
 
220
156
  &::range-thumb {
@@ -249,7 +185,7 @@
249
185
 
250
186
  :where(&:not([disabled], [readonly], [aria-disabled='true' i]):focus),
251
187
  :where(&:not([disabled], [readonly], [aria-disabled='true' i]):focus-within) {
252
- @include focus;
188
+ @include mixins.input-focus;
253
189
 
254
190
  &::file-selector-button {
255
191
  --oui-background-value: var(--oui-blue-2);
@@ -259,7 +195,7 @@
259
195
 
260
196
  &::range-thumb,
261
197
  &::range-track {
262
- @include focus;
198
+ @include mixins.input-focus;
263
199
  }
264
200
 
265
201
  &::range-thumb {
@@ -271,7 +207,7 @@
271
207
 
272
208
  @media (hover: hover) {
273
209
  :where(&:not([disabled], [readonly], [aria-disabled='true' i]):hover) {
274
- @include hover;
210
+ @include mixins.input-hover;
275
211
 
276
212
  &::file-selector-button {
277
213
  --oui-background-value: var(--oui-blue-2);
@@ -284,12 +220,12 @@
284
220
  }
285
221
 
286
222
  &::range-track {
287
- @include hover;
223
+ @include mixins.input-hover;
288
224
  }
289
225
  }
290
226
  }
291
227
 
292
- :where(&[disabled], &[readonly], &[aria-disabled='true' i]) {
228
+ :where(&:is([disabled], [readonly], [aria-disabled='true' i])) {
293
229
  --oui-foreground-percentage: 25%;
294
230
 
295
231
  font-style: italic;
@@ -311,7 +247,7 @@
311
247
  --oui-outline-percentage: 75%;
312
248
  }
313
249
 
314
- :where(&[disabled], &[aria-disabled='true' i]) {
250
+ :where(&:is([disabled], [aria-disabled='true' i])) {
315
251
  --oui-background-percentage: 50%;
316
252
 
317
253
  &::range-thumb {
@@ -383,9 +319,11 @@ select.oui-input:is([multiple]) {
383
319
  font-weight: bold;
384
320
  }
385
321
 
386
- :where(.oui-label) {
387
- cursor: pointer;
388
- transition: 0.125s ease-in-out;
322
+ .oui-label {
323
+ :where(&) {
324
+ cursor: pointer;
325
+ transition: 0.125s ease-in-out;
326
+ }
389
327
 
390
328
  @media (hover: hover) {
391
329
  :where(&[for]:hover) {
@@ -1,3 +1,24 @@
1
+ @mixin badge() {
2
+ --oui-shadow-mixed: color-mix(
3
+ in oklab,
4
+ var(--oui-shadow, var(--oui-gray-6)),
5
+ transparent 92.5%
6
+ );
7
+
8
+ @include shadow(var(--oui-shadow-mixed));
9
+
10
+ display: inline-flex;
11
+ flex-flow: row nowrap;
12
+ gap: 0.5em;
13
+ background-color: color-mix(
14
+ in oklab,
15
+ var(--oui-background, var(--oui-gray-0)),
16
+ transparent 25%
17
+ );
18
+ color: var(--oui-foreground, var(--oui-gray-8));
19
+ line-height: 1.25;
20
+ }
21
+
1
22
  @mixin button() {
2
23
  --oui-background-percentage: 25%;
3
24
  --oui-foreground-percentage: 0%;
@@ -77,6 +98,71 @@
77
98
  }
78
99
  }
79
100
 
101
+ @mixin input {
102
+ --oui-background-percentage: 0%;
103
+ --oui-foreground-percentage: 0%;
104
+
105
+ @include input-outlined;
106
+
107
+ align-content: center;
108
+ background-color: color-mix(
109
+ in oklab,
110
+ var(--oui-background-value),
111
+ transparent var(--oui-background-percentage)
112
+ );
113
+ border: 1px solid var(--oui-border-value, var(--oui-gray-3));
114
+ box-shadow: inset 0 2px 4px -1px var(--oui-gray-3);
115
+ color: color-mix(
116
+ in oklab,
117
+ var(--oui-foreground-value, inherit),
118
+ transparent var(--oui-foreground-percentage)
119
+ );
120
+ -webkit-text-fill-color: color-mix(
121
+ in oklab,
122
+ var(--oui-foreground-value, inherit),
123
+ transparent var(--oui-foreground-percentage)
124
+ );
125
+ }
126
+
127
+ @mixin input-focus() {
128
+ --oui-border-value: var(--oui-blue-5);
129
+ --oui-foreground-value: inherit;
130
+ --oui-outline-percentage: 75%;
131
+ --oui-outline-value: var(--oui-blue-6);
132
+ }
133
+
134
+ @mixin input-hover() {
135
+ --oui-border-value: var(--oui-blue-4);
136
+ --oui-foreground-percentage: 0%;
137
+ --oui-foreground-value: inherit;
138
+ --oui-outline-percentage: 90%;
139
+ --oui-outline-value: var(--oui-blue-6);
140
+ }
141
+
142
+ @mixin input-invalid() {
143
+ --oui-border-value: var(--oui-red-5);
144
+ --oui-foreground-value: var(--oui-red-9);
145
+ --oui-outline-percentage: 82.5%;
146
+ --oui-outline-value: var(--oui-red-6);
147
+ }
148
+
149
+ @mixin input-outlined {
150
+ --oui-outline-percentage: 100%;
151
+ --oui-outline-value: var(--oui-blue-6);
152
+
153
+ outline: 4px solid
154
+ color-mix(in oklab, var(--oui-outline-value), transparent var(--oui-outline-percentage));
155
+ outline-offset: 0;
156
+ transition: 0.125s ease-in-out;
157
+ }
158
+
159
+ @mixin input-valid() {
160
+ --oui-border-value: var(--oui-green-5);
161
+ --oui-foreground-value: var(--oui-green-9);
162
+ --oui-outline-percentage: 82.5%;
163
+ --oui-outline-value: var(--oui-green-6);
164
+ }
165
+
80
166
  @mixin shadow($color: rgb(0 0 0 / 5%), $inset: transparent) {
81
167
  box-shadow:
82
168
  inset 0 1px 0 0 $inset,