Skip to content

Instantly share code, notes, and snippets.

@samsartor
Last active January 6, 2024 01:29
Show Gist options
  • Save samsartor/1b1c45d0966b911dafc5a71f6a8b14f5 to your computer and use it in GitHub Desktop.
Save samsartor/1b1c45d0966b911dafc5a71f6a8b14f5 to your computer and use it in GitHub Desktop.
import Browser
import Html exposing (Html, Attribute, div, input, text, button)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput, onClick)
import Dict exposing (Dict)
main =
Browser.sandbox { init = init, update = update, view = view }
-- MODEL
type alias Material =
{ name : String
}
type alias Model =
{ materials : Dict Int Material
, nextuid : Int
, favorite : Maybe Int
}
init : Model
init =
{ materials = Dict.fromList
[ (0, { name = "Foo"})
, (1, { name = "Bar"})
]
, nextuid = 2
, favorite = Nothing
}
-- UPDATE
type Msg
= ChangeMaterialName Int String
| AddMaterial
| RemoveMaterial Int
| FavoriteMaterial (Maybe Int)
update : Msg -> Model -> Model
update msg model =
case msg of
ChangeMaterialName uid name ->
{ model
| materials = Dict.update uid (\maybemat -> case maybemat of
Just mat -> Just { mat | name = name }
Nothing -> Nothing
) model.materials
}
AddMaterial ->
{ model
| nextuid = model.nextuid + 1
, materials = Dict.insert model.nextuid { name = "Unnamed" } model.materials
}
RemoveMaterial uid ->
{ model
| materials = Dict.remove uid model.materials
}
FavoriteMaterial uid ->
{ model | favorite = uid }
-- VIEW
viewMaterial : Model -> Int -> Material -> Html Msg
viewMaterial model uid mat =
div []
[ text "Material: "
, input
[ type_ "text"
, value mat.name
, class "edit"
, onInput (ChangeMaterialName uid)
]
[]
, ( case model.favorite == Just uid of
True -> button
[ onClick (FavoriteMaterial Nothing) ]
[ text "★" ]
False -> button
[ onClick (FavoriteMaterial (Just uid)) ]
[ text "☆" ]
)
, button
[ onClick (RemoveMaterial uid) ]
[ text "✖" ]
]
viewFavoriteMaterial : Int -> Material -> Html Msg
viewFavoriteMaterial uid mat =
div []
[ text "Favorite: "
, input
[ type_ "text"
, value mat.name
, class "edit"
, onInput (ChangeMaterialName uid)
]
[]
]
viewFavoriteMaterialId : Model -> Int -> Maybe (Html Msg)
viewFavoriteMaterialId model uid =
Dict.get uid model.materials
|> Maybe.map (viewFavoriteMaterial uid)
view : Model -> Html Msg
view model =
div [] ( List.concat
[ [ button
[ onClick AddMaterial ]
[ text "✚" ]
]
, ( model.materials
|> Dict.map (viewMaterial model)
|> Dict.values
)
, ( case Maybe.andThen (viewFavoriteMaterialId model) model.favorite of
Just v -> [v]
Nothing -> [] )
] )
<script>
import { writable } from 'svelte/store';
let materials = [
{ 'name': 'Foo' },
{ 'name': 'Bar' },
];
let favorite = null;
</script>
<button on:click={
() => materials = [...materials, { 'name': 'Unnamed'}]
}>✚</button>
{#each materials as mat}
<div>
Material:
<input type="text" bind:value={mat.name}/>
{#if favorite === mat}
<button on:click={() => favorite = null}>★</button>
{:else}
<button on:click={() => favorite = mat}>☆</button>
{/if}
<button on:click={
() => materials = materials.filter(m => m !== mat)
}>✖</button>
</div>
{/each}
{#if favorite !== null }
Favorite:
<input type="text" bind:value={favorite.name} on:input={
() => materials = materials
}/>
{/if}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment