@revikornmann/muka-ui 0.14.0 → 0.15.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/Input/Input.js +8 -6
- package/dist/cjs/components/Input/Input.js.map +1 -1
- package/dist/cjs/components/LicensePlateInput/LicensePlateInput.js +10 -5
- package/dist/cjs/components/LicensePlateInput/LicensePlateInput.js.map +1 -1
- package/dist/cjs/components/NumberInput/NumberInput.js +6 -4
- package/dist/cjs/components/NumberInput/NumberInput.js.map +1 -1
- package/dist/cjs/components/SearchInput/SearchInput.js +15 -5
- package/dist/cjs/components/SearchInput/SearchInput.js.map +1 -1
- package/dist/cjs/components/Textarea/Textarea.js +5 -4
- package/dist/cjs/components/Textarea/Textarea.js.map +1 -1
- package/dist/cjs/utils/accessibility.js +14 -0
- package/dist/cjs/utils/accessibility.js.map +1 -1
- package/dist/esm/components/Input/Input.js +8 -6
- package/dist/esm/components/Input/Input.js.map +1 -1
- package/dist/esm/components/LicensePlateInput/LicensePlateInput.js +10 -5
- package/dist/esm/components/LicensePlateInput/LicensePlateInput.js.map +1 -1
- package/dist/esm/components/NumberInput/NumberInput.js +6 -4
- package/dist/esm/components/NumberInput/NumberInput.js.map +1 -1
- package/dist/esm/components/SearchInput/SearchInput.js +15 -5
- package/dist/esm/components/SearchInput/SearchInput.js.map +1 -1
- package/dist/esm/components/Textarea/Textarea.js +5 -4
- package/dist/esm/components/Textarea/Textarea.js.map +1 -1
- package/dist/esm/utils/accessibility.js +13 -0
- package/dist/esm/utils/accessibility.js.map +1 -1
- package/dist/styles/index.css +6443 -6443
- package/dist/styles/muka-dark.css +6443 -6443
- package/dist/styles/muka-light.css +6443 -6443
- package/dist/styles/wireframe-dark.css +6443 -6443
- package/dist/styles/wireframe-light.css +6443 -6443
- package/dist/types/components/Input/Input.d.ts +4 -2
- package/dist/types/components/Input/Input.d.ts.map +1 -1
- package/dist/types/components/LicensePlateInput/LicensePlateInput.d.ts +2 -2
- package/dist/types/components/LicensePlateInput/LicensePlateInput.d.ts.map +1 -1
- package/dist/types/components/NumberInput/NumberInput.d.ts +2 -2
- package/dist/types/components/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/types/components/SearchInput/SearchInput.d.ts +2 -2
- package/dist/types/components/SearchInput/SearchInput.d.ts.map +1 -1
- package/dist/types/components/Textarea/Textarea.d.ts +2 -2
- package/dist/types/components/Textarea/Textarea.d.ts.map +1 -1
- package/dist/types/utils/accessibility.d.ts +10 -0
- package/dist/types/utils/accessibility.d.ts.map +1 -1
- package/package.json +2 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React, { useState, useId, useRef } from 'react';
|
|
4
|
+
import { mergeIds } from '../../utils/accessibility';
|
|
4
5
|
import '../Input/Input.css';
|
|
5
6
|
import './NumberInput.css';
|
|
6
7
|
/**
|
|
@@ -14,7 +15,7 @@ import './NumberInput.css';
|
|
|
14
15
|
* - input.field.radius / padding / height
|
|
15
16
|
* - text.input.{size} / text.label.{size}.semibold
|
|
16
17
|
*/
|
|
17
|
-
export const NumberInput = React.forwardRef(function NumberInput({ value, onChange, label, helperText, error = false, errorMessage, disabled = false, size = 'md', prefix, suffix, step, min, max, placeholder, fullWidth = false, className = '', id, name, required = false, readOnly = false, onBlur, onFocus, }, forwardedRef) {
|
|
18
|
+
export const NumberInput = React.forwardRef(function NumberInput({ value, onChange, label, helperText, error = false, errorMessage, disabled = false, size = 'md', prefix, suffix, step, min, max, placeholder, fullWidth = false, className = '', id, name, required = false, readOnly = false, onBlur, onFocus, inputMode = 'decimal', 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, onKeyDownCapture, ...rest }, forwardedRef) {
|
|
18
19
|
const [isFocused, setIsFocused] = useState(false);
|
|
19
20
|
const inputRef = useRef(null);
|
|
20
21
|
const generatedId = useId();
|
|
@@ -24,7 +25,7 @@ export const NumberInput = React.forwardRef(function NumberInput({ value, onChan
|
|
|
24
25
|
const hasPrefix = Boolean(prefix);
|
|
25
26
|
const hasSuffix = Boolean(suffix);
|
|
26
27
|
const showError = error && errorMessage;
|
|
27
|
-
const describedBy = showError ? errorMessageId : helperText ? helperTextId : undefined;
|
|
28
|
+
const describedBy = mergeIds(ariaDescribedBy, showError ? errorMessageId : helperText ? helperTextId : undefined);
|
|
28
29
|
const wrapperClasses = [
|
|
29
30
|
'muka-input',
|
|
30
31
|
'muka-numberinput',
|
|
@@ -46,14 +47,14 @@ export const NumberInput = React.forwardRef(function NumberInput({ value, onChan
|
|
|
46
47
|
e.preventDefault();
|
|
47
48
|
inputRef.current?.focus();
|
|
48
49
|
}
|
|
49
|
-
}, children: [hasPrefix && (_jsx("span", { className: "muka-numberinput__addon muka-numberinput__addon--prefix", children: prefix })), _jsx("input", { ref: (node) => {
|
|
50
|
+
}, children: [hasPrefix && (_jsx("span", { className: "muka-numberinput__addon muka-numberinput__addon--prefix", children: prefix })), _jsx("input", { ...rest, ref: (node) => {
|
|
50
51
|
inputRef.current = node;
|
|
51
52
|
if (typeof forwardedRef === 'function')
|
|
52
53
|
forwardedRef(node);
|
|
53
54
|
else if (forwardedRef)
|
|
54
55
|
forwardedRef.current =
|
|
55
56
|
node;
|
|
56
|
-
}, id: inputId, className: "muka-input__native", type: "number", inputMode:
|
|
57
|
+
}, id: inputId, className: "muka-input__native", type: "number", inputMode: inputMode, value: Number.isFinite(value) ? value : 0, step: step, min: min, max: max, placeholder: placeholder, disabled: disabled, readOnly: readOnly, name: name, required: required, "aria-invalid": ariaInvalid ?? (error || undefined), "aria-describedby": describedBy, onChange: (e) => {
|
|
57
58
|
const parsed = e.target.valueAsNumber;
|
|
58
59
|
onChange?.(Number.isFinite(parsed) ? parsed : 0);
|
|
59
60
|
}, onFocus: (e) => {
|
|
@@ -66,6 +67,7 @@ export const NumberInput = React.forwardRef(function NumberInput({ value, onChan
|
|
|
66
67
|
if ((e.metaKey || e.ctrlKey) && e.key === 'a') {
|
|
67
68
|
e.stopPropagation();
|
|
68
69
|
}
|
|
70
|
+
onKeyDownCapture?.(e);
|
|
69
71
|
} }), hasSuffix && (_jsx("span", { className: "muka-numberinput__addon muka-numberinput__addon--suffix", children: suffix }))] }), showError && (_jsx("p", { className: "muka-input__error", id: errorMessageId, role: "alert", children: errorMessage })), !showError && helperText && (_jsx("p", { className: "muka-input__helper", id: helperTextId, children: helperText }))] }));
|
|
70
72
|
});
|
|
71
73
|
export default NumberInput;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NumberInput.js","sourceRoot":"","sources":["../../../../components/NumberInput/NumberInput.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,oBAAoB,CAAC;AAC5B,OAAO,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"NumberInput.js","sourceRoot":"","sources":["../../../../components/NumberInput/NumberInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -15,7 +15,10 @@ import './SearchInput.css';
|
|
|
15
15
|
* - Renders as `<input type="search">` inside a `<form role="search">` landmark
|
|
16
16
|
* - Clear and cancel buttons have descriptive aria-labels
|
|
17
17
|
*/
|
|
18
|
-
export const SearchInput = forwardRef(({ value, onChange, placeholder = 'Search', clearable = true, cancellable = false, cancelLabel = 'Cancel', onCancel, onSubmit, loading = false, variant = 'default', autoFocus = false, disabled = false, size = 'md', 'aria-label': ariaLabel, className = '',
|
|
18
|
+
export const SearchInput = forwardRef(({ value, onChange, placeholder = 'Search', clearable = true, cancellable = false, cancelLabel = 'Cancel', onCancel, onSubmit, loading = false, variant = 'default', autoFocus = false, disabled = false, size = 'md', 'aria-label': ariaLabel, className = '',
|
|
19
|
+
// Disable browser-supplied autofill/correction by default — the field
|
|
20
|
+
// renders its own clear affordance. Consumers can still override these.
|
|
21
|
+
autoComplete = 'off', autoCorrect = 'off', spellCheck = false, onKeyDown, onFocus, onBlur, ...rest }, forwardedRef) => {
|
|
19
22
|
const inputRef = useRef(null);
|
|
20
23
|
useImperativeHandle(forwardedRef, () => inputRef.current);
|
|
21
24
|
const [focused, setFocused] = useState(false);
|
|
@@ -42,6 +45,7 @@ export const SearchInput = forwardRef(({ value, onChange, placeholder = 'Search'
|
|
|
42
45
|
else if (e.key === 'Escape' && cancellable) {
|
|
43
46
|
handleCancel();
|
|
44
47
|
}
|
|
48
|
+
onKeyDown?.(e);
|
|
45
49
|
};
|
|
46
50
|
const rootClasses = [
|
|
47
51
|
'muka-search-input',
|
|
@@ -53,10 +57,16 @@ export const SearchInput = forwardRef(({ value, onChange, placeholder = 'Search'
|
|
|
53
57
|
]
|
|
54
58
|
.filter(Boolean)
|
|
55
59
|
.join(' ');
|
|
56
|
-
return (_jsxs("form", { className: rootClasses, role: "search", onSubmit: (e) => e.preventDefault(), children: [_jsxs("div", { className: "muka-search-input__field", children: [_jsx("span", { className: "muka-search-input__leading", "aria-hidden": "true", children: _jsx(Icon, { name: "search", variant: "line", size: "md" }) }), _jsx("input", { ref: inputRef, type: "search", className: "muka-search-input__input", value: value, onChange: (e) => onChange(e.target.value), onFocus: () =>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
return (_jsxs("form", { className: rootClasses, role: "search", onSubmit: (e) => e.preventDefault(), children: [_jsxs("div", { className: "muka-search-input__field", children: [_jsx("span", { className: "muka-search-input__leading", "aria-hidden": "true", children: _jsx(Icon, { name: "search", variant: "line", size: "md" }) }), _jsx("input", { ...rest, ref: inputRef, type: "search", className: "muka-search-input__input", value: value, onChange: (e) => onChange(e.target.value), onFocus: (e) => {
|
|
61
|
+
setFocused(true);
|
|
62
|
+
onFocus?.(e);
|
|
63
|
+
}, onBlur: (e) => {
|
|
64
|
+
setFocused(false);
|
|
65
|
+
onBlur?.(e);
|
|
66
|
+
}, onKeyDown: handleKeyDown, placeholder: placeholder, disabled: disabled, autoFocus: autoFocus, "aria-label": ariaLabel || placeholder,
|
|
67
|
+
// The browser-supplied clear icon is hidden in CSS via the
|
|
68
|
+
// `-webkit-search-cancel-button` pseudo-element — we render our own.
|
|
69
|
+
autoComplete: autoComplete, autoCorrect: autoCorrect, spellCheck: spellCheck }), loading && (_jsx("span", { className: "muka-search-input__trailing", children: _jsx(Spinner, { size: "sm", variant: "subtle" }) })), showClear && (_jsx("button", { type: "button", className: "muka-search-input__clear", onClick: handleClear, "aria-label": "Clear search", tabIndex: -1, children: _jsx(Icon, { name: "close", variant: "line", size: "sm" }) }))] }), showCancel && (_jsx("button", { type: "button", className: "muka-search-input__cancel", onClick: handleCancel, children: cancelLabel }))] }));
|
|
60
70
|
});
|
|
61
71
|
SearchInput.displayName = 'SearchInput';
|
|
62
72
|
export default SearchInput;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchInput.js","sourceRoot":"","sources":["../../../../components/SearchInput/SearchInput.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"SearchInput.js","sourceRoot":"","sources":["../../../../components/SearchInput/SearchInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React, { useState, useId } from 'react';
|
|
4
|
+
import { mergeIds } from '../../utils/accessibility';
|
|
4
5
|
import './Textarea.css';
|
|
5
|
-
export const Textarea = React.forwardRef(function Textarea({ value, onChange, placeholder, label, helperText, error = false, errorMessage, disabled = false, readOnly = false, size = 'md', rows, resize = 'vertical', showCount = false, maxLength, className = '', name, id, required = false, onBlur, onFocus, }, forwardedRef) {
|
|
6
|
+
export const Textarea = React.forwardRef(function Textarea({ value, onChange, placeholder, label, helperText, error = false, errorMessage, disabled = false, readOnly = false, size = 'md', rows, resize = 'vertical', showCount = false, maxLength, className = '', name, id, required = false, onBlur, onFocus, style, 'aria-describedby': ariaDescribedBy, 'aria-invalid': ariaInvalid, ...rest }, forwardedRef) {
|
|
6
7
|
const [isFocused, setIsFocused] = useState(false);
|
|
7
8
|
const generatedId = useId();
|
|
8
9
|
const textareaId = id || name || generatedId;
|
|
9
10
|
const helperTextId = `${textareaId}-helper`;
|
|
10
11
|
const errorMessageId = `${textareaId}-error`;
|
|
11
12
|
const showError = error && errorMessage;
|
|
12
|
-
const describedBy = showError ? errorMessageId : helperText ? helperTextId : undefined;
|
|
13
|
+
const describedBy = mergeIds(ariaDescribedBy, showError ? errorMessageId : helperText ? helperTextId : undefined);
|
|
13
14
|
const charCount = value?.length ?? 0;
|
|
14
15
|
const wrapperClasses = [
|
|
15
16
|
'muka-textarea',
|
|
@@ -22,13 +23,13 @@ export const Textarea = React.forwardRef(function Textarea({ value, onChange, pl
|
|
|
22
23
|
error && 'muka-textarea__field--error',
|
|
23
24
|
disabled && 'muka-textarea__field--disabled',
|
|
24
25
|
].filter(Boolean).join(' ');
|
|
25
|
-
return (_jsxs("div", { className: wrapperClasses, children: [label && (_jsxs("label", { className: `muka-textarea__label muka-textarea__label--${size}`, htmlFor: textareaId, children: [label, required && _jsx("span", { className: "muka-textarea__required", "aria-hidden": "true", children: " *" })] })), _jsx("div", { className: fieldClasses, children: _jsx("textarea", { ref: forwardedRef, id: textareaId, className: "muka-textarea__native", value: value, onChange: onChange, placeholder: placeholder, disabled: disabled, readOnly: readOnly, name: name, required: required, rows: rows, maxLength: maxLength, "aria-invalid": error || undefined, "aria-describedby": describedBy, onFocus: (e) => {
|
|
26
|
+
return (_jsxs("div", { className: wrapperClasses, children: [label && (_jsxs("label", { className: `muka-textarea__label muka-textarea__label--${size}`, htmlFor: textareaId, children: [label, required && _jsx("span", { className: "muka-textarea__required", "aria-hidden": "true", children: " *" })] })), _jsx("div", { className: fieldClasses, children: _jsx("textarea", { ...rest, ref: forwardedRef, id: textareaId, className: "muka-textarea__native", value: value, onChange: onChange, placeholder: placeholder, disabled: disabled, readOnly: readOnly, name: name, required: required, rows: rows, maxLength: maxLength, "aria-invalid": ariaInvalid ?? (error || undefined), "aria-describedby": describedBy, onFocus: (e) => {
|
|
26
27
|
setIsFocused(true);
|
|
27
28
|
onFocus?.(e);
|
|
28
29
|
}, onBlur: (e) => {
|
|
29
30
|
setIsFocused(false);
|
|
30
31
|
onBlur?.(e);
|
|
31
|
-
}, style: { resize } }) }), _jsxs("div", { className: "muka-textarea__footer", children: [showError && (_jsx("p", { className: "muka-textarea__error", id: errorMessageId, role: "alert", children: errorMessage })), !showError && helperText && (_jsx("p", { className: "muka-textarea__helper", id: helperTextId, children: helperText })), showCount && (_jsxs("span", { className: "muka-textarea__count", children: [charCount, maxLength ? `/${maxLength}` : ''] }))] })] }));
|
|
32
|
+
}, style: { resize, ...style } }) }), _jsxs("div", { className: "muka-textarea__footer", children: [showError && (_jsx("p", { className: "muka-textarea__error", id: errorMessageId, role: "alert", children: errorMessage })), !showError && helperText && (_jsx("p", { className: "muka-textarea__helper", id: helperTextId, children: helperText })), showCount && (_jsxs("span", { className: "muka-textarea__count", children: [charCount, maxLength ? `/${maxLength}` : ''] }))] })] }));
|
|
32
33
|
});
|
|
33
34
|
export default Textarea;
|
|
34
35
|
//# sourceMappingURL=Textarea.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.js","sourceRoot":"","sources":["../../../../components/Textarea/Textarea.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"Textarea.js","sourceRoot":"","sources":["../../../../components/Textarea/Textarea.tsx"],"names":[],"mappings":"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"}
|
|
@@ -14,4 +14,17 @@ export function warnMissingA11yProp(component, condition, message) {
|
|
|
14
14
|
console.warn(`[${component}] Accessibility: ${message}`);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Merge `aria-describedby` / `aria-labelledby` id lists.
|
|
19
|
+
*
|
|
20
|
+
* Components own ids for their helper text and error message, but consumers
|
|
21
|
+
* may point the same attribute at their own element. Both need to survive, so
|
|
22
|
+
* the ids are concatenated rather than one replacing the other.
|
|
23
|
+
*
|
|
24
|
+
* Returns `undefined` when nothing is left, so the attribute is omitted.
|
|
25
|
+
*/
|
|
26
|
+
export function mergeIds(...ids) {
|
|
27
|
+
const merged = ids.filter(Boolean).join(' ');
|
|
28
|
+
return merged || undefined;
|
|
29
|
+
}
|
|
17
30
|
//# sourceMappingURL=accessibility.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accessibility.js","sourceRoot":"","sources":["../../../utils/accessibility.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,sFAAsF;AACtF,MAAM,CAAC,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAE5D;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,SAAkB,EAClB,OAAe;IAEf,sEAAsE;IACtE,MAAM,KAAK,GACT,OAAO,OAAO,KAAK,WAAW;QAC9B,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,YAAY,CAAC;IAE1C,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,IAAI,SAAS,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"accessibility.js","sourceRoot":"","sources":["../../../utils/accessibility.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,sFAAsF;AACtF,MAAM,CAAC,MAAM,qBAAqB,GAAG,sBAAsB,CAAC;AAE5D;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,SAAkB,EAClB,OAAe;IAEf,sEAAsE;IACtE,MAAM,KAAK,GACT,OAAO,OAAO,KAAK,WAAW;QAC9B,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,YAAY,CAAC;IAE1C,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;QACvB,OAAO,CAAC,IAAI,CAAC,IAAI,SAAS,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACtB,GAAG,GAA6C;IAEhD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,OAAO,MAAM,IAAI,SAAS,CAAC;AAC7B,CAAC"}
|