Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -441,3 +441,62 @@ Methods:
* [translate(x: string | number, y?: string | number)](./docs/transform.md#translate-x-string-number-y-string-number-)
* [skew(x: string | number, y?: string | number)](./docs/transform.md#skew-x-string-number-y-string-number-)
* [transform(value: string)](./docs/transform.md#transform-value-string-)

## [CSS]()

Method for injecting arbitrary Stitches CSS into the current chain.
Use this when you need a style that isn’t (yet) covered by the first-class chain methods,
or when you want to author nested selectors and media queries inline.

```typescript

import { Frame } from "tile-css";

const Hello = Frame()
.size(300)
.fg("white")
.mono(21, { color: "#000" })
.css({
border: "1px solid #000",
boxShadow: "0 10px 24px rgba(0,0,0,.18)",
textAlign: "center",
})
.css({
"@media (max-width: 480px)": {
width: 240,
height: 240,
fontSize: 14,
},
})
.element();

function App() {
return <Hello>Hello world :)</Hello>;
}

export { App }
```

## [Additional]()

if you chain a method that isn’t provided by a built-in module, it’s treated as a **CSS property** (camelCased) or a
**Stitches util** key and merged into the style tree. This lets you use one-off properties without writing a new module.

```typescript

import { View } from "tile-css";

const Avatar = View("img")
.size(200)
.border("1px solid #000")
.round(12)
.objectFit('fill') // This doesn't exist in the first-class chain methods
.objectPosition('20% 20%') // This doesn't exist in the first-class chain methods
.element();

function App() {
return <Avatar src="https://picsum.photos/100/100" alt="avatar" />
}

export { App }
```
42 changes: 35 additions & 7 deletions lib/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ export function createChain(
const variants: VariantCSS = { ...startingValues?.variants };
const children: Record<string, CSS | Chain> = { ...startingValues?.children };

let self: Chain;

const chain: Chain = {
extend: (newElementTag?: Tag) => {
return createChain(stitches, newElementTag || elementTag, {
Expand All @@ -80,7 +82,7 @@ export function createChain(
// @ts-ignore
select: (selector: string, subchain: CSS | Chain) => {
children[selector] = subchain;
return chain;
return self;
},
// In your element method:
element: (rawCSS?: CSS) => {
Expand Down Expand Up @@ -112,23 +114,49 @@ export function createChain(
},
];
}

return chain;
return self;
},

css: (rawCSS: CSS) => {
update(rawCSS);
return chain;
return self;
},
};

modules.forEach((m) => m.register(addMethod));

return chain;
const proxy = new Proxy(chain as Chain, {
get(target, propKey, receiver) {
// Default implemented methods
if (propKey in target) {
return Reflect.get(target, propKey, receiver);
}

if (typeof propKey !== "string") {
return undefined;
}

return (...args: any[]) => {
if (!args.length) {
return receiver;
}

// Fallback to style property update with given key-value pairs.
update({ [propKey]: args[0] });

return receiver;
};
},
});

self = proxy as Chain;

return proxy as Chain;

function addMethod(name: string, fn: ChainMethod) {
chain[name] = (...args: unknown[]) => {
update(fn.apply(chain, [tree, ...args]));
return chain;
return self;
};
}

Expand Down Expand Up @@ -157,7 +185,7 @@ export function createChain(
for (const selector in children) {
output[selector] =
typeof children[selector].compile === "function"
? children[selector].compile()
? (children[selector] as Chain).compile()
: children[selector];
}

Expand Down
39 changes: 29 additions & 10 deletions playground/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ var Tile = (() => {
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// node_modules/.deno/react@18.3.1/node_modules/react/cjs/react.development.js
// node_modules/react/cjs/react.development.js
var require_react_development = __commonJS({
"node_modules/.deno/react@18.3.1/node_modules/react/cjs/react.development.js"(exports, module) {
"node_modules/react/cjs/react.development.js"(exports, module) {
"use strict";
if (true) {
(function() {
Expand Down Expand Up @@ -1904,9 +1904,9 @@ var Tile = (() => {
}
});

// node_modules/.deno/react@18.3.1/node_modules/react/index.js
// node_modules/react/index.js
var require_react = __commonJS({
"node_modules/.deno/react@18.3.1/node_modules/react/index.js"(exports, module) {
"node_modules/react/index.js"(exports, module) {
"use strict";
if (false) {
module.exports = null;
Expand All @@ -1931,7 +1931,7 @@ var Tile = (() => {
style: () => style
});

// node_modules/.deno/@stitches+react@1.2.8/node_modules/@stitches/react/dist/index.mjs
// node_modules/@stitches/react/dist/index.mjs
var import_react = __toESM(require_react(), 1);
var e = "colors";
var t = "sizes";
Expand Down Expand Up @@ -3802,6 +3802,7 @@ var Tile = (() => {
let tree = { ...startingValues?.tree };
const variants = { ...startingValues?.variants };
const children = { ...startingValues?.children };
let self;
const chain = {
extend: (newElementTag) => {
return createChain(stitches, newElementTag || elementTag, {
Expand All @@ -3814,7 +3815,7 @@ var Tile = (() => {
// @ts-ignore
select: (selector, subchain) => {
children[selector] = subchain;
return chain;
return self;
},
// In your element method:
element: (rawCSS) => {
Expand All @@ -3839,19 +3840,37 @@ var Tile = (() => {
}
];
}
return chain;
return self;
},
css: (rawCSS) => {
update(rawCSS);
return chain;
return self;
}
};
modules.forEach((m2) => m2.register(addMethod));
return chain;
const proxy = new Proxy(chain, {
get(target, propKey, receiver) {
if (propKey in target) {
return Reflect.get(target, propKey, receiver);
}
if (typeof propKey !== "string") {
return void 0;
}
return (...args) => {
if (!args.length) {
return receiver;
}
update({ [propKey]: args[0] });
return receiver;
};
}
});
self = proxy;
return proxy;
function addMethod(name, fn) {
chain[name] = (...args) => {
update(fn.apply(chain, [tree, ...args]));
return chain;
return self;
};
}
function update(updates) {
Expand Down