{"id":4543,"url":"https://github.com/tmpfs/prism","last_synced_at":"2025-04-21T07:31:48.293Z","repository":{"id":57339219,"uuid":"119234263","full_name":"tmpfs/prism","owner":"tmpfs","description":"Minimal, idiomatic style management for React Native","archived":false,"fork":false,"pushed_at":"2018-11-18T02:28:11.000Z","size":948,"stargazers_count":19,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-10T07:17:57.050Z","etag":null,"topics":["css","prism","react","reactnative","ui"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tmpfs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-28T06:30:17.000Z","updated_at":"2021-01-07T12:25:25.000Z","dependencies_parsed_at":"2022-09-16T07:23:58.129Z","dependency_job_id":null,"html_url":"https://github.com/tmpfs/prism","commit_stats":null,"previous_names":["fika-community/prism"],"tags_count":203,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmpfs%2Fprism","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmpfs%2Fprism/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmpfs%2Fprism/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tmpfs%2Fprism/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tmpfs","download_url":"https://codeload.github.com/tmpfs/prism/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250014684,"owners_count":21360995,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css","prism","react","reactnative","ui"],"created_at":"2024-01-05T20:17:15.782Z","updated_at":"2025-04-21T07:31:43.271Z","avatar_url":"https://github.com/tmpfs.png","language":"JavaScript","readme":"\u003ch1 align=\"center\"\u003ePrism\u003c/h1\u003e\n\u003cp align=\"center\"\u003eMinimal, idiomatic style management for React Native.\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"256\" height=\"256\" src=\"https://raw.githubusercontent.com/tmpfs/prism/master/prism.png\" /\u003e\n\u003c/p\u003e\n\n---\n\n- [Installation](#installation)\n- [Synopsis](#synopsis)\n- [Getting Started](#getting-started)\n  - [Defining Styles](#defining-styles)\n    - [Styles](#styles)\n    - [Colors](#colors)\n    - [Fonts](#fonts)\n  - [Application Configuration](#application-configuration)\n- [Components](#components)\n  - [Defining Styled Components](#defining-styled-components)\n  - [Quick Components](#quick-components)\n  - [Bundling Styles](#bundling-styles)\n  - [Default Styles](#default-styles)\n  - [Style Names](#style-names)\n  - [Style Name Property](#style-name-property)\n  - [Mapping Properties To Styles](#mapping-properties-to-styles)\n    - [mapPropsToStyle](#mappropstostyle)\n      - [Pseudo State](#pseudo-state)\n      - [Child Components](#child-components)\n    - [mapStyleToProps](#mapstyletoprops)\n  - [Component State](#component-state)\n    - [Lifecycle](#lifecycle)\n      - [shouldStyleUpdate](#shouldstyleupdate)\n    - [Options](#options)\n  - [Property Type Validation](#property-type-validation)\n  - [Namespaces](#namespaces)\n  - [Requirements](#requirements)\n- [Properties](#properties)\n  - [Style Properties](#style-properties)\n    - [style](#style)\n    - [className](#classname)\n  - [Extended Style Properties](#extended-style-properties)\n    - [background](#background)\n    - [border](#border)\n    - [padding](#padding)\n    - [margin](#margin)\n    - [flex](#flex)\n    - [row](#row)\n    - [wrap](#wrap)\n    - [justify](#justify)\n    - [position](#position)\n    - [radius](#radius)\n    - [width](#width)\n    - [height](#height)\n  - [Font Properties](#font-properties)\n    - [color](#color)\n    - [align](#align)\n    - [bold](#bold)\n    - [font](#font)\n  - [Experimental Properties](#experimental-properties)\n    - [textTransform](#texttransform)\n- [Cascade](#cascade)\n  - [Default Properties](#default-properties)\n  - [Default Style Rule](#default-style-rule)\n  - [Component Mapping](#component-mapping)\n  - [Class Name](#class-name)\n  - [Inline Property](#inline-property)\n  - [Inline Style](#inline-style)\n- [Configuration](#configuration)\n- [Appendix](#appendix)\n  - [Platform Styles](#platform-styles)\n  - [Color Names](#color-names)\n  - [Flat Styles](#flat-styles)\n  - [Plugins](#plugins)\n    - [Creating Plugins](#creating-plugins)\n      - [Property Plugins](#property-plugins)\n      - [Global Plugins](#global-plugins)\n    - [Plugin Configuration](#plugin-configuration)\n      - [plugins](#plugins-1)\n      - [additionalPlugins](#additionalplugins)\n      - [disabledPlugins](#disabledplugins)\n  - [Processor](#processor)\n  - [Invariants](#invariants)\n  - [Best Practices](#best-practices)\n  - [Pure Mode](#pure-mode)\n  - [Performance](#performance)\n- [License](#license)\n\n---\n\n## Installation\n\nUse your preferred package manager for installation.\n\n```\nnpm i --save react-native-prism\nyarn add react-native-prism\n```\n\n## Synopsis\n\nPrism is a library that returns a Higher Order Component (HOC) exposing access to a style registry containing user-defined colors, fonts and styles.\n\nIt provides a simple yet flexible mechanism for mapping properties to styles and finding style declarations in the registry.\n\nFor any non-trival RN application the question arises on how to manage styles for your components. The Prism library provides a solution using idiomatic techniques that will leave your JSX clean and serene allowing you to focus on your application's state and logic.\n\nIf you want to migrate an existing application you should start with [Prism Primitives][] which provides a drop-in replacement for the RN visual components. See [Prism Components][] for some *slightly* more advanced components; if you want to see a running application clone and run the RN app in the [Prism Components][] repository.\n\n## Getting Started\n\n### Defining Styles\n\nTo configure your application stylesheets first create a theme with some styles, colors and fonts.\n\nFile: [theme.js](https://github.com/tmpfs/prism/blob/master/doc/examples/theme.js)\n\n```javascript\nexport default {\n  colors: {\n    bg: 'steelblue',\n    highlight: '#fdfbdf',\n    normal: '#9a9a9a'\n  },\n  fonts: {\n    regular: 'WorkSans-Regular',\n    medium: 'WorkSans-Medium'\n  },\n  styles: ({colors, fonts}) =\u003e {\n    return {\n      Label: {\n        fontSize: 20,\n        fontFamily: fonts.regular,\n        color: colors.normal\n      },\n      bold: {\n        fontFamily: fonts.medium\n      }\n    }\n  }\n}\n```\n\n#### Styles\n\nStyles are declared as a function that is passed the style registry, typically you only need access to the colors and fonts.\n\n#### Colors\n\nColors are a map from color name to string value. Use of custom color names is optional but it can help make your styles more semantic.\n\n#### Fonts\n\nFonts are a map from font identifier to string font family name.\n\n```javascript\n{regular: 'WorkSans-Regular'}\n```\n\nBecause Android uses the file name and iOS uses the PostScript name the easiest thing to do is name your fonts *using the PostScript* name otherwise use [platform styles](#platform-styles).\n\n### Application Configuration\n\nTo configure your application create a style registry with your theme and instruct your components to use it:\n\nFile: [App.js](https://github.com/tmpfs/prism/blob/master/doc/examples/App.js)\n\n```javascript\nimport React, {Component} from 'react';\nimport {Prism, StyleRegistry} from 'react-native-prism'\nimport theme from './theme'\nimport Label from './Label'\n\nconst registry = new StyleRegistry({theme})\nPrism.configure(\n  registry,\n  {\n    extendedProperties: true,\n    fontProperties: true,\n    experimentalPlugins: true,\n    textTransform: true,\n    colorNames: true\n  }\n)\nexport default class Application extends Component {\n  render () {\n    return (\n      \u003cLabel\n        background='bg'\n        color='highlight'\n        bold\n        align='center'\n        textTransform='capitalize'\n        padding={15}\u003e\n        Prism example application\n      \u003c/Label\u003e\n    )\n  }\n}\n```\n\nWith the `extendedProperties` option all the built in and extended [style properties](#style-properties) are available.\n\nNote that you should `import` all your Prism enabled components *before* calling `configure()`.\n\n## Components\n\n### Defining Styled Components\n\nTo create a styled component you just need to pass the component class to the `Prism` function which will return the HOC component.\n\n```javascript\nimport {View} from 'react-native'\nimport {Prism} from 'react-native-prism'\nexport default Prism(View, 'View')\n```\n\nHere is a working example for the application shown above.\n\nFile: [Label.js](https://github.com/tmpfs/prism/blob/master/doc/examples/Label.js)\n\n```javascript\nimport React, {Component} from 'react'\nimport PropTypes from 'prop-types'\nimport {Text} from 'react-native'\nimport {Prism} from 'react-native-prism'\n\nclass Label extends Component {\n  static styleName = 'Label'\n  static styleOptions = {\n    supportsText: true\n  }\n\n  render () {\n    // Get the computed style sheet\n    const {style} = this.props\n    return (\n      \u003cText style={style}\u003e{this.props.children}\u003c/Text\u003e\n    )\n  }\n}\n\nexport default Prism(Label)\n```\n\nBecause the component configured `styleName` with `Label` the style rule we created earlier already provides styles for our new component!\n\n### Quick Components\n\n```javascript\nPrism.style(Type, style, props)\n```\n\nSometimes you want to wrap a component using fixed styles without too much fuss, use `Prism.style()` to wrap a component with basic styles.\n\nThis is particularly useful when you just want to draw a shape, a convoluted example to illustrate inheritance:\n\n```javascript\nconst Rectangle = Prism.style(\n  View,\n  {\n    flex: 0,\n    width: 20,\n    height: 20,\n    // Set absolute minimum color (defaultProps.style)\n    backgroundColor: 'red'\n  },\n  {\n    // Override backgroundColor with extended property\n    background: 'green'\n  }\n)\n```\n\n```html\n// Use the green background\n\u003cRectangle /\u003e\n// Resize and use a blue background\n\u003cRectangle width={50} height={50} background='blue' /\u003e\n```\n\n### Bundling Styles\n\nComponent libraries should supply a style registry which is merged with the user-supplied registry to bundle their default styles. Pass a theme and the `bundle` flag to a style registry assigned to the component, here is how we wire it up:\n\n```javascript\nimport {Prism, StyleRegistry} from 'react-native-prism'\nconst namespace = 'prism'\nconst theme = {\n  styles: () =\u003e {\n    return {\n      'prism|Label': {\n        fontSize: 22,\n        color: 'white',\n        backgroundColor: 'black'\n      }\n    }\n  }\n}\nconst registry = new StyleRegistry({theme, bundle: true})\nclass Label extends Component {\n  static styleName = 'Label'\n  static styleOptions = {\n    registry: registry\n  }\n}\nexport default Prism(Label, {namespace})\n```\n\nThen a user of the component can just overwrite the declarations they need to change:\n\n```javascript\n'prism|Label': {\n  color: 'black',\n  backgroundColor: 'white'\n}\n```\n\nThe default `fontSize` is respected but now the colors are inverted!\n\nAn example of bundling default styles for a component library is in the [Layout](https://github.com/tmpfs/prism-components/blob/master/src/Layout.js) and corresponding [theme](https://github.com/tmpfs/prism-components/blob/master/src/theme.js) for [Prism Components][].\n\n### Default Styles\n\nIt is recommended that you bundle styles using a theme and style registry however it is possible to set the bare minimum styles for a component with `defaultProps`, to do so you use an object named using the corresponding property:\n\n```javascript\nstatic defaultProps = {\n  style: {\n    fontSize: 16,\n    color: 'black'\n  }\n}\n```\n\nWe can declare default styles for [child components](#child-components) too.\n\n```javascript\nstatic mapPropsToStyle = {\n  labelStyle: {}\n}\nstatic defaultProps = {\n  style: {\n    flex: 1\n  },\n  labelStyle: {\n    fontSize: 16,\n    color: 'black'\n  }\n}\n```\n\n### Style Names\n\nYou must give your component a `styleName` which becomes the default style to use for the component. If a component is namespaced this does not affect the namespace it affects the *class name*. An earlier version of prism inferred the style name from the class name but this will not work in release builds as the name of a function is not guaranteed after name mangling.\n\nThe `styleName` static declaration is preferred:\n\n```javascript\nclass Label extends Component {\n  // Look up a style sheet using selector `Label` by default\n  static styleName = 'Label'\n}\n```\n\nAlternatively you can pass a string or `styleName` option to Prism:\n\n```javascript\n// Same as above, use `Label` as selector\nexport default Prism(Label, 'Label')\n// Use `prism|Label` as the selector\nexport default Prism(Label, {namespace: 'prism', styleName: 'Label'})\n```\n\n### Style Name Property\n\nYou may pass a `styleName` property to any component and it will *overwrite* the static `styleName` defined by the component just for that instance.\n\nThis allows you to create completely different groups of styles for an existing component without defining a wrapper component class. For example, it is common to want two or more completely different button styles.\n\nIf you pass `styleName` to a button component:\n\n```javascript\n\u003cTouchButton styleName='TextButton'\u003e\n  Label Text\n\u003c/TouchButton\u003e\n```\n\nYou can now style it using the assigned style name:\n\n```javascript\nexport default {\n  'prism|TextButton': {\n    /* TextButton does not have a background style */\n  },\n  'prism|TextButton label': {\n    color: 'white'\n  },\n  'prism|TextButton label:disabled': {\n    color: '#999999'\n  }\n}\n```\n\nNotice that the namespace for the component definition is respected.\n\n### Mapping Properties To Styles\n\nComponents have varied needs for mapping properties to style declarations so the library provides several ways to map properties depending upon the requirement.\n\nEach of the mapping options may be either a function or object, when it is a function it is passed the style registry and should return an object.\n\nPrism is flexible with these declarations, the `static` style is the most terse and preferred when other `styleOptions` are not needed:\n\nThe following are all equivalent:\n\n```javascript\nstatic mapPropsToStyle = {\n  bold: ({styleSheet}) =\u003e styleSheet.bold\n}\n```\n\n```javascript\nstatic styleOptions = {\n  mapPropsToStyle: ({styleSheet}) =\u003e {\n    return {\n      bold: () =\u003e styleSheet.bold\n    }\n  }\n}\n```\n\n```javascript\nstatic styleOptions = ({styleSheet}) =\u003e {\n  return {\n    mapPropsToStyle: {\n      bold: () =\u003e styleSheet.bold\n    }\n  }\n}\n```\n\n#### mapPropsToStyle\n\nUse `mapPropsToStyle` when you want the presence of a property to trigger inclusion of styles into the computed style. Each object key maps to a property name and the corresponding function is called when the property is defined on the component.\n\nYou have access to all the properties so you can apply styles conditionally based on other properties:\n\n```javascript\nstatic mapPropsToStyle = {\n  space: ({prop, props}) =\u003e {\n    const {horizontal} = props\n    const styleProp = horizontal ? 'marginRight' : 'marginBottom'\n    const style = {}\n    style[styleProp] = prop\n    return style\n  }\n}\n```\n\nFunctions declared in this way have access to the style registry and it's properties (`colors` etc) the `props`, current `prop` and  `propName`. Functions should return a style object or array of objects to be included in the computed styles, to take no action return `undefined`.\n\nWhen the passed `prop` is returned a style rule is created using the property name and value which is useful when the property name matches the style property name:\n\n```javascript\n{color: ({prop}) =\u003e prop}\n```\n\nIs shorthand for:\n\n```javascript\n{\n  color: ({prop}) =\u003e {\n    return {color: prop}\n  }\n}\n```\n\n##### Pseudo State\n\nIf you call `css.pseudo()` with a string a style sheet is resolved using the familiar `a:hover` syntax.\n\nFor a component called `Notice`:\n\n```javascript\nstatic mapPropsToStyle = {\n  error: ({css, prop, propName}) =\u003e {\n    if (prop === true) {\n      // Include the style for Notice:error\n      return css.pseudo(propName)\n    }\n  }\n}\n```\n\nWould result in including the rule for `Notice:error` when the `error` property is `true`:\n\n```javascript\n{\n  'Notice:error': {\n    backgroundColor: 'red',\n    color: 'white'\n  }\n}\n```\n\n```html\n\u003cNotice error\u003eError message\u003c/Notice\u003e\n```\n\nThis can be an easy way to trigger style variations that are resolved from the style sheet based on a property value. For example, if you have a `size` property that accepts `small|medium|large` you can do:\n\n```javascript\nstatic mapPropsToStyle = {\n  size: ({css, prop}) =\u003e css.pseudo(prop)\n}\n```\n\nTo resolve a style sheet for the value of `size`, eg: `Notice:small`, `Notice:medium` or `Notice:large`.\n\n##### Child Components\n\nFor composite components you can route properties to styles that you apply to child components.\n\nAt it's simplest level the empty object just declares that your component wants a style object to pass to a child, but you can also route properties to child style objects:\n\n```javascript\nstatic mapPropsToStyle = {\n  headerStyle: {\n    color: ({prop}) =\u003e prop\n  },\n  bodyStyle: {}\n}\n```\n\nWhich will define and create the `headerStyle` and `bodyStyle` properties for your component and route the `color` property in to the `headerStyle` object. The `propTypes` for the child style objects are automatically declared as we know ahead of time they should have the same property type as `style`.\n\nThe immediate benefit is that you can now define style rules for the child components which will automatically be resolved as default styles.\n\n```javascript\n'Panel header': {\n  color: 'blue',\n  padding: 10\n},\n'Panel body': {\n  padding: 20\n}\n```\n\nFor style declaration lookup the child component name is determined by the property name with any `Style` suffix removed. If the component is namespaced use the fully qualified name, eg: `prism|Panel header`.\n\nThen your render should route the properties to child components, for example:\n\n```javascript\nrender () {\n  const {style, headerStyle, bodyStyle, label} = this.props\n  return (\n    \u003cView style={style}\u003e\n      \u003cText style={headerStyle}\u003e\n        {label}\n      \u003c/Text\u003e\n      \u003cView style={bodyStyle}\u003e\n        {this.props.children}\n      \u003c/View\u003e\n    \u003c/View\u003e\n  )\n}\n```\n\nNow use of the `color` property on the parent is directed to the `headerStyle` object (and therefore the child component):\n\n```html\n\u003cPanel color='red' /\u003e\n```\n\nYou can combine `css.pseudo()` with multiple child components to create some interesting behaviour:\n\n```javascript\nstatic mapPropsToStyle = {\n  titleStyle: {\n    size: ({css, prop}) =\u003e css.pseudo(prop)\n  },\n  numberStyle: {\n    size: ({css, prop}) =\u003e css.pseudo(prop)\n  }\n}\n```\n\nFor a component `NumberStack`:\n\n```html\n\u003cNumberStack size='medium' /\u003e\n```\n\nWill resolve `NumberStack title:small` to include in `titleStyle` and `NumberStack number:small` for the `numberStyle`.\n\n#### mapStyleToProps\n\nThis is the inverse mapping that extracts a style property and assigns it as a property on the component.\n\nIt is recommended to only use `mapStyleToProps` when you absolutely must as it requires flattening the computed styles.\n\n```javascript\nstatic mapStyleToProps = {\n  tintColor: ({prop}) =\u003e prop\n}\n```\n\nTypically this is used to deal with [invariants](#invariants) as in the example above which allows your component to respect `tintColor` in a style rule:\n\n```javascript\nActivity: {\n  tintColor: 'purple'\n}\n```\n\nAnd have it extracted to a property on the component:\n\n```javascript\nrender () {\n  const {style, tintColor} = this.props\n  return (\n    \u003cView style={style}\u003e\n      \u003cActivityIndicator tintColor={tintColor} /\u003e\n    \u003c/View\u003e\n  )\n}\n```\n\nSee [Activity.js](https://github.com/tmpfs/prism-components/blob/master/src/Activity.js) for a complete implementation.\n\n### Component State\n\nFor most use cases when you are triggering state changes from a property `mapPropsToStyle` and `css.pseudo()` will do the job just fine (see [pseudo state](#pseudo-state)). However there are times when you need finer control over style invalidation as the component state changes.\n\nTo enable state invalidation you need to specify the `withState` configuration option and enable `supportsState` in your component:\n\n```javascript\nstatic styleOptions = {\n  supportsState: true\n}\n```\n\nA typical scenario is when you are managing state based on events from a child component and want the state change to be reflected in the styles.\n\n```javascript\nrender () {\n  const toggle = () =\u003e this.setState({active: !this.state.active})\n  return (\n    \u003cChildComponent onPress={toggle} /\u003e\n  )\n}\n```\n\nOnce state invalidation is enabled you can do:\n\n```javascript\nstatic mapPropsToStyle = {\n  state: ({state, css}) =\u003e {\n    if (state.active) {\n      return css.pseudo('active')\n    }\n  }\n}\n```\n\nTo add the `:active` pseudo class to the component when `state.active` is true. If you want the state change to automatically be applied to child components you can use the `cascadeState` option:\n\n```javascript\nstatic styleOptions = {\n  supportsState: true,\n  cascadeState: true\n}\nstatic mapPropsToStyle = {\n  state: ({state, css}) =\u003e {\n    if (state.active) {\n      return css.pseudo('active')\n    }\n  }\n  // We don't need to declare a state handler\n  // for these as `cascadeState` is enabled\n  // the `:active` pseudo class will be triggered\n  // for these styles automatically\n  headerStyle: {},\n  footerStyle: {}\n}\n```\n\nYou should try to match the default style of your component to the default state but you can trigger invalidation of the styles using the *initial component state* when it mounts by declaring the `mountStateStyle` option for your component.\n\n```javascript\nstatic styleOptions = {\n  supportsState: true,\n  mountStateStyle: true\n}\n```\n\n#### Lifecycle\n\nThe component state functionality decorates your component with a simple lifecycle that lets you decide when state changes should trigger style invalidation.\n\nBy default as soon as you enable this feature every call to `setState()` will trigger invalidation of the styles but you can implement `shouldStyleUpdate()` on your component to control this behaviour.\n\n##### shouldStyleUpdate\n\n```javascript\nshouldStyleUpdate(state, newState)\n```\n\nImplement this function to control whether to invalidate the styles when the state changes, it should return a boolean.\n\n#### Options\n\n* `supportsState` opt-in to state style invalidation.\n* `cascadeState` call primary state handler for child component styles.\n* `mountStateStyle` automatically invalidate using the state of the component when it mounts.\n\n### Property Type Validation\n\nIt is important to know that the `propTypes` you declare are assigned to the HOC so properties work as expected and that your static `propTypes` are *augmented* with all the [style properties](#style-properties).\n\nBuilt in `propTypes` are merged first so your `propTypes` will win if there is a property name collision however the behaviour is undefined so you should take care that your `propTypes` do not conflict.\n\nIf you need it the `Prism.propTypes` field exposes the system property types.\n\n### Namespaces\n\nThe `Prism` function accepts a namespace option which can be used to specify a namespace for your component. This is useful (and recommended) when designing reusable component sets.\n\n```javascript\nconst namespace = 'prism'\nclass Label extends Component {\n  static styleName = 'Label'\n  /* ... */\n}\nexport default Prism(Label, {namespace})\n```\n\nNow the default component style declaration name uses CSS-style namespaces `prism|Label` and a consumer needs to declare the style using the fully qualified name:\n\n```javascript\n'prism|Label': {\n  color: 'black'\n}\n```\n\n### Requirements\n\nSometimes a component or library of components needs certain conditions to be met to be able to work correctly.\n\nYou may pass a `requirements` option to `Prism()` which is a function passed the `registry` and `config` and can be used to validate the component requirements.\n\nHere is an example from the [Prism Components][]:\n\n```javascript\nconst requirements = ({config}) =\u003e {\n  if (config.extendedProperties !== true) {\n    return `extendedProperties must be set in config ` +\n      `to use the ${namespace} component library`\n  }\n}\n\nexport default Prism(Layout, {requirements})\n```\n\nIf the component requirements are not met you can throw an error or return an error or a string. When a string is returned it is wrapped in an error and thrown.\n\nNote that you can use this technique to validate style rules exist, for example:\n\n```javascript\nconst requirements = ({registry}) =\u003e {\n  if (!registry.has('bold')) {\n    return `bold style rule is required`\n  }\n}\n```\n\n## Properties\n\n### Style Properties\n\nBy default plugins are enabled that expose the following properties on all styled components.\n\nThe property mapping API and these properties should be sufficient for most applications and indeed it would be considered best practice not to use the extended and experimental properties so that all styling information can be maintained in a single file.\n\n#### style\n\n`Array | Object`\n\nInline styles for the component.\n\n#### className\n\n`String | Array\u003cString\u003e`\n\nAssign stylesheets to the component. When a string is given separate stylesheet names should be delimited with whitespace.\n\nThe declaration in the style sheet should use a dot prefix as is the CSS convention:\n\n```javascript\n'.highlight': {\n  color: 'orange'\n}\n```\n\n### Extended Style Properties\n\nExtended properties allow for rapidly mocking layouts with a variety of convenient shortcuts for common style properties. Enable the `extendedProperties` option to use these properties.\n\nSome extended properties require a component *opt-in* using `styleOptions` for the style to be applied, for example to receive the `color` property:\n\n```javascript\nstatic styleOptions = () =\u003e {\n  return {\n    supportsText: true\n  }\n}\n```\n\n* `supportsText`: Component can receive text style props.\n* `supportsDimension`: Component can receive `width` and `height`.\n\nNote that the `supportsText` option is also used to test whether a component can receive `textTransform` on it's children.\n\n#### background\n\n`String`\n\nSet the `backgroundColor` style property.\n\n#### border\n\n`String | Array | Object`\n\nEnables a border for the component, this shortcut is great for quickly visualizing component dimensions.\n\nWhen a string is given `borderColor` is set and a default `borderWidth` is used.\n\nWhen an array is given it takes the form `[width, color]`.\n\n```javascript\n{\n  color: 'red',\n  top: 0,\n  right: 0,\n  bottom: 0,\n  left: 0\n}\n```\n\nNote that not all RN components will set borders as expected when different widths are given for each side, if you experience problems with this syntax ensure the style is applied to a `View` rather than `Image` etc.\n\n#### padding\n\n`Number | Object | Array`\n\nSets padding properties, a number sets all edges to be equal.\n\nArrays are a shorthand for setting vertical and horizontal values and take the form: `[vertical, horizontal]`.\n\n```javascript\n{top: 0, right: 0, bottom: 0, top:0}\n[5,10]\n```\n\n#### margin\n\n`Number | Object | Array`\n\nSets margin properties, a number sets all edges to be equal.\n\nArrays are a shorthand for setting vertical and horizontal values and take the form: `[vertical, horizontal]`.\n\n```javascript\n{top: 0, right: 0, bottom: 0, top:0}\n[5,10]\n```\n\n#### flex\n\n`Number | Boolean | Object`\n\nShorthand for `flex` properties. A number is assigned directly to the `flex` style property, boolean is coerced to a number (yields zero or one).\n\nObject notation supports the `grow`, `row` and `wrap` fields:\n\n```\n{\n  grow: 1,\n  row: true,\n  wrap: true\n}\n```\n\nThe `row` boolean sets `flexDirection`, `wrap` sets `flexWrap` and `grow` sets the `flex` property.\n\n#### row\n\n`Boolean`\n\nSet the `flexDirection` style property to `row`.\n\n#### wrap\n\n`Boolean`\n\nSet the `flexWrap` style property.\n\n#### justify\n\n`Enum\u003cString\u003e (center|start|end|between|around)`\n\nSet the `justifyContent` style property, note that the `flex-` prefixes are omitted.\n\n#### position\n\n`Object`\n\nMakes a component absolutely positioned (relative to the parent as is the RN way) and sets the style properties to the given values.\n\n```javascript\n{top: 0, right: 0, bottom: 0, top:0}\n```\n\n#### radius\n\n`Number | Object`\n\nSets border radius style properties.\n\n```javascript\n{\n  top: {left: 0, right: 0},\n  bottom: {left: 0, right: 0}\n}\n```\n\n#### width\n\n`Number | String`\n\nPass the `width` property into the computed style, requires the `supportsDimension` flag.\n\n#### height\n\n`Number | String`\n\nPass the `height` property into the computed style, requires the `supportsDimension` flag.\n\n### Font Properties\n\nWhen the `fontProperties` option is given these properties are configured.\n\nOnly `Text` and `TextInput` components can accept these style properties so components that wish to receive them in their computed stylesheet must specify the `supportsText` option.\n\n#### color\n\n`String`\n\nSet the `color` style property.\n\n#### align\n\n`Enum\u003cString\u003e (left|center|right)`\n\nSets the `textAlign` style property.\n\n#### bold\n\n`Boolean`\n\nLooks for a style rule named `bold` and returns it if available otherwise sets `fontWeight` to `bold`.\n\n#### font\n\nThe `font` property provides a convenient shortcut for all the [Text Style Props][] and can be useful if you have a lot of inline text styling.\n\nNote that to propagate down to children this property requires that `experimentalPlugins` is enabled so that `context` is used, see [experimental properties](#experimental-properties).\n\nAn example using [Prism Components][]:\n\n```html\n\u003cLayout font={{size: 'large', color: 'red'}}\u003e\n  \u003cLayout\u003e\n    \u003cLabel\u003eRed text\u003c/Label\u003e\n    \u003cLabel font={{color: 'green'}}\u003e\n      Font style properties combined with those inherited from the grandparent\n    \u003c/Label\u003e\n  \u003c/Layout\u003e\n\u003c/Layout\u003e\n```\n\nThe shape of the font object is described in [propTypes.js](https://github.com/tmpfs/prism/blob/master/src/propTypes.js).\n\n### Experimental Properties\n\nWhen the `experimentalPlugins` option is given these properties are configured.\n\nThey are considered experimental due to use of `context` to propagate values to child components and the behaviour is undefined when components wrapped by `Prism()` make use of the `context`.\n\n#### textTransform\n\n```javascript\nlowercase|uppercase|capitalize\n```\n\nThe `textTransform` property provides a means to apply text transformations to components, it requires the `supportsText` flag on receiving components and requires that the `textTransform` and `experimentalPlugins` options are enabled.\n\nThis property is distinct from the `font` property as it's behaviour is very different, instead of injecting values into a style sheet it *modifies a component's children*.\n\nIn a style sheet:\n\n```javascript\n'Panel header': {\n  textTransform: 'capitalize'\n}\n```\n\nInline property usage illustrating inheritance:\n\n```html\n\u003cList space={5} textTransform='uppercase'\u003e\n  \u003cList space={10}\u003e\n    \u003cParagraph\u003e\n      This is some uppercase text \u003cLabel textTransform='lowercase'\u003eincluding some lowercase text in a Label\u003c/Label\u003e in a paragraph. \u003cLabel textTransform='capitalize'\u003eWe can capitalize too\u003c/Label\u003e.\n    \u003c/Paragraph\u003e\n  \u003c/List\u003e\n\u003c/List\u003e\n```\n\nCaveat that you cannot undo a transformation on a child (`none` is not supported), you can only override with a new transformation.\n\n## Cascade\n\nThis section gives an overview of the cascade or inheritance mechanism using the default configuration.\n\n1. Compute style from `defaultProps`\n2. Include styles from `defaultStyleRule`\n3. Process global plugins (property mapping)\n4. Process property plugins (eg: extended and experimental)\n5. Run processors\n\nNote that property plugins are massaged so that `style`, `labelStyle` etc always execute after other configured property plugins.\n\nThis means the inheritance for say `color` of `Label` can be described in this order.\n\n### Default Properties\n\n```javascript\nstatic defaultProps = {\n  style: {\n    color: 'red'\n  }\n}\n```\n\n```html\n// Color is red\n\u003cLabel /\u003e\n```\n\n### Default Style Rule\n\n```javascript\n'Label': {\n  color: 'green'\n}\n```\n\n```html\n// Color is green now we have a default style rule\n\u003cLabel /\u003e\n```\n\n### Component Mapping\n\n```javascript\nstatic mapPropsToStyle = {\n  color: () =\u003e {\n    return {color: 'blue'}\n  }\n}\n```\n\n```\n// Our component now says it should be blue\n\u003cLabel /\u003e\n```\n\n### Class Name\n\n```javascript\n'.highlight': {\n  color: 'steelblue'\n}\n```\n\n```html\n// Prefer the color in another style rule\n\u003cLabel className='highlight' /\u003e\n```\n\n### Inline Property\n\n```html\n// Prefer the inline property over the className style\n\u003cLabel className='highlight' color='orange' /\u003e\n```\n\n### Inline Style\n\n```html\n// Inline style beats everything else\n\u003cLabel className='highlight' color='orange' style={{color: 'purple'}} /\u003e\n```\n\n## Configuration\n\nYou can pass a configuration object as the second argument to `Prism.configure()` to modify the library configuration. These are the common configuration options, some more advanced options are shown in [plugin configuration](#plugin-configuration).\n\n* `defaultProps` use the [defaultProps](https://github.com/tmpfs/prism/blob/master/src/defaultProps.js) plugin, default is `true`.\n* `defaultStyleRule` use the [defaultStyleRule](https://github.com/tmpfs/prism/blob/master/src/defaultStyleRule.js) plugin, default is `true`.\n* `mapPropsToStyle` use the [mapPropsToStyle](https://github.com/tmpfs/prism/blob/master/src/mapPropsToStyle.js) plugin, default is `true`.\n* `mapStyleToProps` use the [mapStyleToProps](https://github.com/tmpfs/prism/blob/master/src/mapStyleToProps.js) plugin, default is `true`.\n* `className` use the property plugin for [className](https://github.com/tmpfs/prism/blob/master/src/className.js), default is `true`.\n* `extendedProperties` enables the [extended property plugins](https://github.com/tmpfs/prism/blob/master/src/extendedPropertyPlugins.js).\n* `fontProperties` enables the [font property plugins](https://github.com/tmpfs/prism/blob/master/src/fontProperties.js).\n* `experimentalPlugins` enables the [experimental plugins](https://github.com/tmpfs/prism/blob/master/src/experimentalPlugins.js).\n* `colorNames` enables the [color names](https://github.com/tmpfs/prism/blob/master/src/colorNames.js) processor.\n* `textTransform` enables the text transform support (requires experimental plugins).\n* `withState` enables [component state](#component-state) support.\n* `pure` advanced option, see [pure mode](#pure-mode).\n* `debug` print information at boot, default value is `__DEV__`.\n\nWhen no configuration object is given support for the `className` property is enabled and the global plugins to support mapping properties to styles and resolving default styles.\n\nThis is a sensible minimal default configuration which will be sufficient for many applications and creates the least chance of conflict if you want to integrate Prism with an existing application.\n\nTo use the [extended style properties](#extended-style-properties) and enable color name lookup:\n\n```javascript\nPrism.configure(registry, {extendedProperties: true, colorNames: true})\n```\n\nTo use `textTransform` you need to enable `experimentalPlugins`:\n\n```javascript\nPrism.configure(\n  registry,\n  {\n    experimentalPlugins: true,\n    textTransform: true\n  }\n)\n```\n\nFile: [configuration.js](https://github.com/tmpfs/prism/blob/master/src/configuration.js)\n\n```javascript\nexport default {\n  plugins: [],\n  processors: [],\n  defaultProps: true,\n  defaultStyleRule: true,\n  mapPropsToStyle: true,\n  mapStyleToProps: true,\n  className: true,\n  extendedProperties: false,\n  fontProperties: false,\n  experimentalPlugins: false,\n  withState: false,\n  inlineStyle: true,\n  colorNames: false,\n  textTransform: false,\n  pure: false,\n  debug: __DEV__,\n  invariants: [],\n  sizes: {\n    'xx-small': 12,\n    'x-small': 13,\n    'small': 14,\n    'medium': 16,\n    'large': 18,\n    'x-large': 22,\n    'xx-large': 26\n  }\n}\n```\n\n## Appendix\n\n### Platform Styles\n\nYou can use platform specific styles for your fonts and style sheets by using the standard notation passed to `Platform.select()`.\n\nIf you need a platform-specific font family specify an object in your fonts map:\n\n```javascript\nexport default {\n  regular: {\n    ios: 'WorkSans-Regular',\n    android: 'worksans'\n  }\n}\n```\n\nPlatform-specific styles are merged over the top of default rules using a selective merge so you can overwrite declarations and inherit the other styles. To illustrate:\n\n```javascript\nexport default {\n  Label: {\n    fontSize: 20,\n    color: 'red'\n  },\n  android: {\n    Label: {\n      // Overwrite for android but inherit\n      // fontSize from the top-level Label\n      color: 'green'\n    }\n  }\n}\n```\n\n### Color Names\n\nStyles are much easier to change and we can add semantic meaning to our colors if we can refer to them by name, use the `colorNames` option to enable this functionality.\n\nWith the `colorNames` option enabled and a theme like:\n\n```javascript\n{\n  colors: {\n    primary: '#333333',\n    muted: '#999999',\n  },\n  styles: ({colors}) =\u003e {\n    return {\n      Label: {\n        fontSize: 16,\n        color: colors.primary\n      }\n    }\n  }\n}\n```\n\nYou can now override the color by name:\n\n```html\n\u003cLabel color='muted' /\u003e\n```\n\nTo work in all scenarios (default properties, style sheets and properties) this logic is implemented as a [processor](#processor) and adds overhead therefore it is not enabled by default.\n\nConsider that there may be a better way for your application to manage named colors internally before enabling this option.\n\n### Flat Styles\n\nSometimes you are wrapping a third-party component and want to proxy the `style` object to the component but it does not accept an array for the `style` property; it enforces an object only property type.\n\nThe computed `style` property passed to your component is guaranteed to be an array; here however we need it to be an object. To do so you can use the `flat` option:\n\n```javascript\nstatic styleOptions = {\n  flat: true\n}\n```\n\nNow you can just proxy it to the child component knowing it will be an object:\n\n```javascript\nrender () {\n  const {style} = this.props\n  return (\n    \u003cNonIdiomaticComponent style={style} /\u003e\n  )\n}\n```\n\nFlat styles are applied to [child components](#child-components) too.\n\n### Plugins\n\nPlugins allow you to change the default behaviour.\n\n#### Creating Plugins\n\nTo create a plugin you pass a plugin name, handler function and plugin options:\n\n```javascript\nimport {Plugin} from 'react-native-prism'\nnew Plugin(\n  'pluginName',\n  () =\u003e { /* ... */ },\n  {/* options */}\n)\n```\n\n##### Property Plugins\n\nIf your plugin is for a property you should use the `propType` option:\n\n```javascript\nimport PropTypes from 'prop-types'\nconst plugins = [\n  new Plugin(\n    'transform',\n    ({prop, propName, styleSheet, colors}) =\u003e {\n      // Return some transform specific style declarations\n    },\n    {propType: PropTypes.object}\n  )\n]\n```\n\nThese plugins will only execute when the property is defined on the component.\n\nSee [extendedPropertyPlugins.js](https://github.com/tmpfs/prism/blob/master/src/extendedPropertyPlugins.js) for several examples.\n\n##### Global Plugins\n\nGlobal plugins are those without a `propType` option:\n\n```javascript\nnew Plugin(\n  'globalPlugin',\n  ({props, styleSheet}) =\u003e { /* ... */ },\n  {requireOptions: true}\n)\n```\n\nThese plugins provide the ability to modify the computed style sheets without being triggered by the presence of a property.\n\nThey can provide options that filter when they are executed. For example `requireOptions` means *only run this plugin for components that have declared a corresponding options object*.\n\nFor the example above a component needs to explicitly enable the plugin:\n\n```javascript\nstatic styleOptions: {\n  // Trigger execution of the plugin for this component\n  globalPlugin: {}\n}\n```\n\n#### Plugin Configuration\n\nUse these configuration options to control plugins:\n\n* `additionalPlugins` array of plugin definitions to append to the system plugins.\n* `disabledPlugins` array of string plugin names to disable.\n* `plugins` array of plugin definitions to use, overrides the system plugins.\n\n##### plugins\n\nUse your own `plugins` array when you want to specify a list of plugins to use *before* any plugins enabled using the configuration flags, you can disable `className` and `mapPropsToStyle` etc to use only the custom plugins you specify.\n\n##### additionalPlugins\n\nUse the `additionalPlugins` option to add custom functionality to all your styled components, see [plugins](#plugins) for information on defining custom plugins.\n\n```javascript\nPrism.configure(\n  registry,\n  {\n    extendedProperties: true,\n    additionalPlugins: [\n      new Plugin(\n        'customGlobalPlugin',\n        ({props, styleSheet}) =\u003e {\n          // Do something cool\n        }\n      )\n    ]\n  }\n)\n```\n\n##### disabledPlugins\n\nYou may want to remove plugins you don't need or if you find a property name collision:\n\n```javascript\nPrism.configure(\n  registry,\n  {\n    extendedProperties: true,\n    disabledPlugins: ['position', 'wrap']\n  }\n)\n```\n\nThe `disabledPlugins` option is processed after `plugins` and `additionalPlugins` so you may use this to disable your custom plugins. If you give a plugin name that does not exist it is ignored.\n\n### Processor\n\nProcessors are plugins that operate on a *flat representation* of the computed styles, they are used to support named colors and invariants. The default configuration does not enable any processors but it is worth knowing that certain configuration options add some processing overhead:\n\n* `colorNames`\n* `textTransform`\n\n### Invariants\n\nInvariants are unknown style declarations that would trigger an error when compiling style sheets with `StyleSheet.create()`. This strict behaviour of RN is very useful but there are occasions where it makes more sense to put the information in a style sheet and invariants allow us to do that. Internally they are extracted as invariant style rules and later resolved when styles are computed.\n\nAn example of this is `tintColor` where we need to assign to the `tintColor` property of `ActivityIndicator` but really it's styling information and is better suited to being in a style sheet.\n\nAlso the experimental `textTransform` property is treated as an invariant so it can be declared in style rules and processed using the plugin system yet never appear in compiled or computed style sheets.\n\nInvariants use a processor to ensure computed styles do not contain these properties so they incur the same performance penalty.\n\n### Best Practices\n\nYou are free to do as you please however here are some guidelines:\n\n* Avoid setting styles in `defaultProps`.\n* Use class name style rule for default styles (eg: `Label`).\n* Prefer `className` as first option for style overrides.\n* Use extended properties sparingly, useful for rapid devlopment, later migrate to `className`.\n* Avoid inline `style` properties.\n\n### Pure Mode\n\nIf you like the style sheet paradigm that Prism has but want to get closer to the metal we offer a pure mode of operation. When the `pure` configuration option is given plugins and style computation are disabled. Your components are given direct access to the style registry instead.\n\nIn pure mode your components are only passed two properties by the HOC:\n\n* `styleRegistry` the application style registry.\n* `styleSheet` alias for the registry style sheet.\n\nNote that `style` is no longer passed!\n\nNow you need to pass the styles manually by finding them in the registry:\n\n```javascript\nrender () {\n  const {styleSheet} = this.props\n  \u003cText style={styleSheet.text}\u003e\n    {this.props.children}\n  \u003c/Text\u003e\n}\n```\n\nTypically you would decide to use this mode of operation from the beginning. If you enable pure mode for an existing application using Prism features your views will revert to zero style.\n\nThis would apply to any third-party components you may be using too!\n\n### Performance\n\nWe have made every effort to keep iterations and function calls to a bare minimum and in it's default configuration performance impact should be minimal.\n\nHowever performance may be impacted if you use any of the following features as they all require a flat representation of the computed styles:\n\n* [Processor](#processor) operate on flat computed styles.\n* [Invariants](#invariants) implies use of a processor.\n* [Flat Styles](#flat-styles) computes a component-specific flat stylesheet.\n\nAnd of course caveat emptor this is not the sort of thing you want to use to style say many thousands of game sprites.\n\n## License\n\nMIT\n\n---\n\nCreated by [mkdoc](https://github.com/mkdoc/mkdoc) on June 18, 2018\n\n[prism primitives]: https://github.com/tmpfs/prism-primitives\n[prism components]: https://github.com/tmpfs/prism-components\n[text style props]: https://facebook.github.io/react-native/docs/text-style-props.html\n\n","funding_links":[],"categories":["Components"],"sub_categories":["Styling"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftmpfs%2Fprism","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftmpfs%2Fprism","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftmpfs%2Fprism/lists"}