@kismet-ux/constellation 1.7.0 → 1.9.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/README.md +36 -0
- package/dist/form/Input/input.css +32 -0
- package/dist/form/Input/input.d.ts +18 -1
- package/dist/form/Input/input.d.ts.map +1 -1
- package/dist/form/Input/input.js +20 -2
- package/dist/form/Input/input.js.map +1 -1
- package/dist/form/Input/input.module.scss.js +1 -1
- package/dist/form/Select/select.css +9 -0
- package/dist/form/Select/select.d.ts +11 -1
- package/dist/form/Select/select.d.ts.map +1 -1
- package/dist/form/Select/select.js +10 -2
- package/dist/form/Select/select.js.map +1 -1
- package/dist/form/Select/select.module.scss.js +1 -1
- package/dist/form.d.ts +2 -2
- package/dist/{index-Bexoc2w4.d.ts → index-CRrCqjAW.d.ts} +13 -3
- package/dist/{index-K2b259WI.d.ts → index-Mihuyg_o.d.ts} +4 -2
- package/dist/{index-IHzHSsCh.d.ts → index-ZgohDspB.d.ts} +14 -14
- package/dist/index.d.ts +13 -55
- package/dist/{input-CWHXOpeH.d.ts → input-Cp5LET5i.d.ts} +17 -0
- package/dist/layout/Container/container.css +1 -1
- package/dist/layout/Container/container.d.ts.map +1 -1
- package/dist/layout/Container/container.js +5 -2
- package/dist/layout/Container/container.js.map +1 -1
- package/dist/layout/Sidebar/sidebar.d.ts.map +1 -1
- package/dist/layout/Sidebar/sidebar.js.map +1 -1
- package/dist/layout.d.ts +3 -3
- package/dist/navigation.d.ts +1 -1
- package/dist/{tooltip-CYRWWtkq.d.ts → tooltip-cjwkBINy.d.ts} +5 -1
- package/dist/types/layout/container.d.ts +2 -0
- package/dist/types/layout/container.d.ts.map +1 -1
- package/dist/ui/Button/button-variants.d.ts +1 -1
- package/dist/ui/Button/button.css +92 -77
- package/dist/ui/Button/button.d.ts +4 -0
- package/dist/ui/Button/button.d.ts.map +1 -1
- package/dist/ui/Button/button.js +8 -2
- package/dist/ui/Button/button.js.map +1 -1
- package/dist/ui/Icon/icon-variants.d.ts +1 -1
- package/dist/ui/Toggle/toggle-variants.d.ts +1 -1
- package/dist/ui.d.ts +2 -2
- package/package.json +1 -1
- package/vite-plugin.mjs +7 -2
package/README.md
CHANGED
|
@@ -154,6 +154,42 @@ Each component is a folder: `component-name.tsx` + `component-name.module.scss`
|
|
|
154
154
|
|
|
155
155
|
---
|
|
156
156
|
|
|
157
|
+
## Developing it against a real app
|
|
158
|
+
|
|
159
|
+
Publishing a version for every small change is how versioning goes off the rails. Instead, point a consuming app at a sibling checkout:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
projects/
|
|
163
|
+
kismet-constellation/ ← this repo
|
|
164
|
+
your-app/
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
In the app's `vite.config.js`:
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
import constellationLocal from '@kismet-ux/constellation/vite';
|
|
171
|
+
|
|
172
|
+
export default defineConfig({
|
|
173
|
+
plugins: [constellationLocal({ root: '../kismet-constellation' }), react()],
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
…and in its `.env.local`:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
CONSTELLATION_LOCAL=true
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The plugin builds resolve aliases from this package's own `exports` map, so there is no alias list to maintain. It aliases to `dist`, so keep a build running:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
npx rollup -c --watch
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
`__CONSTELLATION_LOCAL__` is defined as `true` while it is on, which is what `DevIndicator` reads to show its badge. With the variable unset the plugin is inert and the app uses the published package, so nothing depends on the checkout existing.
|
|
190
|
+
|
|
191
|
+
⚠️ **The plugin appends to `server.fs.allow`, and must.** Setting that option at all replaces Vite's default, so listing only the library root locks the consuming app out of its own source — every module 403s and the page renders blank with no useful error.
|
|
192
|
+
|
|
157
193
|
## Commands
|
|
158
194
|
|
|
159
195
|
```bash
|
|
@@ -46,6 +46,30 @@
|
|
|
46
46
|
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
|
47
47
|
width: 100%;
|
|
48
48
|
}
|
|
49
|
+
.input-module_container__bycn1 .input-module_input-container__nw0Oc .input-module_ghost-wrap__pHzia {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-grow: 1;
|
|
52
|
+
min-width: 0;
|
|
53
|
+
position: relative;
|
|
54
|
+
}
|
|
55
|
+
.input-module_container__bycn1 .input-module_input-container__nw0Oc {
|
|
56
|
+
/*
|
|
57
|
+
* Shares the field's box exactly: same font (inherited), `inset: 0` on a
|
|
58
|
+
* wrapper that IS the field's box, and `white-space: pre` so runs of
|
|
59
|
+
* spaces in the tail are not collapsed away and the offset stays true.
|
|
60
|
+
*/
|
|
61
|
+
}
|
|
62
|
+
.input-module_container__bycn1 .input-module_input-container__nw0Oc .input-module_ghost__yVtI- {
|
|
63
|
+
color: var(--text-disabled);
|
|
64
|
+
inset: 0;
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
pointer-events: none;
|
|
67
|
+
position: absolute;
|
|
68
|
+
white-space: pre;
|
|
69
|
+
}
|
|
70
|
+
.input-module_container__bycn1 .input-module_input-container__nw0Oc .input-module_ghost-typed__r9NZN {
|
|
71
|
+
visibility: hidden;
|
|
72
|
+
}
|
|
49
73
|
.input-module_container__bycn1 .input-module_input-container__nw0Oc input,
|
|
50
74
|
.input-module_container__bycn1 .input-module_input-container__nw0Oc textarea {
|
|
51
75
|
background: none;
|
|
@@ -55,6 +79,14 @@
|
|
|
55
79
|
font-size: inherit;
|
|
56
80
|
min-width: 0;
|
|
57
81
|
outline: none !important;
|
|
82
|
+
}
|
|
83
|
+
.input-module_container__bycn1 .input-module_input-container__nw0Oc input--ghosted,
|
|
84
|
+
.input-module_container__bycn1 .input-module_input-container__nw0Oc textarea--ghosted {
|
|
85
|
+
background: transparent;
|
|
86
|
+
position: relative;
|
|
87
|
+
}
|
|
88
|
+
.input-module_container__bycn1 .input-module_input-container__nw0Oc input,
|
|
89
|
+
.input-module_container__bycn1 .input-module_input-container__nw0Oc textarea {
|
|
58
90
|
overflow: hidden;
|
|
59
91
|
padding: 0;
|
|
60
92
|
text-overflow: ellipsis;
|
|
@@ -8,6 +8,23 @@ export interface InputBaseProps {
|
|
|
8
8
|
helperText?: string;
|
|
9
9
|
startAdornment?: React.ReactNode;
|
|
10
10
|
endAdornment?: React.ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* Inline completion drawn behind the caret — the TAIL only, not the whole
|
|
13
|
+
* word. `value='Avo'` with `ghost='cado'` reads as "Avocado", the suggestion
|
|
14
|
+
* dimmed.
|
|
15
|
+
*
|
|
16
|
+
* The component owns the alignment; you own the policy. What to suggest and
|
|
17
|
+
* which key accepts it are decisions about your data and your users (a phone
|
|
18
|
+
* has a spacebar under the thumb and no Tab), so they stay with the caller.
|
|
19
|
+
* Accept by setting `value` to the completed string in your own `onKeyDown`.
|
|
20
|
+
*
|
|
21
|
+
* Pass `''` (not `undefined`) for "nothing to suggest right now": the
|
|
22
|
+
* element structure stays stable, so the field is never remounted mid-word.
|
|
23
|
+
*
|
|
24
|
+
* Ignored for `type='textarea'` — a ghost cannot follow a caret across
|
|
25
|
+
* wrapped lines without measuring, which is a different component.
|
|
26
|
+
*/
|
|
27
|
+
ghost?: string;
|
|
11
28
|
}
|
|
12
29
|
type InputFieldProps = InputBaseProps & React.InputHTMLAttributes<HTMLInputElement> & {
|
|
13
30
|
type?: Exclude<InputType, 'textarea'>;
|
|
@@ -18,6 +35,6 @@ type TextAreaProps = InputBaseProps & React.TextareaHTMLAttributes<HTMLTextAreaE
|
|
|
18
35
|
rows?: number;
|
|
19
36
|
};
|
|
20
37
|
type InputProps = InputFieldProps | TextAreaProps;
|
|
21
|
-
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<
|
|
38
|
+
declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
|
|
22
39
|
export { Input };
|
|
23
40
|
//# sourceMappingURL=input.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/form/Input/input.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,KAAK,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpC,KAAK,SAAS,GAAG,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;AAElF,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../src/form/Input/input.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,KAAK,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpC,KAAK,SAAS,GAAG,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC;AAElF,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,KAAK,eAAe,GAAG,cAAc,GACnC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,GAAG;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,KAAK,CAAC;CACd,CAAC;AAEJ,KAAK,aAAa,GAAG,cAAc,GACjC,KAAK,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,GAAG;IAClD,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAGJ,KAAK,UAAU,GAAG,eAAe,GAAG,aAAa,CAAC;AAGlD,QAAA,MAAM,KAAK,2GAgKV,CAAC;AAIF,OAAO,EAAE,KAAK,EAAE,CAAC"}
|
package/dist/form/Input/input.js
CHANGED
|
@@ -7,7 +7,7 @@ import * as React from 'react';
|
|
|
7
7
|
import inputStyles from './input.module.scss.js';
|
|
8
8
|
|
|
9
9
|
// The Custom Input Component
|
|
10
|
-
const Input = React.forwardRef(({ label, sizeVariant, error = false, helperText, startAdornment, endAdornment, id, type = 'text', rows, onFocus, onBlur, ...rest }, ref) => {
|
|
10
|
+
const Input = React.forwardRef(({ label, sizeVariant, error = false, helperText, startAdornment, endAdornment, id, type = 'text', rows, ghost, onFocus, onBlur, ...rest }, ref) => {
|
|
11
11
|
const { isBelow } = useBreakpoint();
|
|
12
12
|
/*
|
|
13
13
|
* Compose rather than let the caller's handler win.
|
|
@@ -32,7 +32,25 @@ const Input = React.forwardRef(({ label, sizeVariant, error = false, helperText,
|
|
|
32
32
|
const isTextArea = type === 'textarea';
|
|
33
33
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
34
34
|
const containerClasses = cn(inputStyles.container, inputStyles[resolvedSize], { [inputStyles.error]: error }, { [inputStyles.disabled]: rest.disabled }, { [inputStyles.placeholder]: rest.placeholder }, { [inputStyles['is-focused']]: isFocused }, { [inputStyles['has-value']]: rest.value });
|
|
35
|
-
return (jsxs("div", { "data-slot": 'input', "data-constellation-field": true, className: containerClasses, children: [jsxs("div", { className: cn(inputStyles['input-container'], isTextArea && inputStyles['textarea-container']), children: [startAdornment && (jsx("span", { "data-slot": 'input-start-adornment', className: inputStyles['adornment'], children: startAdornment })), jsx("div", { className: inputStyles['label-container'], children: jsxs(Label, { htmlFor: inputId, children: [label, (rest['aria-required'] || rest.required) && jsx("span", { className: inputStyles.required, children: "*" })] }) }), isTextArea ? (jsx("textarea", { "data-slot": 'input-field', id: inputId, className: inputStyles['input-field'], "aria-invalid": error ? 'true' : undefined, "aria-describedby": helperId, onFocus: handleFocus, onBlur: handleBlur, ref: ref, rows: rows, ...rest })) :
|
|
35
|
+
return (jsxs("div", { "data-slot": 'input', "data-constellation-field": true, className: containerClasses, children: [jsxs("div", { className: cn(inputStyles['input-container'], isTextArea && inputStyles['textarea-container']), children: [startAdornment && (jsx("span", { "data-slot": 'input-start-adornment', className: inputStyles['adornment'], children: startAdornment })), jsx("div", { className: inputStyles['label-container'], children: jsxs(Label, { htmlFor: inputId, children: [label, (rest['aria-required'] || rest.required) && jsx("span", { className: inputStyles.required, children: "*" })] }) }), isTextArea ? (jsx("textarea", { "data-slot": 'input-field', id: inputId, className: inputStyles['input-field'], "aria-invalid": error ? 'true' : undefined, "aria-describedby": helperId, onFocus: handleFocus, onBlur: handleBlur, ref: ref, rows: rows, ...rest })) : ghost !== undefined ? (
|
|
36
|
+
/*
|
|
37
|
+
* The ghost is drawn by re-rendering the typed value INVISIBLY and
|
|
38
|
+
* letting the suggestion follow it, so the two share one text flow
|
|
39
|
+
* and the ghost lands exactly where the caret is — no measuring, and
|
|
40
|
+
* nothing to drift when the font or padding changes.
|
|
41
|
+
*
|
|
42
|
+
* The wrapper exists so `inset: 0` means the input's box rather than
|
|
43
|
+
* the container's, which would be off by the padding and by any
|
|
44
|
+
* start adornment.
|
|
45
|
+
*
|
|
46
|
+
* Branching on `ghost !== undefined` rather than on the string being
|
|
47
|
+
* non-empty is load-bearing: a suggestion appears and disappears as
|
|
48
|
+
* you type, and switching JSX shape underneath a live field makes
|
|
49
|
+
* React unmount and remount the input — which drops focus, the
|
|
50
|
+
* caret and any IME composition mid-word. Pass `ghost=''` for "no
|
|
51
|
+
* suggestion right now" and the element stays put.
|
|
52
|
+
*/
|
|
53
|
+
jsxs("span", { className: inputStyles['ghost-wrap'], children: [ghost ? (jsxs("span", { "aria-hidden": 'true', className: inputStyles['ghost'], children: [jsx("span", { className: inputStyles['ghost-typed'], children: String(rest.value ?? '') }), ghost] })) : null, jsx("input", { "data-slot": 'input-field', id: inputId, className: cn(inputStyles['input-field'], ghost && inputStyles['input-field--ghosted']), "aria-invalid": error ? 'true' : undefined, "aria-describedby": helperId, "aria-autocomplete": 'inline', onFocus: handleFocus, onBlur: handleBlur, ref: ref, type: type, ...rest })] })) : (jsx("input", { "data-slot": 'input-field', id: inputId, className: inputStyles['input-field'], "aria-invalid": error ? 'true' : undefined, "aria-describedby": helperId, onFocus: handleFocus, onBlur: handleBlur, ref: ref, type: type, ...rest })), endAdornment && (jsx("span", { "data-slot": 'input-end-adornment', className: inputStyles['adornment'], children: endAdornment }))] }), helperText && (jsx(Typography, { "data-slot": 'input-helper-text', id: helperId, variant: 'caption', className: inputStyles['helper-text'], children: helperText }))] }));
|
|
36
54
|
});
|
|
37
55
|
Input.displayName = 'Input';
|
|
38
56
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.js","sources":["../../../src/form/Input/input.tsx"],"sourcesContent":["import { Label } from '@constellation/form/Label';\nimport { useBreakpoint } from '@constellation/hooks/use-mobile';\nimport { Typography } from '@constellation/typography/Typography';\nimport cn from 'clsx';\nimport * as React from 'react';\nimport s from './input.module.scss';\n\n// Define the possible size variants\ntype InputSize = 'sm' | 'md' | 'lg';\n\ntype InputType = React.InputHTMLAttributes<HTMLInputElement>['type'] | 'textarea';\n\nexport interface InputBaseProps {\n label?: string;\n sizeVariant?: InputSize;\n error?: boolean;\n helperText?: string;\n startAdornment?: React.ReactNode;\n endAdornment?: React.ReactNode;\n}\n\ntype InputFieldProps = InputBaseProps &\n React.InputHTMLAttributes<HTMLInputElement> & {\n type?: Exclude<InputType, 'textarea'>;\n rows?: never;\n };\n\ntype TextAreaProps = InputBaseProps &\n React.TextareaHTMLAttributes<HTMLTextAreaElement> & {\n type: 'textarea';\n rows?: number;\n };\n\n// Define the component's prop interface\ntype InputProps = InputFieldProps | TextAreaProps;\n\n// The Custom Input Component\nconst Input = React.forwardRef<HTMLInputElement | HTMLTextAreaElement, InputProps>(\n (\n {\n label,\n sizeVariant,\n error = false,\n helperText,\n startAdornment,\n endAdornment,\n id,\n type = 'text',\n rows,\n onFocus,\n onBlur,\n ...rest\n },\n ref,\n ) => {\n const { isBelow } = useBreakpoint();\n\n /*\n * Compose rather than let the caller's handler win.\n *\n * These used to be set before `{...rest}` spread over them, so any consumer\n * passing `onFocus` — to select-all on entry, say — silently replaced the\n * one driving the floating label, and the label stopped animating with no\n * error to point at it.\n */\n const handleFocus = (event: React.FocusEvent<HTMLInputElement & HTMLTextAreaElement>) => {\n setIsFocused(true);\n onFocus?.(event);\n };\n const handleBlur = (event: React.FocusEvent<HTMLInputElement & HTMLTextAreaElement>) => {\n setIsFocused(false);\n onBlur?.(event);\n };\n const generatedId = React.useId();\n const inputId = id ?? generatedId;\n const helperId = helperText ? `${inputId}-helper` : undefined;\n const resolvedSize =\n sizeVariant === 'md' && isBelow(900) ? 'sm' : (sizeVariant ?? (isBelow(900) ? 'sm' : 'md'));\n const isTextArea = type === 'textarea';\n const [isFocused, setIsFocused] = React.useState(false);\n\n const containerClasses = cn(\n s.container,\n s[resolvedSize],\n { [s.error]: error },\n { [s.disabled]: rest.disabled },\n { [s.placeholder]: rest.placeholder },\n { [s['is-focused']]: isFocused },\n { [s['has-value']]: rest.value },\n );\n\n return (\n <div data-slot={'input'} data-constellation-field className={containerClasses}>\n <div className={cn(s['input-container'], isTextArea && s['textarea-container'])}>\n {/* Start Adornment */}\n {startAdornment && (\n <span data-slot={'input-start-adornment'} className={s['adornment']}>\n {startAdornment}\n </span>\n )}\n\n <div className={s['label-container']}>\n <Label htmlFor={inputId}>\n {label}\n {(rest['aria-required'] || rest.required) && <span className={s.required}>*</span>}\n </Label>\n </div>\n {isTextArea ? (\n <textarea\n data-slot={'input-field'}\n id={inputId}\n className={s['input-field']}\n aria-invalid={error ? 'true' : undefined}\n aria-describedby={helperId}\n onFocus={handleFocus}\n onBlur={handleBlur}\n ref={ref as React.Ref<HTMLTextAreaElement>}\n rows={rows}\n {...(rest as React.TextareaHTMLAttributes<HTMLTextAreaElement>)}\n />\n ) : (\n <input\n data-slot={'input-field'}\n id={inputId}\n className={s['input-field']}\n aria-invalid={error ? 'true' : undefined}\n aria-describedby={helperId}\n onFocus={handleFocus}\n onBlur={handleBlur}\n ref={ref as React.Ref<HTMLInputElement>}\n type={type}\n {...(rest as React.InputHTMLAttributes<HTMLInputElement>)}\n />\n )}\n\n {/* End Adornment */}\n {endAdornment && (\n <span data-slot={'input-end-adornment'} className={s['adornment']}>\n {endAdornment}\n </span>\n )}\n </div>\n\n {/* Helper Text */}\n {helperText && (\n <Typography\n data-slot={'input-helper-text'}\n id={helperId}\n variant={'caption'}\n className={s['helper-text']}\n >\n {helperText}\n </Typography>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = 'Input';\n\nexport { Input };\n"],"names":["s","_jsxs","_jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"input.js","sources":["../../../src/form/Input/input.tsx"],"sourcesContent":["import { Label } from '@constellation/form/Label';\nimport { useBreakpoint } from '@constellation/hooks/use-mobile';\nimport { Typography } from '@constellation/typography/Typography';\nimport cn from 'clsx';\nimport * as React from 'react';\nimport s from './input.module.scss';\n\n// Define the possible size variants\ntype InputSize = 'sm' | 'md' | 'lg';\n\ntype InputType = React.InputHTMLAttributes<HTMLInputElement>['type'] | 'textarea';\n\nexport interface InputBaseProps {\n label?: string;\n sizeVariant?: InputSize;\n error?: boolean;\n helperText?: string;\n startAdornment?: React.ReactNode;\n endAdornment?: React.ReactNode;\n /**\n * Inline completion drawn behind the caret — the TAIL only, not the whole\n * word. `value='Avo'` with `ghost='cado'` reads as \"Avocado\", the suggestion\n * dimmed.\n *\n * The component owns the alignment; you own the policy. What to suggest and\n * which key accepts it are decisions about your data and your users (a phone\n * has a spacebar under the thumb and no Tab), so they stay with the caller.\n * Accept by setting `value` to the completed string in your own `onKeyDown`.\n *\n * Pass `''` (not `undefined`) for \"nothing to suggest right now\": the\n * element structure stays stable, so the field is never remounted mid-word.\n *\n * Ignored for `type='textarea'` — a ghost cannot follow a caret across\n * wrapped lines without measuring, which is a different component.\n */\n ghost?: string;\n}\n\ntype InputFieldProps = InputBaseProps &\n React.InputHTMLAttributes<HTMLInputElement> & {\n type?: Exclude<InputType, 'textarea'>;\n rows?: never;\n };\n\ntype TextAreaProps = InputBaseProps &\n React.TextareaHTMLAttributes<HTMLTextAreaElement> & {\n type: 'textarea';\n rows?: number;\n };\n\n// Define the component's prop interface\ntype InputProps = InputFieldProps | TextAreaProps;\n\n// The Custom Input Component\nconst Input = React.forwardRef<HTMLInputElement | HTMLTextAreaElement, InputProps>(\n (\n {\n label,\n sizeVariant,\n error = false,\n helperText,\n startAdornment,\n endAdornment,\n id,\n type = 'text',\n rows,\n ghost,\n onFocus,\n onBlur,\n ...rest\n },\n ref,\n ) => {\n const { isBelow } = useBreakpoint();\n\n /*\n * Compose rather than let the caller's handler win.\n *\n * These used to be set before `{...rest}` spread over them, so any consumer\n * passing `onFocus` — to select-all on entry, say — silently replaced the\n * one driving the floating label, and the label stopped animating with no\n * error to point at it.\n */\n const handleFocus = (event: React.FocusEvent<HTMLInputElement & HTMLTextAreaElement>) => {\n setIsFocused(true);\n onFocus?.(event);\n };\n const handleBlur = (event: React.FocusEvent<HTMLInputElement & HTMLTextAreaElement>) => {\n setIsFocused(false);\n onBlur?.(event);\n };\n const generatedId = React.useId();\n const inputId = id ?? generatedId;\n const helperId = helperText ? `${inputId}-helper` : undefined;\n const resolvedSize =\n sizeVariant === 'md' && isBelow(900) ? 'sm' : (sizeVariant ?? (isBelow(900) ? 'sm' : 'md'));\n const isTextArea = type === 'textarea';\n const [isFocused, setIsFocused] = React.useState(false);\n\n const containerClasses = cn(\n s.container,\n s[resolvedSize],\n { [s.error]: error },\n { [s.disabled]: rest.disabled },\n { [s.placeholder]: rest.placeholder },\n { [s['is-focused']]: isFocused },\n { [s['has-value']]: rest.value },\n );\n\n return (\n <div data-slot={'input'} data-constellation-field className={containerClasses}>\n <div className={cn(s['input-container'], isTextArea && s['textarea-container'])}>\n {/* Start Adornment */}\n {startAdornment && (\n <span data-slot={'input-start-adornment'} className={s['adornment']}>\n {startAdornment}\n </span>\n )}\n\n <div className={s['label-container']}>\n <Label htmlFor={inputId}>\n {label}\n {(rest['aria-required'] || rest.required) && <span className={s.required}>*</span>}\n </Label>\n </div>\n {isTextArea ? (\n <textarea\n data-slot={'input-field'}\n id={inputId}\n className={s['input-field']}\n aria-invalid={error ? 'true' : undefined}\n aria-describedby={helperId}\n onFocus={handleFocus}\n onBlur={handleBlur}\n ref={ref as React.Ref<HTMLTextAreaElement>}\n rows={rows}\n {...(rest as React.TextareaHTMLAttributes<HTMLTextAreaElement>)}\n />\n ) : ghost !== undefined ? (\n /*\n * The ghost is drawn by re-rendering the typed value INVISIBLY and\n * letting the suggestion follow it, so the two share one text flow\n * and the ghost lands exactly where the caret is — no measuring, and\n * nothing to drift when the font or padding changes.\n *\n * The wrapper exists so `inset: 0` means the input's box rather than\n * the container's, which would be off by the padding and by any\n * start adornment.\n *\n * Branching on `ghost !== undefined` rather than on the string being\n * non-empty is load-bearing: a suggestion appears and disappears as\n * you type, and switching JSX shape underneath a live field makes\n * React unmount and remount the input — which drops focus, the\n * caret and any IME composition mid-word. Pass `ghost=''` for \"no\n * suggestion right now\" and the element stays put.\n */\n <span className={s['ghost-wrap']}>\n {ghost ? (\n <span aria-hidden={'true'} className={s['ghost']}>\n <span className={s['ghost-typed']}>{String(rest.value ?? '')}</span>\n {ghost}\n </span>\n ) : null}\n <input\n data-slot={'input-field'}\n id={inputId}\n className={cn(s['input-field'], ghost && s['input-field--ghosted'])}\n aria-invalid={error ? 'true' : undefined}\n aria-describedby={helperId}\n aria-autocomplete={'inline'}\n onFocus={handleFocus}\n onBlur={handleBlur}\n ref={ref as React.Ref<HTMLInputElement>}\n type={type}\n {...(rest as React.InputHTMLAttributes<HTMLInputElement>)}\n />\n </span>\n ) : (\n <input\n data-slot={'input-field'}\n id={inputId}\n className={s['input-field']}\n aria-invalid={error ? 'true' : undefined}\n aria-describedby={helperId}\n onFocus={handleFocus}\n onBlur={handleBlur}\n ref={ref as React.Ref<HTMLInputElement>}\n type={type}\n {...(rest as React.InputHTMLAttributes<HTMLInputElement>)}\n />\n )}\n\n {/* End Adornment */}\n {endAdornment && (\n <span data-slot={'input-end-adornment'} className={s['adornment']}>\n {endAdornment}\n </span>\n )}\n </div>\n\n {/* Helper Text */}\n {helperText && (\n <Typography\n data-slot={'input-helper-text'}\n id={helperId}\n variant={'caption'}\n className={s['helper-text']}\n >\n {helperText}\n </Typography>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = 'Input';\n\nexport { Input };\n"],"names":["s","_jsxs","_jsx"],"mappings":";;;;;;;;AAqDA;AACA,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAC5B,CACE,EACE,KAAK,EACL,WAAW,EACX,KAAK,GAAG,KAAK,EACb,UAAU,EACV,cAAc,EACd,YAAY,EACZ,EAAE,EACF,IAAI,GAAG,MAAM,EACb,IAAI,EACJ,KAAK,EACL,OAAO,EACP,MAAM,EACN,GAAG,IAAI,EACR,EACD,GAAG,KACD;AACF,IAAA,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,EAAE;AAEnC;;;;;;;AAOG;AACH,IAAA,MAAM,WAAW,GAAG,CAAC,KAA+D,KAAI;QACtF,YAAY,CAAC,IAAI,CAAC;AAClB,QAAA,OAAO,GAAG,KAAK,CAAC;AAClB,IAAA,CAAC;AACD,IAAA,MAAM,UAAU,GAAG,CAAC,KAA+D,KAAI;QACrF,YAAY,CAAC,KAAK,CAAC;AACnB,QAAA,MAAM,GAAG,KAAK,CAAC;AACjB,IAAA,CAAC;AACD,IAAA,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,EAAE;AACjC,IAAA,MAAM,OAAO,GAAG,EAAE,IAAI,WAAW;AACjC,IAAA,MAAM,QAAQ,GAAG,UAAU,GAAG,CAAA,EAAG,OAAO,CAAA,OAAA,CAAS,GAAG,SAAS;AAC7D,IAAA,MAAM,YAAY,GAChB,WAAW,KAAK,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,WAAW,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;AAC7F,IAAA,MAAM,UAAU,GAAG,IAAI,KAAK,UAAU;AACtC,IAAA,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;AAEvD,IAAA,MAAM,gBAAgB,GAAG,EAAE,CACzBA,WAAC,CAAC,SAAS,EACXA,WAAC,CAAC,YAAY,CAAC,EACf,EAAE,CAACA,WAAC,CAAC,KAAK,GAAG,KAAK,EAAE,EACpB,EAAE,CAACA,WAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,EAC/B,EAAE,CAACA,WAAC,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,EACrC,EAAE,CAACA,WAAC,CAAC,YAAY,CAAC,GAAG,SAAS,EAAE,EAChC,EAAE,CAACA,WAAC,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,CACjC;AAED,IAAA,QACEC,IAAA,CAAA,KAAA,EAAA,EAAA,WAAA,EAAgB,OAAO,EAAA,0BAAA,EAAA,IAAA,EAA2B,SAAS,EAAE,gBAAgB,EAAA,QAAA,EAAA,CAC3EA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,EAAE,CAACD,WAAC,CAAC,iBAAiB,CAAC,EAAE,UAAU,IAAIA,WAAC,CAAC,oBAAoB,CAAC,CAAC,EAAA,QAAA,EAAA,CAE5E,cAAc,KACbE,GAAA,CAAA,MAAA,EAAA,EAAA,WAAA,EAAiB,uBAAuB,EAAE,SAAS,EAAEF,WAAC,CAAC,WAAW,CAAC,EAAA,QAAA,EAChE,cAAc,EAAA,CACV,CACR,EAEDE,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAEF,WAAC,CAAC,iBAAiB,CAAC,EAAA,QAAA,EAClCC,IAAA,CAAC,KAAK,EAAA,EAAC,OAAO,EAAE,OAAO,aACpB,KAAK,EACL,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,QAAQ,KAAKC,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAEF,WAAC,CAAC,QAAQ,EAAA,QAAA,EAAA,GAAA,EAAA,CAAU,CAAA,EAAA,CAC5E,EAAA,CACJ,EACL,UAAU,IACTE,GAAA,CAAA,UAAA,EAAA,EAAA,WAAA,EACa,aAAa,EACxB,EAAE,EAAE,OAAO,EACX,SAAS,EAAEF,WAAC,CAAC,aAAa,CAAC,EAAA,cAAA,EACb,KAAK,GAAG,MAAM,GAAG,SAAS,EAAA,kBAAA,EACtB,QAAQ,EAC1B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,GAAqC,EAC1C,IAAI,EAAE,IAAI,EAAA,GACL,IAA0D,GAC/D,IACA,KAAK,KAAK,SAAS;AACrB;;;;;;;;;;;;;;;;AAgBG;oBACHC,IAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAED,WAAC,CAAC,YAAY,CAAC,EAAA,QAAA,EAAA,CAC7B,KAAK,IACJC,IAAA,CAAA,MAAA,EAAA,EAAA,aAAA,EAAmB,MAAM,EAAE,SAAS,EAAED,WAAC,CAAC,OAAO,CAAC,EAAA,QAAA,EAAA,CAC9CE,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAEF,WAAC,CAAC,aAAa,CAAC,YAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,EAAA,CAAQ,EACnE,KAAK,CAAA,EAAA,CACD,IACL,IAAI,EACRE,GAAA,CAAA,OAAA,EAAA,EAAA,WAAA,EACa,aAAa,EACxB,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,EAAE,CAACF,WAAC,CAAC,aAAa,CAAC,EAAE,KAAK,IAAIA,WAAC,CAAC,sBAAsB,CAAC,CAAC,EAAA,cAAA,EACrD,KAAK,GAAG,MAAM,GAAG,SAAS,sBACtB,QAAQ,EAAA,mBAAA,EACP,QAAQ,EAC3B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,GAAkC,EACvC,IAAI,EAAE,IAAI,KACL,IAAoD,EAAA,CACzD,IACG,KAEPE,4BACa,aAAa,EACxB,EAAE,EAAE,OAAO,EACX,SAAS,EAAEF,WAAC,CAAC,aAAa,CAAC,EAAA,cAAA,EACb,KAAK,GAAG,MAAM,GAAG,SAAS,EAAA,kBAAA,EACtB,QAAQ,EAC1B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,GAAkC,EACvC,IAAI,EAAE,IAAI,EAAA,GACL,IAAoD,EAAA,CACzD,CACH,EAGA,YAAY,KACXE,GAAA,CAAA,MAAA,EAAA,EAAA,WAAA,EAAiB,qBAAqB,EAAE,SAAS,EAAEF,WAAC,CAAC,WAAW,CAAC,YAC9D,YAAY,EAAA,CACR,CACR,CAAA,EAAA,CACG,EAGL,UAAU,KACTE,GAAA,CAAC,UAAU,EAAA,EAAA,WAAA,EACE,mBAAmB,EAC9B,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,SAAS,EAClB,SAAS,EAAEF,WAAC,CAAC,aAAa,CAAC,EAAA,QAAA,EAE1B,UAAU,EAAA,CACA,CACd,CAAA,EAAA,CACG;AAEV,CAAC;AAGH,KAAK,CAAC,WAAW,GAAG,OAAO;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import './input.css';
|
|
2
2
|
|
|
3
|
-
var inputStyles = {"container":"input-module_container__bycn1","label-container":"input-module_label-container__SngtG","required":"input-module_required__J1bMP","input-container":"input-module_input-container__nw0Oc","adornment":"input-module_adornment__cO4v1","textarea-container":"input-module_textarea-container__cc9-3","helper-text":"input-module_helper-text__DvzFI","is-focused":"input-module_is-focused__08nzj","error":"input-module_error__ftn_q","disabled":"input-module_disabled__9RjjE","sm":"input-module_sm__AtYYB","placeholder":"input-module_placeholder__I29pr","has-value":"input-module_has-value__juKDe","md":"input-module_md__nPnVp","lg":"input-module_lg__dC2Tp"};
|
|
3
|
+
var inputStyles = {"container":"input-module_container__bycn1","label-container":"input-module_label-container__SngtG","required":"input-module_required__J1bMP","input-container":"input-module_input-container__nw0Oc","ghost-wrap":"input-module_ghost-wrap__pHzia","ghost":"input-module_ghost__yVtI-","ghost-typed":"input-module_ghost-typed__r9NZN","adornment":"input-module_adornment__cO4v1","textarea-container":"input-module_textarea-container__cc9-3","helper-text":"input-module_helper-text__DvzFI","is-focused":"input-module_is-focused__08nzj","error":"input-module_error__ftn_q","disabled":"input-module_disabled__9RjjE","sm":"input-module_sm__AtYYB","placeholder":"input-module_placeholder__I29pr","has-value":"input-module_has-value__juKDe","md":"input-module_md__nPnVp","lg":"input-module_lg__dC2Tp"};
|
|
4
4
|
|
|
5
5
|
export { inputStyles as default };
|
|
6
6
|
//# sourceMappingURL=input.module.scss.js.map
|
|
@@ -204,6 +204,15 @@
|
|
|
204
204
|
width: 0.875rem;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
.select-module_group-label__J50K8 {
|
|
208
|
+
color: var(--text-secondary);
|
|
209
|
+
font-size: 0.68rem;
|
|
210
|
+
font-weight: 600;
|
|
211
|
+
letter-spacing: 0.06em;
|
|
212
|
+
padding: 0.4rem 0.55rem 0.2rem;
|
|
213
|
+
text-transform: uppercase;
|
|
214
|
+
}
|
|
215
|
+
|
|
207
216
|
.select-module_separator__aPMWg {
|
|
208
217
|
background-color: var(--divider);
|
|
209
218
|
height: 1px;
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import { type SelectContentProps, type SelectFieldProps, type SelectProps } from '@constellation/types';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
declare function Select({ open: openProp, defaultOpen, onOpenChange, value: valueProp, defaultValue, onValueChange, disabled, children, ...props }: SelectProps): React.JSX.Element;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* A titled run of options — the `<optgroup>` of this select.
|
|
6
|
+
*
|
|
7
|
+
* The heading is presentational and never focusable: it names the run, it is
|
|
8
|
+
* not a thing you can pick. Labelling the group with `aria-label` rather than
|
|
9
|
+
* pointing at the heading keeps it out of the option list for a screen reader
|
|
10
|
+
* too.
|
|
11
|
+
*/
|
|
12
|
+
declare function SelectGroup({ label, children, ...props }: React.HTMLAttributes<HTMLDivElement> & {
|
|
13
|
+
label?: React.ReactNode;
|
|
14
|
+
}): React.JSX.Element;
|
|
5
15
|
declare function SelectValue({ children, placeholder, ...props }: React.HTMLAttributes<HTMLSpanElement> & {
|
|
6
16
|
placeholder?: React.ReactNode;
|
|
7
17
|
}): React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/form/Select/select.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EAErB,KAAK,WAAW,EAEjB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAya/B,iBAAS,MAAM,CAAC,EACd,IAAI,EAAE,QAAQ,EACd,WAAW,EACX,YAAY,EACZ,KAAK,EAAE,SAAS,EAChB,YAAY,EACZ,aAAa,EACb,QAAgB,EAChB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,qBAoHb;AAED,iBAAS,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/form/Select/select.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EAErB,KAAK,WAAW,EAEjB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAya/B,iBAAS,MAAM,CAAC,EACd,IAAI,EAAE,QAAQ,EACd,WAAW,EACX,YAAY,EACZ,KAAK,EAAE,SAAS,EAChB,YAAY,EACZ,aAAa,EACb,QAAgB,EAChB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,WAAW,qBAoHb;AAED;;;;;;;GAOG;AACH,iBAAS,WAAW,CAAC,EACnB,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,qBAgBpE;AAED,iBAAS,WAAW,CAAC,EACnB,QAAQ,EACR,WAAW,EACX,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,qBAS3E;AAED,iBAAS,aAAa,CAAC,EACrB,SAAS,EACT,QAAQ,EACR,OAAO,EACP,SAAS,EACT,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,qBAwD/C;AAED,iBAAS,aAAa,CAAC,EACrB,KAAe,EACf,SAAS,EACT,QAAQ,EACR,gBAA4C,EAC5C,SAAS,EACT,QAAmB,EACnB,IAAe,EACf,UAAc,EACd,GAAG,KAAK,EACT,EAAE,kBAAkB,qBA2FpB;AAED,iBAAS,UAAU,CAAC,EAClB,SAAS,EACT,QAAQ,EACR,QAAgB,EAChB,OAAO,EACP,WAAW,EACX,KAAK,EACL,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,qBA2CnE;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,qBAErF;AA0lBD,iBAAS,WAAW,CAAC,KAAK,EAAE,gBAAgB,qBA8N3C;AAED,OAAO,EACL,MAAM,EACN,aAAa,EACb,WAAW,EACX,WAAW,EACX,UAAU,EACV,eAAe,EACf,aAAa,EACb,WAAW,GACZ,CAAC"}
|
|
@@ -342,8 +342,16 @@ function Select({ open: openProp, defaultOpen, onOpenChange, value: valueProp, d
|
|
|
342
342
|
]);
|
|
343
343
|
return (jsx(SelectContext.Provider, { value: contextValue, children: jsx("div", { "data-slot": 'select', ...props, children: children }) }));
|
|
344
344
|
}
|
|
345
|
-
|
|
346
|
-
|
|
345
|
+
/**
|
|
346
|
+
* A titled run of options — the `<optgroup>` of this select.
|
|
347
|
+
*
|
|
348
|
+
* The heading is presentational and never focusable: it names the run, it is
|
|
349
|
+
* not a thing you can pick. Labelling the group with `aria-label` rather than
|
|
350
|
+
* pointing at the heading keeps it out of the option list for a screen reader
|
|
351
|
+
* too.
|
|
352
|
+
*/
|
|
353
|
+
function SelectGroup({ label, children, ...props }) {
|
|
354
|
+
return (jsxs("div", { "data-slot": 'select-group', role: 'group', "aria-label": typeof label === 'string' ? label : undefined, ...props, children: [label ? (jsx("div", { "data-slot": 'select-group-label', "aria-hidden": 'true', className: s['group-label'], children: label })) : null, children] }));
|
|
347
355
|
}
|
|
348
356
|
function SelectValue({ children, placeholder, ...props }) {
|
|
349
357
|
const context = useSelectContext('SelectValue');
|