{"id":14961352,"url":"https://github.com/motion/gloss","last_synced_at":"2025-10-24T20:31:32.477Z","repository":{"id":57132629,"uuid":"78135290","full_name":"motion/gloss","owner":"motion","description":"a powerful style system for building ui kits","archived":false,"fork":false,"pushed_at":"2017-07-02T19:34:32.000Z","size":211,"stargazers_count":16,"open_issues_count":3,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-31T04:23:27.548Z","etag":null,"topics":["components","css","css-in-js","cssinjs","js","jss","motion","react","stylesheets","theme"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/motion.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-05T17:52:44.000Z","updated_at":"2019-10-07T04:42:13.000Z","dependencies_parsed_at":"2022-08-24T22:51:19.643Z","dependency_job_id":null,"html_url":"https://github.com/motion/gloss","commit_stats":null,"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motion%2Fgloss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motion%2Fgloss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motion%2Fgloss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/motion%2Fgloss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/motion","download_url":"https://codeload.github.com/motion/gloss/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238035385,"owners_count":19405682,"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":["components","css","css-in-js","cssinjs","js","jss","motion","react","stylesheets","theme"],"created_at":"2024-09-24T13:24:52.443Z","updated_at":"2025-10-24T20:31:31.269Z","avatar_url":"https://github.com/motion.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"powerful, lightweight, elegant css in js\n\n- [JSS](https://github.com/cssinjs/jss) styles\n- themes\n- simple $style props through babel transform\n- super fast\n- built on jss\n  - nice object to styles syntax\n  - auto prefixes\n  - animations\n  - pseudos\n  - media queries\n  - '\u003e selectors', etc\n\n## install\n\n```js\nnpm install --save gloss\n```\n\nbabel transform for efficient $shorthand props\n\n```js\n{\n  \"babel\": {\n    \"plugins\": [\n      [\"gloss/transform\", { \"decoratorName\": \"style\" }]\n    ]\n  }\n}\n```\n\n## usage\n\nhere's a pretty good base view you can build from:\n\n```js\n// note: uses babel-jsx-if\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport gloss, { color as $, Theme, ThemeProvide } from 'gloss'\nimport Icon from './icon'\nimport Popover from './popover'\n\nconst LINE_HEIGHT = 30\n\nconst { decorator: style } = gloss({\n  baseStyles: styles,\n  themeProp: 'theme',\n  tagName: 'tagName',\n  isColor: color =\u003e color \u0026\u0026 !!color.rgb,\n  processColor: color =\u003e color.toString(),\n})\n\nReactDOM.render(\n  \u003cThemeProvide bright={{ background: '#000' }}\u003e\n    \u003cTheme name=\"bright\"\u003e\n      \u003cSurface icon=\"name\" /\u003e\n    \u003c/Theme\u003e\n  \u003c/ThemeProvide\u003e,\n  document.querySelector('#app')\n)\n\n@style\nexport default class Surface {\n  static defaultProps = {\n    tagName: 'div',\n    size: 1,\n  }\n\n  render({\n    onClick,\n    children,\n    icon,\n    iconProps,\n    iconSize: _iconSize,\n    iconAfter,\n    iconColor,\n    className,\n    tagName,\n    getRef,\n    after\n  }) {\n    const { theme } = this\n    const hasIconBefore = icon \u0026\u0026 !iconAfter\n    const hasIconAfter = icon \u0026\u0026 iconAfter\n    const stringIcon = typeof icon === 'string'\n    const iconSize =\n      _iconSize ||\n      (theme \u0026\u0026 theme.element.style.fontSize * 0.9) ||\n      Math.log(size + 1) * 15\n\n    const passProps = {\n      className,\n      onClick,\n      tagName,\n      ref: getRef,\n    }\n\n    return (\n      \u003csurface {...!wrapElement \u0026\u0026 passProps}\u003e\n        {icon \u0026\u0026 \u003cIcon\n          $icon\n          $iconAfter={hasIconAfter}\n          name={icon}\n          size={iconSize}\n          {...iconProps}\n        /\u003e}\n        \u003celement\n          {...wrapElement \u0026\u0026 passProps}\n          $hasIconBefore={hasIconBefore}\n          $hasIconAfter={hasIconAfter}\n        \u003e\n          {children}\n        \u003c/element\u003e\n        {after || null}\n      \u003c/surface\u003e\n    )\n  }\n\n  static style = {\n    surface: {\n      lineHeight: '1rem',\n      fontWeight: 400,\n      flexFlow: 'row',\n      alignItems: 'center',\n      justifyContent: 'center',\n      borderWidth: 1,\n      borderStyle: 'solid',\n      borderColor: 'transparent',\n      position: 'relative',\n      boxShadow: ['inset', 0, 0.5, 0, [255,255,255,0.2]],\n    },\n    minimal: {\n      boxShadow: 'none',\n    },\n    element: {\n      border: 'none',\n      background: 'transparent',\n      userSelect: 'none',\n      height: '100%',\n      justifyContent: 'center',\n      alignItems: 'center',\n    },\n    icon: {\n      pointerEvents: 'none',\n    },\n    hasIconBefore: {\n      marginLeft: '0.7vh',\n    },\n    hasIconAfter: {\n      marginRight: '0.7vh',\n    },\n    iconAfter: {\n      order: 3,\n    },\n  }\n\n  static disabledStyle = {\n    opacity: 0.25,\n    pointerEvents: 'none',\n  }\n\n  static dimStyle = {\n    opacity: 0.5,\n    '\u0026:hover': {\n      opacity: 1,\n    },\n  }\n\n  static spacedStyles = {\n    margin: [0, 5],\n    borderRightWidth: 1,\n  }\n\n  static theme = (props, theme) =\u003e {\n    // sizes\n    const height = props.size * LINE_HEIGHT\n    const width = props.width\n    const padding =\n      typeof props.padding !== 'undefined'\n        ? props.padding\n        : props.wrapElement ? 0 : [0, height / 4]\n    const fontSize = props.fontSize || height * 0.5\n    const flex = props.flex === true ? 1 : props.flex\n\n    // radius\n    const baseBorderRadius = props.borderRadius\n      ? props.borderRadius\n      : height / 5\n    const borderRadius = props.circular\n      ? height\n      : baseBorderRadius || height / 10\n\n    // colors\n    const background =\n      props.background || theme.base.background || 'transparent'\n    const borderColor = props.borderColor || theme.base.borderColor\n    const color = props.highlight\n      ? props.highlightColor || theme.highlight.color || props.color\n      : props.active ? theme.active.color : props.color || theme.base.color\n    const hoverColor =\n      (props.highlight \u0026\u0026 $(color).lighten(0.2)) ||\n      props.hoverColor ||\n      theme.hover.color ||\n      (props.color \u0026\u0026 $(props.color).lighten(0.2))\n    const iconColor = props.iconColor || color\n    const iconHoverColor = props.iconHoverColor || hoverColor\n\n    const segmentStyles = props.inSegment \u0026\u0026 {\n      marginLeft: -1,\n      borderLeftRadius: props.inSegment.first ? borderRadius : 0,\n      borderRightRadius: props.inSegment.last ? borderRadius : 0,\n    }\n    const circularStyles = props.circular \u0026\u0026 {\n      padding: 0,\n      width: height,\n      borderRadius: props.size * LINE_HEIGHT,\n      overflow: 'hidden',\n    }\n    return {\n      element: {\n        ...props.elementStyles,\n        fontSize,\n        lineHeight: '1px',\n        color,\n        '\u0026:hover': {\n          color: hoverColor,\n        },\n      },\n      surface: {\n        height,\n        width,\n        flex,\n        padding,\n        borderRadius,\n        borderColor,\n        background,\n        ...circularStyles,\n        ...segmentStyles,\n        ...(props.inline \u0026\u0026 this.constructor.surfaceStyle),\n        ...(props.disabled \u0026\u0026 this.constructor.disabledStyle),\n        ...(props.dim \u0026\u0026 this.constructor.dimStyle),\n        ...(props.spaced \u0026\u0026 this.constructor.spacedStyle),\n        ...(props.chromeless \u0026\u0026 {\n          borderWidth: 0,\n        }),\n        '\u0026 \u003e icon': {\n          color: iconColor,\n        },\n        '\u0026:hover \u003e icon': {\n          color: iconHoverColor,\n        },\n        '\u0026:hover': {\n          ...theme.hover,\n        },\n        // this is just onmousedown\n        '\u0026:active': {\n          position: 'relative',\n          zIndex: 1000,\n        },\n        // inForm\n        ...(props.inForm \u0026\u0026 {\n          '\u0026:active': theme.active,\n          '\u0026:focus': theme.focus,\n        }),\n      },\n    }\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmotion%2Fgloss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmotion%2Fgloss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmotion%2Fgloss/lists"}