@fusion.dev/helix-headless 0.101.0 → 0.103.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.
@@ -46674,6 +46674,14 @@
46674
46674
  "module": "src/loader/index.js"
46675
46675
  }
46676
46676
  },
46677
+ {
46678
+ "kind": "js",
46679
+ "name": "*",
46680
+ "declaration": {
46681
+ "name": "*",
46682
+ "module": "src/map/index.js"
46683
+ }
46684
+ },
46677
46685
  {
46678
46686
  "kind": "js",
46679
46687
  "name": "*",
@@ -55414,6 +55422,812 @@
55414
55422
  }
55415
55423
  ]
55416
55424
  },
55425
+ {
55426
+ "kind": "javascript-module",
55427
+ "path": "src/map/index.ts",
55428
+ "declarations": [],
55429
+ "exports": [
55430
+ {
55431
+ "kind": "js",
55432
+ "name": "HelixHeadlessMap",
55433
+ "declaration": {
55434
+ "name": "HelixHeadlessMap",
55435
+ "module": "./root/map-root.js"
55436
+ }
55437
+ }
55438
+ ]
55439
+ },
55440
+ {
55441
+ "kind": "javascript-module",
55442
+ "path": "src/map/root/map-root.ts",
55443
+ "declarations": [
55444
+ {
55445
+ "kind": "class",
55446
+ "description": "**Helix draws no map.** There are no tiles here, no projection and no\nnetwork, and there should not be: a tile renderer is a library, and what a\ndesign system can add to MapLibre or Leaflet is the frame. The consumer slots\ntheir map and this owns the box, the name, the controls and the way out,\nwhich is the shape `VideoPlaylist` uses for a player it never renders.\n\n**The accessibility argument is the reason this exists**, and it was measured\nrather than assumed: a map embedded the ordinary way is a canvas with no role\nand no name, and it has *no node at all* in the accessibility tree. A reader\nusing a screen reader does not walk past it so much as never meet it. A named\nregion with controls in it is the whole of the difference.\n\n**The controls are buttons, and that is a deliberate choice against arrow\nkeys.** Arrows work here too, but what a screen reader does with them is not\nours to decide: macOS passes them through, Windows readers hold them for\ntheir own reading mode unless a page takes `role=\"application\"`, which costs\nthe reader their normal way of reading everything else in the frame. A button\nis findable and operable in every screen reader on every platform without\nthat bargain, so panning and zooming are buttons first and keys second.\n\n**Nothing here moves the map.** Both controls ask, through `helix-map-pan`\nand `helix-map-zoom`, and the consumer answers against whatever they slotted.\nA frame that moved the map would have to know whose map it was.",
55447
+ "name": "HelixHeadlessMap",
55448
+ "cssParts": [
55449
+ {
55450
+ "description": "The group the pan and zoom buttons sit in.",
55451
+ "name": "controls"
55452
+ },
55453
+ {
55454
+ "description": "The button that fills the screen.",
55455
+ "name": "fullscreen"
55456
+ },
55457
+ {
55458
+ "description": "The button that moves the map down.",
55459
+ "name": "pan-down"
55460
+ },
55461
+ {
55462
+ "description": "The button that moves the map the way the text ends, which is right on an English page.",
55463
+ "name": "pan-end"
55464
+ },
55465
+ {
55466
+ "description": "The button that moves the map the way the text starts, which is left on an English page.",
55467
+ "name": "pan-start"
55468
+ },
55469
+ {
55470
+ "description": "The button that moves the map up.",
55471
+ "name": "pan-up"
55472
+ },
55473
+ {
55474
+ "description": "The named region the map is slotted into.",
55475
+ "name": "region"
55476
+ },
55477
+ {
55478
+ "description": "The box the map is drawn in.",
55479
+ "name": "viewport"
55480
+ },
55481
+ {
55482
+ "description": "The button that zooms in.",
55483
+ "name": "zoom-in"
55484
+ },
55485
+ {
55486
+ "description": "The button that zooms out.",
55487
+ "name": "zoom-out"
55488
+ }
55489
+ ],
55490
+ "slots": [
55491
+ {
55492
+ "description": "The map, which is the consumer's own.",
55493
+ "name": ""
55494
+ },
55495
+ {
55496
+ "description": "Whoever the tiles belong to, which most licenses require you to say.",
55497
+ "name": "attribution"
55498
+ },
55499
+ {
55500
+ "description": "Chrome below the map, such as a legend or a scale.",
55501
+ "name": "footer"
55502
+ },
55503
+ {
55504
+ "description": "Chrome above the map, such as a title or a search field.",
55505
+ "name": "header"
55506
+ }
55507
+ ],
55508
+ "members": [
55509
+ {
55510
+ "kind": "field",
55511
+ "name": "controls",
55512
+ "type": {
55513
+ "text": "string | undefined"
55514
+ },
55515
+ "description": "Which of the controls this frame draws, as a list of what to keep.\n\n**A list rather than a switch, because the overlap is not symmetric.**\nEvery map library draws zoom controls and none of them draws pan buttons:\nMapLibre's navigation control is zoom and a compass, Leaflet's is zoom,\nGoogle's is zoom. So a consumer slotting one of those has our zoom twice\nover and our pan pad not at all, and a single switch would make them choose\nbetween a duplicate and nothing.\n\n`none` draws none of them, which is the right answer where the slotted map\nalready has controls a reader can find: what this family argues for is that\n*a* findable control exists, never that it is ours. The methods stay public\neither way, so a consumer drawing their own chrome can still drive the\nframe.\n\nAbsent is all three, which is this library's rule that a resting value is an\nattribute's absence, and it is what the stylesheet asks about: the layout\nrules are written against `[controls]:not([controls~=\"zoom\"])` rather than\nthe bare negation, or a frame that named no list at all would be laid out as\nthough it had dropped everything.",
55516
+ "attribute": "controls",
55517
+ "reflects": true
55518
+ },
55519
+ {
55520
+ "kind": "field",
55521
+ "name": "controlsPlacement",
55522
+ "type": {
55523
+ "text": "'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | undefined"
55524
+ },
55525
+ "description": "Which corner the controls sit in.\n\n**Configurable because there is no safe default**, and this is a collision\nrather than a taste: MapLibre puts its own controls at the top end, Leaflet\nand OpenLayers at the top start, Google's zoom at the bottom end. Whichever\ncorner this took would land on somebody's, which is why every one of those\nlibraries made it a setting too.\n\nLogical corners rather than left and right, so a right-to-left page moves\nthem without a consumer writing a second rule.\n\nAbsent is the top end, which is this library's rule that a resting value is\nan attribute's absence: a default that reflected would write an attribute\nonto every host that no server sent and nobody asked for.",
55526
+ "attribute": "controls-placement",
55527
+ "reflects": true
55528
+ },
55529
+ {
55530
+ "kind": "field",
55531
+ "name": "fullscreenLabel",
55532
+ "type": {
55533
+ "text": "string"
55534
+ },
55535
+ "default": "'Fill the screen'",
55536
+ "description": "What the control that fills the screen is called.",
55537
+ "attribute": "fullscreen-label"
55538
+ },
55539
+ {
55540
+ "kind": "field",
55541
+ "name": "idleDelay",
55542
+ "type": {
55543
+ "text": "number"
55544
+ },
55545
+ "default": "0",
55546
+ "description": "How long the reader may be still before the chrome hides, in milliseconds.\n\nZero keeps it up, which is the default: a map's controls are how a keyboard\nreader operates it, and chrome that hides itself by default would be this\ncomponent undoing its own argument. Set it for a display map nobody drives.",
55547
+ "attribute": "idle-delay"
55548
+ },
55549
+ {
55550
+ "kind": "field",
55551
+ "name": "label",
55552
+ "type": {
55553
+ "text": "string"
55554
+ },
55555
+ "default": "''",
55556
+ "description": "Accessible name for the map, which is the one thing a consumer must write.\n\nThere is no sensible default. \"Map\" names the widget rather than the place,\nand a reader meeting three of them on a page learns nothing from hearing the\nsame word three times.",
55557
+ "attribute": "label"
55558
+ },
55559
+ {
55560
+ "kind": "field",
55561
+ "name": "panLabel",
55562
+ "type": {
55563
+ "text": "string"
55564
+ },
55565
+ "default": "'Pan {way}'",
55566
+ "description": "What the controls are called, for a page not in English.",
55567
+ "attribute": "pan-label"
55568
+ },
55569
+ {
55570
+ "kind": "field",
55571
+ "name": "panStep",
55572
+ "type": {
55573
+ "text": "number"
55574
+ },
55575
+ "default": "0.25",
55576
+ "description": "How far one press moves the map, as a fraction of what is on screen.\n\nA fraction rather than a distance, because this frame does not know the\nscale of what is inside it: a quarter of the viewport is the same gesture at\nstreet level and at country level, and a consumer who wants metres can\nmultiply by their own.",
55577
+ "attribute": "pan-step"
55578
+ },
55579
+ {
55580
+ "kind": "field",
55581
+ "name": "zoomInLabel",
55582
+ "type": {
55583
+ "text": "string"
55584
+ },
55585
+ "default": "'Zoom in'",
55586
+ "description": "What the zoom controls are called.",
55587
+ "attribute": "zoom-in-label"
55588
+ },
55589
+ {
55590
+ "kind": "field",
55591
+ "name": "zoomOutLabel",
55592
+ "type": {
55593
+ "text": "string"
55594
+ },
55595
+ "default": "'Zoom out'",
55596
+ "description": "What the zoom control that goes the other way is called.",
55597
+ "attribute": "zoom-out-label"
55598
+ },
55599
+ {
55600
+ "kind": "field",
55601
+ "name": "resting",
55602
+ "type": {
55603
+ "text": "boolean"
55604
+ },
55605
+ "privacy": "private",
55606
+ "default": "false",
55607
+ "description": "Whether the reader has been still long enough to hide the chrome."
55608
+ },
55609
+ {
55610
+ "kind": "field",
55611
+ "name": "filled",
55612
+ "type": {
55613
+ "text": "boolean"
55614
+ },
55615
+ "privacy": "private",
55616
+ "default": "false",
55617
+ "description": "Whether the frame is filling the screen."
55618
+ },
55619
+ {
55620
+ "kind": "field",
55621
+ "name": "fullscreen",
55622
+ "privacy": "private",
55623
+ "readonly": true,
55624
+ "default": "new FullscreenController(this, (full) => { this.filled = full })"
55625
+ },
55626
+ {
55627
+ "kind": "field",
55628
+ "name": "idle",
55629
+ "privacy": "private",
55630
+ "readonly": true,
55631
+ "default": "new IdleController( this, () => this.idleDelay, (resting) => { this.resting = resting }, )"
55632
+ },
55633
+ {
55634
+ "kind": "method",
55635
+ "name": "draws",
55636
+ "privacy": "private",
55637
+ "return": {
55638
+ "type": {
55639
+ "text": "boolean"
55640
+ }
55641
+ },
55642
+ "parameters": [
55643
+ {
55644
+ "name": "group",
55645
+ "type": {
55646
+ "text": "'pan' | 'zoom' | 'fullscreen'"
55647
+ }
55648
+ }
55649
+ ],
55650
+ "description": "Whether a named group of controls is one this frame draws."
55651
+ },
55652
+ {
55653
+ "kind": "method",
55654
+ "name": "toggleFullscreen",
55655
+ "return": {
55656
+ "type": {
55657
+ "text": "void"
55658
+ }
55659
+ },
55660
+ "description": "Fills the screen with the frame, or comes back.",
55661
+ "type": {
55662
+ "text": "toggleFullscreen() => void"
55663
+ }
55664
+ },
55665
+ {
55666
+ "kind": "method",
55667
+ "name": "pan",
55668
+ "return": {
55669
+ "type": {
55670
+ "text": "void"
55671
+ }
55672
+ },
55673
+ "parameters": [
55674
+ {
55675
+ "name": "to",
55676
+ "type": {
55677
+ "text": "Way"
55678
+ }
55679
+ }
55680
+ ],
55681
+ "description": "Asks for the map to move, which the consumer answers.",
55682
+ "type": {
55683
+ "text": "pan(to: Way) => void"
55684
+ }
55685
+ },
55686
+ {
55687
+ "kind": "method",
55688
+ "name": "zoom",
55689
+ "return": {
55690
+ "type": {
55691
+ "text": "void"
55692
+ }
55693
+ },
55694
+ "parameters": [
55695
+ {
55696
+ "name": "by",
55697
+ "type": {
55698
+ "text": "number"
55699
+ }
55700
+ }
55701
+ ],
55702
+ "description": "Asks for the map to zoom, `1` in and `-1` out.",
55703
+ "type": {
55704
+ "text": "zoom(by: number) => void"
55705
+ }
55706
+ },
55707
+ {
55708
+ "kind": "field",
55709
+ "name": "handleKeydown",
55710
+ "privacy": "private",
55711
+ "readonly": true,
55712
+ "description": "The arrow keys, which are the second way rather than the only one.\n\n`inlineStep` rather than a test against `ArrowLeft`, so the reader on a\nright-to-left page gets `end` from the key that points the way their text\nruns, which is what the pan buttons say too."
55713
+ },
55714
+ {
55715
+ "kind": "method",
55716
+ "name": "named",
55717
+ "privacy": "private",
55718
+ "return": {
55719
+ "type": {
55720
+ "text": "string"
55721
+ }
55722
+ },
55723
+ "parameters": [
55724
+ {
55725
+ "name": "way",
55726
+ "type": {
55727
+ "text": "Way"
55728
+ }
55729
+ }
55730
+ ],
55731
+ "description": "What one pan button is called, with the way it goes filled in.\n\nLeft and right rather than start and end, because the label is read aloud\nand a reader knows which way left is. The event keeps the reading-order\nname, which is the one a right-to-left page needs."
55732
+ },
55733
+ {
55734
+ "kind": "method",
55735
+ "name": "renderControls",
55736
+ "privacy": "private",
55737
+ "return": {
55738
+ "type": {
55739
+ "text": "TemplateResult | typeof nothing"
55740
+ }
55741
+ },
55742
+ "description": "The controls, or nothing where a consumer kept none of them.\n\n**Written out rather than generated**, because a part name behind an\ninterpolation is a part the manifest cannot see: it would publish `pan-`\nand a consumer's `::part(pan-up)` would match nothing. The same cost\n`drawIcon` names for `Trend`."
55743
+ },
55744
+ {
55745
+ "kind": "field",
55746
+ "name": "tier",
55747
+ "type": {
55748
+ "text": "string"
55749
+ },
55750
+ "static": true,
55751
+ "default": "'helix-headless-'",
55752
+ "description": "The prefix this tier registers its elements under.\n\n**A component that renders another renders its own tier's version of it**,\nso `helix-headless-pagination-size` composes `helix-headless-select` and\n`helix-pagination-size` composes `helix-select`. One template says\n`${this.tag('select')}` and each tier answers with its own name.\n\n**The public tag may not be the composed one, in either tier.** Using it\ncosts three things: the name means two different things depending on what a\nconsumer imported, the headless tier composes an element it does not ship,\nand the composition cannot be tested there at all, because there is no\n`helix-select` on that tier to test it against.\n\n**A prefix rather than an override per composition**, which was the first\nplan and does not compile. An override re-renders the fragment from the\nsubclass, and the fragment reads members the base keeps private:\n`PaginationSize` alone would have had to widen `options`, `current` and\n`handleChange` to `protected` so a subclass could say the same thing again.\nSixteen families of that is a lot of encapsulation spent on saying one\nword differently.",
55753
+ "inheritedFrom": {
55754
+ "name": "HelixElement",
55755
+ "module": "src/helix-element/helix-element.ts"
55756
+ }
55757
+ },
55758
+ {
55759
+ "kind": "method",
55760
+ "name": "tag",
55761
+ "privacy": "protected",
55762
+ "return": {
55763
+ "type": {
55764
+ "text": "StaticValue"
55765
+ }
55766
+ },
55767
+ "parameters": [
55768
+ {
55769
+ "name": "name",
55770
+ "type": {
55771
+ "text": "string"
55772
+ }
55773
+ }
55774
+ ],
55775
+ "description": "One composed tag, as a static value a template can interpolate.\n\n`unsafeStatic` is safe by construction: the name is a literal in our own\nsource and the prefix is one of two strings this class defines. Called per\nrender and not cached, which costs nothing, because `static-html` keys its\ntemplate cache on the joined string rather than on the object.",
55776
+ "inheritedFrom": {
55777
+ "name": "HelixElement",
55778
+ "module": "src/helix-element/helix-element.ts"
55779
+ }
55780
+ },
55781
+ {
55782
+ "kind": "method",
55783
+ "name": "partNamed",
55784
+ "privacy": "protected",
55785
+ "return": {
55786
+ "type": {
55787
+ "text": "T | null"
55788
+ }
55789
+ },
55790
+ "parameters": [
55791
+ {
55792
+ "name": "name",
55793
+ "type": {
55794
+ "text": "string"
55795
+ }
55796
+ }
55797
+ ],
55798
+ "description": "One of this element's own parts, by name, or null where it is not rendered.\n\nNot `part`, which every element already has: `Element.part` is the\n`DOMTokenList` of the names the element itself carries, and a method under\nthat name is a type error on every subclass.\n\n**One guard for every lookup.** Lit's server shim has no `querySelector`\non the render root, so a lookup reached during a server render, from a\ngetter a template reads or from `willUpdate`, throws there and nowhere\nelse. Four spellings of the same guard had grown across the library, and\na fifth site with none. Null on the server, which is what the rest of the\ncode already treats a part that has not rendered as.\n\n**`~=` and not `=`.** A part drawn in a state carries a second name while\nthe state holds, `part=\"page page-current\"`, and an exact match stops\nfinding it for exactly as long as it is the one that matters.\n\n`helix component`'s `selectors` reads these calls the way it reads a\n`querySelector('[part=\"x\"]')`, so a name nothing renders is a finding\nrather than a null an optional chain swallows.",
55799
+ "inheritedFrom": {
55800
+ "name": "HelixElement",
55801
+ "module": "src/helix-element/helix-element.ts"
55802
+ }
55803
+ },
55804
+ {
55805
+ "kind": "field",
55806
+ "name": "internals",
55807
+ "type": {
55808
+ "text": "ElementInternals"
55809
+ },
55810
+ "privacy": "protected",
55811
+ "readonly": true,
55812
+ "description": "The element's semantics, set without touching the DOM.\n\n`ElementInternals` sets the implicit role, which an author's own `role`\nattribute still overrides, and it writes no attribute. Setting `role` on the\nhost directly would: that is an attribute the element gives itself after it\nupgrades, which a React consumer's server markup never had, and hydration\nreports it as a mismatch.\n\nAvailable during server rendering. Lit's shim implements `attachInternals`,\nso nothing here needs a guard.",
55813
+ "inheritedFrom": {
55814
+ "name": "HelixElement",
55815
+ "module": "src/helix-element/helix-element.ts"
55816
+ }
55817
+ },
55818
+ {
55819
+ "kind": "method",
55820
+ "name": "toggleState",
55821
+ "privacy": "protected",
55822
+ "return": {
55823
+ "type": {
55824
+ "text": "void"
55825
+ }
55826
+ },
55827
+ "parameters": [
55828
+ {
55829
+ "name": "name",
55830
+ "type": {
55831
+ "text": "string"
55832
+ }
55833
+ },
55834
+ {
55835
+ "name": "on",
55836
+ "type": {
55837
+ "text": "boolean"
55838
+ }
55839
+ }
55840
+ ],
55841
+ "description": "Records a boolean fact about this element as a custom state.\n\n**The host belongs to whoever rendered it, and a component's own\nbookkeeping may not be kept there.** An attribute written on the first\nupdate is markup a consumer's server never sent, so a React consumer\nhydrates a DOM that has gained attributes since and reports a mismatch it\nwill not patch up. A custom state is not in the DOM at all: it carries the\nfact to a stylesheet through `:state()` and leaves the markup alone, so the\nserver's output and the client's agree by construction.\n\n`SETTLED` carries the long version of that argument; `checked`, `open`,\n`invalid` and `has-label` are recorded the same way, each of them a state a\n`default-*` attribute resolves before React reaches the node.\n\n**Deferring the definitions is not a fix and could not be.** Importing them\nfrom an effect so the upgrades fall the other side of hydration works only\nwhile hydration is one pass: anything that splits it, a streamed segment or\na suspended boundary, puts an upgrade back inside the window. Timing cannot\nbe the guarantee when the fact is kept somewhere React reconciles.\n\nFeature-tested rather than assumed, the way `hostAria` tests element\nreferences. An engine without `CustomStateSet` records nothing and keeps\nwhatever the resting rule draws, which is the safe direction to fail.\n\n**The engines the test is for are browsers**: Safari below 17.4 and Firefox\nbelow 126, where the write is a `TypeError`, so a component bypassing this\nfails to render rather than rendering without whatever the state draws.\nLit's server shim sets `states`, so the guard passes there and records a\nstate nothing reads, which is harmless.",
55842
+ "inheritedFrom": {
55843
+ "name": "HelixElement",
55844
+ "module": "src/helix-element/helix-element.ts"
55845
+ }
55846
+ },
55847
+ {
55848
+ "kind": "field",
55849
+ "name": "whenSettled",
55850
+ "type": {
55851
+ "text": "Promise<void>"
55852
+ },
55853
+ "readonly": true,
55854
+ "description": "Resolves a frame after the first update, when transitions are switched on.\n\n**Named `whenSettled` because `settled` is taken four times over**, by\nImage, Splitter and both color controls, none of them about transitions. A\nbase class takes the name every subclass then cannot use.\n\n**The state it reports cannot be watched, which is why this exists.** A\ncustom state is deliberately not in the DOM, so there is no\n`MutationObserver` equivalent for `ElementInternals.states`. Await this\ninstead.\n\nSeparate from `updateComplete`, which resolves in the microtask checkpoint\nthe suppression is still active in. That is the distinction `readyToMove`\nin `@fusion.dev/helix-testing` is written around.\n\nIt never resolves where `requestAnimationFrame` never fires, which is a\nserver, a hidden tab, and happy-dom. Callers that must not hang there race\nit against a timeout, as the happy-dom harness's `readyToMove` does. The\nbrowser harness's awaits it alone: a browser always runs the frame, and a\ntimer beside it was a bet on how long one takes, which a busy run lost.",
55855
+ "default": "new Promise<void>((resolve) => { this.resolveSettled = resolve })",
55856
+ "inheritedFrom": {
55857
+ "name": "HelixElement",
55858
+ "module": "src/helix-element/helix-element.ts"
55859
+ }
55860
+ },
55861
+ {
55862
+ "kind": "field",
55863
+ "name": "resolveSettled",
55864
+ "type": {
55865
+ "text": "() => void"
55866
+ },
55867
+ "privacy": "private",
55868
+ "description": "Resolves `whenSettled`, once, from the frame that records the state.",
55869
+ "inheritedFrom": {
55870
+ "name": "HelixElement",
55871
+ "module": "src/helix-element/helix-element.ts"
55872
+ }
55873
+ },
55874
+ {
55875
+ "kind": "field",
55876
+ "name": "fromServer",
55877
+ "type": {
55878
+ "text": "boolean"
55879
+ },
55880
+ "privacy": "private",
55881
+ "default": "false",
55882
+ "description": "Whether the shadow root was a server's, parsed from declarative shadow DOM.",
55883
+ "inheritedFrom": {
55884
+ "name": "HelixElement",
55885
+ "module": "src/helix-element/helix-element.ts"
55886
+ }
55887
+ },
55888
+ {
55889
+ "kind": "field",
55890
+ "name": "hydrating",
55891
+ "type": {
55892
+ "text": "boolean"
55893
+ },
55894
+ "privacy": "protected",
55895
+ "description": "Whether this update is hydrating a server's markup, and so has to render\nexactly what the server rendered.\n\n**Lit hydrates by assuming the markup already shows the first render.** A\nvalue that differs is recorded and never written, so the page keeps the\nserver's, and a template that differs throws. The server has no children,\nso anything a component reads from its children waits for the update after\nhydration, which `finishHydration` asks for. Without a server's markup the\nfirst render reads them and there is one render.",
55896
+ "readonly": true,
55897
+ "inheritedFrom": {
55898
+ "name": "HelixElement",
55899
+ "module": "src/helix-element/helix-element.ts"
55900
+ }
55901
+ },
55902
+ {
55903
+ "kind": "field",
55904
+ "name": "serverRendered",
55905
+ "type": {
55906
+ "text": "boolean"
55907
+ },
55908
+ "privacy": "protected",
55909
+ "description": "Whether this element hydrated a server's markup rather than rendering its own.\n\nFor what happened before hydration and cannot be heard after it: an image\nthe parser fetched fires `load` or `error` before any listener exists, so a\ncomponent asks the image instead, once, when this is true.",
55910
+ "readonly": true,
55911
+ "inheritedFrom": {
55912
+ "name": "HelixElement",
55913
+ "module": "src/helix-element/helix-element.ts"
55914
+ }
55915
+ },
55916
+ {
55917
+ "kind": "method",
55918
+ "name": "finishHydration",
55919
+ "privacy": "protected",
55920
+ "return": {
55921
+ "type": {
55922
+ "text": "void"
55923
+ }
55924
+ },
55925
+ "description": "Asks for the update a hydration put off, so the reads it skipped happen.\n\nCalled from `firstUpdated`, the end of the hydrating update. The render it\nschedules can only follow that one, which is the exception Lit's\nchange-in-update warning names, and it happens only on a page a server\nrendered.",
55926
+ "inheritedFrom": {
55927
+ "name": "HelixElement",
55928
+ "module": "src/helix-element/helix-element.ts"
55929
+ }
55930
+ },
55931
+ {
55932
+ "kind": "field",
55933
+ "name": "childrenKnown",
55934
+ "type": {
55935
+ "text": "boolean"
55936
+ },
55937
+ "privacy": "protected",
55938
+ "description": "Whether this render can know the children.\n\nA server cannot: its element shim carries attributes and no tree, so\n`children` is undefined there. A render hydrating what a server sent must\nnot, because it has to be the server's render. Anywhere else it can. A\ncomponent whose render depends on its children reads them through\n`knownChildren`, and treats \"not known\" as its own answer rather than as\n\"none\": a list that renders its empty state because nobody has looked yet is\nthe one thing an empty state must never do.",
55939
+ "readonly": true,
55940
+ "inheritedFrom": {
55941
+ "name": "HelixElement",
55942
+ "module": "src/helix-element/helix-element.ts"
55943
+ }
55944
+ },
55945
+ {
55946
+ "kind": "field",
55947
+ "name": "knownChildren",
55948
+ "type": {
55949
+ "text": "Element[]"
55950
+ },
55951
+ "privacy": "protected",
55952
+ "description": "The children a render may read: all of them where they are known, and none otherwise.",
55953
+ "readonly": true,
55954
+ "inheritedFrom": {
55955
+ "name": "HelixElement",
55956
+ "module": "src/helix-element/helix-element.ts"
55957
+ }
55958
+ },
55959
+ {
55960
+ "kind": "field",
55961
+ "name": "assignsByName",
55962
+ "type": {
55963
+ "text": "boolean"
55964
+ },
55965
+ "privacy": "protected",
55966
+ "description": "Whether this element's slots route by name although it asked to assign them\nby hand.\n\n**A declarative shadow root is always the by-name kind.** HTML has no way to\nask for manual assignment, so a component that assigns by hand and hydrates\na server's root gets one where `slot.assign()` does nothing, and its\nchildren land wherever their `slot` attribute sends them. The way through is\nto write that attribute, which is what `route` does. Only there: on a root\nthis element made, assignment stays manual and the consumer's markup is\nnever touched, which is what a React consumer's hydration requires.",
55967
+ "readonly": true,
55968
+ "inheritedFrom": {
55969
+ "name": "HelixElement",
55970
+ "module": "src/helix-element/helix-element.ts"
55971
+ }
55972
+ },
55973
+ {
55974
+ "kind": "method",
55975
+ "name": "route",
55976
+ "privacy": "protected",
55977
+ "return": {
55978
+ "type": {
55979
+ "text": "void"
55980
+ }
55981
+ },
55982
+ "parameters": [
55983
+ {
55984
+ "name": "child",
55985
+ "type": {
55986
+ "text": "Element"
55987
+ }
55988
+ },
55989
+ {
55990
+ "name": "name",
55991
+ "type": {
55992
+ "text": "string | undefined"
55993
+ }
55994
+ }
55995
+ ],
55996
+ "description": "Sends a child to a slot by name, on a root that routes by name.\n\n`undefined` is the default slot. Written only when it differs, so routing\nthe same child again on every update writes nothing.",
55997
+ "inheritedFrom": {
55998
+ "name": "HelixElement",
55999
+ "module": "src/helix-element/helix-element.ts"
56000
+ }
56001
+ },
56002
+ {
56003
+ "kind": "field",
56004
+ "name": "stopInner",
56005
+ "privacy": "protected",
56006
+ "readonly": true,
56007
+ "description": "Stops an inner control's own announcement at this element's boundary.\n\n**A composed control is one control to a consumer, and the natives had no\nequivalent of the stop the prefixed events already get.** `<helix-select>`\nrenders a `<helix-listbox>`, and both announce: the listbox dispatches\n`input` and `change` from its own host, `input` is composed by\nspecification, and a consumer listening on the select therefore heard one\nchoice twice. Measured before this existed, on the styled tier, one choice\non the inner listbox: select `input` twice and `change` three times,\ncombobox, date input, time input and color input twice each. `Command` was\nthe only one that was right, because it happened to reach for\n`stopImmediatePropagation` for a different reason.\n\nBound on the child in the parent's template, so it runs while the event is\nstill at the child and before it can cross. The guard is for the case where\na component binds this on itself: an element must never stop its own\nannouncement, which is the one it exists to make.\n\nThis is the same job the `helix-before-*` handlers do with their own\n`stopPropagation`, and it is separate rather than folded into them because\na consumer may legitimately refuse a request without the notification ever\nhappening: the two travel at different times and one can be absent.",
56008
+ "inheritedFrom": {
56009
+ "name": "HelixElement",
56010
+ "module": "src/helix-element/helix-element.ts"
56011
+ }
56012
+ },
56013
+ {
56014
+ "kind": "method",
56015
+ "name": "relayNativeEvent",
56016
+ "privacy": "protected",
56017
+ "return": {
56018
+ "type": {
56019
+ "text": "void"
56020
+ }
56021
+ },
56022
+ "parameters": [
56023
+ {
56024
+ "name": "event",
56025
+ "type": {
56026
+ "text": "Event"
56027
+ }
56028
+ },
56029
+ {
56030
+ "name": "init",
56031
+ "optional": true,
56032
+ "type": {
56033
+ "text": "EventInit"
56034
+ }
56035
+ }
56036
+ ],
56037
+ "description": "Re-emits a native event from the host, under its own name.\n\nA native event fired by an inner `<input>` or `<textarea>` is not composed,\nso it stops at the shadow boundary and a consumer listening on\n`<helix-input>` hears nothing. Re-dispatching it from the host is what\nmakes the component behave like the control it wraps.\n\nThe relayed event keeps the native name deliberately. `change` is `change`,\nwhich is what a consumer already knows to listen for, and it is what\nreaches React: its synthetic system claims `onChange` and wires it to that\nname, so a prefixed one would never arrive.\n\n`composed` is not forced. It defaults to the original event's own value, so\na relayed `change` stops at the next shadow boundary exactly as a native\none would. Pass it explicitly only where escaping is the intent, and say so\nwhere you do.",
56038
+ "inheritedFrom": {
56039
+ "name": "HelixElement",
56040
+ "module": "src/helix-element/helix-element.ts"
56041
+ }
56042
+ },
56043
+ {
56044
+ "kind": "method",
56045
+ "name": "finalizeStyles",
56046
+ "privacy": "protected",
56047
+ "static": true,
56048
+ "return": {
56049
+ "type": {
56050
+ "text": "CSSResultOrNative[]"
56051
+ }
56052
+ },
56053
+ "parameters": [
56054
+ {
56055
+ "name": "styles",
56056
+ "optional": true,
56057
+ "type": {
56058
+ "text": "CSSResultOrNative | CSSResultOrNative[]"
56059
+ }
56060
+ }
56061
+ ],
56062
+ "description": "Prepends the shadow-root reset to every subclass's styles, so no component\nhas to remember to include it.",
56063
+ "inheritedFrom": {
56064
+ "name": "HelixElement",
56065
+ "module": "src/helix-element/helix-element.ts"
56066
+ }
56067
+ }
56068
+ ],
56069
+ "events": [
56070
+ {
56071
+ "type": {
56072
+ "text": "HelixMapPanEvent"
56073
+ },
56074
+ "description": "The reader asked the map to move. Answer it against your own map.",
56075
+ "name": "helix-map-pan",
56076
+ "reactProp": "onhelix-map-pan"
56077
+ },
56078
+ {
56079
+ "type": {
56080
+ "text": "HelixMapZoomEvent"
56081
+ },
56082
+ "description": "The reader asked the map to zoom, by a direction rather than to a level.",
56083
+ "name": "helix-map-zoom",
56084
+ "reactProp": "onhelix-map-zoom"
56085
+ }
56086
+ ],
56087
+ "attributes": [
56088
+ {
56089
+ "name": "controls",
56090
+ "type": {
56091
+ "text": "string | undefined"
56092
+ },
56093
+ "description": "Which of the controls this frame draws, as a list of what to keep.\n\n**A list rather than a switch, because the overlap is not symmetric.**\nEvery map library draws zoom controls and none of them draws pan buttons:\nMapLibre's navigation control is zoom and a compass, Leaflet's is zoom,\nGoogle's is zoom. So a consumer slotting one of those has our zoom twice\nover and our pan pad not at all, and a single switch would make them choose\nbetween a duplicate and nothing.\n\n`none` draws none of them, which is the right answer where the slotted map\nalready has controls a reader can find: what this family argues for is that\n*a* findable control exists, never that it is ours. The methods stay public\neither way, so a consumer drawing their own chrome can still drive the\nframe.\n\nAbsent is all three, which is this library's rule that a resting value is an\nattribute's absence, and it is what the stylesheet asks about: the layout\nrules are written against `[controls]:not([controls~=\"zoom\"])` rather than\nthe bare negation, or a frame that named no list at all would be laid out as\nthough it had dropped everything.",
56094
+ "fieldName": "controls"
56095
+ },
56096
+ {
56097
+ "name": "controls-placement",
56098
+ "type": {
56099
+ "text": "'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | undefined"
56100
+ },
56101
+ "description": "Which corner the controls sit in.\n\n**Configurable because there is no safe default**, and this is a collision\nrather than a taste: MapLibre puts its own controls at the top end, Leaflet\nand OpenLayers at the top start, Google's zoom at the bottom end. Whichever\ncorner this took would land on somebody's, which is why every one of those\nlibraries made it a setting too.\n\nLogical corners rather than left and right, so a right-to-left page moves\nthem without a consumer writing a second rule.\n\nAbsent is the top end, which is this library's rule that a resting value is\nan attribute's absence: a default that reflected would write an attribute\nonto every host that no server sent and nobody asked for.",
56102
+ "fieldName": "controlsPlacement"
56103
+ },
56104
+ {
56105
+ "name": "fullscreen-label",
56106
+ "type": {
56107
+ "text": "string"
56108
+ },
56109
+ "default": "'Fill the screen'",
56110
+ "description": "What the control that fills the screen is called.",
56111
+ "fieldName": "fullscreenLabel"
56112
+ },
56113
+ {
56114
+ "name": "idle-delay",
56115
+ "type": {
56116
+ "text": "number"
56117
+ },
56118
+ "default": "0",
56119
+ "description": "How long the reader may be still before the chrome hides, in milliseconds.\n\nZero keeps it up, which is the default: a map's controls are how a keyboard\nreader operates it, and chrome that hides itself by default would be this\ncomponent undoing its own argument. Set it for a display map nobody drives.",
56120
+ "fieldName": "idleDelay"
56121
+ },
56122
+ {
56123
+ "name": "label",
56124
+ "type": {
56125
+ "text": "string"
56126
+ },
56127
+ "default": "''",
56128
+ "description": "Accessible name for the map, which is the one thing a consumer must write.\n\nThere is no sensible default. \"Map\" names the widget rather than the place,\nand a reader meeting three of them on a page learns nothing from hearing the\nsame word three times.",
56129
+ "fieldName": "label"
56130
+ },
56131
+ {
56132
+ "name": "pan-label",
56133
+ "type": {
56134
+ "text": "string"
56135
+ },
56136
+ "default": "'Pan {way}'",
56137
+ "description": "What the controls are called, for a page not in English.",
56138
+ "fieldName": "panLabel"
56139
+ },
56140
+ {
56141
+ "name": "pan-step",
56142
+ "type": {
56143
+ "text": "number"
56144
+ },
56145
+ "default": "0.25",
56146
+ "description": "How far one press moves the map, as a fraction of what is on screen.\n\nA fraction rather than a distance, because this frame does not know the\nscale of what is inside it: a quarter of the viewport is the same gesture at\nstreet level and at country level, and a consumer who wants metres can\nmultiply by their own.",
56147
+ "fieldName": "panStep"
56148
+ },
56149
+ {
56150
+ "name": "zoom-in-label",
56151
+ "type": {
56152
+ "text": "string"
56153
+ },
56154
+ "default": "'Zoom in'",
56155
+ "description": "What the zoom controls are called.",
56156
+ "fieldName": "zoomInLabel"
56157
+ },
56158
+ {
56159
+ "name": "zoom-out-label",
56160
+ "type": {
56161
+ "text": "string"
56162
+ },
56163
+ "default": "'Zoom out'",
56164
+ "description": "What the zoom control that goes the other way is called.",
56165
+ "fieldName": "zoomOutLabel"
56166
+ }
56167
+ ],
56168
+ "cssStates": [
56169
+ {
56170
+ "description": "While the frame fills the screen.",
56171
+ "name": "fullscreen"
56172
+ },
56173
+ {
56174
+ "description": "While the reader has been still long enough to hide the chrome.",
56175
+ "name": "idle"
56176
+ },
56177
+ {
56178
+ "description": "Set a frame after the first render. Transitions are held off until it is, so an element never animates its own arrival.",
56179
+ "name": "settled",
56180
+ "inheritedFrom": {
56181
+ "name": "HelixElement",
56182
+ "module": "src/helix-element/helix-element.ts"
56183
+ }
56184
+ }
56185
+ ],
56186
+ "superclass": {
56187
+ "name": "HelixElement",
56188
+ "package": "@fusion.dev/helix-core"
56189
+ },
56190
+ "summary": "A frame around somebody else's map.",
56191
+ "helix": {
56192
+ "category": "media",
56193
+ "since": "0.100.0",
56194
+ "status": "stable",
56195
+ "documentation": "https://fusion.dev/helix/components/map",
56196
+ "aliases": [
56197
+ "Map frame",
56198
+ "Map container",
56199
+ "Geo"
56200
+ ],
56201
+ "tier": "headless",
56202
+ "group": "BaseMap",
56203
+ "part": "Root",
56204
+ "source": "helix/headless/src/map"
56205
+ },
56206
+ "tagName": "helix-headless-map",
56207
+ "customElement": true,
56208
+ "modulePath": "src/map/root/map-root.ts",
56209
+ "definitionPath": "src/map/root/map-root.ts"
56210
+ }
56211
+ ],
56212
+ "exports": [
56213
+ {
56214
+ "kind": "js",
56215
+ "name": "HelixHeadlessMap",
56216
+ "declaration": {
56217
+ "name": "HelixHeadlessMap",
56218
+ "module": "src/map/root/map-root.ts"
56219
+ }
56220
+ },
56221
+ {
56222
+ "kind": "custom-element-definition",
56223
+ "name": "helix-headless-map",
56224
+ "declaration": {
56225
+ "name": "HelixHeadlessMap",
56226
+ "module": "src/map/root/map-root.ts"
56227
+ }
56228
+ }
56229
+ ]
56230
+ },
55417
56231
  {
55418
56232
  "kind": "javascript-module",
55419
56233
  "path": "src/megamenu/index.ts",