diff --git a/.changeset/view-inset-center.md b/.changeset/view-inset-center.md index e7230b86..50edf85e 100644 --- a/.changeset/view-inset-center.md +++ b/.changeset/view-inset-center.md @@ -2,4 +2,4 @@ "reshaped": minor --- -View: Added insetInline and insetBlock props with support for the "center" keyword value for centering absolutely positioned elements +View: Added `insetInline` and `insetBlock` props, and a `"center"` keyword value for `inset`, `insetInline` and `insetBlock` to center absolutely positioned elements without manual CSS transforms. `inset="center"` centers on both axes, `insetInline`/`insetBlock` center on a single axis. diff --git a/packages/reshaped/src/components/View/View.types.ts b/packages/reshaped/src/components/View/View.types.ts index bacb475f..74fa03c3 100644 --- a/packages/reshaped/src/components/View/View.types.ts +++ b/packages/reshaped/src/components/View/View.types.ts @@ -101,8 +101,8 @@ export type Props; /** Position style */ position?: G.Responsive; - /** Inset style, base unit token number multiplier when used as a number */ - inset?: G.Responsive; + /** Inset style, base unit token number multiplier when used as a number, "center" centers the element on both axes */ + inset?: G.Responsive; /** Inset start, base unit token number multiplier when used as a number */ insetStart?: G.Responsive; /** Inset end, base unit token number multiplier when used as a number */ diff --git a/packages/reshaped/src/components/View/tests/View.stories.tsx b/packages/reshaped/src/components/View/tests/View.stories.tsx index b834bd35..e1426a27 100644 --- a/packages/reshaped/src/components/View/tests/View.stories.tsx +++ b/packages/reshaped/src/components/View/tests/View.stories.tsx @@ -1066,6 +1066,18 @@ export const inset = { + + + + + + handles 0 value 1`] = ` { + "classNames": [ + "_root_31d553", + [ + "_--inline-unit_31d553", + ], + [ + "_--block-unit_31d553", + ], + ], + "variables": { + "--rs-inset-block-s": 0, + "--rs-inset-inline-s": 0, + }, +} +`; + +exports[`Styles/Inset > handles center value 1`] = ` +{ + "classNames": [ + "_root_31d553", + [ + "_--inline-center_31d553", + ], + [ + "_--block-center_31d553", + ], + ], "variables": { - "--rs-inset-s": 0, + "--rs-inset-block-s": "center", + "--rs-inset-inline-s": "center", }, } `; exports[`Styles/Inset > handles positive value 1`] = ` { + "classNames": [ + "_root_31d553", + [ + "_--inline-unit_31d553", + ], + [ + "_--block-unit_31d553", + ], + ], "variables": { - "--rs-inset-s": 4, + "--rs-inset-block-s": 4, + "--rs-inset-inline-s": 4, + }, +} +`; + +exports[`Styles/Inset > handles responsive center value 1`] = ` +{ + "classNames": [ + "_root_31d553", + [ + "_--inline-center_31d553", + "_--inline-unit--m_31d553", + ], + [ + "_--block-center_31d553", + "_--block-unit--m_31d553", + ], + ], + "variables": { + "--rs-inset-block-m": 4, + "--rs-inset-block-s": "center", + "--rs-inset-inline-m": 4, + "--rs-inset-inline-s": "center", }, } `; exports[`Styles/Inset > handles responsive value 1`] = ` { + "classNames": [ + "_root_31d553", + [ + "_--inline-unit_31d553", + "_--inline-unit--m_31d553", + "_--inline-unit--l_31d553", + ], + [ + "_--block-unit_31d553", + "_--block-unit--m_31d553", + "_--block-unit--l_31d553", + ], + ], "variables": { - "--rs-inset-l": 2, - "--rs-inset-m": 0, - "--rs-inset-s": 4, + "--rs-inset-block-l": 2, + "--rs-inset-block-m": 0, + "--rs-inset-block-s": 4, + "--rs-inset-inline-l": 2, + "--rs-inset-inline-m": 0, + "--rs-inset-inline-s": 4, }, } `; diff --git a/packages/reshaped/src/styles/resolvers/inset/index.test.ts b/packages/reshaped/src/styles/resolvers/inset/index.test.ts index b7269166..d1d27133 100644 --- a/packages/reshaped/src/styles/resolvers/inset/index.test.ts +++ b/packages/reshaped/src/styles/resolvers/inset/index.test.ts @@ -25,6 +25,14 @@ describe("Styles/Inset", () => { test("handles responsive value", async () => { expect(inset({ s: 4, m: 0, l: 2 })).toMatchSnapshot(); }); + + test("handles center value", () => { + expect(inset("center")).toMatchSnapshot(); + }); + + test("handles responsive center value", async () => { + expect(inset({ s: "center", m: 4 })).toMatchSnapshot(); + }); }); describe("Styles/Inset/Top", () => { diff --git a/packages/reshaped/src/styles/resolvers/inset/index.ts b/packages/reshaped/src/styles/resolvers/inset/index.ts index 96632e01..d90a2f1c 100644 --- a/packages/reshaped/src/styles/resolvers/inset/index.ts +++ b/packages/reshaped/src/styles/resolvers/inset/index.ts @@ -3,9 +3,30 @@ import * as T from "@/styles/types"; import s from "./inset.module.css"; import "./inset.css"; -const inset: T.StyleResolver = (value) => { +const inset: T.StyleResolver = (value) => { if (value === undefined) return {}; - return { variables: responsiveVariables("--rs-inset", value) }; + // Insetting all sides is sugar for insetting both axes, which also lets + // `inset="center"` reuse the per-axis centering classes for both directions + const inlineClassNames = responsiveClassNames( + s, + (value) => (value === "center" ? "--inline-center" : "--inline-unit"), + value, + { excludeValueFromClassName: true } + ); + const blockClassNames = responsiveClassNames( + s, + (value) => (value === "center" ? "--block-center" : "--block-unit"), + value, + { excludeValueFromClassName: true } + ); + + return { + classNames: [s.root, inlineClassNames, blockClassNames], + variables: { + ...responsiveVariables("--rs-inset-inline", value), + ...responsiveVariables("--rs-inset-block", value), + }, + }; }; export const insetTop: T.StyleResolver = (value) => { diff --git a/packages/reshaped/src/styles/resolvers/inset/inset.css b/packages/reshaped/src/styles/resolvers/inset/inset.css index 896a5e3f..a101c760 100644 --- a/packages/reshaped/src/styles/resolvers/inset/inset.css +++ b/packages/reshaped/src/styles/resolvers/inset/inset.css @@ -1,9 +1,3 @@ -@responsive [style*="--rs-inset-s:"] { - @variable --rs-inset 0; - - inset: calc(var(--rs-inset) * var(--rs-unit-x1)); -} - @responsive [style*="--rs-inset-end-"] { @variable --rs-inset-end 0; diff --git a/packages/reshaped/src/styles/types.ts b/packages/reshaped/src/styles/types.ts index 133e92c4..d30c3ea2 100644 --- a/packages/reshaped/src/styles/types.ts +++ b/packages/reshaped/src/styles/types.ts @@ -90,7 +90,7 @@ export type Mixin = { position?: G.Responsive; zIndex?: ZIndex; - inset?: G.Responsive; + inset?: G.Responsive; insetTop?: G.Responsive; insetBottom?: G.Responsive; insetStart?: G.Responsive;