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.
Files changed (62) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bundle.css +1 -1
  3. package/bundle.d.ts +2 -0
  4. package/bundle.js +10 -10
  5. package/cli/theming/index.js +2 -0
  6. package/components/Accordion/AccordionContent.js +1 -0
  7. package/components/Button/Button.js +2 -2
  8. package/components/Button/Button.types.d.ts +1 -1
  9. package/components/FormControl/FormControl.client.d.ts +3 -0
  10. package/components/FormControl/FormControl.client.js +28 -0
  11. package/components/FormControl/FormControl.d.ts +8 -5
  12. package/components/FormControl/FormControl.js +9 -62
  13. package/components/FormControl/FormControl.utilities.d.ts +2 -0
  14. package/components/FormControl/FormControl.utilities.js +1 -0
  15. package/components/FormControl/FormControlCaption.d.ts +3 -0
  16. package/components/FormControl/FormControlCaption.js +15 -0
  17. package/components/FormControl/FormControlError.d.ts +3 -0
  18. package/components/FormControl/FormControlError.js +12 -0
  19. package/components/FormControl/FormControlHelper.d.ts +3 -0
  20. package/components/FormControl/FormControlHelper.js +10 -0
  21. package/components/FormControl/FormControlLabel.d.ts +3 -0
  22. package/components/FormControl/FormControlLabel.js +18 -0
  23. package/components/FormControl/tests/FormControl.stories.d.ts +4 -5
  24. package/components/MenuItem/MenuItem.js +2 -2
  25. package/components/MenuItem/MenuItem.types.d.ts +1 -1
  26. package/components/Pagination/Pagination.d.ts +3 -0
  27. package/components/Pagination/Pagination.js +10 -0
  28. package/components/Pagination/Pagination.types.d.ts +52 -0
  29. package/components/Pagination/Pagination.types.js +1 -0
  30. package/components/Pagination/PaginationControlled.d.ts +3 -0
  31. package/components/Pagination/PaginationControlled.js +47 -0
  32. package/components/Pagination/PaginationUncontrolled.d.ts +3 -0
  33. package/components/Pagination/PaginationUncontrolled.js +25 -0
  34. package/components/Pagination/index.d.ts +2 -0
  35. package/components/Pagination/index.js +1 -0
  36. package/components/Pagination/tests/Pagination.stories.d.ts +11 -0
  37. package/components/Pagination/tests/Pagination.stories.js +24 -0
  38. package/components/Table/Table.js +2 -2
  39. package/components/Table/Table.module.css +1 -1
  40. package/components/Table/Table.types.d.ts +1 -0
  41. package/components/Table/tests/Table.stories.js +17 -0
  42. package/components/Text/Text.js +2 -2
  43. package/components/Text/Text.module.css +1 -1
  44. package/components/Text/Text.types.d.ts +1 -0
  45. package/components/Text/tests/Text.stories.d.ts +1 -0
  46. package/components/Text/tests/Text.stories.js +7 -0
  47. package/components/TextArea/TextArea.js +15 -6
  48. package/components/TextArea/TextArea.module.css +1 -1
  49. package/components/TextArea/TextArea.types.d.ts +1 -0
  50. package/components/TextArea/tests/TextArea.stories.d.ts +1 -0
  51. package/components/TextArea/tests/TextArea.stories.js +8 -0
  52. package/components/_private/Expandable/Expandable.js +7 -28
  53. package/components/_private/Expandable/Expandable.module.css +1 -1
  54. package/index.d.ts +2 -0
  55. package/index.js +1 -0
  56. package/package.json +30 -30
  57. package/themes/figma/media.css +1 -1
  58. package/themes/reshaped/media.css +1 -1
  59. package/themes/reshaped/theme.css +1 -1
  60. package/themes/slate/media.css +1 -1
  61. package/utilities/helpers.d.ts +1 -0
  62. package/utilities/helpers.js +5 -0
@@ -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" : ""}`;
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  import { jsx as _jsx } from "react/jsx-runtime";
2
3
  import React from "react";
3
4
  import Expandable from "../_private/Expandable/index.js";
