Skip to content

Commit 4156893

Browse files
authored
feat: add object-fit & object-position (#117)
1 parent 781ec13 commit 4156893

File tree

5 files changed

+127
-30
lines changed

5 files changed

+127
-30
lines changed

src/__tests__/vendor/tailwind/_tailwind.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { PropsWithChildren, ReactElement } from "react";
22

3+
import { inspect } from "node:util";
4+
35
import tailwind from "@tailwindcss/postcss";
46
import {
57
screen,
@@ -30,7 +32,7 @@ export type NativewindRenderOptions = RenderOptions & {
3032
/** Whether to include the plugin in the generated CSS. @default true */
3133
plugin?: boolean;
3234
/** Enable debug logging. @default false - Set process.env.NATIVEWIND_TEST_AUTO_DEBUG and run tests with the node inspector */
33-
debug?: boolean;
35+
debug?: boolean | "verbose";
3436
};
3537

3638
const debugDefault = Boolean(process.env.NODE_OPTIONS?.includes("--inspect"));
@@ -69,7 +71,7 @@ export async function render(
6971
css += `\n${extraCss}`;
7072
}
7173

72-
if (debug) {
74+
if (debug === "verbose") {
7375
console.log(`Input CSS:\n---\n${css}\n---\n`);
7476
}
7577

@@ -87,6 +89,16 @@ export async function render(
8789

8890
const compiled = registerCSS(output, { debug: false });
8991

92+
if (debug) {
93+
console.log(
94+
inspect(compiled.stylesheet(), {
95+
colors: true,
96+
compact: false,
97+
depth: null,
98+
}),
99+
);
100+
}
101+
90102
return Object.assign(
91103
{},
92104
tlRender(component, {

src/__tests__/vendor/tailwind/layout.test.tsx

Lines changed: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -393,89 +393,117 @@ describe("Layout - Isolation", () => {
393393
describe("Layout - Object Fit", () => {
394394
test("object-contain", async () => {
395395
expect(await renderCurrentTest()).toStrictEqual({
396-
props: {},
397-
warnings: { properties: ["object-fit"] },
396+
props: {
397+
contentFit: "contain",
398+
style: {},
399+
},
398400
});
399401
});
400402
test("object-cover", async () => {
401403
expect(await renderCurrentTest()).toStrictEqual({
402-
props: {},
403-
warnings: { properties: ["object-fit"] },
404+
props: {
405+
contentFit: "cover",
406+
style: {},
407+
},
404408
});
405409
});
406410
test("object-fill", async () => {
407411
expect(await renderCurrentTest()).toStrictEqual({
408-
props: {},
409-
warnings: { properties: ["object-fit"] },
412+
props: {
413+
contentFit: "fill",
414+
style: {},
415+
},
410416
});
411417
});
412418
test("object-none", async () => {
413419
expect(await renderCurrentTest()).toStrictEqual({
414-
props: {},
415-
warnings: { properties: ["object-fit"] },
420+
props: {
421+
contentFit: "none",
422+
style: {},
423+
},
416424
});
417425
});
418426
test("object-scale-down", async () => {
419427
expect(await renderCurrentTest()).toStrictEqual({
420-
props: {},
421-
warnings: { properties: ["object-fit"] },
428+
props: {
429+
contentFit: "scale-down",
430+
style: {},
431+
},
422432
});
423433
});
424434
});
425435

426436
describe("Layout - Object Position", () => {
427437
test("object-bottom", async () => {
428438
expect(await renderCurrentTest()).toStrictEqual({
429-
props: {},
430-
warnings: { properties: ["object-position"] },
439+
props: {
440+
contentPosition: "bottom",
441+
style: {},
442+
},
431443
});
432444
});
433445
test("object-center", async () => {
434446
expect(await renderCurrentTest()).toStrictEqual({
435-
props: {},
436-
warnings: { properties: ["object-position"] },
447+
props: {
448+
contentPosition: "center",
449+
style: {},
450+
},
437451
});
438452
});
439453
test("object-left", async () => {
440454
expect(await renderCurrentTest()).toStrictEqual({
441-
props: {},
442-
warnings: { properties: ["object-position"] },
455+
props: {
456+
contentPosition: "left",
457+
style: {},
458+
},
443459
});
444460
});
445461
test("object-left-bottom", async () => {
446462
expect(await renderCurrentTest()).toStrictEqual({
447-
props: {},
448-
warnings: { properties: ["object-position"] },
463+
props: {
464+
contentPosition: "left bottom",
465+
style: {},
466+
},
449467
});
450468
});
451469
test("object-left-top", async () => {
452470
expect(await renderCurrentTest()).toStrictEqual({
453-
props: {},
454-
warnings: { properties: ["object-position"] },
471+
props: {
472+
contentPosition: "left top",
473+
style: {},
474+
},
455475
});
456476
});
457477
test("object-right", async () => {
458478
expect(await renderCurrentTest()).toStrictEqual({
459-
props: {},
460-
warnings: { properties: ["object-position"] },
479+
props: {
480+
contentPosition: "right",
481+
style: {},
482+
},
461483
});
462484
});
463485
test("object-right-bottom", async () => {
464486
expect(await renderCurrentTest()).toStrictEqual({
465-
props: {},
466-
warnings: { properties: ["object-position"] },
487+
props: {
488+
contentPosition: "right bottom",
489+
style: {},
490+
},
467491
});
468492
});
469493
test("object-right-top", async () => {
470494
expect(await renderCurrentTest()).toStrictEqual({
471-
props: {},
472-
warnings: { properties: ["object-position"] },
495+
props: {
496+
contentPosition: "right top",
497+
style: {},
498+
},
473499
});
474500
});
475501
test("object-top", async () => {
476502
expect(await renderCurrentTest()).toStrictEqual({
477-
props: {},
478-
warnings: { properties: ["object-position"] },
503+
props: {
504+
contentPosition: "top",
505+
style: {},
506+
},
479507
});
480508
});
481509
});

src/compiler/declarations.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
BorderStyle,
88
ColorOrAuto,
99
CssColor,
10+
CustomProperty,
1011
Declaration,
1112
DimensionPercentageFor_LengthValue,
1213
EnvironmentVariable,
@@ -975,6 +976,12 @@ export function parseCustomDeclaration(
975976
parseUnparsed(declaration.value.value, builder, property) ===
976977
"borderless",
977978
);
979+
} else if (property === "object-fit") {
980+
// https://github.com/parcel-bundler/lightningcss/issues/1046
981+
parseObjectFit(declaration.value, builder);
982+
} else if (property === "object-position") {
983+
// https://github.com/parcel-bundler/lightningcss/issues/1047
984+
parseObjectPosition(declaration.value, builder);
978985
} else if (
979986
validProperties.has(property) ||
980987
property.startsWith("--") ||
@@ -2997,6 +3004,33 @@ function parseGradientItem(
29973004
}
29983005
}
29993006

3007+
function parseObjectFit(
3008+
declaration: CustomProperty,
3009+
builder: StylesheetBuilder,
3010+
) {
3011+
builder.addMapping({
3012+
"object-fit": "contentFit",
3013+
});
3014+
builder.addDescriptor(
3015+
"object-fit",
3016+
parseUnparsed(declaration.value, builder, "object-fit"),
3017+
);
3018+
}
3019+
3020+
function parseObjectPosition(
3021+
declaration: CustomProperty,
3022+
builder: StylesheetBuilder,
3023+
) {
3024+
builder.addMapping({
3025+
"object-position": "contentPosition",
3026+
});
3027+
builder.addDescriptor("object-position", [
3028+
{},
3029+
"join",
3030+
[parseUnparsed(declaration.value, builder, "object-position"), " "],
3031+
]);
3032+
}
3033+
30003034
function parseVisibility(
30013035
declaration: DeclarationType<"visibility">,
30023036
builder: StylesheetBuilder,

src/runtime/native/styles/functions/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export * from "./animation-timing";
22
export * from "./calc";
33
export * from "./filters";
44
export * from "./platform-functions";
5+
export * from "./string-functions";
56
export * from "./transform-functions";
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { StyleFunctionResolver } from "../resolve";
2+
3+
export const join: StyleFunctionResolver = (resolveValue, value) => {
4+
const args = resolveValue(value[2]);
5+
6+
if (!Array.isArray(args)) {
7+
return args;
8+
}
9+
10+
const array: unknown = args[0];
11+
const separator: unknown = args[1] ?? ",";
12+
13+
if (!Array.isArray(array)) {
14+
return array;
15+
}
16+
17+
if (!separator || typeof separator !== "string") {
18+
return array.join();
19+
}
20+
21+
return array.join(separator);
22+
};

0 commit comments

Comments
 (0)