Source: BlazeUI.js

import { Styles } from './lib/Styles'
import { Attributes } from './lib/Attributes'
import { Theme } from './lib/Theme'
import { State } from './lib/State'
import { UIComponent } from './lib/UIComponent'
import * as types from './utils/types'
import { toObject } from './utils/toObject'

/**
 * A UI component system for Meteor-Blaze and TailwindCSS.
 * Register and extend Tailwind-based UI Components in Blaze.
 *
 * This object can also be accessed inside methods, such as
 * `attributes`, where it is passed as `api` parameter.
 *
 * @example
 * <template name="Hoverable">
 *   <div {{blazeui_atts}}>
 *     {{> Template.contentBlock}}
 *   </div>
 * </template>
 *
 *
 * @example
 * import { BlazeUI } from 'meteor/blazeui:core'
 * import './Hoverable.html'
 *
 * BlazeUI.register({
 *   name: 'Hoverable',
 *   class: 'bg-transparent hover:bg-primary text-foreground hover:text-primary-foreground'
 * })
 *
 * @namespace
 */
export const BlazeUI = {}

/**
 * Registers one or many new {Component} definitions.
 * @param values {UIComponent[]}
 */
BlazeUI.register = (...values) => values.map(register)

/**
 * @private
 * @param ctx {UIComponent}
 * @return {UIComponent}
 */
const register = (ctx) => {
  const component = new UIComponent(ctx)
  Attributes.register(component)
  Styles.create(component)
  return component
}

/**
 * Add/update variants of a given UIComponent context.
 * @param ctx {UIComponent}
 * @param type {string}
 * @param values {object=}
 * @param defaultValue {string=}
 */
BlazeUI.variants = ({ ctx, type, values, default: defaultValue }) => {
  if (values && ctx.variants) {
    // add a new category to existing variant
    if (type in ctx.variants) {
      const target = ctx.variants[type]
      Object.assign(target, values)
      Styles.create(ctx)
    }
    // add a whole new variant category
    else {
      ctx.variants[type] = values
    }
  }

  // optionally set the default for the given variant
  if (defaultValue) {
    ctx.defaultVariants[type] = defaultValue
  }
}

/**
 * Returns the global Attributes resolver implementation
 * @return {Attributes}
 */
BlazeUI.attributes = () => Attributes

/**
 * Returns the global Styles resolver implementation
 * @return {Styles}
 */
BlazeUI.styles = () => Styles

/**
 * Returns the global Theme resolver implementation
 * @return {Theme}
 */
BlazeUI.theme = () => Theme

/**
 * Returns the global shared-State resolver implementation
 * @return {State}
 */
BlazeUI.state = () => State

Object.assign(BlazeUI, types, { toObject })