@gramlot/gramlot-examples 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,7 +12,7 @@ npm install @gramlot/gramlot-examples
12
12
  [![PyPI](https://img.shields.io/pypi/v/gramlot-examples)](https://pypi.org/project/gramlot-examples/)
13
13
  [![npm](https://img.shields.io/npm/v/@gramlot/gramlot-examples)](https://www.npmjs.com/package/@gramlot/gramlot-examples)
14
14
 
15
- Current release: 0.3.7.
15
+ Current release: 0.3.8.
16
16
 
17
17
  [Documentation and learning sequence](https://gramlot-examples.readthedocs.io/en/latest/)
18
18
  include every lesson, its Python and JavaScript source, and the gallery guide.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gramlot/gramlot-examples",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "Gramlot example pages, the gallery page and its catalogue.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -14,7 +14,7 @@
14
14
  "prepack": "node scripts/build-browser.mjs"
15
15
  },
16
16
  "dependencies": {
17
- "@gramlot/gramlot": ">=0.3.4"
17
+ "@gramlot/gramlot": ">=0.3.5"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@genrojs/bag": ">=0.11.0",
@@ -24299,6 +24299,19 @@ var rangeParameters = {
24299
24299
  };
24300
24300
  function rangeEditor(vertical) {
24301
24301
  return (Base) => class extends Base {
24302
+ #sourceContext;
24303
+ #correcting = false;
24304
+ setSourceContext(context) {
24305
+ this.#sourceContext = context;
24306
+ }
24307
+ projectAttributes(attrs, adapt) {
24308
+ const previous = this.parameters;
24309
+ const rest = super.projectAttributes(attrs, adapt);
24310
+ if (previous && ["min", "max", "step"].some((name) => previous[name] !== this.parameters[name])) {
24311
+ this.writeControlValue(this.parameters.value);
24312
+ }
24313
+ return rest;
24314
+ }
24302
24315
  createControl() {
24303
24316
  const control = this.ownerDocument.createElement("input");
24304
24317
  control.type = "range";
@@ -24312,7 +24325,16 @@ function rangeEditor(vertical) {
24312
24325
  return this.control.valueAsNumber;
24313
24326
  }
24314
24327
  writeControlValue(value) {
24315
- if (this.control.valueAsNumber !== value) this.control.value = String(value);
24328
+ this.control.value = String(value);
24329
+ const corrected = this.control.valueAsNumber;
24330
+ if (!this.#correcting && Number.isFinite(value) && Number.isFinite(corrected) && corrected !== value) {
24331
+ this.#correcting = true;
24332
+ try {
24333
+ this.#sourceContext.writeParameter("value", corrected);
24334
+ } finally {
24335
+ this.#correcting = false;
24336
+ }
24337
+ }
24316
24338
  }
24317
24339
  };
24318
24340
  }
@@ -24322,6 +24344,7 @@ var HorizontalSlider = defineComponent({
24322
24344
  base: NativeControl,
24323
24345
  mixins: [Labelbox, FieldState],
24324
24346
  parameters: rangeParameters,
24347
+ sourceContext: true,
24325
24348
  implementation: rangeEditor(false)
24326
24349
  });
24327
24350
  var VerticalSlider = defineComponent({
@@ -24330,6 +24353,7 @@ var VerticalSlider = defineComponent({
24330
24353
  base: NativeControl,
24331
24354
  mixins: [Labelbox, FieldState],
24332
24355
  parameters: rangeParameters,
24356
+ sourceContext: true,
24333
24357
  implementation: rangeEditor(true)
24334
24358
  });
24335
24359
  var NumberTextBox = defineComponent({
@@ -21,11 +21,17 @@ Finally, try the design and corner-radius controls. These change presentation wh
21
21
  The slider and the region both use a plain pointer to the same number. Numeric region widths and heights are pixels; the borderContainer converts them to CSS internally. Dragging the splitter writes back the constrained number through the binding, so the slider follows immediately.
22
22
 
23
23
  ```python
24
- sliders.horizontalSlider(value="^regions.outer.left", min=90, max=240, live=True)
24
+ sliders.horizontalSlider(value="^regions.outer.left", min=90, max=240, step=1, live=True)
25
25
  nav = outer.borderContainer(region="left", width="^regions.outer.left",
26
26
  splitter=True, minSize=90, maxSize=240)
27
27
  ```
28
28
 
29
+ Each size slider uses `step=1`. It also corrects numbers received through the binding:
30
+ a fractional splitter measurement such as `176.73` becomes `177` in Data, then the
31
+ panel and label follow that same value. In Inspector, set `regions.outer.left`
32
+ to `176.73` and observe it settle at `177`. The slider writes only when correction
33
+ is needed; a number already on the step grid is not written again.
34
+
29
35
  There is no formatting suffix or synchronization controller. `regions` is just the Data branch chosen by this example; it is not a special container parameter. You can find all seven shared size bindings in **Code**.
30
36
 
31
37
  The nested containers still have a simple responsibility: each lays out its own immediate children. The outer container does not calculate the positions of every field inside the editor.