atlassian-labs / compiled

A familiar and performant compile time CSS-in-JS library for React.
https://compiledcssinjs.com
Apache License 2.0
1.98k stars 68 forks source link

Add custom property values to loose XCSSProp #1665

Closed AndrewOCC closed 4 months ago

AndrewOCC commented 4 months ago

Currently, the loose XCSSProp allows makers to type an xcss prop that only accepts certain CSS properties (for example, limiting a text component to only accept color. And create-strict-api allows libraries to create a restricted XCSSProp with limited values.

However, there's no lightweight approach for a component to customize XCSSProp to accept both a restricted set of properties, and restricted values. After pairing on the issue with @itsdouges , he suggested the following change!

This PR augments XCSSProp to accept an object as the first generic TAllowedProperties, in addition to the existing string union type. When TAllowedProperties is set to an object, the required properties for XCSSProp are set automatically, and so requiredProperties is set to never.

changeset-bot[bot] commented 4 months ago

🦋 Changeset detected

Latest commit: 75b394ab1a4b30702de72784f33df3336461cc05

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 7 packages | Name | Type | | --------------------------------------------------------- | ----- | | @compiled/react | Minor | | @compiled/parcel-optimizer-test-app | Patch | | @compiled/parcel-transformer-test-app | Patch | | @compiled/parcel-transformer-test-compress-class-name-app | Patch | | @compiled/parcel-transformer-test-custom-resolve-app | Patch | | @compiled/parcel-transformer-test-custom-resolver-app | Patch | | @compiled/parcel-transformer-test-extract-app | Patch |

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

AndrewOCC commented 4 months ago

Closing this PR; after discussion with @kylorhall-atlassian we found that although this feature is desired, a more robust implementation through a separate API may be necessary. In addition, there are implications for other parts of the compiled API works - for example, how do you support tight types in CSSMap when the types are different per-component?

kylorhall-atlassian commented 3 months ago

For example, how do you support tight types in CSSMap when the types are different per-component?

Yeah, I think this change is required for us to move the needle in the future—but what does this look like? How do we allow color: Text | IconFill color schemes in a shared cssMap where we only want color: Text by default?

A generic override and on the common css source?

import { cssMap } from '@atlaskit/css';
import { Icon, type IconSchema } from '@atlaskit/icon';
const styles = cssMap<IconSchema>({ primary: { color: 'var(--ds-icon-color)' } });
export default () => <Icon xcss={styles.primary} />;

Per-package css exports from every package:

import { Icon, cssMap } from '@atlaskit/icon';
const styles = cssMap({ primary: { color: 'var(--ds-icon-color)' } });
export default () => <Icon xcss={styles.primary} />;

Very loose interfaces with strict component-level interfaces

import { cssMap } from '@atlaskit/css';
import { Button } from '@atlaskit/Button';
import { Icon } from '@atlaskit/Icon';

// This `color` interface allows for both icon and text colors.
const styles = cssMap({ primary: { color: 'var(--ds-icon-color)' } });

export default () => <>
  {/* This is fine because it allows icon-specific colors */}
  <Icon xcss={styles.primary} />
  {/* This errors because it doesn't allow icon colors */}
  <Button xcss={styles.primary} />
</>