@fusion.dev/helix-headless 0.164.0 → 0.165.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.
@@ -49934,7 +49934,7 @@
49934
49934
  "text": "readonly string[] | undefined"
49935
49935
  },
49936
49936
  "privacy": "protected",
49937
- "description": "Each date, where `mode` holds several, sent one entry each.\n\nOne date that is text and no date, such as `August 5`, is sent as an empty\nentry, as a native date field sends a date it cannot read.",
49937
+ "description": "Each date, where `mode` holds several, sent one entry each.\n\nText that is no date, such as `August 5`, is sent as one empty entry, as\na native date field sends a date it cannot read, in every mode.",
49938
49938
  "readonly": true,
49939
49939
  "inheritedFrom": {
49940
49940
  "name": "MixinPickerField",
@@ -50514,6 +50514,81 @@
50514
50514
  "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
50515
50515
  }
50516
50516
  },
50517
+ {
50518
+ "kind": "method",
50519
+ "name": "edit",
50520
+ "privacy": "private",
50521
+ "return": {
50522
+ "type": {
50523
+ "text": "boolean"
50524
+ }
50525
+ },
50526
+ "parameters": [
50527
+ {
50528
+ "name": "element",
50529
+ "type": {
50530
+ "text": "HTMLElement"
50531
+ }
50532
+ },
50533
+ {
50534
+ "name": "key",
50535
+ "type": {
50536
+ "text": "string"
50537
+ }
50538
+ }
50539
+ ],
50540
+ "description": "Applies an editing key to the segment, the arrows, Backspace, a digit or\na letter, and says whether it edited anything.",
50541
+ "inheritedFrom": {
50542
+ "name": "MixinSegmentedField",
50543
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
50544
+ }
50545
+ },
50546
+ {
50547
+ "kind": "field",
50548
+ "name": "composing",
50549
+ "type": {
50550
+ "text": "[Node, string | null][]"
50551
+ },
50552
+ "privacy": "private",
50553
+ "default": "[]",
50554
+ "description": "What the segment's text was when a composition started to write into it.",
50555
+ "inheritedFrom": {
50556
+ "name": "MixinSegmentedField",
50557
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
50558
+ }
50559
+ },
50560
+ {
50561
+ "kind": "field",
50562
+ "name": "handleSegmentBeforeInput",
50563
+ "privacy": "private",
50564
+ "readonly": true,
50565
+ "description": "Text a touch keyboard writes into a segment, which arrives as input and\nnot as a key: an on-screen keyboard sends `Unidentified` for its keys,\nso a digit tapped on a phone is read here, as React Aria's segments read\nit. Every input is canceled, so the segment holds only what the field\ndraws in it.",
50566
+ "inheritedFrom": {
50567
+ "name": "MixinSegmentedField",
50568
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
50569
+ }
50570
+ },
50571
+ {
50572
+ "kind": "field",
50573
+ "name": "handleSegmentInput",
50574
+ "privacy": "private",
50575
+ "readonly": true,
50576
+ "inheritedFrom": {
50577
+ "name": "MixinSegmentedField",
50578
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
50579
+ }
50580
+ },
50581
+ {
50582
+ "kind": "field",
50583
+ "name": "collapseSelection",
50584
+ "privacy": "private",
50585
+ "readonly": true,
50586
+ "description": "Keeps the caret at the start of the segment with focus, where Chromium\nfires input for a typed key, and where Android's keyboard does not\ncompose over the segment's text. A selection already there, or outside\nthe segment, is left alone.",
50587
+ "inheritedFrom": {
50588
+ "name": "MixinSegmentedField",
50589
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
50590
+ }
50591
+ },
50517
50592
  {
50518
50593
  "kind": "field",
50519
50594
  "name": "handleSegmentKeydown",
@@ -72046,7 +72121,7 @@
72046
72121
  "type": {
72047
72122
  "text": "'long' | 'narrow' | 'short' | undefined"
72048
72123
  },
72049
- "description": "Shows how long ago the timestamp was, or how long until it, in words, in\nplace of the date: `long` (\"3 hours ago\"), `short` (\"3 hr. ago\") or\n`narrow` (\"3h ago\").\n\nThe reading refreshes as it goes stale, as `elapsed` does, and the whole\ndate is its title. `elapsed` wins where both are set.",
72124
+ "description": "Shows how long ago the timestamp was, or how long until it, in words, in\nplace of the date: `long` (\"3 hours ago\"), `short` (\"3 hr. ago\") or\n`narrow` (\"3h ago\").\n\nThe reading refreshes as it goes stale, as `elapsed` does, and the whole\ndate is its title. `elapsed` wins where both are set. Written with no\nvalue, as `elapsed` is, or with a style `Intl` does not know, it reads\n`long`.",
72050
72125
  "attribute": "relative"
72051
72126
  },
