Skip to content

Commit

Permalink
Specify rotation axis using a modifier
Browse files Browse the repository at this point in the history
Support single rotation angles in line with the [CSS `rotate` property](https://developer.mozilla.org/en-US/docs/Web/CSS/rotate). Using modifiers (e.g. `rotate-45/x`) makes it clearer that the axis of rotation is modified. Thanks @adamwathan for this suggestion.

Composing angles is only supported in CSS via a pipeline of `transform` functions. I'll add arbitrary value support to `transform` next as an escape hatch for those cases that need more complex transformations.
  • Loading branch information
KrisBraun committed Mar 18, 2024
1 parent d9d7df1 commit 2e302b1
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 335 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1269,9 +1269,6 @@ exports[`getClassList 1`] = `
"rotate-45",
"rotate-6",
"rotate-90",
"rotate-x",
"rotate-y",
"rotate-z",
"rounded-b-full",
"rounded-b-none",
"rounded-bl-full",
Expand Down
320 changes: 17 additions & 303 deletions packages/tailwindcss/src/utilities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2549,330 +2549,44 @@ test('translate-y', () => {
})

test('rotate', () => {
expect(run(['rotate-45', '-rotate-45', 'rotate-[123deg]'])).toMatchInlineSnapshot(`
expect(run(['rotate-45', '-rotate-45', 'rotate-[123deg]', 'rotate-[0.3_0.7_1_45deg]']))
.toMatchInlineSnapshot(`
".-rotate-45 {
--tw-rotate: calc(45deg * -1);
rotate: -45deg;
}
.rotate-45 {
--tw-rotate: 45deg;
rotate: 45deg;
}
.rotate-\\[123deg\\] {
--tw-rotate: 123deg;
rotate: 123deg;
}
@property --tw-rotate {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --tw-rotate-x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-y {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-z {
syntax: "<number>";
inherits: false;
initial-value: 0;
}"
`)
expect(run(['rotate-45', 'rotate-[0.3_0.7_1]'])).toMatchInlineSnapshot(`
".rotate-45 {
--tw-rotate: 45deg;
rotate: 45deg;
}
.rotate-\\[0\\.3_0\\.7_1\\] {
rotate: .3 .7 1 var(--tw-rotate);
}
@property --tw-rotate {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --tw-rotate-x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-y {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-z {
syntax: "<number>";
inherits: false;
initial-value: 0;
}"
`)
expect(run(['rotate-[0.3_0.7_1_45deg]'])).toMatchInlineSnapshot(`
".rotate-\\[0\\.3_0\\.7_1_45deg\\] {
.rotate-\\[0\\.3_0\\.7_1_45deg\\] {
rotate: .3 .7 1 45deg;
}"
`)
expect(run(['rotate', 'rotate-unknown'])).toEqual('')
})

test('rotate-x', () => {
expect(run(['rotate-45', 'rotate-x'])).toMatchInlineSnapshot(`
".rotate-45 {
--tw-rotate: 45deg;
rotate: 45deg;
}
.rotate-x {
--tw-rotate-x: 1;
rotate: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-rotate);
}
@property --tw-rotate {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --tw-rotate-x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-y {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-z {
syntax: "<number>";
inherits: false;
initial-value: 0;
}"
`)
expect(run(['rotate-45', 'rotate-x', 'rotate-y'])).toMatchInlineSnapshot(`
".rotate-45 {
--tw-rotate: 45deg;
rotate: 45deg;
}
.rotate-x {
--tw-rotate-x: 1;
rotate: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-rotate);
}
.rotate-y {
--tw-rotate-y: 1;
rotate: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-rotate);
}
@property --tw-rotate {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --tw-rotate-x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-y {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-z {
syntax: "<number>";
inherits: false;
initial-value: 0;
}"
`)
expect(run(['rotate-x'])).toMatchInlineSnapshot(`
".rotate-x {
--tw-rotate-x: 1;
rotate: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-rotate);
}
@property --tw-rotate {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --tw-rotate-x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-y {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-z {
syntax: "<number>";
inherits: false;
initial-value: 0;
}"
`)
})

test('rotate-y', () => {
expect(run(['rotate-45', 'rotate-y'])).toMatchInlineSnapshot(`
".rotate-45 {
--tw-rotate: 45deg;
rotate: 45deg;
}
.rotate-y {
--tw-rotate-y: 1;
rotate: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-rotate);
}
@property --tw-rotate {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --tw-rotate-x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-y {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-z {
syntax: "<number>";
inherits: false;
initial-value: 0;
}"
`)
expect(run(['rotate-y'])).toMatchInlineSnapshot(`
".rotate-y {
--tw-rotate-y: 1;
rotate: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-rotate);
}
@property --tw-rotate {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --tw-rotate-x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-y {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-z {
syntax: "<number>";
inherits: false;
initial-value: 0;
}"
`)
})

test('rotate-z', () => {
expect(run(['rotate-45', 'rotate-z'])).toMatchInlineSnapshot(`
".rotate-45 {
--tw-rotate: 45deg;
rotate: 45deg;
}
.rotate-z {
--tw-rotate-z: 1;
rotate: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-rotate);
}
@property --tw-rotate {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --tw-rotate-x {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-y {
syntax: "<number>";
inherits: false;
initial-value: 0;
}
@property --tw-rotate-z {
syntax: "<number>";
inherits: false;
initial-value: 0;
.rotate-\\[123deg\\] {
rotate: 123deg;
}"
`)
expect(run(['rotate-z'])).toMatchInlineSnapshot(`
".rotate-z {
--tw-rotate-z: 1;
rotate: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-rotate);
}
@property --tw-rotate {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
expect(
run(['rotate-45/x', 'rotate-45/y', 'rotate-45/[1_2_3]', 'rotate-[123deg]/[0.3_0.7_1]']),
).toMatchInlineSnapshot(`
".rotate-45\\/\\[1_2_3\\] {
rotate: 1 2 3 45deg;
}
@property --tw-rotate-x {
syntax: "<number>";
inherits: false;
initial-value: 0;
.rotate-45\\/x {
rotate: x 45deg;
}
@property --tw-rotate-y {
syntax: "<number>";
inherits: false;
initial-value: 0;
.rotate-45\\/y {
rotate: y 45deg;
}
@property --tw-rotate-z {
syntax: "<number>";
inherits: false;
initial-value: 0;
.rotate-\\[123deg\\]\\/\\[0\\.3_0\\.7_1\\] {
rotate: .3 .7 1 123deg;
}"
`)
expect(run(['rotate', 'rotate-x', 'rotate-y', 'rotate-z', 'rotate-unknown'])).toEqual('')
})

test('skew', () => {
Expand Down
Loading

0 comments on commit 2e302b1

Please sign in to comment.