Tempest

Tempest #

  • On-request dynamic styles utility-based framework
  • CSS, JS, Fonts manager
  • API inspired by TailwindCSS
  • Classes and their styles are cached

Config #

  • Tempest uses global config and sync.Map to store classes, so you need to configure it before app config initialization

Advice

  • Init Tempest Config in same file as an app config
func init() {
	tempest.GlobalConfig = &tempest.Config{
		// App font family
		FontFamily: "Sora, sans-serif",
		// Aditional fonts
		Font: map[string]tempest.Font{
			"sora": {
				Value: "Sora, sans-serif",
				Url:   "https://fonts.googleapis.com/css2?family=Sora:[email protected]&display=swap",
			},
		},
		// Additional styles, which will be bundled
		Styles: []string{},
		// Scripts to bundle
		Scripts: []string{},
		// Custom colors
		Color: map[string]tempest.Color{
			palette.Primary: palette.PrimaryPallete,
		},
		// Custom shadows
		Shadow: map[string][]tempest.Shadow{
			"focus": {
				{
					Value: "0 0 0 0.25rem",
					Hex: palette.PrimaryPallete[400], 
					Opacity: 15,
				},
			},
		},
	}
	tempest.Start()
}

Start #

Process and prepare all necessary things to provide frontend assets

Assets providing #

By default, Hiro has routes for dynamic Tempest content, so you don’t need to worry about that

Class #

  • tempest.Class() is factory, which create gox.Node class element or string
  • Use methods chaining to apply all classes, you want to

Warning

  • Not all classes have been implemented yet
Div(
	tempest.Class().P(1).M(1).TextSlate(900).TextWhite(tempest.Dark())
),

Component Action #

  • If you use tempest.Class() in smart component action response, you have to add .Name(c.Request().Action())
  • Actions are dynamic and Tempest doesn’t use request context, so they are stored by action name
  • Not cached classes are dynamically added to response
tempest.Class().Name(c.Request().Action()).BgSlate(100).P(4)

Modifier #

Placeholder #

tempest.Class().TextSlate(900).TextSlate(400, tempest.Placeholder())

Dark #

Classes with Dark() modifier will be used, if any parent has dark class

tempest.Class().BgWhite().BgSlate(900, tempest.Dark())

Advice

  • You can store dark mode in cookies and use dark in body class
Body(
	Clsx{
      tempest.Class().Dark(): c.Cookie.Get("X-Dark-Mode") == "true",
    }
)

Hover #

tempest.Class().BgSlate(400).BgBlue(400, tempest.Hover())

Focus #

tempest.Class().Border(1).BorderSlate(300).BorderBlue(400, tempest.Focus())

Checked #

tempest.Class().
    BgWhite().BgBlue(400, tempest.Checked())
    Border(1).BorderSlate(300).BorderBlue(400, tempest.Checked())

Peer #

tempest.Class().
    BgWhite().BgBlue(400, tempest.Checked(tempest.Peer))
    Border(1).BorderSlate(300).BorderBlue(400, tempest.Checked(tempest.Peer))

Group #

tempest.Class().BgWhite().BgBlue(400, tempest.Hover(tempest.Group))

Opacity #

tempest.Class().BgSlate(900, tempest.Opacity(80))

Media query #

tempest.Class().
    W(4).
    W(8, tempest.Xs()).
    W(12, tempest.Sm()).
    W(16, tempest.Md()).
    W(24, tempest.Lg()).
    W(32, tempest.Xl()).
    W(64, tempest.Xxl())