@fusion.dev/helix-core 0.52.1 → 0.53.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 +387 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/mixins/mixin-chart-source/mixin-chart-source.d.ts +22 -5
- package/dist/mixins/mixin-chart-source/mixin-chart-source.js +4 -4
- package/dist/mixins/mixin-collection/mixin-collection.js +1 -1
- package/dist/mixins/mixin-field/mixin-field.d.ts +7 -0
- package/dist/mixins/mixin-field/mixin-field.js +2 -1
- package/dist/mixins/mixin-selectable-item/mixin-selectable-item.d.ts +66 -0
- package/dist/mixins/mixin-selectable-item/mixin-selectable-item.js +44 -0
- package/dist/utils/mark-region/mark-region.d.ts +43 -0
- package/dist/utils/mark-region/mark-region.js +9 -0
- package/dist/utils/written-list/written-list.d.ts +23 -0
- package/dist/utils/written-list/written-list.js +1 -0
- package/package.json +4 -4
package/custom-elements.json
CHANGED
|
@@ -5235,6 +5235,22 @@
|
|
|
5235
5235
|
"module": "./mixins/mixin-chart-source/mixin-chart-source.js"
|
|
5236
5236
|
}
|
|
5237
5237
|
},
|
|
5238
|
+
{
|
|
5239
|
+
"kind": "js",
|
|
5240
|
+
"name": "PLOT_HEIGHT",
|
|
5241
|
+
"declaration": {
|
|
5242
|
+
"name": "PLOT_HEIGHT",
|
|
5243
|
+
"module": "./mixins/mixin-chart-source/mixin-chart-source.js"
|
|
5244
|
+
}
|
|
5245
|
+
},
|
|
5246
|
+
{
|
|
5247
|
+
"kind": "js",
|
|
5248
|
+
"name": "PLOT_WIDTH",
|
|
5249
|
+
"declaration": {
|
|
5250
|
+
"name": "PLOT_WIDTH",
|
|
5251
|
+
"module": "./mixins/mixin-chart-source/mixin-chart-source.js"
|
|
5252
|
+
}
|
|
5253
|
+
},
|
|
5238
5254
|
{
|
|
5239
5255
|
"kind": "js",
|
|
5240
5256
|
"name": "seriesIndex",
|
|
@@ -5395,6 +5411,22 @@
|
|
|
5395
5411
|
"module": "./mixins/mixin-picker-field/mixin-picker-field.js"
|
|
5396
5412
|
}
|
|
5397
5413
|
},
|
|
5414
|
+
{
|
|
5415
|
+
"kind": "js",
|
|
5416
|
+
"name": "MixinSelectableItem",
|
|
5417
|
+
"declaration": {
|
|
5418
|
+
"name": "MixinSelectableItem",
|
|
5419
|
+
"module": "./mixins/mixin-selectable-item/mixin-selectable-item.js"
|
|
5420
|
+
}
|
|
5421
|
+
},
|
|
5422
|
+
{
|
|
5423
|
+
"kind": "js",
|
|
5424
|
+
"name": "MixinSelectableItemInterface",
|
|
5425
|
+
"declaration": {
|
|
5426
|
+
"name": "MixinSelectableItemInterface",
|
|
5427
|
+
"module": "./mixins/mixin-selectable-item/mixin-selectable-item.js"
|
|
5428
|
+
}
|
|
5429
|
+
},
|
|
5398
5430
|
{
|
|
5399
5431
|
"kind": "js",
|
|
5400
5432
|
"name": "MixinTokens",
|
|
@@ -5611,6 +5643,22 @@
|
|
|
5611
5643
|
"module": "./utils/line-path/line-path.js"
|
|
5612
5644
|
}
|
|
5613
5645
|
},
|
|
5646
|
+
{
|
|
5647
|
+
"kind": "js",
|
|
5648
|
+
"name": "markRegion",
|
|
5649
|
+
"declaration": {
|
|
5650
|
+
"name": "markRegion",
|
|
5651
|
+
"module": "./utils/mark-region/mark-region.js"
|
|
5652
|
+
}
|
|
5653
|
+
},
|
|
5654
|
+
{
|
|
5655
|
+
"kind": "js",
|
|
5656
|
+
"name": "RegionOptions",
|
|
5657
|
+
"declaration": {
|
|
5658
|
+
"name": "RegionOptions",
|
|
5659
|
+
"module": "./utils/mark-region/mark-region.js"
|
|
5660
|
+
}
|
|
5661
|
+
},
|
|
5614
5662
|
{
|
|
5615
5663
|
"kind": "js",
|
|
5616
5664
|
"name": "onUnlessFalse",
|
|
@@ -5882,6 +5930,14 @@
|
|
|
5882
5930
|
"name": "valueAsTime",
|
|
5883
5931
|
"module": "./utils/value-as/value-as.js"
|
|
5884
5932
|
}
|
|
5933
|
+
},
|
|
5934
|
+
{
|
|
5935
|
+
"kind": "js",
|
|
5936
|
+
"name": "writtenList",
|
|
5937
|
+
"declaration": {
|
|
5938
|
+
"name": "writtenList",
|
|
5939
|
+
"module": "./utils/written-list/written-list.js"
|
|
5940
|
+
}
|
|
5885
5941
|
}
|
|
5886
5942
|
]
|
|
5887
5943
|
},
|
|
@@ -5916,6 +5972,24 @@
|
|
|
5916
5972
|
],
|
|
5917
5973
|
"description": "The palette slot for the nth series, counting from one and wrapping."
|
|
5918
5974
|
},
|
|
5975
|
+
{
|
|
5976
|
+
"kind": "variable",
|
|
5977
|
+
"name": "PLOT_WIDTH",
|
|
5978
|
+
"type": {
|
|
5979
|
+
"text": "number"
|
|
5980
|
+
},
|
|
5981
|
+
"default": "100",
|
|
5982
|
+
"description": "The drawing's own coordinates, which a `viewBox` maps onto whatever box CSS\ngives it.\n\nHere for the reason `PALETTE` is here, one paragraph up: six families drew\ninto the same square and declared it six times under three names, and one of\nthem wrote the same number as a literal on one axis and as its own constant\non the other, in one attribute. A round hundred so a `d` attribute is\nreadable in the inspector.\n\n**Two names for one number, because the axes are two facts.** `x2=${PLOT_WIDTH}`\nand `y2=${PLOT_HEIGHT}` say which edge they reach; one name used twice says\nnothing, and the day a chart is not square the call sites are already right.\n`Sparkline` is that day already: it is a strip rather than a plot, so it takes\nthis width and states its own height beside it."
|
|
5983
|
+
},
|
|
5984
|
+
{
|
|
5985
|
+
"kind": "variable",
|
|
5986
|
+
"name": "PLOT_HEIGHT",
|
|
5987
|
+
"type": {
|
|
5988
|
+
"text": "number"
|
|
5989
|
+
},
|
|
5990
|
+
"default": "100",
|
|
5991
|
+
"description": "The drawing's own coordinates. See `PLOT_WIDTH`."
|
|
5992
|
+
},
|
|
5919
5993
|
{
|
|
5920
5994
|
"kind": "function",
|
|
5921
5995
|
"name": "seriesNames",
|
|
@@ -5932,7 +6006,7 @@
|
|
|
5932
6006
|
}
|
|
5933
6007
|
}
|
|
5934
6008
|
],
|
|
5935
|
-
"description": "A list of series names, as the attributes that take one are written.\n\n**Here because five properties across two tiers read the same list and two of\nthem read it differently.** `BarChart.lines` and `secondary` split on\nwhitespace; `outlined`, `subtle` and `glass` on the styled tier split on\nwhitespace or a comma, under a sentence saying the first three are matched\n\"the way `lines` and `secondary` are\". So `lines=\"Gateway, Billing\"` looked\nexactly like `outlined=\"Gateway, Billing\"` and matched nothing, because\n`gateway,` is not a column heading: no column drawn as a line, no error, and\nnothing to read off the page that says why
|
|
6009
|
+
"description": "A list of series names, as the attributes that take one are written.\n\n**Here because five properties across two tiers read the same list and two of\nthem read it differently.** `BarChart.lines` and `secondary` split on\nwhitespace; `outlined`, `subtle` and `glass` on the styled tier split on\nwhitespace or a comma, under a sentence saying the first three are matched\n\"the way `lines` and `secondary` are\". So `lines=\"Gateway, Billing\"` looked\nexactly like `outlined=\"Gateway, Billing\"` and matched nothing, because\n`gateway,` is not a column heading: no column drawn as a line, no error, and\nnothing to read off the page that says why.\n\n`writtenList` is the split, and carries the argument for accepting a comma.\nWhat this adds is the lowercase, the headings being matched\ncase-insensitively."
|
|
5936
6010
|
},
|
|
5937
6011
|
{
|
|
5938
6012
|
"kind": "class",
|
|
@@ -6282,6 +6356,22 @@
|
|
|
6282
6356
|
"module": "src/mixins/mixin-chart-source/mixin-chart-source.ts"
|
|
6283
6357
|
}
|
|
6284
6358
|
},
|
|
6359
|
+
{
|
|
6360
|
+
"kind": "js",
|
|
6361
|
+
"name": "PLOT_WIDTH",
|
|
6362
|
+
"declaration": {
|
|
6363
|
+
"name": "PLOT_WIDTH",
|
|
6364
|
+
"module": "src/mixins/mixin-chart-source/mixin-chart-source.ts"
|
|
6365
|
+
}
|
|
6366
|
+
},
|
|
6367
|
+
{
|
|
6368
|
+
"kind": "js",
|
|
6369
|
+
"name": "PLOT_HEIGHT",
|
|
6370
|
+
"declaration": {
|
|
6371
|
+
"name": "PLOT_HEIGHT",
|
|
6372
|
+
"module": "src/mixins/mixin-chart-source/mixin-chart-source.ts"
|
|
6373
|
+
}
|
|
6374
|
+
},
|
|
6285
6375
|
{
|
|
6286
6376
|
"kind": "js",
|
|
6287
6377
|
"name": "seriesNames",
|
|
@@ -7574,6 +7664,15 @@
|
|
|
7574
7664
|
"description": "The public surface `MixinField` adds.\n\nDeclared separately because TypeScript cannot emit declarations for an\nanonymous class that has private members (TS4094). Casting the mixin's return\nto this interface keeps the internals private and the build working.",
|
|
7575
7665
|
"name": "MixinFieldInterface",
|
|
7576
7666
|
"members": [
|
|
7667
|
+
{
|
|
7668
|
+
"kind": "field",
|
|
7669
|
+
"name": "controlId",
|
|
7670
|
+
"type": {
|
|
7671
|
+
"text": "string"
|
|
7672
|
+
},
|
|
7673
|
+
"privacy": "protected",
|
|
7674
|
+
"description": "Id the field's label points at, written by the control this wraps.\n\nThe third fixed id and the only one this mixin does not render, the\ncontrol being the family's. See the note on the class member."
|
|
7675
|
+
},
|
|
7577
7676
|
{
|
|
7578
7677
|
"kind": "field",
|
|
7579
7678
|
"name": "hint",
|
|
@@ -7729,6 +7828,16 @@
|
|
|
7729
7828
|
"description": "Grafts a label, help text, and a validation message onto a control.\n\n**Over `HelixElement` rather than `HelixFormElement`, because not every\ncontrol that wants a label is form-associated.** A checkbox group is the\ncase: each box in it submits itself already, so the group deliberately\nreports no value of its own, and every form-related member of\n`ElementInternals` throws `NotSupportedError` on an element that is not\nform-associated. Measured, and the ARIA members are fine on the same\nelement, which is why the naming and describing work there and only the\nvalidity has to ask first.\n\nEvery form control wants the same three things around it and wants them in a\ndifferent arrangement: a label above an input, beside a checkbox, and over a\ngroup. So this owns the properties, the parts, and the wiring, and each\ncontrol places the nodes where its own geometry needs them. Same part names\neither way, so one stylesheet in the styled tier dresses all of them.\n\n**Not a wrapping `Field` component, and that is not a style preference.** A\nwrapper cannot name what it wraps. Its label would live in its own shadow\nroot and the control in another, and measured in Chrome 148: an\n`aria-labelledby` IDREF cannot see across, and\n`control.ariaLabelledByElements = [labelInTheWrapper]` reads back as zero\nelements, the reference dropped. The same assignment with a label in the\ncontrol's own tree is kept. That pattern works in React libraries because\nthey have no shadow boundary; bringing it here brings the ergonomics and none\nof the conditions that made it work.\n\n**A control whose label is its content renders its own.** A checkbox is named\nby the words beside it, inside the `<label>` that forwards the press, so it\nuses its default slot and nesting `renderLabel`'s `<label>` in there would be\ninvalid markup. `label` is that slot's fallback either way.\n\nWorth knowing, because it costs a label and gives no warning: **a\nwhitespace-only text node is assigned to the default slot and defeats its\nfallback.** Measured in Chrome 148, and a newline between the tags is enough,\nso `<helix-checkbox label=\"Accept\">` closed on the next line renders no label\nat all. A named slot does not have this problem, because `slot=\"label\"` is an\nattribute and a text node has none. It is the platform's behavior rather\nthan ours, and the same is already true of every slot fallback here.\n\n**The ids are fixed rather than generated.** IDREFs resolve within the tree\nthat holds them, so two controls on a page each carrying `helix-hint` in\ntheir own shadow root do not collide. That also removes the usual hydration\nhazard, since there is no generated value for a server and a client to\ndisagree about.\n\n**A group has to say it differently.** A control's `<input>` and its hint\nare both in the shadow root, so a plain `aria-describedby` resolves. A\ngroup's host is in the light DOM and its hint is not, so the IDREF cannot\nreach and `element.ariaDescribedByElements` drops the reference. Only\n`internals.ariaDescribedByElements` keeps it, which is what `describeHost`\nuses. Measured the same way, and the failure is silent either way: the\ndescription simply never reaches the accessibility tree.\n\n**The label, the hint and the feedback are documented on each component that\napplies this, rather than here.** Declaring them once on this mixin is the\nobvious fix and does not work: the analyzer reads `@csspart` off a custom\nelement class, so a class-level tag here reaches the manifest as nothing at\nall, on this JSDoc and on the inner class alike. Measured both ways, and the\ninner-class version is the dangerous one, since it satisfies the rule while\nevery API page stays exactly as wrong as before. Members are different and\ndo inherit, which is what the note about the inner class in the area rules\nis about. `:state(invalid)` is listed the same way, as a `@cssstate` on each\ncomponent, for the same reason.",
|
|
7730
7829
|
"name": "MixinField",
|
|
7731
7830
|
"members": [
|
|
7831
|
+
{
|
|
7832
|
+
"kind": "field",
|
|
7833
|
+
"name": "controlId",
|
|
7834
|
+
"type": {
|
|
7835
|
+
"text": "string"
|
|
7836
|
+
},
|
|
7837
|
+
"privacy": "protected",
|
|
7838
|
+
"default": "'control'",
|
|
7839
|
+
"description": "Id the field's label points at, written by the control this wraps.\n\n`renderLabel` emits the `for` and the family renders the `id`, so the\ntwo ends of one IDREF sat in two packages as a pair of literals with\nnothing holding them together: eleven templates wrote `id=\"control\"`,\ntwo wrote a second `for=\"control\"` of their own, and a family that\nspelled either differently got a `<label for>` resolving to nothing.\nThat failure is silent in the way the area rules describe for a\n`[part=]` naming a part nobody renders: no error, no warning, and a\nlabel that has stopped focusing its field.\n\nA member rather than a module constant, which is what the anchor\nargument for `reportRequired` already settled one level down: the name\nbelongs to the control the family renders, so the family has to be able\nto read it, and `HINT_ID` and `FEEDBACK_ID` stay private because this\nmixin renders both of those itself."
|
|
7840
|
+
},
|
|
7732
7841
|
{
|
|
7733
7842
|
"kind": "field",
|
|
7734
7843
|
"name": "feedback",
|
|
@@ -8456,6 +8565,196 @@
|
|
|
8456
8565
|
}
|
|
8457
8566
|
]
|
|
8458
8567
|
},
|
|
8568
|
+
{
|
|
8569
|
+
"kind": "javascript-module",
|
|
8570
|
+
"path": "src/mixins/mixin-selectable-item/mixin-selectable-item.ts",
|
|
8571
|
+
"declarations": [
|
|
8572
|
+
{
|
|
8573
|
+
"kind": "class",
|
|
8574
|
+
"description": "The public surface `MixinSelectableItem` adds.\n\nDeclared separately because TypeScript cannot emit declarations for an\nanonymous class that has private members (TS4094). Casting the mixin's return\nto this interface keeps the internals private and the build working.",
|
|
8575
|
+
"name": "MixinSelectableItemInterface",
|
|
8576
|
+
"members": [
|
|
8577
|
+
{
|
|
8578
|
+
"kind": "field",
|
|
8579
|
+
"name": "disabled",
|
|
8580
|
+
"type": {
|
|
8581
|
+
"text": "boolean"
|
|
8582
|
+
},
|
|
8583
|
+
"description": "Whether this one can be chosen."
|
|
8584
|
+
},
|
|
8585
|
+
{
|
|
8586
|
+
"kind": "method",
|
|
8587
|
+
"name": "focusItem",
|
|
8588
|
+
"return": {
|
|
8589
|
+
"type": {
|
|
8590
|
+
"text": "void"
|
|
8591
|
+
}
|
|
8592
|
+
},
|
|
8593
|
+
"description": "Moves focus to the control this renders, for the set's arrow keys."
|
|
8594
|
+
},
|
|
8595
|
+
{
|
|
8596
|
+
"kind": "field",
|
|
8597
|
+
"name": "itemPart",
|
|
8598
|
+
"type": {
|
|
8599
|
+
"text": "string"
|
|
8600
|
+
},
|
|
8601
|
+
"privacy": "protected",
|
|
8602
|
+
"description": "The part `focusItem` focuses, which each family names for itself.\n\nParameterised for the reason `MixinField`'s `reportRequired` takes its\nanchor as an argument: the control is the family's to render, so a literal\nhere would be a lookup for a part this file does not write."
|
|
8603
|
+
},
|
|
8604
|
+
{
|
|
8605
|
+
"kind": "method",
|
|
8606
|
+
"name": "select",
|
|
8607
|
+
"return": {
|
|
8608
|
+
"type": {
|
|
8609
|
+
"text": "boolean"
|
|
8610
|
+
}
|
|
8611
|
+
},
|
|
8612
|
+
"description": "Chooses this one and announces it, and reports whether the request stood.\n\n`MixinDismissible.dismiss` next door has the same shape and for the same\nreason: a mixin has no family, so the answer to a cancelable event it\ndispatches is read at the dispatch or nowhere. The set acting on the choice\noffers the second refusal on its own root."
|
|
8613
|
+
},
|
|
8614
|
+
{
|
|
8615
|
+
"kind": "field",
|
|
8616
|
+
"name": "selected",
|
|
8617
|
+
"type": {
|
|
8618
|
+
"text": "boolean"
|
|
8619
|
+
},
|
|
8620
|
+
"description": "Whether this is the current one. Written by the set."
|
|
8621
|
+
},
|
|
8622
|
+
{
|
|
8623
|
+
"kind": "field",
|
|
8624
|
+
"name": "value",
|
|
8625
|
+
"type": {
|
|
8626
|
+
"text": "string"
|
|
8627
|
+
},
|
|
8628
|
+
"description": "Identifies this one to the set, and is what a form submits."
|
|
8629
|
+
}
|
|
8630
|
+
],
|
|
8631
|
+
"helix": {}
|
|
8632
|
+
},
|
|
8633
|
+
{
|
|
8634
|
+
"kind": "mixin",
|
|
8635
|
+
"description": "The item half of a set: what is chosen, and what the arrow keys move over.\n\n**This is `KeyboardNavigationController.NavigableItem`, implemented.** That\ninterface has declared the contract since the controller was written and\nnothing implemented it, so every family that took the controller wrote the\nsame five members out again: Radio and Toggle were byte-identical down to the\nfourteen-line note on `willUpdate`, and Tab differed in one part name. A\ncontract with no implementation is a contract each caller reinvents, and the\nreinventions drift: the mirror is the half that must not, because a stylesheet\nselects on it.\n\n**The render stays with the family and only the part name comes here.** These\nelements are a radio, a switch and a tab, and what goes inside the control is\nthe whole of what makes them different. `itemPart` is the one thing the mixin\nhas to know, because focusing is the one thing it does to the render.\n\n**What is deliberately not here.** `defaultSelected` belongs to the families\nwhose selection a consumer declares in markup, and `focusable` to the ones\nwhose set has a tab stop to park while nothing is chosen. Neither is true of\nevery item in the library, and a mixin that granted them would publish a\nproperty on a reference page for a fact the family has no answer to. The\nitems whose current one is wherever focus happens to be (`Menu.Item`,\n`Drilldown.Item`, `SpeedDial.Item`) are the other kind again: their `selected`\nis a getter over `activeElement` rather than a property a parent writes, so\nthey satisfy the same interface by a different route and take nothing from\nhere.",
|
|
8636
|
+
"name": "MixinSelectableItem",
|
|
8637
|
+
"members": [
|
|
8638
|
+
{
|
|
8639
|
+
"kind": "field",
|
|
8640
|
+
"name": "disabled",
|
|
8641
|
+
"type": {
|
|
8642
|
+
"text": "boolean"
|
|
8643
|
+
},
|
|
8644
|
+
"default": "false",
|
|
8645
|
+
"description": "Whether this one can be chosen.",
|
|
8646
|
+
"attribute": "disabled",
|
|
8647
|
+
"reflects": true
|
|
8648
|
+
},
|
|
8649
|
+
{
|
|
8650
|
+
"kind": "field",
|
|
8651
|
+
"name": "selected",
|
|
8652
|
+
"type": {
|
|
8653
|
+
"text": "boolean"
|
|
8654
|
+
},
|
|
8655
|
+
"default": "false",
|
|
8656
|
+
"description": "Whether this is the current one.\n\nWritten by the set rather than by a consumer, which is why it takes no\ndefault from an attribute here: a family whose selection a consumer\ndeclares in markup carries `defaultSelected` of its own to say so.",
|
|
8657
|
+
"attribute": "selected"
|
|
8658
|
+
},
|
|
8659
|
+
{
|
|
8660
|
+
"kind": "field",
|
|
8661
|
+
"name": "value",
|
|
8662
|
+
"type": {
|
|
8663
|
+
"text": "string"
|
|
8664
|
+
},
|
|
8665
|
+
"default": "''",
|
|
8666
|
+
"description": "Identifies this one to the set, and is what a form submits.",
|
|
8667
|
+
"attribute": "value"
|
|
8668
|
+
},
|
|
8669
|
+
{
|
|
8670
|
+
"kind": "field",
|
|
8671
|
+
"name": "itemPart",
|
|
8672
|
+
"type": {
|
|
8673
|
+
"text": "string"
|
|
8674
|
+
},
|
|
8675
|
+
"privacy": "protected",
|
|
8676
|
+
"default": "'item'",
|
|
8677
|
+
"description": "The part `focusItem` focuses. See the interface note."
|
|
8678
|
+
},
|
|
8679
|
+
{
|
|
8680
|
+
"kind": "method",
|
|
8681
|
+
"name": "focusItem",
|
|
8682
|
+
"return": {
|
|
8683
|
+
"type": {
|
|
8684
|
+
"text": "void"
|
|
8685
|
+
}
|
|
8686
|
+
},
|
|
8687
|
+
"description": "Moves focus to the control this renders, for the set's arrow keys.\n\nThe set drives the keys and cannot reach the control itself, which is\ninside this shadow root, so the intent is a method and the internals stay\nthe item's."
|
|
8688
|
+
},
|
|
8689
|
+
{
|
|
8690
|
+
"kind": "method",
|
|
8691
|
+
"name": "select",
|
|
8692
|
+
"return": {
|
|
8693
|
+
"type": {
|
|
8694
|
+
"text": "boolean"
|
|
8695
|
+
}
|
|
8696
|
+
},
|
|
8697
|
+
"description": "Chooses this one and announces it, and reports whether it stood."
|
|
8698
|
+
}
|
|
8699
|
+
],
|
|
8700
|
+
"attributes": [
|
|
8701
|
+
{
|
|
8702
|
+
"name": "disabled",
|
|
8703
|
+
"type": {
|
|
8704
|
+
"text": "boolean"
|
|
8705
|
+
},
|
|
8706
|
+
"default": "false",
|
|
8707
|
+
"description": "Whether this one can be chosen.",
|
|
8708
|
+
"fieldName": "disabled"
|
|
8709
|
+
},
|
|
8710
|
+
{
|
|
8711
|
+
"name": "selected",
|
|
8712
|
+
"type": {
|
|
8713
|
+
"text": "boolean"
|
|
8714
|
+
},
|
|
8715
|
+
"default": "false",
|
|
8716
|
+
"description": "Whether this is the current one.\n\nWritten by the set rather than by a consumer, which is why it takes no\ndefault from an attribute here: a family whose selection a consumer\ndeclares in markup carries `defaultSelected` of its own to say so.",
|
|
8717
|
+
"fieldName": "selected"
|
|
8718
|
+
},
|
|
8719
|
+
{
|
|
8720
|
+
"name": "value",
|
|
8721
|
+
"type": {
|
|
8722
|
+
"text": "string"
|
|
8723
|
+
},
|
|
8724
|
+
"default": "''",
|
|
8725
|
+
"description": "Identifies this one to the set, and is what a form submits.",
|
|
8726
|
+
"fieldName": "value"
|
|
8727
|
+
}
|
|
8728
|
+
],
|
|
8729
|
+
"parameters": [
|
|
8730
|
+
{
|
|
8731
|
+
"name": "Base",
|
|
8732
|
+
"type": {
|
|
8733
|
+
"text": "T"
|
|
8734
|
+
}
|
|
8735
|
+
}
|
|
8736
|
+
]
|
|
8737
|
+
}
|
|
8738
|
+
],
|
|
8739
|
+
"exports": [
|
|
8740
|
+
{
|
|
8741
|
+
"kind": "js",
|
|
8742
|
+
"name": "MixinSelectableItemInterface",
|
|
8743
|
+
"declaration": {
|
|
8744
|
+
"name": "MixinSelectableItemInterface",
|
|
8745
|
+
"module": "src/mixins/mixin-selectable-item/mixin-selectable-item.ts"
|
|
8746
|
+
}
|
|
8747
|
+
},
|
|
8748
|
+
{
|
|
8749
|
+
"kind": "js",
|
|
8750
|
+
"name": "MixinSelectableItem",
|
|
8751
|
+
"declaration": {
|
|
8752
|
+
"name": "MixinSelectableItem",
|
|
8753
|
+
"module": "src/mixins/mixin-selectable-item/mixin-selectable-item.ts"
|
|
8754
|
+
}
|
|
8755
|
+
}
|
|
8756
|
+
]
|
|
8757
|
+
},
|
|
8459
8758
|
{
|
|
8460
8759
|
"kind": "javascript-module",
|
|
8461
8760
|
"path": "src/mixins/mixin-tokens/mixin-tokens.ts",
|
|
@@ -9505,6 +9804,59 @@
|
|
|
9505
9804
|
}
|
|
9506
9805
|
]
|
|
9507
9806
|
},
|
|
9807
|
+
{
|
|
9808
|
+
"kind": "javascript-module",
|
|
9809
|
+
"path": "src/utils/mark-region/mark-region.ts",
|
|
9810
|
+
"declarations": [
|
|
9811
|
+
{
|
|
9812
|
+
"kind": "function",
|
|
9813
|
+
"name": "markRegion",
|
|
9814
|
+
"return": {
|
|
9815
|
+
"type": {
|
|
9816
|
+
"text": "void"
|
|
9817
|
+
}
|
|
9818
|
+
},
|
|
9819
|
+
"parameters": [
|
|
9820
|
+
{
|
|
9821
|
+
"name": "root",
|
|
9822
|
+
"type": {
|
|
9823
|
+
"text": "ParentNode | null | undefined"
|
|
9824
|
+
}
|
|
9825
|
+
},
|
|
9826
|
+
{
|
|
9827
|
+
"name": "part",
|
|
9828
|
+
"type": {
|
|
9829
|
+
"text": "string"
|
|
9830
|
+
}
|
|
9831
|
+
},
|
|
9832
|
+
{
|
|
9833
|
+
"name": "slots",
|
|
9834
|
+
"type": {
|
|
9835
|
+
"text": "readonly string[]"
|
|
9836
|
+
}
|
|
9837
|
+
},
|
|
9838
|
+
{
|
|
9839
|
+
"name": "options",
|
|
9840
|
+
"default": "{}",
|
|
9841
|
+
"type": {
|
|
9842
|
+
"text": "RegionOptions"
|
|
9843
|
+
}
|
|
9844
|
+
}
|
|
9845
|
+
],
|
|
9846
|
+
"description": "Says on a rendered region whether anything is in it.\n\nNine families ask one question of a slot and write the same two attributes on\nthe box around it, and three of them carried this method byte for byte. What\ndiffers between them is the region's name, which slots count toward it, and\nwhether the component draws into the region itself, so those are the\narguments and nothing else is. `slotFilled` beside this is the half that\nanswers whether there is anything there, and carries the reason no selector\ncan.\n\n**The empty string names the default slot**, and it resolves to\n`slot:not([name])` rather than to a bare `slot`, which matches whichever slot\ncomes first in the shadow root and is the right answer only while a component\nhas one.\n\nOn the region inside the shadow root rather than on the host: an attribute\nwritten onto the host is a change to markup the consumer rendered, which\nReact reports on hydration and does not patch up."
|
|
9847
|
+
}
|
|
9848
|
+
],
|
|
9849
|
+
"exports": [
|
|
9850
|
+
{
|
|
9851
|
+
"kind": "js",
|
|
9852
|
+
"name": "markRegion",
|
|
9853
|
+
"declaration": {
|
|
9854
|
+
"name": "markRegion",
|
|
9855
|
+
"module": "src/utils/mark-region/mark-region.ts"
|
|
9856
|
+
}
|
|
9857
|
+
}
|
|
9858
|
+
]
|
|
9859
|
+
},
|
|
9508
9860
|
{
|
|
9509
9861
|
"kind": "javascript-module",
|
|
9510
9862
|
"path": "src/utils/on-unless-false/on-unless-false.ts",
|
|
@@ -10260,6 +10612,40 @@
|
|
|
10260
10612
|
}
|
|
10261
10613
|
}
|
|
10262
10614
|
]
|
|
10615
|
+
},
|
|
10616
|
+
{
|
|
10617
|
+
"kind": "javascript-module",
|
|
10618
|
+
"path": "src/utils/written-list/written-list.ts",
|
|
10619
|
+
"declarations": [
|
|
10620
|
+
{
|
|
10621
|
+
"kind": "function",
|
|
10622
|
+
"name": "writtenList",
|
|
10623
|
+
"return": {
|
|
10624
|
+
"type": {
|
|
10625
|
+
"text": "string[]"
|
|
10626
|
+
}
|
|
10627
|
+
},
|
|
10628
|
+
"parameters": [
|
|
10629
|
+
{
|
|
10630
|
+
"name": "source",
|
|
10631
|
+
"type": {
|
|
10632
|
+
"text": "string | undefined"
|
|
10633
|
+
}
|
|
10634
|
+
}
|
|
10635
|
+
],
|
|
10636
|
+
"description": "A list a consumer wrote into an attribute, split the way they write one.\n\n**Whitespace or commas, because a reader listing words puts commas between\nthem.** A split on whitespace alone turns `extra-controls=\"speed, pip\"` into\n`speed,` and `pip`, and `speed,` is not a control name: the control is\ndropped, nothing is logged, and the docblock on the property says\nunrecognized values are skipped, so the behavior looks like the documented\none. That is the undebuggable case `gridlines` names in its own docblock,\narrived at from the other direction, and it is why the widest spelling is the\none every consumer-written list takes.\n\n**Not for a value.** A payload is comma separated and nothing else, because a\nvalue may hold a space: splitting `value=\"New York,Paris\"` on whitespace\nwould submit a city that does not exist. Select, Listbox, Combobox and\nCheckbox Group each split their own value on a comma and trim, which is the\nother rule and not a lesser version of this one.\n\n**Nor for an IDREF list**, which is the platform's own format: `aria-*` and\n`for` take whitespace and only whitespace, and accepting a comma there would\nresolve an id nobody can write."
|
|
10637
|
+
}
|
|
10638
|
+
],
|
|
10639
|
+
"exports": [
|
|
10640
|
+
{
|
|
10641
|
+
"kind": "js",
|
|
10642
|
+
"name": "writtenList",
|
|
10643
|
+
"declaration": {
|
|
10644
|
+
"name": "writtenList",
|
|
10645
|
+
"module": "src/utils/written-list/written-list.ts"
|
|
10646
|
+
}
|
|
10647
|
+
}
|
|
10648
|
+
]
|
|
10263
10649
|
}
|
|
10264
10650
|
]
|
|
10265
10651
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export { eventsForTag, registerElementEvents } from './events/element-events.js'
|
|
|
17
17
|
export { type CaretDetail, type ChangeDetail, type CompleteDetail, type ConsoleDetail, type CopyDetail, type CreateDetail, type DismissDetail, type FacetDetail, type FilterDetail, HelixActivateEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCaretEvent, HelixCompleteEvent, HelixConsoleEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixFacetEvent, HelixFilterEvent, HelixHistoryEvent, HelixNavigateEvent, HelixNextEvent, HelixPreviousEvent, HelixReadEvent, HelixReorderEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixTourAskEvent, type NavigateDetail, type OpenDetail, type ReadDetail, type ResizeDetail, type ScrolledDetail, type SelectDetail, type SendDetail, type ShortcutDetail, type SkipDetail, type SortDetail, type ToggleDetail, } from './events/events.js';
|
|
18
18
|
export { HelixElement, whenHydrated } from './helix-element/helix-element.js';
|
|
19
19
|
export { HelixFormElement } from './helix-form-element/helix-form-element.js';
|
|
20
|
-
export { MixinChartSource, type MixinChartSourceInterface, PALETTE, seriesIndex, seriesNames, } from './mixins/mixin-chart-source/mixin-chart-source.js';
|
|
20
|
+
export { MixinChartSource, type MixinChartSourceInterface, PALETTE, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, seriesNames, } from './mixins/mixin-chart-source/mixin-chart-source.js';
|
|
21
21
|
export { type CollectionElement, MixinCollection, } from './mixins/mixin-collection/mixin-collection.js';
|
|
22
22
|
export { MixinControllerActive, type MixinControllerActiveInterface, } from './mixins/mixin-controller-active/mixin-controller-active.js';
|
|
23
23
|
export { MixinControllerChecked, type MixinControllerCheckedInterface, } from './mixins/mixin-controller-checked/mixin-controller-checked.js';
|
|
@@ -27,6 +27,7 @@ export { type DismissibleElement, MixinDismissible, } from './mixins/mixin-dismi
|
|
|
27
27
|
export { MixinField, type MixinFieldInterface } from './mixins/mixin-field/mixin-field.js';
|
|
28
28
|
export { MixinPickerEditing, type MixinPickerEditingInterface, } from './mixins/mixin-picker-editing/mixin-picker-editing.js';
|
|
29
29
|
export { MixinPickerField, type MixinPickerFieldInterface, } from './mixins/mixin-picker-field/mixin-picker-field.js';
|
|
30
|
+
export { MixinSelectableItem, type MixinSelectableItemInterface, } from './mixins/mixin-selectable-item/mixin-selectable-item.js';
|
|
30
31
|
export { MixinTokens, type MixinTokensInterface } from './mixins/mixin-tokens/mixin-tokens.js';
|
|
31
32
|
export { anchorElement } from './utils/anchor-element/anchor-element.js';
|
|
32
33
|
export { capturePointer } from './utils/capture-pointer/capture-pointer.js';
|
|
@@ -42,6 +43,7 @@ export { type HostAria, hostAria } from './utils/host-aria/host-aria.js';
|
|
|
42
43
|
export { type DisableableItem, forgetDisabled, inheritDisabled, } from './utils/inherit-disabled/inherit-disabled.js';
|
|
43
44
|
export { inlineStep } from './utils/inline-step/inline-step.js';
|
|
44
45
|
export { type Curve, linePath, type Point } from './utils/line-path/line-path.js';
|
|
46
|
+
export { markRegion, type RegionOptions } from './utils/mark-region/mark-region.js';
|
|
45
47
|
export { onUnlessFalse } from './utils/on-unless-false/on-unless-false.js';
|
|
46
48
|
export { type Row, type RowCell, readRows, readSeries, type Series, type SeriesPoint, } from './utils/read-series/read-series.js';
|
|
47
49
|
export { type Relative, relativeTime, } from './utils/relative-time/relative-time.js';
|
|
@@ -56,3 +58,4 @@ export { tellDisclosure } from './utils/tell-disclosure/tell-disclosure.js';
|
|
|
56
58
|
export { subscribe } from './utils/ticker/ticker.js';
|
|
57
59
|
export { type HelixStatusTone, TONE_MARKS, type ToneMark, toneMark, } from './utils/tone-marks/tone-marks.js';
|
|
58
60
|
export { dateAsValue, numberAsValue, timeAsValue, valueAsDate, valueAsNumber, valueAsTime, } from './utils/value-as/value-as.js';
|
|
61
|
+
export { writtenList } from './utils/written-list/written-list.js';
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ export { eventsForTag, registerElementEvents } from './events/element-events.js'
|
|
|
17
17
|
export { HelixActivateEvent, HelixBeforeActivateEvent, HelixBeforeChangeEvent, HelixBeforeCloseEvent, HelixBeforeCollapseEvent, HelixBeforeEditEvent, HelixBeforeOpenEvent, HelixBeforePanelResizeEvent, HelixBeforePinEvent, HelixBeforeResizeEvent, HelixBeforeSplitEvent, HelixBeforeToggleEvent, HelixCaretEvent, HelixCompleteEvent, HelixConsoleEvent, HelixCopyEvent, HelixCreateEvent, HelixDismissEvent, HelixFacetEvent, HelixFilterEvent, HelixHistoryEvent, HelixNavigateEvent, HelixNextEvent, HelixPreviousEvent, HelixReadEvent, HelixReorderEvent, HelixResizeEvent, HelixSampleEndEvent, HelixSampleStartEvent, HelixScrolledEvent, HelixSelectEvent, HelixSendEvent, HelixShortcutEvent, HelixSortEvent, HelixTourAskEvent, } from './events/events.js';
|
|
18
18
|
export { HelixElement, whenHydrated } from './helix-element/helix-element.js';
|
|
19
19
|
export { HelixFormElement } from './helix-form-element/helix-form-element.js';
|
|
20
|
-
export { MixinChartSource, PALETTE, seriesIndex, seriesNames, } from './mixins/mixin-chart-source/mixin-chart-source.js';
|
|
20
|
+
export { MixinChartSource, PALETTE, PLOT_HEIGHT, PLOT_WIDTH, seriesIndex, seriesNames, } from './mixins/mixin-chart-source/mixin-chart-source.js';
|
|
21
21
|
export { MixinCollection, } from './mixins/mixin-collection/mixin-collection.js';
|
|
22
22
|
export { MixinControllerActive, } from './mixins/mixin-controller-active/mixin-controller-active.js';
|
|
23
23
|
export { MixinControllerChecked, } from './mixins/mixin-controller-checked/mixin-controller-checked.js';
|
|
@@ -27,6 +27,7 @@ export { MixinDismissible, } from './mixins/mixin-dismissible/mixin-dismissible.
|
|
|
27
27
|
export { MixinField } from './mixins/mixin-field/mixin-field.js';
|
|
28
28
|
export { MixinPickerEditing, } from './mixins/mixin-picker-editing/mixin-picker-editing.js';
|
|
29
29
|
export { MixinPickerField, } from './mixins/mixin-picker-field/mixin-picker-field.js';
|
|
30
|
+
export { MixinSelectableItem, } from './mixins/mixin-selectable-item/mixin-selectable-item.js';
|
|
30
31
|
export { MixinTokens } from './mixins/mixin-tokens/mixin-tokens.js';
|
|
31
32
|
export { anchorElement } from './utils/anchor-element/anchor-element.js';
|
|
32
33
|
export { capturePointer } from './utils/capture-pointer/capture-pointer.js';
|
|
@@ -42,6 +43,7 @@ export { hostAria } from './utils/host-aria/host-aria.js';
|
|
|
42
43
|
export { forgetDisabled, inheritDisabled, } from './utils/inherit-disabled/inherit-disabled.js';
|
|
43
44
|
export { inlineStep } from './utils/inline-step/inline-step.js';
|
|
44
45
|
export { linePath } from './utils/line-path/line-path.js';
|
|
46
|
+
export { markRegion } from './utils/mark-region/mark-region.js';
|
|
45
47
|
export { onUnlessFalse } from './utils/on-unless-false/on-unless-false.js';
|
|
46
48
|
export { readRows, readSeries, } from './utils/read-series/read-series.js';
|
|
47
49
|
export { relativeTime, } from './utils/relative-time/relative-time.js';
|
|
@@ -56,3 +58,4 @@ export { tellDisclosure } from './utils/tell-disclosure/tell-disclosure.js';
|
|
|
56
58
|
export { subscribe } from './utils/ticker/ticker.js';
|
|
57
59
|
export { TONE_MARKS, toneMark, } from './utils/tone-marks/tone-marks.js';
|
|
58
60
|
export { dateAsValue, numberAsValue, timeAsValue, valueAsDate, valueAsNumber, valueAsTime, } from './utils/value-as/value-as.js';
|
|
61
|
+
export { writtenList } from './utils/written-list/written-list.js';
|
|
@@ -13,6 +13,25 @@ type Constructor<T> = new (...args: any[]) => T;
|
|
|
13
13
|
export declare const PALETTE = 24;
|
|
14
14
|
/** The palette slot for the nth series, counting from one and wrapping. */
|
|
15
15
|
export declare const seriesIndex: (depth: number) => number;
|
|
16
|
+
/**
|
|
17
|
+
* The drawing's own coordinates, which a `viewBox` maps onto whatever box CSS
|
|
18
|
+
* gives it.
|
|
19
|
+
*
|
|
20
|
+
* Here for the reason `PALETTE` is here, one paragraph up: six families drew
|
|
21
|
+
* into the same square and declared it six times under three names, and one of
|
|
22
|
+
* them wrote the same number as a literal on one axis and as its own constant
|
|
23
|
+
* on the other, in one attribute. A round hundred so a `d` attribute is
|
|
24
|
+
* readable in the inspector.
|
|
25
|
+
*
|
|
26
|
+
* **Two names for one number, because the axes are two facts.** `x2=${PLOT_WIDTH}`
|
|
27
|
+
* and `y2=${PLOT_HEIGHT}` say which edge they reach; one name used twice says
|
|
28
|
+
* nothing, and the day a chart is not square the call sites are already right.
|
|
29
|
+
* `Sparkline` is that day already: it is a strip rather than a plot, so it takes
|
|
30
|
+
* this width and states its own height beside it.
|
|
31
|
+
*/
|
|
32
|
+
export declare const PLOT_WIDTH = 100;
|
|
33
|
+
/** The drawing's own coordinates. See `PLOT_WIDTH`. */
|
|
34
|
+
export declare const PLOT_HEIGHT = 100;
|
|
16
35
|
/**
|
|
17
36
|
* A list of series names, as the attributes that take one are written.
|
|
18
37
|
*
|
|
@@ -23,12 +42,10 @@ export declare const seriesIndex: (depth: number) => number;
|
|
|
23
42
|
* "the way `lines` and `secondary` are". So `lines="Gateway, Billing"` looked
|
|
24
43
|
* exactly like `outlined="Gateway, Billing"` and matched nothing, because
|
|
25
44
|
* `gateway,` is not a column heading: no column drawn as a line, no error, and
|
|
26
|
-
* nothing to read off the page that says why.
|
|
27
|
-
* `gridlines` names in its own docblock, arrived at from the other direction.
|
|
45
|
+
* nothing to read off the page that says why.
|
|
28
46
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* shipped. Lowercased and trimmed, since the headings are matched
|
|
47
|
+
* `writtenList` is the split, and carries the argument for accepting a comma.
|
|
48
|
+
* What this adds is the lowercase, the headings being matched
|
|
32
49
|
* case-insensitively.
|
|
33
50
|
*/
|
|
34
51
|
export declare const seriesNames: (list: string | undefined) => string[];
|
|
@@ -7,12 +7,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { property } from 'lit/decorators.js';
|
|
8
8
|
import { ChartPointerController } from '../../controllers/chart-pointer-controller/chart-pointer-controller.js';
|
|
9
9
|
import { SourceController } from '../../controllers/source-controller/source-controller.js';
|
|
10
|
+
import { writtenList } from '../../utils/written-list/written-list.js';
|
|
10
11
|
export const PALETTE = 24;
|
|
11
12
|
export const seriesIndex = (depth) => (depth % PALETTE) + 1;
|
|
12
|
-
export const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
.filter(Boolean);
|
|
13
|
+
export const PLOT_WIDTH = 100;
|
|
14
|
+
export const PLOT_HEIGHT = 100;
|
|
15
|
+
export const seriesNames = (list) => writtenList(list).map((name) => name.toLowerCase());
|
|
16
16
|
export const MixinChartSource = (Base) => {
|
|
17
17
|
class ChartSourceElement extends Base {
|
|
18
18
|
constructor() {
|
|
@@ -9,6 +9,13 @@ type Constructor<T> = new (...args: any[]) => T;
|
|
|
9
9
|
* to this interface keeps the internals private and the build working.
|
|
10
10
|
*/
|
|
11
11
|
export declare class MixinFieldInterface {
|
|
12
|
+
/**
|
|
13
|
+
* Id the field's label points at, written by the control this wraps.
|
|
14
|
+
*
|
|
15
|
+
* The third fixed id and the only one this mixin does not render, the
|
|
16
|
+
* control being the family's. See the note on the class member.
|
|
17
|
+
*/
|
|
18
|
+
protected controlId: string;
|
|
12
19
|
/**
|
|
13
20
|
* Help under the control, shown while there is nothing wrong.
|
|
14
21
|
*
|
|
@@ -13,6 +13,7 @@ export const MixinField = (Base) => {
|
|
|
13
13
|
class FieldElement extends Base {
|
|
14
14
|
constructor() {
|
|
15
15
|
super(...arguments);
|
|
16
|
+
this.controlId = 'control';
|
|
16
17
|
this.feedback = '';
|
|
17
18
|
this.hint = '';
|
|
18
19
|
this.label = '';
|
|
@@ -52,7 +53,7 @@ export const MixinField = (Base) => {
|
|
|
52
53
|
if (this.label === '' && !hidden) {
|
|
53
54
|
return nothing;
|
|
54
55
|
}
|
|
55
|
-
return html `<label part="label" for
|
|
56
|
+
return html `<label part="label" for=${this.controlId} ?data-hidden=${hidden !== null}
|
|
56
57
|
><slot name="label">${this.label || hidden}</slot></label
|
|
57
58
|
>`;
|
|
58
59
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { HelixElement } from '../../helix-element/helix-element.js';
|
|
2
|
+
type Constructor<T> = new (...args: any[]) => T;
|
|
3
|
+
/**
|
|
4
|
+
* The public surface `MixinSelectableItem` adds.
|
|
5
|
+
*
|
|
6
|
+
* Declared separately because TypeScript cannot emit declarations for an
|
|
7
|
+
* anonymous class that has private members (TS4094). Casting the mixin's return
|
|
8
|
+
* to this interface keeps the internals private and the build working.
|
|
9
|
+
*/
|
|
10
|
+
export declare class MixinSelectableItemInterface {
|
|
11
|
+
/** Whether this one can be chosen. */
|
|
12
|
+
disabled: boolean;
|
|
13
|
+
/** Moves focus to the control this renders, for the set's arrow keys. */
|
|
14
|
+
focusItem(): void;
|
|
15
|
+
/**
|
|
16
|
+
* The part `focusItem` focuses, which each family names for itself.
|
|
17
|
+
*
|
|
18
|
+
* Parameterised for the reason `MixinField`'s `reportRequired` takes its
|
|
19
|
+
* anchor as an argument: the control is the family's to render, so a literal
|
|
20
|
+
* here would be a lookup for a part this file does not write.
|
|
21
|
+
*/
|
|
22
|
+
protected itemPart: string;
|
|
23
|
+
/**
|
|
24
|
+
* Chooses this one and announces it, and reports whether the request stood.
|
|
25
|
+
*
|
|
26
|
+
* `MixinDismissible.dismiss` next door has the same shape and for the same
|
|
27
|
+
* reason: a mixin has no family, so the answer to a cancelable event it
|
|
28
|
+
* dispatches is read at the dispatch or nowhere. The set acting on the choice
|
|
29
|
+
* offers the second refusal on its own root.
|
|
30
|
+
*/
|
|
31
|
+
select(): boolean;
|
|
32
|
+
/** Whether this is the current one. Written by the set. */
|
|
33
|
+
selected: boolean;
|
|
34
|
+
/** Identifies this one to the set, and is what a form submits. */
|
|
35
|
+
value: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The item half of a set: what is chosen, and what the arrow keys move over.
|
|
39
|
+
*
|
|
40
|
+
* **This is `KeyboardNavigationController.NavigableItem`, implemented.** That
|
|
41
|
+
* interface has declared the contract since the controller was written and
|
|
42
|
+
* nothing implemented it, so every family that took the controller wrote the
|
|
43
|
+
* same five members out again: Radio and Toggle were byte-identical down to the
|
|
44
|
+
* fourteen-line note on `willUpdate`, and Tab differed in one part name. A
|
|
45
|
+
* contract with no implementation is a contract each caller reinvents, and the
|
|
46
|
+
* reinventions drift: the mirror is the half that must not, because a stylesheet
|
|
47
|
+
* selects on it.
|
|
48
|
+
*
|
|
49
|
+
* **The render stays with the family and only the part name comes here.** These
|
|
50
|
+
* elements are a radio, a switch and a tab, and what goes inside the control is
|
|
51
|
+
* the whole of what makes them different. `itemPart` is the one thing the mixin
|
|
52
|
+
* has to know, because focusing is the one thing it does to the render.
|
|
53
|
+
*
|
|
54
|
+
* **What is deliberately not here.** `defaultSelected` belongs to the families
|
|
55
|
+
* whose selection a consumer declares in markup, and `focusable` to the ones
|
|
56
|
+
* whose set has a tab stop to park while nothing is chosen. Neither is true of
|
|
57
|
+
* every item in the library, and a mixin that granted them would publish a
|
|
58
|
+
* property on a reference page for a fact the family has no answer to. The
|
|
59
|
+
* items whose current one is wherever focus happens to be (`Menu.Item`,
|
|
60
|
+
* `Drilldown.Item`, `SpeedDial.Item`) are the other kind again: their `selected`
|
|
61
|
+
* is a getter over `activeElement` rather than a property a parent writes, so
|
|
62
|
+
* they satisfy the same interface by a different route and take nothing from
|
|
63
|
+
* here.
|
|
64
|
+
*/
|
|
65
|
+
export declare const MixinSelectableItem: <T extends Constructor<HelixElement>>(Base: T) => Constructor<MixinSelectableItemInterface> & T;
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { property } from 'lit/decorators.js';
|
|
8
|
+
import { HelixSelectEvent } from '../../events/events.js';
|
|
9
|
+
export const MixinSelectableItem = (Base) => {
|
|
10
|
+
class SelectableItem extends Base {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this.disabled = false;
|
|
14
|
+
this.selected = false;
|
|
15
|
+
this.value = '';
|
|
16
|
+
this.itemPart = 'item';
|
|
17
|
+
}
|
|
18
|
+
focusItem() {
|
|
19
|
+
this.partNamed(this.itemPart)?.focus();
|
|
20
|
+
}
|
|
21
|
+
select() {
|
|
22
|
+
if (this.disabled) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const event = new HelixSelectEvent({ value: this.value });
|
|
26
|
+
this.dispatchEvent(event);
|
|
27
|
+
return !event.defaultPrevented;
|
|
28
|
+
}
|
|
29
|
+
willUpdate(changed) {
|
|
30
|
+
super.willUpdate(changed);
|
|
31
|
+
this.toggleState('selected', this.selected);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
__decorate([
|
|
35
|
+
property({ reflect: true, type: Boolean })
|
|
36
|
+
], SelectableItem.prototype, "disabled", void 0);
|
|
37
|
+
__decorate([
|
|
38
|
+
property({ type: Boolean })
|
|
39
|
+
], SelectableItem.prototype, "selected", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
property()
|
|
42
|
+
], SelectableItem.prototype, "value", void 0);
|
|
43
|
+
return SelectableItem;
|
|
44
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** What a region may hold besides what a consumer slotted. */
|
|
2
|
+
export interface RegionOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Whether an empty region leaves the box tree as well as being marked.
|
|
5
|
+
*
|
|
6
|
+
* True everywhere but one place, and that exception is why this is an option
|
|
7
|
+
* rather than the behavior. A region a component paints into while it is
|
|
8
|
+
* empty has to keep its box: `Chat.Message` draws its typing indicator into a
|
|
9
|
+
* content region whose emptiness is exactly what says to draw it, so hiding
|
|
10
|
+
* the region would take the indicator with it.
|
|
11
|
+
*/
|
|
12
|
+
hide?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* A selector for something the component itself renders into the region.
|
|
15
|
+
*
|
|
16
|
+
* A region holding only what the component drew is not empty. Data Table's
|
|
17
|
+
* footer holds its own pagination and Notifications' header its own mark-all
|
|
18
|
+
* control, and both would otherwise be hidden out from under the thing they
|
|
19
|
+
* were rendered to carry.
|
|
20
|
+
*/
|
|
21
|
+
occupied?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Says on a rendered region whether anything is in it.
|
|
25
|
+
*
|
|
26
|
+
* Nine families ask one question of a slot and write the same two attributes on
|
|
27
|
+
* the box around it, and three of them carried this method byte for byte. What
|
|
28
|
+
* differs between them is the region's name, which slots count toward it, and
|
|
29
|
+
* whether the component draws into the region itself, so those are the
|
|
30
|
+
* arguments and nothing else is. `slotFilled` beside this is the half that
|
|
31
|
+
* answers whether there is anything there, and carries the reason no selector
|
|
32
|
+
* can.
|
|
33
|
+
*
|
|
34
|
+
* **The empty string names the default slot**, and it resolves to
|
|
35
|
+
* `slot:not([name])` rather than to a bare `slot`, which matches whichever slot
|
|
36
|
+
* comes first in the shadow root and is the right answer only while a component
|
|
37
|
+
* has one.
|
|
38
|
+
*
|
|
39
|
+
* On the region inside the shadow root rather than on the host: an attribute
|
|
40
|
+
* written onto the host is a change to markup the consumer rendered, which
|
|
41
|
+
* React reports on hydration and does not patch up.
|
|
42
|
+
*/
|
|
43
|
+
export declare const markRegion: (root: ParentNode | null | undefined, part: string, slots: readonly string[], options?: RegionOptions) => void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { slotFilled } from '../slot-filled/slot-filled.js';
|
|
2
|
+
export const markRegion = (root, part, slots, options = {}) => {
|
|
3
|
+
const region = root?.querySelector(`[part="${part}"]`);
|
|
4
|
+
const filled = slots.some((name) => slotFilled(root?.querySelector(name === '' ? 'slot:not([name])' : `slot[name="${name}"]`))) || Boolean(options.occupied && root?.querySelector(options.occupied));
|
|
5
|
+
region?.toggleAttribute('data-empty', !filled);
|
|
6
|
+
if (options.hide !== false) {
|
|
7
|
+
region?.toggleAttribute('hidden', !filled);
|
|
8
|
+
}
|
|
9
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A list a consumer wrote into an attribute, split the way they write one.
|
|
3
|
+
*
|
|
4
|
+
* **Whitespace or commas, because a reader listing words puts commas between
|
|
5
|
+
* them.** A split on whitespace alone turns `extra-controls="speed, pip"` into
|
|
6
|
+
* `speed,` and `pip`, and `speed,` is not a control name: the control is
|
|
7
|
+
* dropped, nothing is logged, and the docblock on the property says
|
|
8
|
+
* unrecognized values are skipped, so the behavior looks like the documented
|
|
9
|
+
* one. That is the undebuggable case `gridlines` names in its own docblock,
|
|
10
|
+
* arrived at from the other direction, and it is why the widest spelling is the
|
|
11
|
+
* one every consumer-written list takes.
|
|
12
|
+
*
|
|
13
|
+
* **Not for a value.** A payload is comma separated and nothing else, because a
|
|
14
|
+
* value may hold a space: splitting `value="New York,Paris"` on whitespace
|
|
15
|
+
* would submit a city that does not exist. Select, Listbox, Combobox and
|
|
16
|
+
* Checkbox Group each split their own value on a comma and trim, which is the
|
|
17
|
+
* other rule and not a lesser version of this one.
|
|
18
|
+
*
|
|
19
|
+
* **Nor for an IDREF list**, which is the platform's own format: `aria-*` and
|
|
20
|
+
* `for` take whitespace and only whitespace, and accepting a comma there would
|
|
21
|
+
* resolve an id nobody can write.
|
|
22
|
+
*/
|
|
23
|
+
export declare const writtenList: (source: string | undefined) => string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const writtenList = (source) => (source ?? '').split(/[\s,]+/).filter((one) => one !== '');
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-core",
|
|
3
3
|
"description": "Helix element primitives: base classes, mixins, decorators, utilities.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.53.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@floating-ui/dom": "^1.8.0",
|
|
37
|
-
"@fusion.dev/helix-icons": "0.
|
|
37
|
+
"@fusion.dev/helix-icons": "0.53.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@custom-elements-manifest/analyzer": "^0.11.0",
|
|
41
|
-
"@fusion.dev/helix-cem": "0.
|
|
42
|
-
"@fusion.dev/helix-testing": "0.
|
|
41
|
+
"@fusion.dev/helix-cem": "0.53.0",
|
|
42
|
+
"@fusion.dev/helix-testing": "0.53.0",
|
|
43
43
|
"lit": "^3.2.1"
|
|
44
44
|
},
|
|
45
45
|
"homepage": "https://fusion.dev",
|