72052
72127
  {
@@ -72693,7 +72768,7 @@
72693
72768
  "type": {
72694
72769
  "text": "'long' | 'narrow' | 'short' | undefined"
72695
72770
  },
72696
- "description": "Shows how long ago the timestamp was, or how long until it, in words, in\nplace of the date: `long` (\"3 hours ago\"), `short` (\"3 hr. ago\") or\n`narrow` (\"3h ago\").\n\nThe reading refreshes as it goes stale, as `elapsed` does, and the whole\ndate is its title. `elapsed` wins where both are set.",
72771
+ "description": "Shows how long ago the timestamp was, or how long until it, in words, in\nplace of the date: `long` (\"3 hours ago\"), `short` (\"3 hr. ago\") or\n`narrow` (\"3h ago\").\n\nThe reading refreshes as it goes stale, as `elapsed` does, and the whole\ndate is its title. `elapsed` wins where both are set. Written with no\nvalue, as `elapsed` is, or with a style `Intl` does not know, it reads\n`long`.",
72697
72772
  "fieldName": "relative"
72698
72773
  },
72699
72774
  {
@@ -87220,6 +87295,23 @@
87220
87295
  "description": "The items, read from the host.\n\n**`knownChildren` and not `children`**, which is undefined on the server:\nspreading it threw the first time a lightbox was rendered there open,\nwhich is the first time anything asked it for its items on a server.",
87221
87296
  "readonly": true
87222
87297
  },
87298
+ {
87299
+ "kind": "field",
87300
+ "name": "handleSlotChange",
87301
+ "privacy": "private",
87302
+ "readonly": true,
87303
+ "description": "The set changed: render it again.\n\n`items` is read on each render and nothing else marks a render as due when\nan item arrives or leaves, so an item appended after the first render had\nno role description, no place in the set, and no part in the count until\nsome unrelated property changed."
87304
+ },
87305
+ {
87306
+ "kind": "field",
87307
+ "name": "itemWatch",
87308
+ "type": {
87309
+ "text": "MutationObserver | undefined"
87310
+ },
87311
+ "privacy": "private",
87312
+ "default": "undefined",
87313
+ "description": "Watches each item's `label` and `value`, which no slot reports.\n\n`value` decides which item `active` names, and `label` fills `{label}` in\n`status-label` and `slide-label`. A change to either left the old item\nshown, or the old words in the counter, until some unrelated property\nchanged. `Select` watches its options for the same reason.\n\nThe subtree, since an observer on the host sees no attribute on its\nchildren otherwise. Only changes on the items themselves count: a `<progress\nvalue>` inside an item, updated while a video plays, would otherwise render\nthe viewer again on each update.\n\nMade on connection, there being no `MutationObserver` on a server."
87314
+ },
87223
87315
  {
87224
87316
  "kind": "field",
87225
87317
  "name": "dialog",
@@ -87414,6 +87506,16 @@
87414
87506
  ],
87415
87507
  "description": "Home and End, which are an index rather than a step."
87416
87508
  },