@@ -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", className, children, rounded, attributes, onClick, icon, endIcon, } = props;
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,3 @@
1
+ import type * as T from "./FormControl.types";
2
+ declare const FormControl: (props: T.Props) => import("react/jsx-runtime").JSX.Element;
3
+ export default FormControl;
@@ -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
- declare const FormControl: {
3
- (props: T.Props): import("react/jsx-runtime").JSX.Element;
4
- Label: (props: T.LabelProps) => import("react/jsx-runtime").JSX.Element;
5
- Helper: (props: T.CaptionProps) => import("react/jsx-runtime").JSX.Element;
6
- Error: (props: T.CaptionProps) => import("react/jsx-runtime").JSX.Element | null;
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
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import React from "react";
4
- import useElementId from "../../hooks/useElementId.js";
5
- import Text from "../Text/index.js";
6
- import { Provider, useFormControlPrivate } from "./FormControl.context.js";
7
- import s from "./FormControl.module.css";
8
- const getCaptionId = (id, variant) => `${id}-${variant || "caption"}`;
9
- const FormControl = (props) => {
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,2 @@
1
+ import type * as T from "./FormControl.types";
2
+ export declare const getCaptionId: (id: string, variant?: T.PrivateCaptionProps["variant"]) => string;
@@ -0,0 +1 @@
1
+ export const getCaptionId = (id, variant) => `${id}-${variant || "caption"}`;
@@ -0,0 +1,3 @@
1
+ import type * as T from "./FormControl.types";
2
+ declare const FormControlCaption: (props: T.PrivateCaptionProps) => import("react/jsx-runtime").JSX.Element;
3
+ export default FormControlCaption;
@@ -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,3 @@
1
+ import type * as T from "./FormControl.types";
2
+ declare const FormControlError: (props: T.CaptionProps) => import("react/jsx-runtime").JSX.Element | null;
3
+ export default FormControlError;
@@ -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,3 @@
1
+ import type * as T from "./FormControl.types";
2
+ declare const FormControlHelper: (props: T.CaptionProps) => import("react/jsx-runtime").JSX.Element;
3
+ export default FormControlHelper;
@@ -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,3 @@
1
+ import type * as T from "./FormControl.types";
2
+ declare const FormControlLabel: (props: T.LabelProps) => import("react/jsx-runtime").JSX.Element;
3
+ export default FormControlLabel;
@@ -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
- (props: import("./..").FormControlProps): import("react").JSX.Element;
5
- Label: (props: import("../FormControl.types").LabelProps) => import("react").JSX.Element;
6
- Helper: (props: import("../FormControl.types").CaptionProps) => import("react").JSX.Element;
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,3 @@
1
+ import * as T from "./Pagination.types";
2
+ declare const Pagination: (props: T.Props) => import("react/jsx-runtime").JSX.Element;
3
+ export default Pagination;
@@ -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,3 @@
1
+ import type * as T from "./Pagination.types";
2
+ declare const PaginationControlled: (props: T.ControlledProps) => import("react/jsx-runtime").JSX.Element;
3
+ export default PaginationControlled;
@@ -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,3 @@
1
+ import * as T from "./Pagination.types";
2
+ declare const PaginationUncontrolled: (props: T.UncontrolledProps) => import("react/jsx-runtime").JSX.Element;
3
+ export default PaginationUncontrolled;
@@ -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,2 @@
1
+ export { default } from "./Pagination";
2
+ export type { Props as PaginationProps } from "./Pagination.types";
@@ -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;border-radius:var(--rs-unit-radius-medium);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:first-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}.--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-column .cell:not(:first-child){border-inline-start:1px solid var(--rs-color-border-neutral-faded)}.--border-column .cell:first-child{padding-inline-end:calc(var(--rs-unit-x1) * var(--rs-table-p-horizontal-s))}
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))}
@@ -14,6 +14,7 @@ export type RowProps = {
14
14
  };
15
15
  export type CellProps = {
16
16
  align?: "start" | "center" | "end";
17
+ verticalAlign?: "start" | "center" | "end";
17
18
  rowSpan?: number;
18
19
  colSpan?: number;
19
20
  padding?: number;
@@ -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>
@@ -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
  };