์๋ ํ์ญ๋๊น,
์ด ๋ฌธ์ ๋ Feliz ๋ฐ Feliz.Bulma์์ ๊ฒฝํ์ ๊ณต์ ํ๊ธฐ ์ํ ๊ฒ์ ๋๋ค.
์ด ํผ๋๋ฐฑ์ Fable Repl์ Fable.React + Fulma ์์ Feliz + Feliz.Bulma ๋ก ๋ณํํ๋ ๊ฒ์ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค.
์ฒซ ๋ฒ์งธ ์น์ ์์๋ Feliz๋ฅผ ์ฌ์ฉํ ๋ ์ข์ํ๊ฑฐ๋ ๋ฌธ์ ๊ฐ ์์๋ ๋ชจ๋ ํญ๋ชฉ์ ๋์ดํฉ๋๋ค. ๋๋ Fable.React์ Fulma์ ๋ํด ๋น์ทํ ์ผ์ ํ ๊ฒ์ ๋๋ค. ์๋ํ๋ฉด ๊ทธ๋ค์ ์ข์ ๋ถ๋ถ๊ณผ ๋ ์ข์ ๋ถ๋ถ์์ ๋ฉด์ ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋ฐ ๋ค์ ๋ ๋ฒ์งธ ์๊ฐ์ Feliz์ Feliz.Bulma์์ ๊ฒฝํ์ด ์ด๋ ๋์ง ์ค๋ช ํ๋ ค๊ณ ํฉ๋๋ค. ๋ชฉํ๋ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ด ๊ด์ ์ด ์ด๋ป๊ฒ ๋ณํ๊ณ ๊ทธ ์ด์ ๋ฅผ ๊ณต์ ํ๋ ๊ฒ์ ๋๋ค.
์ค์ํ
๋๋ ๋ด๊ฐ ๋ถ์ํ๋ ์ฃผ์ ๊ฐ ๋ฏผ๊ฐํ๊ณ ๋๋ฅผ ๋๋ ต๊ฒ ํ๋ ๋์์ด๋ผ๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์๊ฒฌ ์น์ ์ ๊ธ์ ์ ์ผ๋ก ์ ์งํ๋ ๊ฒ์ ์์ง ๋ง์ญ์์ค.
ํผ๋๋ฐฑ์ ์ ๋ฆฌํ ๋ฐฉ๋ฒ์ ์ฐพ์ผ๋ ค๊ณ ๋ ธ๋ ฅํ์ง๋ง ๊ณ ์ ์ ์ธ "์ฅ๋จ์ "์ด ๋๋ฌด ์ ํ์ ์ด๊ณ ๊ณต๊ฒฉ์ ์ผ๋ก ๋๊ปด์ก์ต๋๋ค.
๋์ ๊ธฐํธ๋ฅผ ์ฌ์ฉํ๊ฒ ์ต๋๋ค.
๋์ผํ ํญ๋ชฉ์ ์ฌ๋ฌ ๊ธฐํธ๊ฐ ์์ ์ ์์ต๋๋ค. :)
โ๏ธ Feliz๋ Fable.React ์์ Feliz๊ฐ ๋ ์ด์ด์ด๊ธฐ ๋๋ฌธ์ Feliz์ Fable.React๋ฅผ ํผํฉํ ์ ์์ต๋๋ค.
โ๏ธ ์ฝ๋๋ Fable.React์ ๋นํด ๋ค์ฌ์ฐ๊ธฐ๊ฐ ๋ ํธํฉ๋๋ค. ๋ชฉ๋ก์ด ํ๋๋ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ํ๋ฅผ ๋ฐ๋ผ๊ฐ์๋ฉด ์ฝ์ต๋๋ค.
์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ญ์์ค
**Fable.React + ํ๋ง**
div [ ]
[ Hero.hero [ Hero.IsFullHeight ]
[ Hero.body [ ]
[ Container.container [ ]
[ img [ Src "img/fable-ionide.png"
Style [ Display DisplayOptions.Block
Width "auto"
Margin "auto" ] ]
br [ ]
Heading.h3 [ Heading.Modifiers [ Modifier.TextAlignment (Screen.All, TextAlignment.Centered) ] ]
[ str "Fable REPL" ]
Heading.p [ Heading.IsSubtitle
Heading.Is5
Heading.Modifiers [ Modifier.TextAlignment (Screen.All, TextAlignment.Centered) ] ]
[ str "is only available on desktop" ] ] ] ] ]
**Feliz + Feliz.Bulma**Html.div [
Bulma.hero [
hero.isFullHeight
prop.children [
Bulma.heroBody [
Bulma.container [
Html.img [
prop.src "img/fable-ionide.png"
prop.style [
style.display.block
style.width length.auto
style.margin length.auto
]
]
Html.br [ ]
Bulma.title3 [
text.hasTextCentered
prop.text "Fable REPL"
]
Bulma.subtitle5 [
text.hasTextCentered
prop.text "is only available on desktop"
]
]
]
]
]
]
โ๏ธ ์ด์ ํฌ์ธํธ ๋๋ถ์ ์ฝ๋๋ฅผ ์ฝ๊ฒ ์ด๋ํ ์ ์์ต๋๋ค.
โ๏ธ DOM ์์ฑ์ ์ํ ๊ฐ๋ ฅํ ํ์์ API
โ๏ธ ICSSUnits
๋ฅผ ํตํ CSS ๋ฐ CSS ๋จ์์ ๋ํ ๊ฐ๋ ฅํ ํ์์ API
style.marginLeft (length.em 0.5)
style.width (length.percent (model.PanelSplitRatio * 100.))
โ๏ธ ์ปจํ
์คํธ๋ฅผ ์ค์ผ์ํค์ง ์์ผ๋ฉฐ ๋๋ถ๋ถ์ ํญ๋ชฉ์ด Html.*
๋๋ Prop.*
๋ฏธ๋ง์
๋๋ค.
โ๏ธ โ ๏ธ Feliz๋ ์ฝ๋์์ ๋ ธ์ด์ฆ๋ฅผ ํผํ ์ ์๋ ๊ฐ๋ฅ์ฑ์ ์ ๊ณตํฉ๋๋ค.
์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ญ์์ค
Html.span "Fable REPL"
// instead of
// Feliz verbose version
span [
str "Fable REPL"
]
// Fable.React
span [ ]
[ str "Fable REPL" ]
// --------------------
Bulma.title4 "Fable REPL"
// instead of
// Feliz.Bulma verbose version
Bulma.title4 [
prop.text "Fable REPL"
]
// Fable.React
Headings.h4 [ ]
[ str "Fable REPL" ]
๋์ผํ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ฝ๋๋ฅผ "์ฝ์ ์" ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ๋๋๋ก ์ธ๋ถ ๋งฅ๋ฝ์ ์ดํดํ๊ธฐ ์ํด ํ ๋ฐ ๋ฌผ๋ฌ์์ผ ํฉ๋๋ค. ์ด๊ฒ์ ๋ํ ๋ชจ๋ ๊ฒ์ด ๊ฐ์ ๋ฐฉ์์ผ๋ก ์์ฑ๋์ง ์๊ธฐ ๋๋ฌธ์ ์ฝ๋๋ฅผ ๋ "์ผ๊ด๋๊ฒ" ๋ง๋ญ๋๋ค.Html.tr [
Html.th "Steps"
Html.th [
prop.className "has-text-right"
prop.text "ms"
]
]
โ ๏ธ (์์ง) SSR์ ์ง์ํ์ง ์์ต๋๋ค
โ ๏ธ ๋ฉ์๋/์์ฑ ๊ณผ๋ถํ๋ฅผ ๋ฐ๊ฒฌํ๋ ๊ฒ์ ์ฝ์ง ์์ต๋๋ค (์ด๊ฒ์ ์๋ง๋ ๋ด๊ฐ ๋ชจ๋ฅด๋ Ionide์ ํ๊ณ์ผ ๊ฒ์ ๋๋ค)
๋๋ํด์ผํ๋ค :
prop.text 2.0
๊ฐ ์ง์๋๋์ง ์ฌ๋ถ๋ฅผ ํ
์คํธํฉ๋๋ค.โ ๏ธ ๋ ์ด์์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋ฐฑ ์ฌ์ฉ์ ๋ ์ด๋ ต๊ฒ ๋ง๋์ธ์. Fable.REPL์์๋ System.Func<_,_,_>
๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์ปค๋ฆฌ๋ฅผ ๊ฐ์ ์คํํด์ผ ํ์ต๋๋ค.
์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ญ์์ค
[<Erase>]
type editor =
/// <summary>Triggered when the Editor has been mounted</summary>
static member inline editorDidMount (f : System.Func<Monaco.Editor.IStandaloneCodeEditor, Monaco.IExports, unit>) = Interop.mkAttr "editorDidMount" f
ํธ์ถ ์ธก์์ ๋ค์ ์ฝ๋๋ฅผ ์ ๊ณตํฉ๋๋ค.let private registerCompileCommand dispatch =
System.Func<_,_,_>(
fun (editor : Monaco.Editor.IStandaloneCodeEditor) (monacoModule : Monaco.IExports) ->
let triggerCompile () = StartCompile None |> dispatch
editor.addCommand(monacoModule.KeyMod.Alt ||| int Monaco.KeyCode.Enter, triggerCompile, "") |> ignore
editor.addCommand(monacoModule.KeyMod.CtrlCmd ||| int Monaco.KeyCode.KEY_S, triggerCompile, "") |> ignore
)
โ๏ธ โ ๏ธ Feliz๋ ์ฌ์ฉ์์ ์ถ์ ์กฐ๊ธ ๋ ์ฝ๊ฒ ๋ง๋ค๊ธฐ ์ํด ๊ณผ๋ถํ๋ฅผ ์ ๊ณตํ์ง๋ง ์ด๊ฒ์ ๋น์ฉ์ด ๋ญ๋๋ค.
prop.onChange
๊ฒฝ์ฐ ๋ฃ๊ณ ์ถ์ ํญ๋ชฉ์ ๋ฐ๋ผ 6๊ฐ์ ์ค๋ฒ๋ก๋๊ฐ ์์ต๋๋ค.
static member inline onChange (handler: bool -> unit)
static member inline onChange (handler: Event -> unit)
static member inline onChange (handler: File -> unit)
static member inline onChange (handler: File list -> unit)
static member inline onChange (handler: string -> unit)
static member inline onCheckedChange (handler: bool -> unit)
์ด๊ฒ์ ์ฌ๋๋ค์ด "no" ์ฌ๋ฏธ์๋ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ๋๋ฌธ์ ์ข์ง๋ง ์๋๋ฐฉ์ ๋ช ์์ ์ผ๋ก ์ํ๋ ์ด๋ฒคํธ ์ ํ์ ๋งํด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค.
// Feliz
prop.onChange (fun (e : Types.Event) -> e.Value |> ChangeGistToken |> dispatch)
// Fable.React
prop.onChange (fun e -> e.Value |> ChangeGistToken |> dispatch)
โ๏ธ โ ๏ธ Feliz ์ํ๊ณ๋ ๋๋ถ๋ถ ์ ํ ์์ ํ์ง๋ง ์๋ชป๋ ์ฝ๋ ์์ฑ์ ๋ฐฉ์งํ์ง๋ ์์ต๋๋ค. Feliz์ Feliz.Bulma์ ๊ฐ์ ํ์ฅ ๊ธฐ๋ฅ ์ค ํ๋๋ฅผ ์ฌ์ฉํ ๋ ์์ฑ์ ์ฝ๊ฒ ํผํฉํ ์ ์์ง๋ง ํ ๋ ์ฃผ์ํด์ผ ํฉ๋๋ค.
์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ญ์์ค
์ด ์ฝ๋๋ Feliz์ F# ์ปดํ์ผ๋ฌ์ ๊ด์ ์์ ๋ณผ ๋ ๊ด์ฐฎ์ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ์์ํ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ์ง๋ ์์ต๋๋ค.
Html.p [
text.isUppercase
text.isItalic
color.hasTextSuccess
prop.text "Hello Feliz"
]
`text.isUppsercase`, `text.isItalic` ๋ฐ `color.hasTextSuccess`๋ ๋ชจ๋ `ClassName "my-css-class`์ ๊ฐ์ ๊ฒ์ ์ถ๋ ฅํฉ๋๋ค. ๊ทธ๋ฌ๋ React์์๋ ๋ง์ง๋ง ํ๋๋ง ํจ๊ณผ๊ฐ ์์ผ๋ฏ๋ก ์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ์ฝ๋๋ ์์ฑํ๋ค:<p class="has-text-success">Hello Feliz<\p>
๋์ ์<p class="is-uppercase is-italic has-text-success>Hello Feliz</p>
์ด์ ๋ํ ํด๊ฒฐ์ฑ
์ Feliz.Bulma์์ ์ ๊ณตํ๋ `++`๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค.open Feliz.Bulma.Operators
Html.p [
text.isUppercase
++ text.isItalic
++ color.hasTextSuccess
prop.text "Hello Feliz"
]
์ด๊ฒ์ ํธํ๋๋ ๊ฒฝ์ฐ "Feliz ์์"์ ๋ค๋ฅธ Feliz ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ค๋ ๋์์ ์ถ๊ฐํ ์ ์์์ ์๋ฏธํ๊ธฐ ๋๋ฌธ์ ์ฌ์ ํ ์ข์ ๊ฐ๋ฅ์ฑ์
๋๋ค. ์ฌ๋๋ค์ ๊ทธ๊ฒ์ ๋ํด ์กฐ์ฌํด์ผํฉ๋๋ค.โน ์ฒ์์๋ Feliz๊ฐ Fable.React๋ฅผ ์ฌ์ฉํ ๋ ์ป์ ์ ์๋ ์คํ ev.Value
๊ตฌ๋ฌธ์ ์ ๊ณตํ์ง ์๋๋ค๊ณ ์๊ฐํ์ง๋ง ๊ทธ๋ ์ง ์์ต๋๋ค.
Fable.React.Extension
๋ ๊ตฌ๋ฌธ ์คํ์ ํธ์คํ
ํ๋ฏ๋ก ๋ชจ๋ Fable.React ํจ์๋ก ์ปจํ
์คํธ๋ฅผ ์ค์ผ์ํค์ง ์๋๋ก ์ด ์ ์์ต๋๋ค.
open Feliz
open Fable.React.Extensions
โน ๊ตฌ๋ฌธ์ HTML ์ฌ๊ณ ๋ฐฉ์์ ์ฌํํ์ง ์์ต๋๋ค. Feliz๋ HTML๋ณด๋ค React API ์์ ์๋ ๊ตฌ๋ฌธ ์คํ์
๋๋ค. Feliz๋ children
๋ ์์ฑ์ด๊ธฐ ๋๋ฌธ์ ์์ฑ์ ๊ด์ ์์ ์๊ฐํฉ๋๋ค.
โ๏ธ Feliz์ ์ ํตํฉ๋จ
โ๏ธ Fulma์ ๋นํด ๋ค์ฌ์ฐ๊ธฐ ์ฉ์ด
์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ญ์์ค
// Fulma
Card.card [ ]
[ Card.header [ Common.Props [ OnClick (fun _ -> ToggleWidget title |> dispatch ) ] ]
[ Card.Header.title [ ]
[ Icon.icon [ Icon.Props [ Style [ MarginRight ".5em" ] ] ]
[ Fa.i [ icon; Fa.Size Fa.FaLarge ] [] ]
str title ]
Card.Header.icon [ ]
[ Icon.icon [ ] [ Fa.i [ headerIcon ; Fa.Size Fa.FaLarge ] [] ] ] ]
ofOption content ]
// Feliz.Bulma
Bulma.card [
Bulma.cardHeader [
prop.onClick (fun _ -> ToggleWidget title |> dispatch )
prop.children [
Bulma.cardHeaderTitle [
Bulma.icon [
prop.style [
style.marginRight (length.em 0.5)
]
prop.children [
Fa.i [ icon; Fa.Size Fa.FaLarge ] []
]
]
Html.text title
]
Bulma.cardHeaderIcon [
Bulma.icon [
Fa.i [ headerIcon ; Fa.Size Fa.FaLarge ] []
]
]
]
]
Html.ofOption content
]
โ๏ธ Bulma
์ ๋์ด ๋๋ถ์ Bulma
๊ตฌ์ฑ ์์๋ฅผ ์ฝ๊ฒ ์๋ณํ ์ ์์ต๋๋ค.
โ๏ธ โ ๏ธ ์์ฑ์ ์ก์ธ์คํ ์ ์์ง๋ง ์ปจํ
์คํธ button.*
, help.*
, columns.*
์ค์ผ์ํต๋๋ค.
์ด๋ก ์ ์ผ๋ก ์ฌ๋๋ค์ ํ๋์ CSS ํ๋ ์์ํฌ๋ง ์ฌ์ฉํด์ผ ํ๋ฏ๋ก button.*
, columns.*
๋ฑ๊ณผ ๊ฐ์ ์ผ๋ฐ ์์ฑ์ ๋ํด ์ถฉ๋์ด ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
โ๏ธ ๊ตฌ์ฑ ์์ ๊ณ์ธต ๊ตฌ์กฐ๋ ํ์ ํ๊ธฐ ์ฝ์ต๋๋ค.
Bulma.card
> Bulma.cardHeader
> Bulma.cardHeaderTitle
์๋ฅผ ๋ค์ด ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ญ์์ค
Bulma.card [
Bulma.cardHeader [
prop.onClick (fun _ -> ToggleWidget title |> dispatch )
prop.children [
Bulma.cardHeaderTitle [
// ...
]
Bulma.cardHeaderIcon [
// ...
]
]
]
]
โ ๏ธ ๊ทธ๋ฌ๋ ์ผ๋ถ ๊ตฌ์ฑ ์์๋ ๋์ผํ ๊ท์น์ ๋ฐ๋ฅด์ง ์์ต๋๋ค.
Bulma.passwordInput
๋์ Bulma.inputPassword
์ด ๊ฒฝ์ฐ ๋์ผํ "์ ๋์ฌ"๋ก ์์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ์ ํ์ ์ ๋ ฅ์ ์ฝ๊ฒ ํ์ํ ์ ์์ต๋๋ค.
โ๏ธ โ ๏ธ Feliz.Bulma๋ฅผ ์ฌ์ฉํ๋ฉด ๊ตฌ์ฑ ์์ ๋์์ ์ฝ๊ฒ ํผํฉํ ์ ์์ต๋๋ค.
์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ญ์์ค
Bulma.button [
// Properties specific to a button coming from Feliz.Bulma
button.isOutlined
// Properties specific to a tooltip coming from Feliz.Bulma
tooltip.hasTooltipRight
tooltip.text tooltipText
// General properties coming from Feliz
prop.disabled isCompiling
prop.onClick (fun _ -> dispatch msg)
prop.children [
Bulma.icon [
icon.isLarge
prop.children faIcon
]
]
]
๋ณด์๋ค์ํผ ๊ธฐ์กด ๊ตฌ์ฑ ์์์ ์ ๋์์ ์ถ๊ฐํ๊ธฐ ์ฝ๊ธฐ ๋๋ฌธ์ ์ข์ต๋๋ค. ์ฌ๊ธฐ์์ ๋ฒํผ์ ๋์ ํดํ์ ์ถ๊ฐํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ๋ํ ๋ค์๊ณผ ๊ฐ์ ์๋ชป๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์์ ์๋ฏธํฉ๋๋ค.Html.select [
select.isFullwidth
]
๋์ ์Bulma.select [
select.isFullwidth
]
Fulma๋ ๊ตฌ์ฑ ์์ ๋ถ๋ฆฌ์ ๋ํด ๋ ์๊ฒฉํ๋ฉฐ `CustomClass` ์ํ์ ํตํด CSS ํด๋์ค๋ฅผ ์ ๋ฌํ์ง ์๋ ํ ๋์์ ํผํฉํ๋ ๊ฒ์ ํ์ฉํ์ง ์์ต๋๋ค.โ๏ธ โ ๏ธ Feliz.Bulma๋ ์ถ๋ ฅํ๋ ค๋ โโHTML ์์๋ฅผ ์ ์ดํ๋ โโ๋ฐฉ๋ฒ์ ์ ๊ณตํ์ง ์์ต๋๋ค.
์๋ฅผ ๋ค์ด Bulma.field
๋ฅผ ์์ฑํ๋ div
์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋๋ก๋ p
์์๊ฐ ์ถ๋ ฅ์ผ๋ก ํ์ํฉ๋๋ค.
โ๏ธ โ ๏ธ Feliz.Bulma๋ Bulma์ ๋ํ ์ ํํ ๋งคํ์ ๋๋ค.
๋ ์ฌํด์ ์ข๋ค์.
๊ทธ๋ฌ๋ ๋ค์์ ์๋ฏธํ๊ธฐ๋ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด, Bulma.tabs
๊ตฌ์ฑ ์์๋ฅผ ์์ฑํ ๋ ์๋ด๋ฅผ ๋ฐ์ง ์๊ณ tabs
๋ ul
๋ค์์ li
์ a
๊ฐ ํ์ํ๋ค๋ ๊ฒ์ ์์์ผ ํฉ๋๋ค a
.
์ฝ๋๋ฅผ ๋ณด๋ ค๋ฉด ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ธ์
// Feliz + Feliz.Bulma
Bulma.tabs [
tabs.isCentered
tabs.isMedium
tabs.isToggle
prop.children [
Html.ul [
Html.li [
if (activeTab = CodeTab.FSharp) then
prop.className "is-active"
prop.onClick (fun _ -> SetCodeTab CodeTab.FSharp |> dispatch)
prop.children [
Html.a [
prop.text "F#"
]
]
]
Html.li [
if (activeTab = CodeTab.Html) then
prop.className "is-active"
prop.onClick (fun _ -> SetCodeTab CodeTab.Html |> dispatch)
prop.children [
Html.a [
prop.text "HTML"
]
]
]
Html.li [
if (activeTab = CodeTab.Css) then
prop.className "is-active"
prop.onClick (fun _ -> SetCodeTab CodeTab.Css |> dispatch)
prop.children [
Html.a [
prop.text "CSS"
]
]
]
]
]
]
Fulma๋ ์ฌ์ฉ์๊ฐ "Bulma ๊ตฌ์ฑ ์์"์ ๊ด์ ์์ ๋ ๋ง์ด ์๊ฐํ ์ ์๋๋ก ํฉ๋๋ค.// Fable.React + Fulma
Tabs.tabs [ Tabs.IsCentered
Tabs.Size Size.IsMedium
Tabs.IsToggle ]
[ Tabs.tab [ Tabs.Tab.IsActive (activeTab = CodeTab.FSharp)
Tabs.Tab.Props [
OnClick (fun _ -> SetCodeTab CodeTab.FSharp |> dispatch)
] ]
[ a [ ] [ str "F#" ] ]
Tabs.tab [ Tabs.Tab.IsActive (activeTab = CodeTab.Html)
Tabs.Tab.Props [
OnClick (fun _ -> SetCodeTab CodeTab.Html |> dispatch)
] ]
[ a [ ] [ str "HTML" ] ]
Tabs.tab [ Tabs.Tab.IsActive (activeTab = CodeTab.Css)
Tabs.Tab.Props [
OnClick (fun _ -> SetCodeTab CodeTab.Css |> dispatch)
] ]
[ a [ ] [ str "CSS" ] ] ]
๋ฉ๋ชจ:
Fulma๋ tab
๋ฅผ ๊ตฌ์ฑ ์์๋ก ๊ฐ์ฃผํ๊ณ Tabs.Tab.*
ํน์ ๋ํผ๋ฅผ ์ ๊ณตํฉ๋๋ค.
Fulma๋ ์ฌ์ ํ a
์์๊ฐ ํ์ํ์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ์ถ๊ฐํ ์ ์์ต๋๋ค(์ผ๋ถ ๊ตฌ์ฑ ์์์ ๊ฒฝ์ฐ).
โ๏ธ โ ๏ธ Feliz.Bulma๋ ์๊ท๋ชจ ํ๋ก์ ํธ์์ ๋ฒ๋ค ํฌ๊ธฐ์ ๋ฏธ์น๋ ์ํฅ์ด ์์ง๋ง ํ๋ก์ ํธ ํฌ๊ธฐ๊ฐ ์ปค์ง์๋ก ๋ ํฐ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
์์ธํ ๋ด์ฉ์ ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ญ์์ค
Fulma๋ Bulma ํด๋์ค๋ฅผ ๋ชจ๋ธ๋งํ๊ธฐ ์ํด ๋ง์ DU๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. [Common.fs](https://github.com/Fulma/Fulma/blob/2f99474cd6c793776001d07da009f7211be2f30c/src/Fulma/Common.fs)์์ ํ์ธํ ์ ์์ต๋๋ค. ๋ํ ๊ฐ ๊ตฌ์ฑ ์์์๋ ๊ณ ์ ํ DU๊ฐ ์์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ Fulma๊ฐ DU๋ฅผ ํด๋์ค๋ก ๋ณํํ๋ 'parseOptions' ํจ์ ํธ์ถ์ ๊ตฌํํด์ผ ํฉ๋๋ค. Feliz.Bulma๋ Bulma ํด๋์ค ์์ DSL์ ์์ฑํ์ง ์๊ณ ํด๋์ค๋ฅผ ์ง์ ์ถ๋ ฅํจ์ผ๋ก์จ ๋ณด๋ค ์ง์ ์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ์ทจํฉ๋๋ค.
// Fulma
Column.column
[
Column.Width (Screen.Desktop, Column.IsHalf)
Column.Width (Screen.Mobile, Column.IsFull)
]
[
// ...
]
// Feliz
Bulma.column [
column.isHalfDesktop
column.isFullMobile
prop.children [
// ...
]
]
ํด๋์ค๋ฅผ ์ง์ ์ฌ์ฉํ๊ณ ์์ฑ ๋ชฉ๋ก์ ์กฐ์ํ ๋๋ถ์ Feliz.Bulma๋ Fulma์ ์ถ๊ฐ๋ ๋ชจ๋ DU ๋ฐ ์ฝ๋์ ๋ํ ํฐ ๋น์ฉ์ด ๋ค์ง ์์ต๋๋ค. ๊ทธ๋ฌ๋ ๋ชจ๋ ํด๋์ค์ "๊ฐ์
"ํ๋ ค๋ฉด ์ฌ์ ํ ์ถ๊ฐ ํจ์ค๊ฐ ํ์ํฉ๋๋ค. ์ด ๋ถ๋ถ์ [Feliz.Bulma.ElementBuilders.Helpers ๋ชจ๋](https://github.com/Dzoukr/Feliz.Bulma/blob/3ecbba1579d2a26281f24e6a6664b5d9c5222603/src/Feliz.Bulma/ElementBuilder)์ ํตํด ์ํ๋ฉ๋๋ค. ์ด๋ฌํ ํจ์๋ ์ธ๋ผ์ธ๋ฉ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํ๋ก์ ํธ๊ฐ ํด์๋ก ์ฝ๋์ ๋ฏธ์น๋ ์ํฅ๋ ์ปค์ง๋๋ค.โ ๏ธ ์๋ก์ด ์์ ์ง์์ ์ถ๊ฐํ๋ ๊ฒ์ ์ฝ์ง ์์ต๋๋ค.
Feliz.Bulma์์ ๊ฐ ๊ตฌ์ฑ ์์๋ button.isWarning
, help.isWarning
๋ฑ๊ณผ ๊ฐ์ ์์ฒด ์์ ๊ตฌํ์ ๋ณด์ ํฉ๋๋ค.
๋ฐ๋ผ์ ์์์ ์ถ๊ฐํ๋ ค๋ฉด button.isMyNewColor
, help.isMyNewColor
๋ชจ๋๋ฅผ ๊ตฌํํด์ผ ํฉ๋๋ค.
Fulma์์๋ ๋ชจ๋ ๊ฐ์ ์์ ์ ํ์ ๊ณต์ ํฉ๋๋ค. ๋ฌธ์ ์ฐธ์กฐ
โ๏ธ ์์ฑ ๋ชฉ๋ก๊ณผ ์์ ๋ชฉ๋ก์ผ๋ก ์๊ฐํ ๋ HTML ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฆ ๋๋ค.
โ ๏ธ ์ด์ค ๋ชฉ๋ก์ ๊ตฌ์ฑํด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ค์ฌ์ฐ๊ธฐ ๊ท์น์ ์ ํ๊ธฐ ์ด๋ ต๊ณ ์ผ๋ฐ์ ์ผ๋ก ์์ธ์ ์ธ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
์์ธํ ์ค๋ช
์ ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ธ์
์์:
// When I want to put an empty div
div [ ] [ ]
// When I want to put a div with a single property
div [ ClassName "button" ] [ ]
// or
div [ ClassName "button" ]
[ ]
// When I want to put a div with several property
div [ ClassName "button"; Id "my-button" ]
[ ]
// yes but what if one of my property is not that simple?
div
[
ClassName "button"
OnClick (fun _ ->
// do something
)
]
[ ]
// It's also possible to have consistent indentation if you do something like that
div [ ] [
// Children 1
// Children 2
]
// But if you have non simple property you still have problems, I don't personally don't find it easy to read
// I am not sure if that's how people would write it because I don't use this format personally
div [
ClassName "button"
OnClick (fun _ ->
// do something
)
] [
div [ ] [
str "Children 1"
]
]
// and so on
์์ฑ ๋ชฉ๋ก์์ ๋ช ๊ฐ์ง ๊ฒฝ์ฐ๋ฅผ ์ฒ๋ฆฌํ ๋ ๋ณผ ์ ์๋ฏ์ด ๋ช ๊ฐ์ง ๊ฐ๋ฅํ ๊ตฌ๋ฌธ์ด ์์ต๋๋ค. ๋ด ํ๋ก์ ํธ์์ ์ผ๊ด๋ ๊ตฌ๋ฌธ์ ์ค์ ํด์ผ ํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒ์
๋๋ค.div
[
// Property 1 ...
// Property 2 ...
// Property 3 ...
]
[
div
[
// Property 1 ...
// Property 2 ...
// Property 3 ...
]
[
// Children 1 ...
// Children 2 ...
// Children 3 ...
]
div
[
// Property 1 ...
// Property 2 ...
// Property 3 ...
]
[
// Children 1 ...
// Children 2 ...
// Children 3 ...
]
]
// So for an empty element
div
[
]
[
]
// Awesome... ๐
Feliz์์ ๋น๊ต๋ฅผ ์ํด ๋ค์์ ์ํํฉ๋๋ค.// Empty div
Html.div [ ]
// Non empty div
Htmldiv [
// Property 1
// Property 2
// Property 3
prop.children [
Html.div [
// Property 1
// Property 2
// Property 3
]
Html.div [
// Property 1
// Property 2
// Property 3
// Complexe property
OnClick (fun _ ->
// Do something
)
]
]
]
๊ทธ๋์ ์ง๊ธ์ 2๊ฐ์ ๊ฒฝ์ฐ๋ง ๊ฐ์ง๊ณ ์์ผ๋ฉฐ Feliz ์ฝ๋๋ฅผ ๊ตฌ์กฐํํ๋ ๋จ์ผ ๋ฐฉ๋ฒ์ ์ ๋ง๋ก ์ํ๋ค๋ฉด ๋๋ฌด ๋ง์ ๋
ธ์ด์ฆ ์์ด ๋น ๋ฒ์ ์ ์ฌ๋ฌ ์ค์ ์์ฑํ ์๋ ์์ต๋๋ค.โ ๏ธ ๋๋ถ๋ถ์ API๋ ์ ๋ ฅ๋์ง ์์ต๋๋ค.
type HTMLAttr =
| DefaultChecked of bool
| DefaultValue of obj
| Accept of string
| AcceptCharset of string
| AccessKey of string
| Action of string
| AllowFullScreen of bool
| AllowTransparency of bool
โ๏ธ โ ๏ธ ์ผ๋ถ API๊ฐ ์ ๋ ฅ๋์์ง๋ง ์ ๋ถ๋ ์๋๋ฏ๋ก ์ฝ๋๊ฐ ์ผ๊ด๋์ง ์์ต๋๋ค.
โ๏ธ SSR์ ์ง์ํฉ๋๋ค.
โ๏ธ ์ ํ ์์ API
Modifier.TextAlignment (Screen.All, TextAlignment.Centered)
Button.button [ Button.Color IsWhite ]
[ str "White" ]
โ๏ธ Fulma API๋ ๊ตฌ์ฑ ๋ฐฉ์์ ์ดํดํ๋ฉด Intellisense๋ฅผ ํตํด ์ฝ๊ฒ ํ์ํ ์ ์์ต๋๋ค.
โ๏ธ Fulma๋ ๊ตฌ์ฑ ์์์ ๋ํด ์๊ฐํ๋๋ก ๊ฐ์ํฉ๋๋ค.
โ๏ธ IsCustomColor
๋๋ถ์ ์ง์๋๋ ์์์ ์ฝ๊ฒ ํ์ฅํ ์ ์์ต๋๋ค.
// All you need to add `custom-purple` support to all your components is this line
let isCustomPurple = IsCustomColor "custom-purple"
โ๏ธ โ ๏ธ ๋ชจ๋ ๊ตฌ์ฑ ์์์ ๋ํ ์์ ๊ฐ ํฌํจ๋ ์ข์ ๋ฌธ์๊ฐ ์๋ค๊ณ ์๊ฐํ์ง๋ง ๋ชจ๋ ๊ตฌ์ฑ ์์์ ๋์ผํ ์์ค์ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์์ง๋ ์์ต๋๋ค.
โ๏ธ โ ๏ธ Fulma๊ฐ ๋ฒ๋ค ํฌ๊ธฐ์ ๋ฏธ์น๋ ์ํฅ์ "์์ ์ "์ ๋๋ค. ์ด ์ ์ Feliz.Bulma ์น์ ์ ์ค๋ช ๋์ด ์์ต๋๋ค.
โ ๏ธ ์ฌ๋๋ค์ "ํน๋ณ ๋์ฐ๋ฏธ"๋ฅผ ์ฝ๊ฒ ์ฐพ์ง ์์ต๋๋ค.
โ ๏ธ Fulma ์ฝ๋๋ ๊ฐ๋ ฅํ ํ์์ DSL๋ก ์ธํด ์ฝ๋์ ๋ ธ์ด์ฆ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
์๋ฅผ ๋ณด๋ ค๋ฉด ์ฌ๊ธฐ๋ฅผ ํด๋ฆญํ์ญ์์ค.
// Fulma
Heading.p [ Heading.IsSubtitle
Heading.Is5
Heading.Modifiers [ Modifier.TextAlignment (Screen.All, TextAlignment.Centered) ] ]
[ str "is only available on desktop" ]
// Feliz.Bulma
Bulma.subtitle5 [
text.hasTextCentered
prop.text "is only available on desktop"
]
โ ๏ธ Fulma ์ฝ๋๋ Props
, Modifiers
๋ฅผ ๊ฒฐํฉํ ๋ ์ค์ฒฉ๋ ๋ชฉ๋ก์ด ๋ง๊ธฐ ๋๋ฌธ์ ์ฌ๋ฐ๋ฅด๊ฒ ํฌ๋งทํ๊ธฐ๊ฐ ์ฝ์ง ์์ต๋๋ค.
์ ๋ 2-3์ฃผ ๋์ ์ด ๋ถ์์ ์งํํ์ผ๋ฉฐ ์ฌ์ ํ ๊ณ์ํ ์ ์์ต๋๋ค. ํ์ง๋ง ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฌ๊ณ ์ํฉ์ ๋ ์ ๋ณผ ์ ์๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ ์ข ๋ฃํด์ผ ํฉ๋๋ค.
Fable.React์ Fulma์ ๋ํด ํนํ ๋์ดํด์ผ ํ ์ข์ ์ ์ด๋ ๋ฌธ์ ๊ฐ ๋ ์์ ์ ์์ง๋ง ๊ทธ๊ฒ์ด ์ ๊ฐ ๊ฐ์ฅ ์ด๋ ค์ด ๋ถ๋ถ์ด๊ธฐ๋ ํฉ๋๋ค. 3๋ ๋๊ฒ ์ฌ์ฉํ๊ณ ๋์์ธํ๋ค ๋ณด๋ ๊ฐ๊ด์ ์ธ ์์ ์ ๊ฐ๊ธฐ ์ด๋ ต์ต๋๋ค.
Fable.React์์ Feliz๋ก์ ๋ณํ์ ์ถฉ๋ถํ ์ฌ์ ์ต๋๋ค. Feliz๋ Fable.React์ ํธํ๋๋ฏ๋ก ํ์ผ๋ณ ํ์ผ, ๊ตฌ์ฑ์์๋ณ ๊ตฌ์ฑ์์ ๋ฑ์ ์ ์ง์ ์ผ๋ก ๋ณํํ ์ ์์ต๋๋ค.
๋ชจ๋ open Fable.React
๋ฐ open Fable.React.Props
์ง์นจ์ ์ ๊ฑฐํ ๋ชจ๋ ๊ฒ์ ๋ณํํ๋์ง ํ์ธํฉ๋๋ค. ๋ํ ์ข
์์ฑ์ผ๋ก Fulma๋ฅผ ์ ๊ฑฐํ์ต๋๋ค.
๋ฌผ๋ก ์ผ๋ถ ํ์ผ์ ์์ด๋ฒ๋ ค ์ปดํ์ผ๋ฌ ์ค๋ฅ๋ฅผ ์์ ํ ๋ค์ ์๋ํ์ต๋๋ค.
์ฌ๊ธฐ ์์ ๋ณํ์ ํธ์คํ ํ๋ ๋ณํฉ ์์ฒญ์ ๋ณผ ์ ์์ต๋๋ค.
Feliz๋ฅผ ์ฒ์ ๋ฐ๊ฒฌํ์ ๋ "HTML/JSX ๋ฐฉ์"์ ๋ฐ๋ฅด์ง ์์๊ณ ๋ด๊ฐ ๋ง์ ๋ ธ๋ ฅ์ ํฌ์ํ ๊ฒ์ ๋ํ ๋์ฒด ํ๋ก์ ํธ์ด๊ธฐ ๋๋ฌธ์ ๋ฐฉ์ด์ ์ด์์ต๋๋ค.
๊ทธ๋ฐ ๋ค์ ํ์ ์ด ์๋ํ๋ ๋ฐฉ์๊ณผ ๊ทธ๊ฒ์ด ์ฐ๋ฆฌ๋ฅผ ์ฑ์ฅ์ํฌ ์ ์๋ ๋ฐฉ๋ฒ์ด๋ผ๋ ๊ฒ์ ๊ธฐ์ตํ์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๊ทธ ๋๋ถ์ ์ค๋๋ Elmish๊ฐ ์์ต๋๋ค.
๋ด๊ฐ ๊ธฐ์ตํ ๋ ๋ค๋ฅธ ์ฌ์ค์ JSX๊ฐ "์ค์ React API"๊ฐ ์๋๋ผ๋ ๊ฒ์
๋๋ค. ์ค์ ๋ก React API๋ React.createElement
์
๋๋ค. JSX๋ ๊ทธ ์์ ๊ตฌ๋ฌธ ์คํ์ด๋ฉฐ Fable.React ๋ฐ Feliz๋ ๋ง์ฐฌ๊ฐ์ง์
๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ๋๋ฅผ ์ํด ์์ผ๋ก ๋์๊ฐ๊ณ ๊ทธ๊ฒ์ ๋ํด ๊ถ๊ธํดํ๋ ๋ฐ ๋์์ด ๋์๊ธฐ ๋๋ฌธ์ ์ฃผ์ฅํฉ๋๋ค.
Feliz๋ฅผ ํ ์คํธํ๊ธฐ ์ํด Fable REPL์ธ ์ค๊ฐ ๊ท๋ชจ ํ๋ก์ ํธ๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. Fable REPL์ ๋ณต์กํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋์ง๋ง Fable๊ณผ React์ ๋ง์ ๊ธฐ๋ฅ์ ์ฌ์ฉํฉ๋๋ค.
์ด ๊ฒฐ์ ๋๋ถ์ ๋ด๊ฐ ํ ์คํธํ ๊ฒ๋ค์ ์ ์ฒด ๋ชฉ๋ก์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋ณํ์ ์์ํ ๋ ์ฝ๋ ํ์์ ์ง์ ํ๋ ๊ฒ์ด ์ผ๋ง๋ ์ฌ์ด์ง ๋งค์ฐ ๋ง์กฑํ์ต๋๋ค. Feliz ๊ธฐ๋ฐ ๋ทฐ๋ฅผ ์์ฑํ๊ธฐ ์ํ ๊ท์น์ ๋ฐ๋ฅด๋ฉด ์ ๋ง ์ฝ๊ฒ ๋ฐ๋ผํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ด ์์ฉ ํ๋ก๊ทธ๋จ์ด ์ปค์ง์๋ก ์ฝ๋ ํ์์ด ๋ ์ค์ํ๋ค๋ ๊ฒ์ ์๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ฌ๋ค ์ค๊ฐ์ ๋ญ๊ฐ ์ง์ฆ์ด ๋๊ธฐ ์์ํ๋๋ฐ ์ฐพ์ ์๊ฐ ์์์ด์.
Fable REPL์ Feliz๋ก ๋ณํํ๋ ์์ ์ ์๋ฃํ๋๋ฐ ์ฌ์ฉ ๊ฒฝํ์ด ๋ง์์ ๋๋์ง ์๋์ง ํ์ ํ ์ ์์์ต๋๋ค.
์ด์ ์์ผ ๋ถ์์ ๋ง๋ฌด๋ฆฌํ๋ ค๊ณ ํ๊ณ , ๋ฌด์์ด ๋๋ฅผ ๊ฐ๋ก๋ง๋์ง ์ดํดํ๊ฒ ๋์์ต๋๋ค. Feliz์ ๊ทธ๋ค์ง ๊ด๋ จ์ด ์์ง๋ง Feliz.Bulma์ ๊ด๋ จ์ด ์์ต๋๋ค.
์ ๋ 2.5๋ ์ด์ Fulma๋ฅผ ๊ฐ๋ฐํ๊ณ ๊ฐ์ ํด ์๋ค๋ ๊ฒ์ ๊ธฐ์ตํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. Fulma๋ ์ ์ ๊ฐ์ฅ ํฐ ํ๋ก์ ํธ ์ค ํ๋์ ๋๋ค. ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ํนํ ๋ชจ๋ ๊ฒ์ด ํ์ํ๋๊ณ ๊ตฌ์ฑ ์์์ ๊ด์ ์์ ์๊ฐํ๊ฒ ํ๊ธฐ ๋๋ฌธ์ ํ๋ฅญํฉ๋๋ค.
Feliz.Bulma๋ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ์ทจํ๊ณ Fulma๋ณด๋ค ์ ์ต๋๋ค. ๋ง 5๊ฐ์์ ๋๋ค.
๋งํ๋ค ๋ชจ๋์ ํจ๊ป, ๋๋ ๋ด ๊ฒฐ๋ก ์ผ๋ก ์ด๋ํฉ๋๋ค ์ง๊ธ ์๊ฐ์ด ์๊ฐ :)
ํ ๋ฆฌ์ฆ์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ ์ฑ๊ธ๋ฆฌ์คํธ ์คํ์ผ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๊ฒ์ ๋ด๊ฐ ๋ง์ด ์ธ๊ธํ ๊ฒ์ด์ง๋ง ๋ด ์ฝ๋๋ฅผ ์ฝ๊ฒ ํฌ๋งทํ ์ ์๊ณ ๋ค์ ์ค์ ์ด๋์ ์์ํด์ผ ํ๋์ง ์๊ฐํ ํ์๊ฐ ์๋ค๋ ๊ฒ์ด ํฐ ์ฅ์ ์ ๋๋ค.
๋์งธ, ์ ํ ์์ API๋ ํ์ํ์ ๋๋ค. ๋๋ฑํ CSS๋ณด๋ค ๋ ์ฅํฉํ์ง๋ง ์ข์ ๊ธฐ๋ฅ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ๋๋ ๊ทธ๊ฒ์ผ๋ก ๋ฉ์ง ๊ฒ์ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ๊ฒ์ด ์ง์๋๋์ง ๋งํ ์๋ ์์ง๋ง ๊ทธ๋ ์ง ์๋ค๋ฉด ์ฐ๋ฆฌ๋ ํญ์ ๊ทธ๊ฒ์ ๊ณ ์น ์ ์๋ PR์ ๋ง๋ค ์ ์์ต๋๋ค. :).
Feliz.Bulma๋ Feliz๋ฅผ ํ์ฅํ๋ ์ ๋งํ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ์ง๋ง ์์ง Fulma์ ์ง์ ์ ์ผ๋ก ๋๋ฑํ ๋งํผ ์ฑ์ํ์ง ์์ต๋๋ค. ์ด๊ฒ์ @Dzoukr๋ก ๋ ํ๊ตฌํ๊ณ ์ถ์ ๊ฒ์ด๋ฉฐ Feliz.Bulma์ ๋จ์ํจ๊ณผ Fulma์ ์์ ํ์ง๋ง ์ฅํฉํ ๊ฒ ์ฌ์ด์์ ์ค๊ฐ ์ง์ ์ ์ฐพ์ ์ ์๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
3๋ ์ , 2017๋ 3์ 8์ผ , Tomas, Eugene๊ณผ ์ ๋ Fable.Arch๋ฅผ Elmish์ ๋ณํฉํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. ์ด๋ฅผ ํตํด ์ฐ๋ฆฌ๋ ์ปค๋ฎค๋ํฐ๋ก์ ์ค๋๋ ์ฐ๋ฆฌ๊ฐ ๊ฐ์ง๊ณ ์๋ ๋๋ผ์ด ์ํ๊ณ๋ฅผ ๊ตฌ์ถํ ์ ์์์ต๋๋ค.
์ฐ๋ฆฌ๋ ํ์ฌ Feliz์ Fable.React์ ๋น์ทํ ์๋๋ฅผ ์ด๊ณ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. Feliz๊ฐ Fable.React๋ณด๋ค ๋ ๋ง์ ๊ฒฌ์ธ๋ ฅ์ ์ป์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๊ทธ๋ฌ๋ ๋ ๋ค ํจ๊ป ๊ณต์กดํ ๊ฒ์
๋๋ค. ๊ฒฐ๊ตญ ๋ ๋ค ์ ์๋ํ๋ฏ๋ก ์ฌ๋๋ค์ด ์ ํธํ๋ ๊ฒ์ ์ ํํ ์ ์์ต๋๋ค.
์ ๋ถ์์ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋๊ธ ์น์ ์์ ๊ธฐ๊บผ์ด ๋ ผ์ํ๊ฒ ์ต๋๋ค. :)
ํ๋ฅญํ ๋ถ์์ ๋๋ค.
๊ฐ์ธ์ ์ผ๋ก ์ด์ค ๋ชฉ๋ก ํ์์ด ๋๋๋ก ๊ณ ํต์ค๋ฝ๊ธด ํ์ง๋ง Fable.React ์ฝ๋๋ฅผ ๋ณด๋ฉด ๊ธฐ๋ณธ html์ ๊ตฌ์กฐ๋ฅผ ๋ ์ ๋ณผ ์ ์๋ค๊ณ ๋๋๋๋ค. ๊ทธ๊ฒ์ div [.. , Html.div [.... (etc)๊ฐ ์๋๋๋ค. ๋ณ๊ฑฐ ์๋๊ฑฐ ๊ฐ์ง๋ง ๋ด ๋๋ Fable.React๋ฅผ ๋ ์ฝ๊ฒ ํ์ฑํ๋ ๊ฒ ๊ฐ๋ค.
@MangelMaxime ์ ์ฐ์ จ ์ต๋๋ค. ์ข์ ์ง์ ์ ๋ง์ด
๋ด๊ฐ ์์งํ ๊ฒ์์ ์ด๊ฒ์ ์ฃผ์ ๋ด์ฉ์ ๋๋ถ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ฅ๋๋ ๋ฐฉ์๊ณผ ์ต์ ์ผ๋ก ์ํ๋์ง ์์ ๋ ๋ฐ์ํ๋ ๋ฌธ์ ์ ๊ดํ ๊ฒ์ ๋๋ค.
Feliz
์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํ๋ฉด ๊ฐ๋ฐ์๊ฐ ๋ ๋ง์ ์์
์ ํด์ผ ํ๋ค๋ ๋ฐ ๋์ํ์ง๋ง ๊ฒฐ๊ณผ API๊ฐ ์ฌ์ฉํ๊ธฐ์ ๋๋ฌด ์ข์ ๋ ๋
ธ๋ ฅํ ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ ๋ Feliz
๋ํด ์๋นํ ์์ ํ์ฅ์ ์์ฑํ๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ง์ ๋ฌธ์ ๋ฅผ ์ํํ๋ ๋ฐฉ๋ฒ์ ๋ํ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋๋ Visual Studio๋ฅผ ์ฌ์ฉํ๊ณ ์ด๋ค ์ค๋ฒ๋ก๋๋ฅผ ์ฌ์ฉํ ์ ์๋์ง ์ฐพ๋ ๋ฐ ์ ํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์๋ง๋ ์ด๊ฒ์ด ionide์ ๋์์ ๊ฐ์ ๋ ์ ์๋ ๊ฒ์ ๋๊น?
prop.text
toString
๋ฉค๋ฒ๊ฐ ํ์ํ ๋จ์ผ ์ธ๋ผ์ธ ํจ์๋ก ๋ง๋ค๊ณ ๋ชจ๋ ์ ํ์ ํ์ฉํ ์ ์์ต๋๊น?
๋์ ์:
[<Erase>]
type editor =
/// <summary>Triggered when the Editor has been mounted</summary>
static member inline editorDidMount (f : System.Func<Monaco.Editor.IStandaloneCodeEditor, Monaco.IExports, unit>) = Interop.mkAttr "editorDidMount" f
์ฐ๋ค:
[<Erase>]
type editor =
/// <summary>Triggered when the Editor has been mounted</summary>
static member inline editorDidMount (f : Monaco.Editor.IStandaloneCodeEditor -> Monaco.IExports -> unit) = Interop.mkAttr "editorDidMount" (Func<_,_,_> f)
๊ทธ๋ฐ ๋ค์ ํด๋ผ์ด์ธํธ ์ธก์์ ์์ํ ๋๋ก ์์ฑ์ ํธ์ถํ ์ ์์ต๋๋ค.
๋ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค ์ผ๋ถ์ ์๋ ๋งํผ ๋ค๋ฅธ ์ฌ๋์ด ์ด๊ฒ์ ์ ์ฉํ๋ ๊ฒ์ ๋ณธ ์ ์ด ์์ผ๋ฉฐ Html
ํ์ฅํ ๋ ์์ ํ ์ ์ฉ๋์ง ์์ ์ ์์ต๋๋ค. ์ด๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐฉ๋ฒ์ ๋ด ๊ฐ์ฅ ํฐ Feliz
๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ์ํ ์์ฑ์ ์ถ๊ฐ ์ธํฐํ์ด์ค ์ ํ์ ์ถ๊ฐํ๋ ๊ฒ์
๋๋ค. Feliz.Plotly
์ ํจํ์ง ์์ ์์ฑ์ ์ฌ์ฉํ๋ ค๊ณ ํฉ๋๋ค. ์ ์ผํ ๋จ์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฐ๋ฐ์์๊ฒ ๊ฝค ๋ง์ ์์
์ด ์์๋๋ค๋ ๊ฒ์
๋๋ค.
ํ์ฅํ๋ ค๋ฉด ํด๋ฆญ
[<AutoOpen;EditorBrowsable(EditorBrowsableState.Never)>]
module Types =
type IPlotProperty = interface end
type IModeBarButtonsProperty = interface end
type IAaxisProperty = interface end
type IAggregateProperty = interface end
type IAggregationProperty = interface end
type IAggregationsProperty = interface end
type IAngularaxisProperty = interface end
type IAnimationProperty = interface end
type IAnnotationProperty = interface end
type IAnnotationsProperty = interface end
type IAreaProperty = interface end
type IAspectratioProperty = interface end
type IAxisProperty = interface end
type IBarProperty = interface end
type IBarpolarProperty = interface end
type IBaxisProperty = interface end
type IBorderProperty = interface end
type IBoxProperty = interface end
type IButtonProperty = interface end
type ICameraProperty = interface end
type ICandlestickProperty = interface end
type ICapsProperty = interface end
type ICarpetProperty = interface end
type ICaxisProperty = interface end
type ICellsProperty = interface end
type ICenterProperty = interface end
type IChoroplethProperty = interface end
type IChoroplethmapboxProperty = interface end
type ICircleProperty = interface end
type IColoraxisProperty = interface end
type IColorbarProperty = interface end
type IColorscaleProperty = interface end
type IColorscalesProperty = interface end
type IConcentrationscalesProperty = interface end
type IConeProperty = interface end
type IConfigProperty = interface end
type IConnectorProperty = interface end
type IContourProperty = interface end
type IContourcarpetProperty = interface end
type IContoursProperty = interface end
type ICumulativeProperty = interface end
type ICurrentvalueProperty = interface end
type IDecreasingProperty = interface end
type IDeltaProperty = interface end
type IDensitymapboxProperty = interface end
type IDiagonalProperty = interface end
type IDimensionProperty = interface end
type IDimensionsProperty = interface end
type IDomainProperty = interface end
type IEditsProperty = interface end
type IErrorXProperty = interface end
type IErrorYProperty = interface end
type IErrorZProperty = interface end
type IEyeProperty = interface end
type IFillProperty = interface end
type IFilterProperty = interface end
type IFontProperty = interface end
type IFrameProperty = interface end
type IFramesEntryProperty = interface end
type IFramesProperty = interface end
type IFunnelProperty = interface end
type IFunnelareaProperty = interface end
type IGaugeProperty = interface end
type IGeoProperty = interface end
type IGradientProperty = interface end
type IGridProperty = interface end
type IGroupbyProperty = interface end
type IHeaderProperty = interface end
type IHeatmapProperty = interface end
type IHeatmapglProperty = interface end
type IHistogram2dProperty = interface end
type IHistogram2dcontourProperty = interface end
type IHistogramProperty = interface end
type IHoverlabelProperty = interface end
type IImageProperty = interface end
type IImagesProperty = interface end
type IIncreasingProperty = interface end
type IIndicatorProperty = interface end
type IInsidetextfontProperty = interface end
type IIsosurfaceProperty = interface end
type ILabelfontProperty = interface end
type ILataxisProperty = interface end
type ILayerProperty = interface end
type ILayersProperty = interface end
type ILayoutProperty = interface end
type ILeafProperty = interface end
type ILegendProperty = interface end
type ILightingProperty = interface end
type ILightpositionProperty = interface end
type ILineProperty = interface end
type ILinkProperty = interface end
type ILonaxisProperty = interface end
type IMapboxProperty = interface end
type IMarginProperty = interface end
type IMarkerProperty = interface end
type IMeanlineProperty = interface end
type IMesh3dProperty = interface end
type IModebarProperty = interface end
type INodeProperty = interface end
type INumberProperty = interface end
type IOhlcProperty = interface end
type IOutsidetextfontProperty = interface end
type IPadProperty = interface end
type IParcatsProperty = interface end
type IParcoordsProperty = interface end
type IPathbarProperty = interface end
type IPieProperty = interface end
type IPointcloudProperty = interface end
type IPolarProperty = interface end
type IProjectProperty = interface end
type IProjectionProperty = interface end
type IRadialaxisProperty = interface end
type IRangebreakProperty = interface end
type IRangebreaksProperty = interface end
type IRangefontProperty = interface end
type IRangeselectorProperty = interface end
type IRangesliderProperty = interface end
type IRotationProperty = interface end
type ISankeyProperty = interface end
type IScatter3dProperty = interface end
type IScatterProperty = interface end
type IScattercarpetProperty = interface end
type IScattergeoProperty = interface end
type IScatterglProperty = interface end
type IScattermapboxProperty = interface end
type IScatterpolarProperty = interface end
type IScatterpolarglProperty = interface end
type IScatterternaryProperty = interface end
type ISceneProperty = interface end
type ISelectedProperty = interface end
type IShapeProperty = interface end
type IShapesProperty = interface end
type ISlicesProperty = interface end
type ISliderProperty = interface end
type ISlidersProperty = interface end
type ISortProperty = interface end
type ISpaceframeProperty = interface end
type ISplomProperty = interface end
type IStartsProperty = interface end
type IStepProperty = interface end
type IStepsProperty = interface end
type IStreamProperty = interface end
type IStreamtubeProperty = interface end
type IStyleProperty = interface end
type IStylesProperty = interface end
type ISunburstProperty = interface end
type ISurfaceProperty = interface end
type ISymbolProperty = interface end
type ITableProperty = interface end
type ITernaryProperty = interface end
type ITextfontProperty = interface end
type IThresholdProperty = interface end
type ITickfontProperty = interface end
type ITickformatstopProperty = interface end
type ITickformatstopsProperty = interface end
type ITilingProperty = interface end
type ITitleProperty = interface end
type ITotalsProperty = interface end
type ITracesProperty = interface end
type ITransformsProperty = interface end
type ITransitionProperty = interface end
type ITreemapProperty = interface end
type IUniformtextProperty = interface end
type IUnselectedProperty = interface end
type IUpProperty = interface end
type IUpdatemenuProperty = interface end
type IUpdatemenusProperty = interface end
type IViolinProperty = interface end
type IVolumeProperty = interface end
type IWaterfallProperty = interface end
type IXProperty = interface end
type IXaxisProperty = interface end
type IXbinsProperty = interface end
type IYProperty = interface end
type IYaxisProperty = interface end
type IYbinsProperty = interface end
type IZProperty = interface end
type IZaxisProperty = interface end
type IButtonsProperty = inherit IModeBarButtonsProperty
type IMeasureProperty = interface end
type ITemplateProperty = interface end
๋น์ทํ ๋งฅ๋ฝ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฝ๋์์ ์ํ๋ ๊ฒฝ์ฐ ์์ฑ์ "์๋์ผ๋ก" ๊ฒฐํฉํ๋๋ก ๊ตฌํํ ์๋ ์์ต๋๋ค. ์์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ธ๋ถ์์ ์ฌ์ฉํ ๋ ์ด๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์ด์ ๋ํ ํธ๋ฆญ์ ํด๋น ํญ๋ชฉ์ IReactProperty
์ ๋ค๋ฅธ ์ ํ์ผ๋ก ๋ง๋๋ ๊ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด Feliz.Plotly
์์๋ ์ฃผ์ด์ง ๊ตฌ์ฑ์ ๋ฐ๋ผ ์ฌ์ฉ์ ์
๋ ฅ์ ์์ /์์ง/๋ณ๊ฒฝํ์ฌ ์ค์ ์ฝ๋๊ฐ ์ด๋ป๊ฒ ์๊ฒผ๋์ง ์ ์ ํ๊ฒ ๋ณํํ๋ ๋ง์ ์์
์ ์ํํฉ๋๋ค. ํญ์ ์กด์ฌํ๋ ๊ฒ๋ค์ ์ ๊ฑฐํ๋ ๊ฒ์ ์ด๋ค ๋ฉด์์๋ ์ ๋ง ์ข์ต๋๋ค.
"Feliz" ๋ฐฉ์์ผ๋ก ์์ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ ๋์ ๋ฌธ์๋ก ๋น์ ์ด ๊ฒช์๋ ๋ง์ ๊ณ ํต์ ํด๊ฒฐํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์๋ง๋ @Zaid-Ajaj์ ๋๋ ๋ฏธ๋์ ๊ทธ ์ผ์ ํ ์ ์์ ๊ฒ์ ๋๋ค.
@l3m ๊ฐ์ฌํฉ๋๋ค
๊ฐ์ธ์ ์ผ๋ก ์ด์ค ๋ชฉ๋ก ํ์์ด ๋๋๋ก ๊ณ ํต์ค๋ฝ๊ธด ํ์ง๋ง Fable.React ์ฝ๋๋ฅผ ๋ณด๋ฉด ๊ธฐ๋ณธ html์ ๊ตฌ์กฐ๋ฅผ ๋ ์ ๋ณผ ์ ์๋ค๊ณ ๋๋๋๋ค. ๊ทธ๊ฒ์ div [.. , Html.div [.... (etc)๊ฐ ์๋๋๋ค. ๋ณ๊ฑฐ ์๋๊ฑฐ ๊ฐ์ง๋ง ๋ด ๋๋ Fable.React๋ฅผ ๋ ์ฝ๊ฒ ํ์ฑํ๋ ๊ฒ ๊ฐ๋ค.
์ค์ ๋ก ์ฝ๋๋ฅผ ์ฝ๋ ๋ฐฉ๋ฒ์ ์ ํํ๋ ๊ฒ์ ์ฌ์ด ์ผ์ด ์๋๋๋ค. ๊ทธ๋์ ์ ๊ฒฝ์ฐ์๋ ์ฝ๋๋ฅผ HTML๋ก ๋ณด์ง ์์์ผ ํ๋ค๊ณ ์ธ๊ธํ ๊ฒ์ด ์ ํํ๋ ๋ฐ ๋์์ด ๋์์ต๋๋ค.
F# 5์ "์ ์ ํด๋์ค ์ด๊ธฐ" ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด Feliz๊ฐ Html ํด๋์ค๋ฅผ ์ฌ๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ Html.div
๋ฐ div
๊ตฌ๋ฌธ์ ๋ชจ๋ ์ง์ํ ์ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์๊ฒฌ์ ์ฃผ์ @Shmew ์๊ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ์ค์ ๋ก Feliz์ ์ฌ๋ฌ ์ ํ์ "๋ผ์ด๋ธ๋ฌ๋ฆฌ"๊ฐ ์๋ค๋ ์ฌ์ค์ ์์ด๋ฒ๋ ธ์ต๋๋ค.
"์๋ชป๋ ์ฝ๋ ์์ฑ"์ ๋ํด ์, ํ์ง๋ง ์ผ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์๋ Props
์ ๊ฐ์ ํน์ ๋์ฐ๋ฏธ๋ฅผ ํตํด ํ์ค ์์ฑ์ ์ ๋ฌํด์ผ ํ๋ Fulma ์ํฉ์ ํผํ๊ธฐ ์ํด IReactProperty
์ ํ์ "ํ์ฅ"ํ๋ ค๊ณ ํฉ๋๋ค. Props
. ๊ทธ ์ด์ ๋ Bulma "๊ตฌ์ฑ ์์"๊ฐ DOM ์์์ ๋ํ ์ ๋ฌธํ์ ๋ถ๊ณผํ๊ธฐ ๋๋ฌธ์
๋๋ค.
HTML ์์์ ๊ธฐ๋ณธ์ ์ผ๋ก ํด๋์ค๋ฅผ ์ฝ์ ํ๋ ์ฝ๋์ผ ๋ฟ์ ๋๋ค.
Bulma.button
๋ <div class="button">
"์ค์ " ๊ตฌ์ฑ ์์์์ ์๋ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ฒฝ์ฐ(์ฃ์กํ์ง๋ง ์ด๋ฆ์ ๋ค๋ฅด๊ฒ ์ง์ ํ๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฆ ๋๋ค) ๊ทํ์ ์๋ฃจ์ ์ ์ค์ ๋ก ์ฌ๋ฐ๋ฅธ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด Fable.ReactLeaflet ์์ ๊ฐ ๊ตฌ์ฑ ์์์ ํน์ ์์ฑ์ ์ ์ํ๋ ๋ฐฉ์์ ๋๋ค. ๋ฐ๋ผ์ ๊ตฌ์ฑ ์์๋ ๋ชจ๋ ํ์ค HTML ์์ฑ์ ์ง์ํ ํ์๊ฐ ์์ต๋๋ค.
"์ฝ๋ฐฑ"์ ๋ํ ๊ทํ์ ์๋ฃจ์
์ ๋ํด์๋ ์ ์๊ฒ ํจ๊ณผ๊ฐ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ Fable์ด ์ ๋ฌํ ํจ์์๋ ์นด๋ ์ธ์๊ฐ ์์๊ณ myFunction(arg1)(arg2)
์ ๊ฐ์ ๊ฒ์ ์์ฑํ๊ณ ์ถ์ง ์๋ค๋ฉด System.Func
๋ฅผ ํตํด uncurried ๋ฒ์ ์ ๊ฐ์ ์คํํด์ผ ํ์ต๋๋ค.
์๋ํ๊ฒ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์๋ค๋ฉด https://github.com/fable-compiler/repl/pull/108/files ์์ ์์ ํ๊ธฐ ์ํด PR์ ๋ณด๋ด๋๋ฆฌ๊ฒ ์ต๋๋ค.
์๋ ํ์ธ์ @MangelMaxime ์ ๋๋ค .
์ฐ์ , ํ๋ก์ ํธ์์ Feliz๋ฅผ ์๋ํ๋ ๊ฒ๋ฟ๋ง ์๋๋ผ ๊ด๋ฒ์ํ ๋ถ์์ ์์ฑํ๊ธฐ ์ํด ์๊ฐ๊ณผ ๋ ธ๋ ฅ์ ๋ค์ธ ๊ฒ์ ๋ํด ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋ง์ Fable ์ฌ์ฉ์๊ฐ ๋งค์ฐ ์ ์ฉํ๊ณ ์ ์ตํ๋ค๋ ๊ฒ์ ์๊ฒ ๋ ๊ฒ์ด๋ผ๊ณ ํ์ ํฉ๋๋ค.
์ ๋ ์ด๋ฌํ ์ข ๋ฅ์ ํผ๋๋ฐฑ๊ณผ ๊ฐ๋ฐฉ์ฑ์ ์ ๋ง ๊ฐ์ฌํ๋ฉฐ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ํ๊ณ์ ํจ๊ป ํ ์ ์๋ ์ต์์ ์ํ๋ก ๋ง๋๋ ๊ฒ์ด ์ค์ํ๋ค๊ณ ๋ฏฟ์ต๋๋ค.
์ํ๊ณ์์ ์ผ์ข ์ ํน๋ณํ๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ Feliz.Bulma์ ๋ํด ์ ์ ์ด์ผ๊ธฐํ๊ฒ ์ต๋๋ค. ๋จผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์ด๋ฏธ ๊ณ ์น ์ ์๋ ๋ช ๊ฐ์ง ๋ฌธ์ ์ ๋ํด ๋ต๋ณํ๊ฒ ์ต๋๋ค.
onChange
๊ณผ๋ถํ๋ช ์์ ์ผ๋ก ์ํ๋ ์ด๋ฒคํธ ์ ํ์ ๋งํด์ผ ํฉ๋๋ค.
์ฌ์ค, ๋น์ ์ํ์ง ์์ต๋๋ค. ์ ํ์ ๋ค์๊ณผ ๊ฐ์ด ๋ฉ์์ง ์ ํ์์ ์ ์ถ๋์ด์ผ ํฉ๋๋ค.
prop.onChange (ChangeGistToken >> dispatch)
ChangeGistToken
์ ์ ํ์ ๋ฐ๋ผ ์ฌ๋ฐ๋ฅธ ์ค๋ฒ๋ก๋๊ฐ ์ ์ถ๋ฉ๋๋ค. DU ์ผ์ด์ค๊ฐ ChangeGistToken of string
์ด๋ฉด string -> unit
์ ๊ณผ๋ถํ๊ฐ ์ ํ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์
๋ ฅ ์ ํ์ด file
์ธ ๊ฒฝ์ฐ FileSelected of File
์๋ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๊ณผ๋ถํ File -> unit
๊ฐ ์ ์ถ๋๋ ์์
๋๋ค. ev.Value
์์ Fable.React
ev.Value
์ ๊ตฌ๋ฌธ ์คํ์ด ํ์ํ์ง ์์ต๋๋ค.
onChange
๊ฐ ์ด๋ฏธ ๋ถ์ธ ๋์๋ฌธ์๋ฅผ ์ฒ๋ฆฌํ๋ฏ๋ก prop.onCheckedChange๊ฐ ์ ๊ฑฐ๋ฉ๋๋ค.
@Shmew ๋ ์ด๋ฏธ ์ด ๋ฌธ์ ๋ฅผ ๋ค๋ฃจ์์ผ๋ฉฐ ์ค์ ๋ก ์ด๊ฒ์ด ์ด๋ฌํ ์ ํ์ ์์ฑ์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. Feliz ํ์ฅ์ ๊ตฌํํ ๋ ์์ฑ์ ์ค์ ํ๊ธฐ ์ ์ ๋ณํ ์ ์ํํ ์ ์์์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
type myExtension =
static member inline extenstionProperty value =
// transform value here
let transformedValue = doWeirdStuffWith value
Interop.mkAttr "extenstionProperty" transformedValue
์ด ๋
ผ๋ฆฌ์ ๋ฐ๋ผ ๋ด๋ถ์ ์ผ๋ก 'A -> 'B -> unit
๋ฅผ Func<'A, 'B, unit>
๋ก ๋ณํํ ์ ์์ต๋๋ค.
[<Erase>]
type editor =
/// <summary>Triggered when the Editor has been mounted</summary>
static member inline editorDidMount (f : Monaco.Editor.IStandaloneCodeEditor -> Monaco.IExports -> unit) =
let transformedFunction = System.Func<Monaco.Editor.IStandaloneCodeEditor, Monaco.IExports, unit>(fun editor exported -> f editor exported)
Interop.mkAttr "editorDidMount" transformedFunction
์ด๊ฒ์ @Shmew์์ ์ ๊ณตํ๋ ๊ฒ๋ณด๋ค ๋ ๋ช ์์ ์ธ ๋ฒ์ ์ ๋๋ค(๋ฐ์ธ๋ฉ์ ๋ํด ์๊ณ ์๋ฏ์ด, ๋ฐ์ธ๋ฉ์ ์ฌ๊ธฐ์ ์์ต๋๋ค
์์์ ์ธ๊ธํ @Shmew : ์ ์ ํ Feliz ํ์ฅ์ ์๋ชป ๋์ํ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ํ์ฉํ์ง ์์ผ๋ฉฐ ์์ฑ ์ ํ์ ์ ํํ๋ฉด ์ด๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค. Feliz.Recharts์ฒ๋ผ prop
์ ์๋ ๊ธฐ์กด ์์ฑ๊ณผ์ ์ญํธํ์ฑ์ ํ์ฉํ๋ IReactProperty
๋ฅผ ๋ฐํํ๋ ์์ฑ์ ๋น๋ํ๊ฑฐ๋ ์ง์ํ๊ธฐ ์ํด ๋ณด๋ค ์ ๋ฌธํ๋ ์ ํ ISpecialiedProperty
์ ๊ตฌํํ ์ ์์ต๋๋ค. ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด IReactProperty
์์ ์ผ๋ถ ์์ฑ์ ์ด๋ฆ์ ๋ณต์ ํ๋ ๋์ ์์ฑ์ ํ์ ์งํฉ๋ง:
type felizExtension =
static member inline specializedProp (value: string) : ISpecializedProperty = unbox (prop.text value)
์ด๊ฒ์ ๋ด๊ฐ Feliz.AntDesign์ผ๋ก ์ํํ ์์
์
๋๋ค. ์๋ฅผ ๋ค์ด ์ฌ๊ธฐ ์์ button
์ง์
์ ์์ ์ฌ์ฉํ ์ ์๋๋ก ์ผ๋ถ ์์ฑ์ ๋ณต์ ํ๊ณ ์์ต๋๋ค(๋์ค์ ์์ฑ์ ์๊ฒฉํ ์ ํ์ผ๋ก ๋ ์ ๋ฌธํํ ์ ์์ง๋ง ์ฒ์์๋ , ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ์ฒ์ ์์ํ๋ ์์น์
๋๋ค). Feliz.MaterialUI๋ ์์ฑ์ ์ ๋ฌธํํ๊ธฐ๋ณด๋ค IReactProperty
๋ฅผ ํ์ฅํ๊ธฐ ์ํด ์ ์ฌํ ์์
์ ์ํํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด๊ฒ์ Feliz.Bulma์ ๊ฒฝ์ฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
Feliz.Bulma๊ฐ ๊ตฌํ๋๊ธฐ ์ ์ CSS ์ ์ฉ ํ๋ ์์ํฌ๋ฅผ ์ํ Feliz ํ์ฅ์ ๊ตฌ์ถ ํ ํ์ ๊ฐ yield
๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์ฌ ๋ ์ฝ์ต๋๋ค. ์ด๊ฒ์ TypedCssClasses ์ ๊ฒฐํฉํ๋ฉด CSS ์ ์ฉ ํ๋ ์์ํฌ๋ฅผ ๊ตฌํํ ํ์๊ฐ ์์ต๋๋ค. ๊ตฌํ ๋ฐ ์ ์ง ๊ด๋ฆฌ ๋น์ฉ์ด ์์ต๋๋ค. ์ง์ ๋ฌธ์ ์น์ฌ์ดํธ๋ฅผ ๊ตฌ์ถํ ํ์ ์์ด ํ์ดํ๋ ์คํ์ผ์ํธ๋ฅผ ์ฌ์ฉํ๊ณ ํ๋ก์ ํธ ์์ฒด์ ๋ํ ์ด๋ฏธ ์ ๋ง ์ข์ ๋ฌธ์๋ฅผ ์ฌ์ฉํ์ญ์์ค.
๊ทธ๋ฌ๋ @Dzoukr์ด Feliz.Bulma๋ฅผ ๊ตฌํํ ๊ฒ์ ๋ณธ ํ์๋ ์ดํด๊ฐ ๋์์ต๋๋ค. Bulma์ ํ ๋ชจ๋์์ CSS ๊ตฌ์ฑ ์์์ ํน์ "์ง์
์ "์ ๋์
ํ์ฌ ์ฝ๋๋ฅผ ๋ง์ด ๋จ์ํํ์ฌ Bulma.button
๋ฅผ ์ป์ ์ ์์์ต๋๋ค Bulma.card
๋ฑ. ์ฌ์ฉํ๊ธฐ ์ ๋ง ์ข์ต๋๋ค. ์์ ์์ ๊ดํด์๋ Roman์ ์ ๊ทผ ๋ฐฉ์์ด ๋ฐ๋ฅด๊ธฐ ์ฝ๊ณ ์์
ํ๊ธฐ ์ฝ๋ค๊ณ ์๊ฐํ์ง๋ง ๋ง์ํ์ ๊ฒ์ฒ๋ผ ๋๋ก๋ ํฅ๋ฏธ๋ก์ด ๊ฒฐ๊ณผ๋ฅผ ์ค ์๋ ์์ต๋๋ค. ํ์คํ ๊ทธ ๋ถ์์์ ๋ ๊ฐ์ ํด์ผ ํ ์ ์ด ์์ผ๋ฉฐ ์ด์จ๋ Roman์ Feliz์ ๋น์ ์ ๋ฐ๋ผ ๋ฐฐ์ฐ๊ณ ์ฌ์ฉํ๊ธฐ ์ฌ์ด ๊ฒ์ ๊ตฌ์ถํ๋ ๋ฐ ํฐ ์ญํ ์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
ํ์ฌ Fable.React
๋ฐ Feliz
์ ํฐ ์ฐจ์ด์ ์ ์ง์ ํ๊ณ ์ถ์ต๋๋ค. ํจํค์ง ๋ฒ์ ๊ด๋ฆฌ ๋ฐ ๊ด๋ฆฌ์
๋๋ค. Feliz ๋ฒ์ ์ ๋ชจ๋ ์ํ๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ Femto์ ํธํ๋๋ฏ๋ก ํ์ํ npm ํจํค์ง๋ฅผ ์๋์ผ๋ก ์ค์นํ๊ฑฐ๋ ํธํ๋๋ ๋ฒ์ ์ ์์์ผ ํ๋ ์ฌ์ฉ์์ ๋ถ๋ด์ ์ ๊ฑฐํฉ๋๋ค. ์ด๊ฒ์ ๋ชจ๋ ํ์ Fable.React
๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฌ์ง์ด ๊ทธ๋ ์ง ์์ Fable.React
์์ฒด์๋ ๋ค๋ฆ
๋๋ค.
์ฌ์ค, ๋น์ ์ํ์ง ์์ต๋๋ค. ์ ํ์ ๋ค์๊ณผ ๊ฐ์ด ๋ฉ์์ง ์ ํ์์ ์ ์ถ๋์ด์ผ ํฉ๋๋ค.
prop.onChange (ChangeGistToken >> dispatch)
์ฌ์ค, ๋๋์ด ์ฌ์ฉ๋ฒ์ ๋ํด ์๊ฐํ์ง ์์์ต๋๋ค.
๋ค์ค ์ธ์ ์ฝ๋ฐฑ
@Shmew ๋ ์ด๋ฏธ ์ด ๋ฌธ์ ๋ฅผ ๋ค๋ฃจ์์ผ๋ฉฐ ์ค์ ๋ก ์ด๊ฒ์ด ์ด๋ฌํ ์ ํ์ ์์ฑ์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
์ฃ์กํฉ๋๋ค. @Shmew์์ ์ ๊ณตํ ์ค๋ํซ์ ๋์ ๋ณด์ง ๋ชปํ์ต๋๋ค. ๋ฐฉ๊ธ ์๋ช ์ ์ธ์ ๋ณด์๊ณ ์๋ํ์ง ์๋ ๊ฒ์ฒ๋ผ ๋ณด์์ต๋๋ค.
๋ ๋ค ๋ง์ต๋๋ค. ์์ฑ์ ๊ฐ์ ์ ๋ฌํ๊ธฐ ์ ์ ๋ณํ์ ์ํํ ์ ์์ต๋๋ค.
๋ค, TypedCssClasses๋ ๊ด์ฐฎ์ง๋ง Fulma๋ Feliz.Bulma์ ๋น๊ตํ๋ฉด ๊ฐ์ ์์ค์ ๊ธฐ๋ฅ์ ์ ๊ณตํ ์ ์์ต๋๋ค. CSS ํ์ผ์ ๋ชจ๋ ๊ฒ์ด ํฌํจ๋์ด ์์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
๋ ๋ค๋ฅธ ์ ์ ๊ฐ๋ฐ ๋ชจ๋์์ ๋์คํฌ์ ํ์ผ์ด ํญ์ ์์ฑ๋๋ ๊ฒ์ ์๋๋ฉฐ TypedCssClasses๊ฐ ์ด ์๋๋ฆฌ์ค๋ฅผ ์ง์ํ๋์ง ํ์คํ์ง ์๋ค๋ ๊ฒ์ ๋๋ค.
๋๋ Roman์ด Feliz์ ๋น์ ์ ๋ฐ๋ผ ๋ฐฐ์ฐ๊ธฐ ์ฝ๊ณ ์ฌ์ฉํ๊ธฐ ์ฌ์ด ๊ฒ์ ๋ง๋๋ ๋ฐ ํฐ ์ญํ ์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
๋์ํฉ๋๋ค. Fulma์์ ์ํํ ์์ ์ ์ฝ๊ฐ ์ถ๊ฐํ์ฌ ์ ์ฌํ๊ฒ ๋ง๋ค ํ์๊ฐ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ๋ด๊ฐ ๋งํ๋ฏ์ด ์ฐ๋ฆฌ๋ ๋ ์ฌ์ด์ ์ฌ๋ฐ๋ฅธ ์ค๊ฐ ์ง์ ์ ์ฐพ์์ผ ํฉ๋๋ค.
๋ด๊ฐ ์ง๊ธ ์ผ๋์ ๋๊ณ ์๋ ๋๋ฝ๋ ๊ธฐ๋ฅ์ ์ถ๋ ฅ ์์๋ฅผ ์ ์ดํ๊ณ ์ง์๋๋ ์์ ์ธํธ๋ฅผ ๋ ์ฝ๊ฒ ํ์ฅํ ์ ์๋๋ก ํ๋ ๊ฒ์ ๋๋ค. ๋๋ ๊ทธ๊ฒ์ด ๊ทธ๊ฒ์ ๋ง์ ๋ณต์ก์ฑ์ ๋ํ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ง ์์ต๋๋ค.
@Zaid-Ajaj๋ ํผ๋๋ฐฑ๊ณผ ํนํ Feliz ์ ์ฌ๋ ฅ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ฌ๋ฐ๋ฅธ ๋ฐฉํฅ์ ์๋ ค์ฃผ์
์ ๊ฐ์ฌํฉ๋๋ค.
๋๋ Feliz ๋ฌธ์๋ฅผ ์ค์ ๋ก ์ฝ์ง ์์์์ ์ธ์ ํฉ๋๋ค. ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ์ถ๊ฐํด์ผ ํ ๋ช ๊ฐ์ง ์ฌํญ์ ๋ ์๊ณ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. :)
๊ฐ์ฌํฉ๋๋ค @MangelMaxime - ํ๋ฅญํ ๋น๊ต์
๋๋ค. ๋น์ ์ ์ธ๊ธํ์ง ์์ Fantomas์๊ฒ ๋น์ ๋ Fable.React ๋๋ ํ ๋ฆฌ ์ฆ์ Fantomas ์์
ํ ๊ธฐํ๊ฐ ์์๋์ - ์๋ฌด ๊ณณ์ด๋ ์ฝ๋์ ์์์ ์๋ ํ์๋์?
Fantomas๋ฅผ ์ฌ์ฉํ๋ Fable ํ๋ก์ ํธ ์ค ํ๋์์ Ionide์์ ํ์ผ ์ ์ฅ ์ ์๋ ํฌ๋งท์ ์ผฐ๊ณ ์ด๊ฒ์ด ์์ฐ์ฑ ํฅ์์ ๋์์ด ๋๋ค๊ณ ๋งํด์ผ ํฉ๋๋ค. ์๋ ํฌ๋งท์ ๋ํด ์ ํ ๊ฑฑ์ ํ ํ์๊ฐ ์์ต๋๋ค!
Fantomas๊ฐ ์ด์ ์ถ์ง๋ ฅ์ ์ป๊ณ ์๋ค๊ณ ์๊ฐํ๋ฉฐ Fable ๋ฐ React/Feliz์ ํจ๊ป ๋ ๋๋ฆฌ ์ฑํ๋๊ธฐ๋ฅผ ์ํฉ๋๋ค.
@theimowski ๋๋
๋๋ถ๋ถ ๋ด ์ฝ๋๋ฅผ ์๋ง์ผ๋ก ๋ง๋ค๊ณ ์ฝ๊ธฐ๊ฐ ์ ๋ง ์ด๋ ต๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ด ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด Fable.React ๋ฐ Feliz์ ์ ์๋ํ์ง ์์์ต๋๋ค.
๋ํ Fantomas์ ๊ธฐ๋ณธ๊ฐ์ด ๋ง์์ ๋ค์ง ์์ต๋๋ค. ๋์ค์ ๋ด ์ฝ๋๋ฅผ ๋ค์ฌ์ฐ๊ธฐํ๋ ๋ฐฉ๋ฒ์ ์๊ฒ ๋๋ฉด ๋ค์ ํ์ธํด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ repo๋ฅผ ์ดํด๋ณธ ๊ฒฐ๊ณผ Fantomas๊ฐ ์ปจํ ์คํธ ํฌ๊ธฐ์ ๋ฐ๋ผ ์ฝ๋๋ฅผ ํ์ํํ๊ธฐ ๋๋ฌธ์ ๋๋ถ๋ถ ๋ด ์๊ตฌ์ ๋ง์ง ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด ์์ฑํ๋ฉด
type Test =
{
Prop1 : string
}
ํ ์ค์ ๋ค์ด๊ฐ ์ ์๋ค๋ ์ด์ ๋ง์ผ๋ก type Test = { Prop1 : string }
๊ฐ ๋์ง ์๊ณ ๊ทธ๋๋ก ์ ์ง๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
๊ธฐ๋ก์ด ์ข์ ์๊ฐ ์๋ ์๋ ์์ง๋ง, ์ ๋ง์ ์๋ฏธ๋ฅผ ์ดํดํด์ฃผ์ จ์ผ๋ฉด ํฉ๋๋ค. :)
@theimowski ๋ฐ๊ฐ ์ต๋๋ค. ์ ๋ Fable์ด ์๋ ํ๋ก์ ํธ์์ ํฌํ ๋ง๋ฅผ ์ฌ์ฉํฉ๋๋ค. ํ ๋ฒ ๋ ํด๋ณด๊ณ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ง ๋ด์ผ๊ฒ ๋ค์.
@MangelMaxime ์์ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ์ด์ฉ์ง ๋น์ ์ Fulma ํ๋ก์ ํธ๊ฐ ์ฐํ์ ์ธ๊ณ๋ก ๋๋ฅผ ๊ณต๊ฒฉํ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋ ์ฌํ์ ์ ๋ง ์ฆ๊ธด๋ค.
๋๋ ๋ํ ๋จ์ผ ๋ชฉ๋ก์ ์ข์ํ์ง๋ง ํด๋์ค ๋ฉค๋ฒ ์ฌ์ ์๋ณด๋ค DU๋ ์ข์ํฉ๋๋ค. ๋๋ก๋ DU๊ฐ ์ฌ์ ์๋ฅผ ์ง์ํ๋์ง ๊ถ๊ธํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ ๋ง ์ข์ ๊ฒ์
๋๋ค.
์ด๋ฏธ Fable.React๋ฅผ ๋ง์ด ์ฌ์ฉํ์ง๋ง ์ฌ์ ํ ๋จ์ผ ๋ชฉ๋ก์ ์ํ๊ธฐ ๋๋ฌธ์ > ์ฐ์ฐ์๋ฅผ ๋ง๋ค๊ณ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
let myView =
div </> [
Classes [ ""; ""; "" ]
Children [
...
]
]
์ฐ์ฐ์๋ ๋งค์ฐ ๊ฐ๋จํ๊ณ DU๋ ํ์ฉ ํฉ๋๋ค. ์ฌ๊ธฐ์์ ๋๋ต์ ์ธ ๊ตฌํ์ ํ์ธํ ์ ์์ต๋๋ค.
@Zaid-Ajaj ํ๋ฅญํ ์์ ์ ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋ํ ์ผ๋ถ ํ๋ก์ ํธ๋ฅผ Feliz ๋ฐ Feliz.Material๋ก ๋ณํํ๊ธฐ ์์ํ์ต๋๋ค.
๊ฐ์ฌ ํด์!
์๋
ํ์ธ์ @MangelMaxime ์
๋๋ค .
์ฐ์ ๊ฐ์ฌํฉ๋๋ค! ์์งํ ๋๋ ๋ด๊ฐ ์ฃผ๋ก dogfooding ์์ ์ ํ๋ก์ ํธ๋ฅผ ์ํด ๋ง๋ค๊ณ ๋ถ์์ฉ์ผ๋ก ๊ฒ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋๊ตฐ๊ฐ๊ฐ ๊ทธ๋ ๊ฒ ๊น์ด ๋ค์ฌ๋ค๋ณผ ๊ฒ์ด๋ผ๊ณ ๊ธฐ๋ํ์ง ์์์ต๋๋ค. "์ด๋ด, @Zaid-Ajaj๊ฐ Feliz๋ฅผ ๋์์ธํ ๋ฐฉ๋ฒ์ด ํ๋ฅญํฉ๋๋ค. Bulma๋ ๋๊ฐ์ด ํฉ์๋ค"๋ผ๋ ์๊ฐ์ด ๋ถํ์ด ์ค๋ฅธ ๊ฒ์ด ์๊ธฐ๋ค์.
์ ๋ ์ด๋ฏธ Feliz.Bulma
repo์ ์๋ก์ด Issue๋ฅผ ๋ง๋ค์์ผ๋ฉฐ v2๋ฅผ ๋ ์ข๊ฒ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ํด ํ ๋ก ํ๋ ๊ฒ์ ์ข์ํฉ๋๋ค. ๋๋ถ๋ถ์ ๋ฌธ์ ์ ๋ํด ํฉ์๊ฐ ๋ ๊ฒ ๊ฐ์ผ๋ version2
๋ถ๊ธฐ๋ฅผ ์์ํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ ๊ฒ์
๋๋ค. ๋ํ ๋ค์ ์ฃผ์ ๋ฆด๋ฆฌ์ค์ ๋ํ Zaid์ ๊ณํ์ ์ดํด๋ณด๋ ๊ฒ์ ์ต์ ์ฃผ์ ๋ฒ์ ๊ฐ์ API๋ฅผ 100% ํธํ๋๋๋ก ์ ์งํ๋ ๋ฐ ์ ์ฉํ ์ ์์ต๋๋ค.
์ด์จ๋ , ๋ค์ ํ ๋ฒ ๊ฐ์ฌ๋๋ฆฝ๋๋ค-ํ๋ฅญํ ๋ถ์!
์ํ์์ ์ด์ ๋ ผ์๋ฅผ ์ฌ๊ฐํ๋ค (!) ๋ฏธ์ ๋ ๊ทธ๋ฅ ๋ค์ฌ ์ฐ๊ธฐ ๋ ผ์์ ๋ด ๋ ์ผํธ๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์ -์ด (๋ค์)๋ ์ฐ๋ฆฌ๊ฐ ์ข์ ์ผ๊ด๋ identation์ ํ์ฉ ์๋ ๋ฐ๋ผ ์คํ์ผ๋ง๊ณผ Fable.React์ ๋ํด ๋ค์ ์คํ์ผ.
๊ทธ๋ฌ๋ ์ด๊ฒ์ด ์ ์ฉ๋์ง ์๋ ํ ๊ณณ์ ์ฌ์ํ ์คํ์ผ๋ง์ ๋๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ์ ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด ์ด๊ฒ์ ์์์ ์์(์๋ง๋ 10-20%)๋ง์ ์ค๋ช ํฉ๋๋ค.
div [ ] [
Hero.hero [ Hero.IsFullHeight ] [
Hero.body [ ] [
Container.container [ ] [
img [ Src "img/fable-ionide.png"
Style [ Display DisplayOptions.Block
Width "auto"
Margin "auto" ]
]
br [ ]
Heading.h3 [ Heading.Modifiers [ Modifier.TextAlignment (Screen.All, TextAlignment.Centered) ] ] [
str "Fable REPL"
]
Heading.p [ Heading.IsSubtitle
Heading.Is5
Heading.Modifiers [ Modifier.TextAlignment (Screen.All, TextAlignment.Centered) ] ] [
str "is only available on desktop"
]
]
]
]
]
๋ํ VS Code ๋ฐ Rainbow Brackets ๊ฐ์ ๊ฒ์ ์ฌ์ฉํ๋ฉด ๋ธ๋ํท ๊ณผ๋ถํ๋ฅผ ํผํ๋ ๋ฐ ์ค์ ๋ก ๋์์ด ๋ ์ ์์ต๋๋ค.
๊ณ ๋ คํด์ผ ํ ๋ค๋ฅธ ์ฌํญ(์์์ ๋์ณค์ ์ ์์)์ GiraffeViewEngine์ด Fable.React ์คํ์ผ, ์ฆ ์์ attr-list children-list๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ๋ ์ฌ์ด๋ฅผ ์ ํํ๋ ์ฌ๋๋ค์ ๊ด์ ์์ ์๊ฐํ ์ ์๋ ๊ฒ์ ๋๋ค.
@Zaid-Ajaj๋ Femto์ ๋ํด ์ข์ ์ง์ ์ ํฉ๋๋ค. Fable.React ์คํ์ผ ๊ตฌ์ฑ ์์์์ ์ด๊ฒ์ด ๊ตฌํ ๋์ง ์์ ์ด์ ๊ฐ ์์ต๋๊น? ์๋๋ฉด Femto๊ฐ ๊ฒฐํฉ๋ Feliz ์คํ์ผ์ ๊ณ ์ ํ ๊ฒ์ด ์์ต๋๊น?
Fable.React ์คํ์ผ ๊ตฌ์ฑ ์์์์ ์ด๊ฒ์ด ๊ตฌํ๋์ง ์์ ์ด์ ๊ฐ ์์ต๋๊น? ์๋๋ฉด Femto๊ฐ ๊ฒฐํฉ๋ Feliz ์คํ์ผ์ ๊ณ ์ ํ ๊ฒ์ด ์์ต๋๊น?
@isaacabraham
Fable.React์์ ํ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ Femto ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ ์ ์๊ณ ์ถ๊ฐํด์ผ ํ์ง๋ง Fable.React ์์ฒด์๋ react
, react-dom
๋ฐ react-native
์ ํธํ๋์ง ์๋ ํผํฉ์ด ์๊ธฐ ๋๋ฌธ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. . @MangelMaxime ์ ํจํค์ง ๋ถํ ์์
์ ์์ํ์ง๋ง ์์๋ณด๋ค ํจ์ฌ ๋ ๋ง์ ์์
์ด์๊ณ ์๋ง๋ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ ๋์
ํ ๊ฒ์
๋๋ค.
Fable.React
์์ ํ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํด ์ด๊ฒ์ด ์๋ฏธํ๋ ๋ฐ๋ Fable.React๊ฐ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ ์ข
์์ฑ์ npm ๋ฉํ๋ฐ์ดํฐ๋ฟ๋ง ์๋๋ผ react
๋ฐ react-dom
ํธํ ๋ฒ์ ๋ ํฌํจํด์ผ ํ๋ค๋ ๊ฒ์
๋๋ค. ( react
๋ฐ react-dom
์์ํ๋ Feliz์ ๋ฌ๋ฆฌ Feliz ํ์ฅ ํ๋ก๊ทธ๋จ์ ํ์ํ ๊ฒ๋ง ์ถ๊ฐํฉ๋๋ค.) ๋ถํํ๋, ๋๋ ๊ทธ ์๋ฃจ์
์ด ๊ฝค ์ค๋ซ๋์ ์ฃผ๋ณ์ ์์์์๋ ๋ถ๊ตฌํ๊ณ ์ํฉ์ ๊ฐ์ ํ๊ธฐ ์ํด ์ฃผ๋๊ถ์ ์ก์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ง ๋ณด์ง ๋ชปํ์ต๋๋ค.
ํ์ ์ง์ ๊ณผ ๊ด๋ จํ์ฌ: Fantomas๋ ์์ง DSL์ ํฉ๋ฆฌ์ ์ธ ๋ฐฉ์์ผ๋ก ํ์ํํ ์ ์์ผ๋ฉฐ ๋ชฉ๋ก ํ์ ์ง์ ์ ๊ตฌ์ฑ ๊ฐ๋ฅ ํ๊ฒ ๋ง๋๋ ์์ ์ด ํ์ํ๊ฑฐ๋ ๋ฉ์ง ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉํ์ฌ React DSL์ ํ์ํํ๊ธฐ ์ํด ์ผ์ข ์ "Feliz-mode" ํ๋๊ทธ๊ฐ ์์ด์ผ ํฉ๋๋ค. ์ต๋)
@Zaid-Ajaj React npm ์ข ์์ฑ๊ณผ ๊ด๋ จ๋ ๋ฌธ์ ๋ Femto๋ฅผ ์ค๋จํ์ง ์๊ณ react ๋์ preact๋ฅผ ์ฌ์ฉํ ์ ์์ด์ผ ํ๋ฏ๋ก ๋ ๋ณต์กํฉ๋๋ค.
@l3m ์ฌ์ค, ํ์ง๋ง ์ด ๊ฒฝ์ฐ์๋ Femto๋ฅผ ์ถ๊ฐํ์ฌ ์ด ๊ฒฝ์ฐ๋ฅผ ์ง์ํ ์ ์์ต๋๋ค. ๋ญ๊ฐ๋ฅผ ๊ธฐ์ตํ๊ณ ์์ด์ Femto repo์ ๋ฌธ์ ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค(์ง๊ธ ํ์ธํ ์๊ฐ์ด ์์ด ์ฃ์กํฉ๋๋ค ^^)
@l3m Preact๋ Femto npm ๋ฉํ๋ฐ์ดํฐ์ ์๊ด์์ด React ๋์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ธฐ์กด React ์ ํ๋ฆฌ์ผ์ด์ ์ด ์๋ ๊ฒฝ์ฐ Switching to Preact ์ ์ง์นจ์ ๋ฐ๋ผ ๋ชจ๋ ๊ฐ์ ธ์ค๊ธฐ ๋ณ์นญ๋ง ๊ตฌ์ฑํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
์์ํ Preact ๋ฐ์ธ๋ฉ(100% non-React ์ฝ๋)์ ๊ตฌ์ถํ๋ ๊ฒ์ Feliz์ ๋ชฉํ๊ฐ ์๋๋ฉฐ ์๋ง๋ Preact ์ ์ฉ ๋ฐ์ธ๋ฉ์ด ํ์ฅ๋๊ณ ํ์ฅ๋ ๋
๋ฆฝํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(Feliz.Preact์ ์์กดํ์ง ์๋ Feliz.Preact)๋ก ๊ตฌํ๋์ด์ผ ํฉ๋๋ค. preact/compat
์์ ๋ฒ์ด๋๊ณ ์ถ์ ๋ ์ฌ์ฉ
@Zaid-Ajaj ์ ๋ ์ง๊ธ Elmish ์ฑ์์ preact๋ฅผ ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ์ ์๋ํฉ๋๋ค. Femto๊ฐ React deps์ ํจ๊ป nuget์ ๋ณด๋ ๊ฒฝ์ฐ packages.json์ ์์ ํ๋ ๊ฒ์ ๋ํด ์กฐ์ฌ์ค๋ฌ์ ๊ณ ์ด๋ฅผ ๊ฐ์กฐํ๊ณ ์ถ์์ต๋๋ค. ๊ทธ๊ฒ์ด ๋ฌธ์ ๊ฐ ์๋๋ผ๋ฉด, ๋ ์ข์ต๋๋ค.
๋ํ preact/compat
๋ ์ต์ preact์์ ๋ ์ด์ ํ์ํ์ง ์์ผ๋ฉฐ ์ด์ ํต์ฌ์
๋๋ค.
์ํ์ ๋ฌด๋ฆ ์ฐ๊ณ ์ค๋๋ ํ ๋ก ์ ๋ค์ ์ด ์ ์์ต๋๋ค(์ฃ์กํฉ๋๋ค!). ์ ๋ ๋ค์ฌ์ฐ๊ธฐ ํ ๋ก ์ 2์ผํธ๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์์ต๋๋ค. ์ด๊ฒ์ Fable.React์ ๋ํด ํ๋ฅญํ๊ณ ์ผ๊ด๋ ์๋ณ ๋ฐ ํ๋ก์ฐ๋ฅผ ํ์ฉํ๋ _does_ ๋ฐ๋ฅด๋ ์คํ์ผ์ ๋๋ค. ์คํ์ผ.
๋๋ Isaac์ ๊ฒ๊ณผ ๋งค์ฐ ์ ์ฌํ ๋ฐฉ์์ผ๋ก ์ฝ๋๋ฅผ ๋ค์ฌ์ฐ๊ณ ์์ผ๋ฉฐ ๊ฝค ์ฝ๊ธฐ ์ฝ์ต๋๋ค.
์ผ์ ํ๋ ๋จ์ผ ๋ชฉ๋ก ๋ฐฉ์๊ณผ ๋น๊ตํ๊ธฐ ์ด๋ ต๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง ์๋ณธ ๊ฒ์๋ฌผ์ ๋ค์ฌ์ฐ๊ธฐ๋ ๋ ๋์ ๋น๊ต๋ฅผ ์ํด ๊ทธ์ ์ฝ๋์ ์ ์ฌํ ๊ฒ์ ๋ฐ์ํ ์ ์์ต๋๋ค.
F# 5์ "์ ์ ํด๋์ค ์ด๊ธฐ" ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด Feliz๊ฐ Html ํด๋์ค๋ฅผ ์ฌ๋์ง ์ฌ๋ถ์ ๋ฐ๋ผ
Html.div
๋ฐdiv
๊ตฌ๋ฌธ์ ๋ชจ๋ ์ง์ํ ์ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์ ๋ง ๋ฉ์ง ๊ฒ์ ๋๋ค. ์ด ์ ์๋๋ก Html ํด๋์ค๋ฅผ ์ ์ ์ผ๋ก ๋ง๋ค ์ ์์ต๋๊น?
@fc1943s Html
, prop
๋ฐ style
๋ ๋ชจ๋ ์ ์ ํด๋์ค์
๋๋ค. ๊ทธ๋ฌ๋ F# 5์์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ฉด ํด๋น ์ ์ ํด๋์ค ๋ด์์ ์ฌ์ฉ ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ ๋ํ ๊ฒ์ ์ง์
์ ๋ฐ ๊ทธ๋ฃนํ ์ง์ ์ด ์ ์ฒด ์ง์ ์ ์๊ธฐ ๋๋ฌธ์ ์ด์ง ์๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ ์ ํด๋์ค๋ฅผ ์ด๋ฉด ๊ฒ์์ด ์ด๋ป๊ฒ ๋ฐฉํด๋ฉ๋๊น? ์ฌ์ ํ Feliz.Html์ ์
๋ ฅํ ์ ์์ต๋๋ค.
@MaxWilsonMS "์ต์ข " ์ฝ๋๋ฅผ ์ถ๋ ฅํ๋ ค๋ฉด ์ถ๊ฐ ๋จ๊ณ๊ฐ ํ์ํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ Feliz.Html.div
์ฐ๊ณ ์ด์ํด ๋ณด์ด๋ Feliz.Html.
๋ถ๋ถ์ โโ์ง์๋๋ค.
์ข์ ์ ์ ์ฌ๋๋ค์ด ๊ธฐ๋ณธ ์ค์ ์ ๋ฐ๋ผ ์ ์ ํด๋์ค๋ฅผ ์ด๊ฑฐ๋ ์ด์ง ์์ ์ ์๋ค๋ ๊ฒ์ ๋๋ค. :)
์์์ ๋งํ ๋ด์ฉ์ ๋ฐ๋ณตํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ์ผ๋ง๋ ์ ์ฉํ์ง ํ์คํ์ง ์์ง๋ง ์์ ํ ์ด๋ณด์๋ก์์ ๊ฒฝํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋๋ ๋ค์ฌ์ฐ๊ธฐ์ Feliz ์ ๊ทผ ๋ฐฉ์์ ์ ํธํฉ๋๋ค. ๋๋ Isaac์ด ์ ์ํ ๊ฒ๊ณผ ์ ์ฌํ ์ ๊ทผ ๋ฐฉ์์ ์๋ํ์ง๋ง ๋ค์ฌ์ฐ๊ธฐ๊ฐ ๋ชจ๋ 2/4๊ฐ ์๋๊ธฐ ๋๋ฌธ์ "๋๋ก๋ ๊ทธ๊ฒ์ ๋ํด ์๊ฐํ๋ ๋ฐ ์๊ฐ์ ๋ณด๋ ๋๋ค". Feliz์ ํจ๊ป๋ผ๋ฉด ๊ทธ๊ฒ์ ๋ํด ์๊ฐํ ์๊ฐ์ด ์ ํ ์์ต๋๋ค.
๋ด๊ฐ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ๋ง๋ค๊ณ ์๋ค๋ฉด ์ง๊ธ์ Fable.React ๋ฐฉ์์ผ๋ก ํ์ ๊ฒ์ ๋๋ค. ๋๋ "Feliz ๋ฐฉ์"์ผ๋ก ๊ฑด๋ฌผ์ ์ง๋ ๊ฒ์ ๋ณด๊ณ ์ฆ์ ๋๋ง์ณค์ต๋๋ค(์ธ์ ๊ฐ ๋ค์ ๋ฐฉ๋ฌธํ ์์ ์ ๋๋ค!).
๋ฌธ์๊ฐ "์ด๊ฒ์ด ์ฌ์ฉ์ ์ ์ ์์ฑ์ ๋ง๋๋ ๋ฐฉ๋ฒ" ์ธก๋ฉด์ ๋ณด๋ค ์ ๊ธฐ์ ์ผ๋ก ์ฐ์ ์์๋ฅผ ๋ถ์ฌํ๋ค๋ฉด ์ ๋ง ์ ์ฉํ ๊ฒ์ ๋๋ค. ์์์ ์์ฑ์์ ํจ๊ป ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ CSS์์ ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒ์ ๋ํ API ํ๋ฉด์ ์ ๊ณตํ๋ ๋ฐ ์ข ์ข ์ด๋ ค์์ ๊ฒช์ ์ ์๋ค๋ ์ ์ ๋ฐ์๋ค์ด๋ ๊ฒ์ด ๊ณต์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค(์: ์๋ฅผ ๋ค์ด). ๋ฐ๋ผ์ ์ด๋ณด์๊ฐ "fontSize"๋ฅผ ์ค์ ํ ์ ์์ ๋ ๋งํ๊ฒ ๋๋ค๋ฉด "em"์ ์๊ฑฐ๋ "grid-template-rows"๋ฅผ ์ฐพ์ ์ ์๊ฑฐ๋ "Screen.All" ์ธ์๋ฅผ ์ ๊ณตํด์ผ ํ๋์ง ์ ํ ๋ชจ๋ฆ ๋๋ค. ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
๋ช ๊ฐ์ง ์ ์ฌ์ ์ธ ์ฐ๋ ค๋ฅผ ์์ ๊ธฐ ์์ํ๋ ์ผ๋ถ "์ถ์ ์ง" ๊ฐ์ ์ด ์ด๋ฃจ์ด์ง ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค... ์๋ฅผ ๋ค์ด Feliz์์ ์คํ์ผ ์ํ์ ๊ธด ์์ง ๋ชฉ๋ก์ ๋ณผ ๋ style.paddingHorizontal
๊ฐ ์์ ์ ์๋์ง ๊ถ๊ธํ๊ธฐ ์์ํฉ๋๋ค. style.paddingVertical
. ๋๋ ๋ด ์์ ์ ๋์ฐ๋ฏธ๋ฅผ ๋ง๋ค ์ ์๋ค๋ ๊ฒ์ ๊นจ๋ฌ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ๊ธฐ๋ฅ์ ์์ฒญํ๋ ๊ณณ์ด ์๋๋ฉฐ ํ์ค์ด ์๋ ๊ฒ์ ๋์
ํ๋ ๊ฒ์ ํผํ๊ณ ์ถ์ ์๊ตฌ๊ฐ ์์ ์ ์์ต๋๋ค. :)
๋๋ ์๋ก์ด F#์์ Html
์ ์ ํด๋์ค๋ฅผ ์ฌ๋ ์์ด๋์ด๋ฅผ ์ข์ํฉ๋๋ค. ๋นํ์ ์ผ๋ก - ๋๋ฃ๋ค์ด ๋ด ์ด๊นจ ๋๋จธ๋ก ๋ฐ๋ผ๋ณผ ๋ ๊ทธ๊ฒ์ ์ดํดํ ์ ์์ ๊ฒ์
๋๋ค - ๊ทธ๋ฆฌ๊ณ ๋ ๋ง์ ์ฌ๋๋ค์ ์ฐธ์ฌ์ํค๋ ๊ฒ์ด ์ค์ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์
๋ง์ ์นํธ์ ์ญํ ์ ํ๋ ค๋ฉด div
๋ฅผ ์
๋ ฅํ๋ ๋ฐ ์ค๋ ๊ฑธ๋ฆฌ์ง ์์ผ๋ฉฐ ์ด๋ฅผ ๋ฐ๊ฒฌํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ง๋ฒ์ ์ํํ๋ ์ค์ ์ ์ฌ์ฉํ ๋ ๋ถ๋ชํ ๊ฐ์ฅ ์์ ๋ฌธ์ ์
๋๋ค. ๋์๊ฒ ์๋ฐ์คํฌ๋ฆฝํธ, React, CSS ๋ฑ์ ์จ๊ธฐ๋ ๊ฒ. ๊ทธ๋ฌ๋ ์ผ๋ฐ์ ์ผ๋ก API์ ๊ฒ์ ๊ฐ๋ฅ์ฑ์ ๋ฐ์ด๋ฉ๋๋ค.
ํนํ ์คํ์ผ์ ๋ํ ์ ํ/์ ๋๋ฉ์ด์ ์ ๊ฒฝ์ฐ Feliz ๋ฐฉ์์ ๋งค์ฐ ์๋ฏธ๊ฐ ์์ต๋๋ค. ์์ ํ๊ธฐ์ ์ ๋ง ์ข์ต๋๋ค.
๋ ์ผ๋ฐ์ ์ผ๋ก ๊ทธ๋ฆฌ๊ณ ์๋ง๋ ์ ํ ์ ์์ต๋๋ค. ๋ด๊ฐ ์ง์์ ์ผ๋ก ๋ถ๋ช์น๋ ๋ฌธ์ ๋ Elmish ์ธ๊ณ๊ฐ ๋๋๊ณ React ์ธ๊ณ๊ฐ ์์๋๋ ์์น๋ฅผ ์ดํดํ๋ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ ์ค์ ๋ก ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ด์ฌ์ฌ๊ฐ ์๋๋๋ค. ๊ทธ๋ฌ๋ React์ ๋ํ ๊ฐ์ฅ ํ๋ฆฟํ ๋จ์๊ฐ ์๊ธฐ ๋๋ฌธ์ Fable.React ๋๋ Feliz์์ Function Component๋ฅผ ์ป์ ์ ์๋ค๋ ์ฌ์ค์ด ์ ๋ฅผ ํผ๋์ค๋ฝ๊ฒ ํฉ๋๋ค. ๋ฌผ๋ก ์ด๊ฒ์ ๋ฐฐ์ฐ๋ ๊ฒ์ ๋์ ์ฑ ์์ด์ง๋ง ์ธ๊ธํ ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํ์ต๋๋ค. ์ ๋ ํ์ฌ Elmish์ React ์ ๊ทผ ๋ฐฉ์์ ํจ๊ป ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ์ด๋ก ์ธํด ์ ๋ฐ์ดํธ ์ ๋ชจ๋ ๊ตฌ์ฑ ์์๊ฐ ๋ค์ ๋ ๋๋ง๋๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด์ ๊ฐ์ด ์์ ํ ๋น๋๋ ์ฑ์ ์๋ ์ฐพ๊ธฐ ํ๋ค๋ค. ๋๋ก๋ Javascript๋ก ํ๋ก๋์ ๋ฑ๊ธ์ React ์ฑ์ ๋จผ์ ๋ง๋ค๊ณ Fable/Elmish๋ก ์กธ์ ํด์ผ ํ๋ค๋ ์ธ์์ ๋ฐ๊ธฐ๋ ํฉ๋๋ค. ๋ฉด์ฑ ์กฐํญ: ์ ๋ Feliz ๋ฌธ์๋ฅผ ๊ด๋ฒ์ํ๊ฒ ์ฝ์ง ์์์ผ๋ฉฐ ์ ๋ง ์ข์ต๋๋ค. ๊ทธ๋์ ์ด๊ฒ์ ์๋ง๋ ์ ์ฑ ์์ ๋๋ค!
์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ณต์ ํด ์ฃผ์ ๋ชจ๋ ๋ถ๋ค๊ป ๊ฐ์ฌ๋๋ฆฝ๋๋ค!
@drk-mtr ์ ๋ ฅํด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
๋ด๊ฐ ์ฌ์ฉ์ ์ ์ ์์๋ฅผ ๋ง๋ค๊ณ ์๋ค๋ฉด ์ง๊ธ์ Fable.React ๋ฐฉ์์ผ๋ก ํ์ ๊ฒ์ ๋๋ค. ๋๋ "Feliz ๋ฐฉ์"์ผ๋ก ๊ฑด๋ฌผ์ ์ง๋ ๊ฒ์ ๋ณด๊ณ ์ฆ์ ๋๋ง์ณค์ต๋๋ค(์ธ์ ๊ฐ ๋ค์ ๋ฐฉ๋ฌธํ ์์ ์ ๋๋ค!).
์, ์ฒ์์๋ ๊ฝค ์ด๋ ค์ ๋ณด์ผ ์ ์์ง๋ง ์ต์ํด์ง๋ฉด ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํ ๋ ๊ฐ๋ฐ์์๊ฒ ์๋นํ ์ด๊ธฐ ๋น์ฉ์ด ๋ ๋ค๊ณ ํฉ๋๋ค. ๋๋ค์์ ์ฌ์ฉ์๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์์ฑํ์ง ์์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ด ๊ฝค ์์ฉ ๊ฐ๋ฅํ ์ ์ถฉ์์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ด ์ข๊ฒ๋ ์์ ์์ฒด๋ ๋งค์ฐ ๊ฐ๋จํ๋ฉฐ ์ผ๋ถ ๋ณต์ฌ + ๋ถ์ฌ๋ฃ๊ธฐ๋ ๋ง์ ์์ ์ ์๋๋ฅผ ๋์ผ ์ ์์ต๋๋ค(๋๋ ์ฐ๋ฆฌ ์ค ์ผ๋ถ์ฒ๋ผ ์ฝ๋๋ฅผ ๋น๋ํ๊ธฐ ์ํด ์์ฑ๊ธฐ๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ).
๋ฌธ์๊ฐ "์ด๊ฒ์ด ์ฌ์ฉ์ ์ ์ ์์ฑ์ ๋ง๋๋ ๋ฐฉ๋ฒ" ์ธก๋ฉด์ ๋ณด๋ค ์ ๊ธฐ์ ์ผ๋ก ์ฐ์ ์์๋ฅผ ๋ถ์ฌํ๋ค๋ฉด ์ ๋ง ์ ์ฉํ ๊ฒ์ ๋๋ค. ์์์ ์์ฑ์์ ํจ๊ป ์ด๋ฌํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ CSS์์ ๊ฐ๋ฅํ ๋ชจ๋ ๊ฒ์ ๋ํ API ํ๋ฉด์ ์ ๊ณตํ๋ ๋ฐ ์ข ์ข ์ด๋ ค์์ ๊ฒช์ ์ ์๋ค๋ ์ ์ ๋ฐ์๋ค์ด๋ ๊ฒ์ด ๊ณต์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค(์: ์๋ฅผ ๋ค์ด). ๋ฐ๋ผ์ ์ด๋ณด์๊ฐ "fontSize"๋ฅผ ์ค์ ํ ์ ์์ ๋ ๋งํ๊ฒ ๋๋ค๋ฉด "em"์ ์๊ฑฐ๋ "grid-template-rows"๋ฅผ ์ฐพ์ ์ ์๊ฑฐ๋ "Screen.All" ์ธ์๋ฅผ ์ ๊ณตํด์ผ ํ๋์ง ์ ํ ๋ชจ๋ฆ ๋๋ค. ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์์ผ๋ฉด ์ข์ ๊ฒ์ ๋๋ค.
๋น์ ์ด ์์ง ๋ชปํ๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ (์ด ์ปจํ ์คํธ์์๋ ๋งํ ์ ์์ต๋๋ค):
prop
๋ฐ style
์ ํ ๋ชจ๋์ custom
๋ฉ์๋๊ฐ ์์ต๋๋ค.
ICssUnit
๋ฅผ ํ์ฉํ๋ ๋ชจ๋ ๊ฒ์ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ ์ ์์ต๋๋ค. style.fontSize (length.em 1)
๋ฌธ์ ์ ๋ฐ์ดํธ๋ ์ถฉ๋ถํ ์ฌ์์ผ ํฉ๋๋ค.
๋ช ๊ฐ์ง ์ ์ฌ์ ์ธ ์ฐ๋ ค๋ฅผ ์์ ๊ธฐ ์์ํ๋ ์ผ๋ถ "์ถ์ ์ง" ๊ฐ์ ์ด ์ด๋ฃจ์ด์ง ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค... ์๋ฅผ ๋ค์ด Feliz์์ ์คํ์ผ ์ํ์ ๊ธด ์ธ๋ก ๋ชฉ๋ก์ ๋ณผ ๋ style.paddingHorizontal์ด ์์ ์ ์๋์ง ๊ถ๊ธํ๊ธฐ ์์ํฉ๋๋ค. style.padding์์ง. ๋๋ ๋ด ์์ ์ ๋์ฐ๋ฏธ๋ฅผ ๋ง๋ค ์ ์๋ค๋ ๊ฒ์ ๊นจ๋ฌ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ๊ธฐ๋ฅ์ ์์ฒญํ๋ ๊ณณ์ด ์๋๋ฉฐ ํ์ค์ด ์๋ ๊ฒ์ ๋์ ํ๋ ๊ฒ์ ํผํ๊ณ ์ถ์ ์๊ตฌ๊ฐ ์์ ์ ์์ต๋๋ค. :)
์ฌ์ฉ์ ๊ฒฝํ์ ๋ ์ฝ๊ฒ ๋ง๋๋ ๋ฐ ๋์์ด ๋๋ ๊ฒ์ ๋ฌด์์ด๋ ๋ด ์ฑ ์์ ํ์ํฉ๋๋ค. ๋๋ ๋น์ ์ด ๋ฐ๊ฒฌํ ์ด๋ฌํ ๊ฒ๋ค์ ๋ํ ์ด์/ํ๋ณด๋ฅผ ๋ณด๊ณ ์ถ์ต๋๋ค!
๋ ์ผ๋ฐ์ ์ผ๋ก ๊ทธ๋ฆฌ๊ณ ์๋ง๋ ์ ํ ์ ์์ต๋๋ค. ๋ด๊ฐ ์ง์์ ์ผ๋ก ๋ถ๋ช์น๋ ๋ฌธ์ ๋ Elmish ์ธ๊ณ๊ฐ ๋๋๊ณ React ์ธ๊ณ๊ฐ ์์๋๋ ์์น๋ฅผ ์ดํดํ๋ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ ์ค์ ๋ก ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๊ด์ฌ์ฌ๊ฐ ์๋๋๋ค. ๊ทธ๋ฌ๋ React์ ๋ํ ๊ฐ์ฅ ํ๋ฆฟํ ๋จ์๊ฐ ์๊ธฐ ๋๋ฌธ์ Fable.React ๋๋ Feliz์์ Function Component๋ฅผ ์ป์ ์ ์๋ค๋ ์ฌ์ค์ด ์ ๋ฅผ ํผ๋์ค๋ฝ๊ฒ ํฉ๋๋ค. ๋ฌผ๋ก ์ด๊ฒ์ ๋ฐฐ์ฐ๋ ๊ฒ์ ๋์ ์ฑ ์์ด์ง๋ง ์ธ๊ธํ ๊ฐ์น๊ฐ ์๋ค๊ณ ์๊ฐํ์ต๋๋ค. ์ ๋ ํ์ฌ Elmish์ React ์ ๊ทผ ๋ฐฉ์์ ํจ๊ป ์ฌ์ฉํ๊ณ ์์ผ๋ฉฐ ์ด๋ก ์ธํด ์ ๋ฐ์ดํธ ์ ๋ชจ๋ ๊ตฌ์ฑ ์์๊ฐ ๋ค์ ๋ ๋๋ง๋๋ค๊ณ ์๊ฐํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด์ ๊ฐ์ด ์์ ํ ๋น๋๋ ์ฑ์ ์๋ ์ฐพ๊ธฐ ํ๋ค๋ค. ๋๋ก๋ Javascript๋ก ํ๋ก๋์ ๋ฑ๊ธ์ React ์ฑ์ ๋จผ์ ๋ง๋ค๊ณ Fable/Elmish๋ก ์กธ์ ํด์ผ ํ๋ค๋ ์ธ์์ ๋ฐ๊ธฐ๋ ํฉ๋๋ค. ๋ฉด์ฑ ์กฐํญ: ์ ๋ Feliz ๋ฌธ์๋ฅผ ๊ด๋ฒ์ํ๊ฒ ์ฝ์ง ์์์ผ๋ฉฐ ์ ๋ง ์ข์ต๋๋ค. ๊ทธ๋์ ์ด๊ฒ์ ์๋ง๋ ์ ์ฑ ์์ ๋๋ค!
Fable ์ธ๊ณ(Feliz ์ด์ )์์์ ๋ด ๊ฒฝํ์ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ๋ชจ๋ ๊ฒ์ ์ผ๋ฐ ํจ์๋ก ์์ฑํ๋ค๋ ๊ฒ์ ๋๋ค(์: ๊ฐ .fs์ ๋ํ ํ๋์ ๊ตฌ์ฑ์์). ๊ทธ ๊ฒฐ๊ณผ React ์์คํ ์ด ์ ๊ณตํ๋ ๋ง์ ์ด์ ์ ์์์ต๋๋ค. Feliz๋ฅผ ์์ํ ์ดํ๋ก ๋๋ React๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง์ ๋ํด ๋ ๊น์ด ํ๊ณ ๋ค์ด์ผ ํ์ต๋๋ค. ์ต์ํด์ง๋๊น ๋ ์ด์ ์์์ ์ผ๋ก ์๊ฐํ์ง๋ ์๋๋ค. ๋ ๋๋ง์ ์ํํ๋ ๋ด๊ฐ ์์ฑํ ๋ชจ๋ ๋จ์ผ ํจ์๋ ํจ์ ๊ตฌ์ฑ ์์์ ๋๋ค.
๊ด์ฉ์ ์ผ๋ก React๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ ๋ง๋ก ๋ฐฐ์ฐ๊ณ ์ถ๋ค๋ฉด Elmish๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋ฐ๋ชจ ์ฑ์์ ๊ธฐ๋ฅ ๊ตฌ์ฑ ์์/ํํฌ๋ง ์ฌ์ฉํ๋๋ก ์ ํํ๋ ๊ฒ๋ง ํผ ๊ฐ๋จํ๋ค๊ณ ์๊ฐํฉ๋๋ค. API๊ฐ ๊ฑฐ์ ๋์ผํ๊ธฐ ๋๋ฌธ์ JS๋ก ์์ฑ๋ ๋ชจ๋ ๊ฒ์ ๋งค์ฐ ์ฝ๊ฒ ๋ฐ๋ผ๊ฐ ์ ์์ต๋๋ค.
Feliz๋ก ์์ฑ๋ ์์ง์ ์คํ ์์ค ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ฐ๋ ๊ฒ์ ํ์คํ ๋์์ด ๋ ๊ฒ์ ๋๋ค. ๋๋ ์ ์ ๋์ #67์ ๋ํ ๋ฌธ์ ๋ฅผ ๋ง๋ค์์ต๋๋ค. ์ง๊ธ ๊ฐ์ฅ ๊ฐ๊น์ด ๊ฒ์ ์๋ง๋ ๋ฌธ์ ์ฑ ์์ฒด ๋๋ @cmeeren ์ Electron Demo ์ผ ๊ฒ ์ ๋๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์๋ ํ์ธ์ @MangelMaxime ์ ๋๋ค .
์ฐ์ , ํ๋ก์ ํธ์์ Feliz๋ฅผ ์๋ํ๋ ๊ฒ๋ฟ๋ง ์๋๋ผ ๊ด๋ฒ์ํ ๋ถ์์ ์์ฑํ๊ธฐ ์ํด ์๊ฐ๊ณผ ๋ ธ๋ ฅ์ ๋ค์ธ ๊ฒ์ ๋ํด ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋ง์ Fable ์ฌ์ฉ์๊ฐ ๋งค์ฐ ์ ์ฉํ๊ณ ์ ์ตํ๋ค๋ ๊ฒ์ ์๊ฒ ๋ ๊ฒ์ด๋ผ๊ณ ํ์ ํฉ๋๋ค.
์ ๋ ์ด๋ฌํ ์ข ๋ฅ์ ํผ๋๋ฐฑ๊ณผ ๊ฐ๋ฐฉ์ฑ์ ์ ๋ง ๊ฐ์ฌํ๋ฉฐ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ํ๊ณ์ ํจ๊ป ํ ์ ์๋ ์ต์์ ์ํ๋ก ๋ง๋๋ ๊ฒ์ด ์ค์ํ๋ค๊ณ ๋ฏฟ์ต๋๋ค.
์ํ๊ณ์์ ์ผ์ข ์ ํน๋ณํ๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ Feliz.Bulma์ ๋ํด ์ ์ ์ด์ผ๊ธฐํ๊ฒ ์ต๋๋ค. ๋จผ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์ด๋ฏธ ๊ณ ์น ์ ์๋ ๋ช ๊ฐ์ง ๋ฌธ์ ์ ๋ํด ๋ต๋ณํ๊ฒ ์ต๋๋ค.
onChange
๊ณผ๋ถํ์ฌ์ค, ๋น์ ์ํ์ง ์์ต๋๋ค. ์ ํ์ ๋ค์๊ณผ ๊ฐ์ด ๋ฉ์์ง ์ ํ์์ ์ ์ถ๋์ด์ผ ํฉ๋๋ค.
ChangeGistToken
์ ์ ํ์ ๋ฐ๋ผ ์ฌ๋ฐ๋ฅธ ์ค๋ฒ๋ก๋๊ฐ ์ ์ถ๋ฉ๋๋ค. DU ์ผ์ด์ค๊ฐChangeGistToken of string
์ด๋ฉดstring -> unit
์ ๊ณผ๋ถํ๊ฐ ์ ํ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ ์ ๋ ฅ ์ ํ์ดfile
์ธ ๊ฒฝ์ฐFileSelected of File
์๋ ์์ต๋๋ค. ์ด ๊ฒฝ์ฐ ๊ณผ๋ถํFile -> unit
๊ฐ ์ ์ถ๋๋ ์์ ๋๋ค.ev.Value
์์Fable.React
ev.Value
์ ๊ตฌ๋ฌธ ์คํ์ด ํ์ํ์ง ์์ต๋๋ค.๋ค์ค ์ธ์ ์ฝ๋ฐฑ
@Shmew ๋ ์ด๋ฏธ ์ด ๋ฌธ์ ๋ฅผ ๋ค๋ฃจ์์ผ๋ฉฐ ์ค์ ๋ก ์ด๊ฒ์ด ์ด๋ฌํ ์ ํ์ ์์ฑ์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. Feliz ํ์ฅ์ ๊ตฌํํ ๋ ์์ฑ์ ์ค์ ํ๊ธฐ ์ ์ ๋ณํ ์ ์ํํ ์ ์์์ ์ดํดํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ด ๋ ผ๋ฆฌ์ ๋ฐ๋ผ ๋ด๋ถ์ ์ผ๋ก
'A -> 'B -> unit
๋ฅผFunc<'A, 'B, unit>
๋ก ๋ณํํ ์ ์์ต๋๋ค.์ด๊ฒ์ @Shmew์์ ์ ๊ณตํ๋ ๊ฒ๋ณด๋ค ๋ ๋ช ์์ ์ธ ๋ฒ์ ์ ๋๋ค(๋ฐ์ธ๋ฉ์ ๋ํด ์๊ณ ์๋ฏ์ด, ๋ฐ์ธ๋ฉ์ ์ฌ๊ธฐ์ ์์ต๋๋ค
Feliz ์ํ๊ณ์ ์ ํ ์์
์์์ ์ธ๊ธํ @Shmew : ์ ์ ํ Feliz ํ์ฅ์ ์๋ชป ๋์ํ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ ํ์ฉํ์ง ์์ผ๋ฉฐ ์์ฑ ์ ํ์ ์ ํํ๋ฉด ์ด๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค. Feliz.Recharts์ฒ๋ผ
prop
์ ์๋ ๊ธฐ์กด ์์ฑ๊ณผ์ ์ญํธํ์ฑ์ ํ์ฉํ๋IReactProperty
๋ฅผ ๋ฐํํ๋ ์์ฑ์ ๋น๋ํ๊ฑฐ๋ ์ง์ํ๊ธฐ ์ํด ๋ณด๋ค ์ ๋ฌธํ๋ ์ ํISpecialiedProperty
์ ๊ตฌํํ ์ ์์ต๋๋ค. ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํดIReactProperty
์์ ์ผ๋ถ ์์ฑ์ ์ด๋ฆ์ ๋ณต์ ํ๋ ๋์ ์์ฑ์ ํ์ ์งํฉ๋ง:์ด๊ฒ์ ๋ด๊ฐ Feliz.AntDesign์ผ๋ก ์ํํ ์์ ์ ๋๋ค. ์๋ฅผ ๋ค์ด ์ฌ๊ธฐ ์์
button
์ง์ ์ ์์ ์ฌ์ฉํ ์ ์๋๋ก ์ผ๋ถ ์์ฑ์ ๋ณต์ ํ๊ณ ์์ต๋๋ค(๋์ค์ ์์ฑ์ ์๊ฒฉํ ์ ํ์ผ๋ก ๋ ์ ๋ฌธํํ ์ ์์ง๋ง ์ฒ์์๋ , ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ์ฒ์ ์์ํ๋ ์์น์ ๋๋ค). Feliz.MaterialUI๋ ์์ฑ์ ์ ๋ฌธํํ๊ธฐ๋ณด๋คIReactProperty
๋ฅผ ํ์ฅํ๊ธฐ ์ํด ์ ์ฌํ ์์ ์ ์ํํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด๊ฒ์ Feliz.Bulma์ ๊ฒฝ์ฐ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.Feliz.Bulma ์ฌ๊ฑด
Feliz.Bulma๊ฐ ๊ตฌํ๋๊ธฐ ์ ์ CSS ์ ์ฉ ํ๋ ์์ํฌ๋ฅผ ์ํ Feliz ํ์ฅ์ ๊ตฌ์ถ ํ ํ์ ๊ฐ
yield
๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์ฌ ๋ ์ฝ์ต๋๋ค. ์ด๊ฒ์ TypedCssClasses ์ ๊ฒฐํฉํ๋ฉด CSS ์ ์ฉ ํ๋ ์์ํฌ๋ฅผ ๊ตฌํํ ํ์๊ฐ ์์ต๋๋ค. ๊ตฌํ ๋ฐ ์ ์ง ๊ด๋ฆฌ ๋น์ฉ์ด ์์ต๋๋ค. ์ง์ ๋ฌธ์ ์น์ฌ์ดํธ๋ฅผ ๊ตฌ์ถํ ํ์ ์์ด ํ์ดํ๋ ์คํ์ผ์ํธ๋ฅผ ์ฌ์ฉํ๊ณ ํ๋ก์ ํธ ์์ฒด์ ๋ํ ์ด๋ฏธ ์ ๋ง ์ข์ ๋ฌธ์๋ฅผ ์ฌ์ฉํ์ญ์์ค.๊ทธ๋ฌ๋ @Dzoukr์ด Feliz.Bulma๋ฅผ ๊ตฌํํ ๊ฒ์ ๋ณธ ํ์๋ ์ดํด๊ฐ ๋์์ต๋๋ค. Bulma์ ํ ๋ชจ๋์์ CSS ๊ตฌ์ฑ ์์์ ํน์ "์ง์ ์ "์ ๋์ ํ์ฌ ์ฝ๋๋ฅผ ๋ง์ด ๋จ์ํํ์ฌ
Bulma.button
๋ฅผ ์ป์ ์ ์์์ต๋๋คBulma.card
๋ฑ. ์ฌ์ฉํ๊ธฐ ์ ๋ง ์ข์ต๋๋ค. ์์ ์์ ๊ดํด์๋ Roman์ ์ ๊ทผ ๋ฐฉ์์ด ๋ฐ๋ฅด๊ธฐ ์ฝ๊ณ ์์ ํ๊ธฐ ์ฝ๋ค๊ณ ์๊ฐํ์ง๋ง ๋ง์ํ์ ๊ฒ์ฒ๋ผ ๋๋ก๋ ํฅ๋ฏธ๋ก์ด ๊ฒฐ๊ณผ๋ฅผ ์ค ์๋ ์์ต๋๋ค. ํ์คํ ๊ทธ ๋ถ์์์ ๋ ๊ฐ์ ํด์ผ ํ ์ ์ด ์์ผ๋ฉฐ ์ด์จ๋ Roman์ Feliz์ ๋น์ ์ ๋ฐ๋ผ ๋ฐฐ์ฐ๊ณ ์ฌ์ฉํ๊ธฐ ์ฌ์ด ๊ฒ์ ๊ตฌ์ถํ๋ ๋ฐ ํฐ ์ญํ ์ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.Feliz์ ํจํค์ง ๊ด๋ฆฌ
ํ์ฌ
Fable.React
๋ฐFeliz
์ ํฐ ์ฐจ์ด์ ์ ์ง์ ํ๊ณ ์ถ์ต๋๋ค. ํจํค์ง ๋ฒ์ ๊ด๋ฆฌ ๋ฐ ๊ด๋ฆฌ์ ๋๋ค. Feliz ๋ฒ์ ์ ๋ชจ๋ ์ํ๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ Femto์ ํธํ๋๋ฏ๋ก ํ์ํ npm ํจํค์ง๋ฅผ ์๋์ผ๋ก ์ค์นํ๊ฑฐ๋ ํธํ๋๋ ๋ฒ์ ์ ์์์ผ ํ๋ ์ฌ์ฉ์์ ๋ถ๋ด์ ์ ๊ฑฐํฉ๋๋ค. ์ด๊ฒ์ ๋ชจ๋ ํ์Fable.React
๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฌ์ง์ด ๊ทธ๋ ์ง ์์Fable.React
์์ฒด์๋ ๋ค๋ฆ ๋๋ค.ํฅํ ๊ณํ