87509
+ {
87510
+ "kind": "field",
87511
+ "name": "zoomedItem",
87512
+ "type": {
87513
+ "text": "HelixHeadlessLightboxItem | undefined"
87514
+ },
87515
+ "privacy": "private",
87516
+ "default": "undefined",
87517
+ "description": "The item shown at the last update, whose zoom a different item does not keep."
87518
+ },
87417
87519
  {
87418
87520
  "kind": "field",
87419
87521
  "name": "shown",
@@ -115159,7 +115261,7 @@
115159
115261
  "declarations": [
115160
115262
  {
115161
115263
  "kind": "class",
115162
- "description": "A separate family from `Input`'s `type=\"number\"`. It renders two buttons,\nbinds four keys `Input` does not, and handles clamping and stepping.\n\nThe field is `type=\"text\"` with `inputmode=\"decimal\"`. Tested in a real\nbrowser, `type=\"number\"` fails in three ways:\n- Typing `12e` gives a `.value` of `\"\"`, so the element cannot see what you\n typed. A `type=\"text\"` field keeps `\"12e\"`.\n- The mouse wheel over a focused field changes the value, for example from 5\n to 4, when you only meant to scroll the page.\n- `selectionStart` is `null`, so the caret cannot be managed.\n\n`inputmode=\"decimal\"` keeps the numeric keypad on phones.\n\n`format-options` shows the number with `Intl.NumberFormat` in `locale`, as a\ncurrency, a percent or a unit, while the field is not being edited. Focus\nshows the number itself, and a typed `$1,200` or `25%` is read back with the\nsame options. The value stays the plain number: `1200`, or `0.25` for 25%.\nThe locale's group separators are read in every field, so `1,234` is a\nnumber in `en-US`.\n\nThe field and its two buttons sit in a `role=\"group\"` named by the label,\nand the field carries `role-label`, \"number field\" in English, as its\n`aria-roledescription`, as React Aria's NumberField does. On iOS and iPadOS the field is a plain text\nfield, with no `role=\"spinbutton\"`, which VoiceOver reads as a slider you\ncannot type in, and no role description, so VoiceOver says the field is\nrequired. React Aria's NumberField does the same.\n\nValidity follows the platform's rules: `min`, `max`, and `step` are checked\nand reported through the host's own `setValidity`, under the platform's flag\nnames.\n\nStepping is separate from typing, so a number is not corrected while you type\nit. While you type, the form holds the number the text reads as, so a field\nshowing `$2,500.50` gives the form 2500.5, and text that is not a number\ngives it nothing, as a native number field does.\n\nHolding a stepper button down steps once, then again after 400 milliseconds,\nthen every 60 milliseconds until you let go, as React Aria's NumberField does.\n\n**Keyboard.** The field is one tab stop, and the stepper buttons are not in\nthe tab order.\n\n| Key | What it does |\n|---|---|\n| Up, Down | Steps the value up or down by `step`. |\n| Page Up, Page Down | Steps by `large-step` steps, ten by default. |\n| Home, End | Goes to `min` or `max`, where there is one. Without one, moves the caret. |\n| Enter | Commits the typed number and submits the form, as a native field does. |\n\nThe field has `role=\"spinbutton\"` with `aria-valuenow`, `aria-valuemin`,\n`aria-valuemax`, and the formatted text in `aria-valuetext`.",
115264
+ "description": "A separate family from `Input`'s `type=\"number\"`. It renders two buttons,\nbinds four keys `Input` does not, and handles clamping and stepping.\n\nThe field is `type=\"text\"` with an `inputmode` for a number. Tested in a real\nbrowser, `type=\"number\"` fails in three ways:\n- Typing `12e` gives a `.value` of `\"\"`, so the element cannot see what you\n typed. A `type=\"text\"` field keeps `\"12e\"`.\n- The mouse wheel over a focused field changes the value, for example from 5\n to 4, when you only meant to scroll the page.\n- `selectionStart` is `null`, so the caret cannot be managed.\n\n`inputmode` keeps a numeric keypad on phones, chosen as React Aria's\nNumberField chooses it: a keypad with a minus key where the number can be\nnegative, and one with a decimal separator where the format shows a\nfraction. An iPhone has no keypad with a minus key, so a field that can be\nnegative takes the full keyboard there.\n\n`format-options` shows the number with `Intl.NumberFormat` in `locale`, as a\ncurrency, a percent or a unit, while the field is not being edited. Focus\nshows the number itself, and a typed `$1,200` or `25%` is read back with the\nsame options. The value stays the plain number: `1200`, or `0.25` for 25%.\nThe locale's group separators are read in every field, so `1,234` is a\nnumber in `en-US`.\n\nThe field and its two buttons sit in a `role=\"group\"` named by the label,\nand the field carries `role-label`, \"number field\" in English, as its\n`aria-roledescription`, as React Aria's NumberField does. On iOS and iPadOS the field is a plain text\nfield, with no `role=\"spinbutton\"`, which VoiceOver reads as a slider you\ncannot type in, and no role description, so VoiceOver says the field is\nrequired. React Aria's NumberField does the same.\n\nValidity follows the platform's rules: `min`, `max`, and `step` are checked\nand reported through the host's own `setValidity`, under the platform's flag\nnames.\n\nStepping is separate from typing, so a number is not corrected while you type\nit. While you type, the form holds the number the text reads as, so a field\nshowing `$2,500.50` gives the form 2500.5, and text that is not a number\ngives it nothing, as a native number field does.\n\nHolding a stepper button down steps once, then again after 400 milliseconds,\nthen every 60 milliseconds until you let go, as React Aria's NumberField does.\n\n**Keyboard.** The field is one tab stop, and the stepper buttons are not in\nthe tab order.\n\n| Key | What it does |\n|---|---|\n| Up, Down | Steps the value up or down by `step`. |\n| Page Up, Page Down | Steps by `large-step` steps, ten by default. |\n| Home, End | Goes to `min` or `max`, where there is one. Without one, moves the caret. |\n| Enter | Commits the typed number and submits the form, as a native field does. |\n\nThe field has `role=\"spinbutton\"` with `aria-valuenow`, `aria-valuemin`,\n`aria-valuemax`, and the formatted text in `aria-valuetext`.",
115163
115265
  "name": "HelixHeadlessNumberInput",
115164
115266
  "cssParts": [
115165
115267
  {
@@ -115432,9 +115534,9 @@
115432
115534
  "kind": "field",
115433
115535
  "name": "step",
115434
115536
  "type": {
115435
- "text": "number | undefined"
115537
+ "text": "number | 'any' | undefined"
115436
115538
  },
115437
- "description": "How far one step moves. A value off the step grid, counted from `min`, is\ninvalid, as it is in a native number field.\n\nUnset, a step moves by one, or by one percent under a percent format, and\na typed number is rounded to the smallest amount `format-options` shows\nrather than to whole steps, as React Aria's NumberField does: a field\nshowing dollars keeps the cents typed into it. Without `format-options`\nthe grid is whole numbers, as in a native number field.",
115539
+ "description": "How far one step moves. A value off the step grid, counted from `min`, is\ninvalid, as it is in a native number field.\n\nUnset, a step moves by one, or by one percent under a percent format, and\na typed number is rounded to the smallest amount the format shows, as\nReact Aria's NumberField does: a field showing dollars keeps the cents\ntyped into it, and one with no `format-options` keeps three decimal\nplaces. `any` puts the number on no grid, as it does in a native number\nfield: a step moves by one, and any number in range is valid.",
115438
115540
  "attribute": "step"
115439
115541
  },
115440
115542
  {
@@ -115510,6 +115612,23 @@
115510
115612
  "readonly": true,
115511
115613
  "description": "Whether this is an iPhone or an iPad, read once on the client. A server\nhas no navigator and renders the spinbutton."
115512
115614
  },
115615
+ {
115616
+ "kind": "field",
115617
+ "name": "phone",
115618
+ "privacy": "private",
115619
+ "readonly": true,
115620
+ "description": "The phone the field is on, read once on the client, for the keypad it offers."
115621
+ },
115622
+ {
115623
+ "kind": "field",
115624
+ "name": "keypad",
115625
+ "type": {
115626
+ "text": "'decimal' | 'numeric' | 'text'"
115627
+ },
115628
+ "privacy": "private",
115629
+ "description": "The keypad a phone shows, as React Aria's NumberField chooses it.\n`numeric` on Android has a minus key and a decimal separator, and\n`decimal` has no minus key. On an iPhone neither has a minus key, so a\nnumber that can be negative takes the full keyboard. Measured before\nthis: `decimal` with `min=\"-10\"`, so a phone could not type the minus.",
115630
+ "readonly": true
115631
+ },
115513
115632
  {
115514
115633
  "kind": "field",
115515
115634
  "name": "control",
@@ -115538,6 +115657,16 @@
115538
115657
  "privacy": "private",
115539
115658
  "description": "The grain last read off the format, with the locale and options it was read for."
115540
115659
  },
115660
+ {
115661
+ "kind": "field",
115662
+ "name": "stepSize",
115663
+ "type": {
115664
+ "text": "number"
115665
+ },
115666
+ "privacy": "private",
115667
+ "description": "The step as a number, or zero where it is unset or `any`.",
115668
+ "readonly": true
115669
+ },
115541
115670
  {
115542
115671
  "kind": "field",
115543
115672
  "name": "stride",
@@ -115555,7 +115684,7 @@
115555
115684
  "text": "number"
115556
115685
  },
115557
115686
  "privacy": "private",
115558
- "description": "The grid a typed number is rounded to: `step` where it is set, and\notherwise the smallest amount the format shows, or whole numbers.",
115687
+ "description": "The grid a typed number is rounded to: `step` where it is set, nothing\nwhere it is `any`, and otherwise the smallest amount the format shows.\nMeasured before this: with no step and no format, `2,75` typed in German\nbecame 3 on blur.",
115559
115688
  "readonly": true
115560
115689
  },
115561
115690
  {
@@ -115717,6 +115846,13 @@
115717
115846
  "readonly": true,
115718
115847
  "description": "A stepper button pressed with a pointer steps at once, and again while it\nis held.\n\nCaptured, so letting go outside the button still ends the hold. A click\nwith no press before it, from a screen reader or a script, steps once in\n`handleStepperClick`."
115719
115848
  },
115849
+ {
115850
+ "kind": "field",
115851
+ "name": "handleStepperMouseDown",
115852
+ "privacy": "private",
115853
+ "readonly": true,
115854
+ "description": "Keeps a pressed stepper from taking focus from the field."
115855
+ },
115720
115856
  {
115721
115857
  "kind": "field",
115722
115858
  "name": "stopRepeat",
@@ -117364,9 +117500,9 @@
117364
117500
  {
117365
117501
  "name": "step",
117366
117502
  "type": {
117367
- "text": "number | undefined"
117503
+ "text": "number | 'any' | undefined"
117368
117504
  },
117369
- "description": "How far one step moves. A value off the step grid, counted from `min`, is\ninvalid, as it is in a native number field.\n\nUnset, a step moves by one, or by one percent under a percent format, and\na typed number is rounded to the smallest amount `format-options` shows\nrather than to whole steps, as React Aria's NumberField does: a field\nshowing dollars keeps the cents typed into it. Without `format-options`\nthe grid is whole numbers, as in a native number field.",
117505
+ "description": "How far one step moves. A value off the step grid, counted from `min`, is\ninvalid, as it is in a native number field.\n\nUnset, a step moves by one, or by one percent under a percent format, and\na typed number is rounded to the smallest amount the format shows, as\nReact Aria's NumberField does: a field showing dollars keeps the cents\ntyped into it, and one with no `format-options` keeps three decimal\nplaces. `any` puts the number on no grid, as it does in a native number\nfield: a step moves by one, and any number in range is valid.",
117370
117506
  "fieldName": "step"
117371
117507
  },
117372
117508
  {
@@ -117526,6 +117662,14 @@
117526
117662
  }
117527
117663
  ],
117528
117664
  "cssStates": [
117665
+ {
117666
+ "description": "The number is at `max`, so it cannot step up, as React Aria's NumberField says with `canIncrement`.",
117667
+ "name": "at-max"
117668
+ },
117669
+ {
117670
+ "description": "The number is at `min`, so it cannot step down.",
117671
+ "name": "at-min"
117672
+ },
117529
117673
  {
117530
117674
  "description": "The control has an error to show, from the browser's validation or from your `feedback`.",
117531
117675
  "name": "invalid"
@@ -120117,6 +120261,21 @@
120117
120261
  }
120118
120262
  ]
120119
120263
  },
120264
+ {
120265
+ "kind": "javascript-module",
120266
+ "path": "src/option/root/index.ts",
120267
+ "declarations": [],
120268
+ "exports": [
120269
+ {
120270
+ "kind": "js",
120271
+ "name": "*",
120272
+ "declaration": {
120273
+ "name": "*",
120274
+ "module": "src/option/root/option-root.js"
120275
+ }
120276
+ }
120277
+ ]
120278
+ },
120120
120279
  {
120121
120280
  "kind": "javascript-module",
120122
120281
  "path": "src/option/root/option-root.ts",
@@ -162129,6 +162288,21 @@
162129
162288
  }
162130
162289
  ]
162131
162290
  },
