reshaped 2.9.4 → 2.10.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/CHANGELOG.md +14 -0
- package/bundle.css +1 -1
- package/bundle.d.ts +2 -0
- package/bundle.js +10 -10
- package/cli/theming/index.js +2 -0
- package/components/Accordion/AccordionContent.js +1 -0
- package/components/Button/Button.js +2 -2
- package/components/Button/Button.types.d.ts +1 -1
- package/components/FormControl/FormControl.client.d.ts +3 -0
- package/components/FormControl/FormControl.client.js +28 -0
- package/components/FormControl/FormControl.d.ts +8 -5
- package/components/FormControl/FormControl.js +9 -62
- package/components/FormControl/FormControl.utilities.d.ts +2 -0
- package/components/FormControl/FormControl.utilities.js +1 -0
- package/components/FormControl/FormControlCaption.d.ts +3 -0
- package/components/FormControl/FormControlCaption.js +15 -0
- package/components/FormControl/FormControlError.d.ts +3 -0
- package/components/FormControl/FormControlError.js +12 -0
- package/components/FormControl/FormControlHelper.d.ts +3 -0
- package/components/FormControl/FormControlHelper.js +10 -0
- package/components/FormControl/FormControlLabel.d.ts +3 -0
- package/components/FormControl/FormControlLabel.js +18 -0
- package/components/FormControl/tests/FormControl.stories.d.ts +4 -5
- package/components/MenuItem/MenuItem.js +2 -2
- package/components/MenuItem/MenuItem.types.d.ts +1 -1
- package/components/Pagination/Pagination.d.ts +3 -0
- package/components/Pagination/Pagination.js +10 -0
- package/components/Pagination/Pagination.types.d.ts +52 -0
- package/components/Pagination/Pagination.types.js +1 -0
- package/components/Pagination/PaginationControlled.d.ts +3 -0
- package/components/Pagination/PaginationControlled.js +47 -0
- package/components/Pagination/PaginationUncontrolled.d.ts +3 -0
- package/components/Pagination/PaginationUncontrolled.js +25 -0
- package/components/Pagination/index.d.ts +2 -0
- package/components/Pagination/index.js +1 -0
- package/components/Pagination/tests/Pagination.stories.d.ts +11 -0
- package/components/Pagination/tests/Pagination.stories.js +24 -0
- package/components/Table/Table.js +2 -2
- package/components/Table/Table.module.css +1 -1
- package/components/Table/Table.types.d.ts +1 -0
- package/components/Table/tests/Table.stories.js +17 -0
- package/components/Text/Text.js +2 -2
- package/components/Text/Text.module.css +1 -1
- package/components/Text/Text.types.d.ts +1 -0
- package/components/Text/tests/Text.stories.d.ts +1 -0
- package/components/Text/tests/Text.stories.js +7 -0
- package/components/TextArea/TextArea.js +15 -6
- package/components/TextArea/TextArea.module.css +1 -1
- package/components/TextArea/TextArea.types.d.ts +1 -0
- package/components/TextArea/tests/TextArea.stories.d.ts +1 -0
- package/components/TextArea/tests/TextArea.stories.js +8 -0
- package/components/_private/Expandable/Expandable.js +7 -28
- package/components/_private/Expandable/Expandable.module.css +1 -1
- package/index.d.ts +2 -0
- package/index.js +1 -0
- package/package.json +30 -30
- package/themes/figma/media.css +1 -1
- package/themes/reshaped/media.css +1 -1
- package/themes/reshaped/theme.css +1 -1
- package/themes/slate/media.css +1 -1
- package/utilities/helpers.d.ts +1 -0
- package/utilities/helpers.js +5 -0
package/cli/theming/index.js
CHANGED
@@ -18,8 +18,10 @@ const transformDefinition = (name, definition, options) => {
|
|
18
18
|
: path_1.default.resolve(outputPath, name);
|
19
19
|
const themePath = path_1.default.resolve(themeFolderPath, "theme.css");
|
20
20
|
const themeMediaPath = path_1.default.resolve(themeFolderPath, "media.css");
|
21
|
+
const themeJsonPath = path_1.default.resolve(themeFolderPath, "theme.json");
|
21
22
|
fs_1.default.mkdirSync(themeFolderPath, { recursive: true });
|
22
23
|
fs_1.default.writeFileSync(themePath, code.variables);
|
24
|
+
fs_1.default.writeFileSync(themeJsonPath, JSON.stringify(definition));
|
23
25
|
if (code.media)
|
24
26
|
fs_1.default.writeFileSync(themeMediaPath, code.media);
|
25
27
|
const logOutput = `Compiled ${chalk_1.default.bold(name)} theme${isFragment ? " fragment" : ""}`;
|
@@ -8,7 +8,7 @@ import ButtonGroup from "./ButtonGroup.js";
|
|
8
8
|
import ButtonAligner from "./ButtonAligner.js";
|
9
9
|
import s from "./Button.module.css";
|
10
10
|
const Button = forwardRef((props, ref) => {
|
11
|
-
const { variant = "solid", color = "neutral", elevated, highlighted, fullWidth, loading, disabled, type, href, size = "medium",
|
11
|
+
const { variant = "solid", color = "neutral", elevated, highlighted, fullWidth, loading, disabled, type, href, size = "medium", children, rounded, onClick, icon, endIcon, as, className, attributes, } = props;
|
12
12
|
const iconOnly = (icon || endIcon) && !children;
|
13
13
|
const rootClassName = classNames(s.root, className, color && s[`--color-${color}`], variant && s[`--variant-${variant}`], responsiveClassNames(s, "--size", size), responsiveClassNames(s, "--full-width", fullWidth), elevated && variant !== "ghost" && s["--elevated"], rounded && s["--rounded"], disabled && s["--disabled"], loading && s["--loading"], highlighted && s["--highlighted"], iconOnly && s["--icon-only"]);
|
14
14
|
const renderIcon = (position) => {
|
@@ -27,7 +27,7 @@ const Button = forwardRef((props, ref) => {
|
|
27
27
|
});
|
28
28
|
return (_jsx(Icon, { className: iconClassName, svg: (position === "start" ? icon : endIcon), size: iconSize, autoWidth: true }));
|
29
29
|
};
|
30
|
-
return (_jsxs(Actionable, { disabled: disabled || loading, className: rootClassName, attributes: Object.assign(Object.assign({}, attributes), { "data-rs-aligner-target": true }), type: type, onClick: onClick, href: href, ref: ref, children: [loading && (_jsx("div", { className: s.loader, children: _jsx(Loader, { size: "small", color: "inherit" }) })), renderIcon("start"), children && _jsx("span", { className: s.text, children: children }), renderIcon("end")] }));
|
30
|
+
return (_jsxs(Actionable, { disabled: disabled || loading, className: rootClassName, attributes: Object.assign(Object.assign({}, attributes), { "data-rs-aligner-target": true }), type: type, onClick: onClick, href: href, ref: ref, as: as, children: [loading && (_jsx("div", { className: s.loader, children: _jsx(Loader, { size: "small", color: "inherit" }) })), renderIcon("start"), children && _jsx("span", { className: s.text, children: children }), renderIcon("end")] }));
|
31
31
|
});
|
32
32
|
Button.Group = ButtonGroup;
|
33
33
|
Button.Aligner = ButtonAligner;
|
@@ -4,7 +4,7 @@ import type { ActionableProps } from "../Actionable";
|
|
4
4
|
import type { AlignerProps as BaseAlignerProps } from "../_private/Aligner";
|
5
5
|
import type * as G from "../../types/global";
|
6
6
|
export type Size = "xlarge" | "large" | "medium" | "small";
|
7
|
-
export type Props = Pick<ActionableProps, "attributes" | "className" | "disabled" | "children" | "href" | "onClick" | "type"> & {
|
7
|
+
export type Props = Pick<ActionableProps, "attributes" | "className" | "disabled" | "children" | "href" | "onClick" | "type" | "as"> & {
|
8
8
|
color?: "black" | "white" | "primary" | "critical" | "positive" | "neutral" | "inherit";
|
9
9
|
variant?: "solid" | "outline" | "ghost" | "faded";
|
10
10
|
icon?: IconProps["svg"];
|
@@ -0,0 +1,28 @@
|
|
1
|
+
"use client";
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
3
|
+
import React from "react";
|
4
|
+
import useElementId from "../../hooks/useElementId.js";
|
5
|
+
import { Provider } from "./FormControl.context.js";
|
6
|
+
import { getCaptionId } from "./FormControl.utilities.js";
|
7
|
+
const FormControl = (props) => {
|
8
|
+
const { children, id: passedId, required, hasError, group, disabled, size } = props;
|
9
|
+
const id = useElementId(passedId);
|
10
|
+
const WrapperTagName = group ? "fieldset" : "div";
|
11
|
+
const [helperRendered, setHelperRendered] = React.useState(false);
|
12
|
+
const [errorRendered, setErrorRendered] = React.useState(false);
|
13
|
+
const describedby = [
|
14
|
+
helperRendered && getCaptionId(id),
|
15
|
+
errorRendered && getCaptionId(id, "error"),
|
16
|
+
]
|
17
|
+
.filter(Boolean)
|
18
|
+
.join(" ");
|
19
|
+
const attributes = { id, "aria-describedby": describedby };
|
20
|
+
const errorRef = () => {
|
21
|
+
setErrorRendered(true);
|
22
|
+
};
|
23
|
+
const helperRef = () => {
|
24
|
+
setHelperRendered(true);
|
25
|
+
};
|
26
|
+
return (_jsx(WrapperTagName, { children: _jsx(Provider, { value: { required, hasError, errorRef, helperRef, attributes, group, disabled, size }, children: children }) }));
|
27
|
+
};
|
28
|
+
export default FormControl;
|
@@ -1,8 +1,11 @@
|
|
1
1
|
import type * as T from "./FormControl.types";
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
/**
|
3
|
+
* Keeping the compound component composition inside a server component to make sure
|
4
|
+
* frameworks like Next.js won't require use client to be added on the product side
|
5
|
+
*/
|
6
|
+
declare const FormControl: import("react").ComponentType<T.Props> & {
|
7
|
+
Label: React.ComponentType<T.LabelProps>;
|
8
|
+
Helper: React.ComponentType<T.CaptionProps>;
|
9
|
+
Error: React.ComponentType<T.CaptionProps>;
|
7
10
|
};
|
8
11
|
export default FormControl;
|
@@ -1,65 +1,12 @@
|
|
1
|
-
"
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
const FormControl =
|
10
|
-
const { children, id: passedId, required, hasError, group, disabled, size } = props;
|
11
|
-
const id = useElementId(passedId);
|
12
|
-
const WrapperTagName = group ? "fieldset" : "div";
|
13
|
-
const [helperRendered, setHelperRendered] = React.useState(false);
|
14
|
-
const [errorRendered, setErrorRendered] = React.useState(false);
|
15
|
-
const describedby = [
|
16
|
-
helperRendered && getCaptionId(id),
|
17
|
-
errorRendered && getCaptionId(id, "error"),
|
18
|
-
]
|
19
|
-
.filter(Boolean)
|
20
|
-
.join(" ");
|
21
|
-
const attributes = { id, "aria-describedby": describedby };
|
22
|
-
const errorRef = () => {
|
23
|
-
setErrorRendered(true);
|
24
|
-
};
|
25
|
-
const helperRef = () => {
|
26
|
-
setHelperRendered(true);
|
27
|
-
};
|
28
|
-
return (_jsx(WrapperTagName, { children: _jsx(Provider, { value: { required, hasError, errorRef, helperRef, attributes, group, disabled, size }, children: children }) }));
|
29
|
-
};
|
30
|
-
const FormControlLabel = (props) => {
|
31
|
-
const { children } = props;
|
32
|
-
const { attributes, required, group, disabled, size } = useFormControlPrivate();
|
33
|
-
const id = `${attributes.id}-label`;
|
34
|
-
const tagProps = group
|
35
|
-
? { as: "legend", attributes: { id } }
|
36
|
-
: {
|
37
|
-
as: "label",
|
38
|
-
attributes: { id, htmlFor: attributes.id },
|
39
|
-
};
|
40
|
-
return (_jsxs(Text, Object.assign({}, tagProps, { variant: size === "large" ? "body-2" : "body-3", weight: "medium", className: s.label, color: disabled ? "disabled" : undefined, children: [children, required && (_jsx(Text, { color: disabled ? "disabled" : "critical", as: "span", children: "*" }))] })));
|
41
|
-
};
|
42
|
-
/* Private component */
|
43
|
-
const FormControlCaption = (props) => {
|
44
|
-
const { children, variant, disabled } = props;
|
45
|
-
const { attributes, size, helperRef, errorRef } = useFormControlPrivate();
|
46
|
-
const id = getCaptionId(attributes.id, variant);
|
47
|
-
const color = variant === "error" ? "critical" : "neutral-faded";
|
48
|
-
const ref = variant === "error" ? errorRef : helperRef;
|
49
|
-
return (_jsx(Text, { as: "span", variant: size === "large" ? "body-3" : "caption-1", color: disabled && !variant ? "disabled" : color, attributes: { id, role: color ? "alert" : undefined, ref }, className: s.caption, children: children }));
|
50
|
-
};
|
51
|
-
const FormControlHelper = (props) => {
|
52
|
-
const { children } = props;
|
53
|
-
const { disabled } = useFormControlPrivate();
|
54
|
-
return _jsx(FormControlCaption, { disabled: disabled, children: children });
|
55
|
-
};
|
56
|
-
const FormControlError = (props) => {
|
57
|
-
const { children } = props;
|
58
|
-
const { hasError } = useFormControlPrivate();
|
59
|
-
if (!hasError)
|
60
|
-
return null;
|
61
|
-
return _jsx(FormControlCaption, { variant: "error", children: children });
|
62
|
-
};
|
1
|
+
import FormControlClient from "./FormControl.client.js";
|
2
|
+
import FormControlLabel from "./FormControlLabel.js";
|
3
|
+
import FormControlError from "./FormControlError.js";
|
4
|
+
import FormControlHelper from "./FormControlHelper.js";
|
5
|
+
/**
|
6
|
+
* Keeping the compound component composition inside a server component to make sure
|
7
|
+
* frameworks like Next.js won't require use client to be added on the product side
|
8
|
+
*/
|
9
|
+
const FormControl = FormControlClient;
|
63
10
|
FormControl.Label = FormControlLabel;
|
64
11
|
FormControl.Helper = FormControlHelper;
|
65
12
|
FormControl.Error = FormControlError;
|
@@ -0,0 +1 @@
|
|
1
|
+
export const getCaptionId = (id, variant) => `${id}-${variant || "caption"}`;
|
@@ -0,0 +1,15 @@
|
|
1
|
+
"use client";
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
3
|
+
import Text from "../Text/index.js";
|
4
|
+
import { useFormControlPrivate } from "./FormControl.context.js";
|
5
|
+
import { getCaptionId } from "./FormControl.utilities.js";
|
6
|
+
import s from "./FormControl.module.css";
|
7
|
+
const FormControlCaption = (props) => {
|
8
|
+
const { children, variant, disabled } = props;
|
9
|
+
const { attributes, size, helperRef, errorRef } = useFormControlPrivate();
|
10
|
+
const id = getCaptionId(attributes.id, variant);
|
11
|
+
const color = variant === "error" ? "critical" : "neutral-faded";
|
12
|
+
const ref = variant === "error" ? errorRef : helperRef;
|
13
|
+
return (_jsx(Text, { as: "span", variant: size === "large" ? "body-3" : "caption-1", color: disabled && !variant ? "disabled" : color, attributes: { id, role: color ? "alert" : undefined, ref }, className: s.caption, children: children }));
|
14
|
+
};
|
15
|
+
export default FormControlCaption;
|
@@ -0,0 +1,12 @@
|
|
1
|
+
"use client";
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
3
|
+
import { useFormControlPrivate } from "./FormControl.context.js";
|
4
|
+
import FormControlCaption from "./FormControlCaption.js";
|
5
|
+
const FormControlError = (props) => {
|
6
|
+
const { children } = props;
|
7
|
+
const { hasError } = useFormControlPrivate();
|
8
|
+
if (!hasError)
|
9
|
+
return null;
|
10
|
+
return _jsx(FormControlCaption, { variant: "error", children: children });
|
11
|
+
};
|
12
|
+
export default FormControlError;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
"use client";
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
3
|
+
import { useFormControlPrivate } from "./FormControl.context.js";
|
4
|
+
import FormControlCaption from "./FormControlCaption.js";
|
5
|
+
const FormControlHelper = (props) => {
|
6
|
+
const { children } = props;
|
7
|
+
const { disabled } = useFormControlPrivate();
|
8
|
+
return _jsx(FormControlCaption, { disabled: disabled, children: children });
|
9
|
+
};
|
10
|
+
export default FormControlHelper;
|
@@ -0,0 +1,18 @@
|
|
1
|
+
"use client";
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
3
|
+
import { useFormControlPrivate } from "./FormControl.context.js";
|
4
|
+
import Text from "../Text/index.js";
|
5
|
+
import s from "./FormControl.module.css";
|
6
|
+
const FormControlLabel = (props) => {
|
7
|
+
const { children } = props;
|
8
|
+
const { attributes, required, group, disabled, size } = useFormControlPrivate();
|
9
|
+
const id = `${attributes.id}-label`;
|
10
|
+
const tagProps = group
|
11
|
+
? { as: "legend", attributes: { id } }
|
12
|
+
: {
|
13
|
+
as: "label",
|
14
|
+
attributes: { id, htmlFor: attributes.id },
|
15
|
+
};
|
16
|
+
return (_jsxs(Text, Object.assign({}, tagProps, { variant: size === "large" ? "body-2" : "body-3", weight: "medium", className: s.label, color: disabled ? "disabled" : undefined, children: [children, required && (_jsx(Text, { color: disabled ? "disabled" : "critical", as: "span", children: "*" }))] })));
|
17
|
+
};
|
18
|
+
export default FormControlLabel;
|
@@ -1,10 +1,9 @@
|
|
1
1
|
declare const _default: {
|
2
2
|
title: string;
|
3
|
-
component: {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
Error: (props: import("../FormControl.types").CaptionProps) => import("react").JSX.Element | null;
|
3
|
+
component: import("react").ComponentType<import("./..").FormControlProps> & {
|
4
|
+
Label: import("react").ComponentType<import("../FormControl.types").LabelProps>;
|
5
|
+
Helper: import("react").ComponentType<import("../FormControl.types").CaptionProps>;
|
6
|
+
Error: import("react").ComponentType<import("../FormControl.types").CaptionProps>;
|
8
7
|
};
|
9
8
|
parameters: {
|
10
9
|
iframe: {
|
@@ -7,11 +7,11 @@ import View from "../View/index.js";
|
|
7
7
|
import MenuItemAligner from "./MenuItemAligner.js";
|
8
8
|
import s from "./MenuItem.module.css";
|
9
9
|
const MenuItem = forwardRef((props, ref) => {
|
10
|
-
const { icon, startSlot, endSlot, children, color = "primary", selected, disabled, onClick, href, size = "medium", roundedCorners, className, attributes, } = props;
|
10
|
+
const { icon, startSlot, endSlot, children, color = "primary", selected, disabled, onClick, href, size = "medium", roundedCorners, as, className, attributes, } = props;
|
11
11
|
const rootClassNames = classNames(s.root, className, responsiveClassNames(s, "--size", size), responsiveClassNames(s, "--rounded-corners", roundedCorners), color && s[`--color-${color}`], selected && s["--selected"], disabled && s["--disabled"]);
|
12
12
|
const gapSize = responsivePropDependency(size, (size) => (size === "large" ? 3 : 2));
|
13
13
|
const iconSize = responsivePropDependency(size, (size) => (size === "large" ? 5 : 4));
|
14
|
-
return (_jsx(Actionable, { disabled: disabled, className: rootClassNames, attributes: Object.assign(Object.assign({}, attributes), { "data-rs-aligner-target": true }), onClick: onClick, href: href, ref: ref, children: _jsxs(View, { direction: "row", gap: gapSize, align: "center", children: [icon && _jsx(Icon, { svg: icon, className: s.icon, size: iconSize }), !icon && startSlot, children && (_jsx(View.Item, { grow: true, className: s.content, children: children })), endSlot] }) }));
|
14
|
+
return (_jsx(Actionable, { disabled: disabled, className: rootClassNames, attributes: Object.assign(Object.assign({}, attributes), { "data-rs-aligner-target": true }), onClick: onClick, href: href, ref: ref, as: as, children: _jsxs(View, { direction: "row", gap: gapSize, align: "center", children: [icon && _jsx(Icon, { svg: icon, className: s.icon, size: iconSize }), !icon && startSlot, children && (_jsx(View.Item, { grow: true, className: s.content, children: children })), endSlot] }) }));
|
15
15
|
});
|
16
16
|
MenuItem.Aligner = MenuItemAligner;
|
17
17
|
export default MenuItem;
|
@@ -3,7 +3,7 @@ import type { IconProps } from "../Icon";
|
|
3
3
|
import type { ActionableProps } from "../Actionable";
|
4
4
|
import type * as G from "../../types/global";
|
5
5
|
export type Size = "small" | "medium" | "large";
|
6
|
-
export type Props = Pick<ActionableProps, "attributes" | "className" | "disabled" | "children" | "href" | "onClick"> & {
|
6
|
+
export type Props = Pick<ActionableProps, "attributes" | "className" | "disabled" | "children" | "href" | "onClick" | "as"> & {
|
7
7
|
color?: "neutral" | "critical" | "primary";
|
8
8
|
icon?: IconProps["svg"];
|
9
9
|
startSlot?: React.ReactNode;
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
2
|
+
import PaginationControlled from "./PaginationControlled.js";
|
3
|
+
import PaginationUncontrolled from "./PaginationUncontrolled.js";
|
4
|
+
const Pagination = (props) => {
|
5
|
+
const { page } = props;
|
6
|
+
if (page !== undefined)
|
7
|
+
return _jsx(PaginationControlled, Object.assign({}, props));
|
8
|
+
return _jsx(PaginationUncontrolled, Object.assign({}, props));
|
9
|
+
};
|
10
|
+
export default Pagination;
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import type * as G from "../../types/global";
|
2
|
+
export type BaseProps = {
|
3
|
+
/**
|
4
|
+
* Total number of pages available
|
5
|
+
*/
|
6
|
+
total: number;
|
7
|
+
/**
|
8
|
+
* Event handler triggered when the current page changes
|
9
|
+
*/
|
10
|
+
onChange?: (args: {
|
11
|
+
page: number;
|
12
|
+
}) => void;
|
13
|
+
/**
|
14
|
+
* Function to dynamically get an aria-label for each
|
15
|
+
*/
|
16
|
+
pageAriaLabel?: (args: {
|
17
|
+
page: number;
|
18
|
+
}) => string;
|
19
|
+
/**
|
20
|
+
* aria-label for the previous page button
|
21
|
+
*/
|
22
|
+
previousAriaLabel: string;
|
23
|
+
/**
|
24
|
+
* aria-label for the next page button
|
25
|
+
*/
|
26
|
+
nextAriaLabel: string;
|
27
|
+
/**
|
28
|
+
* Custom root element className
|
29
|
+
*/
|
30
|
+
className?: G.ClassName;
|
31
|
+
/**
|
32
|
+
* Custom root element attributes
|
33
|
+
*/
|
34
|
+
attributes?: G.Attributes<"div", Props>;
|
35
|
+
};
|
36
|
+
export type ControlledProps = BaseProps & {
|
37
|
+
/**
|
38
|
+
* Currently selected page number, starts with 1.
|
39
|
+
* Enables controlled component behavior.
|
40
|
+
*/
|
41
|
+
page: number;
|
42
|
+
defaultPage?: never;
|
43
|
+
};
|
44
|
+
export type UncontrolledProps = BaseProps & {
|
45
|
+
page?: never;
|
46
|
+
/**
|
47
|
+
* Default selected page number, starts with 1.
|
48
|
+
* Enables uncontrolled component behavior.
|
49
|
+
*/
|
50
|
+
defaultPage?: number;
|
51
|
+
};
|
52
|
+
export type Props = ControlledProps | UncontrolledProps;
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,47 @@
|
|
1
|
+
"use client";
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
3
|
+
import Button from "../Button/index.js";
|
4
|
+
import View from "../View/index.js";
|
5
|
+
import IconChevronLeft from "../../icons/ChevronLeft.js";
|
6
|
+
import IconChevronRight from "../../icons/ChevronRight.js";
|
7
|
+
import { range } from "../../utilities/helpers.js";
|
8
|
+
const PaginationControlled = (props) => {
|
9
|
+
const { total, page: selectedPage = 1, onChange, pageAriaLabel, previousAriaLabel, nextAriaLabel, className, attributes, } = props;
|
10
|
+
const selectionRadius = 1;
|
11
|
+
const edgeRadius = 1;
|
12
|
+
const pages = [];
|
13
|
+
const hasHead = selectedPage - selectionRadius > edgeRadius + 2;
|
14
|
+
const hasTail = selectedPage + selectionRadius < total - edgeRadius;
|
15
|
+
/**
|
16
|
+
* Calculate the amount of rendered pages + dots
|
17
|
+
* Removing head or tail also removes their dots
|
18
|
+
*/
|
19
|
+
let count = selectionRadius * 2 + 1;
|
20
|
+
if (!hasHead)
|
21
|
+
count += edgeRadius + 1;
|
22
|
+
if (!hasTail)
|
23
|
+
count += edgeRadius + 1;
|
24
|
+
const selectionStart = hasHead
|
25
|
+
? Math.min(total - count + 1, Math.max(1, selectedPage - selectionRadius))
|
26
|
+
: 1;
|
27
|
+
const selectionEnd = hasTail ? Math.min(selectionStart + count - 1, total) : total;
|
28
|
+
if (hasHead)
|
29
|
+
pages.push(...range(1, edgeRadius), null);
|
30
|
+
pages.push(...range(selectionStart, selectionEnd));
|
31
|
+
if (hasTail)
|
32
|
+
pages.push(null, ...range(total - edgeRadius + 1, total));
|
33
|
+
const changePage = (page) => {
|
34
|
+
const resolvedValue = Math.min(total, Math.max(1, page));
|
35
|
+
onChange === null || onChange === void 0 ? void 0 : onChange({ page: resolvedValue });
|
36
|
+
};
|
37
|
+
return (_jsxs(View, { direction: "row", align: "center", gap: 1, className: className, attributes: attributes, children: [_jsx(Button, { variant: "ghost", size: "small", icon: IconChevronLeft, onClick: () => changePage(selectedPage - 1), disabled: selectedPage === 1, attributes: { "aria-label": previousAriaLabel } }), pages.map((page, index) => {
|
38
|
+
if (page === null) {
|
39
|
+
return (_jsx(View, { width: 7, align: "center", children: "..." }, `dots-${index}`));
|
40
|
+
}
|
41
|
+
return (_jsx(Button, { size: "small", variant: page === selectedPage ? "solid" : "ghost", color: page === selectedPage ? "primary" : "neutral", onClick: () => changePage(page), attributes: {
|
42
|
+
"aria-label": pageAriaLabel === null || pageAriaLabel === void 0 ? void 0 : pageAriaLabel({ page }),
|
43
|
+
"aria-current": page === selectedPage,
|
44
|
+
}, children: page }, index));
|
45
|
+
}), _jsx(Button, { variant: "ghost", size: "small", icon: IconChevronRight, onClick: () => changePage(selectedPage + 1), disabled: selectedPage === total, attributes: { "aria-label": nextAriaLabel } })] }));
|
46
|
+
};
|
47
|
+
export default PaginationControlled;
|
@@ -0,0 +1,25 @@
|
|
1
|
+
"use client";
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
3
|
+
var t = {};
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
5
|
+
t[p] = s[p];
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
9
|
+
t[p[i]] = s[p[i]];
|
10
|
+
}
|
11
|
+
return t;
|
12
|
+
};
|
13
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
14
|
+
import React from "react";
|
15
|
+
import PaginationControlled from "./PaginationControlled.js";
|
16
|
+
const PaginationUncontrolled = (props) => {
|
17
|
+
const { defaultPage = 1, onChange } = props, controlledProps = __rest(props, ["defaultPage", "onChange"]);
|
18
|
+
const [page, setPage] = React.useState(defaultPage || 1);
|
19
|
+
const handleChange = (args) => {
|
20
|
+
setPage(args.page);
|
21
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(args);
|
22
|
+
};
|
23
|
+
return _jsx(PaginationControlled, Object.assign({}, controlledProps, { onChange: handleChange, page: page }));
|
24
|
+
};
|
25
|
+
export default PaginationUncontrolled;
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default } from "./Pagination.js";
|
@@ -0,0 +1,11 @@
|
|
1
|
+
declare const _default: {
|
2
|
+
title: string;
|
3
|
+
component: (props: import("./..").PaginationProps) => import("react").JSX.Element;
|
4
|
+
parameters: {
|
5
|
+
iframe: {
|
6
|
+
url: string;
|
7
|
+
};
|
8
|
+
};
|
9
|
+
};
|
10
|
+
export default _default;
|
11
|
+
export declare const truncate: () => import("react").JSX.Element;
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { Example } from "../../../utilities/storybook/index.js";
|
2
|
+
import Pagination from "../index.js";
|
3
|
+
export default {
|
4
|
+
title: "Components/Pagination",
|
5
|
+
component: Pagination,
|
6
|
+
parameters: {
|
7
|
+
iframe: {
|
8
|
+
url: "https://reshaped.so/docs/components/pagination",
|
9
|
+
},
|
10
|
+
},
|
11
|
+
};
|
12
|
+
export const truncate = () => {
|
13
|
+
return (<Example>
|
14
|
+
<Example.Item title="start">
|
15
|
+
<Pagination total={10} previousAriaLabel="Previous page" nextAriaLabel="Next page" pageAriaLabel={(args) => `Page ${args.page}`}/>
|
16
|
+
</Example.Item>
|
17
|
+
<Example.Item title="middle">
|
18
|
+
<Pagination total={10} defaultPage={5} previousAriaLabel="Previous page" nextAriaLabel="Next page" pageAriaLabel={(args) => `Page ${args.page}`}/>
|
19
|
+
</Example.Item>
|
20
|
+
<Example.Item title="end">
|
21
|
+
<Pagination total={10} defaultPage={10} previousAriaLabel="Previous page" nextAriaLabel="Next page" pageAriaLabel={(args) => `Page ${args.page}`}/>
|
22
|
+
</Example.Item>
|
23
|
+
</Example>);
|
24
|
+
};
|
@@ -5,11 +5,11 @@ import getWidthStyles from "../../styles/width/index.js";
|
|
5
5
|
import getMinWidthStyles from "../../styles/minWidth/index.js";
|
6
6
|
import s from "./Table.module.css";
|
7
7
|
const TableCellPrivate = (props) => {
|
8
|
-
const { minWidth, rowSpan, colSpan, align, tagName: TagName, padding, paddingInline, paddingBlock, children, attributes, } = props;
|
8
|
+
const { minWidth, rowSpan, colSpan, align, verticalAlign, tagName: TagName, padding, paddingInline, paddingBlock, children, attributes, } = props;
|
9
9
|
const width = props.width === "auto" ? "0px" : props.width;
|
10
10
|
const widthStyles = getWidthStyles(width);
|
11
11
|
const minWidthStyles = getMinWidthStyles(minWidth || width);
|
12
|
-
const headingClassNames = classNames(s.cell, widthStyles === null || widthStyles === void 0 ? void 0 : widthStyles.classNames, minWidthStyles === null || minWidthStyles === void 0 ? void 0 : minWidthStyles.classNames, align && s[`cell--align-${align}`]);
|
12
|
+
const headingClassNames = classNames(s.cell, widthStyles === null || widthStyles === void 0 ? void 0 : widthStyles.classNames, minWidthStyles === null || minWidthStyles === void 0 ? void 0 : minWidthStyles.classNames, align && s[`cell--align-${align}`], verticalAlign && s[`cell--valign-${verticalAlign}`]);
|
13
13
|
const headingStyle = Object.assign(Object.assign(Object.assign(Object.assign({}, widthStyles === null || widthStyles === void 0 ? void 0 : widthStyles.variables), minWidthStyles === null || minWidthStyles === void 0 ? void 0 : minWidthStyles.variables), responsiveVariables("--rs-table-p-vertical", paddingBlock !== null && paddingBlock !== void 0 ? paddingBlock : padding)), responsiveVariables("--rs-table-p-horizontal", paddingInline !== null && paddingInline !== void 0 ? paddingInline : padding));
|
14
14
|
return (_jsx(TagName, Object.assign({}, attributes, { className: headingClassNames, rowSpan: rowSpan, colSpan: colSpan, style: headingStyle, children: children })));
|
15
15
|
};
|
@@ -1 +1 @@
|
|
1
|
-
.root{margin:0 calc(var(--rs-unit-x4) * -1);mask-image:linear-gradient(to right,transparent 0,#000 var(--rs-unit-x4),#000 calc(100% - var(--rs-unit-x4)),transparent 100%);overflow:auto;padding:0 var(--rs-unit-x4)}.table{border-collapse:separate;
|
1
|
+
.root{margin:0 calc(var(--rs-unit-x4) * -1);mask-image:linear-gradient(to right,transparent 0,#000 var(--rs-unit-x4),#000 calc(100% - var(--rs-unit-x4)),transparent 100%);overflow:auto;padding:0 var(--rs-unit-x4)}.table{border-collapse:separate;min-width:100%;overflow:hidden}.row{transition:background-color var(--rs-duration-fast) var(--rs-easing-standard)}.cell{--rs-table-p-vertical-s:3;--rs-table-p-horizontal-s:4;padding:calc(var(--rs-unit-x1) * var(--rs-table-p-vertical-s)) calc(var(--rs-unit-x1) * var(--rs-table-p-horizontal-s));text-align:start;vertical-align:top}.cell:not(:last-child){padding-inline-end:0}.row:not(:first-child) .cell{border-top:1px solid var(--rs-color-border-neutral-faded)}.cell--align-start{text-align:start}.cell--align-center{text-align:center}.cell--align-end{text-align:end}.cell--valign-start{vertical-align:top}.cell--valign-center{vertical-align:middle}.cell--valign-end{vertical-align:bottom}.--row-highlighted{background-color:rgba(var(--rs-color-rgb-background-neutral),40%)}.--border-outer .table{border:1px solid var(--rs-color-border-neutral-faded);border-radius:var(--rs-unit-radius-medium)}.--border-column .cell:not(:first-child){border-inline-start:1px solid var(--rs-color-border-neutral-faded)}.--border-column .cell:not(:last-child){padding-inline-end:calc(var(--rs-unit-x1) * var(--rs-table-p-horizontal-s))}
|
@@ -3,6 +3,7 @@ import { Example } from "../../../utilities/storybook/index.js";
|
|
3
3
|
import Table from "../index.js";
|
4
4
|
import Checkbox from "../../Checkbox/index.js";
|
5
5
|
import Card from "../../Card/index.js";
|
6
|
+
import View from "../../View/index.js";
|
6
7
|
export default {
|
7
8
|
title: "Components/Table",
|
8
9
|
component: Table,
|
@@ -54,6 +55,22 @@ export const layout = () => (<Example>
|
|
54
55
|
</Table.Row>
|
55
56
|
</Table>
|
56
57
|
</Example.Item>
|
58
|
+
<Example.Item title="valign: center for cell 2, valign: end for cell 3">
|
59
|
+
<Table>
|
60
|
+
<Table.Row>
|
61
|
+
<Table.Heading>Column 1</Table.Heading>
|
62
|
+
<Table.Heading>Column 2</Table.Heading>
|
63
|
+
<Table.Heading>Column 2</Table.Heading>
|
64
|
+
</Table.Row>
|
65
|
+
<Table.Row>
|
66
|
+
<Table.Cell>
|
67
|
+
<View height={15} backgroundColor="neutral-faded"/>
|
68
|
+
</Table.Cell>
|
69
|
+
<Table.Cell verticalAlign="center">Cell 2</Table.Cell>
|
70
|
+
<Table.Cell verticalAlign="end">Cell 3</Table.Cell>
|
71
|
+
</Table.Row>
|
72
|
+
</Table>
|
73
|
+
</Example.Item>
|
57
74
|
<Example.Item title="width: 40%, minWidth: 200px for col 1">
|
58
75
|
<Table>
|
59
76
|
<Table.Row>
|
package/components/Text/Text.js
CHANGED
@@ -10,14 +10,14 @@ const tagMap = {
|
|
10
10
|
"title-6": "h6",
|
11
11
|
};
|
12
12
|
const Text = (props) => {
|
13
|
-
const { variant, color, weight, align, decoration, maxLines, children, className, attributes } = props;
|
13
|
+
const { variant, color, weight, align, decoration, maxLines, wrap, children, className, attributes, } = props;
|
14
14
|
const largestVariant = typeof variant === "string" ? variant : (variant === null || variant === void 0 ? void 0 : variant.xl) || (variant === null || variant === void 0 ? void 0 : variant.l) || (variant === null || variant === void 0 ? void 0 : variant.m) || (variant === null || variant === void 0 ? void 0 : variant.s);
|
15
15
|
/**
|
16
16
|
* Using any here to let TS save on type resolving, otherwise TS throws an error due to the type complexity
|
17
17
|
* It still resolves the attributes correctly based on the tag
|
18
18
|
*/
|
19
19
|
const TagName = props.as || (largestVariant && tagMap[largestVariant]) || "div";
|
20
|
-
const rootClassName = classNames(s.root, color && s[`--color-${color}`], ...responsiveClassNames(s, "--variant", variant), ...responsiveClassNames(s, "--align", align), weight && s[`--weight-${weight}`], decoration && s[`--decoration-${decoration}`], maxLines !== undefined && s[`--clamp`], maxLines === 1 && s["--break-all"], className);
|
20
|
+
const rootClassName = classNames(s.root, color && s[`--color-${color}`], ...responsiveClassNames(s, "--variant", variant), ...responsiveClassNames(s, "--align", align), weight && s[`--weight-${weight}`], decoration && s[`--decoration-${decoration}`], maxLines !== undefined && s[`--clamp`], maxLines === 1 && s["--break-all"], wrap && s[`--wrap-${wrap}`], className);
|
21
21
|
const style = Object.assign(Object.assign({}, attributes === null || attributes === void 0 ? void 0 : attributes.style), { "--rs-text-lines": maxLines });
|
22
22
|
return (_jsx(TagName, Object.assign({}, attributes, { className: rootClassName, style: style, children: children })));
|
23
23
|
};
|