@revikornmann/muka-ui 0.25.0 → 0.27.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.
- package/dist/cjs/components/Autocomplete/Autocomplete.css +63 -0
- package/dist/cjs/components/Autocomplete/Autocomplete.js +190 -0
- package/dist/cjs/components/Autocomplete/Autocomplete.js.map +1 -0
- package/dist/cjs/components/Autocomplete/index.js +6 -0
- package/dist/cjs/components/Autocomplete/index.js.map +1 -0
- package/dist/cjs/components/Avatar/Avatar.css +79 -30
- package/dist/cjs/components/Avatar/Avatar.js +1 -1
- package/dist/cjs/components/Avatar/Avatar.js.map +1 -1
- package/dist/cjs/components/Avatar/AvatarGroup.js +4 -3
- package/dist/cjs/components/Avatar/AvatarGroup.js.map +1 -1
- package/dist/cjs/components/Button/Button.css +33 -0
- package/dist/cjs/components/Button/Button.js +2 -2
- package/dist/cjs/components/Combobox/Combobox.js +7 -23
- package/dist/cjs/components/Combobox/Combobox.js.map +1 -1
- package/dist/cjs/components/ContextSelect/ContextSelect.js +2 -2
- package/dist/cjs/components/ContextSelect/ContextSelect.js.map +1 -1
- package/dist/cjs/components/DataPieChart/DataPieChart.js +5 -2
- package/dist/cjs/components/DataPieChart/DataPieChart.js.map +1 -1
- package/dist/cjs/components/DataPieChart/index.js.map +1 -1
- package/dist/cjs/components/Dialog/Dialog.js +9 -1
- package/dist/cjs/components/Dialog/Dialog.js.map +1 -1
- package/dist/cjs/components/DropdownSelect/DropdownSelect.js +2 -2
- package/dist/cjs/components/DropdownSelect/DropdownSelect.js.map +1 -1
- package/dist/cjs/components/InputCounter/InputCounter.css +175 -0
- package/dist/cjs/components/InputCounter/InputCounter.js +196 -0
- package/dist/cjs/components/InputCounter/InputCounter.js.map +1 -0
- package/dist/cjs/components/InputCounter/index.js +11 -0
- package/dist/cjs/components/InputCounter/index.js.map +1 -0
- package/dist/cjs/components/Menu/Menu.js +26 -11
- package/dist/cjs/components/Menu/Menu.js.map +1 -1
- package/dist/cjs/components/Popover/Popover.js +10 -8
- package/dist/cjs/components/Popover/Popover.js.map +1 -1
- package/dist/cjs/components/Tabs/Tabs.css +37 -14
- package/dist/cjs/components/Tabs/Tabs.js +30 -10
- package/dist/cjs/components/Tabs/Tabs.js.map +1 -1
- package/dist/cjs/components/Tooltip/Tooltip.js +7 -2
- package/dist/cjs/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/cjs/components/index.js +7 -3
- package/dist/cjs/components/index.js.map +1 -1
- package/dist/cjs/utils/suggestionList.js +27 -0
- package/dist/cjs/utils/suggestionList.js.map +1 -0
- package/dist/cjs/utils/usePortalContainer.js +33 -0
- package/dist/cjs/utils/usePortalContainer.js.map +1 -0
- package/dist/esm/components/Autocomplete/Autocomplete.css +63 -0
- package/dist/esm/components/Autocomplete/Autocomplete.js +187 -0
- package/dist/esm/components/Autocomplete/Autocomplete.js.map +1 -0
- package/dist/esm/components/Autocomplete/index.js +2 -0
- package/dist/esm/components/Autocomplete/index.js.map +1 -0
- package/dist/esm/components/Avatar/Avatar.css +79 -30
- package/dist/esm/components/Avatar/Avatar.js +1 -1
- package/dist/esm/components/Avatar/Avatar.js.map +1 -1
- package/dist/esm/components/Avatar/AvatarGroup.js +4 -3
- package/dist/esm/components/Avatar/AvatarGroup.js.map +1 -1
- package/dist/esm/components/Button/Button.css +33 -0
- package/dist/esm/components/Button/Button.js +2 -2
- package/dist/esm/components/Combobox/Combobox.js +5 -21
- package/dist/esm/components/Combobox/Combobox.js.map +1 -1
- package/dist/esm/components/ContextSelect/ContextSelect.js +2 -2
- package/dist/esm/components/ContextSelect/ContextSelect.js.map +1 -1
- package/dist/esm/components/DataPieChart/DataPieChart.js +4 -1
- package/dist/esm/components/DataPieChart/DataPieChart.js.map +1 -1
- package/dist/esm/components/DataPieChart/index.js.map +1 -1
- package/dist/esm/components/Dialog/Dialog.js +9 -1
- package/dist/esm/components/Dialog/Dialog.js.map +1 -1
- package/dist/esm/components/DropdownSelect/DropdownSelect.js +2 -2
- package/dist/esm/components/DropdownSelect/DropdownSelect.js.map +1 -1
- package/dist/esm/components/InputCounter/InputCounter.css +175 -0
- package/dist/esm/components/InputCounter/InputCounter.js +160 -0
- package/dist/esm/components/InputCounter/InputCounter.js.map +1 -0
- package/dist/esm/components/InputCounter/index.js +3 -0
- package/dist/esm/components/InputCounter/index.js.map +1 -0
- package/dist/esm/components/Menu/Menu.js +26 -11
- package/dist/esm/components/Menu/Menu.js.map +1 -1
- package/dist/esm/components/Popover/Popover.js +10 -5
- package/dist/esm/components/Popover/Popover.js.map +1 -1
- package/dist/esm/components/Tabs/Tabs.css +37 -14
- package/dist/esm/components/Tabs/Tabs.js +30 -10
- package/dist/esm/components/Tabs/Tabs.js.map +1 -1
- package/dist/esm/components/Tooltip/Tooltip.js +7 -2
- package/dist/esm/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/esm/components/index.js +2 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/utils/suggestionList.js +22 -0
- package/dist/esm/utils/suggestionList.js.map +1 -0
- package/dist/esm/utils/usePortalContainer.js +29 -0
- package/dist/esm/utils/usePortalContainer.js.map +1 -0
- package/dist/styles/components/Autocomplete.css +63 -0
- package/dist/styles/components/Avatar.css +79 -30
- package/dist/styles/components/Button.css +33 -0
- package/dist/styles/components/InputCounter.css +175 -0
- package/dist/styles/components/Tabs.css +37 -14
- package/dist/styles/index.css +1150 -758
- package/dist/styles/muka-dark.css +1150 -758
- package/dist/styles/muka-light.css +1150 -758
- package/dist/styles/tokens-bouwplan-dark.css +48 -5
- package/dist/styles/tokens-bouwplan-light.css +48 -5
- package/dist/styles/tokens-fscl-dark.css +48 -5
- package/dist/styles/tokens-fscl-light.css +48 -5
- package/dist/styles/tokens-grip-dark.css +48 -5
- package/dist/styles/tokens-grip-light.css +48 -5
- package/dist/styles/tokens-muka-dark.css +48 -5
- package/dist/styles/tokens-muka-light.css +48 -5
- package/dist/styles/tokens-wireframe-dark.css +48 -5
- package/dist/styles/tokens-wireframe-light.css +48 -5
- package/dist/styles/wireframe-dark.css +1150 -758
- package/dist/styles/wireframe-light.css +1150 -758
- package/dist/types/components/Autocomplete/Autocomplete.d.ts +105 -0
- package/dist/types/components/Autocomplete/Autocomplete.d.ts.map +1 -0
- package/dist/types/components/Autocomplete/index.d.ts +2 -0
- package/dist/types/components/Autocomplete/index.d.ts.map +1 -0
- package/dist/types/components/Avatar/Avatar.d.ts +8 -3
- package/dist/types/components/Avatar/Avatar.d.ts.map +1 -1
- package/dist/types/components/Avatar/AvatarGroup.d.ts +10 -5
- package/dist/types/components/Avatar/AvatarGroup.d.ts.map +1 -1
- package/dist/types/components/Avatar/index.d.ts +1 -1
- package/dist/types/components/Avatar/index.d.ts.map +1 -1
- package/dist/types/components/Button/Button.d.ts +3 -3
- package/dist/types/components/Button/Button.d.ts.map +1 -1
- package/dist/types/components/Combobox/Combobox.d.ts +2 -2
- package/dist/types/components/Combobox/Combobox.d.ts.map +1 -1
- package/dist/types/components/ContextSelect/ContextSelect.d.ts +6 -0
- package/dist/types/components/ContextSelect/ContextSelect.d.ts.map +1 -1
- package/dist/types/components/DataPieChart/DataPieChart.d.ts +13 -2
- package/dist/types/components/DataPieChart/DataPieChart.d.ts.map +1 -1
- package/dist/types/components/DataPieChart/index.d.ts +1 -1
- package/dist/types/components/DataPieChart/index.d.ts.map +1 -1
- package/dist/types/components/Dialog/Dialog.d.ts.map +1 -1
- package/dist/types/components/DropdownSelect/DropdownSelect.d.ts +6 -0
- package/dist/types/components/DropdownSelect/DropdownSelect.d.ts.map +1 -1
- package/dist/types/components/InputCounter/InputCounter.d.ts +79 -0
- package/dist/types/components/InputCounter/InputCounter.d.ts.map +1 -0
- package/dist/types/components/InputCounter/index.d.ts +3 -0
- package/dist/types/components/InputCounter/index.d.ts.map +1 -0
- package/dist/types/components/Menu/Menu.d.ts +4 -4
- package/dist/types/components/Menu/Menu.d.ts.map +1 -1
- package/dist/types/components/Popover/Popover.d.ts +12 -0
- package/dist/types/components/Popover/Popover.d.ts.map +1 -1
- package/dist/types/components/Tabs/Tabs.d.ts +17 -2
- package/dist/types/components/Tabs/Tabs.d.ts.map +1 -1
- package/dist/types/components/Tooltip/Tooltip.d.ts +6 -0
- package/dist/types/components/Tooltip/Tooltip.d.ts.map +1 -1
- package/dist/types/components/index.d.ts +4 -2
- package/dist/types/components/index.d.ts.map +1 -1
- package/dist/types/utils/suggestionList.d.ts +13 -0
- package/dist/types/utils/suggestionList.d.ts.map +1 -0
- package/dist/types/utils/usePortalContainer.d.ts +19 -0
- package/dist/types/utils/usePortalContainer.d.ts.map +1 -0
- package/docs/consumers/README.md +2 -2
- package/package.json +1 -1
- package/tokens/t1-primitives/color.json +10 -0
- package/tokens/t2-alias/base.json +14 -0
- package/tokens/t2-alias/brand/bouwplan/dark.json +5 -0
- package/tokens/t2-alias/brand/bouwplan/light.json +5 -0
- package/tokens/t2-alias/brand/fscl/dark.json +5 -0
- package/tokens/t2-alias/brand/fscl/light.json +5 -0
- package/tokens/t2-alias/brand/grip/dark.json +14 -0
- package/tokens/t2-alias/brand/grip/light.json +14 -0
- package/tokens/t2-alias/brand/muka/dark.json +14 -0
- package/tokens/t2-alias/brand/muka/light.json +14 -0
- package/tokens/t2-alias/brand/wireframe/dark.json +14 -0
- package/tokens/t2-alias/brand/wireframe/light.json +14 -0
- package/tokens/t3-semantics/ui.json +49 -2
- package/tokens/t4-components/avatar.json +82 -18
- package/tokens/t4-components/button.json +56 -0
- package/tokens/t4-components/tabs.json +41 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/* Autocomplete — Figma Input Autocomplete (Input field + single-line suggestion Menu).
|
|
2
|
+
The field reuses the Input styles (.muka-input*); only the menu wiring lives here. */
|
|
3
|
+
|
|
4
|
+
.muka-autocomplete {
|
|
5
|
+
min-width: 200px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/* Covers the field's outer edge so the menu matches its full width. The menu
|
|
9
|
+
is only open while focused, when the field has the bold border. */
|
|
10
|
+
.muka-autocomplete__menu-anchor {
|
|
11
|
+
position: absolute;
|
|
12
|
+
inset: calc(-1 * var(--border-width-bold));
|
|
13
|
+
z-index: 0;
|
|
14
|
+
margin: 0;
|
|
15
|
+
padding: 0;
|
|
16
|
+
border: none;
|
|
17
|
+
background: transparent;
|
|
18
|
+
pointer-events: none;
|
|
19
|
+
opacity: 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Keep the field content above the invisible anchor. */
|
|
23
|
+
.muka-autocomplete__field > :not(.muka-autocomplete__menu-anchor) {
|
|
24
|
+
position: relative;
|
|
25
|
+
z-index: 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Figma: the menu is as wide as the field (never below the menu min-width token). */
|
|
29
|
+
.muka-autocomplete__menu {
|
|
30
|
+
width: var(--radix-dropdown-menu-trigger-width);
|
|
31
|
+
max-width: calc(100vw - 2rem);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Suggestions are single-line; long labels truncate. */
|
|
35
|
+
.muka-autocomplete__menu .muka-menu__item-label {
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
text-overflow: ellipsis;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Loading and empty rows: menu-row geometry, not selectable. */
|
|
41
|
+
.muka-autocomplete__status {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
gap: var(--menu-item-gap);
|
|
45
|
+
min-height: var(--menu-item-height);
|
|
46
|
+
padding: var(--menu-item-padding-y) var(--menu-item-padding-x);
|
|
47
|
+
color: var(--color-text-subtle-default);
|
|
48
|
+
font-family: var(--text-label-md-regular-fontFamily);
|
|
49
|
+
font-size: var(--text-label-md-regular-fontSize);
|
|
50
|
+
font-weight: var(--text-label-md-regular-fontWeight);
|
|
51
|
+
line-height: var(--text-label-md-regular-lineHeight);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.muka-autocomplete__footer {
|
|
55
|
+
flex-shrink: 0;
|
|
56
|
+
padding: var(--spacing-2) var(--spacing-3);
|
|
57
|
+
border-top: var(--border-width-regular) solid var(--color-border-default);
|
|
58
|
+
color: var(--color-text-subtle-default);
|
|
59
|
+
font-family: var(--text-label-sm-regular-fontFamily);
|
|
60
|
+
font-size: var(--text-label-sm-regular-fontSize);
|
|
61
|
+
font-weight: var(--text-label-sm-regular-fontWeight);
|
|
62
|
+
line-height: var(--text-label-sm-regular-lineHeight);
|
|
63
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Autocomplete = Autocomplete;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
const react_1 = require("react");
|
|
7
|
+
const Icon_1 = require("../Icon");
|
|
8
|
+
const Menu_1 = require("../Menu");
|
|
9
|
+
const Spinner_1 = require("../Spinner");
|
|
10
|
+
const accessibility_1 = require("../../utils/accessibility");
|
|
11
|
+
const suggestionList_1 = require("../../utils/suggestionList");
|
|
12
|
+
const usePortalContainer_1 = require("../../utils/usePortalContainer");
|
|
13
|
+
require("../Input/Input.css");
|
|
14
|
+
require("./Autocomplete.css");
|
|
15
|
+
/**
|
|
16
|
+
* Autocomplete — single-value free-input text field with a suggestion Menu.
|
|
17
|
+
*
|
|
18
|
+
* Matches Figma "Input Autocomplete". The consumer supplies the suggestions
|
|
19
|
+
* (typically fetched as the user types); picking one writes its label into
|
|
20
|
+
* the field. Typed text that matches nothing is kept as is.
|
|
21
|
+
*
|
|
22
|
+
* For multiple values as chips, use `Combobox`.
|
|
23
|
+
*/
|
|
24
|
+
function Autocomplete({ value, onInputChange, options, onSelect, loading = false, minChars = 1, emptyMessage, filter = false, menuFooter, clearable = true, clearLabel = 'Clear', loadingLabel = 'Loading suggestions', resultsLabel = (count) => `${count} suggestions`, placeholder, label, helperText, error = false, errorMessage, disabled = false, readOnly = false, size = 'md', fullWidth = false, iconLeft, name, id, required = false, className = '', 'aria-label': ariaLabel, onBlur, onFocus, portalContainer, }) {
|
|
25
|
+
const generatedId = (0, react_1.useId)();
|
|
26
|
+
const fieldId = id || name || generatedId;
|
|
27
|
+
const helperTextId = `${fieldId}-helper`;
|
|
28
|
+
const errorMessageId = `${fieldId}-error`;
|
|
29
|
+
const listboxId = `${fieldId}-listbox`;
|
|
30
|
+
const inputRef = (0, react_1.useRef)(null);
|
|
31
|
+
const rootRef = (0, react_1.useRef)(null);
|
|
32
|
+
const menuRef = (0, react_1.useRef)(null);
|
|
33
|
+
const menuContainer = (0, usePortalContainer_1.usePortalContainer)(portalContainer, rootRef);
|
|
34
|
+
// Drives the focused treatment: true only while focus is inside the field
|
|
35
|
+
// or its (portaled) menu (MUK-86).
|
|
36
|
+
const [focused, setFocused] = (0, react_1.useState)(false);
|
|
37
|
+
// Closed by a pick, Escape or an outside press; reopens on the next keystroke
|
|
38
|
+
// or ArrowDown, or when focus comes back into the field.
|
|
39
|
+
const [dismissed, setDismissed] = (0, react_1.useState)(false);
|
|
40
|
+
const [activeIndex, setActiveIndex] = (0, react_1.useState)(0);
|
|
41
|
+
const query = value.trim();
|
|
42
|
+
const interactive = !disabled && !readOnly;
|
|
43
|
+
const visibleOptions = (0, react_1.useMemo)(() => {
|
|
44
|
+
if (!filter)
|
|
45
|
+
return options;
|
|
46
|
+
const q = query.toLowerCase();
|
|
47
|
+
return options.filter((option) => filter(option, q));
|
|
48
|
+
}, [options, filter, query]);
|
|
49
|
+
const hasOptions = visibleOptions.length > 0;
|
|
50
|
+
const showLoadingRow = loading && !hasOptions;
|
|
51
|
+
const showEmptyRow = !loading && !hasOptions && Boolean(emptyMessage);
|
|
52
|
+
const showMenu = interactive &&
|
|
53
|
+
focused &&
|
|
54
|
+
!dismissed &&
|
|
55
|
+
query.length >= minChars &&
|
|
56
|
+
(hasOptions || showLoadingRow || showEmptyRow);
|
|
57
|
+
const optionKey = visibleOptions.map((option) => option.value).join('\0');
|
|
58
|
+
(0, react_1.useEffect)(() => {
|
|
59
|
+
setActiveIndex((0, suggestionList_1.firstEnabledIndex)(visibleOptions));
|
|
60
|
+
// Reset only when the set of options changes, not on every render.
|
|
61
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
62
|
+
}, [optionKey]);
|
|
63
|
+
const optionId = (index) => `${listboxId}-option-${index}`;
|
|
64
|
+
const activeOption = showMenu && hasOptions ? visibleOptions[activeIndex] : undefined;
|
|
65
|
+
const announcement = !showMenu
|
|
66
|
+
? ''
|
|
67
|
+
: hasOptions
|
|
68
|
+
? resultsLabel(visibleOptions.length)
|
|
69
|
+
: showLoadingRow
|
|
70
|
+
? loadingLabel
|
|
71
|
+
: typeof emptyMessage === 'string'
|
|
72
|
+
? emptyMessage
|
|
73
|
+
: '';
|
|
74
|
+
const showError = error && errorMessage;
|
|
75
|
+
const describedBy = (0, accessibility_1.mergeIds)(showError ? errorMessageId : helperText ? helperTextId : undefined);
|
|
76
|
+
const selectOption = (option) => {
|
|
77
|
+
if (option.disabled)
|
|
78
|
+
return;
|
|
79
|
+
onInputChange(option.label, 'select');
|
|
80
|
+
onSelect?.(option);
|
|
81
|
+
setDismissed(true);
|
|
82
|
+
inputRef.current?.focus();
|
|
83
|
+
};
|
|
84
|
+
const handleInputChange = (event) => {
|
|
85
|
+
setDismissed(false);
|
|
86
|
+
onInputChange(event.target.value, 'input');
|
|
87
|
+
};
|
|
88
|
+
const handleClear = () => {
|
|
89
|
+
onInputChange('', 'clear');
|
|
90
|
+
setDismissed(false);
|
|
91
|
+
inputRef.current?.focus();
|
|
92
|
+
};
|
|
93
|
+
const handleFocus = () => {
|
|
94
|
+
if (disabled)
|
|
95
|
+
return;
|
|
96
|
+
setFocused(true);
|
|
97
|
+
};
|
|
98
|
+
// Moving between the field and the portaled menu keeps focus "inside";
|
|
99
|
+
// only a real exit drops the focused style, closes the menu and calls onBlur.
|
|
100
|
+
const handleBlur = (event) => {
|
|
101
|
+
const next = event.relatedTarget;
|
|
102
|
+
if (next && (rootRef.current?.contains(next) || menuRef.current?.contains(next))) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
setFocused(false);
|
|
106
|
+
setDismissed(false);
|
|
107
|
+
onBlur?.(event);
|
|
108
|
+
};
|
|
109
|
+
const handleKeyDown = (event) => {
|
|
110
|
+
if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
|
|
111
|
+
if (!showMenu) {
|
|
112
|
+
if (event.key === 'ArrowDown' && dismissed) {
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
setDismissed(false);
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
event.preventDefault();
|
|
119
|
+
setActiveIndex((current) => (0, suggestionList_1.nextEnabledIndex)(visibleOptions, current, event.key === 'ArrowDown' ? 1 : -1));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (event.key === 'Enter') {
|
|
123
|
+
// Only intercept Enter when it picks a row, so a form can still submit.
|
|
124
|
+
if (activeOption && !activeOption.disabled) {
|
|
125
|
+
event.preventDefault();
|
|
126
|
+
selectOption(activeOption);
|
|
127
|
+
}
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (event.key === 'Escape' && showMenu) {
|
|
131
|
+
// Close the menu only; don't let Escape also close an enclosing Dialog.
|
|
132
|
+
event.preventDefault();
|
|
133
|
+
event.stopPropagation();
|
|
134
|
+
setDismissed(true);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const showClear = clearable && interactive && value.length > 0;
|
|
138
|
+
const iconSize = size === 'sm' ? 'xs' : size === 'lg' ? 'md' : 'sm';
|
|
139
|
+
const rootClasses = [
|
|
140
|
+
'muka-input',
|
|
141
|
+
'muka-autocomplete',
|
|
142
|
+
fullWidth && 'muka-input--full-width',
|
|
143
|
+
className,
|
|
144
|
+
]
|
|
145
|
+
.filter(Boolean)
|
|
146
|
+
.join(' ');
|
|
147
|
+
const fieldClasses = [
|
|
148
|
+
'muka-input__field',
|
|
149
|
+
`muka-input__field--${size}`,
|
|
150
|
+
'muka-autocomplete__field',
|
|
151
|
+
focused && 'muka-input__field--focused',
|
|
152
|
+
error && 'muka-input__field--error',
|
|
153
|
+
disabled && 'muka-input__field--disabled',
|
|
154
|
+
iconLeft && 'muka-input__field--has-icon-left',
|
|
155
|
+
showClear && 'muka-input__field--has-icon-right',
|
|
156
|
+
]
|
|
157
|
+
.filter(Boolean)
|
|
158
|
+
.join(' ');
|
|
159
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: rootClasses, ref: rootRef, children: [label && ((0, jsx_runtime_1.jsxs)("label", { className: `muka-input__label muka-input__label--${size}`, htmlFor: fieldId, children: [label, required && (0, jsx_runtime_1.jsx)("span", { className: "muka-input__required", "aria-hidden": "true", children: " *" })] })), (0, jsx_runtime_1.jsxs)(Menu_1.Menu, { trigger: "click", open: showMenu, onOpenChange: (next) => {
|
|
160
|
+
// Radix closes on an outside press; it never opens the menu itself.
|
|
161
|
+
if (!next)
|
|
162
|
+
setDismissed(true);
|
|
163
|
+
}, modal: false, children: [(0, jsx_runtime_1.jsxs)("div", { className: fieldClasses, onFocus: handleFocus, onBlur: handleBlur, onPointerDown: (event) => {
|
|
164
|
+
if (disabled)
|
|
165
|
+
return;
|
|
166
|
+
// A press on the padding or the clear button must not blur the
|
|
167
|
+
// input. Presses on the input keep native caret placement.
|
|
168
|
+
if (event.target !== inputRef.current)
|
|
169
|
+
event.preventDefault();
|
|
170
|
+
}, onClick: (event) => {
|
|
171
|
+
if (disabled)
|
|
172
|
+
return;
|
|
173
|
+
// Focus on click, never on pointerdown: on iOS Safari an early
|
|
174
|
+
// focus opens the keyboard and scrolls mid-tap, so the tap lands
|
|
175
|
+
// on whatever slid under the finger (MUK-88).
|
|
176
|
+
const target = event.target;
|
|
177
|
+
if (target === inputRef.current || target.closest('button'))
|
|
178
|
+
return;
|
|
179
|
+
inputRef.current?.focus();
|
|
180
|
+
}, children: [iconLeft && ((0, jsx_runtime_1.jsx)("span", { className: "muka-input__icon muka-input__icon--left", "aria-hidden": "true", children: iconLeft })), (0, jsx_runtime_1.jsx)("input", { ref: inputRef, id: fieldId, name: name, type: "text", className: "muka-input__native", value: value, onChange: handleInputChange, onKeyDown: handleKeyDown, onFocus: onFocus, placeholder: placeholder, disabled: disabled, readOnly: readOnly, required: required, "aria-label": label ? undefined : ariaLabel || placeholder, "aria-invalid": error || undefined, "aria-describedby": describedBy, role: "combobox", "aria-autocomplete": "list", "aria-controls": listboxId, "aria-expanded": showMenu, "aria-activedescendant": activeOption ? optionId(activeIndex) : undefined, autoComplete: "off", autoCorrect: "off", spellCheck: false }), showClear && ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "muka-input__clear", "aria-label": clearLabel, tabIndex: -1, onClick: handleClear, children: (0, jsx_runtime_1.jsx)(Icon_1.Icon, { name: "close", variant: "line", size: iconSize }) })), (0, jsx_runtime_1.jsx)(Menu_1.MenuTrigger, { asChild: true, disabled: disabled, children: (0, jsx_runtime_1.jsx)("button", { type: "button", className: "muka-autocomplete__menu-anchor", tabIndex: -1, "aria-hidden": "true", disabled: disabled }) })] }), (0, jsx_runtime_1.jsxs)(Menu_1.MenuContent, { align: "start", side: "bottom", sideOffset: 4, className: "muka-autocomplete__menu", onOpenAutoFocus: (event) => {
|
|
181
|
+
// Keep the caret in the text field while suggestions are open.
|
|
182
|
+
event.preventDefault();
|
|
183
|
+
inputRef.current?.focus();
|
|
184
|
+
}, onCloseAutoFocus: (event) => event.preventDefault(), loop: false, container: menuContainer, children: [(0, jsx_runtime_1.jsxs)("div", { ref: menuRef, id: listboxId, role: "listbox", "aria-label": label || ariaLabel || placeholder, onBlur: handleBlur, children: [visibleOptions.map((option, index) => ((0, jsx_runtime_1.jsx)(Menu_1.MenuItem, { id: optionId(index), hint: "enter", disabled: option.disabled, highlighted: index === activeIndex, textValue: option.label, onSelect: (event) => {
|
|
185
|
+
event.preventDefault();
|
|
186
|
+
selectOption(option);
|
|
187
|
+
}, children: (0, Menu_1.highlightMenuMatch)(option.label, query) }, `${option.value}-${index}`))), showLoadingRow && ((0, jsx_runtime_1.jsxs)("div", { className: "muka-autocomplete__status", "aria-hidden": "true", children: [(0, jsx_runtime_1.jsx)(Spinner_1.Spinner, { size: "sm", label: loadingLabel }), (0, jsx_runtime_1.jsx)("span", { children: loadingLabel })] })), showEmptyRow && ((0, jsx_runtime_1.jsx)("div", { className: "muka-autocomplete__status", "aria-hidden": "true", children: emptyMessage }))] }), menuFooter && (0, jsx_runtime_1.jsx)("div", { className: "muka-autocomplete__footer", children: menuFooter })] })] }), (0, jsx_runtime_1.jsx)("span", { className: accessibility_1.VISUALLY_HIDDEN_CLASS, "aria-live": "polite", "aria-atomic": "true", children: announcement }), showError && ((0, jsx_runtime_1.jsx)("p", { className: "muka-input__error", id: errorMessageId, role: "alert", children: errorMessage })), !showError && helperText && ((0, jsx_runtime_1.jsx)("p", { className: "muka-input__helper", id: helperTextId, children: helperText }))] }));
|
|
188
|
+
}
|
|
189
|
+
exports.default = Autocomplete;
|
|
190
|
+
//# sourceMappingURL=Autocomplete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Autocomplete.js","sourceRoot":"","sources":["../../../../components/Autocomplete/Autocomplete.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Autocomplete = void 0;
|
|
4
|
+
var Autocomplete_1 = require("./Autocomplete");
|
|
5
|
+
Object.defineProperty(exports, "Autocomplete", { enumerable: true, get: function () { return Autocomplete_1.Autocomplete; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/Autocomplete/index.ts"],"names":[],"mappings":";;;AAAA,+CAKwB;AAJtB,4GAAA,YAAY,OAAA"}
|
|
@@ -12,12 +12,29 @@
|
|
|
12
12
|
vertical-align: middle;
|
|
13
13
|
background-color: var(--avatar-color-background-default);
|
|
14
14
|
color: var(--avatar-color-foreground-default);
|
|
15
|
-
border: var(--avatar-border-width) solid var(--avatar-color-border-default);
|
|
16
15
|
font-family: var(--alias-font-brand-family);
|
|
17
16
|
font-weight: var(--alias-font-brand-weight-semibold);
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
/* Size variants */
|
|
20
|
+
.muka-avatar--4xs {
|
|
21
|
+
width: var(--avatar-size-4xs);
|
|
22
|
+
height: var(--avatar-size-4xs);
|
|
23
|
+
font-size: var(--avatar-font-size-3xs); /* only used by an AvatarGroup "+N" */
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.muka-avatar--3xs {
|
|
27
|
+
width: var(--avatar-size-3xs);
|
|
28
|
+
height: var(--avatar-size-3xs);
|
|
29
|
+
font-size: var(--avatar-font-size-3xs);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.muka-avatar--2xs {
|
|
33
|
+
width: var(--avatar-size-2xs);
|
|
34
|
+
height: var(--avatar-size-2xs);
|
|
35
|
+
font-size: var(--avatar-font-size-2xs);
|
|
36
|
+
}
|
|
37
|
+
|
|
21
38
|
.muka-avatar--xs {
|
|
22
39
|
width: var(--avatar-size-xs);
|
|
23
40
|
height: var(--avatar-size-xs);
|
|
@@ -57,6 +74,20 @@
|
|
|
57
74
|
border-radius: var(--avatar-radius-square);
|
|
58
75
|
}
|
|
59
76
|
|
|
77
|
+
.muka-avatar--square.muka-avatar--4xs,
|
|
78
|
+
.muka-avatar--square.muka-avatar--3xs,
|
|
79
|
+
.muka-avatar--square.muka-avatar--2xs {
|
|
80
|
+
border-radius: var(--avatar-radius-square-sm);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/* 4xs is too small for initials, the fallback icon or a status dot:
|
|
84
|
+
it shows the picture, or the plain background */
|
|
85
|
+
.muka-avatar--4xs .muka-avatar__initials,
|
|
86
|
+
.muka-avatar--4xs .muka-avatar__fallback,
|
|
87
|
+
.muka-avatar--4xs .muka-avatar__status {
|
|
88
|
+
display: none;
|
|
89
|
+
}
|
|
90
|
+
|
|
60
91
|
/* Clickable state */
|
|
61
92
|
.muka-avatar--clickable {
|
|
62
93
|
cursor: pointer;
|
|
@@ -160,6 +191,16 @@
|
|
|
160
191
|
box-sizing: border-box;
|
|
161
192
|
}
|
|
162
193
|
|
|
194
|
+
.muka-avatar--3xs .muka-avatar__status {
|
|
195
|
+
width: var(--avatar-status-size-3xs);
|
|
196
|
+
height: var(--avatar-status-size-3xs);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
.muka-avatar--2xs .muka-avatar__status {
|
|
200
|
+
width: var(--avatar-status-size-2xs);
|
|
201
|
+
height: var(--avatar-status-size-2xs);
|
|
202
|
+
}
|
|
203
|
+
|
|
163
204
|
.muka-avatar--xs .muka-avatar__status {
|
|
164
205
|
width: var(--avatar-status-size-xs);
|
|
165
206
|
height: var(--avatar-status-size-xs);
|
|
@@ -213,44 +254,17 @@
|
|
|
213
254
|
background-color: var(--avatar-color-status-away);
|
|
214
255
|
}
|
|
215
256
|
|
|
216
|
-
/* Avatar Group */
|
|
257
|
+
/* Avatar Group (Figma "Avatar Stack") */
|
|
217
258
|
.muka-avatar-group {
|
|
218
259
|
display: inline-flex;
|
|
219
260
|
align-items: center;
|
|
220
261
|
flex-direction: row;
|
|
221
262
|
}
|
|
222
263
|
|
|
264
|
+
/* Later avatars sit on top of earlier ones (DOM order); a hovered one comes to the front */
|
|
223
265
|
.muka-avatar-group__item {
|
|
224
266
|
position: relative;
|
|
225
267
|
display: inline-flex;
|
|
226
|
-
border: 2px solid var(--color-surface-level1);
|
|
227
|
-
border-radius: inherit;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/* Add border radius to match avatar shape */
|
|
231
|
-
.muka-avatar-group__item .muka-avatar--circle {
|
|
232
|
-
border-radius: var(--avatar-radius-circle);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
.muka-avatar-group__item .muka-avatar--square {
|
|
236
|
-
border-radius: var(--avatar-radius-square);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
.muka-avatar-group__item .muka-avatar {
|
|
240
|
-
border: none;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/* Spacing variants for avatar group */
|
|
244
|
-
.muka-avatar-group--tight .muka-avatar-group__item:not(:first-child) {
|
|
245
|
-
margin-left: calc(var(--avatar-group-spacing-tight));
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
.muka-avatar-group--normal .muka-avatar-group__item:not(:first-child) {
|
|
249
|
-
margin-left: calc(var(--avatar-group-spacing-normal));
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/* Z-index stacking for overlap effect */
|
|
253
|
-
.muka-avatar-group__item {
|
|
254
268
|
z-index: 0;
|
|
255
269
|
}
|
|
256
270
|
|
|
@@ -258,6 +272,41 @@
|
|
|
258
272
|
z-index: 10;
|
|
259
273
|
}
|
|
260
274
|
|
|
275
|
+
/* Grouped avatars get a ring outside their edge, drawn as a shadow so it
|
|
276
|
+
does not change the avatar's size or the overlap */
|
|
277
|
+
.muka-avatar-group__item .muka-avatar {
|
|
278
|
+
box-shadow: 0 0 0 var(--avatar-group-ring-width) var(--avatar-group-ring-color);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* Overlap. Figma specifies exact values for 48 / 32 / 24px avatars (sm / 2xs / 3xs);
|
|
282
|
+
other sizes use the same proportions: tight 2/3, compact 1/2, spacious 1/3. */
|
|
283
|
+
.muka-avatar-group--4xs { --muka-avatar-group-size: var(--avatar-size-4xs); }
|
|
284
|
+
.muka-avatar-group--3xs { --muka-avatar-group-size: var(--avatar-size-3xs); }
|
|
285
|
+
.muka-avatar-group--2xs { --muka-avatar-group-size: var(--avatar-size-2xs); }
|
|
286
|
+
.muka-avatar-group--xs { --muka-avatar-group-size: var(--avatar-size-xs); }
|
|
287
|
+
.muka-avatar-group--sm { --muka-avatar-group-size: var(--avatar-size-sm); }
|
|
288
|
+
.muka-avatar-group--md { --muka-avatar-group-size: var(--avatar-size-md); }
|
|
289
|
+
.muka-avatar-group--lg { --muka-avatar-group-size: var(--avatar-size-lg); }
|
|
290
|
+
.muka-avatar-group--xl { --muka-avatar-group-size: var(--avatar-size-xl); }
|
|
291
|
+
|
|
292
|
+
.muka-avatar-group--tight { --muka-avatar-group-overlap: calc(var(--muka-avatar-group-size) * 2 / 3); }
|
|
293
|
+
.muka-avatar-group--compact { --muka-avatar-group-overlap: calc(var(--muka-avatar-group-size) / 2); }
|
|
294
|
+
.muka-avatar-group--spacious { --muka-avatar-group-overlap: calc(var(--muka-avatar-group-size) / 3); }
|
|
295
|
+
|
|
296
|
+
.muka-avatar-group--tight.muka-avatar-group--sm { --muka-avatar-group-overlap: var(--avatar-group-overlap-tight-sm); }
|
|
297
|
+
.muka-avatar-group--tight.muka-avatar-group--2xs { --muka-avatar-group-overlap: var(--avatar-group-overlap-tight-2xs); }
|
|
298
|
+
.muka-avatar-group--tight.muka-avatar-group--3xs { --muka-avatar-group-overlap: var(--avatar-group-overlap-tight-3xs); }
|
|
299
|
+
.muka-avatar-group--compact.muka-avatar-group--sm { --muka-avatar-group-overlap: var(--avatar-group-overlap-compact-sm); }
|
|
300
|
+
.muka-avatar-group--compact.muka-avatar-group--2xs { --muka-avatar-group-overlap: var(--avatar-group-overlap-compact-2xs); }
|
|
301
|
+
.muka-avatar-group--compact.muka-avatar-group--3xs { --muka-avatar-group-overlap: var(--avatar-group-overlap-compact-3xs); }
|
|
302
|
+
.muka-avatar-group--spacious.muka-avatar-group--sm { --muka-avatar-group-overlap: var(--avatar-group-overlap-spacious-sm); }
|
|
303
|
+
.muka-avatar-group--spacious.muka-avatar-group--2xs { --muka-avatar-group-overlap: var(--avatar-group-overlap-spacious-2xs); }
|
|
304
|
+
.muka-avatar-group--spacious.muka-avatar-group--3xs { --muka-avatar-group-overlap: var(--avatar-group-overlap-spacious-3xs); }
|
|
305
|
+
|
|
306
|
+
.muka-avatar-group__item:not(:first-child) {
|
|
307
|
+
margin-left: calc(-1 * var(--muka-avatar-group-overlap));
|
|
308
|
+
}
|
|
309
|
+
|
|
261
310
|
/* Overflow avatar styling */
|
|
262
311
|
.muka-avatar--overflow {
|
|
263
312
|
background-color: var(--avatar-color-background-default);
|
|
@@ -26,7 +26,7 @@ function getInitials(name) {
|
|
|
26
26
|
* 4. Default icon - Generic user icon
|
|
27
27
|
*
|
|
28
28
|
* Features:
|
|
29
|
-
* -
|
|
29
|
+
* - 8 sizes: 4xs (16px) to xl (112px)
|
|
30
30
|
* - 2 shapes: circle, square
|
|
31
31
|
* - Status indicators: online, offline, busy, away
|
|
32
32
|
* - Loading and error states
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../../../../components/Avatar/Avatar.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;;;AAEb,iCAAwC;AACxC,6DAAgE;AAChE,wBAAsB;
|
|
1
|
+
{"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../../../../components/Avatar/Avatar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -40,12 +40,13 @@ require("./Avatar.css");
|
|
|
40
40
|
/**
|
|
41
41
|
* AvatarGroup Component
|
|
42
42
|
*
|
|
43
|
-
* Displays a horizontal stack of avatars with overlap.
|
|
43
|
+
* Displays a horizontal stack of avatars with overlap (Figma "Avatar Stack").
|
|
44
|
+
* Each avatar gets a ring in the surface colour so the overlap reads clearly.
|
|
44
45
|
* When there are more avatars than `max`, shows remaining count as "+N".
|
|
45
46
|
*
|
|
46
47
|
* Features:
|
|
47
48
|
* - Configurable max visible avatars
|
|
48
|
-
* -
|
|
49
|
+
* - Three spacing modes: tight, compact, spacious
|
|
49
50
|
* - Size propagation to child avatars
|
|
50
51
|
* - Overflow counter display
|
|
51
52
|
*
|
|
@@ -53,7 +54,7 @@ require("./Avatar.css");
|
|
|
53
54
|
* - Uses role="group" with aria-label
|
|
54
55
|
* - Overflow count includes accessible label
|
|
55
56
|
*/
|
|
56
|
-
const AvatarGroup = ({ children, max = 5, size = 'md', spacing = '
|
|
57
|
+
const AvatarGroup = ({ children, max = 5, size = 'md', spacing = 'compact', className = '', 'aria-label': ariaLabel = 'Avatar group', ...props }) => {
|
|
57
58
|
const childArray = react_1.Children.toArray(children);
|
|
58
59
|
const totalCount = childArray.length;
|
|
59
60
|
const visibleCount = Math.min(max, totalCount);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AvatarGroup.js","sourceRoot":"","sources":["../../../../components/Avatar/AvatarGroup.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAwC;
|
|
1
|
+
{"version":3,"file":"AvatarGroup.js","sourceRoot":"","sources":["../../../../components/Avatar/AvatarGroup.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAwC;AAExC,wBAAsB;AAyBtB;;;;;;;;;;;;;;;;GAgBG;AACI,MAAM,WAAW,GAA+B,CAAC,EACtD,QAAQ,EACR,GAAG,GAAG,CAAC,EACP,IAAI,GAAG,IAAI,EACX,OAAO,GAAG,SAAS,EACnB,SAAS,GAAG,EAAE,EACd,YAAY,EAAE,SAAS,GAAG,cAAc,EACxC,GAAG,KAAK,EACT,EAAE,EAAE;IACH,MAAM,UAAU,GAAG,gBAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC;IACrC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAC/C,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,GAAG,CAAC,CAAC;IAEpD,MAAM,eAAe,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;IAE1D,MAAM,YAAY,GAAG;QACnB,mBAAmB;QACnB,sBAAsB,OAAO,EAAE;QAC/B,sBAAsB,IAAI,EAAE;QAC5B,SAAS;KACV,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE5B,MAAM,eAAe,GAAG;QACtB,aAAa;QACb,uBAAuB;QACvB,gBAAgB,IAAI,EAAE;QACtB,qBAAqB;KACtB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE5B,OAAO,CACL,iCACE,SAAS,EAAE,YAAY,EACvB,IAAI,EAAC,OAAO,gBACA,SAAS,KACjB,KAAK,aAER,eAAe,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBACpC,IAAI,CAAC,eAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjC,OAAO,KAAK,CAAC;gBACf,CAAC;gBAED,sDAAsD;gBACtD,OAAO,CACL,gCAAiB,SAAS,EAAC,yBAAyB,YACjD,eAAK,CAAC,YAAY,CAAC,KAAK,EAAE;wBACzB,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI;wBAC9B,GAAG,KAAK,CAAC,KAAK;qBACY,CAAC,IAJrB,KAAK,CAKT,CACP,CAAC;YACJ,CAAC,CAAC,EAED,aAAa,GAAG,CAAC,IAAI,CACpB,gCAAK,SAAS,EAAC,yBAAyB,YACtC,gCACE,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAC,KAAK,gBACE,GAAG,aAAa,SAAS,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,YAEhF,kCAAM,SAAS,EAAC,6BAA6B,kBACzC,aAAa,IACV,GACH,GACF,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC;AApEW,QAAA,WAAW,eAoEtB;AAEF,kBAAe,mBAAW,CAAC"}
|
|
@@ -116,6 +116,39 @@
|
|
|
116
116
|
opacity: 1; /* Remove opacity since we have proper disabled tokens */
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
/* Destructive variant - primary's structure on the solid error fill, for
|
|
120
|
+
irreversible actions. Hover and pressed step away from the label color, so
|
|
121
|
+
contrast never drops (darker in light themes, lighter in dark themes).
|
|
122
|
+
Disabled is neutral grey rather than primary's brand-tinted fill. */
|
|
123
|
+
.muka-button--destructive {
|
|
124
|
+
background-color: var(--button-color-destructive-background-default);
|
|
125
|
+
color: var(--button-color-destructive-foreground-default);
|
|
126
|
+
box-shadow: var(--button-color-destructive-shadow-default);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.muka-button--destructive:hover:not(:disabled) {
|
|
130
|
+
background-color: var(--button-color-destructive-background-hover);
|
|
131
|
+
color: var(--button-color-destructive-foreground-hover);
|
|
132
|
+
box-shadow: var(--button-color-destructive-shadow-hover);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.muka-button--destructive:active:not(:disabled),
|
|
136
|
+
.muka-button--destructive.muka-button--pressed:not(:disabled),
|
|
137
|
+
.muka-button--destructive[data-state="open"]:not(:disabled),
|
|
138
|
+
.muka-button--destructive[aria-pressed="true"]:not(:disabled) {
|
|
139
|
+
background-color: var(--button-color-destructive-background-pressed);
|
|
140
|
+
color: var(--button-color-destructive-foreground-pressed);
|
|
141
|
+
box-shadow: var(--button-color-destructive-shadow-pressed);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.muka-button--destructive:disabled {
|
|
145
|
+
background-color: var(--button-color-destructive-background-disabled);
|
|
146
|
+
color: var(--button-color-destructive-foreground-disabled);
|
|
147
|
+
box-shadow: var(--button-color-destructive-shadow-disabled);
|
|
148
|
+
cursor: not-allowed;
|
|
149
|
+
opacity: 1;
|
|
150
|
+
}
|
|
151
|
+
|
|
119
152
|
/* Secondary variant - supporting actions, no border, only bottom inner shadow */
|
|
120
153
|
.muka-button--secondary {
|
|
121
154
|
background-color: var(--button-color-secondary-background-default);
|
|
@@ -10,8 +10,8 @@ require("./Button.css");
|
|
|
10
10
|
* Button Component
|
|
11
11
|
*
|
|
12
12
|
* Built using the Muka design token system with support for:
|
|
13
|
-
* -
|
|
14
|
-
* -
|
|
13
|
+
* - 6 variants: primary, secondary, tertiary, ghost, muted, destructive
|
|
14
|
+
* - 4 sizes: sm, md, lg, xl
|
|
15
15
|
* - Interactive states: default, hover, pressed, disabled
|
|
16
16
|
* - Icons with flexible positioning (left, right, or both)
|
|
17
17
|
* - Icon-only buttons (label can be hidden)
|
|
@@ -6,6 +6,8 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
6
6
|
const react_1 = require("react");
|
|
7
7
|
const Chip_1 = require("../Chip");
|
|
8
8
|
const Menu_1 = require("../Menu");
|
|
9
|
+
const suggestionList_1 = require("../../utils/suggestionList");
|
|
10
|
+
const usePortalContainer_1 = require("../../utils/usePortalContainer");
|
|
9
11
|
require("./Combobox.css");
|
|
10
12
|
const defaultFilter = (option, query) => {
|
|
11
13
|
if (!query)
|
|
@@ -13,21 +15,6 @@ const defaultFilter = (option, query) => {
|
|
|
13
15
|
const hay = `${option.label} ${option.caption ?? ''}`.toLowerCase();
|
|
14
16
|
return hay.includes(query);
|
|
15
17
|
};
|
|
16
|
-
const firstEnabledIndex = (items) => {
|
|
17
|
-
const index = items.findIndex((item) => !item.disabled);
|
|
18
|
-
return index === -1 ? 0 : index;
|
|
19
|
-
};
|
|
20
|
-
const nextEnabledIndex = (items, from, direction) => {
|
|
21
|
-
if (items.length === 0)
|
|
22
|
-
return 0;
|
|
23
|
-
let index = from;
|
|
24
|
-
for (let step = 0; step < items.length; step += 1) {
|
|
25
|
-
index = (index + direction + items.length) % items.length;
|
|
26
|
-
if (!items[index]?.disabled)
|
|
27
|
-
return index;
|
|
28
|
-
}
|
|
29
|
-
return from;
|
|
30
|
-
};
|
|
31
18
|
/**
|
|
32
19
|
* Combobox — free-input multi-value field with chips and a suggestion Menu.
|
|
33
20
|
*
|
|
@@ -49,10 +36,7 @@ const Combobox = ({ value, onChange, options = [], placeholder = 'Hint text', la
|
|
|
49
36
|
const menuRef = (0, react_1.useRef)(null);
|
|
50
37
|
// A native <dialog> opened with showModal() lives in the top layer and makes
|
|
51
38
|
// everything outside it inert, so a body-level portal would be unreachable.
|
|
52
|
-
const
|
|
53
|
-
(0, react_1.useLayoutEffect)(() => {
|
|
54
|
-
setDialogContainer(rootRef.current?.closest('dialog') ?? null);
|
|
55
|
-
}, []);
|
|
39
|
+
const menuContainer = (0, usePortalContainer_1.usePortalContainer)(portalContainer, rootRef);
|
|
56
40
|
const [query, setQuery] = (0, react_1.useState)('');
|
|
57
41
|
const [open, setOpen] = (0, react_1.useState)(false);
|
|
58
42
|
// Drives the focused treatment: true only while focus is inside the field
|
|
@@ -107,7 +91,7 @@ const Combobox = ({ value, onChange, options = [], placeholder = 'Hint text', la
|
|
|
107
91
|
suggestions.length > 0;
|
|
108
92
|
const suggestionKey = suggestions.map((item) => item.id).join('\0');
|
|
109
93
|
(0, react_1.useEffect)(() => {
|
|
110
|
-
setActiveIndex(firstEnabledIndex(suggestions));
|
|
94
|
+
setActiveIndex((0, suggestionList_1.firstEnabledIndex)(suggestions));
|
|
111
95
|
}, [suggestionKey, suggestions]);
|
|
112
96
|
const activeSuggestion = suggestions[activeIndex];
|
|
113
97
|
const showError = error && errorMessage;
|
|
@@ -171,14 +155,14 @@ const Combobox = ({ value, onChange, options = [], placeholder = 'Hint text', la
|
|
|
171
155
|
if (!showSuggestions)
|
|
172
156
|
return;
|
|
173
157
|
event.preventDefault();
|
|
174
|
-
setActiveIndex((current) => nextEnabledIndex(suggestions, current, 1));
|
|
158
|
+
setActiveIndex((current) => (0, suggestionList_1.nextEnabledIndex)(suggestions, current, 1));
|
|
175
159
|
return;
|
|
176
160
|
}
|
|
177
161
|
if (event.key === 'ArrowUp') {
|
|
178
162
|
if (!showSuggestions)
|
|
179
163
|
return;
|
|
180
164
|
event.preventDefault();
|
|
181
|
-
setActiveIndex((current) => nextEnabledIndex(suggestions, current, -1));
|
|
165
|
+
setActiveIndex((current) => (0, suggestionList_1.nextEnabledIndex)(suggestions, current, -1));
|
|
182
166
|
return;
|
|
183
167
|
}
|
|
184
168
|
if (event.key === 'Enter') {
|
|
@@ -241,7 +225,7 @@ const Combobox = ({ value, onChange, options = [], placeholder = 'Hint text', la
|
|
|
241
225
|
// Keep the blinking caret in the text field while suggestions open.
|
|
242
226
|
event.preventDefault();
|
|
243
227
|
inputRef.current?.focus();
|
|
244
|
-
}, onCloseAutoFocus: (event) => event.preventDefault(), loop: false, container:
|
|
228
|
+
}, onCloseAutoFocus: (event) => event.preventDefault(), loop: false, container: menuContainer, children: (0, jsx_runtime_1.jsx)("div", { ref: menuRef, id: listboxId, role: "listbox", "aria-label": label || placeholder, onBlur: handleBlur, children: suggestions.map((suggestion, index) => ((0, jsx_runtime_1.jsx)(Menu_1.MenuItem, { id: suggestion.id, hint: "enter", disabled: suggestion.disabled, highlighted: index === activeIndex, textValue: suggestion.label, onSelect: (event) => {
|
|
245
229
|
event.preventDefault();
|
|
246
230
|
if (!suggestion.disabled)
|
|
247
231
|
commitValue(suggestion.value);
|