162291
+ {
162292
+ "kind": "javascript-module",
162293
+ "path": "src/tag/root/index.ts",
162294
+ "declarations": [],
162295
+ "exports": [
162296
+ {
162297
+ "kind": "js",
162298
+ "name": "*",
162299
+ "declaration": {
162300
+ "name": "*",
162301
+ "module": "src/tag/root/tag-root.js"
162302
+ }
162303
+ }
162304
+ ]
162305
+ },
162132
162306
  {
162133
162307
  "kind": "javascript-module",
162134
162308
  "path": "src/tag/root/tag-root.ts",
@@ -165945,7 +166119,7 @@
165945
166119
  "text": "readonly string[] | undefined"
165946
166120
  },
165947
166121
  "privacy": "protected",
165948
- "description": "Each time, where `mode` holds several, sent one entry each.\n\nOne time that is text and no time, such as `2:45 P`, is sent as an empty\nentry, as a native time field sends a time it cannot read.",
166122
+ "description": "Each time, where `mode` holds several, sent one entry each.\n\nText that is no time, such as `2:45 P`, is sent as one empty entry, as a\nnative time field sends a time it cannot read. Measured before this: a\nrange written `09:00/10:30` was invalid and submitted the text.",
165949
166123
  "readonly": true,
165950
166124
  "inheritedFrom": {
165951
166125
  "name": "MixinPickerField",
@@ -166454,6 +166628,81 @@
166454
166628
  "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
166455
166629
  }
