Skip to content

atomic-css major refactor! Please Review. Fixes #17 #21

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dist-newstyle
node_modules
Session.vim
dist
.DS_Store
tags
Expand Down
23 changes: 15 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,43 @@
# Revision history for web-view
# Revision history for atomic-css

## 0.7.0
## atomic-css 0.1.0

Renamed library to atomic-css with a focus on css utilities. View, Url and other Hyperbole-specific types moved to Hyperbole. Still provides an Html monad

Major rewrite of Library and API
* New interface with operators: (@) for attributes, (~) to utilities
* Defining custom CSS selectors and new utilities is more intuitive

## web-view 0.7.0

* stack, popup, offset, layer - more intuitive interface
* added Web.View.Url.renderPath
* Style class
* added code, lists

## 0.6.0
## web-view 0.6.0

* stack - layout children on top of each other
* ChildCombinator: apply styles to direct children
* `Mod` is now `Mod context`, allowing for type-safe `Mod`s
* fixed: escaping in auto-generated `<style>`
* Refactored: selectors and rendering

## 0.5.0
## web-view 0.5.0

* Rendering improvements
* extClass to add external css class
* inline elements
* Url: no longer lowercases automatically. Show/Read instance
*

## 0.4.0
## web-view 0.4.0

* Added new Mods. Length type. Improved Url type

## 0.3.1
## web-view 0.3.1

* Cleanup. Refactored Mods

## 0.2.3 -- 2023-11-27
## web-view 0.2.3 -- 2023-11-27

* First version. Released on an unsuspecting world.
24 changes: 24 additions & 0 deletions DELETEME.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

OK, so....

hover needs to work with multiple classes:
=> hover (bg Green <> color Red)

but overriding selectors needs to work in a sane way
-- use a monadic bind?
-- this sure looks like one!
setSelector $ \this $ a |> b >> this

-- they don't have to be directly serializable
-- they could be functions!

bg Green => {bg-green}
hover (bg Green) => \sel -> sel ': "hover"


-- I like the new stuff. Now you can't do setSelector (placeholder "woot")


Ok ok ok ... so... selector...


114 changes: 63 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,100 +1,112 @@
Web View
Atomic CSS
============

