reshaped 3.2.0-canary.1 → 3.2.0-canary.3
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/CHANGELOG.md +4 -0
- package/dist/bundle.css +1 -1
- package/dist/bundle.d.ts +1 -1
- package/dist/bundle.js +11 -11
- package/dist/components/Autocomplete/Autocomplete.js +22 -18
- package/dist/components/Autocomplete/Autocomplete.types.d.ts +4 -2
- package/dist/components/Autocomplete/index.d.ts +1 -1
- package/dist/components/Autocomplete/tests/Autocomplete.stories.d.ts +1 -0
- package/dist/components/Autocomplete/tests/Autocomplete.stories.js +81 -0
- package/dist/components/Badge/Badge.module.css +1 -1
- package/dist/components/Modal/Modal.types.d.ts +1 -1
- package/dist/components/TextField/TextField.js +5 -6
- package/dist/components/TextField/TextField.module.css +1 -1
- package/dist/components/TextField/TextField.types.d.ts +2 -0
- package/dist/components/TextField/tests/TextField.stories.d.ts +1 -1
- package/dist/components/TextField/tests/TextField.stories.js +6 -2
- package/dist/components/_private/Aligner/Aligner.module.css +1 -1
- package/dist/components/_private/Portal/Portal.types.d.ts +2 -2
- package/dist/constants/keys.d.ts +1 -0
- package/dist/constants/keys.js +1 -0
- package/dist/hooks/_private/useSingletonHotkeys.d.ts +3 -3
- package/dist/hooks/useDrag.d.ts +1 -1
- package/dist/icons/Plus.d.ts +2 -0
- package/dist/icons/Plus.js +3 -0
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
@@ -6,18 +6,29 @@ import DropdownMenu from "../DropdownMenu/index.js";
|
|
6
6
|
import useHotkeys from "../../hooks/useHotkeys.js";
|
7
7
|
import { getActiveElement } from "../../utilities/a11y/focus.js";
|
8
8
|
import * as keys from "../../constants/keys.js";
|
9
|
+
import useHandlerRef from "../../hooks/useHandlerRef.js";
|
9
10
|
const AutocompleteContext = React.createContext({});
|
10
11
|
const Autocomplete = (props) => {
|
11
|
-
const { children, onChange, onInput, onItemSelect, name, containerRef, ...textFieldProps } = props;
|
12
|
-
const
|
12
|
+
const { children, onChange, onInput, onItemSelect, name, containerRef, instanceRef, onBackspace, ...textFieldProps } = props;
|
13
|
+
const onBackspaceRef = useHandlerRef(onBackspace);
|
14
|
+
const internalInputRef = React.useRef(null);
|
15
|
+
const inputAttributesRef = textFieldProps.inputAttributes?.ref;
|
16
|
+
const inputRef = inputAttributesRef && typeof inputAttributesRef !== "string" && "current" in inputAttributesRef
|
17
|
+
? inputAttributesRef
|
18
|
+
: internalInputRef;
|
13
19
|
const [active, setActive] = React.useState(false);
|
14
|
-
// Prevent dropdown from opening on selecting an item
|
15
|
-
const [locked, setLocked] = React.useState(false);
|
16
20
|
const hasChildren = !!React.Children.toArray(children).filter(Boolean).length;
|
21
|
+
const lockedRef = React.useRef(false);
|
17
22
|
const handleOpen = React.useCallback(() => setActive(true), []);
|
18
23
|
const handleClose = () => setActive(false);
|
19
24
|
useHotkeys({
|
20
|
-
[
|
25
|
+
[keys.BACKSPACE]: () => onBackspaceRef.current?.(),
|
26
|
+
}, [onBackspaceRef], {
|
27
|
+
ref: inputRef,
|
28
|
+
disabled: !onBackspaceRef.current,
|
29
|
+
});
|
30
|
+
useHotkeys({
|
31
|
+
[keys.DOWN]: () => handleOpen(),
|
21
32
|
[keys.ENTER]: () => {
|
22
33
|
const el = getActiveElement();
|
23
34
|
el?.click();
|
@@ -25,34 +36,27 @@ const Autocomplete = (props) => {
|
|
25
36
|
}, [handleOpen], { ref: inputRef, preventDefault: true });
|
26
37
|
const handleChange = (args) => {
|
27
38
|
onChange?.(args);
|
28
|
-
setLocked(false);
|
29
39
|
handleOpen();
|
30
40
|
};
|
31
41
|
const handleItemClick = (args) => {
|
32
42
|
onChange?.({ value: args.value, name });
|
33
43
|
onItemSelect?.({ value: args.value });
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
if (!locked)
|
39
|
-
return;
|
40
|
-
setActive(false);
|
41
|
-
setLocked(false);
|
42
|
-
});
|
43
|
-
textFieldProps.onFocus?.(e);
|
44
|
+
// Prevent dropdown from re-opening when clicked on item with mouse
|
45
|
+
// and focus moves to the item and back to the input
|
46
|
+
lockedRef.current = true;
|
47
|
+
setTimeout(() => (lockedRef.current = false), 100);
|
44
48
|
};
|
45
49
|
const handleInput = (e) => {
|
46
50
|
onInput?.({ value: e.currentTarget.value, name, event: e });
|
47
51
|
textFieldProps.inputAttributes?.onInput?.(e);
|
48
52
|
};
|
49
|
-
return (_jsx(AutocompleteContext.Provider, { value: { onItemClick: handleItemClick }, children: _jsxs(DropdownMenu, { position: "bottom", width: "trigger", triggerType: "focus", trapFocusMode: "selection-menu", active: !
|
53
|
+
return (_jsx(AutocompleteContext.Provider, { value: { onItemClick: handleItemClick }, children: _jsxs(DropdownMenu, { position: "bottom", width: "trigger", triggerType: "focus", trapFocusMode: "selection-menu", active: !lockedRef.current && hasChildren && active, onClose: handleClose, onOpen: handleOpen, containerRef: containerRef, disableHideAnimation: true, instanceRef: instanceRef, children: [_jsx(DropdownMenu.Trigger, { children: ({ ref, ...attributes }) => (_jsx(TextField, { ...textFieldProps, name: name, onChange: handleChange, focused: hasChildren && active,
|
50
54
|
// Ignoring the type check since TS can't infer the correct html element type
|
51
55
|
attributes: { ...textFieldProps.attributes, ref }, inputAttributes: {
|
52
56
|
...textFieldProps.inputAttributes,
|
53
57
|
onFocus: (e) => {
|
54
58
|
attributes.onFocus?.();
|
55
|
-
|
59
|
+
textFieldProps.onFocus?.(e);
|
56
60
|
},
|
57
61
|
onInput: handleInput,
|
58
62
|
ref: inputRef,
|
@@ -1,11 +1,12 @@
|
|
1
1
|
import type { TextFieldProps } from "../TextField";
|
2
2
|
import type { MenuItemProps } from "../MenuItem";
|
3
|
-
import type { DropdownMenuProps } from "../DropdownMenu";
|
4
|
-
export type Props = TextFieldProps & Pick<DropdownMenuProps, "containerRef"> & {
|
3
|
+
import type { DropdownMenuProps, DropdownMenuInstance } from "../DropdownMenu";
|
4
|
+
export type Props = TextFieldProps & Pick<DropdownMenuProps, "containerRef" | "instanceRef"> & {
|
5
5
|
onInput?: TextFieldProps["onChange"];
|
6
6
|
onItemSelect?: (args: {
|
7
7
|
value: string;
|
8
8
|
}) => void;
|
9
|
+
onBackspace?: () => void;
|
9
10
|
children: React.ReactNode;
|
10
11
|
};
|
11
12
|
export type ItemProps = MenuItemProps & {
|
@@ -16,3 +17,4 @@ export type Context = {
|
|
16
17
|
value: string;
|
17
18
|
}) => void;
|
18
19
|
};
|
20
|
+
export type Instance = DropdownMenuInstance;
|
@@ -1,2 +1,2 @@
|
|
1
1
|
export { default } from "./Autocomplete";
|
2
|
-
export type { Props as AutocompleteProps } from "./Autocomplete.types";
|
2
|
+
export type { Props as AutocompleteProps, Instance as AutocompleteInstance, } from "./Autocomplete.types";
|
@@ -3,6 +3,14 @@ import { Example } from "../../../utilities/storybook/index.js";
|
|
3
3
|
import Autocomplete from "../index.js";
|
4
4
|
import Loader from "../../Loader/index.js";
|
5
5
|
import View from "../../View/index.js";
|
6
|
+
import Badge from "../../Badge/index.js";
|
7
|
+
import useToggle from "../../../hooks/useToggle.js";
|
8
|
+
import Modal from "../../Modal/index.js";
|
9
|
+
import TextField from "../../TextField/index.js";
|
10
|
+
import Text from "../../Text/index.js";
|
11
|
+
import Button from "../../Button/index.js";
|
12
|
+
import PlusIcon from "../../../icons/Plus.js";
|
13
|
+
import Dismissible from "../../Dismissible/index.js";
|
6
14
|
export default {
|
7
15
|
title: "Components/Autocomplete",
|
8
16
|
component: Autocomplete,
|
@@ -53,3 +61,76 @@ export const base = () => (<Example>
|
|
53
61
|
<DemoAsync />
|
54
62
|
</Example.Item>
|
55
63
|
</Example>);
|
64
|
+
export const multiselect = () => {
|
65
|
+
const inputRef = React.useRef(null);
|
66
|
+
const [values, setValues] = React.useState([]);
|
67
|
+
const [query, setQuery] = React.useState("");
|
68
|
+
const [customValueQuery, setCustomValueQuery] = React.useState("");
|
69
|
+
const customValueToggle = useToggle();
|
70
|
+
const handleDismiss = (dismissedValue) => {
|
71
|
+
const nextValues = values.filter((value) => value !== dismissedValue);
|
72
|
+
setValues(nextValues);
|
73
|
+
inputRef.current?.focus();
|
74
|
+
};
|
75
|
+
const handleAddCustomValue = () => {
|
76
|
+
if (customValueQuery.length) {
|
77
|
+
setValues((prev) => [...prev, customValueQuery]);
|
78
|
+
}
|
79
|
+
customValueToggle.deactivate();
|
80
|
+
setCustomValueQuery("");
|
81
|
+
};
|
82
|
+
const valuesNode = !!values.length && (<View direction="row" gap={1}>
|
83
|
+
{values.map((value) => (<Badge dismissAriaLabel="Dismiss value" onDismiss={() => handleDismiss(value)} key={value} size="small">
|
84
|
+
{value}
|
85
|
+
</Badge>))}
|
86
|
+
</View>);
|
87
|
+
return (<>
|
88
|
+
<Autocomplete name="fruit" value={query} placeholder="Pick your food" startSlot={valuesNode} inputAttributes={{ ref: inputRef }} onBackspace={() => {
|
89
|
+
if (!query.length)
|
90
|
+
handleDismiss(values[values.length - 1]);
|
91
|
+
}} multiline onChange={(args) => setQuery(args.value)} onItemSelect={(args) => {
|
92
|
+
setCustomValueQuery(query);
|
93
|
+
setQuery("");
|
94
|
+
if (args.value === "_custom") {
|
95
|
+
customValueToggle.activate();
|
96
|
+
return;
|
97
|
+
}
|
98
|
+
setValues((prev) => [...prev, args.value]);
|
99
|
+
}}>
|
100
|
+
{["Pizza", "Pie", "Ice-cream"].map((v) => {
|
101
|
+
if (!v.toLowerCase().includes(query.toLowerCase()))
|
102
|
+
return;
|
103
|
+
if (values.includes(v))
|
104
|
+
return;
|
105
|
+
return (<Autocomplete.Item key={v} value={v}>
|
106
|
+
{v}
|
107
|
+
</Autocomplete.Item>);
|
108
|
+
})}
|
109
|
+
{!!query.length && (<Autocomplete.Item value="_custom" icon={PlusIcon}>
|
110
|
+
Add a custom value
|
111
|
+
</Autocomplete.Item>)}
|
112
|
+
</Autocomplete>
|
113
|
+
<Modal onClose={customValueToggle.deactivate} active={customValueToggle.active}>
|
114
|
+
<View gap={4}>
|
115
|
+
<Dismissible onClose={customValueToggle.deactivate} closeAriaLabel="Close modal">
|
116
|
+
<Modal.Title>
|
117
|
+
<Text variant="body-3" weight="medium">
|
118
|
+
Add a custom value
|
119
|
+
</Text>
|
120
|
+
</Modal.Title>
|
121
|
+
</Dismissible>
|
122
|
+
<View direction="row" gap={3} as="form" attributes={{
|
123
|
+
onSubmit: (e) => {
|
124
|
+
e.preventDefault();
|
125
|
+
handleAddCustomValue();
|
126
|
+
},
|
127
|
+
}}>
|
128
|
+
<View.Item grow>
|
129
|
+
<TextField name="custom" onChange={(args) => setCustomValueQuery(args.value)} value={customValueQuery}/>
|
130
|
+
</View.Item>
|
131
|
+
<Button type="submit">Add</Button>
|
132
|
+
</View>
|
133
|
+
</View>
|
134
|
+
</Modal>
|
135
|
+
</>);
|
136
|
+
};
|
@@ -1 +1 @@
|
|
1
|
-
.root{align-items:center;backface-visibility:hidden;background:var(--rs-color-background-neutral);border:1px solid var(--rs-color-background-neutral);
|
1
|
+
.root{align-items:center;backface-visibility:hidden;background:var(--rs-color-background-neutral);border:1px solid var(--rs-color-background-neutral);box-sizing:border-box;color:var(--rs-color-foreground-neutral);display:inline-flex;gap:var(--rs-badge-gap);justify-content:center;min-width:calc(var(--rs-badge-line-height) + 2px + (var(--rs-badge-p-v) * 2));padding:var(--rs-badge-p-v) var(--rs-badge-p-h);transition:var(--rs-duration-medium) var(--rs-easing-standard);transition-property:transform,opacity;vertical-align:top}.dismiss,.root{border-radius:var(--rs-radius-small)}.dismiss{transition:var(--rs-duration-fast) var(--rs-easing-standard);transition-property:opacity}.root .dismiss:hover,.root.--actionable:hover:not(:has(.dismiss:hover)){opacity:.8}.root.--variant-faded{background:var(--rs-color-background-neutral-faded);border-color:var(--rs-color-background-neutral-faded);color:var(--rs-color-foreground-neutral-faded)}.root.--variant-outline{background:none;border-color:var(--rs-color-border-neutral-faded)}.root.--color-positive{background:var(--rs-color-background-positive);border-color:var(--rs-color-background-positive);color:var(--rs-color-on-background-positive)}.root.--color-positive.--variant-faded{background:var(--rs-color-background-positive-faded);border-color:var(--rs-color-background-positive-faded);color:var(--rs-color-foreground-positive)}.root.--color-positive.--variant-outline{background:none;border-color:var(--rs-color-border-positive);color:var(--rs-color-foreground-positive)}.root.--color-critical{background:var(--rs-color-background-critical);border-color:var(--rs-color-background-critical);color:var(--rs-color-on-background-critical)}.root.--color-critical.--variant-faded{background:var(--rs-color-background-critical-faded);border-color:var(--rs-color-background-critical-faded);color:var(--rs-color-foreground-critical)}.root.--color-critical.--variant-outline{background:none;border-color:var(--rs-color-border-critical);color:var(--rs-color-foreground-critical)}.root.--color-warning{background:var(--rs-color-background-warning);border-color:var(--rs-color-background-warning);color:var(--rs-color-on-background-warning)}.root.--color-warning.--variant-faded{background:var(--rs-color-background-warning-faded);border-color:var(--rs-color-background-warning-faded);color:var(--rs-color-foreground-warning)}.root.--color-warning.--variant-outline{background:none;border-color:var(--rs-color-border-warning);color:var(--rs-color-foreground-warning)}.root.--color-primary{background:var(--rs-color-background-primary);border-color:var(--rs-color-background-primary);color:var(--rs-color-on-background-primary)}.root.--color-primary.--variant-faded{background:var(--rs-color-background-primary-faded);border-color:var(--rs-color-background-primary-faded);color:var(--rs-color-foreground-primary)}.root.--color-primary.--variant-outline{background:none;border-color:var(--rs-color-border-primary);color:var(--rs-color-foreground-primary)}.root.--size-small{--rs-badge-p-v:0px;--rs-badge-p-h:var(--rs-unit-x1);--rs-badge-line-height:var(--rs-line-height-caption-1);--rs-badge-empty-size:var(--rs-unit-x2);--rs-badge-gap:calc(var(--rs-unit-x1) / 2)}.root.--size-medium{--rs-badge-p-v:calc(var(--rs-unit-x1) - 1px);--rs-badge-p-h:calc(var(--rs-unit-x2) - 1px);--rs-badge-line-height:var(--rs-line-height-caption-1);--rs-badge-empty-size:var(--rs-unit-x3);--rs-badge-gap:var(--rs-unit-x1)}.root.--size-large{--rs-badge-p-v:calc(var(--rs-unit-x1) - 1px);--rs-badge-p-h:calc(var(--rs-unit-x2) - 1px);--rs-badge-line-height:var(--rs-line-height-body-3);--rs-badge-empty-size:var(--rs-unit-x4);--rs-badge-gap:var(--rs-unit-x1)}.root.--rounded{border-radius:999px}.root:empty{height:var(--rs-badge-empty-size);min-width:auto;padding:0;width:var(--rs-badge-empty-size)}.root.--hidden{opacity:0;transform:scale(.2)}.container{display:inline-block;position:relative;vertical-align:top}.container .root{inset-inline-end:0;pointer-events:none;position:absolute;transform:translate(50%,var(--rs-badge-translate-y)) scale(1);z-index:10}.container .root.--hidden{transform:translate(50%,var(--rs-badge-translate-y)) scale(.2)}[dir=rtl] .container .root{transform:translate(-50%,var(--rs-badge-translate-y)) scale(1)}[dir=rtl] .container .root.--hidden{transform:translate(-50%,var(--rs-badge-translate-y)) scale(.2)}.--container-overlap .root{inset-inline-end:14%}.--container-position-top-end .root{--rs-badge-translate-y:-50%;top:0}.--container-position-top-end.--container-overlap .root{top:14%}.--container-position-bottom-end .root{--rs-badge-translate-y:50%;bottom:0}.--container-position-bottom-end.--container-overlap .root{bottom:14%}
|
@@ -28,6 +28,6 @@ export type Props = {
|
|
28
28
|
className?: G.ClassName;
|
29
29
|
overlayClassName?: G.ClassName;
|
30
30
|
attributes?: G.Attributes<"div"> & {
|
31
|
-
ref?: React.RefObject<HTMLDivElement
|
31
|
+
ref?: React.RefObject<HTMLDivElement>;
|
32
32
|
};
|
33
33
|
} & Pick<OverlayProps, "onClose" | "onOpen" | "active">;
|
@@ -10,9 +10,8 @@ const TextFieldSlot = (props) => {
|
|
10
10
|
const { slot, icon, size, affix, position } = props;
|
11
11
|
if (!icon && !slot && !affix)
|
12
12
|
return null;
|
13
|
-
const attachmentClassNames = classNames(s.attachment, s[`attachment--position-${position}`]);
|
14
13
|
const content = [
|
15
|
-
slot && (_jsx("div", { className: s.slot, children: slot }, "slot")),
|
14
|
+
slot && (_jsx("div", { className: classNames(s.slot, s[`slot--position-${position}`]), children: slot }, "slot")),
|
16
15
|
icon && (_jsx("div", { className: s.icon, children: _jsx(Icon, { size: responsivePropDependency(size, (size) => {
|
17
16
|
if (size === "large")
|
18
17
|
return 5;
|
@@ -20,19 +19,19 @@ const TextFieldSlot = (props) => {
|
|
20
19
|
return 6;
|
21
20
|
return 4;
|
22
21
|
}), svg: icon }) }, "icon")),
|
23
|
-
affix && (_jsx("div", { className: s.affix, children: affix }, "affix")),
|
22
|
+
affix && (_jsx("div", { className: classNames(s.affix, s[`affix--position-${position}`]), children: affix }, "affix")),
|
24
23
|
].filter(Boolean);
|
25
|
-
return
|
24
|
+
return position === "end" ? content.reverse() : content;
|
26
25
|
};
|
27
26
|
const TextField = (props) => {
|
28
|
-
const { onChange, onFocus, onBlur, name, value, defaultValue, placeholder, icon, endIcon, startSlot, endSlot, prefix, suffix, size = "medium", variant = "outline", className, attributes, } = props;
|
27
|
+
const { onChange, onFocus, onBlur, name, value, defaultValue, placeholder, icon, endIcon, startSlot, endSlot, prefix, suffix, size = "medium", variant = "outline", focused, multiline, className, attributes, } = props;
|
29
28
|
const formControl = useFormControl();
|
30
29
|
const id = useElementId(props.id);
|
31
30
|
const inputId = formControl?.attributes.id || props.inputAttributes?.id || id;
|
32
31
|
const disabled = formControl?.disabled || props.disabled;
|
33
32
|
const hasError = formControl?.hasError || props.hasError;
|
34
33
|
const inputAttributes = { ...props.inputAttributes, ...formControl?.attributes };
|
35
|
-
const rootClassName = classNames(s.root, className, size && responsiveClassNames(s, "--size", size), hasError && s["--status-error"], disabled && s["--disabled"], variant && s[`--variant-${variant}`]);
|
34
|
+
const rootClassName = classNames(s.root, className, size && responsiveClassNames(s, "--size", size), hasError && s["--status-error"], disabled && s["--disabled"], focused && s["--focused"], multiline && s["--multiline"], variant && s[`--variant-${variant}`]);
|
36
35
|
const handleChange = (event) => {
|
37
36
|
if (!onChange)
|
38
37
|
return;
|
@@ -1 +1 @@
|
|
1
|
-
.root{--rs-p-
|
1
|
+
.root{--rs-p-h:var(--rs-text-field-gap);background:var(--rs-color-background-elevation-base);border:1px solid var(--rs-color-border-neutral);display:flex;gap:var(--rs-text-field-gap);padding:calc(var(--rs-unit-x1) - 1px) var(--rs-text-field-gap);position:relative;row-gap:var(--rs-unit-x1);z-index:0}.root:not(:has(button:focus,a:focus,[tabindex="0"]:focus)):focus-within{border-color:var(--rs-color-border-primary);box-shadow:0 0 0 1px var(--rs-color-border-primary)}.root.--multiline{flex-wrap:wrap}.root.--multiline .input{width:auto}.input{background:none;border:none;box-sizing:border-box;color:var(--rs-color-foreground-neutral);flex-grow:1;font-family:var(--rs-font-family-body);font-weight:var(--rs-font-weight-regular);margin:calc(var(--rs-unit-x1) * -1) calc(var(--rs-text-field-gap) * -1);outline:none;padding-inline:var(--rs-text-field-gap);position:relative;width:100%;z-index:1}.input:-webkit-autofill{-webkit-background-clip:text;-webkit-text-fill-color:var(--rs-color-foreground-neutral)}.affix,.icon,.slot{align-items:center;display:flex;flex-shrink:0;min-height:calc(var(--rs-text-field-line-height) + var(--rs-unit-x1) * 2);position:relative;z-index:5}.slot--position-end{margin-inline-end:calc(var(--rs-unit-x1) * -1)}.icon{pointer-events:none}.affix{color:var(--rs-color-foreground-neutral-faded)}.affix.affix--position-start{padding-inline-end:var(--rs-text-field-gap)}.affix.affix--position-start:after{border-inline-end:1px solid var(--rs-color-border-neutral-faded);content:"";inset-block:var(--rs-unit-x1);inset-inline-end:0;position:absolute}.affix.affix--position-end{padding-inline-start:var(--rs-text-field-gap)}.affix.affix--position-end:after{border-inline-start:1px solid var(--rs-color-border-neutral-faded);content:"";inset-block:var(--rs-unit-x1);inset-inline-start:0;position:absolute}.root.--disabled{background:var(--rs-color-background-disabled-faded);border-color:var(--rs-color-border-disabled)}.root.--disabled,.root.--disabled .input{color:var(--rs-color-foreground-disabled);cursor:not-allowed}.--size-medium{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium .input{padding-block:var(--rs-unit-x2)}.--size-medium .affix,.--size-medium .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large .input{padding-block:var(--rs-unit-x3)}.--size-large .affix,.--size-large .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge .input{padding-block:var(--rs-unit-x4)}.--size-xlarge .affix,.--size-xlarge .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.root.--variant-faded{background:var(--rs-color-background-neutral-faded);border-color:transparent}.root.--variant-faded:focus-within{border-color:var(--rs-color-border-primary)}.root.--variant-headless{background:transparent;border-color:transparent}.root.--variant-headless.--status-error,.root.--variant-headless.--status-error:focus-within,.root.--variant-headless:focus-within{border-color:transparent;box-shadow:none}.root.--status-error{border-color:var(--rs-color-border-critical)}.root.--status-error:focus-within{border-color:var(--rs-color-border-primary)}@media (--rs-viewport-s ) and (hover:none){.input{font-size:var(--rs-font-size-body-2)!important}}@media (--rs-viewport-m ){.--size-medium--m{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium--m .input{padding-block:var(--rs-unit-x2)}.--size-medium--m .affix,.--size-medium--m .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large--m{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large--m .input{padding-block:var(--rs-unit-x3)}.--size-large--m .affix,.--size-large--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge--m{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge--m .input{padding-block:var(--rs-unit-x4)}.--size-xlarge--m .affix,.--size-xlarge--m .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-l ){.--size-medium--l{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium--l .input{padding-block:var(--rs-unit-x2)}.--size-medium--l .affix,.--size-medium--l .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large--l{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large--l .input{padding-block:var(--rs-unit-x3)}.--size-large--l .affix,.--size-large--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge--l{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge--l .input{padding-block:var(--rs-unit-x4)}.--size-xlarge--l .affix,.--size-xlarge--l .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}@media (--rs-viewport-xl ){.--size-medium--xl{--rs-text-field-gap:var(--rs-unit-x2);--rs-text-field-line-height:var(--rs-line-height-body-3);border-radius:var(--rs-radius-small)}.--size-medium--xl .input{padding-block:var(--rs-unit-x2)}.--size-medium--xl .affix,.--size-medium--xl .input{font-size:var(--rs-font-size-body-3);letter-spacing:var(--rs-letter-spacing-body-3);line-height:var(--rs-line-height-body-3)}.--size-large--xl{--rs-text-field-gap:var(--rs-unit-x3);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-large--xl .input{padding-block:var(--rs-unit-x3)}.--size-large--xl .affix,.--size-large--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}.--size-xlarge--xl{--rs-text-field-gap:var(--rs-unit-x4);--rs-text-field-line-height:var(--rs-line-height-body-2);border-radius:var(--rs-radius-medium)}.--size-xlarge--xl .input{padding-block:var(--rs-unit-x4)}.--size-xlarge--xl .affix,.--size-xlarge--xl .input{font-size:var(--rs-font-size-body-2);letter-spacing:var(--rs-letter-spacing-body-2);line-height:var(--rs-line-height-body-2)}}
|
@@ -15,7 +15,7 @@ export declare const value: () => import("react").JSX.Element;
|
|
15
15
|
export declare const variants: () => import("react").JSX.Element;
|
16
16
|
export declare const disabled: () => import("react").JSX.Element;
|
17
17
|
export declare const error: () => import("react").JSX.Element;
|
18
|
-
export declare const
|
18
|
+
export declare const attachments: () => import("react").JSX.Element;
|
19
19
|
export declare const size: () => import("react").JSX.Element;
|
20
20
|
export declare const affixes: () => import("react").JSX.Element;
|
21
21
|
export declare const slots: () => import("react").JSX.Element;
|
@@ -49,7 +49,7 @@ export const error = () => (<Example>
|
|
49
49
|
<TextField name="Name" placeholder="Enter your name" hasError/>
|
50
50
|
</Example.Item>
|
51
51
|
</Example>);
|
52
|
-
export const
|
52
|
+
export const attachments = () => (<Example>
|
53
53
|
<Example.Item title="icon">
|
54
54
|
<TextField name="Name" placeholder="Enter your name" value="Reshaped" icon={IconZap}/>
|
55
55
|
</Example.Item>
|
@@ -60,6 +60,10 @@ export const icon = () => (<Example>
|
|
60
60
|
<Example.Item title="width affixes">
|
61
61
|
<TextField name="Name" placeholder="Enter your name" value="Reshaped" endIcon={IconZap} icon={IconZap} prefix="Estimated value" suffix="m2"/>
|
62
62
|
</Example.Item>
|
63
|
+
|
64
|
+
<Example.Item title="multine">
|
65
|
+
<TextField name="Name" placeholder="Enter your name" value="Reshaped" endIcon={IconZap} icon={IconZap} prefix="Estimated value" suffix="m2" multiline/>
|
66
|
+
</Example.Item>
|
63
67
|
</Example>);
|
64
68
|
export const size = () => (<Example>
|
65
69
|
<Example.Item title="size: medium">
|
@@ -89,7 +93,7 @@ export const affixes = () => (<Example>
|
|
89
93
|
</Example>);
|
90
94
|
export const slots = () => (<Example>
|
91
95
|
<Example.Item title={["startSlot", "vertical and horizontal padding aligned"]}>
|
92
|
-
<TextField name="Name" placeholder="Enter your name" value="Reshaped" startSlot={<Placeholder h={
|
96
|
+
<TextField name="Name" placeholder="Enter your name" value="Reshaped" startSlot={<Placeholder h={20}/>}/>
|
93
97
|
</Example.Item>
|
94
98
|
<Example.Item title={["endSlot", "vertical and horizontal padding aligned"]}>
|
95
99
|
<TextField name="Name" placeholder="Enter your name" value="Reshaped" endSlot={<Button icon={IconZap} size="small" onClick={() => { }}/>}/>
|
@@ -1 +1 @@
|
|
1
|
-
.root [data-rs-aligner-target]{--rs-aligner-p-h:var(--rs-p-h,var(--rs-p));--rs-aligner-p-v:var(--rs-p-v,var(--rs-p))}.root.--side-all [data-rs-aligner-target]{margin:calc(var(--rs-aligner-p-v) * -1) calc(var(--rs-aligner-p-h) * -1)}.root.--side-inline [data-rs-aligner-target],.root.--side-start [data-rs-aligner-target]{margin-inline-start:calc(var(--rs-aligner-p-h) * -1)}.root.--side-end [data-rs-aligner-target],.root.--side-inline [data-rs-aligner-target]{margin-inline-end:calc(var(--rs-aligner-p-h) * -1)}.root.--side-block [data-rs-aligner-target],.root.--side-top [data-rs-aligner-target]{margin-block-start:calc(var(--rs-aligner-p-v) * -1)}.root.--side-block [data-rs-aligner-target],.root.--side-bottom [data-rs-aligner-target]{margin-block-end:calc(var(--rs-aligner-p-v) * -1)}
|
1
|
+
.root [data-rs-aligner-target]{--rs-aligner-p-h:var(--rs-p-h,var(--rs-p,0px));--rs-aligner-p-v:var(--rs-p-v,var(--rs-p,0px))}.root.--side-all [data-rs-aligner-target]{margin:calc(var(--rs-aligner-p-v) * -1) calc(var(--rs-aligner-p-h) * -1)}.root.--side-inline [data-rs-aligner-target],.root.--side-start [data-rs-aligner-target]{margin-inline-start:calc(var(--rs-aligner-p-h) * -1)}.root.--side-end [data-rs-aligner-target],.root.--side-inline [data-rs-aligner-target]{margin-inline-end:calc(var(--rs-aligner-p-h) * -1)}.root.--side-block [data-rs-aligner-target],.root.--side-top [data-rs-aligner-target]{margin-block-start:calc(var(--rs-aligner-p-v) * -1)}.root.--side-block [data-rs-aligner-target],.root.--side-bottom [data-rs-aligner-target]{margin-block-end:calc(var(--rs-aligner-p-v) * -1)}
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import React from "react";
|
2
2
|
export type Props = {
|
3
3
|
children?: React.ReactNode;
|
4
|
-
targetRef?: React.RefObject<HTMLElement | ShadowRoot
|
4
|
+
targetRef?: React.RefObject<HTMLElement | ShadowRoot>;
|
5
5
|
};
|
6
6
|
export type ScopeProps<T extends HTMLElement> = {
|
7
7
|
children: (ref: React.RefObject<T>) => React.ReactNode;
|
8
8
|
};
|
9
9
|
export type Context = {
|
10
|
-
scopeRef: React.RefObject<HTMLElement
|
10
|
+
scopeRef: React.RefObject<HTMLElement>;
|
11
11
|
};
|
package/dist/constants/keys.d.ts
CHANGED
package/dist/constants/keys.js
CHANGED
@@ -10,17 +10,17 @@ type HotkeyOptions = {
|
|
10
10
|
};
|
11
11
|
type Context = {
|
12
12
|
isPressed: (key: string) => boolean;
|
13
|
-
addHotkeys: (hotkeys: Hotkeys, ref: React.RefObject<HTMLElement
|
13
|
+
addHotkeys: (hotkeys: Hotkeys, ref: React.RefObject<HTMLElement>, options?: HotkeyOptions) => (() => void) | undefined;
|
14
14
|
};
|
15
15
|
type HotkeyData = {
|
16
16
|
callback: Callback;
|
17
|
-
ref: React.RefObject<HTMLElement
|
17
|
+
ref: React.RefObject<HTMLElement>;
|
18
18
|
options: HotkeyOptions;
|
19
19
|
};
|
20
20
|
export declare class HotkeyStore {
|
21
21
|
hotkeyMap: Record<string, Set<HotkeyData>>;
|
22
22
|
getSize: () => number;
|
23
|
-
bindHotkeys: (hotkeys: Hotkeys, ref: React.RefObject<HTMLElement
|
23
|
+
bindHotkeys: (hotkeys: Hotkeys, ref: React.RefObject<HTMLElement>, options: HotkeyOptions) => void;
|
24
24
|
unbindHotkeys: (hotkeys: Hotkeys) => void;
|
25
25
|
handleKeyDown: (pressedMap: PressedMap, e: KeyboardEvent) => void;
|
26
26
|
}
|
package/dist/hooks/useDrag.d.ts
CHANGED
@@ -10,7 +10,7 @@ declare const useDrag: <TriggerElement extends HTMLElement = HTMLButtonElement,
|
|
10
10
|
containerRef?: React.RefObject<ContainerElement>;
|
11
11
|
orientation?: "horizontal" | "vertical" | "all";
|
12
12
|
}) => {
|
13
|
-
ref: React.
|
13
|
+
ref: React.RefObject<TriggerElement>;
|
14
14
|
containerRef: React.RefObject<ContainerElement>;
|
15
15
|
active: boolean;
|
16
16
|
};
|
@@ -0,0 +1,3 @@
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
+
const PlusIcon = () => (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }), _jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })] }));
|
3
|
+
export default PlusIcon;
|
package/dist/index.d.ts
CHANGED
@@ -10,7 +10,7 @@ export type { ActionBarProps } from "./components/ActionBar";
|
|
10
10
|
export { default as Alert } from "./components/Alert";
|
11
11
|
export type { AlertProps } from "./components/Alert";
|
12
12
|
export { default as Autocomplete } from "./components/Autocomplete";
|
13
|
-
export type { AutocompleteProps } from "./components/Autocomplete";
|
13
|
+
export type { AutocompleteProps, AutocompleteInstance } from "./components/Autocomplete";
|
14
14
|
export { default as Avatar } from "./components/Avatar";
|
15
15
|
export type { AvatarProps } from "./components/Avatar";
|
16
16
|
export { default as Badge } from "./components/Badge";
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "reshaped",
|
3
3
|
"description": "Professionally crafted design system in React & Figma for building products of any scale and complexity",
|
4
|
-
"version": "3.2.0-canary.
|
4
|
+
"version": "3.2.0-canary.3",
|
5
5
|
"license": "MIT",
|
6
6
|
"email": "hello@reshaped.so",
|
7
7
|
"homepage": "https://reshaped.so",
|