166456
166630
  },
166631
+ {
166632
+ "kind": "method",
166633
+ "name": "edit",
166634
+ "privacy": "private",
166635
+ "return": {
166636
+ "type": {
166637
+ "text": "boolean"
166638
+ }
166639
+ },
166640
+ "parameters": [
166641
+ {
166642
+ "name": "element",
166643
+ "type": {
166644
+ "text": "HTMLElement"
166645
+ }
166646
+ },
166647
+ {
166648
+ "name": "key",
166649
+ "type": {
166650
+ "text": "string"
166651
+ }
166652
+ }
166653
+ ],
166654
+ "description": "Applies an editing key to the segment, the arrows, Backspace, a digit or\na letter, and says whether it edited anything.",
166655
+ "inheritedFrom": {
166656
+ "name": "MixinSegmentedField",
166657
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
166658
+ }
166659
+ },
166660
+ {
166661
+ "kind": "field",
166662
+ "name": "composing",
166663
+ "type": {
166664
+ "text": "[Node, string | null][]"
166665
+ },
166666
+ "privacy": "private",
166667
+ "default": "[]",
166668
+ "description": "What the segment's text was when a composition started to write into it.",
166669
+ "inheritedFrom": {
166670
+ "name": "MixinSegmentedField",
166671
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
166672
+ }
166673
+ },
166674
+ {
166675
+ "kind": "field",
166676
+ "name": "handleSegmentBeforeInput",
166677
+ "privacy": "private",
166678
+ "readonly": true,
166679
+ "description": "Text a touch keyboard writes into a segment, which arrives as input and\nnot as a key: an on-screen keyboard sends `Unidentified` for its keys,\nso a digit tapped on a phone is read here, as React Aria's segments read\nit. Every input is canceled, so the segment holds only what the field\ndraws in it.",
166680
+ "inheritedFrom": {
166681
+ "name": "MixinSegmentedField",
166682
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
166683
+ }
166684
+ },
166685
+ {
166686
+ "kind": "field",
166687
+ "name": "handleSegmentInput",
166688
+ "privacy": "private",
166689
+ "readonly": true,
166690
+ "inheritedFrom": {
166691
+ "name": "MixinSegmentedField",
166692
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
166693
+ }
166694
+ },
166695
+ {
166696
+ "kind": "field",
166697
+ "name": "collapseSelection",
166698
+ "privacy": "private",
166699
+ "readonly": true,
166700
+ "description": "Keeps the caret at the start of the segment with focus, where Chromium\nfires input for a typed key, and where Android's keyboard does not\ncompose over the segment's text. A selection already there, or outside\nthe segment, is left alone.",
166701
+ "inheritedFrom": {
166702
+ "name": "MixinSegmentedField",
166703
+ "module": "src/mixins/mixin-segmented-field/mixin-segmented-field.ts"
166704
+ }
166705
+ },
166457
166706
  {
166458
166707
  "kind": "field",
166459
166708
  "name": "handleSegmentKeydown",
@@ -193414,6 +193663,6 @@
193414
193663
  ],