[![Hackage](https://img.shields.io/hackage/v/web-view.svg)][hackage]
[![Hackage](https://img.shields.io/hackage/v/atomic-css.svg)][hackage]

Type-safe, composable CSS utility functions. Inspired by Tailwindcss and Elm-UI

Type-safe HTML and CSS with intuitive layout and composable styles. Inspired by Tailwindcss and Elm-UI

### Write Haskell instead of CSS

Type-safe utility functions to generate styled HTML.
Style your html with composable CSS utility functions:

```haskell
myPage = col (gap 10) $ do
el (bold . fontSize 32) "My page"
button (border 1) "Click Me"
el ~ bold . pad 8 $ "Hello World"
```

This renders as the following HTML with embedded CSS utility classes:

```html
<style type='text/css'>
.bold { font-weight:bold }
.p-8 { padding:0.500rem }
</style>

<div class='bold p-8'>Hello World</div>
```

Leverage the full power of Haskell functions for reuse, instead of relying on CSS.
Instead of relying on the fickle cascade, factor and compose styles with the full power of Haskell functions!

```haskell
header = bold
h1 = header . fontSize 32
h2 = header . fontSize 24
page = gap 10
page = flexCol . gap 10 . pad 10

myPage = col page $ do
el h1 "My Page"
...
example = el ~ page $ do
el ~ h1 $ "My Page"
el ~ h2 $ "Introduction"
el "lorem ipsum..."
```

This approach is inspired by Tailwindcss' [Utility Classes](https://tailwindcss.com/docs/utility-first)
This approach is inspired by Tailwindcss' [Utility Classes](https://tailwindcss.com/docs/styling-with-utility-classes)


### Intuitive Layouts
### Intuitive Flexbox Layouts

Easily create layouts with `row`, `col`, `grow`, and `space`
Create complex layouts with `row`, `col`, `grow`, and `space`

```haskell
holygrail :: View c ()
holygrail = layout id $ do
row section "Top Bar"
row grow $ do
col section "Left Sidebar"
col (section . grow) "Main Content"
col section "Right Sidebar"
row section "Bottom Bar"
where section = 'border' 1
holygrail = do
col ~ grow $ do
row "Top Bar"
row ~ grow $ do
col "Left Sidebar"
col ~ grow $ "Main Content"
col "Right Sidebar"
row "Bottom Bar"
```

### Embedded CSS

Views track which styles are used in any child node, and automatically embed all CSS when rendered.

>>> renderText $ el bold "Hello"

<style type='text/css'>.bold { font-weight:bold }</style>
<div class='bold'>Hello</div>


### Stateful Styles

We can apply styles when certain states apply. For example, to change the background on hover:
We can apply utilities when certain states apply. For example, to change the background on hover:

```haskell
button (bg Primary . hover (bg PrimaryLight)) "Hover Me"
button ~ bg Primary . hover (bg PrimaryLight) $ "Hover Me"
```

Media states allow us to create responsive designs

```haskell
el (width 100 . media (MinWidth 800) (width 400))
el ~ width 100 . media (MinWidth 800) (width 400) $ do
"Big if window > 800"
```


### Embedded CSS

Only the utilities used in a given html fragment are rendered:

>>> renderText $ el ~ bold $ "Hello"

<style type='text/css'>.bold { font-weight:bold }</style>
<div class='bold'>Hello</div>


### Try Example Project with Nix

If you want to get a feel for web-view without cloning the project run `nix run github:seanhess/web-view` to run the example webserver locally
If you want to get a feel for atomic-css without cloning the project run `nix run github:seanhess/atomic-css` to run the example webserver locally

Import Flake
------------

You can import this flake's overlay to add `web-view` to `overriddenHaskellPackages` and which provides a ghc966 and ghc982 package set that satisfy `web-view`'s dependencies.
You can import this flake's overlay to add `atomic-css` to `overriddenHaskellPackages` and which provides a ghc966 and ghc982 package set that satisfy `atomic-css`'s dependencies.

```nix
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
web-view.url = "github:seanhess/web-view"; # or "path:/path/to/cloned/web-view";
atomic-css.url = "github:seanhess/atomic-css"; # or "path:/path/to/cloned/atomic-css";
flake-utils.url = "github:numtide/flake-utils";
};

outputs = { self, nixpkgs, web-view, flake-utils, ... }:
outputs = { self, nixpkgs, atomic-css, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs {
inherit system;
overlays = [ web-view.overlays.default ];
overlays = [ atomic-css.overlays.default ];
};
haskellPackagesOverride = pkgs.overriddenHaskellPackages.ghc966.override (old: {
overrides = pkgs.lib.composeExtensions (old.overrides or (_: _: { })) (hfinal: hprev: {
Expand All @@ -104,7 +116,7 @@ You can import this flake's overlay to add `web-view` to `overriddenHaskellPacka
in
{
devShells.default = haskellPackagesOverride.shellFor {
packages = p: [ p.web-view ];
packages = p: [ p.atomic-css ];
};
}
);
Expand All @@ -116,16 +128,16 @@ Local Development

### Recommended ghcid command

If you want to work on both the web-view library and example code, this `ghcid` command will run and reload the examples server as you change any non-testing code.
If you want to work on both the atomic-css library and example code, this `ghcid` command will run and reload the examples server as you change any non-testing code.

```
ghcid --command="cabal repl exe:example lib:web-view" --run=Main.main --warnings --reload=./embed/preflight.css
ghcid --command="cabal repl exe:example lib:atomic-css" --run=Main.main --warnings --reload=./embed/preflight.css
```

If you want to work on the test suite, this will run the tests each time any library code is changed.

```
ghcid --command="cabal repl test lib:web-view" --run=Main.main --warnings --reload=./embed/preflight.css
ghcid --command="cabal repl test lib:atomic-css" --run=Main.main --warnings --reload=./embed/preflight.css
```

### Nix
Expand All @@ -136,7 +148,7 @@ ghcid --command="cabal repl test lib:web-view" --run=Main.main --warnings --relo
- `nix run .#ghc966-example` to start the example project with GHC 9.6.6
- `nix develop` or `nix develop .#ghc982-shell` to get a shell with all dependencies installed for GHC 9.8.2.
- `nix develop .#ghc966-shell` to get a shell with all dependencies installed for GHC 9.6.6.
- `nix build`, `nix build .#ghc982-web-view` and `nix build .#ghc966-web-view` builds the library with the `overriddenHaskellPackages`
- `nix build`, `nix build .#ghc982-atomic-css` and `nix build .#ghc966-atomic-css` builds the library with the `overriddenHaskellPackages`
- If you want to import this flake, use the overlay
- `nix flake update nixpkgs` will update the Haskell package sets and development tools

Expand Down Expand Up @@ -165,15 +177,15 @@ Learn More
----------

View Documentation on [Hackage][hackage]
* https://hackage.haskell.org/package/web-view
* https://hackage.haskell.org/package/atomic-css

View on Github
* https://github.com/seanhess/web-view
* https://github.com/seanhess/atomic-css

View [Examples](https://github.com/seanhess/web-view/blob/latest/example/app/Main.hs)
View [Examples](https://github.com/seanhess/atomic-css/blob/latest/example/app/Main.hs)


[hackage]: https://hackage.haskell.org/package/web-view
[hackage]: https://hackage.haskell.org/package/atomic-css


Contributors
Expand Down
Loading
Loading