diff --git a/docs/sw/firefox-range-qa/chrome-disabled.png b/docs/sw/firefox-range-qa/chrome-disabled.png new file mode 100644 index 0000000..e622305 Binary files /dev/null and b/docs/sw/firefox-range-qa/chrome-disabled.png differ diff --git a/docs/sw/firefox-range-qa/chrome-enter-commit.png b/docs/sw/firefox-range-qa/chrome-enter-commit.png new file mode 100644 index 0000000..ace9a56 Binary files /dev/null and b/docs/sw/firefox-range-qa/chrome-enter-commit.png differ diff --git a/docs/sw/firefox-range-qa/chrome-external-0.8.png b/docs/sw/firefox-range-qa/chrome-external-0.8.png new file mode 100644 index 0000000..8e97a48 Binary files /dev/null and b/docs/sw/firefox-range-qa/chrome-external-0.8.png differ diff --git a/docs/sw/firefox-range-qa/chrome-initial.png b/docs/sw/firefox-range-qa/chrome-initial.png new file mode 100644 index 0000000..edd926f Binary files /dev/null and b/docs/sw/firefox-range-qa/chrome-initial.png differ diff --git a/docs/sw/firefox-range-qa/chrome-keyboard-0.65.png b/docs/sw/firefox-range-qa/chrome-keyboard-0.65.png new file mode 100644 index 0000000..ace9a56 Binary files /dev/null and b/docs/sw/firefox-range-qa/chrome-keyboard-0.65.png differ diff --git a/docs/sw/firefox-range-qa/chrome-max.png b/docs/sw/firefox-range-qa/chrome-max.png new file mode 100644 index 0000000..b0ec810 Binary files /dev/null and b/docs/sw/firefox-range-qa/chrome-max.png differ diff --git a/docs/sw/firefox-range-qa/chrome-min.png b/docs/sw/firefox-range-qa/chrome-min.png new file mode 100644 index 0000000..903d2c5 Binary files /dev/null and b/docs/sw/firefox-range-qa/chrome-min.png differ diff --git a/docs/sw/firefox-range-qa/chrome-readonly.png b/docs/sw/firefox-range-qa/chrome-readonly.png new file mode 100644 index 0000000..8e97a48 Binary files /dev/null and b/docs/sw/firefox-range-qa/chrome-readonly.png differ diff --git a/docs/sw/firefox-range-qa/chrome-restored.png b/docs/sw/firefox-range-qa/chrome-restored.png new file mode 100644 index 0000000..903d2c5 Binary files /dev/null and b/docs/sw/firefox-range-qa/chrome-restored.png differ diff --git a/docs/sw/firefox-range-qa/compare-chrome-firefox.png b/docs/sw/firefox-range-qa/compare-chrome-firefox.png new file mode 100644 index 0000000..f2d1436 Binary files /dev/null and b/docs/sw/firefox-range-qa/compare-chrome-firefox.png differ diff --git a/docs/sw/firefox-range-qa/firefox-disabled.png b/docs/sw/firefox-range-qa/firefox-disabled.png new file mode 100644 index 0000000..8db5334 Binary files /dev/null and b/docs/sw/firefox-range-qa/firefox-disabled.png differ diff --git a/docs/sw/firefox-range-qa/firefox-enter-commit.png b/docs/sw/firefox-range-qa/firefox-enter-commit.png new file mode 100644 index 0000000..68ef22e Binary files /dev/null and b/docs/sw/firefox-range-qa/firefox-enter-commit.png differ diff --git a/docs/sw/firefox-range-qa/firefox-external-0.8.png b/docs/sw/firefox-range-qa/firefox-external-0.8.png new file mode 100644 index 0000000..88343f2 Binary files /dev/null and b/docs/sw/firefox-range-qa/firefox-external-0.8.png differ diff --git a/docs/sw/firefox-range-qa/firefox-initial.png b/docs/sw/firefox-range-qa/firefox-initial.png new file mode 100644 index 0000000..068db37 Binary files /dev/null and b/docs/sw/firefox-range-qa/firefox-initial.png differ diff --git a/docs/sw/firefox-range-qa/firefox-keyboard-0.65.png b/docs/sw/firefox-range-qa/firefox-keyboard-0.65.png new file mode 100644 index 0000000..68ef22e Binary files /dev/null and b/docs/sw/firefox-range-qa/firefox-keyboard-0.65.png differ diff --git a/docs/sw/firefox-range-qa/firefox-max.png b/docs/sw/firefox-range-qa/firefox-max.png new file mode 100644 index 0000000..e244942 Binary files /dev/null and b/docs/sw/firefox-range-qa/firefox-max.png differ diff --git a/docs/sw/firefox-range-qa/firefox-min.png b/docs/sw/firefox-range-qa/firefox-min.png new file mode 100644 index 0000000..78e8bfb Binary files /dev/null and b/docs/sw/firefox-range-qa/firefox-min.png differ diff --git a/docs/sw/firefox-range-qa/firefox-readonly.png b/docs/sw/firefox-range-qa/firefox-readonly.png new file mode 100644 index 0000000..88343f2 Binary files /dev/null and b/docs/sw/firefox-range-qa/firefox-readonly.png differ diff --git a/docs/sw/firefox-range-qa/firefox-restored.png b/docs/sw/firefox-range-qa/firefox-restored.png new file mode 100644 index 0000000..78e8bfb Binary files /dev/null and b/docs/sw/firefox-range-qa/firefox-restored.png differ diff --git a/docs/sw/firefox-range-qa/result.json b/docs/sw/firefox-range-qa/result.json new file mode 100644 index 0000000..1fd969c --- /dev/null +++ b/docs/sw/firefox-range-qa/result.json @@ -0,0 +1,1830 @@ +{ + "story": "http://127.0.0.1:6024/iframe.html?id=sw-header--property-panel&viewMode=story", + "viewport": { + "width": 1400, + "height": 1000 + }, + "browsers": { + "chrome": { + "version": "155.0.8059.80", + "errors": [] + }, + "firefox": { + "version": "158.0", + "errors": [ + "downloadable font: download failed (font-family: \"Nunito Sans\" style:normal weight:400 width:100 src index:0): status=2147746065 source: http://127.0.0.1:6024/sb-common-assets/nunito-sans-regular.woff2" + ] + } + }, + "steps": [ + { + "step": "initial", + "chrome": { + "step": "initial", + "value": "0.25", + "fill": "0.25", + "disabled": false, + "number": "0.25", + "x": 1277.65625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true)", + "focused": false, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.65625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 19, + "right": 30, + "top": 1, + "bottom": 14, + "cx": 25, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1616", + "7a0000", + "000000", + "eadec8", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eadec8", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "firefox": { + "step": "initial", + "value": "0.25", + "fill": "0.25", + "disabled": false, + "number": "0.25", + "x": 1277.6666259765625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true)", + "focused": false, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.6666259765625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 19, + "right": 30, + "top": 1, + "bottom": 14, + "cx": 25, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1515", + "7a0000", + "000000", + "ede5d4", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eee5d5", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.06, + "over16": 76, + "over48": 1 + } + }, + { + "step": "keyboard-0.65", + "chrome": { + "step": "keyboard-0.65", + "value": "0.65", + "fill": "0.65", + "disabled": false, + "number": "0.25", + "x": 1277.65625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true)", + "focused": true, + "focusVisible": true, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.65625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 47, + "right": 58, + "top": 1, + "bottom": 14, + "cx": 53, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1616", + "7a0000", + "000000", + "eadec8", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eadec8", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "firefox": { + "step": "keyboard-0.65", + "value": "0.65", + "fill": "0.65", + "disabled": false, + "number": "0.25", + "x": 1277.6666259765625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true)", + "focused": true, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.6666259765625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 47, + "right": 58, + "top": 1, + "bottom": 14, + "cx": 53, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1515", + "7a0000", + "000000", + "ede5d4", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eee5d5", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.08, + "over16": 76, + "over48": 1 + } + }, + { + "step": "enter-commit", + "chrome": { + "step": "enter-commit", + "value": "0.65", + "fill": "0.65", + "disabled": false, + "number": "0.65", + "x": 1277.65625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": true, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.65625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 47, + "right": 58, + "top": 1, + "bottom": 14, + "cx": 53, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1616", + "7a0000", + "000000", + "eadec8", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eadec8", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "firefox": { + "step": "enter-commit", + "value": "0.65", + "fill": "0.65", + "disabled": false, + "number": "0.65", + "x": 1277.6666259765625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.6666259765625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 47, + "right": 58, + "top": 1, + "bottom": 14, + "cx": 53, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1515", + "7a0000", + "000000", + "ede5d4", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eee5d5", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.08, + "over16": 76, + "over48": 1 + } + }, + { + "step": "max", + "chrome": { + "step": "max", + "value": "1", + "fill": "1", + "disabled": false, + "number": "0.65", + "x": 1277.65625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": true, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.65625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 73, + "right": 84, + "top": 1, + "bottom": 14, + "cx": 79, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1616", + "7a0000", + "000000", + "eadec8", + "f1ece1" + ], + "trackCol": [ + "f06161", + "e76161", + "d74e4e", + "c62929", + "a41111", + "780808", + "510000", + "510000", + "5e0000", + "640000" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 3, + "to": 12, + "rows": 10 + } + } + }, + "firefox": { + "step": "max", + "value": "1", + "fill": "1", + "disabled": false, + "number": "0.65", + "x": 1277.6666259765625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.6666259765625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 73, + "right": 84, + "top": 1, + "bottom": 14, + "cx": 79, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1515", + "7a0000", + "000000", + "ede5d4", + "f1ece1" + ], + "trackCol": [ + "f16262", + "e85e5e", + "d74f4f", + "c62929", + "a41212", + "780808", + "510000", + "510000", + "630000", + "630000" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 3, + "to": 12, + "rows": 10 + } + } + }, + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.09, + "over16": 75, + "over48": 1 + } + }, + { + "step": "min", + "chrome": { + "step": "min", + "value": "0", + "fill": "0", + "disabled": false, + "number": "0.65", + "x": 1277.65625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": true, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.65625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 1, + "right": 12, + "top": 1, + "bottom": 14, + "cx": 7, + "cy": 8 + }, + "fillCol": [ + "f55252", + "f87777", + "f9aaaa", + "ca7474", + "903030", + "851818", + "961a1a", + "a51c1c", + "af1515", + "a90d0d" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eadec8", + "f1ece1" + ], + "fillExtent": { + "from": 3, + "to": 12, + "rows": 10 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "firefox": { + "step": "min", + "value": "0", + "fill": "0", + "disabled": false, + "number": "0.65", + "x": 1277.6666259765625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.6666259765625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 1, + "right": 12, + "top": 1, + "bottom": 14, + "cx": 7, + "cy": 8 + }, + "fillCol": [ + "f55252", + "f87474", + "f9aaaa", + "ca7474", + "903030", + "851818", + "961a1a", + "a51c1c", + "b21515", + "a90d0d" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eee5d5", + "f1ece1" + ], + "fillExtent": { + "from": 3, + "to": 12, + "rows": 10 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "diff": { + "pixels": 1800, + "max": 29, + "mean": 1.96, + "over16": 71, + "over48": 0 + } + }, + { + "step": "external-0.8", + "chrome": { + "step": "external-0.8", + "value": "0.8", + "fill": "0.8", + "disabled": false, + "number": "0.8", + "x": 1277.65625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": true, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.65625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 14, + "cx": 64, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1616", + "7a0000", + "000000", + "eadec8", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eadec8", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "firefox": { + "step": "external-0.8", + "value": "0.8", + "fill": "0.8", + "disabled": false, + "number": "0.8", + "x": 1277.6666259765625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.6666259765625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 14, + "cx": 64, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1515", + "7a0000", + "000000", + "ede5d4", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eee5d5", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.08, + "over16": 76, + "over48": 1 + } + }, + { + "step": "disabled", + "chrome": { + "step": "disabled", + "value": "0.8", + "fill": "0.8", + "disabled": true, + "number": "0.8", + "x": 1277.65625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": false, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.65625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 13, + "cx": 64, + "cy": 7.5 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "918e87", + "d99790", + "f7a8a1", + "f09790", + "c28e87", + "918e87", + "efe7d7", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "d7cfbf", + "dfd8c9", + "e1dacb", + "e1dacb", + "dad3c3", + "d6cdbc", + "efe7d7", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 10, + "rows": 6 + }, + "trackExtent": { + "from": 5, + "to": 10, + "rows": 6 + } + } + }, + "firefox": { + "step": "disabled", + "value": "0.8", + "fill": "0.8", + "disabled": true, + "number": "0.8", + "x": 1277.6666259765625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": false, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.6666259765625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 13, + "cx": 64, + "cy": 7.5 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "908d86", + "d8968f", + "f6a6a0", + "ef958e", + "c18d86", + "908d86", + "f0e9dc", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "d6cebe", + "ded7c8", + "e0d9ca", + "e0d9ca", + "d9d2c2", + "d5ccbb", + "f0eadc", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 10, + "rows": 6 + }, + "trackExtent": { + "from": 5, + "to": 10, + "rows": 6 + } + } + }, + "diff": { + "pixels": 1800, + "max": 21, + "mean": 1.15, + "over16": 2, + "over48": 0 + } + }, + { + "step": "readonly", + "chrome": { + "step": "readonly", + "value": "0.8", + "fill": "0.8", + "disabled": true, + "number": "0.8", + "x": 1277.65625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": false, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.65625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 14, + "cx": 64, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1616", + "7a0000", + "000000", + "eadec8", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eadec8", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "firefox": { + "step": "readonly", + "value": "0.8", + "fill": "0.8", + "disabled": true, + "number": "0.8", + "x": 1277.6666259765625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": false, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.6666259765625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 14, + "cx": 64, + "cy": 8 + }, + "fillCol": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1515", + "7a0000", + "000000", + "ede5d4", + "f1ece1" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eee5d5", + "f1ece1" + ], + "fillExtent": { + "from": 5, + "to": 11, + "rows": 7 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.08, + "over16": 76, + "over48": 1 + } + }, + { + "step": "restored", + "chrome": { + "step": "restored", + "value": "0", + "fill": "0", + "disabled": false, + "number": "0.8", + "x": 1277.65625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": true, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.65625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 1, + "right": 12, + "top": 1, + "bottom": 14, + "cx": 7, + "cy": 8 + }, + "fillCol": [ + "f55252", + "f87777", + "f9aaaa", + "ca7474", + "903030", + "851818", + "961a1a", + "a51c1c", + "af1515", + "a90d0d" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eadec8", + "f1ece1" + ], + "fillExtent": { + "from": 3, + "to": 12, + "rows": 10 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "firefox": { + "step": "restored", + "value": "0", + "fill": "0", + "disabled": false, + "number": "0.8", + "x": 1277.6666259765625, + "y": 613.5, + "w": 86, + "h": 16, + "log": "legacyToggle → open(true) → property(opacity, 0.65)", + "focused": true, + "focusVisible": false, + "outline": "none rgb(0, 0, 0)", + "offset": { + "x": 1.6666259765625, + "y": 1.5 + }, + "pixels": { + "thumb": { + "left": 1, + "right": 12, + "top": 1, + "bottom": 14, + "cx": 7, + "cy": 8 + }, + "fillCol": [ + "f55252", + "f87474", + "f9aaaa", + "ca7474", + "903030", + "851818", + "961a1a", + "a51c1c", + "b21515", + "a90d0d" + ], + "trackCol": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eee5d5", + "f1ece1" + ], + "fillExtent": { + "from": 3, + "to": 12, + "rows": 10 + }, + "trackExtent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + "diff": { + "pixels": 1800, + "max": 29, + "mean": 1.96, + "over16": 71, + "over48": 0 + } + } + ], + "checks": [ + { + "name": "chrome 1-3 red fill / beige track / black-edged 6px", + "status": "PASS", + "data": { + "fill": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1616", + "7a0000", + "000000", + "eadec8", + "f1ece1" + ], + "track": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eadec8", + "f1ece1" + ], + "extent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + { + "name": "chrome 4-5 thumb 14px, vertically centred on the track", + "status": "PASS", + "data": { + "left": 19, + "right": 30, + "top": 1, + "bottom": 14, + "cx": 25, + "cy": 8 + } + }, + { + "name": "chrome 6-8/10 min: value 0, thumb centre 7 ≈ 7", + "status": "PASS", + "data": { + "value": "0", + "fill": "0", + "cx": 7 + } + }, + { + "name": "chrome 6-8/10 initial: value 0.25, thumb centre 25 ≈ 25", + "status": "PASS", + "data": { + "value": "0.25", + "fill": "0.25", + "cx": 25 + } + }, + { + "name": "chrome 6-8/10 keyboard-0.65: value 0.65, thumb centre 53 ≈ 53.800000000000004", + "status": "PASS", + "data": { + "value": "0.65", + "fill": "0.65", + "cx": 53 + } + }, + { + "name": "chrome 6-8/10 max: value 1, thumb centre 79 ≈ 79", + "status": "PASS", + "data": { + "value": "1", + "fill": "1", + "cx": 79 + } + }, + { + "name": "chrome 6-8/10 external-0.8: value 0.8, thumb centre 64 ≈ 64.6", + "status": "PASS", + "data": { + "value": "0.8", + "fill": "0.8", + "cx": 64 + } + }, + { + "name": "chrome 9 keyboard + Enter commit", + "status": "PASS", + "data": { + "value": "0.65", + "number": "0.65", + "log": "legacyToggle → open(true) → property(opacity, 0.65)" + } + }, + { + "name": "chrome 11 disabled / readOnly block keys, keep design", + "status": "PASS", + "data": { + "disabled": [ + true, + "0.8" + ], + "readonly": [ + true, + "0.8" + ], + "restored": [ + false, + "0" + ] + } + }, + { + "name": "chrome 12 no console / page errors", + "status": "PASS", + "data": [] + }, + { + "name": "firefox 1-3 red fill / beige track / black-edged 6px", + "status": "PASS", + "data": { + "fill": [ + "f1ece1", + "f1ece1", + "000000", + "b51717", + "fe4040", + "ed1515", + "7a0000", + "000000", + "ede5d4", + "f1ece1" + ], + "track": [ + "f1ece1", + "f1ece1", + "aea28b", + "c3b9a4", + "c7bda9", + "c7bda9", + "b7ac96", + "ac9e84", + "eee5d5", + "f1ece1" + ], + "extent": { + "from": 5, + "to": 11, + "rows": 7 + } + } + }, + { + "name": "firefox 4-5 thumb 14px, vertically centred on the track", + "status": "PASS", + "data": { + "left": 19, + "right": 30, + "top": 1, + "bottom": 14, + "cx": 25, + "cy": 8 + } + }, + { + "name": "firefox 6-8/10 min: value 0, thumb centre 7 ≈ 7", + "status": "PASS", + "data": { + "value": "0", + "fill": "0", + "cx": 7 + } + }, + { + "name": "firefox 6-8/10 initial: value 0.25, thumb centre 25 ≈ 25", + "status": "PASS", + "data": { + "value": "0.25", + "fill": "0.25", + "cx": 25 + } + }, + { + "name": "firefox 6-8/10 keyboard-0.65: value 0.65, thumb centre 53 ≈ 53.800000000000004", + "status": "PASS", + "data": { + "value": "0.65", + "fill": "0.65", + "cx": 53 + } + }, + { + "name": "firefox 6-8/10 max: value 1, thumb centre 79 ≈ 79", + "status": "PASS", + "data": { + "value": "1", + "fill": "1", + "cx": 79 + } + }, + { + "name": "firefox 6-8/10 external-0.8: value 0.8, thumb centre 64 ≈ 64.6", + "status": "PASS", + "data": { + "value": "0.8", + "fill": "0.8", + "cx": 64 + } + }, + { + "name": "firefox 9 keyboard + Enter commit", + "status": "PASS", + "data": { + "value": "0.65", + "number": "0.65", + "log": "legacyToggle → open(true) → property(opacity, 0.65)" + } + }, + { + "name": "firefox 11 disabled / readOnly block keys, keep design", + "status": "PASS", + "data": { + "disabled": [ + true, + "0.8" + ], + "readonly": [ + true, + "0.8" + ], + "restored": [ + false, + "0" + ] + } + }, + { + "name": "firefox 12 no console / page errors", + "status": "PASS", + "data": [ + "downloadable font: download failed (font-family: \"Nunito Sans\" style:normal weight:400 width:100 src index:0): status=2147746065 source: http://127.0.0.1:6024/sb-common-assets/nunito-sans-regular.woff2" + ] + }, + { + "name": "compare initial: columns ±3, thumb ±1px, ≤12 px differ > 48", + "status": "PASS", + "data": { + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.06, + "over16": 76, + "over48": 1 + }, + "focus": [ + false, + false + ], + "chromeThumb": { + "left": 19, + "right": 30, + "top": 1, + "bottom": 14, + "cx": 25, + "cy": 8 + }, + "firefoxThumb": { + "left": 19, + "right": 30, + "top": 1, + "bottom": 14, + "cx": 25, + "cy": 8 + }, + "highlight": [ + "eadec8", + "ede5d4" + ] + } + }, + { + "name": "compare keyboard-0.65: columns ±3, thumb ±1px, ≤12 px differ > 48", + "status": "PASS", + "data": { + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.08, + "over16": 76, + "over48": 1 + }, + "focus": [ + true, + false + ], + "chromeThumb": { + "left": 47, + "right": 58, + "top": 1, + "bottom": 14, + "cx": 53, + "cy": 8 + }, + "firefoxThumb": { + "left": 47, + "right": 58, + "top": 1, + "bottom": 14, + "cx": 53, + "cy": 8 + }, + "highlight": [ + "eadec8", + "ede5d4" + ] + } + }, + { + "name": "compare enter-commit: columns ±3, thumb ±1px, ≤12 px differ > 48", + "status": "PASS", + "data": { + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.08, + "over16": 76, + "over48": 1 + }, + "focus": [ + true, + false + ], + "chromeThumb": { + "left": 47, + "right": 58, + "top": 1, + "bottom": 14, + "cx": 53, + "cy": 8 + }, + "firefoxThumb": { + "left": 47, + "right": 58, + "top": 1, + "bottom": 14, + "cx": 53, + "cy": 8 + }, + "highlight": [ + "eadec8", + "ede5d4" + ] + } + }, + { + "name": "compare max: columns ±3, thumb ±1px, ≤12 px differ > 48", + "status": "PASS", + "data": { + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.09, + "over16": 75, + "over48": 1 + }, + "focus": [ + true, + false + ], + "chromeThumb": { + "left": 73, + "right": 84, + "top": 1, + "bottom": 14, + "cx": 79, + "cy": 8 + }, + "firefoxThumb": { + "left": 73, + "right": 84, + "top": 1, + "bottom": 14, + "cx": 79, + "cy": 8 + }, + "highlight": [ + "eadec8", + "ede5d4" + ] + } + }, + { + "name": "compare min: columns ±3, thumb ±1px, ≤12 px differ > 48", + "status": "PASS", + "data": { + "diff": { + "pixels": 1800, + "max": 29, + "mean": 1.96, + "over16": 71, + "over48": 0 + }, + "focus": [ + true, + false + ], + "chromeThumb": { + "left": 1, + "right": 12, + "top": 1, + "bottom": 14, + "cx": 7, + "cy": 8 + }, + "firefoxThumb": { + "left": 1, + "right": 12, + "top": 1, + "bottom": 14, + "cx": 7, + "cy": 8 + }, + "highlight": [ + "af1515", + "b21515" + ] + } + }, + { + "name": "compare external-0.8: columns ±3, thumb ±1px, ≤12 px differ > 48", + "status": "PASS", + "data": { + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.08, + "over16": 76, + "over48": 1 + }, + "focus": [ + true, + false + ], + "chromeThumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 14, + "cx": 64, + "cy": 8 + }, + "firefoxThumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 14, + "cx": 64, + "cy": 8 + }, + "highlight": [ + "eadec8", + "ede5d4" + ] + } + }, + { + "name": "compare disabled: columns ±3, thumb ±1px, ≤12 px differ > 48", + "status": "PASS", + "data": { + "diff": { + "pixels": 1800, + "max": 21, + "mean": 1.15, + "over16": 2, + "over48": 0 + }, + "focus": [ + false, + false + ], + "chromeThumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 13, + "cx": 64, + "cy": 7.5 + }, + "firefoxThumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 13, + "cx": 64, + "cy": 7.5 + }, + "highlight": [ + "efe7d7", + "f0e9dc" + ] + } + }, + { + "name": "compare readonly: columns ±3, thumb ±1px, ≤12 px differ > 48", + "status": "PASS", + "data": { + "diff": { + "pixels": 1800, + "max": 49, + "mean": 2.08, + "over16": 76, + "over48": 1 + }, + "focus": [ + false, + false + ], + "chromeThumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 14, + "cx": 64, + "cy": 8 + }, + "firefoxThumb": { + "left": 58, + "right": 69, + "top": 1, + "bottom": 14, + "cx": 64, + "cy": 8 + }, + "highlight": [ + "eadec8", + "ede5d4" + ] + } + }, + { + "name": "compare restored: columns ±3, thumb ±1px, ≤12 px differ > 48", + "status": "PASS", + "data": { + "diff": { + "pixels": 1800, + "max": 29, + "mean": 1.96, + "over16": 71, + "over48": 0 + }, + "focus": [ + true, + false + ], + "chromeThumb": { + "left": 1, + "right": 12, + "top": 1, + "bottom": 14, + "cx": 7, + "cy": 8 + }, + "firefoxThumb": { + "left": 1, + "right": 12, + "top": 1, + "bottom": 14, + "cx": 7, + "cy": 8 + }, + "highlight": [ + "af1515", + "b21515" + ] + } + } + ] +} \ No newline at end of file diff --git a/docs/sw/followup-four-qa/A-bar-1920.png b/docs/sw/followup-four-qa/A-bar-1920.png new file mode 100644 index 0000000..8ef2f19 Binary files /dev/null and b/docs/sw/followup-four-qa/A-bar-1920.png differ diff --git a/docs/sw/followup-four-qa/A-bar-right-end.png b/docs/sw/followup-four-qa/A-bar-right-end.png new file mode 100644 index 0000000..091398a Binary files /dev/null and b/docs/sw/followup-four-qa/A-bar-right-end.png differ diff --git a/docs/sw/followup-four-qa/B-tool-active.png b/docs/sw/followup-four-qa/B-tool-active.png new file mode 100644 index 0000000..4213461 Binary files /dev/null and b/docs/sw/followup-four-qa/B-tool-active.png differ diff --git a/docs/sw/followup-four-qa/B-tool-default.png b/docs/sw/followup-four-qa/B-tool-default.png new file mode 100644 index 0000000..9ba5ad8 Binary files /dev/null and b/docs/sw/followup-four-qa/B-tool-default.png differ diff --git a/docs/sw/followup-four-qa/B-tool-hover.png b/docs/sw/followup-four-qa/B-tool-hover.png new file mode 100644 index 0000000..121f91d Binary files /dev/null and b/docs/sw/followup-four-qa/B-tool-hover.png differ diff --git a/docs/sw/followup-four-qa/C-color-open-hover.png b/docs/sw/followup-four-qa/C-color-open-hover.png new file mode 100644 index 0000000..c35af33 Binary files /dev/null and b/docs/sw/followup-four-qa/C-color-open-hover.png differ diff --git a/docs/sw/followup-four-qa/C-dimension-style-open-hover.png b/docs/sw/followup-four-qa/C-dimension-style-open-hover.png new file mode 100644 index 0000000..c3ff8da Binary files /dev/null and b/docs/sw/followup-four-qa/C-dimension-style-open-hover.png differ diff --git a/docs/sw/followup-four-qa/C-layer-open-hover.png b/docs/sw/followup-four-qa/C-layer-open-hover.png new file mode 100644 index 0000000..0a3cc83 Binary files /dev/null and b/docs/sw/followup-four-qa/C-layer-open-hover.png differ diff --git a/docs/sw/followup-four-qa/C-line-style-open-hover.png b/docs/sw/followup-four-qa/C-line-style-open-hover.png new file mode 100644 index 0000000..c62eff1 Binary files /dev/null and b/docs/sw/followup-four-qa/C-line-style-open-hover.png differ diff --git a/docs/sw/followup-four-qa/C-text-style-open-hover.png b/docs/sw/followup-four-qa/C-text-style-open-hover.png new file mode 100644 index 0000000..c3ff8da Binary files /dev/null and b/docs/sw/followup-four-qa/C-text-style-open-hover.png differ diff --git a/docs/sw/followup-four-qa/E-gauge-initial.png b/docs/sw/followup-four-qa/E-gauge-initial.png new file mode 100644 index 0000000..f9e1df0 Binary files /dev/null and b/docs/sw/followup-four-qa/E-gauge-initial.png differ diff --git a/docs/sw/followup-four-qa/E-gauge-keyboard.png b/docs/sw/followup-four-qa/E-gauge-keyboard.png new file mode 100644 index 0000000..94a63a3 Binary files /dev/null and b/docs/sw/followup-four-qa/E-gauge-keyboard.png differ diff --git a/docs/sw/followup-four-qa/E-gauge-max.png b/docs/sw/followup-four-qa/E-gauge-max.png new file mode 100644 index 0000000..dab92aa Binary files /dev/null and b/docs/sw/followup-four-qa/E-gauge-max.png differ diff --git a/docs/sw/followup-four-qa/E-gauge-min.png b/docs/sw/followup-four-qa/E-gauge-min.png new file mode 100644 index 0000000..1a1f48b Binary files /dev/null and b/docs/sw/followup-four-qa/E-gauge-min.png differ diff --git a/docs/sw/followup-four-qa/E-gauge-zoom-x8.png b/docs/sw/followup-four-qa/E-gauge-zoom-x8.png new file mode 100644 index 0000000..c169141 Binary files /dev/null and b/docs/sw/followup-four-qa/E-gauge-zoom-x8.png differ diff --git a/docs/sw/followup-four-qa/E-panel-circle.png b/docs/sw/followup-four-qa/E-panel-circle.png new file mode 100644 index 0000000..a0c207d Binary files /dev/null and b/docs/sw/followup-four-qa/E-panel-circle.png differ diff --git a/docs/sw/followup-four-qa/F-property-panel-all.png b/docs/sw/followup-four-qa/F-property-panel-all.png new file mode 100644 index 0000000..b073a93 Binary files /dev/null and b/docs/sw/followup-four-qa/F-property-panel-all.png differ diff --git a/docs/sw/followup-four-qa/F-property-panel-circle.png b/docs/sw/followup-four-qa/F-property-panel-circle.png new file mode 100644 index 0000000..40fdc20 Binary files /dev/null and b/docs/sw/followup-four-qa/F-property-panel-circle.png differ diff --git a/docs/sw/followup-four-qa/F-property-panel-expanded.png b/docs/sw/followup-four-qa/F-property-panel-expanded.png new file mode 100644 index 0000000..8d71343 Binary files /dev/null and b/docs/sw/followup-four-qa/F-property-panel-expanded.png differ diff --git a/docs/sw/followup-four-qa/F-property-panel-none.png b/docs/sw/followup-four-qa/F-property-panel-none.png new file mode 100644 index 0000000..91e5d4b Binary files /dev/null and b/docs/sw/followup-four-qa/F-property-panel-none.png differ diff --git a/docs/sw/followup-four-qa/reference/Rectangle 6915.svg b/docs/sw/followup-four-qa/reference/Rectangle 6915.svg new file mode 100644 index 0000000..bf4b50f --- /dev/null +++ b/docs/sw/followup-four-qa/reference/Rectangle 6915.svg @@ -0,0 +1,29 @@ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/docs/sw/followup-four-qa/reference/Rectangle 6926.svg b/docs/sw/followup-four-qa/reference/Rectangle 6926.svg new file mode 100644 index 0000000..253333e --- /dev/null +++ b/docs/sw/followup-four-qa/reference/Rectangle 6926.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/docs/sw/followup-four-qa/reference/user-gauge-example.png b/docs/sw/followup-four-qa/reference/user-gauge-example.png new file mode 100644 index 0000000..695382f Binary files /dev/null and b/docs/sw/followup-four-qa/reference/user-gauge-example.png differ diff --git a/docs/sw/followup-four-qa/result.json b/docs/sw/followup-four-qa/result.json new file mode 100644 index 0000000..8302db4 --- /dev/null +++ b/docs/sw/followup-four-qa/result.json @@ -0,0 +1,1186 @@ +{ + "checks": [ + { + "name": "A1 bar ends after last field (padding 6 + border 1)", + "status": "PASS", + "data": { + "left": 377, + "right": 906.671875, + "width": 529.671875, + "height": 28, + "lastFieldRight": 899.671875, + "scrollW": 528, + "clientW": 528, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1920, + "fieldCount": 4 + } + }, + { + "name": "A2 height 28 / header 49 / radius & border kept", + "status": "PASS", + "data": { + "left": 377, + "right": 906.671875, + "width": 529.671875, + "height": 28, + "lastFieldRight": 899.671875, + "scrollW": 528, + "clientW": 528, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1920, + "fieldCount": 4 + } + }, + { + "name": "A3 background and bottom line end together; nothing brown beyond", + "status": "PASS", + "data": { + "inBg": [ + 38, + 30, + 19 + ], + "outBg": [ + 245, + 240, + 229 + ], + "inLine": [ + 8, + 37, + 28 + ], + "outLine": [ + 245, + 240, + 229 + ] + } + }, + { + "name": "A4 bar grows with added fields, none clipped", + "status": "PASS", + "data": { + "left": 377, + "right": 1546.046875, + "width": 1169.046875, + "height": 28, + "lastFieldRight": 1539.046875, + "scrollW": 1167, + "clientW": 1167, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1920, + "fieldCount": 10 + } + }, + { + "name": "A5 longer than space: capped to header edge, scroll reaches last field", + "status": "PASS", + "data": { + "left": 377, + "right": 1920, + "width": 1543, + "height": 28, + "lastFieldRight": 3030.921875, + "scrollW": 2659, + "clientW": 1541, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1920, + "fieldCount": 24, + "lastVisible": true + } + }, + { + "name": "A6 bar shrinks back for a 1-field object", + "status": "PASS", + "data": { + "left": 377, + "right": 534.984375, + "width": 157.984375, + "height": 28, + "lastFieldRight": 527.984375, + "scrollW": 156, + "clientW": 156, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1920, + "fieldCount": 1 + } + }, + { + "name": "A7 width 1440: bar within header, height 28, no page scroll", + "status": "PASS", + "data": { + "left": 377, + "right": 906.671875, + "width": 529.671875, + "height": 28, + "lastFieldRight": 899.671875, + "scrollW": 528, + "clientW": 528, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1440, + "fieldCount": 4, + "overflowX": false + } + }, + { + "name": "A7 width 1080: bar within header, height 28, no page scroll", + "status": "PASS", + "data": { + "left": 203, + "right": 732.671875, + "width": 529.671875, + "height": 28, + "lastFieldRight": 725.671875, + "scrollW": 528, + "clientW": 528, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1080, + "fieldCount": 4, + "overflowX": false + } + }, + { + "name": "A7 width 768: bar within header, height 28, no page scroll", + "status": "PASS", + "data": { + "left": 306, + "right": 768, + "width": 462, + "height": 28, + "lastFieldRight": 828.671875, + "scrollW": 528, + "clientW": 460, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 768, + "fieldCount": 4, + "overflowX": false + } + }, + { + "name": "B1 no CSS border/outline/background on tool button", + "status": "PASS", + "data": { + "border": "0px rgb(0, 0, 0)", + "outline": "none", + "bg": "rgba(0, 0, 0, 0)", + "w": 29, + "h": 27.125, + "imgs": [ + { + "cls": "hm-sw-property__tool-default", + "w": 29, + "h": 27.125, + "src": "data:image/svg+xml,%3csvg%20width='29'%20height='27.129'%20v" + }, + { + "cls": "hm-sw-property__tool-hover", + "w": 29, + "h": 27.125, + "src": "data:image/svg+xml,%3csvg%20width='29'%20height='27.129'%20v" + } + ] + } + }, + { + "name": "B2 images 29 x 27.13 equal the button", + "status": "PASS", + "data": [ + { + "cls": "hm-sw-property__tool-default", + "w": 29, + "h": 27.125, + "src": "data:image/svg+xml,%3csvg%20width='29'%20height='27.129'%20v" + }, + { + "cls": "hm-sw-property__tool-hover", + "w": 29, + "h": 27.125, + "src": "data:image/svg+xml,%3csvg%20width='29'%20height='27.129'%20v" + } + ] + }, + { + "name": "B3 no white frame pixels (default/hover/active)", + "status": "PASS", + "data": { + "def": 0, + "hov": 0, + "act": 0 + } + }, + { + "name": "B4 active toggles (aria-pressed)", + "status": "PASS", + "data": { + "pressed": "true" + } + }, + { + "name": "C layer: open+hover == open idle", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "C layer: hover restored after close", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "D layer: inner row hover kept / detail hover kept", + "status": "PASS", + "data": { + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "C color: open+hover == open idle", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "C color: hover restored after close", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "D color: inner row hover kept / detail hover kept", + "status": "PASS", + "data": { + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "C text-style: open+hover == open idle", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "C text-style: hover restored after close", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "D text-style: inner row hover kept / detail hover kept", + "status": "PASS", + "data": { + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "C dimension-style: open+hover == open idle", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "C dimension-style: hover restored after close", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "D dimension-style: inner row hover kept / detail hover kept", + "status": "PASS", + "data": { + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "C line-style: open+hover == open idle", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "C line-style: hover restored after close", + "status": "PASS", + "data": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "D line-style: inner row hover kept / detail hover kept", + "status": "PASS", + "data": { + "rowChanged": true, + "detailChanged": true + } + }, + { + "name": "E1 initial 0.25: red left of thumb, beige right", + "status": "PASS", + "data": { + "value": "0.25", + "fill": "0.25", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)", + "left": [ + 254, + 64, + 64 + ], + "right": [ + 196, + 186, + 166 + ], + "width": 86 + } + }, + { + "name": "E2 keyboard ArrowRight x40 -> 0.65, fill follows", + "status": "PASS", + "data": { + "value": "0.65", + "fill": "0.65", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)", + "left": [ + 254, + 64, + 64 + ], + "right": [ + 199, + 189, + 169 + ], + "width": 86 + } + }, + { + "name": "E3 commit updates the number input (callback path)", + "status": "PASS", + "data": { + "committed": "0.65" + } + }, + { + "name": "E4 max -> fill 1", + "status": "PASS", + "data": { + "value": "1", + "fill": "1", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)", + "left": [ + 254, + 64, + 64 + ], + "right": [ + 164, + 17, + 17 + ], + "width": 86 + } + }, + { + "name": "E5 min -> fill 0, beige right", + "status": "PASS", + "data": { + "value": "0", + "fill": "0", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)", + "left": [ + 166, + 125, + 3 + ], + "right": [ + 196, + 186, + 166 + ], + "width": 86 + } + }, + { + "name": "E6 value changed elsewhere syncs gauge", + "status": "PASS", + "data": { + "value": "0.5", + "fill": "0.5", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)" + } + }, + { + "name": "F property-panel-none renders", + "status": "PASS", + "data": [ + 314, + 256 + ] + }, + { + "name": "F property-panel-all renders", + "status": "PASS", + "data": [ + 314, + 361 + ] + }, + { + "name": "F property-panel-circle renders", + "status": "PASS", + "data": [ + 314, + 658 + ] + }, + { + "name": "F property-panel-expanded renders", + "status": "PASS", + "data": [ + 314, + 754 + ] + }, + { + "name": "G no page/console errors", + "status": "PASS", + "data": [] + } + ], + "errors": [], + "data": { + "barDefault": { + "left": 377, + "right": 906.671875, + "width": 529.671875, + "height": 28, + "lastFieldRight": 899.671875, + "scrollW": 528, + "clientW": 528, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1920, + "fieldCount": 4 + }, + "barGrown": { + "left": 377, + "right": 1546.046875, + "width": 1169.046875, + "height": 28, + "lastFieldRight": 1539.046875, + "scrollW": 1167, + "clientW": 1167, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1920, + "fieldCount": 10 + }, + "barOverflow": { + "left": 377, + "right": 1920, + "width": 1543, + "height": 28, + "lastFieldRight": 3030.921875, + "scrollW": 2659, + "clientW": 1541, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1920, + "fieldCount": 24 + }, + "barReplaced": { + "left": 377, + "right": 534.984375, + "width": 157.984375, + "height": 28, + "lastFieldRight": 527.984375, + "scrollW": 156, + "clientW": 156, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1920, + "fieldCount": 1 + }, + "bar1440": { + "left": 377, + "right": 906.671875, + "width": 529.671875, + "height": 28, + "lastFieldRight": 899.671875, + "scrollW": 528, + "clientW": 528, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1440, + "fieldCount": 4 + }, + "bar1080": { + "left": 203, + "right": 732.671875, + "width": 529.671875, + "height": 28, + "lastFieldRight": 725.671875, + "scrollW": 528, + "clientW": 528, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 1080, + "fieldCount": 4 + }, + "bar768": { + "left": 306, + "right": 768, + "width": 462, + "height": 28, + "lastFieldRight": 828.671875, + "scrollW": 528, + "clientW": 460, + "borderBottom": "1px rgb(8, 37, 28)", + "radius": "6px/6px", + "bg": "rgb(39, 31, 19)", + "headerH": 49, + "headerRight": 768, + "fieldCount": 4 + }, + "tool": { + "border": "0px rgb(0, 0, 0)", + "outline": "none", + "bg": "rgba(0, 0, 0, 0)", + "w": 29, + "h": 27.125, + "imgs": [ + { + "cls": "hm-sw-property__tool-default", + "w": 29, + "h": 27.125, + "src": "data:image/svg+xml,%3csvg%20width='29'%20height='27.129'%20v" + }, + { + "cls": "hm-sw-property__tool-hover", + "w": 29, + "h": 27.125, + "src": "data:image/svg+xml,%3csvg%20width='29'%20height='27.129'%20v" + } + ] + }, + "toolPixels": { + "def": { + "white": 0, + "outer": [ + [ + 2, + 7, + 5 + ], + [ + 2, + 7, + 5 + ], + [ + 17, + 67, + 52 + ], + [ + 17, + 67, + 52 + ] + ] + }, + "hov": { + "white": 0, + "outer": [ + [ + 2, + 7, + 5 + ], + [ + 2, + 7, + 5 + ], + [ + 17, + 67, + 52 + ], + [ + 17, + 67, + 52 + ] + ] + }, + "act": { + "white": 0, + "outer": [ + [ + 2, + 7, + 5 + ], + [ + 2, + 7, + 5 + ], + [ + 17, + 67, + 52 + ], + [ + 17, + 67, + 52 + ] + ] + }, + "pressed": "true" + }, + "dropdown-layer": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + }, + "dropdown-color": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + }, + "dropdown-text-style": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + }, + "dropdown-dimension-style": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "0", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + }, + "dropdown-line-style": { + "closedHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "openIdle": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "openHover": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": "true" + }, + "closedAgain": { + "after": "0", + "color": "rgb(246, 244, 242)", + "expanded": null + }, + "restored": { + "after": "1", + "color": "rgb(255, 198, 0)", + "expanded": null + }, + "rowChanged": true, + "detailChanged": true + }, + "gaugeInitial": { + "value": "0.25", + "fill": "0.25", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)", + "left": [ + 254, + 64, + 64 + ], + "right": [ + 196, + 186, + 166 + ], + "width": 86 + }, + "gaugeKeyboard": { + "value": "0.65", + "fill": "0.65", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)", + "left": [ + 254, + 64, + 64 + ], + "right": [ + 199, + 189, + 169 + ], + "width": 86 + }, + "gaugeCommitted": "0.65", + "gaugeMax": { + "value": "1", + "fill": "1", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)", + "left": [ + 254, + 64, + 64 + ], + "right": [ + 164, + 17, + 17 + ], + "width": 86 + }, + "gaugeMin": { + "value": "0", + "fill": "0", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)", + "left": [ + 166, + 125, + 3 + ], + "right": [ + 196, + 186, + 166 + ], + "width": 86 + }, + "gaugeExternal": { + "value": "0.5", + "fill": "0.5", + "track": "linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px)" + }, + "property-panel-none": [ + 314, + 256 + ], + "property-panel-all": [ + 314, + 361 + ], + "property-panel-circle": [ + 314, + 658 + ], + "property-panel-expanded": [ + 314, + 754 + ] + } +} \ No newline at end of file diff --git a/docs/sw/property-close-qa/after-default.png b/docs/sw/property-close-qa/after-default.png new file mode 100644 index 0000000..cc1eb1d Binary files /dev/null and b/docs/sw/property-close-qa/after-default.png differ diff --git a/docs/sw/property-close-qa/after-hover.png b/docs/sw/property-close-qa/after-hover.png new file mode 100644 index 0000000..925ce65 Binary files /dev/null and b/docs/sw/property-close-qa/after-hover.png differ diff --git a/docs/sw/property-close-qa/after-result.json b/docs/sw/property-close-qa/after-result.json new file mode 100644 index 0000000..e85acb3 --- /dev/null +++ b/docs/sw/property-close-qa/after-result.json @@ -0,0 +1,81 @@ +{ + "label": "after", + "checks": [ + { + "name": "size 44 x 30, top-right of the panel", + "status": "PASS", + "data": { + "w": 44, + "h": 30, + "right": 1, + "top": 1, + "imgs": [ + [ + "hm-sw-property__close-default", + 44, + 30 + ], + [ + "hm-sw-property__close-hover", + 44, + 30 + ] + ] + } + }, + { + "name": "Default: no canvas-light pixels on the button edge / corner", + "status": "PASS", + "data": { + "bright": 0, + "where": [] + } + }, + { + "name": "Hover: hover asset shown, no canvas-light pixels on the edge / corner", + "status": "PASS", + "data": { + "vis": [ + "hidden", + "visible" + ], + "bright": 0, + "where": [] + } + }, + { + "name": "click closes the panel, focus back on 속성창 trigger", + "status": "PASS", + "data": { + "open": false, + "focusTrigger": true, + "log": "legacyToggle → open(true) → open(false)" + } + }, + { + "name": "Escape closes the panel, focus back on 속성창 trigger", + "status": "PASS", + "data": { + "open": false, + "focusTrigger": true, + "log": "rue) → open(false) → legacyToggle → open(true) → open(false)" + } + }, + { + "name": "no console / page errors", + "status": "PASS", + "data": [] + } + ], + "errors": [], + "pixels": { + "def": { + "bright": 0, + "where": [] + }, + "hov": { + "bright": 0, + "where": [] + } + } +} \ No newline at end of file diff --git a/docs/sw/property-close-qa/before-default.png b/docs/sw/property-close-qa/before-default.png new file mode 100644 index 0000000..876b3f1 Binary files /dev/null and b/docs/sw/property-close-qa/before-default.png differ diff --git a/docs/sw/property-close-qa/before-hover.png b/docs/sw/property-close-qa/before-hover.png new file mode 100644 index 0000000..6f92953 Binary files /dev/null and b/docs/sw/property-close-qa/before-hover.png differ diff --git a/docs/sw/property-close-qa/before-result.json b/docs/sw/property-close-qa/before-result.json new file mode 100644 index 0000000..aa53ae9 --- /dev/null +++ b/docs/sw/property-close-qa/before-result.json @@ -0,0 +1,81 @@ +{ + "label": "before", + "checks": [ + { + "name": "size 44 x 30, top-right of the panel", + "status": "PASS", + "data": { + "w": 44, + "h": 30, + "right": 1, + "top": 1, + "imgs": [ + [ + "hm-sw-property__close-default", + 44, + 30 + ], + [ + "hm-sw-property__close-hover", + 44, + 30 + ] + ] + } + }, + { + "name": "Default: no canvas-light pixels on the button edge / corner", + "status": "PASS", + "data": { + "bright": 0, + "where": [] + } + }, + { + "name": "Hover: hover asset shown, no canvas-light pixels on the edge / corner", + "status": "PASS", + "data": { + "vis": [ + "hidden", + "visible" + ], + "bright": 0, + "where": [] + } + }, + { + "name": "click closes the panel, focus back on 속성창 trigger", + "status": "PASS", + "data": { + "open": false, + "focusTrigger": true, + "log": "legacyToggle → open(true) → open(false)" + } + }, + { + "name": "Escape closes the panel, focus back on 속성창 trigger", + "status": "PASS", + "data": { + "open": false, + "focusTrigger": true, + "log": "rue) → open(false) → legacyToggle → open(true) → open(false)" + } + }, + { + "name": "no console / page errors", + "status": "PASS", + "data": [] + } + ], + "errors": [], + "pixels": { + "def": { + "bright": 0, + "where": [] + }, + "hov": { + "bright": 0, + "where": [] + } + } +} \ No newline at end of file diff --git a/docs/sw/sw-header-design-spec.md b/docs/sw/sw-header-design-spec.md index 6056119..ce629bb 100644 --- a/docs/sw/sw-header-design-spec.md +++ b/docs/sw/sw-header-design-spec.md @@ -1,5 +1,7 @@ # SW Header 디자인 명세 +> **후속 디자인 수정 4건(2026-10-19):** 속성Bar는 Figma 1222px 고정 폭 대신 마지막 필드에서 끝나는 콘텐츠 폭(공간 부족 시 내부 스크롤)을 사용합니다. 속성창 도구 아이콘 SVG의 Figma 캔버스 배경을 제거했고, 레이어·색상·문자·치수스타일 필드는 자기 Dropdown이 열린 동안 Hover를 적용하지 않으며, 게이지는 빨강 채움 + 베이지 Track입니다. 아래 26:10492의 "최대 1222" 설명보다 우선합니다. [검증 기록](./sw-header-followup-four-design-fixes-verification-2026-10-19.md). + > **상세 버튼 공통화 기준(2026-10-16, 이번 요청):** 상세 5개는 기존 `SWHeaderMenuDetail`을 공유하며 **현재 문자스타일 상세**를 우선합니다. Default는 배경 `rgba(197,177,158,.15)`·radius 24·글자 35%·아이콘 SVG 20%, Hover는 배경 .25·radius 25·글자 35%·아이콘 SVG 35%입니다. Disabled는 Default 외형과 클릭 차단을 사용합니다. Callback이 없어도 Hover되며 클릭은 무동작입니다. 치수 상세의 글자 100% Hover와 Callback 부재에 따른 비활성 설명은 이 기준으로 대체합니다. 기존 폭 113/99/128/142/142px·높이 24px, 제거된 Text Stroke 선언을 유지합니다. 과거 검증 문서는 당시 기록으로 보존합니다. [이번 검증 기록](./sw-header-detail-buttons-verification-2026-10-16.md). > **3차 기준(2026-10-16):** 문서 끝 [3차 기준](#3차-기준--구성요소-표시메뉴-순서속성창-상태형상-slot-2026-10-16)이 구성요소 표시·메뉴 순서·속성창 상태·형상 Slot에 우선합니다. [3차 검증 기록](./sw-header-composition-shape-verification-2026-10-16.md). diff --git a/docs/sw/sw-header-firefox-range-close-verification-2026-10-19.md b/docs/sw/sw-header-firefox-range-close-verification-2026-10-19.md new file mode 100644 index 0000000..caeee97 --- /dev/null +++ b/docs/sw/sw-header-firefox-range-close-verification-2026-10-19.md @@ -0,0 +1,55 @@ +# SW 속성창 게이지 Firefox 지원 · 닫기 SVG · Storybook Build 검증 (2026-10-19) + +기준: `feature/sw-package` @ `fc26afd4401d5b3bb74c8818cacb76f669fcd24b`. 직전 후속 4건([검증 기록](./sw-header-followup-four-design-fixes-verification-2026-10-19.md))의 미커밋 변경 위에서 진행했다. + +## A. Firefox 게이지 + +- **원인:** 게이지 디자인이 `::-webkit-slider-runnable-track` / `::-webkit-slider-thumb`에만 정의돼 있었다. Gecko는 이 의사 요소를 쓰지 않아 기본 range 외형이 남았다. +- **방식:** Track 그림(채움 왼쪽 검정 선 + Figma 6926 채움 + 베이지 Track), Thumb 그림(`property-range-thumb.svg`), Thumb 그림자를 input의 custom property(`--hm-sw-range-track-paint`, `--hm-sw-range-thumb-paint`, `--hm-sw-range-thumb-shadow`)로 한 번만 정의했다. 엔진별 규칙이 이 값을 공유한다. + - WebKit/Blink: 기존 track + thumb(`margin-top: -4px`). + - Gecko: `::-moz-range-track`(6px, radius 3) + `::-moz-range-thumb`(14px, 자동 수직 중앙). `::-moz-range-progress`는 높이 0·투명으로 둬서 채움이 두 번 그려지지 않는다. + - 색·자산은 Chrome PASS 값 그대로이고, 새 색은 없다. 각 엔진은 자기 의사 요소만 인식하므로 다른 엔진에 영향이 없다. +- **검증:** `node packages/sw/tests/range-cross-browser.browser.mjs docs/sw/firefox-range-qa` → **29/29 PASS** ([result.json](./firefox-range-qa/result.json), [비교 이미지](./firefox-range-qa/compare-chrome-firefox.png)). + - 브라우저: Chrome 155.0.8059.80(Playwright), 설치된 **Firefox 158.0 실브라우저**(WebDriver BiDi로 직접 제어, Playwright Firefox 빌드 미사용). + - 조건: 같은 Story(`SW/Header/Property Panel` → 원 1개 → 속성창), 1400×1000, DPR 1, 같은 순서의 실제 키 입력. + - 두 브라우저 공통 확인: 빨강 채움, 베이지 Track, 위·아래 검정 1px의 6px 높이, Thumb 12px 검출 폭(14px 그림), Thumb 세로 중심이 Track 중심(8.0). + - 값 0 / 0.25 / 0.65(→ 40회) / 1(End) / 0(Home) / 외부 Props 0.8에서 Thumb 중심이 기대값 ±1px. + - Enter 확정 시 숫자 입력 0.65와 Callback `property(opacity, 0.65)` 확인. + - Disabled·ReadOnly: range가 비활성화되어 키 입력으로 값이 바뀌지 않고, 해제하면 복원된다. + - Chrome 대비 차이: 1,800픽셀 중 48 초과 차이는 최대 1px, 평균 채널 차이 1.2–2.1. 채움·Track 열 색은 ±1 이내. + - 남은 차이는 Track 아래 1px 하이라이트 행 하나다. Chrome #EADEC8, Firefox #EDE5D4로 Gecko의 box-shadow 안티앨리어싱 차이다. + - 최종 실행의 Thumb 중심(px)은 9개 상태 모두 두 엔진이 같다: 0 → 7, 0.25 → 25, 0.65 → 53, 0.8 → 64, 1 → 79. 이전 실행에서는 Chrome Focus 테두리가 포함돼 극값이 7.5 / 78.5로 측정됐다. +- **Focus-visible:** 기존 `.hm-sw-property input:focus-visible`(2px #A67D03) 규칙은 엔진 공통이다. + - headless Firefox는 BiDi 합성 키 입력에서 버튼·텍스트 입력까지 포함해 `:focus-visible`을 켜지 않는다(별도 대조 페이지에서 확인). + - 그래서 비교 스크린샷은 두 브라우저 모두 테스트 전용으로 outline만 숨기고 찍었다. Firefox Focus 링의 시각 확인은 NOT VERIFIED다. +- 콘솔: 두 브라우저 모두 컴포넌트 오류 0. Firefox에는 Storybook manager 글꼴(`/sb-common-assets/nunito-sans-regular.woff2`) 다운로드 실패 1건이 있으며, Storybook 인프라 항목이라 제외했다. +- Story: `PropertyPanelDemo`에 `투명도 외부 값 변경` / `투명도 Disabled` / `투명도 ReadOnly` 버튼 3개만 추가했다(공개 API 변경 없음). +- Chrome 회귀: 기존 `followup-four.browser.mjs` **39/39 PASS** 재실행. + +## B. 닫기 버튼 SVG (Figma 26:12366) + +- `property-close.svg` / `property-close-hover.svg` 모두 도구 아이콘과 같은 Figma 캔버스 4요소를 포함하고 있었다: `#F5F5F5` 44×30 배경, 흰 페이지 path, 10% 검정 페이지 테두리, `#9747FF` 점선 프레임. +- **실제 노출:** 버튼 몸체가 44×30을 덮고 패널의 둥근 모서리·overflow가 대부분을 가린다. 그래서 흰 테두리처럼 보이지는 않았다(가장자리 밝은 픽셀 0). 다만 오른쪽 위 radius 3 곡선의 안티앨리어싱 픽셀(4배율 기준 19 / 15개, 최대 채널 차이 67 / 35)에 밝은 캔버스가 섞여 있었다. +- **수정:** 두 파일에서 위 4요소만 제거했다. viewBox 44×30(버튼과 동일), 버튼 path·Gradient·Hover 빨강 #E40000·X 아이콘·Default/Hover 분리는 그대로다. +- **검증:** `node packages/sw/tests/property-close.browser.mjs docs/sw/property-close-qa after` → **6/6 PASS** ([before](./property-close-qa/before-result.json) / [after](./property-close-qa/after-result.json)). + - 크기 44×30, 패널 오른쪽·위 1px. + - Default/Hover 가장자리 밝은 픽셀 0, Hover 자산 표시 확인. + - 클릭 닫힘 + 속성창 버튼으로 Focus 복귀, Escape 닫힘 + Focus 복귀, 오류 0. + - 전후 차이는 위 모서리 곡선 픽셀뿐이다. +- `.hm-sw-property__tool` 관련 SVG는 이번에 수정하지 않았다. + +## C. Storybook Build + +- `npm run build-storybook`(prebuild: theme-defaults 검사 + 패키지 build 포함) → **exit 0, "Storybook build completed successfully"**. +- 경고 4종은 모두 기존 경고로 SW 변경과 무관하다: Tailwind `bg-[var(...)]` CSS 최적화, lightningcss `host-context`, 500kB 초과 chunk, PLUGIN_TIMINGS. 앞의 3종은 `docs/org-chart/consistency-review-p11-6.md` 등에 이미 기록돼 있다. +- 결과물 `storybook-static/assets/sw-header-*.css`에 `::-moz-range-track/progress/thumb` 각 1회, Thumb SVG data URI가 포함됐다. Story bundle의 SVG에는 `#F5F5F5` / `#9747FF`가 0건이다. + +## 재사용한 기존 PASS (재실행 안 함) + +Storybook 32개 렌더, 구성 77/77, 브라우저 271건, 기본 Header 10폭 차이 0. 공통 Header CSS·팝업 구조는 바꾸지 않았다(range 의사 요소와 닫기 SVG만 변경). + +## NOT VERIFIED + +- Firefox에서 키보드 Focus 링(`:focus-visible`)의 시각 표시. 자동화 입력 한계로 확인하지 못했고, 규칙은 엔진 공통 CSS다. +- 실제 Windows Firefox 창(비 headless)과 고배율(DPR 2) 렌더링. +- Safari(WebKit) 실브라우저. diff --git a/docs/sw/sw-header-followup-four-design-fixes-verification-2026-10-19.md b/docs/sw/sw-header-followup-four-design-fixes-verification-2026-10-19.md new file mode 100644 index 0000000..2a8eaf4 --- /dev/null +++ b/docs/sw/sw-header-followup-four-design-fixes-verification-2026-10-19.md @@ -0,0 +1,32 @@ +# SW Header 후속 디자인 수정 4건 검증 (2026-10-19) + +기준: `feature/sw-package` @ `fc26afd4401d5b3bb74c8818cacb76f669fcd24b`(시작 시 Working Tree clean). Commit·Push 없음. +증거: [followup-four-qa/](./followup-four-qa/) · 결과 [result.json](./followup-four-qa/result.json) · 재실행 `node packages/sw/tests/followup-four.browser.mjs docs/sw/followup-four-qa` (Storybook 6024, `packages/sw/dist` 사용 → SW build 후 실행). + +## 변경 요약 + +| 작업 | 원인 / 결정 | 변경 | +|---|---|---| +| A 속성Bar 길이 | 바가 `width:100%`(최대 1222px)로 앵커 폭을 채워 마지막 필드 뒤가 빈 갈색 영역 | 바 `width: max-content; max-width: 100%`, 앵커는 고정 `width` 대신 `maxWidth: calc(100% - 왼쪽 오프셋)`. 마지막 필드 + 기존 오른쪽 padding 6px + border 1px에서 끝남. 공간보다 길면 Header 오른쪽 끝까지 늘어나고 내부 가로 스크롤. Figma 1222px 고정 폭은 사용자 최신 지시로 대체. **2026-10-19 사용자 확정**: 마지막 필드에서 끝나는 콘텐츠 폭 정책 | +| B 도구 아이콘 흰 테두리 | CSS 원인 아님(border 0·outline none·배경 투명). **SVG 자체**에 Figma 페이지 캔버스가 함께 export됨: `#F5F5F5` 29×28 사각형, 흰색 페이지 path, 10% 검정 페이지 테두리, `#9747FF` 점선 컴포넌트 세트 테두리. 버튼 사각형은 29×27.129·rx 3이므로 네 모서리와 아래 0.87px에 밝은 캔버스가 비침 | 3개 SVG(Default/Hover/Active)에서 위 캔버스 요소 4개만 제거, viewBox/높이 29×27.129, img 높이 28 → 27.13px. 버튼 사각형·`#092920` 외곽·`#08251C` / Active `#A67D03` 내부 Gradient·inner shadow·아이콘 path는 그대로 | +| C Dropdown 열림 Hover | 필드 Hover(글자·미리보기·노란 ring)가 열린 상태에서도 적용 | 기존 필드 Hover selector 5개에 `:not([data-expanded="true"])` 추가. 열림 표현(`data-expanded` 스타일, 선스타일 고정 ring)·내부 행·상세 버튼 Hover·Focus-visible 미변경, `pointer-events` 미사용 | +| D 게이지바 | 기존 Track 전체가 빨강, 채움/미채움 구분 없음 | 입력값에서 0–1 비율을 계산해 `--hm-sw-range-fill`로 전달. **사용자 예시 이미지**([reference/user-gauge-example.png](./followup-four-qa/reference/user-gauge-example.png))를 행 단위로 측정해 적용: 채움은 사용자 제공 Figma 원본 [Rectangle 6926.svg](./followup-four-qa/reference/Rectangle%206926.svg): 6px 알약, 검정 1px 테두리, 내부 #8E0000 / #FF4242 37% / #E40000 76% / #1E0000 세로 Gradient. 왼쪽 끝은 radius 3과 왼쪽 검정 1px로 둥근 테두리, 오른쪽 끝은 항상 Thumb 아래. 미채움 베이지는 예시 이미지 측정값 #AEA28B / #C3B9A4 / #C7BDA9 ×2 / #B7AC96 / #AC9E84, 아래 1px 하이라이트 #EADEC8. 채움 끝은 Thumb 중심. Thumb는 사용자 제공 Figma 원본 [Rectangle 6915.svg](./followup-four-qa/reference/Rectangle%206915.svg) 14px(conic + 2px Gradient 테두리 40%)를 `assets/property-range-thumb.svg`로 저장해 사용(viewBox만 14px 본체로 자르고 Figma 편집용 속성 제거). 원본 그림자 필터 2개는 같은 값의 CSS `box-shadow`(0 0 3px #1C1A16, 0 2px 2px 40%). 토큰 `--hm-sw-property-range-fill / -fill-edge / -track / -highlight` | + +## 실행 결과 (Chrome headless, 2회 연속 39/39 PASS) + +- **A** 1920: 바 x 377–906.7(529.7px), 마지막 필드 끝 899.7 → 차이 7px(padding 6 + border 1). 높이 28, Header 49, 하단 radius 6/6, 하단 border 1px #08251C. 끝 안쪽은 #271F13, 바깥은 배경색이며 하단 라인도 같은 x에서 끝남. 필드 4 → 10개: 1169px로 증가, 잘림 0. 24개: Header 끝(1920)에서 멈추고 스크롤로 마지막 필드 접근. 1개 객체로 교체: 158px로 축소. 1440 / 1080 / 768: Header 안, 28px, 페이지 가로 스크롤 0(768은 내부 스크롤). +- **B** 버튼·이미지 29 × 27.13, CSS border/outline/background 없음. Default / Hover / Active 각 버튼 영역에서 밝은(≥235) 픽셀 0. Active 클릭 시 `aria-pressed=true`. +- **C** 레이어·색상·문자·치수: 열림 상태 Hover 전후 ring opacity·글자색 동일(ring 0). 닫힌 뒤 Hover ring 1·글자 #FFC600 복원. 선스타일: 기존대로 열림 ring 1 유지, Hover로 변하지 않음. +- **D(Hover 유지)** 5개 Dropdown 모두 비선택 내부 행(색상은 ByLayer/ByBlock) Hover 변화 있음, 하단 상세 버튼 Hover 변화 있음. +- **E** 렌더링 미채움 6행은 예시 측정값과, 채움 행은 Figma 6926(검정 / #B51717 / #FE4040 / #ED1515 / #790000 / 검정, 1x)과 일치(1x 픽셀 측정, [x8 확대](./followup-four-qa/E-gauge-zoom-x8.png)). 0.25: Thumb 왼쪽 빨강 / 오른쪽 베이지. 키보드 →×40 = 0.65, 채움 동기화, Enter commit 후 숫자 입력 0.65(Callback 경로). End = 1, Home = 0. 숫자 입력에 0.5 입력 시 게이지 0.5 동기화. +- **F** 속성창 4상태 314×256 / 361 / 658 / 754 렌더. +- **G** page / console 오류 0. +- SW `typecheck`, SW `build`, 루트 `tsc -b` PASS. + +## 미확정 / 미검증 + +- 예시 이미지의 미채움 Track은 Figma 26:11978의 어두운 빨강 대신 베이지로 대체했습니다(사용자 지시). +- 예시 이미지 아래의 최소/최대 라벨(`0`, `90 %`)은 현재 속성창 구현과 Figma에 없는 요소라 추가하지 않았습니다(기존 단위 `%` 표시는 유지). +- `property-close*.svg`에도 같은 Figma 캔버스 요소가 있으나 이번 범위가 아니라 수정하지 않았습니다(44×30 전체가 덮이는지 미확인). +- Firefox `::-moz-range-*`는 기존 코드에도 없으며 이번에도 추가하지 않았습니다. +- Storybook Build·기존 77/77 구성·271건 브라우저·10폭 회귀는 재실행하지 않았습니다(기존 PASS 재사용). diff --git a/packages/sw/src/assets/property-close-hover.svg b/packages/sw/src/assets/property-close-hover.svg index 55f0da3..f985d47 100644 --- a/packages/sw/src/assets/property-close-hover.svg +++ b/packages/sw/src/assets/property-close-hover.svg @@ -1,10 +1,6 @@ - - - - diff --git a/packages/sw/src/assets/property-close.svg b/packages/sw/src/assets/property-close.svg index ec35ebd..be1542f 100644 --- a/packages/sw/src/assets/property-close.svg +++ b/packages/sw/src/assets/property-close.svg @@ -1,10 +1,6 @@ - - - - diff --git a/packages/sw/src/assets/property-range-thumb.svg b/packages/sw/src/assets/property-range-thumb.svg new file mode 100644 index 0000000..4c974cd --- /dev/null +++ b/packages/sw/src/assets/property-range-thumb.svg @@ -0,0 +1,11 @@ + +
+ + + + + + + + +
diff --git a/packages/sw/src/assets/property-tool-active.svg b/packages/sw/src/assets/property-tool-active.svg index a88df4d..ddabc5d 100644 --- a/packages/sw/src/assets/property-tool-active.svg +++ b/packages/sw/src/assets/property-tool-active.svg @@ -1,10 +1,6 @@ - - + - - - diff --git a/packages/sw/src/assets/property-tool-hover.svg b/packages/sw/src/assets/property-tool-hover.svg index f72115d..c40a755 100644 --- a/packages/sw/src/assets/property-tool-hover.svg +++ b/packages/sw/src/assets/property-tool-hover.svg @@ -1,10 +1,6 @@ - - + - - - diff --git a/packages/sw/src/assets/property-tool.svg b/packages/sw/src/assets/property-tool.svg index 2742fc8..7e6d539 100644 --- a/packages/sw/src/assets/property-tool.svg +++ b/packages/sw/src/assets/property-tool.svg @@ -1,10 +1,6 @@ - - + - - - diff --git a/packages/sw/src/components/sw-header/SWHeader.tsx b/packages/sw/src/components/sw-header/SWHeader.tsx index fe6906f..d2a6b2a 100644 --- a/packages/sw/src/components/sw-header/SWHeader.tsx +++ b/packages/sw/src/components/sw-header/SWHeader.tsx @@ -454,7 +454,7 @@ export const SWHeader = forwardRef(function SWHeader } - {barOpen && barData &&
} + {barOpen && barData &&
} {panelOpen && propertyPanel && } ) diff --git a/packages/sw/src/components/sw-header/components/SWHeaderPropertyPanel.tsx b/packages/sw/src/components/sw-header/components/SWHeaderPropertyPanel.tsx index ee93a53..86fa24e 100644 --- a/packages/sw/src/components/sw-header/components/SWHeaderPropertyPanel.tsx +++ b/packages/sw/src/components/sw-header/components/SWHeaderPropertyPanel.tsx @@ -143,6 +143,8 @@ function PropertyEditor({ property, onChange }: { property: SWHeaderProperty; on onChange?.(property, next) } const cancelDraft = () => setDraft(value) + const rangeMin = property.min ?? 0, rangeMax = property.max ?? 100, rangeValue = mixed ? rangeMin : Number(draft) + const rangeFill = rangeMax > rangeMin && Number.isFinite(rangeValue) ? Math.min(1, Math.max(0, (rangeValue - rangeMin) / (rangeMax - rangeMin))) : 0 const nativeKeys = (event: React.KeyboardEvent) => { if (event.nativeEvent.isComposing) return if (event.key === "Enter") { event.preventDefault(); commit(draft) } @@ -170,7 +172,7 @@ function PropertyEditor({ property, onChange }: { property: SWHeaderProperty; on {unit && type !== "slider" && {unit}} {type === "color" && } {property.linePreview && } - {type === "slider" && setDraft(event.target.value)} onBlur={() => commit(draft)} onKeyDown={nativeKeys} />} + {type === "slider" && setDraft(event.target.value)} onBlur={() => commit(draft)} onKeyDown={nativeKeys} />} {unit && type === "slider" && {unit}} diff --git a/packages/sw/src/theme/sw.css b/packages/sw/src/theme/sw.css index a13a09b..3b577b4 100644 --- a/packages/sw/src/theme/sw.css +++ b/packages/sw/src/theme/sw.css @@ -75,6 +75,14 @@ --hm-sw-property-label: #000; --hm-sw-property-table: #d2c8b4; --hm-sw-property-inner-border: #948871; + /* Gauge (user-supplied Figma SVGs, 2026-10-19). Fill = Rectangle 6926: 6px pill, 1px black stroke, + vertical #8E0000 / #FF4242 37% / #E40000 76% / #1E0000 inside the stroke; its right end sits under + the thumb. Unfilled track = beige measured row by row from the user's reference image. + Thumb = Rectangle 6915: 14px conic + 2px 40% ring; its two drop shadows are CSS. */ + --hm-sw-property-range-fill: linear-gradient(#000 0 1px, #8e0000 1px, #ff4242 2.46px, #e40000 3.99px, #1e0000 4.94px, #000 4.94px); + --hm-sw-property-range-fill-edge: #000; + --hm-sw-property-range-track: linear-gradient(#aea28b 0 1px, #c3b9a4 1px 2px, #c7bda9 2px 4px, #b7ac96 4px 5px, #ac9e84 5px); + --hm-sw-property-range-highlight: #eadec8; /* User-confirmed: document (file name) surface */ --hm-sw-header-document-background: linear-gradient(180deg, #081813 0%, #09271e 8.69%, #0b3227 25.43%, #0e3d2f 51.25%, #0b3227 80.03%, #0a2b21 89.76%, #081813 100%); @@ -168,13 +176,16 @@ background: var(--hm-sw-header-background); } -/* Figma 26:10492. Header stays 49px; host content can reserve the extra 28px when open. */ -.hm-sw-header__bar-anchor { position: absolute; top: 49px; z-index: 2; max-width: 1222px; } +/* Figma 26:10492. Header stays 49px; host content can reserve the extra 28px when open. + The strip ends after its last field (user correction 2026-10-19, overrides the fixed 1222px frame): + it shrinks to its content, so no empty brown area, and is capped by the space right of its left + edge (inline max-width); longer property lists scroll inside. */ +.hm-sw-header__bar-anchor { position: absolute; top: 49px; z-index: 2; } .hm-sw-property-bar { --hm-sw-property-bar-background: #271f13; --hm-sw-property-bar-border: #08251c; - width: 100%; - max-width: 1222px; + width: max-content; + max-width: 100%; height: 28px; overflow-x: auto; overflow-y: hidden; @@ -600,11 +611,13 @@ /* Group-field hover (user request): all labels/values and the font sample inherit yellow. Swatches and layer-state graphics retain their data colors. Line borders and the dimension - SVG's black mask outline stay black; only the white foreground changes. Disabled is excluded. */ -.hm-sw-header__field:hover:not(:disabled) { color: var(--hm-sw-header-selected-color); } -.hm-sw-header__field:hover:not(:disabled) .hm-sw-header__linetype > i { background: var(--hm-sw-header-selected-color); } -.hm-sw-header__field:hover:not(:disabled) .hm-sw-header__dimension-icon-default { visibility: hidden; } -.hm-sw-header__field:hover:not(:disabled) .hm-sw-header__dimension-icon-hover { visibility: visible; } + SVG's black mask outline stay black; only the white foreground changes. Disabled is excluded. + While a field's own dropdown is open (data-expanded) hover adds nothing: the expanded styling + stays as is and hover returns once the list closes. Focus-visible is unaffected. */ +.hm-sw-header__field:hover:not(:disabled, [data-expanded="true"]) { color: var(--hm-sw-header-selected-color); } +.hm-sw-header__field:hover:not(:disabled, [data-expanded="true"]) .hm-sw-header__linetype > i { background: var(--hm-sw-header-selected-color); } +.hm-sw-header__field:hover:not(:disabled, [data-expanded="true"]) .hm-sw-header__dimension-icon-default { visibility: hidden; } +.hm-sw-header__field:hover:not(:disabled, [data-expanded="true"]) .hm-sw-header__dimension-icon-hover { visibility: visible; } /* Hover — Figma header/btn_home "hover": the 1px border turns into a yellow vertical gradient. Same treatment on every bordered SW Header button except the file name and 속성Bar / 속성창 @@ -635,7 +648,7 @@ /* Popup guide: the 1px outline is inside its SVG (rect rx 1.5 + 0.5 stroke), so the ring overlays it. */ .hm-sw-header__action--guide { border-radius: 2px; } .hm-sw-header__action--guide::after { inset: 0; } -:is(.hm-sw-header__field, .hm-sw-header__more-trigger, .hm-sw-header__action):hover:not(:disabled)::after { opacity: 1; } +:is(.hm-sw-header__field, .hm-sw-header__more-trigger, .hm-sw-header__action):hover:not(:disabled, [data-expanded="true"])::after { opacity: 1; } /* Selected: text and mono icons turn yellow; no selected background, border or shadow. */ :is(.hm-sw-header, .hm-sw-theme) [data-selected="true"] { color: var(--hm-sw-header-selected-color); } @@ -1483,7 +1496,7 @@ div.hm-sw-header__menu-row { justify-content: space-between; gap: 8px; padding-l .hm-sw-property__title { position: relative; z-index: 2; flex: 1; min-width: 0; margin-left: 7px; padding-right: 4px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: 700; letter-spacing: .04em; color: var(--hm-sw-header-selected-color); text-shadow: var(--hm-sw-header-label-outline); } .hm-sw-property__tool { position: absolute; z-index: 2; right: 43px; top: 1px; width: 29px; height: 27.13px; } .hm-sw-property:not([data-selection-kind="single"]) .hm-sw-property__title { margin-right: 29px; } -.hm-sw-property__tool > img { position: absolute; top: 0; left: 0; display: block; width: 29px; height: 28px; } +.hm-sw-property__tool > img { position: absolute; top: 0; left: 0; display: block; width: 29px; height: 27.13px; } .hm-sw-property__tool-hover { visibility: hidden; } .hm-sw-property__tool:hover > .hm-sw-property__tool-default { visibility: hidden; } .hm-sw-property__tool:hover > .hm-sw-property__tool-hover { visibility: visible; } @@ -1510,8 +1523,24 @@ div.hm-sw-header__menu-row { justify-content: space-between; gap: 8px; padding-l .hm-sw-property__swatch { display: block; flex: 0 0 70px; height: 16px; padding: 1px; border: 1px solid #000; border-radius: 2px; } .hm-sw-property__swatch > i { display: block; height: 12px; border: 1px solid #fff; } .hm-sw-property__value > input[type="range"] { appearance: none; flex: 0 0 86px; width: 86px; height: 16px; margin: 0; background: transparent; cursor: pointer; } -.hm-sw-property__value > input[type="range"]::-webkit-slider-runnable-track { height: 3px; border: 1px solid rgba(28,26,22,.4); border-radius: 8px; background: linear-gradient(#8e0000, #ff4242 37%, #e40000 76%, #1e0000); } -.hm-sw-property__value > input[type="range"]::-webkit-slider-thumb { appearance: none; width: 14px; height: 14px; margin-top: -6px; border: 2px solid #ff5656; border-radius: 12px; background: conic-gradient(#520000, #ffb1b1 35%, #e40000 44%, #ffa7a7 57%, #520000 81%); box-shadow: 0 2px 2px rgba(28,26,22,.4), 0 0 3px #1c1a16; } +/* --hm-sw-range-fill (0-1) is set from the value; the red ends under the thumb centre (14px thumb). + The 3px radius rounds the fill's left cap; the first layer is its left stroke. Track and thumb are + shared values, painted once per engine: WebKit/Blink track + thumb, Gecko track + thumb (Gecko's + ::-moz-range-progress is kept empty so the fill is never painted twice). */ +.hm-sw-property__value > input[type="range"] { + --hm-sw-range-fill-width: calc(7px + (100% - 14px) * var(--hm-sw-range-fill, 0)); + --hm-sw-range-track-paint: + linear-gradient(90deg, var(--hm-sw-property-range-fill-edge) 0 1px, transparent 1px) 0 0 / var(--hm-sw-range-fill-width) 100% no-repeat, + var(--hm-sw-property-range-fill) 0 0 / var(--hm-sw-range-fill-width) 100% no-repeat, + var(--hm-sw-property-range-track); + --hm-sw-range-thumb-paint: url("../assets/property-range-thumb.svg") center / 14px 14px no-repeat; + --hm-sw-range-thumb-shadow: 0 0 3px #1c1a16, 0 2px 2px rgba(28, 26, 22, .4); +} +.hm-sw-property__value > input[type="range"]::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: var(--hm-sw-range-track-paint); box-shadow: 0 1px 0 var(--hm-sw-property-range-highlight); } +.hm-sw-property__value > input[type="range"]::-webkit-slider-thumb { appearance: none; width: 14px; height: 14px; margin-top: -4px; border: 0; border-radius: 50%; background: var(--hm-sw-range-thumb-paint); box-shadow: var(--hm-sw-range-thumb-shadow); } +.hm-sw-property__value > input[type="range"]::-moz-range-track { box-sizing: border-box; height: 6px; border: 0; border-radius: 3px; background: var(--hm-sw-range-track-paint); box-shadow: 0 1px 0 var(--hm-sw-property-range-highlight); } +.hm-sw-property__value > input[type="range"]::-moz-range-progress { height: 0; background: transparent; } +.hm-sw-property__value > input[type="range"]::-moz-range-thumb { box-sizing: border-box; width: 14px; height: 14px; border: 0; border-radius: 50%; background: var(--hm-sw-range-thumb-paint); box-shadow: var(--hm-sw-range-thumb-shadow); } .hm-sw-property__value > .hm-sw-header__line-preview { flex-basis: 68px; width: 68px; } .hm-sw-property__expand { display: block; width: 100%; height: 12px; overflow: hidden; } .hm-sw-property__expand > img { display: block; width: 296px; height: 12px; margin-left: calc((100% - 296px) / 2); } diff --git a/packages/sw/tests/followup-four.browser.mjs b/packages/sw/tests/followup-four.browser.mjs new file mode 100644 index 0000000..eb64a01 --- /dev/null +++ b/packages/sw/tests/followup-four.browser.mjs @@ -0,0 +1,195 @@ +// Usage: node packages/sw/tests/followup-four.browser.mjs [storybook-url] (Storybook uses packages/sw/dist: build first) +import { createRequire } from 'node:module' +import { mkdir, writeFile } from 'node:fs/promises' +import path from 'node:path' +const out = path.resolve(process.argv[2]) +const base = process.argv[3] ?? 'http://127.0.0.1:6024' +const { chromium } = createRequire(import.meta.url)(process.env.SW_PLAYWRIGHT_PATH ?? 'C:/Users/user/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright') +await mkdir(out, { recursive: true }) +const browser = await chromium.launch({ executablePath: process.env.SW_CHROME_PATH ?? 'C:/Program Files/Google/Chrome/Application/chrome.exe' }) +const page = await browser.newPage({ viewport: { width: 1920, height: 1000 } }) +const report = { checks: [], errors: [], data: {} } +page.on('pageerror', e => report.errors.push(e.message)) +page.on('console', m => { if (m.type() === 'error') report.errors.push(m.text()) }) +const check = (name, ok, data) => { report.checks.push({ name, status: ok ? 'PASS' : 'FAIL', data }); console.log(ok ? 'PASS' : 'FAIL', name, JSON.stringify(data)) } +const goto = async (id, w = 1920) => { + await page.setViewportSize({ width: w, height: 1000 }) + await page.goto(`${base}/iframe.html?id=sw-header--${id}&viewMode=story`) + await page.locator('.hm-sw-header, .hm-sw-theme').first().waitFor() + await page.evaluate(() => document.fonts.ready) + await page.mouse.move(1, 1) +} +// Pixel sampler on a screenshot buffer (decoded in page canvas). +const pixels = async (buf, pts) => page.evaluate(async ([b64, pts]) => { + const i = new Image(); i.src = 'data:image/png;base64,' + b64; await i.decode() + const c = document.createElement('canvas'); c.width = i.width; c.height = i.height; const x = c.getContext('2d'); x.drawImage(i, 0, 0) + return pts.map(([px, py]) => [...x.getImageData(px, py, 1, 1).data].slice(0, 3)) +}, [buf.toString('base64'), pts]) +const near = (a, b, t = 12) => a.every((v, k) => Math.abs(v - b[k]) <= t) + +// ---- A. Property bar +await goto('property-bar') +const toggleBar = page.locator('.hm-sw-header [data-property-bar-trigger], .hm-sw-header .hm-sw-header__toggle').filter({ hasText: '속성Bar' }).first() +await toggleBar.click() +const barGeo = () => page.evaluate(() => { + const bar = document.querySelector('.hm-sw-header .hm-sw-property-bar'), r = bar.getBoundingClientRect() + const fields = [...bar.querySelectorAll('.hm-sw-property-bar__field')], last = fields.at(-1).getBoundingClientRect() + const s = getComputedStyle(bar), header = document.querySelector('.hm-sw-header').getBoundingClientRect() + return { left: r.left, right: r.right, width: r.width, height: r.height, lastFieldRight: last.right, scrollW: bar.scrollWidth, clientW: bar.clientWidth, + borderBottom: s.borderBottomWidth + ' ' + s.borderBottomColor, radius: s.borderBottomLeftRadius + '/' + s.borderBottomRightRadius, bg: s.backgroundColor, + headerH: header.height, headerRight: header.right, fieldCount: fields.length } +}) +let g = await barGeo() +report.data.barDefault = g +check('A1 bar ends after last field (padding 6 + border 1)', Math.abs(g.right - g.lastFieldRight - 7) <= 1 && g.width < 1222, g) +check('A2 height 28 / header 49 / radius & border kept', g.height === 28 && g.headerH === 49 && g.radius === '6px/6px' && g.borderBottom.startsWith('1px'), g) +await page.locator('.hm-sw-header .hm-sw-property-bar').screenshot({ path: path.join(out, 'A-bar-1920.png') }) + +// Background and bottom line end at the same x: sample 2px inside and 2px outside the right edge at the bottom border row. +const barTop = await page.evaluate(() => document.querySelector('.hm-sw-header .hm-sw-property-bar').getBoundingClientRect().top) +const shot = await page.screenshot({ clip: { x: Math.floor(g.right) - 20, y: Math.floor(barTop), width: 40, height: 28 } }) +await page.screenshot({ path: path.join(out, 'A-bar-right-end.png'), clip: { x: Math.floor(g.right) - 60, y: Math.floor(barTop) - 10, width: 120, height: 40 } }) +const ex = g.right - (Math.floor(g.right) - 20) +const [inBg, outBg, inLine, outLine] = await pixels(shot, [[Math.floor(ex) - 4, 22], [Math.ceil(ex) + 3, 22], [Math.floor(ex) - 8, 27], [Math.ceil(ex) + 3, 27]]) +check('A3 background and bottom line end together; nothing brown beyond', near(inBg, [0x27, 0x1f, 0x13], 10) && !near(outBg, [0x27, 0x1f, 0x13], 10) && !near(outLine, inLine, 10), { inBg, outBg, inLine, outLine }) +for (let n = 0; n < 6; n++) await page.getByRole('button', { name: 'Bar 필드 추가' }).click() +g = await barGeo(); report.data.barGrown = g +check('A4 bar grows with added fields, none clipped', g.fieldCount === 10 && Math.abs(g.right - g.lastFieldRight - 7) <= 1 && g.scrollW <= g.clientW + 1, g) +for (let n = 0; n < 14; n++) await page.getByRole('button', { name: 'Bar 필드 추가' }).click() +g = await barGeo(); report.data.barOverflow = g +const lastVisible = await page.evaluate(() => { const bar = document.querySelector('.hm-sw-header .hm-sw-property-bar'); bar.scrollLeft = bar.scrollWidth; const f = [...bar.querySelectorAll('.hm-sw-property-bar__field')].at(-1).getBoundingClientRect(), r = bar.getBoundingClientRect(); return f.right <= r.right + 0.5 }) +check('A5 longer than space: capped to header edge, scroll reaches last field', g.right <= g.headerRight + 0.5 && g.scrollW > g.clientW && lastVisible, { ...g, lastVisible }) +await page.getByRole('button', { name: 'Bar 객체 교체' }).click() +g = await barGeo(); report.data.barReplaced = g +check('A6 bar shrinks back for a 1-field object', g.fieldCount === 1 && Math.abs(g.right - g.lastFieldRight - 7) <= 1, g) +for (const w of [1440, 1080, 768]) { + await goto('property-bar', w) + const t = page.locator('.hm-sw-header .hm-sw-header__toggle').filter({ hasText: '속성Bar' }).first() + if (await t.isVisible()) await t.click(); else { await page.locator('.hm-sw-header__more-trigger').click(); await page.locator('.hm-sw-header__more-item').filter({ hasText: '속성Bar' }).click() } + const gg = await barGeo(); report.data[`bar${w}`] = gg + const overflowX = await page.evaluate(() => document.documentElement.scrollWidth > document.documentElement.clientWidth) + check(`A7 width ${w}: bar within header, height 28, no page scroll`, gg.right <= gg.headerRight + 0.5 && gg.height === 28 && gg.headerH === 49 && !overflowX, { ...gg, overflowX }) +} + +// ---- B. Tool icon +await goto('property-panel-all') +const tool = page.locator('.hm-sw-property__tool').first() +const toolInfo = await tool.evaluate(e => { const s = getComputedStyle(e), imgs = [...e.querySelectorAll('img')].map(i => ({ cls: i.className, w: i.getBoundingClientRect().width, h: i.getBoundingClientRect().height, src: i.getAttribute('src').slice(0, 60) })); return { border: s.borderTopWidth + ' ' + s.borderTopColor, outline: s.outlineStyle, bg: s.backgroundColor, w: e.getBoundingClientRect().width, h: e.getBoundingClientRect().height, imgs } }) +report.data.tool = toolInfo +check('B1 no CSS border/outline/background on tool button', toolInfo.border.startsWith('0px') && toolInfo.outline === 'none' && toolInfo.bg === 'rgba(0, 0, 0, 0)', toolInfo) +check('B2 images 29 x 27.13 equal the button', toolInfo.imgs.every(i => i.w === 29 && Math.abs(i.h - 27.13) < 0.02), toolInfo.imgs) +const toolCorners = async name => { + const box = await tool.boundingBox() + const clip = { x: Math.floor(box.x) - 3, y: Math.floor(box.y) - 3, width: 36, height: 34 } + const b = await page.screenshot({ clip, scale: 'css' }) + await page.screenshot({ path: path.join(out, `B-tool-${name}.png`), clip }) + // Any near-white pixel within the 29x27 button area means a light frame. + const pts = []; for (let y = 3; y < 30; y++) for (let x = 3; x < 32; x++) pts.push([x, y]) + const px = await pixels(b, pts) + const white = px.filter(p => p.every(v => v >= 235)).length + const outer = [px[0], px[28], px[pts.length - 29], px[pts.length - 1]] // four corner pixels + return { white, outer } +} +const def = await toolCorners('default') +await tool.hover(); const hov = await toolCorners('hover') +await tool.click(); await page.mouse.move(1, 1); const act = await toolCorners('active') +const pressed = await tool.getAttribute('aria-pressed') +report.data.toolPixels = { def, hov, act, pressed } +check('B3 no white frame pixels (default/hover/active)', def.white === 0 && hov.white === 0 && act.white === 0, { def: def.white, hov: hov.white, act: act.white }) +check('B4 active toggles (aria-pressed)', pressed === 'true', { pressed }) + +// ---- C/D. Dropdown open: no trigger hover, inner hover kept +await goto('additional-hover') +const ringOpacity = sel => page.evaluate(s => { const e = document.querySelector(s); return { after: getComputedStyle(e, '::after').opacity, color: getComputedStyle(e).color, expanded: e.dataset.expanded ?? null } }, sel) +for (const menu of ['layer', 'color', 'text-style', 'dimension-style', 'line-style']) { + const sel = `.hm-sw-header .hm-sw-header__field[data-menu="${menu}"]` + const field = page.locator(sel).first() + await page.mouse.move(1, 1) + await field.hover(); const closedHover = await ringOpacity(sel) + await field.click(); await page.mouse.move(1, 1) + const openIdle = await ringOpacity(sel) + await field.hover(); const openHover = await ringOpacity(sel) + const shotIdle = null + await page.screenshot({ path: path.join(out, `C-${menu}-open-hover.png`), clip: { ...(await field.boundingBox()), x: (await field.boundingBox()).x - 4, y: 0, width: (await field.boundingBox()).width + 8, height: 60 } }) + // Inner list row + detail hover + const panel = page.locator('.hm-sw-header [data-open="true"]').first() + const rows = panel.locator('.hm-sw-header__menu-row:not([data-active="true"]):not([data-disabled]), .hm-sw-header__layer-row:not([data-active="true"]), .hm-sw-header__color-mode:not(:disabled)') + let rowChanged = null + for (let k = 0; k < Math.min(2, await rows.count()); k++) { + const row = rows.nth(k); await page.mouse.move(1, 1) + const st = e => { const t = e.querySelector('.hm-sw-header__menu-text') ?? e; return getComputedStyle(e).backgroundColor + '|' + getComputedStyle(t).color } + const b0 = await row.evaluate(st) + await row.hover(); const b1 = await row.evaluate(st) + rowChanged = rowChanged || b0 !== b1 + } + const detail = panel.locator('.hm-sw-header__menu-detail').first() + let detailChanged = null + if (await detail.count()) { + await page.mouse.move(1, 1) + const d0 = await detail.evaluate(e => getComputedStyle(e).backgroundColor + '|' + getComputedStyle(e).boxShadow + '|' + getComputedStyle(e).color) + await detail.hover(); const d1 = await detail.evaluate(e => getComputedStyle(e).backgroundColor + '|' + getComputedStyle(e).boxShadow + '|' + getComputedStyle(e).color) + detailChanged = d0 !== d1 + } + await page.keyboard.press('Escape'); await page.mouse.move(1, 1) + const closedAgain = await ringOpacity(sel) + await field.hover(); const restored = await ringOpacity(sel) + await page.mouse.move(1, 1) + const res = { closedHover, openIdle, openHover, closedAgain, restored, rowChanged, detailChanged } + report.data[`dropdown-${menu}`] = res + check(`C ${menu}: open+hover == open idle`, openIdle.expanded === 'true' && openHover.after === openIdle.after && openHover.color === openIdle.color, res) + check(`C ${menu}: hover restored after close`, closedAgain.expanded === null && restored.after === '1' && closedHover.after === '1' && restored.color === closedHover.color, res) + check(`D ${menu}: inner row hover kept / detail hover kept`, rowChanged !== false && detailChanged !== false, { rowChanged, detailChanged }) +} +// Focus-visible on an open trigger still shows the outline +{ + const sel = '.hm-sw-header .hm-sw-header__field[data-menu="color"]' + await page.locator(sel).first().focus(); await page.keyboard.press('Enter'); await page.keyboard.press('Shift+Tab').catch(() => {}) +} + +// ---- E. Gauge +await goto('property-panel-circle') +const range = page.locator('.hm-sw-property input[type="range"]').first() +const gaugeState = () => range.evaluate(e => ({ value: e.value, fill: e.style.getPropertyValue('--hm-sw-range-fill'), track: getComputedStyle(e).getPropertyValue('--hm-sw-property-range-track').trim() })) +const gaugePixels = async name => { + const b = await range.boundingBox() + const clip = { x: Math.floor(b.x), y: Math.floor(b.y), width: Math.ceil(b.width), height: Math.ceil(b.height) } + const buf = await page.screenshot({ clip }) + await page.screenshot({ path: path.join(out, `E-gauge-${name}.png`), clip }) + const st = await gaugeState(), f = Number(st.fill), cx = 7 + (clip.width - 14) * f, mid = Math.floor(clip.height / 2) + const [left, right] = await pixels(buf, [[Math.max(2, Math.floor(cx - 10)), mid], [Math.min(clip.width - 3, Math.ceil(cx + 10)), mid]]) + return { ...st, left, right, width: clip.width } +} +let gs = await gaugePixels('initial'); report.data.gaugeInitial = gs +const isRed = p => p[0] > 150 && p[1] < 90 && p[2] < 90, isBeige = p => p[0] > 190 && p[1] > 180 && p[2] > 160 && p[0] - p[2] > 15 +check('E1 initial 0.25: red left of thumb, beige right', gs.value === '0.25' && Math.abs(Number(gs.fill) - 0.25) < 1e-9 && isRed(gs.left) && isBeige(gs.right), gs) +await range.focus(); for (let n = 0; n < 40; n++) await page.keyboard.press('ArrowRight') +gs = await gaugePixels('keyboard'); report.data.gaugeKeyboard = gs +check('E2 keyboard ArrowRight x40 -> 0.65, fill follows', gs.value === '0.65' && Math.abs(Number(gs.fill) - 0.65) < 1e-9 && isRed(gs.left) && isBeige(gs.right), gs) +await page.keyboard.press('Enter') +await page.waitForFunction(() => document.querySelector('.hm-sw-property [data-property-id="opacity"] .hm-sw-header__input')?.value === '0.65', null, { timeout: 2000 }).catch(() => {}) +const committed = await page.locator('.hm-sw-property [data-property-id="opacity"] .hm-sw-header__input').first().inputValue().catch(() => null) +report.data.gaugeCommitted = committed +check('E3 commit updates the number input (callback path)', committed === '0.65', { committed }) +await page.keyboard.press('End'); gs = await gaugePixels('max'); report.data.gaugeMax = gs +check('E4 max -> fill 1', gs.value === '1' && Number(gs.fill) === 1 && isRed(gs.left), gs) +await page.keyboard.press('Home'); gs = await gaugePixels('min'); report.data.gaugeMin = gs +check('E5 min -> fill 0, beige right', gs.value === '0' && Number(gs.fill) === 0 && isBeige(gs.right), gs) +// External value: type into the numeric input and commit +const num = page.locator('.hm-sw-property [data-property-id="opacity"] .hm-sw-header__input').first() +await num.click(); await num.fill('0.5'); await num.press('Enter'); await page.mouse.move(1, 1) +gs = await gaugeState(); report.data.gaugeExternal = gs +check('E6 value changed elsewhere syncs gauge', gs.value === '0.5' && Number(gs.fill) === 0.5, gs) +await page.locator('.hm-sw-property').first().screenshot({ path: path.join(out, 'E-panel-circle.png') }) + +// ---- F. Panel four states render +for (const id of ['property-panel-none', 'property-panel-all', 'property-panel-circle', 'property-panel-expanded']) { + await goto(id) + const sz = await page.locator('.hm-sw-property').first().evaluate(e => { const r = e.getBoundingClientRect(); return [r.width, r.height] }) + report.data[id] = sz + await page.locator('.hm-sw-property').first().screenshot({ path: path.join(out, `F-${id}.png`) }) + check(`F ${id} renders`, sz[0] === 314 && sz[1] > 200, sz) +} +check('G no page/console errors', report.errors.length === 0, report.errors) +await writeFile(path.join(out, 'result.json'), JSON.stringify(report, null, 2)) +await browser.close() +console.log('TOTAL', report.checks.length, 'FAIL', report.checks.filter(c => c.status === 'FAIL').length) diff --git a/packages/sw/tests/property-close.browser.mjs b/packages/sw/tests/property-close.browser.mjs new file mode 100644 index 0000000..62ca875 --- /dev/null +++ b/packages/sw/tests/property-close.browser.mjs @@ -0,0 +1,62 @@ +// Property panel close button (Figma 26:12366): canvas bleed, Default / Hover, close by click and Escape. +// Usage: node packages/sw/tests/property-close.browser.mjs