193415
193664
  "helix": {
193416
193665
  "package": "@fusion.dev/helix-headless",
193417
- "version": "0.164.0"
193666
+ "version": "0.165.0"
193418
193667
  }
193419
193668
  }
@@ -1,7 +1,7 @@
1
1
  import { AriaForwardController, type DateCalendar, HelixFormElement, type MonthCalendar, type MonthSystem } from '@fusion.dev/helix-core';
2
2
  import { type PropertyValues, type TemplateResult } from 'lit';
3
3
  import '../../date-picker/index.js';
4
- import '../../tag/index.js';
4
+ import '../../tag/root/index.js';
5
5
  declare const HelixHeadlessDateInput_base: (new (...args: any[]) => import("@fusion.dev/helix-core").MixinSegmentedFieldInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinPickerEditingInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinPickerFieldInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerOpenInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinTokensInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinControllerValueInterface) & (new (...args: any[]) => import("@fusion.dev/helix-core").MixinFieldInterface) & typeof HelixFormElement;
6
6
  /**
7
7
  * @summary A date, typed or picked from a calendar.
@@ -474,8 +474,8 @@ export declare class HelixHeadlessDateInput extends HelixHeadlessDateInput_base
474
474
  /**
475
475
  * Each date, where `mode` holds several, sent one entry each.
476
476
  *
477
- * One date that is text and no date, such as `August 5`, is sent as an empty
478
- * entry, as a native date field sends a date it cannot read.
477
+ * Text that is no date, such as `August 5`, is sent as one empty entry, as
478
+ * a native date field sends a date it cannot read, in every mode.
479
479
  */
