Changes
9 changed files (+185/-55)
-
-
@@ -10,7 +10,7 @@module Parameters.Form exposing (Model, Msg(..), init, update, view) import Dict exposing (Dict) import Html exposing (div, input, label, node, p, span, text) import Html exposing (hr, input, label, node, p, span, text) import Html.Attributes exposing (..) import Html.Events exposing (onInput) import Length exposing (Length, toMM)
-
@@ -348,52 +348,75 @@ )] type alias GroupProps msg = { title : List (Html.Html msg) } group : GroupProps InternalMsg -> List (Html.Html InternalMsg) -> Html.Html InternalMsg group { title } children = node "x-field-group" [] (p [ attribute "slot" "title" ] title :: children) view : Model -> Parameters -> List (Html.Attribute InternalMsg) -> Html.Html Msg view model params attrs = div attrs [ field model { key = LugWidth , title = [ text "Lug width" ] , description = [ text "This will be the final width of your strap. " , text "You can use a size smaller than your lug width to create a play." ] , unit = Just "mm" , attrs = step "1.0" :: lengthFieldAttrs constraints.lugWidth } , field model { key = BuckleHoleCount , title = [ text "Hole Count" ] , description = [ text "Set 0 to disable buckle holes generation." ] , unit = Nothing , attrs = step "1" :: intFieldAttrs constraints.longPiece.buckleHole.count } , field model { key = BuckleHoleDiameter , title = [ text "Hole Diameter" ] , description = [ text "Diameter of buckle holes. You can leave the default value if you're going to use the center mark." ] , unit = Just "mm" , attrs = step "1.0" :: disabled (params.longPiece.buckleHole.count == 0) :: lengthFieldAttrs constraints.longPiece.buckleHole.diameter } , field model { key = CanvasMargin , title = [ text "Print Margin" ] , description = [ text "Lower values can cause printing problems depending on your printer." ] , unit = Just "mm" , attrs = step "1.0" :: lengthFieldAttrs constraints.rendering.margin } , field model { key = LineWidth , title = [ text "Line Width" ] , description = [ text "Stroke width (thickness) of the cutting lines and seam lines." ] , unit = Just "mm" , attrs = step "0.1" :: lengthFieldAttrs constraints.rendering.lineWidth } node "x-parameters" attrs [ group { title = [ text "General" ] } [ field model { key = LugWidth , title = [ text "Lug width" ] , description = [ text "This will be the final width of your strap. " , text "You can use a size smaller than your lug width to create a play." ] , unit = Just "mm" , attrs = step "1.0" :: lengthFieldAttrs constraints.lugWidth } ] , hr [] [] , group { title = [ text "Buckle / Clasp" ] } [ field model { key = BuckleHoleCount , title = [ text "Hole Count" ] , description = [ text "Set 0 to disable buckle holes generation." ] , unit = Nothing , attrs = step "1" :: intFieldAttrs constraints.longPiece.buckleHole.count } , field model { key = BuckleHoleDiameter , title = [ text "Hole Diameter" ] , description = [ text "Diameter of buckle holes. You can leave the default value if you're going to use the center mark." ] , unit = Just "mm" , attrs = step "1.0" :: disabled (params.longPiece.buckleHole.count == 0) :: lengthFieldAttrs constraints.longPiece.buckleHole.diameter } ] , hr [] [] , group { title = [ text "Rendering" ] } [ field model { key = CanvasMargin , title = [ text "Print Margin" ] , description = [ text "Lower values can cause printing problems depending on your printer." ] , unit = Just "mm" , attrs = step "1.0" :: lengthFieldAttrs constraints.rendering.margin } , field model { key = LineWidth , title = [ text "Line Width" ] , description = [ text "Stroke width (thickness) of the cutting lines and seam lines." ] , unit = Just "mm" , attrs = step "0.1" :: lengthFieldAttrs constraints.rendering.lineWidth } ] ] |> Html.map Internal
-
-
-
@@ -8,12 +8,16 @@ // SPDX-License-Identifier: MPL-2.0import { XAppLayout } from "./x-app-layout.js"; import { XField } from "./x-field.js"; import { XFieldGroup } from "./x-field-group.js"; import { XNumberInput } from "./x-number-input.js"; import { XPanel } from "./x-panel.js"; import { XParameters } from "./x-parameters.js"; import { XPreview } from "./x-preview.js"; customElements.define("x-app-layout", XAppLayout); customElements.define("x-field", XField); customElements.define("x-field-group", XFieldGroup); customElements.define("x-number-input", XNumberInput); customElements.define("x-panel", XPanel); customElements.define("x-parameters", XParameters); customElements.define("x-preview", XPreview);
-
-
-
@@ -0,0 +1,25 @@/* * Copyright 2026 Shota FUJI * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * SPDX-License-Identifier: MPL-2.0 */ :host { display: flex; flex-direction: column; gap: 0.5rem; padding: 1em; } .header { margin-bottom: 1rem; } ::slotted([slot="title"]) { font-weight: 300; font-size: 1.2rem; }
-
-
-
@@ -0,0 +1,34 @@// Copyright 2026 Shota FUJI // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. // // SPDX-License-Identifier: MPL-2.0 import css from "./x-field-group.css"; export class XFieldGroup extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: "open", }); const style = document.createElement("style"); style.textContent = css; shadow.appendChild(style); const header = document.createElement("div"); header.classList.add("header"); shadow.appendChild(header); const title = document.createElement("slot"); title.name = "title"; header.appendChild(title); const slot = document.createElement("slot"); shadow.appendChild(slot); } }
-
-
-
@@ -12,8 +12,6 @@ :host {display: flex; flex-direction: column; gap: 0.1em; /* TODO: Let the consumer set spacing */ margin-top: 1em; } ::slotted([slot="title"]) {
-
@@ -31,16 +29,16 @@ border-color: oklch(40% 0.88 2deg);} ::slotted([slot="description"]), ::slotted([slot="error"]) { margin: 0.5em 0; margin-top: 0.25em; padding: 0.5em 0; padding-top: 0.25em; font-size: 0.8rem; opacity: 0.9; } ::slotted([slot="error"]) { margin-bottom: 0; min-height: 1.5em; padding-bottom: 0; min-height: 1.75em; line-height: 1.5; color: red;
-
-
-
@@ -10,8 +10,8 @@ */:host { display: block; padding: 0.5em 1em; border: 1px solid oklch(0% 0 0deg / 0.2); border: none; border-inline-start: 1px solid ButtonFace; background-color: Canvas; box-shadow: 0 0 3px oklch(0% 0 0deg / 0.2);
-
-
-
@@ -0,0 +1,19 @@/* * Copyright 2026 Shota FUJI * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. * * SPDX-License-Identifier: MPL-2.0 */ :host { display: flex; flex-direction: column; } ::slotted(hr) { border: none; border-top: 1px solid ButtonFace; }
-
-
-
@@ -0,0 +1,26 @@// Copyright 2026 Shota FUJI // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. // // SPDX-License-Identifier: MPL-2.0 import css from "./x-parameters.css"; export class XParameters extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: "open", }); const style = document.createElement("style"); style.textContent = css; shadow.appendChild(style); const slot = document.createElement("slot"); shadow.appendChild(slot); } }
-
-
-
@@ -21,8 +21,9 @@ Elm.Main.init();}); </script> <style> *, *::before, *::after { :where(*, *::before, *::after) { box-sizing: border-box; margin: 0; } @font-face {
-