🐣
This commit is contained in:
commit
22ae65c92f
8 changed files with 188 additions and 0 deletions
13
README.md
Normal file
13
README.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Skog
|
||||||
|
|
||||||
|
Multiplatform mobile and desktop app framework for [Gren](https://gren-lang.org/).
|
||||||
|
|
||||||
|
## Technical notes and references
|
||||||
|
|
||||||
|
* Original design plan at ~/projects/gren-multiplatform-experiment/gren-multiplatform.md
|
||||||
|
* Proof of concept for iOS at ~/projects/gren-mobile-experiment
|
||||||
|
* Driving initial implementation via ~/projects/idlegame-gren
|
||||||
|
|
||||||
|
## Other stuff
|
||||||
|
|
||||||
|
Skog is Norwegian for "forrest" :)
|
||||||
5
devbox.json
Normal file
5
devbox.json
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
"gren@0.6.5"
|
||||||
|
]
|
||||||
|
}
|
||||||
20
gren.json
Normal file
20
gren.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"platform": "browser",
|
||||||
|
"name": "blaix/skog",
|
||||||
|
"summary": "Framework for Gren apps that run on mobile, desktop, and web.",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"exposed-modules": [
|
||||||
|
"Skog",
|
||||||
|
"UI",
|
||||||
|
"UI.Attribute",
|
||||||
|
"Mobile",
|
||||||
|
"Desktop"
|
||||||
|
],
|
||||||
|
"gren-version": "0.6.0 <= v < 0.7.0",
|
||||||
|
"dependencies": {
|
||||||
|
"gren-lang/core": "7.0.0 <= v < 8.0.0",
|
||||||
|
"gren-lang/browser": "6.0.0 <= v < 7.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/Desktop.gren
Normal file
8
src/Desktop.gren
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
module Desktop exposing (Desktop)
|
||||||
|
|
||||||
|
{-| Phantom-type tag for desktop-specific UI elements and views.
|
||||||
|
-}
|
||||||
|
|
||||||
|
|
||||||
|
type Desktop
|
||||||
|
= Desktop
|
||||||
8
src/Mobile.gren
Normal file
8
src/Mobile.gren
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
module Mobile exposing (Mobile)
|
||||||
|
|
||||||
|
{-| Phantom-type tag for mobile-specific UI elements and views.
|
||||||
|
-}
|
||||||
|
|
||||||
|
|
||||||
|
type Mobile
|
||||||
|
= Mobile
|
||||||
33
src/Skog.gren
Normal file
33
src/Skog.gren
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
module Skog exposing (Program, program)
|
||||||
|
|
||||||
|
{-| Define a multi-platform Skog program.
|
||||||
|
|
||||||
|
The app provides shared `init`, `update`, and `subscriptions` along with
|
||||||
|
separate `mobileView` and `desktopView` functions. Bridges (SwiftUI,
|
||||||
|
Compose, DOM) consume the views; this stub just wires up a Platform.worker.
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Desktop exposing (Desktop)
|
||||||
|
import Mobile exposing (Mobile)
|
||||||
|
import Platform
|
||||||
|
import UI
|
||||||
|
|
||||||
|
|
||||||
|
type alias Program model msg =
|
||||||
|
Platform.Program {} model msg
|
||||||
|
|
||||||
|
|
||||||
|
program :
|
||||||
|
{ init : { model : model, command : Cmd msg }
|
||||||
|
, update : msg -> model -> { model : model, command : Cmd msg }
|
||||||
|
, subscriptions : model -> Sub msg
|
||||||
|
, mobileView : model -> UI.Element Mobile msg
|
||||||
|
, desktopView : model -> UI.Element Desktop msg
|
||||||
|
}
|
||||||
|
-> Program model msg
|
||||||
|
program config =
|
||||||
|
Platform.worker
|
||||||
|
{ init = \_ -> config.init
|
||||||
|
, update = config.update
|
||||||
|
, subscriptions = config.subscriptions
|
||||||
|
}
|
||||||
82
src/UI.gren
Normal file
82
src/UI.gren
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
module UI exposing
|
||||||
|
( Element
|
||||||
|
, text
|
||||||
|
, column
|
||||||
|
, row
|
||||||
|
, button
|
||||||
|
, image
|
||||||
|
)
|
||||||
|
|
||||||
|
{-| Cross-platform UI primitives.
|
||||||
|
|
||||||
|
The `platform` type parameter stays polymorphic for elements that work
|
||||||
|
everywhere. Platform-specific elements live in the `Mobile` and `Desktop`
|
||||||
|
modules and constrain the parameter.
|
||||||
|
-}
|
||||||
|
|
||||||
|
import UI.Attribute exposing (Attribute)
|
||||||
|
|
||||||
|
|
||||||
|
type Element platform msg
|
||||||
|
= Text
|
||||||
|
{ attributes : Array (Attribute platform msg)
|
||||||
|
, content : String
|
||||||
|
}
|
||||||
|
| Column
|
||||||
|
{ attributes : Array (Attribute platform msg)
|
||||||
|
, children : Array (Element platform msg)
|
||||||
|
}
|
||||||
|
| Row
|
||||||
|
{ attributes : Array (Attribute platform msg)
|
||||||
|
, children : Array (Element platform msg)
|
||||||
|
}
|
||||||
|
| Button
|
||||||
|
{ attributes : Array (Attribute platform msg)
|
||||||
|
, onPress : msg
|
||||||
|
, label : Element platform msg
|
||||||
|
}
|
||||||
|
| Image
|
||||||
|
{ attributes : Array (Attribute platform msg)
|
||||||
|
, source : String
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
text : Array (Attribute platform msg) -> String -> Element platform msg
|
||||||
|
text attributes content =
|
||||||
|
Text { attributes = attributes, content = content }
|
||||||
|
|
||||||
|
|
||||||
|
column :
|
||||||
|
Array (Attribute platform msg)
|
||||||
|
-> Array (Element platform msg)
|
||||||
|
-> Element platform msg
|
||||||
|
column attributes children =
|
||||||
|
Column { attributes = attributes, children = children }
|
||||||
|
|
||||||
|
|
||||||
|
row :
|
||||||
|
Array (Attribute platform msg)
|
||||||
|
-> Array (Element platform msg)
|
||||||
|
-> Element platform msg
|
||||||
|
row attributes children =
|
||||||
|
Row { attributes = attributes, children = children }
|
||||||
|
|
||||||
|
|
||||||
|
button :
|
||||||
|
Array (Attribute platform msg)
|
||||||
|
-> { onPress : msg, label : Element platform msg }
|
||||||
|
-> Element platform msg
|
||||||
|
button attributes config =
|
||||||
|
Button
|
||||||
|
{ attributes = attributes
|
||||||
|
, onPress = config.onPress
|
||||||
|
, label = config.label
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
image :
|
||||||
|
Array (Attribute platform msg)
|
||||||
|
-> String
|
||||||
|
-> Element platform msg
|
||||||
|
image attributes source =
|
||||||
|
Image { attributes = attributes, source = source }
|
||||||
19
src/UI/Attribute.gren
Normal file
19
src/UI/Attribute.gren
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
module UI.Attribute exposing (Attribute, padding, backgroundColor)
|
||||||
|
|
||||||
|
{-| Styling attributes for UI elements.
|
||||||
|
-}
|
||||||
|
|
||||||
|
|
||||||
|
type Attribute platform msg
|
||||||
|
= Padding Int
|
||||||
|
| BackgroundColor String
|
||||||
|
|
||||||
|
|
||||||
|
padding : Int -> Attribute platform msg
|
||||||
|
padding amount =
|
||||||
|
Padding amount
|
||||||
|
|
||||||
|
|
||||||
|
backgroundColor : String -> Attribute platform msg
|
||||||
|
backgroundColor color =
|
||||||
|
BackgroundColor color
|
||||||
Loading…
Add table
Add a link
Reference in a new issue