480
480
  protected get answers(): readonly string[] | undefined;
481
481
  /** What is wrong with the dates, which the text input cannot say. */
@@ -11,7 +11,7 @@ import { property, state } from 'lit/decorators.js';
11
11
  import { unsafeSVG } from 'lit/directives/unsafe-svg.js';
12
12
  import { html } from 'lit/static-html.js';
13
13
  import '../../date-picker/index.js';
14
- import '../../tag/index.js';
14
+ import '../../tag/root/index.js';
15
15
  const dates = (value) => value
16
16
  .replace(/\s+[–-]\s+/g, ',')
17
17
  .split(',')
@@ -70,9 +70,11 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinSegmented
70
70
  };
71
71
  this.handleTextCommit = (event) => {
72
72
  if (this.mode !== 'multiple') {
73
- const held = this.mode === 'range' && /\s[–-]\s/.test(this.value)
74
- ? this.value.split(/\s+[–-]\s+/).map((one) => one.trim())
75
- : dates(this.value);
73
+ const held = this.mode !== 'range'
74
+ ? [this.value.trim()].filter(Boolean)
75
+ : /\s[–-]\s/.test(this.value)
76
+ ? this.value.split(/\s+[–-]\s+/).map((one) => one.trim())
77
+ : dates(this.value);
76
78
  const read = held.map((one) => this.read(one));
77
79
  if (held.length > 0 && !held.every(isDateValue) && read.every(Boolean)) {
78
80
  this.requestValue(read.join(','));
@@ -220,7 +222,8 @@ let HelixHeadlessDateInput = class HelixHeadlessDateInput extends MixinSegmented
220
222
  }
221
223
  get answers() {
222
224
  if (this.mode !== undefined) {
223
- return dates(this.value);
225
+ const held = dates(this.value);
226
+ return held.every(isDateValue) ? held : [''];
224
227
  }
225
228
  const text = this.value.trim();
226
229
  return text === '' || isDateValue(text) ? undefined : [''];
@@ -200,7 +200,9 @@ export declare class HelixHeadlessFormatDate extends HelixElement {
200
200
  * `narrow` ("3h ago").
201
201
  *
202
202
  * The reading refreshes as it goes stale, as `elapsed` does, and the whole
203
- * date is its title. `elapsed` wins where both are set.
203
+ * date is its title. `elapsed` wins where both are set. Written with no
204
+ * value, as `elapsed` is, or with a style `Intl` does not know, it reads
205
+ * `long`.
204
206
  */
205
207
  relative?: 'long' | 'narrow' | 'short';
206
208
  /**
@@ -10,6 +10,7 @@ import { property } from 'lit/decorators.js';
10
10
  import { drawFields } from '../fields.js';
11
11
  import { formatOptions } from '../options.js';
12
12
  const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/;
13
+ const STYLES = ['long', 'narrow', 'short'];
13
14
  let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement {
14
15
  constructor() {
15
16
  super(...arguments);
@@ -53,7 +54,9 @@ let HelixHeadlessFormatDate = class HelixHeadlessFormatDate extends HelixElement
53
54
  ? elapsedTime(this.language)(moment, now)
54
55
  : relativeTime(this.language, {
55
56
  numeric: this.numeric ?? 'auto',
56
- style: this.relative ?? 'long',
57
+ style: STYLES.includes(this.relative)
58
+ ? this.relative
59
+ : 'long',
57
60
  })(moment, now);
58
61
  }
59
62
  connectedCallback() {
@@ -47,7 +47,9 @@ __decorate([
47
47
  property({ type: Boolean })
48
48
  ], HelixHeadlessLightboxItem.prototype, "current", void 0);
49
49
  __decorate([
50
- property()
50
+ property({
51
+ converter: { fromAttribute: (value) => value ?? '' },
52
+ })
51
53
  ], HelixHeadlessLightboxItem.prototype, "label", void 0);
52
54
  __decorate([
53
55
  property({ attribute: false })
@@ -258,6 +258,32 @@ export declare class HelixHeadlessLightbox extends HelixHeadlessLightbox_base {
258
258
  * which is the first time anything asked it for its items on a server.
259
259
  */
260
260
  private get items();
261
+ /**
262
+ * The set changed: render it again.
263
+ *
264
+ * `items` is read on each render and nothing else marks a render as due when
265
+ * an item arrives or leaves, so an item appended after the first render had
266
+ * no role description, no place in the set, and no part in the count until
267
+ * some unrelated property changed.
268
+ */
269
+ private readonly handleSlotChange;
270
+ /**
271
+ * Watches each item's `label` and `value`, which no slot reports.
272
+ *
273
+ * `value` decides which item `active` names, and `label` fills `{label}` in
274
+ * `status-label` and `slide-label`. A change to either left the old item
275
+ * shown, or the old words in the counter, until some unrelated property
276
+ * changed. `Select` watches its options for the same reason.
277
+ *
278
+ * The subtree, since an observer on the host sees no attribute on its
279
+ * children otherwise. Only changes on the items themselves count: a `<progress
280
+ * value>` inside an item, updated while a video plays, would otherwise render
281
+ * the viewer again on each update.
282
+ *
283
+ * Made on connection, there being no `MutationObserver` on a server.
284
+ */
285
+ private itemWatch;
286
+ connectedCallback(): void;
261
287
  /** The native dialog, or nothing where there is no DOM to hold one. */
262
288
  private get dialog();
263
289
  /** Opens the viewer, which makes the rest of the page inert. */
@@ -322,6 +348,8 @@ export declare class HelixHeadlessLightbox extends HelixHeadlessLightbox_base {
322
348
  private zoomOut;
323
349
  /** Home and End, which are an index rather than a step. */
324
350
  private toEnd;
351
+ /** The item shown at the last update, whose zoom a different item does not keep. */
352
+ private zoomedItem;
325
353
  /** The item on screen: the one `active` names, or the first where it names none. */
326
354
  private get shown();
327
355
  /**
@@ -92,6 +92,10 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
92
92
  '--toggle': () => this.toggleOpen(),
93
93
  },
94
94
  });
95
+ this.handleSlotChange = () => {
96
+ this.requestUpdate();
97
+ };
98
+ this.itemWatch = undefined;
95
99
  this.handleCancel = (event) => {
96
100
  event.preventDefault();
97
101
  this.requestOpen(false);
@@ -129,6 +133,7 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
129
133
  this.toEnd(this.items.length - 1);
130
134
  }
131
135
  };
136
+ this.zoomedItem = undefined;
132
137
  this.handleBackdrop = (event) => {
133
138
  if (this.dragged(event) || !this.onEmptyArea(event)) {
134
139
  return;
@@ -177,6 +182,16 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
177
182
  get items() {
178
183
  return this.knownChildren.filter((child) => child instanceof HelixHeadlessLightboxItem);
179
184
  }
185
+ connectedCallback() {
186
+ super.connectedCallback();
187
+ this.itemWatch = new MutationObserver((records) => {
188
+ if (records.some((record) => record.target instanceof HelixHeadlessLightboxItem &&
189
+ record.target.parentElement === this)) {
190
+ this.requestUpdate();
191
+ }
192
+ });
193
+ this.itemWatch.observe(this, { attributeFilter: ['label', 'value'], subtree: true });
194
+ }
180
195
  get dialog() {
181
196
  return this.renderRoot?.querySelector('dialog') ?? null;
182
197
  }
@@ -292,16 +307,20 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
292
307
  this.toggleState('fullscreen', this.filled);
293
308
  this.toggleState('idle', this.resting);
294
309
  this.toggleState('zoomable', this.maxZoom > 1);
295
- if (changed.has('active') || (changed.has('open') && !this.open)) {
310
+ const shown = this.shown;
311
+ if (shown !== this.zoomedItem || (changed.has('open') && !this.open)) {
296
312
  this.quietZoom = true;
297
313
  this.zoomer.reset();
298
314
  this.quietZoom = false;
299
315
  }
316
+ this.zoomedItem = shown;
300
317
  this.say(changed);
301
318
  }
302
319
  disconnectedCallback() {
303
320
  super.disconnectedCallback();
304
321
  unlockScroll(this);
322
+ this.itemWatch?.disconnect();
323
+ this.itemWatch = undefined;
305
324
  }
306
325
  updated(changed) {
307
326
  super.updated(changed);
@@ -395,7 +414,7 @@ let HelixHeadlessLightbox = class HelixHeadlessLightbox extends MixinControllerA
395
414
  >
396
415
  <slot name="header" part="header"></slot>
397
416
  <div part="viewport">
398
- <slot></slot>
417
+ <slot @slotchange=${this.handleSlotChange}></slot>
399
418
  </div>
400
419
  <slot name="footer" part="footer"></slot>
401
420
  ${this.controls ? this.renderControls() : nothing}