@fusion.dev/helix-headless 0.47.1 → 0.48.0
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/custom-elements.json +143 -33
- package/dist/color-picker/root/color-picker-root.d.ts +78 -3
- package/dist/color-picker/root/color-picker-root.js +47 -4
- package/dist/rating/root/rating-root.d.ts +65 -7
- package/dist/rating/root/rating-root.js +35 -8
- package/dist/time-picker/root/time-picker-root.d.ts +13 -0
- package/dist/time-picker/root/time-picker-root.js +2 -0
- package/package.json +5 -5
- package/types/jsx.d.ts +377 -22
- package/types/vue.d.ts +99 -4
package/custom-elements.json
CHANGED
|
@@ -19143,6 +19143,28 @@
|
|
|
19143
19143
|
"description": "Whether to leave the value out, for a picker whose value is stated elsewhere.\n\nThe row reads the color as text and lets it be typed or pasted, which is\nwhat makes this element complete standing on a page: a square and two ramps\ncan build a color and cannot state one, and a reader who has a hex already\nshould not have to find it by dragging.\n\nColor Input sets this, because its field is that input. Two editable fields\nfor one value is the outcome worth avoiding: two places to type, and no\nanswer to which one is authoritative or which has the caret. Do not close it\nthe other way round, with Color Input dropping its own field: the value\nwould then be unreadable and unpasteable without opening a panel.",
|
|
19144
19144
|
"attribute": "no-value"
|
|
19145
19145
|
},
|
|
19146
|
+
{
|
|
19147
|
+
"kind": "field",
|
|
19148
|
+
"name": "readOnly",
|
|
19149
|
+
"type": {
|
|
19150
|
+
"text": "boolean"
|
|
19151
|
+
},
|
|
19152
|
+
"default": "false",
|
|
19153
|
+
"description": "Whether the control refuses changes while still submitting its value.\n\n**Enforced by refusing every request in one place**, which is the seam this\ncomponent already has: `requestValue` is what every path here comes through,\nand gating it once is what stops the next call site from being written\nwithout the check.\n\nNot `disabled`, which is the confusion worth naming: a disabled control\nsubmits nothing and leaves the tab order, and a read-only one submits its\nvalue and stays reachable, which is what a form showing a color somebody\nelse set needs.\n\n**One gate is not enough here, and the second is `move`.** This picker\nholds a model beside its value, which Date Picker and Time Picker do not:\n`moved` is the HSB the square is drawn from, and it is written before the\nvalue is requested. Gating only the request would leave the square under\nthe reader's pointer and the value where it was, which is a control that\nrefuses and looks like it accepted.",
|
|
19154
|
+
"attribute": "readonly",
|
|
19155
|
+
"reflects": true
|
|
19156
|
+
},
|
|
19157
|
+
{
|
|
19158
|
+
"kind": "field",
|
|
19159
|
+
"name": "required",
|
|
19160
|
+
"type": {
|
|
19161
|
+
"text": "boolean"
|
|
19162
|
+
},
|
|
19163
|
+
"default": "false",
|
|
19164
|
+
"description": "Whether the form refuses to submit while no color is chosen.\n\n**A color is exactly as requirable as a date**, which is the comparison\nthat settles it: this element extends `HelixFormElement`, carries `name`\nand reports its value, so a consumer writing\n`<helix-color-picker name=\"brand\" required>` inside a form has every reason\nto expect the form to refuse an empty one. Its two siblings in the same\ncomposition position, Date Picker and Time Picker, both check it.\n\nWritten out rather than taken from `MixinField`, for the reason those two\nrecord: the mixin brings a label, a hint and a feedback region, and this is\na panel composed *into* a field that already has all three, so taking it\nwould give one control two of each. What is left is the validity call and\nthe anchor the browser points its bubble at.\n\n**Emptiness is the only fault reported, and bad input deliberately is\nnot.** The value row is typed into a character at a time and every\nkeystroke reaches `requestValue`, so `#0`, `#00` and `#00f` would each be a\nreported fault on the way to `#00ff00`. Date Picker and Time Picker can\nreport bad input because their value moves only on a commit. Color Input\nreports it for this family instead, once, against the field the reader\ntyped into.",
|
|
19165
|
+
"attribute": "required",
|
|
19166
|
+
"reflects": true
|
|
19167
|
+
},
|
|
19146
19168
|
{
|
|
19147
19169
|
"kind": "field",
|
|
19148
19170
|
"name": "swatches",
|
|
@@ -19228,6 +19250,31 @@
|
|
|
19228
19250
|
"readonly": true,
|
|
19229
19251
|
"description": "Takes what was typed, and lets the square follow only a whole color."
|
|
19230
19252
|
},
|
|
19253
|
+
{
|
|
19254
|
+
"kind": "method",
|
|
19255
|
+
"name": "requestValue",
|
|
19256
|
+
"return": {
|
|
19257
|
+
"type": {
|
|
19258
|
+
"text": "boolean"
|
|
19259
|
+
}
|
|
19260
|
+
},
|
|
19261
|
+
"parameters": [
|
|
19262
|
+
{
|
|
19263
|
+
"name": "next",
|
|
19264
|
+
"type": {
|
|
19265
|
+
"text": "string"
|
|
19266
|
+
}
|
|
19267
|
+
}
|
|
19268
|
+
],
|
|
19269
|
+
"description": "Refuses every change while read-only. See `readOnly`.",
|
|
19270
|
+
"inheritedFrom": {
|
|
19271
|
+
"name": "MixinControllerValue",
|
|
19272
|
+
"module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
|
|
19273
|
+
},
|
|
19274
|
+
"type": {
|
|
19275
|
+
"text": "requestValue(next: string) => boolean"
|
|
19276
|
+
}
|
|
19277
|
+
},
|
|
19231
19278
|
{
|
|
19232
19279
|
"kind": "field",
|
|
19233
19280
|
"name": "move",
|
|
@@ -19280,7 +19327,18 @@
|
|
|
19280
19327
|
"text": "void"
|
|
19281
19328
|
}
|
|
19282
19329
|
},
|
|
19283
|
-
"description": "Reports the color to the form.\n\n**The one thing a form-associated element owes, and this element owed it\nfrom the start without paying.** It extends `HelixFormElement`, takes\n`MixinControllerValue` and carries `name`, so a consumer writing\n`<helix-color-picker name=\"brand\">` inside a form has every reason to\nexpect an entry, and the form carried none: no error, nothing in the\nmarkup to look at, and a field silently missing from the submission. Its\ntwo siblings in the same composition position, Color Input and Slider,\nboth report.\n\n`null` rather than an empty string where there is no color, which is the\ndifference between a control that submits nothing and one that submits a\nblank
|
|
19330
|
+
"description": "Reports the color to the form.\n\n**The one thing a form-associated element owes, and this element owed it\nfrom the start without paying.** It extends `HelixFormElement`, takes\n`MixinControllerValue` and carries `name`, so a consumer writing\n`<helix-color-picker name=\"brand\">` inside a form has every reason to\nexpect an entry, and the form carried none: no error, nothing in the\nmarkup to look at, and a field silently missing from the submission. Its\ntwo siblings in the same composition position, Color Input and Slider,\nboth report.\n\n`null` rather than an empty string where there is no color, which is the\ndifference between a control that submits nothing and one that submits a\nblank.\n\nThe verdict goes beside it, because `required` is this element's own claim\nand nothing else can answer it: a picker standing on a page has no field\naround it to check on its behalf. What it is *not* is a second opinion on\neverything else, which is why bad input is left to Color Input. See\n`required`."
|
|
19331
|
+
},
|
|
19332
|
+
{
|
|
19333
|
+
"kind": "method",
|
|
19334
|
+
"name": "reportRequired",
|
|
19335
|
+
"privacy": "private",
|
|
19336
|
+
"return": {
|
|
19337
|
+
"type": {
|
|
19338
|
+
"text": "void"
|
|
19339
|
+
}
|
|
19340
|
+
},
|
|
19341
|
+
"description": "Reports \"required and empty\", or clears it.\n\nAnchored on the square, which is where a reader would go to answer: it is\nthe first control in the panel and the one `focus` puts the keyboard on, so\nthe browser's bubble points at the thing to do rather than at the row that\nstates the result."
|
|
19284
19342
|
},
|
|
19285
19343
|
{
|
|
19286
19344
|
"kind": "method",
|
|
@@ -19366,6 +19424,31 @@
|
|
|
19366
19424
|
],
|
|
19367
19425
|
"description": "One axis of the area, taken the way `takeChannel` takes a rail.\n\n**Named rather than inline because of the first line.** The `<input\ntype=\"range\">` behind each axis sends its own composed `input`, which\nreaches a consumer listening on this element beside this element's own\nunless it is stopped: a consumer dragging the area receives the range's\nevent and not this component's."
|
|
19368
19426
|
},
|
|
19427
|
+
{
|
|
19428
|
+
"kind": "method",
|
|
19429
|
+
"name": "putBack",
|
|
19430
|
+
"privacy": "private",
|
|
19431
|
+
"return": {
|
|
19432
|
+
"type": {
|
|
19433
|
+
"text": "void"
|
|
19434
|
+
}
|
|
19435
|
+
},
|
|
19436
|
+
"parameters": [
|
|
19437
|
+
{
|
|
19438
|
+
"name": "control",
|
|
19439
|
+
"type": {
|
|
19440
|
+
"text": "{ value: string }"
|
|
19441
|
+
}
|
|
19442
|
+
},
|
|
19443
|
+
{
|
|
19444
|
+
"name": "at",
|
|
19445
|
+
"type": {
|
|
19446
|
+
"text": "number"
|
|
19447
|
+
}
|
|
19448
|
+
}
|
|
19449
|
+
],
|
|
19450
|
+
"description": "Returns a control that moved itself to what the model still holds.\n\n**A refusal has to undo something, and here it is a handle.** Every other\ncontrol in this picker is drawn from the model, so refusing the change\nleaves the picture right on its own. The two area ranges and the two\nchannel sliders are not: each moved before it announced, and each is bound\nwith `.value`, which lit dirty-checks against the value it last committed.\nThe model never changed, so that binding writes nothing and the handle\nstays where the reader dragged it, on a control that refused. Carousel\nsettles the same question the same way: a refusal puts the track back on\nthe slide the index still holds."
|
|
19451
|
+
},
|
|
19369
19452
|
{
|
|
19370
19453
|
"kind": "method",
|
|
19371
19454
|
"name": "takeChannel",
|
|
@@ -19473,31 +19556,6 @@
|
|
|
19473
19556
|
"module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
|
|
19474
19557
|
}
|
|
19475
19558
|
},
|
|
19476
|
-
{
|
|
19477
|
-
"kind": "method",
|
|
19478
|
-
"name": "requestValue",
|
|
19479
|
-
"return": {
|
|
19480
|
-
"type": {
|
|
19481
|
-
"text": "boolean"
|
|
19482
|
-
}
|
|
19483
|
-
},
|
|
19484
|
-
"parameters": [
|
|
19485
|
-
{
|
|
19486
|
-
"name": "next",
|
|
19487
|
-
"type": {
|
|
19488
|
-
"text": "string"
|
|
19489
|
-
}
|
|
19490
|
-
}
|
|
19491
|
-
],
|
|
19492
|
-
"description": "Requests a new value, and reports whether the request stood.\n\nAnnounces before it acts, so `preventDefault()` on the `helix-before-change` is\na refusal and nothing moves. Nobody refusing means the control updates\nitself, whether or not a consumer declared `value`: a declared property\nis a seed and a correction, the way `<input value>` is, and a consumer\nwho wants the change for themselves refuses it and assigns their own.",
|
|
19493
|
-
"inheritedFrom": {
|
|
19494
|
-
"name": "MixinControllerValue",
|
|
19495
|
-
"module": "src/mixins/mixin-controller-value/mixin-controller-value.ts"
|
|
19496
|
-
},
|
|
19497
|
-
"type": {
|
|
19498
|
-
"text": "requestValue(next: string) => boolean"
|
|
19499
|
-
}
|
|
19500
|
-
},
|
|
19501
19559
|
{
|
|
19502
19560
|
"kind": "method",
|
|
19503
19561
|
"name": "formResetCallback",
|
|
@@ -20134,6 +20192,24 @@
|
|
|
20134
20192
|
"description": "Whether to leave the value out, for a picker whose value is stated elsewhere.\n\nThe row reads the color as text and lets it be typed or pasted, which is\nwhat makes this element complete standing on a page: a square and two ramps\ncan build a color and cannot state one, and a reader who has a hex already\nshould not have to find it by dragging.\n\nColor Input sets this, because its field is that input. Two editable fields\nfor one value is the outcome worth avoiding: two places to type, and no\nanswer to which one is authoritative or which has the caret. Do not close it\nthe other way round, with Color Input dropping its own field: the value\nwould then be unreadable and unpasteable without opening a panel.",
|
|
20135
20193
|
"fieldName": "noValue"
|
|
20136
20194
|
},
|
|
20195
|
+
{
|
|
20196
|
+
"name": "readonly",
|
|
20197
|
+
"type": {
|
|
20198
|
+
"text": "boolean"
|
|
20199
|
+
},
|
|
20200
|
+
"default": "false",
|
|
20201
|
+
"description": "Whether the control refuses changes while still submitting its value.\n\n**Enforced by refusing every request in one place**, which is the seam this\ncomponent already has: `requestValue` is what every path here comes through,\nand gating it once is what stops the next call site from being written\nwithout the check.\n\nNot `disabled`, which is the confusion worth naming: a disabled control\nsubmits nothing and leaves the tab order, and a read-only one submits its\nvalue and stays reachable, which is what a form showing a color somebody\nelse set needs.\n\n**One gate is not enough here, and the second is `move`.** This picker\nholds a model beside its value, which Date Picker and Time Picker do not:\n`moved` is the HSB the square is drawn from, and it is written before the\nvalue is requested. Gating only the request would leave the square under\nthe reader's pointer and the value where it was, which is a control that\nrefuses and looks like it accepted.",
|
|
20202
|
+
"fieldName": "readOnly"
|
|
20203
|
+
},
|
|
20204
|
+
{
|
|
20205
|
+
"name": "required",
|
|
20206
|
+
"type": {
|
|
20207
|
+
"text": "boolean"
|
|
20208
|
+
},
|
|
20209
|
+
"default": "false",
|
|
20210
|
+
"description": "Whether the form refuses to submit while no color is chosen.\n\n**A color is exactly as requirable as a date**, which is the comparison\nthat settles it: this element extends `HelixFormElement`, carries `name`\nand reports its value, so a consumer writing\n`<helix-color-picker name=\"brand\" required>` inside a form has every reason\nto expect the form to refuse an empty one. Its two siblings in the same\ncomposition position, Date Picker and Time Picker, both check it.\n\nWritten out rather than taken from `MixinField`, for the reason those two\nrecord: the mixin brings a label, a hint and a feedback region, and this is\na panel composed *into* a field that already has all three, so taking it\nwould give one control two of each. What is left is the validity call and\nthe anchor the browser points its bubble at.\n\n**Emptiness is the only fault reported, and bad input deliberately is\nnot.** The value row is typed into a character at a time and every\nkeystroke reaches `requestValue`, so `#0`, `#00` and `#00f` would each be a\nreported fault on the way to `#00ff00`. Date Picker and Time Picker can\nreport bad input because their value moves only on a commit. Color Input\nreports it for this family instead, once, against the field the reader\ntyped into.",
|
|
20211
|
+
"fieldName": "required"
|
|
20212
|
+
},
|
|
20137
20213
|
{
|
|
20138
20214
|
"name": "swatches",
|
|
20139
20215
|
"type": {
|
|
@@ -72111,11 +72187,11 @@
|
|
|
72111
72187
|
"name": "--rating-part"
|
|
72112
72188
|
},
|
|
72113
72189
|
{
|
|
72114
|
-
"description": "
|
|
72190
|
+
"description": "Which step along the row a target is, counting from one, whatever `min` leaves open.",
|
|
72115
72191
|
"name": "--rating-step"
|
|
72116
72192
|
},
|
|
72117
72193
|
{
|
|
72118
|
-
"description": "How many steps
|
|
72194
|
+
"description": "How many steps the whole row holds, which is `max` over `step`.",
|
|
72119
72195
|
"name": "--rating-steps"
|
|
72120
72196
|
}
|
|
72121
72197
|
],
|
|
@@ -72124,6 +72200,10 @@
|
|
|
72124
72200
|
"description": "What is wrong with it.",
|
|
72125
72201
|
"name": "feedback"
|
|
72126
72202
|
},
|
|
72203
|
+
{
|
|
72204
|
+
"description": "The row: the marks, and the score beside them.",
|
|
72205
|
+
"name": "field"
|
|
72206
|
+
},
|
|
72127
72207
|
{
|
|
72128
72208
|
"description": "The filled marks, clipped to the score.",
|
|
72129
72209
|
"name": "fill"
|
|
@@ -72190,7 +72270,7 @@
|
|
|
72190
72270
|
"text": "number"
|
|
72191
72271
|
},
|
|
72192
72272
|
"default": "0",
|
|
72193
|
-
"description": "The lowest score a reader can give, which is what clearing returns to.\n\nZero rather than one, because \"no rating\" and \"the worst rating\" are\ndifferent answers and a control that cannot express the first has to\npretend the second. A survey that requires an answer says so with\n`required`, not by making one unreachable.",
|
|
72273
|
+
"description": "The lowest score a reader can give, which is what clearing returns to.\n\nZero rather than one, because \"no rating\" and \"the worst rating\" are\ndifferent answers and a control that cannot express the first has to\npretend the second. A survey that requires an answer says so with\n`required`, not by making one unreachable.\n\n**It is the floor of the scale, and every edge follows from that.**\n\n*Clearing* returns the row to it. An empty rating, a value nothing can\nparse, and a form reset with nothing declared are all the same situation,\nand all three draw `min` filled: at the default of zero that is the empty\nrow this always drew, and at `min=\"2\"` it is two marks, the way an empty\n`Slider` sits at its own minimum rather than at zero. The value is still\n`\"\"` through all of it, so `required` still refuses it and `valueAsNumber`\nis still `NaN`: what the row shows is the bottom of the scale, not an\nanswer somebody gave.\n\n*The steps* are the scores from `step` up to `max` that are not below it,\nso `min=\"2\"` on five marks offers 2 to 5 and leaves the first two marks\nfilled and unpressable. At zero nothing is dropped, which is why the\ndefault row is unchanged.\n\n*The keyboard* moves through those steps and no others. `wrap` is already\nfalse here, so arrowing down from the lowest one holds its ground rather\nthan reaching a score this property forbids, and the tab stop an unrated\nrating carries sits on the lowest score offered rather than on the first\nmark.\n\n*A `min` between two steps* is a floor and not a step: `min=\"1.5\"` with\nwhole marks clamps the value at 1.5 and offers 2 upward, since 1.5 is not\nsomewhere the row can be pressed. That is a real thing to ask for and is\nleft to mean what it says.\n\n*A `min` outside the marks is refused rather than obeyed*, and says so\nonce on the console. Below zero and anything that is not a number are read\nas zero, there being no mark to draw for a negative score; above `max` is\nread as `max`, which collapses the scale to its top score rather than\nleaving a rating with nothing to press. A property that silently accepts\nnonsense is the fault this pays off, so neither case is quietly ignored.",
|
|
72194
72274
|
"attribute": "min"
|
|
72195
72275
|
},
|
|
72196
72276
|
{
|
|
@@ -72272,6 +72352,16 @@
|
|
|
72272
72352
|
"readonly": true,
|
|
72273
72353
|
"default": "new KeyboardNavigationController(this, { items: () => this.options, selects: () => true, wrap: false, })"
|
|
72274
72354
|
},
|
|
72355
|
+
{
|
|
72356
|
+
"kind": "field",
|
|
72357
|
+
"name": "floor",
|
|
72358
|
+
"type": {
|
|
72359
|
+
"text": "number"
|
|
72360
|
+
},
|
|
72361
|
+
"privacy": "private",
|
|
72362
|
+
"description": "The floor the row actually uses, which is `min` where `min` is one.\n\nBetween zero and `max`, and zero for anything that is not a number, per\nthe note on `min`. Derived on read rather than corrected into the property,\nso `rating.min` still reports what the consumer set and the warning below\ncan tell the two apart.",
|
|
72363
|
+
"readonly": true
|
|
72364
|
+
},
|
|
72275
72365
|
{
|
|
72276
72366
|
"kind": "field",
|
|
72277
72367
|
"name": "score",
|
|
@@ -72281,6 +72371,16 @@
|
|
|
72281
72371
|
"description": "The score, as a number, clamped to what the marks can show.",
|
|
72282
72372
|
"readonly": true
|
|
72283
72373
|
},
|
|
72374
|
+
{
|
|
72375
|
+
"kind": "field",
|
|
72376
|
+
"name": "positions",
|
|
72377
|
+
"type": {
|
|
72378
|
+
"text": "number[]"
|
|
72379
|
+
},
|
|
72380
|
+
"privacy": "private",
|
|
72381
|
+
"description": "Every score the marks can show, which is `max / step` of them.\n\nThe whole row rather than the part `min` leaves open, because this is what\nthe stylesheet lays the targets out against: `--rating-steps` is the pitch\nand a step's own place in this list is where it sits along the row. Counted\nfrom the part a reader can press instead, a floor above zero would widen\nevery target and slide the row left.",
|
|
72382
|
+
"readonly": true
|
|
72383
|
+
},
|
|
72284
72384
|
{
|
|
72285
72385
|
"kind": "field",
|
|
72286
72386
|
"name": "steps",
|
|
@@ -72288,7 +72388,7 @@
|
|
|
72288
72388
|
"text": "number[]"
|
|
72289
72389
|
},
|
|
72290
72390
|
"privacy": "private",
|
|
72291
|
-
"description": "Every score a reader can choose, which is
|
|
72391
|
+
"description": "Every score a reader can choose, which is the positions `min` leaves open.",
|
|
72292
72392
|
"readonly": true
|
|
72293
72393
|
},
|
|
72294
72394
|
{
|
|
@@ -72403,7 +72503,7 @@
|
|
|
72403
72503
|
"text": "void"
|
|
72404
72504
|
}
|
|
72405
72505
|
},
|
|
72406
|
-
"description": "Reports the value, and whether the form may go without one.\n\n**`required` arrives from the mixin, so it prints on the reference page\nwhether or not anything here enforces it.** Without a `setValidity` call a\nform holding an unrated required rating submits, `:valid` true and the\nentry present but empty. `reportRequired` is what makes the property real.\n\n**Empty is `value === ''` rather than a score
|
|
72506
|
+
"description": "Reports the value, and whether the form may go without one.\n\n**`required` arrives from the mixin, so it prints on the reference page\nwhether or not anything here enforces it.** Without a `setValidity` call a\nform holding an unrated required rating submits, `:valid` true and the\nentry present but empty. `reportRequired` is what makes the property real.\n\n**Empty is `value === ''` rather than a score at the floor**, and the two\nare not the same thing: an unanswered row draws `min`, per the note on that\nproperty, so a control that read its own picture would call every rating\nwith `min=\"2\"` answered the moment it rendered. What `required` asks is\nwhether the reader answered at all, which only the value knows. A consumer\nwho writes `value=\"0\"` has answered, and is not refused.\n\n`Slider` is deliberately not given the same treatment: a native\n`<input type=\"range\" required>` is always valid, because a range always\nholds a number, and matching the platform there is the point."
|
|
72407
72507
|
},
|
|
72408
72508
|
{
|
|
72409
72509
|
"kind": "field",
|
|
@@ -72423,6 +72523,16 @@
|
|
|
72423
72523
|
"privacy": "private",
|
|
72424
72524
|
"readonly": true
|
|
72425
72525
|
},
|
|
72526
|
+
{
|
|
72527
|
+
"kind": "field",
|
|
72528
|
+
"name": "warned",
|
|
72529
|
+
"type": {
|
|
72530
|
+
"text": "boolean"
|
|
72531
|
+
},
|
|
72532
|
+
"privacy": "private",
|
|
72533
|
+
"default": "false",
|
|
72534
|
+
"description": "Whether the console has already been told about a `min` off the scale."
|
|
72535
|
+
},
|
|
72426
72536
|
{
|
|
72427
72537
|
"kind": "field",
|
|
72428
72538
|
"name": "valueAsNumber",
|
|
@@ -73301,7 +73411,7 @@
|
|
|
73301
73411
|
"text": "number"
|
|
73302
73412
|
},
|
|
73303
73413
|
"default": "0",
|
|
73304
|
-
"description": "The lowest score a reader can give, which is what clearing returns to.\n\nZero rather than one, because \"no rating\" and \"the worst rating\" are\ndifferent answers and a control that cannot express the first has to\npretend the second. A survey that requires an answer says so with\n`required`, not by making one unreachable.",
|
|
73414
|
+
"description": "The lowest score a reader can give, which is what clearing returns to.\n\nZero rather than one, because \"no rating\" and \"the worst rating\" are\ndifferent answers and a control that cannot express the first has to\npretend the second. A survey that requires an answer says so with\n`required`, not by making one unreachable.\n\n**It is the floor of the scale, and every edge follows from that.**\n\n*Clearing* returns the row to it. An empty rating, a value nothing can\nparse, and a form reset with nothing declared are all the same situation,\nand all three draw `min` filled: at the default of zero that is the empty\nrow this always drew, and at `min=\"2\"` it is two marks, the way an empty\n`Slider` sits at its own minimum rather than at zero. The value is still\n`\"\"` through all of it, so `required` still refuses it and `valueAsNumber`\nis still `NaN`: what the row shows is the bottom of the scale, not an\nanswer somebody gave.\n\n*The steps* are the scores from `step` up to `max` that are not below it,\nso `min=\"2\"` on five marks offers 2 to 5 and leaves the first two marks\nfilled and unpressable. At zero nothing is dropped, which is why the\ndefault row is unchanged.\n\n*The keyboard* moves through those steps and no others. `wrap` is already\nfalse here, so arrowing down from the lowest one holds its ground rather\nthan reaching a score this property forbids, and the tab stop an unrated\nrating carries sits on the lowest score offered rather than on the first\nmark.\n\n*A `min` between two steps* is a floor and not a step: `min=\"1.5\"` with\nwhole marks clamps the value at 1.5 and offers 2 upward, since 1.5 is not\nsomewhere the row can be pressed. That is a real thing to ask for and is\nleft to mean what it says.\n\n*A `min` outside the marks is refused rather than obeyed*, and says so\nonce on the console. Below zero and anything that is not a number are read\nas zero, there being no mark to draw for a negative score; above `max` is\nread as `max`, which collapses the scale to its top score rather than\nleaving a rating with nothing to press. A property that silently accepts\nnonsense is the fault this pays off, so neither case is quietly ignored.",
|
|
73305
73415
|
"fieldName": "min"
|
|
73306
73416
|
},
|
|
73307
73417
|
{
|
|
@@ -93661,7 +93771,7 @@
|
|
|
93661
93771
|
},
|
|
93662
93772
|
{
|
|
93663
93773
|
"kind": "class",
|
|
93664
|
-
"description": "**A list rather than three wheels**, and the reason is what a list already\nis. `helix-listbox` brings the keyboard, the typeahead, the scroll into view\nand the announcement of a set of options, and a time at a step is a set of\noptions. Three little wheels for hours, minutes and a meridiem are three\ncontrols to build, three to test, and a tab stop each for something a reader\nanswers once.\n\n**A step is what makes it a list at all.** Fifteen minutes is ninety-six rows,\nwhich a reader scrolls or types into; one minute is one thousand four hundred\nand forty, which is a listbox in name only. So the list is for the times a\nproduct actually offers, and arbitrary times are the field's job in Input\nTime, the same division Date Input draws between typing a date and using the\ncalendar.\n\n**The value is `HH:mm` on a twenty-four hour clock, always.** That is what a\nform submits and what `min` and `max` compare against, and it sorts as a\nstring, which is the whole reason the shape is that one. What each row *says*\nis the reader's own convention, from `Intl`.",
|
|
93774
|
+
"description": "**A list rather than three wheels**, and the reason is what a list already\nis. `helix-listbox` brings the keyboard, the typeahead, the scroll into view\nand the announcement of a set of options, and a time at a step is a set of\noptions. Three little wheels for hours, minutes and a meridiem are three\ncontrols to build, three to test, and a tab stop each for something a reader\nanswers once.\n\n**A step is what makes it a list at all.** Fifteen minutes is ninety-six rows,\nwhich a reader scrolls or types into; one minute is one thousand four hundred\nand forty, which is a listbox in name only. So the list is for the times a\nproduct actually offers, and arbitrary times are the field's job in Input\nTime, the same division Date Input draws between typing a date and using the\ncalendar.\n\n**The value is `HH:mm` on a twenty-four hour clock, always.** That is what a\nform submits and what `min` and `max` compare against, and it sorts as a\nstring, which is the whole reason the shape is that one. What each row *says*\nis the reader's own convention, from `Intl`.\n\n**The chosen row is marked in the markup, not worked out on upgrade.** The\nlistbox is handed the answer as `.value`, and lit-ssr serializes no property\nbinding, so a served `value=\"09:30\"` shipped ninety-six rows with nothing on\nany of them saying which one it was: the mark arrived when the listbox\nupgraded and ran `place`. So each option is given `selected` as well, which\nis an attribute binding and does serve, and which the listbox then agrees\nwith rather than fights, `place` writing the same answer from the same value.\n`selected` is the declaration a consumer writes on `Option` anywhere else in\nthe library, and Date Picker expresses its own choice as markup for the same\nreason: a picker whose answer is invisible until a script runs is a picker\nwhose answer is not served at all. Both readings do it, the list and the\nwheels, a wheel being a listbox like the list is.",
|
|
93665
93775
|
"name": "HelixHeadlessTimePicker",
|
|
93666
93776
|
"cssParts": [
|
|
93667
93777
|
{
|
|
@@ -128,6 +128,52 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
128
128
|
* would then be unreadable and unpasteable without opening a panel.
|
|
129
129
|
*/
|
|
130
130
|
noValue: boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Whether the control refuses changes while still submitting its value.
|
|
133
|
+
*
|
|
134
|
+
* **Enforced by refusing every request in one place**, which is the seam this
|
|
135
|
+
* component already has: `requestValue` is what every path here comes through,
|
|
136
|
+
* and gating it once is what stops the next call site from being written
|
|
137
|
+
* without the check.
|
|
138
|
+
*
|
|
139
|
+
* Not `disabled`, which is the confusion worth naming: a disabled control
|
|
140
|
+
* submits nothing and leaves the tab order, and a read-only one submits its
|
|
141
|
+
* value and stays reachable, which is what a form showing a color somebody
|
|
142
|
+
* else set needs.
|
|
143
|
+
*
|
|
144
|
+
* **One gate is not enough here, and the second is `move`.** This picker
|
|
145
|
+
* holds a model beside its value, which Date Picker and Time Picker do not:
|
|
146
|
+
* `moved` is the HSB the square is drawn from, and it is written before the
|
|
147
|
+
* value is requested. Gating only the request would leave the square under
|
|
148
|
+
* the reader's pointer and the value where it was, which is a control that
|
|
149
|
+
* refuses and looks like it accepted.
|
|
150
|
+
*/
|
|
151
|
+
readOnly: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Whether the form refuses to submit while no color is chosen.
|
|
154
|
+
*
|
|
155
|
+
* **A color is exactly as requirable as a date**, which is the comparison
|
|
156
|
+
* that settles it: this element extends `HelixFormElement`, carries `name`
|
|
157
|
+
* and reports its value, so a consumer writing
|
|
158
|
+
* `<helix-color-picker name="brand" required>` inside a form has every reason
|
|
159
|
+
* to expect the form to refuse an empty one. Its two siblings in the same
|
|
160
|
+
* composition position, Date Picker and Time Picker, both check it.
|
|
161
|
+
*
|
|
162
|
+
* Written out rather than taken from `MixinField`, for the reason those two
|
|
163
|
+
* record: the mixin brings a label, a hint and a feedback region, and this is
|
|
164
|
+
* a panel composed *into* a field that already has all three, so taking it
|
|
165
|
+
* would give one control two of each. What is left is the validity call and
|
|
166
|
+
* the anchor the browser points its bubble at.
|
|
167
|
+
*
|
|
168
|
+
* **Emptiness is the only fault reported, and bad input deliberately is
|
|
169
|
+
* not.** The value row is typed into a character at a time and every
|
|
170
|
+
* keystroke reaches `requestValue`, so `#0`, `#00` and `#00f` would each be a
|
|
171
|
+
* reported fault on the way to `#00ff00`. Date Picker and Time Picker can
|
|
172
|
+
* report bad input because their value moves only on a commit. Color Input
|
|
173
|
+
* reports it for this family instead, once, against the field the reader
|
|
174
|
+
* typed into.
|
|
175
|
+
*/
|
|
176
|
+
required: boolean;
|
|
131
177
|
/**
|
|
132
178
|
* Colors offered under the picker, as a comma-separated list.
|
|
133
179
|
*/
|
|
@@ -183,6 +229,8 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
183
229
|
private settled;
|
|
184
230
|
/** Takes what was typed, and lets the square follow only a whole color. */
|
|
185
231
|
private readonly handleValueInput;
|
|
232
|
+
/** Refuses every change while read-only. See `readOnly`. */
|
|
233
|
+
requestValue(next: string): boolean;
|
|
186
234
|
/** Moves part of the model and announces the value that follows from it. */
|
|
187
235
|
private readonly move;
|
|
188
236
|
/**
|
|
@@ -237,11 +285,24 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
237
285
|
*
|
|
238
286
|
* `null` rather than an empty string where there is no color, which is the
|
|
239
287
|
* difference between a control that submits nothing and one that submits a
|
|
240
|
-
* blank.
|
|
241
|
-
*
|
|
242
|
-
*
|
|
288
|
+
* blank.
|
|
289
|
+
*
|
|
290
|
+
* The verdict goes beside it, because `required` is this element's own claim
|
|
291
|
+
* and nothing else can answer it: a picker standing on a page has no field
|
|
292
|
+
* around it to check on its behalf. What it is *not* is a second opinion on
|
|
293
|
+
* everything else, which is why bad input is left to Color Input. See
|
|
294
|
+
* `required`.
|
|
243
295
|
*/
|
|
244
296
|
private sync;
|
|
297
|
+
/**
|
|
298
|
+
* Reports "required and empty", or clears it.
|
|
299
|
+
*
|
|
300
|
+
* Anchored on the square, which is where a reader would go to answer: it is
|
|
301
|
+
* the first control in the panel and the one `focus` puts the keyboard on, so
|
|
302
|
+
* the browser's bubble points at the thing to do rather than at the row that
|
|
303
|
+
* states the result.
|
|
304
|
+
*/
|
|
305
|
+
private reportRequired;
|
|
245
306
|
protected updated(changed: import('lit').PropertyValues): void;
|
|
246
307
|
/** Puts the keyboard on the square, which is the control a reader wants. */
|
|
247
308
|
focus(options?: FocusOptions): void;
|
|
@@ -262,6 +323,20 @@ export declare class HelixHeadlessColorPicker extends HelixHeadlessColorPicker_b
|
|
|
262
323
|
* event and not this component's.
|
|
263
324
|
*/
|
|
264
325
|
private takeArea;
|
|
326
|
+
/**
|
|
327
|
+
* Returns a control that moved itself to what the model still holds.
|
|
328
|
+
*
|
|
329
|
+
* **A refusal has to undo something, and here it is a handle.** Every other
|
|
330
|
+
* control in this picker is drawn from the model, so refusing the change
|
|
331
|
+
* leaves the picture right on its own. The two area ranges and the two
|
|
332
|
+
* channel sliders are not: each moved before it announced, and each is bound
|
|
333
|
+
* with `.value`, which lit dirty-checks against the value it last committed.
|
|
334
|
+
* The model never changed, so that binding writes nothing and the handle
|
|
335
|
+
* stays where the reader dragged it, on a control that refused. Carousel
|
|
336
|
+
* settles the same question the same way: a refusal puts the track back on
|
|
337
|
+
* the slide the index still holds.
|
|
338
|
+
*/
|
|
339
|
+
private putBack;
|
|
265
340
|
/**
|
|
266
341
|
* A channel's new value, read off the slider that just applied it.
|
|
267
342
|
*
|
|
@@ -24,12 +24,17 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
|
|
|
24
24
|
this.noEyedropper = false;
|
|
25
25
|
this.noFormat = false;
|
|
26
26
|
this.noValue = false;
|
|
27
|
+
this.readOnly = false;
|
|
28
|
+
this.required = false;
|
|
27
29
|
this.swatches = '';
|
|
28
30
|
this.sampling = false;
|
|
29
31
|
this.owned = false;
|
|
30
32
|
this.settled = '';
|
|
31
33
|
this.handleValueInput = (event) => {
|
|
32
34
|
event.stopPropagation();
|
|
35
|
+
if (this.readOnly) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
33
38
|
const typed = event.target.value;
|
|
34
39
|
const parsed = parseColor(typed);
|
|
35
40
|
if (parsed) {
|
|
@@ -39,6 +44,9 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
|
|
|
39
44
|
this.requestValue(typed);
|
|
40
45
|
};
|
|
41
46
|
this.move = (next) => {
|
|
47
|
+
if (this.readOnly) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
42
50
|
this.moved = { ...this.color, ...next };
|
|
43
51
|
this.owned = true;
|
|
44
52
|
this.requestValue(formatColor(this.moved, this.format ?? 'hex', this.alpha));
|
|
@@ -51,6 +59,9 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
|
|
|
51
59
|
}
|
|
52
60
|
};
|
|
53
61
|
this.handleFormat = () => {
|
|
62
|
+
if (this.readOnly) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
54
65
|
this.format = FORMATS[(FORMATS.indexOf(this.format ?? 'hex') + 1) % FORMATS.length] ?? 'hex';
|
|
55
66
|
if (this.value !== '') {
|
|
56
67
|
this.move({});
|
|
@@ -102,12 +113,26 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
|
|
|
102
113
|
get presets() {
|
|
103
114
|
return splitColors(this.swatches).filter((one) => parseColor(one) !== null);
|
|
104
115
|
}
|
|
116
|
+
requestValue(next) {
|
|
117
|
+
if (this.readOnly) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return super.requestValue(next);
|
|
121
|
+
}
|
|
105
122
|
firstUpdated(changed) {
|
|
106
123
|
super.firstUpdated(changed);
|
|
107
124
|
this.finishHydration();
|
|
108
125
|
}
|
|
109
126
|
sync() {
|
|
110
127
|
this.internals.setFormValue(this.value === '' ? null : this.value);
|
|
128
|
+
this.reportRequired();
|
|
129
|
+
}
|
|
130
|
+
reportRequired() {
|
|
131
|
+
if (this.required && this.value === '') {
|
|
132
|
+
this.internals.setValidity({ valueMissing: true }, 'Choose a color.', this.partNamed('grid') ?? undefined);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.internals.setValidity({});
|
|
111
136
|
}
|
|
112
137
|
updated(changed) {
|
|
113
138
|
super.updated(changed);
|
|
@@ -145,13 +170,24 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
|
|
|
145
170
|
}
|
|
146
171
|
takeArea(axis, event) {
|
|
147
172
|
event.stopPropagation();
|
|
148
|
-
const
|
|
149
|
-
this.
|
|
173
|
+
const control = event.target;
|
|
174
|
+
if (this.readOnly) {
|
|
175
|
+
this.putBack(control, this.color[axis]);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
this.move({ [axis]: Number(control.value) });
|
|
179
|
+
}
|
|
180
|
+
putBack(control, at) {
|
|
181
|
+
control.value = String(at);
|
|
150
182
|
}
|
|
151
183
|
takeChannel(channel, event) {
|
|
152
184
|
event.stopPropagation();
|
|
153
|
-
const
|
|
154
|
-
this.
|
|
185
|
+
const control = event.target;
|
|
186
|
+
if (this.readOnly) {
|
|
187
|
+
this.putBack(control, this.color[channel]);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
this.move({ [channel]: Number(control.value) });
|
|
155
191
|
}
|
|
156
192
|
willUpdate(changed) {
|
|
157
193
|
super.willUpdate(changed);
|
|
@@ -248,6 +284,7 @@ let HelixHeadlessColorPicker = class HelixHeadlessColorPicker extends MixinContr
|
|
|
248
284
|
spellcheck="false"
|
|
249
285
|
.value=${this.value}
|
|
250
286
|
?disabled=${this.isDisabled}
|
|
287
|
+
?readonly=${this.readOnly}
|
|
251
288
|
@input=${this.handleValueInput}
|
|
252
289
|
/>`}
|
|
253
290
|
${this.tools ? html `${this.renderTools()}` : nothing}
|
|
@@ -292,6 +329,12 @@ __decorate([
|
|
|
292
329
|
__decorate([
|
|
293
330
|
property({ attribute: 'no-value', type: Boolean })
|
|
294
331
|
], HelixHeadlessColorPicker.prototype, "noValue", void 0);
|
|
332
|
+
__decorate([
|
|
333
|
+
property({ attribute: 'readonly', reflect: true, type: Boolean })
|
|
334
|
+
], HelixHeadlessColorPicker.prototype, "readOnly", void 0);
|
|
335
|
+
__decorate([
|
|
336
|
+
property({ reflect: true, type: Boolean })
|
|
337
|
+
], HelixHeadlessColorPicker.prototype, "required", void 0);
|
|
295
338
|
__decorate([
|
|
296
339
|
property()
|
|
297
340
|
], HelixHeadlessColorPicker.prototype, "swatches", void 0);
|
|
@@ -29,6 +29,7 @@ declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion
|
|
|
29
29
|
* @event {Event} input - Announced once the value has moved.
|
|
30
30
|
*
|
|
31
31
|
* @csspart feedback - What is wrong with it.
|
|
32
|
+
* @csspart field - The row: the marks, and the score beside them.
|
|
32
33
|
* @csspart fill - The filled marks, clipped to the score.
|
|
33
34
|
* @csspart hint - Help under the marks, while nothing is wrong.
|
|
34
35
|
* @csspart label - The question, over the marks.
|
|
@@ -40,8 +41,8 @@ declare const HelixHeadlessRating_base: (new (...args: any[]) => import("@fusion
|
|
|
40
41
|
*
|
|
41
42
|
* @cssproperty --rating-full - How many marks are wholly filled.
|
|
42
43
|
* @cssproperty --rating-part - How much of the next mark is filled, 0 to 1.
|
|
43
|
-
* @cssproperty --rating-step -
|
|
44
|
-
* @cssproperty --rating-steps - How many steps
|
|
44
|
+
* @cssproperty --rating-step - Which step along the row a target is, counting from one, whatever `min` leaves open.
|
|
45
|
+
* @cssproperty --rating-steps - How many steps the whole row holds, which is `max` over `step`.
|
|
45
46
|
*
|
|
46
47
|
* @cssstate invalid - While there is feedback to show: the platform's verdict, or the consumer's `feedback`.
|
|
47
48
|
*/
|
|
@@ -58,6 +59,40 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
|
58
59
|
* different answers and a control that cannot express the first has to
|
|
59
60
|
* pretend the second. A survey that requires an answer says so with
|
|
60
61
|
* `required`, not by making one unreachable.
|
|
62
|
+
*
|
|
63
|
+
* **It is the floor of the scale, and every edge follows from that.**
|
|
64
|
+
*
|
|
65
|
+
* *Clearing* returns the row to it. An empty rating, a value nothing can
|
|
66
|
+
* parse, and a form reset with nothing declared are all the same situation,
|
|
67
|
+
* and all three draw `min` filled: at the default of zero that is the empty
|
|
68
|
+
* row this always drew, and at `min="2"` it is two marks, the way an empty
|
|
69
|
+
* `Slider` sits at its own minimum rather than at zero. The value is still
|
|
70
|
+
* `""` through all of it, so `required` still refuses it and `valueAsNumber`
|
|
71
|
+
* is still `NaN`: what the row shows is the bottom of the scale, not an
|
|
72
|
+
* answer somebody gave.
|
|
73
|
+
*
|
|
74
|
+
* *The steps* are the scores from `step` up to `max` that are not below it,
|
|
75
|
+
* so `min="2"` on five marks offers 2 to 5 and leaves the first two marks
|
|
76
|
+
* filled and unpressable. At zero nothing is dropped, which is why the
|
|
77
|
+
* default row is unchanged.
|
|
78
|
+
*
|
|
79
|
+
* *The keyboard* moves through those steps and no others. `wrap` is already
|
|
80
|
+
* false here, so arrowing down from the lowest one holds its ground rather
|
|
81
|
+
* than reaching a score this property forbids, and the tab stop an unrated
|
|
82
|
+
* rating carries sits on the lowest score offered rather than on the first
|
|
83
|
+
* mark.
|
|
84
|
+
*
|
|
85
|
+
* *A `min` between two steps* is a floor and not a step: `min="1.5"` with
|
|
86
|
+
* whole marks clamps the value at 1.5 and offers 2 upward, since 1.5 is not
|
|
87
|
+
* somewhere the row can be pressed. That is a real thing to ask for and is
|
|
88
|
+
* left to mean what it says.
|
|
89
|
+
*
|
|
90
|
+
* *A `min` outside the marks is refused rather than obeyed*, and says so
|
|
91
|
+
* once on the console. Below zero and anything that is not a number are read
|
|
92
|
+
* as zero, there being no mark to draw for a negative score; above `max` is
|
|
93
|
+
* read as `max`, which collapses the scale to its top score rather than
|
|
94
|
+
* leaving a rating with nothing to press. A property that silently accepts
|
|
95
|
+
* nonsense is the fault this pays off, so neither case is quietly ignored.
|
|
61
96
|
*/
|
|
62
97
|
min: number;
|
|
63
98
|
/**
|
|
@@ -120,9 +155,28 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
|
120
155
|
*/
|
|
121
156
|
private previewing;
|
|
122
157
|
protected readonly keys: KeyboardNavigationController;
|
|
158
|
+
/**
|
|
159
|
+
* The floor the row actually uses, which is `min` where `min` is one.
|
|
160
|
+
*
|
|
161
|
+
* Between zero and `max`, and zero for anything that is not a number, per
|
|
162
|
+
* the note on `min`. Derived on read rather than corrected into the property,
|
|
163
|
+
* so `rating.min` still reports what the consumer set and the warning below
|
|
164
|
+
* can tell the two apart.
|
|
165
|
+
*/
|
|
166
|
+
private get floor();
|
|
123
167
|
/** The score, as a number, clamped to what the marks can show. */
|
|
124
168
|
get score(): number;
|
|
125
|
-
/**
|
|
169
|
+
/**
|
|
170
|
+
* Every score the marks can show, which is `max / step` of them.
|
|
171
|
+
*
|
|
172
|
+
* The whole row rather than the part `min` leaves open, because this is what
|
|
173
|
+
* the stylesheet lays the targets out against: `--rating-steps` is the pitch
|
|
174
|
+
* and a step's own place in this list is where it sits along the row. Counted
|
|
175
|
+
* from the part a reader can press instead, a floor above zero would widen
|
|
176
|
+
* every target and slide the row left.
|
|
177
|
+
*/
|
|
178
|
+
private get positions();
|
|
179
|
+
/** Every score a reader can choose, which is the positions `min` leaves open. */
|
|
126
180
|
private get steps();
|
|
127
181
|
/**
|
|
128
182
|
* The options, as the shared controller wants them.
|
|
@@ -182,10 +236,12 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
|
182
236
|
* form holding an unrated required rating submits, `:valid` true and the
|
|
183
237
|
* entry present but empty. `reportRequired` is what makes the property real.
|
|
184
238
|
*
|
|
185
|
-
* **Empty is `value === ''` rather than a score
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* it. What `required` asks is
|
|
239
|
+
* **Empty is `value === ''` rather than a score at the floor**, and the two
|
|
240
|
+
* are not the same thing: an unanswered row draws `min`, per the note on that
|
|
241
|
+
* property, so a control that read its own picture would call every rating
|
|
242
|
+
* with `min="2"` answered the moment it rendered. What `required` asks is
|
|
243
|
+
* whether the reader answered at all, which only the value knows. A consumer
|
|
244
|
+
* who writes `value="0"` has answered, and is not refused.
|
|
189
245
|
*
|
|
190
246
|
* `Slider` is deliberately not given the same treatment: a native
|
|
191
247
|
* `<input type="range" required>` is always valid, because a range always
|
|
@@ -197,6 +253,8 @@ export declare class HelixHeadlessRating extends HelixHeadlessRating_base {
|
|
|
197
253
|
private readonly handleLeave;
|
|
198
254
|
connectedCallback(): void;
|
|
199
255
|
disconnectedCallback(): void;
|
|
256
|
+
/** Whether the console has already been told about a `min` off the scale. */
|
|
257
|
+
private warned;
|
|
200
258
|
protected updated(changed: PropertyValues): void;
|
|
201
259
|
protected willUpdate(changed: PropertyValues): void;
|
|
202
260
|
protected firstUpdated(changed: PropertyValues): void;
|