@aparte/core 0.15.1 → 0.16.1

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.
Files changed (143) hide show
  1. package/dist/client/aparte-client.d.ts +53 -51
  2. package/dist/client/aparte-client.d.ts.map +1 -1
  3. package/dist/client/lifecycle-events.d.ts +0 -12
  4. package/dist/client/lifecycle-events.d.ts.map +1 -1
  5. package/dist/client/stream-adapter.d.ts +2 -12
  6. package/dist/client/stream-adapter.d.ts.map +1 -1
  7. package/dist/components/bubble/aparte-chat-bubble.d.ts +45 -1
  8. package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -1
  9. package/dist/components/chat/aparte-chat.d.ts +1 -1
  10. package/dist/components/composer/aparte-composer-action.d.ts +1 -1
  11. package/dist/components/composer/aparte-composer-add-attachment.d.ts +1 -1
  12. package/dist/components/composer/aparte-composer-attachments.d.ts +1 -2
  13. package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -1
  14. package/dist/components/composer/aparte-composer-cancel.d.ts +1 -1
  15. package/dist/components/composer/aparte-composer-input.d.ts +1 -1
  16. package/dist/components/composer/aparte-composer-send.d.ts +12 -12
  17. package/dist/components/composer/aparte-composer-send.d.ts.map +1 -1
  18. package/dist/components/composer/aparte-composer.d.ts +29 -12
  19. package/dist/components/composer/aparte-composer.d.ts.map +1 -1
  20. package/dist/components/context/aparte-context.d.ts +31 -8
  21. package/dist/components/context/aparte-context.d.ts.map +1 -1
  22. package/dist/components/conversation-list/aparte-conversation-list.d.ts +93 -36
  23. package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -1
  24. package/dist/components/conversation-list/index.d.ts +1 -1
  25. package/dist/components/conversation-list/index.d.ts.map +1 -1
  26. package/dist/components/elicitation/aparte-elicitation.d.ts +20 -2
  27. package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
  28. package/dist/components/index.d.ts +7 -1
  29. package/dist/components/index.d.ts.map +1 -1
  30. package/dist/components/scroll-rail/aparte-scroll-rail.d.ts +105 -0
  31. package/dist/components/scroll-rail/aparte-scroll-rail.d.ts.map +1 -0
  32. package/dist/components/scroll-rail/index.d.ts +3 -0
  33. package/dist/components/scroll-rail/index.d.ts.map +1 -0
  34. package/dist/components/sidebar/aparte-sidebar.d.ts +186 -0
  35. package/dist/components/sidebar/aparte-sidebar.d.ts.map +1 -0
  36. package/dist/components/sidebar/index.d.ts +3 -0
  37. package/dist/components/sidebar/index.d.ts.map +1 -0
  38. package/dist/components/split/aparte-split.d.ts +354 -0
  39. package/dist/components/split/aparte-split.d.ts.map +1 -0
  40. package/dist/components/split/geometry.d.ts +65 -0
  41. package/dist/components/split/geometry.d.ts.map +1 -0
  42. package/dist/components/split/index.d.ts +3 -0
  43. package/dist/components/split/index.d.ts.map +1 -0
  44. package/dist/components/suggestions/aparte-suggestions.d.ts +7 -1
  45. package/dist/components/suggestions/aparte-suggestions.d.ts.map +1 -1
  46. package/dist/components/viewport/aparte-chat-viewport.d.ts +52 -2
  47. package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
  48. package/dist/config/aparte-config.d.ts +95 -33
  49. package/dist/config/aparte-config.d.ts.map +1 -1
  50. package/dist/config/icon-provider.d.ts +6 -0
  51. package/dist/config/icon-provider.d.ts.map +1 -1
  52. package/dist/config/index.d.ts +2 -2
  53. package/dist/config/index.d.ts.map +1 -1
  54. package/dist/config/locale.d.ts +140 -27
  55. package/dist/config/locale.d.ts.map +1 -1
  56. package/dist/config/sanitize.d.ts +9 -0
  57. package/dist/config/sanitize.d.ts.map +1 -1
  58. package/dist/conversations/conversation-controller.d.ts +13 -1
  59. package/dist/conversations/conversation-controller.d.ts.map +1 -1
  60. package/dist/conversations/conversation-manager.d.ts +9 -0
  61. package/dist/conversations/conversation-manager.d.ts.map +1 -1
  62. package/dist/custom-elements.json +10278 -7784
  63. package/dist/{is-awaiting-reply-BZ_iJ3s3.js → dialog-triggers-CVCxqKg3.js} +718 -1182
  64. package/dist/dialog-triggers-CVCxqKg3.js.map +1 -0
  65. package/dist/elicitation/approval-panel.d.ts +1 -1
  66. package/dist/elicitation/approval-panel.d.ts.map +1 -1
  67. package/dist/elicitation/panel.d.ts +24 -16
  68. package/dist/elicitation/panel.d.ts.map +1 -1
  69. package/dist/elicitation/types.d.ts +31 -0
  70. package/dist/elicitation/types.d.ts.map +1 -1
  71. package/dist/generated/element-attributes.d.ts +47 -1
  72. package/dist/generated/element-attributes.d.ts.map +1 -1
  73. package/dist/{glyphs-B3BZ2TIb.js → glyphs-DQTeOj4w.js} +22 -13
  74. package/dist/{glyphs-B3BZ2TIb.js.map → glyphs-DQTeOj4w.js.map} +1 -1
  75. package/dist/host/aparte-chat-host.d.ts +10 -2
  76. package/dist/host/aparte-chat-host.d.ts.map +1 -1
  77. package/dist/icons/extended.d.ts +4 -2
  78. package/dist/icons/extended.d.ts.map +1 -1
  79. package/dist/icons/glyphs.d.ts +9 -0
  80. package/dist/icons/glyphs.d.ts.map +1 -1
  81. package/dist/icons.js +16 -15
  82. package/dist/icons.js.map +1 -1
  83. package/dist/index.css +1284 -397
  84. package/dist/index.d.ts +26 -15
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +2099 -296
  87. package/dist/index.js.map +1 -1
  88. package/dist/index.node.d.ts +21 -5
  89. package/dist/index.node.d.ts.map +1 -1
  90. package/dist/index.node.js +39 -34
  91. package/dist/index.node.js.map +1 -1
  92. package/dist/interop/dialog-triggers.d.ts +27 -0
  93. package/dist/interop/dialog-triggers.d.ts.map +1 -0
  94. package/dist/interop/element-props.d.ts +16 -8
  95. package/dist/interop/element-props.d.ts.map +1 -1
  96. package/dist/parsers/aparte-stream-parser.d.ts +52 -22
  97. package/dist/parsers/aparte-stream-parser.d.ts.map +1 -1
  98. package/dist/parsers/index.d.ts +1 -1
  99. package/dist/parsers/index.d.ts.map +1 -1
  100. package/dist/primitives/select/aparte-select.d.ts.map +1 -1
  101. package/dist/renderers/segment-renderers.d.ts.map +1 -1
  102. package/dist/renderers/segments/code.d.ts.map +1 -1
  103. package/dist/renderers/segments/tool-call.d.ts.map +1 -1
  104. package/dist/runtime/message-repository.d.ts.map +1 -1
  105. package/dist/transport/backend-handler.d.ts.map +1 -1
  106. package/dist/transport/backend-transport.d.ts +6 -1
  107. package/dist/transport/backend-transport.d.ts.map +1 -1
  108. package/dist/types/chat.d.ts +8 -14
  109. package/dist/types/chat.d.ts.map +1 -1
  110. package/dist/types/element-map.d.ts +54 -4
  111. package/dist/types/element-map.d.ts.map +1 -1
  112. package/dist/types/event-map.d.ts +16 -10
  113. package/dist/types/event-map.d.ts.map +1 -1
  114. package/dist/types/events.d.ts +59 -117
  115. package/dist/types/events.d.ts.map +1 -1
  116. package/dist/types/imperative-api.d.ts +3 -1
  117. package/dist/types/imperative-api.d.ts.map +1 -1
  118. package/dist/types/index.d.ts +5 -4
  119. package/dist/types/index.d.ts.map +1 -1
  120. package/dist/types/models.d.ts +11 -31
  121. package/dist/types/models.d.ts.map +1 -1
  122. package/dist/types/segments.d.ts +11 -47
  123. package/dist/types/segments.d.ts.map +1 -1
  124. package/dist/types/stream-blocks.d.ts +57 -0
  125. package/dist/types/stream-blocks.d.ts.map +1 -0
  126. package/dist/types/tools.d.ts +57 -0
  127. package/dist/types/tools.d.ts.map +1 -1
  128. package/dist/utils/copy-text.d.ts +24 -0
  129. package/dist/utils/copy-text.d.ts.map +1 -0
  130. package/dist/utils/css-escape.d.ts +5 -0
  131. package/dist/utils/css-escape.d.ts.map +1 -1
  132. package/dist/utils/tool-input.d.ts +20 -0
  133. package/dist/utils/tool-input.d.ts.map +1 -0
  134. package/package.json +10 -3
  135. package/dist/is-awaiting-reply-BZ_iJ3s3.js.map +0 -1
  136. package/dist/renderers/segments/artifact/binary-file.d.ts +0 -45
  137. package/dist/renderers/segments/artifact/binary-file.d.ts.map +0 -1
  138. package/dist/renderers/segments/artifact/card.d.ts +0 -3
  139. package/dist/renderers/segments/artifact/card.d.ts.map +0 -1
  140. package/dist/renderers/segments/artifact/preview-document.d.ts +0 -27
  141. package/dist/renderers/segments/artifact/preview-document.d.ts.map +0 -1
  142. package/dist/renderers/segments/artifact/shared.d.ts +0 -29
  143. package/dist/renderers/segments/artifact/shared.d.ts.map +0 -1
@@ -0,0 +1,186 @@
1
+ /** Detail of `aparte-sidebar-toggle`: the state just entered. */
2
+ export interface AparteSidebarToggleDetail {
3
+ collapsed: boolean;
4
+ /** True while the sidebar is a drawer — the window is under the breakpoint. */
5
+ drawer: boolean;
6
+ }
7
+ /**
8
+ * The column beside the chat — conversations, a new-chat button, a search field, an
9
+ * account row — as an element, because it has behaviour: it collapses, it becomes a
10
+ * drawer on a narrow window, and its search field filters the conversation list.
11
+ *
12
+ * What it does NOT own is its content. Children are yours, in the order you want them:
13
+ * a `.aparte-sidebar__header`, a `.aparte-sidebar__search`, a `.aparte-sidebar__body`
14
+ * holding the `<aparte-conversation-list>`, a `.aparte-sidebar__footer`. The
15
+ * stylesheet lays those out and draws nothing you did not put there — the recipe
16
+ * (`.aparte-sidebar`, in `styles/shell/sidebar.css`) is the look, this element is
17
+ * the three behaviours.
18
+ *
19
+ * **Collapse.** `collapsed` is an attribute, reflected, so the host can set it, read
20
+ * it and persist it. Any element carrying `data-aparte-sidebar-toggle` anywhere on
21
+ * the page toggles the nearest sidebar (or the one whose id the attribute names), so
22
+ * a hamburger in the header needs no script. `aparte-sidebar-toggle` fires on every
23
+ * change, whoever caused it.
24
+ *
25
+ * **Drawer.** Under 48rem of window the sidebar leaves the flow and slides over the
26
+ * page (`data-drawer`, set by the element from a media query); open, it draws a
27
+ * scrim, moves the focus to its first focusable child, closes on Escape from anywhere
28
+ * on the page or on a click outside, and hands the focus back to the control that
29
+ * opened it. Nothing here is a portal: the drawer is the same element in the same
30
+ * place, positioned fixed, which is all a sidebar needs and what a dialog would not
31
+ * get away with. Collapsed — folded as a column or slid off as a drawer — it carries
32
+ * `inert` and `aria-hidden`, so nothing invisible keeps a tab stop.
33
+ *
34
+ * **Search.** An input carrying `data-aparte-sidebar-search` filters the conversation
35
+ * list below it by title as the user types — rows that do not match are hidden, and a
36
+ * date group with nothing left hides with them. Client-side, on the titles the list
37
+ * already has: an index over message bodies is the storage adapter's business.
38
+ *
39
+ * @element aparte-sidebar
40
+ *
41
+ * @attr {boolean} collapsed - Hidden (in the flow) or closed (as a drawer). Reflected; set it to start closed.
42
+ * @attr {string} breakpoint - The window width under which the sidebar becomes a drawer: a length (default `48rem`), or `none` for a column that never does.
43
+ * @attr {boolean} data-drawer - Reflected BY the element while the window is under 48rem. Read-only.
44
+ *
45
+ * @fires {CustomEvent<AparteSidebarToggleDetail>} aparte-sidebar-toggle - The sidebar opened or closed, by a toggle, by Escape, by a click on the scrim or by `collapsed` being set. Bubbles.
46
+ *
47
+ * @cssprop [--aparte-sidebar-width=260px] - Width of the column, and of the drawer.
48
+ * @cssprop [--aparte-sidebar-bg=var(--aparte-surface-2)] - Its ground.
49
+ *
50
+ * @example
51
+ * <!-- The sidebar alone, as a column: its header, a search field that filters the list,
52
+ * the list, a footer. The shell it sits in — header, chat — is the app-shell guide's.
53
+ * breakpoint="none" keeps it a column at any width; without it, under 48rem of
54
+ * window it becomes a drawer behind a [data-aparte-sidebar-toggle] control. -->
55
+ * <aparte-sidebar breakpoint="none" style="height: 22rem">
56
+ * <div class="aparte-sidebar__header">
57
+ * <span class="aparte-sidebar__brand">aparté</span>
58
+ * <button class="aparte-btn aparte-btn--icon aparte-btn--sm" type="button" aria-label="New chat">
59
+ * <aparte-icon name="edit"></aparte-icon>
60
+ * </button>
61
+ * </div>
62
+ * <div class="aparte-sidebar__search aparte-field-group">
63
+ * <input class="aparte-field aparte-field--sm" type="search" placeholder="Search conversations" data-aparte-sidebar-search>
64
+ * </div>
65
+ * <div class="aparte-sidebar__body">
66
+ * <aparte-conversation-list active-id="c1"></aparte-conversation-list>
67
+ * </div>
68
+ * <div class="aparte-sidebar__footer">
69
+ * <span class="aparte-avatar aparte-avatar--sm">P</span> Paul
70
+ * </div>
71
+ * </aparte-sidebar>
72
+ * <script>
73
+ * const day = 864e5;
74
+ * document.querySelector('aparte-conversation-list').conversations = [
75
+ * { id: 'c1', title: 'Deploy checklist', updatedAt: Date.now() },
76
+ * { id: 'c2', title: 'Rename the segment types', updatedAt: Date.now() - day },
77
+ * { id: 'c3', title: 'Tokens, not selectors', updatedAt: Date.now() - 4 * day },
78
+ * { id: 'c4', title: 'The first release', updatedAt: Date.now() - 60 * day },
79
+ * ];
80
+ * </script>
81
+ */
82
+ export declare class AparteSidebar extends HTMLElement {
83
+ static get observedAttributes(): string[];
84
+ private _media;
85
+ private _scrim;
86
+ /** The control that last opened the drawer, to hand the focus back to. */
87
+ private _opener;
88
+ private _lastCollapsed;
89
+ /**
90
+ * `connectedCallback` has run and the element knows what its markup asked for.
91
+ *
92
+ * Not `isConnected`: during an UPGRADE the element is already in the document, so
93
+ * `attributeChangedCallback` fires for every authored attribute — connected, and
94
+ * before `connectedCallback` — which is the ordinary case for a server-rendered
95
+ * `<aparte-sidebar collapsed>` upgraded when the module loads. Announcing there
96
+ * tells the host its sidebar just closed when all that happened is that the markup
97
+ * was read, and says `drawer: false` because the media query has not run yet.
98
+ */
99
+ private _ready;
100
+ /**
101
+ * The host (or the markup) asked for the column to be folded, so widening the
102
+ * window must not unfold it. Only a collapse taken OUTSIDE the drawer state counts:
103
+ * dismissing an overlay says nothing about what a wide window should show.
104
+ */
105
+ private _closedByHost;
106
+ /**
107
+ * `_closedByHost` has been taken from the markup once. A re-parent runs
108
+ * `connectedCallback` again, and by then `collapsed` may be the BREAKPOINT's own
109
+ * write — a drawer closes itself on the way in — so reading it back a second time
110
+ * records the element's own doing as the host's word and the column never reopens.
111
+ * Like `_initialCaptured` on `<aparte-split>`, it must survive the move.
112
+ */
113
+ private _hostIntentSeeded;
114
+ /** Raised around `_applyDrawer`'s own writes, so the breakpoint is never read as a host's intent. */
115
+ private _auto;
116
+ /**
117
+ * The element wrote `inert`/`aria-hidden` and may take them back. A host that inerts
118
+ * the sidebar behind its own modal wrote them itself, and `_syncHidden` runs on every
119
+ * breakpoint re-evaluation: without this it would un-inert the page behind the overlay.
120
+ * Same convention as `_relabel`, which leaves a host-authored `aria-label` alone.
121
+ */
122
+ private _ownHidden;
123
+ /** Whether the sidebar is collapsed (hidden in the flow, or closed as a drawer). */
124
+ get collapsed(): boolean;
125
+ set collapsed(value: boolean);
126
+ /** True while the window is under the breakpoint and the sidebar is a drawer. */
127
+ get drawer(): boolean;
128
+ connectedCallback(): void;
129
+ /**
130
+ * The drawer's media query, from the `breakpoint` attribute: a length (`48rem`, the
131
+ * default, or `640px`), or `none` for a column that never becomes a drawer — which
132
+ * a narrow host that has room for it wants, and a documentation frame needs.
133
+ */
134
+ private _watchBreakpoint;
135
+ disconnectedCallback(): void;
136
+ attributeChangedCallback(name: string): void;
137
+ /** Open the sidebar. `opener` is the control to hand the focus back to when it closes. */
138
+ open(opener?: HTMLElement): void;
139
+ close(): void;
140
+ toggle(opener?: HTMLElement): void;
141
+ private _onMediaChange;
142
+ /**
143
+ * Entering the drawer state closes the sidebar: a narrow window that opens on an
144
+ * overlay covering the chat is the wrong first screen. Leaving it reopens, since
145
+ * a wide window has room for the column — unless the host had collapsed it before.
146
+ */
147
+ private _applyDrawer;
148
+ /**
149
+ * A collapsed sidebar is invisible — folded to nothing in the flow, slid off the
150
+ * screen as a drawer — so it must not keep its tab stops or its place in the
151
+ * accessibility tree. `inert` covers focus and the pointer, `aria-hidden` covers
152
+ * the readers that predate it; a browser without `inert` still gets the second.
153
+ *
154
+ * It removes only what it wrote. Both are standard global attributes a host sets
155
+ * itself — inerting the sidebar behind its own modal is the ordinary pattern — and
156
+ * this runs on every breakpoint re-evaluation, so clearing them unconditionally lets
157
+ * an unrelated resize re-expose the page under an overlay. Same convention as
158
+ * `_relabel`, which leaves a host-authored `aria-label` alone.
159
+ *
160
+ * Neither is declared `@attr`, and `data-drawer` is not the precedent: a `@attr` on a
161
+ * STANDARD name displaces the wrappers' own prop for it — React's JSX props are
162
+ * `Omit<HTMLAttributes, keyof T>`, so declaring `inert` here would retype
163
+ * `<aparte-sidebar inert={busy}>` out of existence. The class docblock says it in prose.
164
+ */
165
+ private _syncHidden;
166
+ /**
167
+ * The drawer covers the page, so the focus has to follow it in — otherwise the next
168
+ * Tab walks the transcript under the overlay. The host owns the children, so this
169
+ * takes the first thing that can hold focus and leaves the rest alone; a drawer with
170
+ * nothing focusable in it keeps the focus where it was, which is the honest outcome.
171
+ */
172
+ private _focusFirst;
173
+ private _syncScrim;
174
+ private _onKeydown;
175
+ /** A `[data-aparte-sidebar-toggle]` anywhere toggles this sidebar — no script in the host. */
176
+ private _onDocumentClick;
177
+ private _onInput;
178
+ /**
179
+ * Hide the conversation rows whose title does not contain `query`, and the date
180
+ * groups left empty. Case- and accent-insensitive. An empty query shows everything.
181
+ */
182
+ filter(query: string): void;
183
+ private _onConfigChange;
184
+ private _relabel;
185
+ }
186
+ //# sourceMappingURL=aparte-sidebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aparte-sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/sidebar/aparte-sidebar.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,MAAM,WAAW,yBAAyB;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,+EAA+E;IAC/E,MAAM,EAAE,OAAO,CAAC;CACnB;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC1C,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,MAAM,CAA4B;IAC1C,0EAA0E;IAC1E,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,cAAc,CAAwB;IAE9C;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;OAIG;IACH,OAAO,CAAC,aAAa,CAAS;IAE9B;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB,CAAS;IAElC,qGAAqG;IACrG,OAAO,CAAC,KAAK,CAAS;IAEtB;;;;;OAKG;IACH,OAAO,CAAC,UAAU,CAAS;IAE3B,oFAAoF;IACpF,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;IAED,iFAAiF;IACjF,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,iBAAiB,IAAI,IAAI;IAyBzB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAexB,oBAAoB,IAAI,IAAI;IAU5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA8B5C,0FAA0F;IAC1F,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI;IAKhC,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI;IAOlC,OAAO,CAAC,cAAc,CAAkE;IAExF;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAcpB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,WAAW;IAYnB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,UAAU,CAKhB;IAEF,8FAA8F;IAC9F,OAAO,CAAC,gBAAgB,CAUtB;IAIF,OAAO,CAAC,QAAQ,CAId;IAEF;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAe3B,OAAO,CAAC,eAAe,CAA+B;IAEtD,OAAO,CAAC,QAAQ;CAMnB"}
@@ -0,0 +1,3 @@
1
+ export { AparteSidebar } from './aparte-sidebar.js';
2
+ export type { AparteSidebarToggleDetail } from './aparte-sidebar.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/sidebar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,354 @@
1
+ /** Detail of `aparte-split-resize`: the position that settled, and what settled it. */
2
+ export interface AparteSplitResizeDetail {
3
+ /** The achieved size of the primary pane, as a percentage of the container. */
4
+ position: number;
5
+ /** The primary pane is folded to its minimum. */
6
+ collapsed: boolean;
7
+ /** The split is under its breakpoint and showing one pane. */
8
+ stacked: boolean;
9
+ /** Which pane is shown while stacked. */
10
+ pane: 'start' | 'end';
11
+ /** The container's axis, as the `orientation` attribute names it. */
12
+ orientation: 'horizontal' | 'vertical';
13
+ /** What moved it: a drag, a key, or the host setting the property. */
14
+ source: 'pointer' | 'keyboard' | 'api';
15
+ }
16
+ /**
17
+ * Two panes and a draggable seam — a chat beside a preview, an editor, an artifact card.
18
+ *
19
+ * The grid is the mechanism: `--aparte-split-position` is the primary pane's size and
20
+ * the min/max are CSS clamp bounds, so the browser clamps and nothing here parses a
21
+ * unit. The element adds only what CSS cannot do — the drag, the arrow keys, the ARIA
22
+ * of an APG window splitter, and one pane at a time under a breakpoint. Without the
23
+ * element the `.aparte-split` recipe is still a split; it just does not move.
24
+ *
25
+ * It stores nothing: `position` in, one `aparte-split-resize` out on commit. The
26
+ * attribute is written on COMMIT only — a release, a key up, a double-click, a property
27
+ * set — and the live value during a drag travels on the custom property, so a
28
+ * framework's reconciler is not in the drag loop. Persist from the event; restore by
29
+ * setting `position`.
30
+ *
31
+ * A pane CONTAINS a chat; a chat never contains a split.
32
+ *
33
+ * `aria-orientation` on the handle is the INVERSE of this element's `orientation`: the
34
+ * attribute names the SEPARATOR's own axis, which is what the APG means by "Left Arrow
35
+ * moves a vertical splitter" and what ARIA 1.2 means by the attribute. Do not "fix" it —
36
+ * consumers style against it.
37
+ *
38
+ * Shift + an arrow is ±10%. That is an ecosystem convention, not the APG, which
39
+ * specifies the single step alone.
40
+ *
41
+ * @element aparte-split
42
+ *
43
+ * @attr {number} position - The primary pane's size, as a percentage of the container. Reflected on commit, never per drag frame.
44
+ * @attr {string} orientation - `horizontal` (panes side by side, the default) or `vertical` (stacked). Names the CONTAINER's axis.
45
+ * @attr {string} primary - `start` (default) or `end`: which pane `position` sizes.
46
+ * @attr {boolean} collapsed - The primary pane folded to its minimum. Enter on the seam toggles it; a second Enter restores the size it had.
47
+ * @attr {string} breakpoint - Below this width the split shows one pane at a time. A length (default `48rem`), or `none` to never stack.
48
+ * @attr {string} pane - `start` (default) or `end`: which pane is shown while stacked.
49
+ * @attr {boolean} disabled - No drag, no keys, no tab stop; the seam stays drawn.
50
+ * @attr {string} label - The seam's accessible name. Defaults to the locale's `splitHandleLabel`.
51
+ * @attr {boolean} data-stacked - Written BY the element while one pane is shown. Read-only; style against it.
52
+ *
53
+ * @fires {CustomEvent<AparteSplitResizeDetail>} aparte-split-resize - The position settled: after a drag, a key, a double-click or a property set. Never during a drag — persist from here.
54
+ *
55
+ * @cssprop [--aparte-split-position=38%] - The primary pane's size.
56
+ * @cssprop [--aparte-split-min=20rem] - Floor of the primary pane. Any length or percentage.
57
+ * @cssprop [--aparte-split-max=60%] - Ceiling of the primary pane.
58
+ * @cssprop [--aparte-split-handle-size=4px] - The visible seam.
59
+ * @cssprop [--aparte-split-hit-area=12px] - The invisible grab zone around it. Grows to the touch target on a coarse pointer.
60
+ *
61
+ * @example
62
+ * <!-- The chat in one pane, your own in the other. Drag the seam, or tab to it and use
63
+ * the arrows; double-click resets it. `--aparte-split-min` is a CSS length, so the
64
+ * chat cannot be dragged narrower than 16rem whatever the percentage says. Under
65
+ * 48rem of window the split shows one pane, and the buttons switch it. -->
66
+ * <div class="aparte-app-header">
67
+ * <button class="aparte-btn aparte-btn--sm aparte-btn--surface" type="button" data-aparte-split-pane="start">Chat</button>
68
+ * <button class="aparte-btn aparte-btn--sm aparte-btn--surface" type="button" data-aparte-split-pane="end">Preview</button>
69
+ * </div>
70
+ * <aparte-split position="38" style="height: 22rem; --aparte-split-min: 16rem">
71
+ * <aparte-chat>
72
+ * <aparte-chat-viewport></aparte-chat-viewport>
73
+ * <aparte-composer>
74
+ * <div class="aparte-composer-shell">
75
+ * <div class="aparte-composer-row">
76
+ * <aparte-composer-input></aparte-composer-input>
77
+ * <aparte-composer-send></aparte-composer-send>
78
+ * </div>
79
+ * </div>
80
+ * </aparte-composer>
81
+ * </aparte-chat>
82
+ * <section class="aparte-split__pane">
83
+ * <iframe title="Preview" style="inline-size: 100%; block-size: 100%; border: 0" srcdoc="<h1>Your pane</h1>"></iframe>
84
+ * </section>
85
+ * </aparte-split>
86
+ * <script>
87
+ * document.querySelector('aparte-split').addEventListener('aparte-split-resize', (e) => {
88
+ * localStorage.setItem('split', String(e.detail.position));
89
+ * });
90
+ * </script>
91
+ */
92
+ export declare class AparteSplit extends HTMLElement {
93
+ static get observedAttributes(): string[];
94
+ private _handle;
95
+ private _scrim;
96
+ private _media;
97
+ private _observer;
98
+ /** The pending `_measureBounds()` from a resize, batched to one per frame. */
99
+ private _measureRafId;
100
+ /** The host size the last resize tick measured, so an unchanged one does nothing. */
101
+ private _observedPx;
102
+ /** Ids for the panes `aria-controls` names — a counter, the way the primitives do it. */
103
+ private static _paneIdSeq;
104
+ /** The live position. The attribute holds it only after a commit. */
105
+ private _position;
106
+ /** What `reset()` — and a double-click on the seam — goes back to. */
107
+ private _initialPosition;
108
+ /**
109
+ * `_initialPosition` has been taken from the markup once. A re-parent runs
110
+ * `connectedCallback` again, and by then the attribute holds the LAST COMMIT, not
111
+ * what the author wrote: capturing a second time makes a framework re-render, a tab
112
+ * switch or a drag-and-drop of the panel redefine what "reset" means.
113
+ */
114
+ private _initialCaptured;
115
+ /** The size the primary pane had before it was collapsed, for the second Enter. */
116
+ private _preCollapsePosition;
117
+ /** Committed values, so a reflection of our own does not read as a host's change. */
118
+ private _lastPosition;
119
+ private _lastCollapsed;
120
+ private _lastPane;
121
+ /** What an attribute-driven commit blames. Raised around a key that changes state. */
122
+ private _source;
123
+ /**
124
+ * `connectedCallback` has run and the element knows what its markup asked for.
125
+ *
126
+ * Not `isConnected`: during an UPGRADE the element is already in the document, so
127
+ * `attributeChangedCallback` fires for every authored attribute — connected, and
128
+ * before `connectedCallback` — which is the ordinary case for a server-rendered
129
+ * `<aparte-split position="38">` upgraded when the module loads. Committing there
130
+ * measures a layout the element has not set up yet (no `data-stacked`, so on a
131
+ * phone the probe reads the stacked pane and writes `position="84"`), reflects that
132
+ * over the authored number, and sends it to whatever the host persists.
133
+ */
134
+ private _ready;
135
+ private _dragging;
136
+ private _captured;
137
+ /** The gesture actually moved the seam. A press that did not commits nothing. */
138
+ private _moved;
139
+ private _pointerId;
140
+ private _dragStartPercent;
141
+ private _dragOriginPx;
142
+ private _dragContainerPx;
143
+ /** A key is down and has moved the seam; its keyup is the commit. */
144
+ private _keying;
145
+ /** The primary pane's size, as a percentage of the container. Setting it commits. */
146
+ get position(): number;
147
+ set position(value: number);
148
+ /** The container's axis: `horizontal` (side by side) or `vertical` (stacked). */
149
+ get orientation(): 'horizontal' | 'vertical';
150
+ set orientation(value: 'horizontal' | 'vertical');
151
+ /** Which pane `position` sizes. */
152
+ get primary(): 'start' | 'end';
153
+ set primary(value: 'start' | 'end');
154
+ /** The primary pane is folded to its minimum. */
155
+ get collapsed(): boolean;
156
+ set collapsed(value: boolean);
157
+ /** Which pane is shown while the split is stacked. */
158
+ get pane(): 'start' | 'end';
159
+ set pane(value: 'start' | 'end');
160
+ /** No drag, no keys, no tab stop. The seam stays drawn. */
161
+ get disabled(): boolean;
162
+ set disabled(value: boolean);
163
+ /**
164
+ * True while the split is showing one pane. Read-only.
165
+ *
166
+ * Both routes into that state count. `data-stacked` is the one this element writes
167
+ * from its own breakpoint; `.aparte-split--only-start` / `--only-end` are the CSS
168
+ * route a host takes when it owns its breakpoints and sets `breakpoint="none"`. The
169
+ * sheet gives the two byte-identical rules, so the element has to read them the same
170
+ * way — every guard downstream keys on this getter, and a split stacked by the class
171
+ * alone would measure a one-track grid and commit `position="100"`.
172
+ */
173
+ get stacked(): boolean;
174
+ /** Fold the primary pane to its minimum, remembering the size it had. */
175
+ collapse(): void;
176
+ /** Unfold it, back to the size it had before it collapsed. */
177
+ expand(): void;
178
+ toggleCollapse(): void;
179
+ /** Show one pane, which only has a visible effect while the split is stacked. */
180
+ showPane(which: 'start' | 'end'): void;
181
+ /**
182
+ * Back to the position the split was FIRST connected with — a re-parent restores
183
+ * that, it does not redefine it. What a double-click on the seam does.
184
+ */
185
+ reset(): void;
186
+ connectedCallback(): void;
187
+ disconnectedCallback(): void;
188
+ attributeChangedCallback(name: string): void;
189
+ /**
190
+ * The seam. An author-written `.aparte-split__handle` is ADOPTED — a second one
191
+ * would be a second tab stop drawn over the first — otherwise one is inserted
192
+ * between the first two children, which is where a two-pane grid needs it.
193
+ *
194
+ * An adopted one is MOVED there if the author put it elsewhere. The sheet is
195
+ * positional — three tracks with the seam in the middle, and the stacked rules hide
196
+ * `:nth-child(1)` / `:nth-child(3)` — so a handle written first would take the
197
+ * primary pane's track and make stacking hide the wrong child.
198
+ */
199
+ private _ensureHandle;
200
+ /** The panes: every element child that is not the seam. */
201
+ private _panes;
202
+ private _primaryPane;
203
+ /**
204
+ * The APG's window splitter, plus the two states that take it out of the tab order.
205
+ *
206
+ * `aria-orientation` is the INVERSE of `orientation`: the attribute names the
207
+ * separator's own axis, so a split whose panes sit side by side has a VERTICAL
208
+ * separator between them.
209
+ */
210
+ private _stampHandle;
211
+ private _measure;
212
+ /**
213
+ * What the pane ACTUALLY got, which is not what was asked for: the CSS clamp between
214
+ * `--aparte-split-min` and `--aparte-split-max` has the last word, and announcing the
215
+ * requested value instead is how a splitter comes to tell a screen reader 5% while
216
+ * the pane sits at 22%. Without layout (jsdom, `display: none`, before first paint)
217
+ * the request is all there is, so it stands.
218
+ *
219
+ * While STACKED there is nothing to read: one pane is `display: none` and the other
220
+ * spans the single track, so the ratio is 0 or 100 whatever the seam was set to.
221
+ * Measuring it there is how tapping "Preview" on a phone used to write `position="0"`
222
+ * into the attribute, the event and the host's storage.
223
+ */
224
+ private _achievedPercent;
225
+ /**
226
+ * The range the seam can actually reach, written onto the separator: park the pane
227
+ * at 0% and read it, park it at 100% and read it, put the position back. Two forced
228
+ * layouts in one synchronous task, so nothing paints in between.
229
+ *
230
+ * It also reconciles `aria-valuenow`, because the two have to be one story: the
231
+ * requested percentage can sit outside the clamped range the probe just announced —
232
+ * with a `--aparte-split-min` of `20rem`, `position="38"` on a 700px container asks
233
+ * for 38 and gets ~46 — and a separator whose value is below its own minimum is the
234
+ * unclamped-announcement bug this probe exists to prevent, just at rest. `_position`
235
+ * is left alone: it is the REQUESTED value, and `reset()` means it.
236
+ *
237
+ * Gated on `!_dragging`: a ResizeObserver tick mid-gesture would move the pane to
238
+ * both ends under the pointer. Gated on `!stacked` for the reason
239
+ * `_achievedPercent()` is: a pane that spans everything measures the same at 0% and
240
+ * at 100%, which would announce a range of one number.
241
+ */
242
+ private _measureBounds;
243
+ /**
244
+ * Re-measure when the container's size changes — and only then. The probe writes the
245
+ * host's `style` three times, and the reflection is commit-only precisely because a
246
+ * `MutationObserver({ attributes: true })` (the docs' preview frame has one) reposts
247
+ * a frame height per mutation, which resizes the split, which re-ticks this observer.
248
+ * So: ignore a tick that did not move the size, and batch the rest to one per frame.
249
+ */
250
+ private _watchSize;
251
+ private _setLive;
252
+ /**
253
+ * The commit: reflect, announce, dispatch — once. Everything downstream reads the
254
+ * ACHIEVED size, so the attribute, `aria-valuenow` and the detail are one number.
255
+ *
256
+ * There is no per-frame event on purpose. A bubbling, composed CustomEvent per
257
+ * pointermove is a reconciler in the drag loop, and no pane in this repo re-lays
258
+ * itself out in JS — they resize in CSS. The trigger for adding
259
+ * `aparte-split-resizing` is a consumer whose pane needs a JS measurement mid-drag.
260
+ */
261
+ private _commit;
262
+ /** The computed direction, never `document.dir`: a host can flip one subtree. */
263
+ private _rtl;
264
+ private _onPointerDown;
265
+ /**
266
+ * Only the pointer that started the gesture. On a hybrid device a hovering pen or a
267
+ * stray touch delivers a `pointermove` with `buttons === 0`, which would otherwise
268
+ * fall into the release branch below and end someone else's mouse drag.
269
+ */
270
+ private _isOurPointer;
271
+ private _onPointerMove;
272
+ private _onPointerUp;
273
+ private _onPointerCancel;
274
+ private _endDrag;
275
+ private _releasePointer;
276
+ /**
277
+ * The drag overlay: a fixed, transparent child of the HANDLE, alive for one gesture.
278
+ * Topmost, so it swallows an iframe pane's hit-testing — the case this exists for —
279
+ * and paints the drag cursor across the page. A child of the handle rather than of
280
+ * the body so `click`, and therefore `dblclick`, still dispatches at the handle.
281
+ */
282
+ private _addScrim;
283
+ /**
284
+ * Take the overlay off.
285
+ *
286
+ * `retire` is the press that never moved — the one a click, and then a double-click,
287
+ * is built from. Its release happened ON the scrim (nothing captured the pointer
288
+ * yet), and WebKit works out what a click hit by walking the pointerup target's LIVE
289
+ * ancestors: take the node out here and that chain is rooted nowhere, so no `click`
290
+ * fires at all, no `dblclick` follows, and the seam never resets. Chromium and Gecko
291
+ * resolve the target before dispatch and do not care.
292
+ *
293
+ * So a retired scrim goes INERT immediately — `pointer-events: none`, which is what
294
+ * actually matters, since a full-page overlay left hit-testable is a page dead to the
295
+ * pointer — and leaves the document a moment later. Not on the next task: a first
296
+ * measurement removed it there and it still raced the click under a loaded machine
297
+ * (the trace is in `e2e/tests/layout.spec.ts`). The reference is dropped either way,
298
+ * so the next press builds its own; an inert one on its way out costs nothing.
299
+ *
300
+ * Teardown never retires: `disconnectedCallback` takes the live one out at once.
301
+ */
302
+ private _removeScrim;
303
+ private _onDoubleClick;
304
+ private _onKeydown;
305
+ /**
306
+ * The keyup commits, not the keydown: a held arrow repeats, and one release should
307
+ * write one attribute and send one event, not thirty.
308
+ */
309
+ private _onKeyup;
310
+ /**
311
+ * The other end of a key step. If focus leaves the seam while the key is still down —
312
+ * alt-tab, a click into a pane, a host moving focus — the keyup never arrives, and
313
+ * the pane would stay where the keydown put it while the attribute and
314
+ * `aria-valuenow` kept the old number for good. What is rendered is what commits.
315
+ */
316
+ private _onFocusOut;
317
+ /**
318
+ * The stacking query, from the `breakpoint` attribute: a length (`48rem`, the
319
+ * default, or `640px`), or `none` for a split that stays two panes at any width —
320
+ * which a documentation frame needs and a host with its own breakpoint wants.
321
+ */
322
+ private _watchBreakpoint;
323
+ private _onMediaChange;
324
+ /**
325
+ * Entering the stacked state shows the START pane: the chat, never a preview of
326
+ * nothing — the same judgement that makes the sidebar's drawer enter closed. Unless
327
+ * the markup already named one, which is an answer to the same question and a better
328
+ * one. Leaving it restores both panes, and with them the seam and its tab stop.
329
+ *
330
+ * `was` is the ATTRIBUTE, not the `stacked` getter: the getter also counts
331
+ * `.aparte-split--only-*`, the CSS route a host takes when it owns its breakpoints
332
+ * and sets `breakpoint="none"`. Read through the getter, that mount looks like a
333
+ * split leaving a stacked state it never entered — and the `pane` the author wrote
334
+ * is deleted on the way in.
335
+ */
336
+ private _applyStacked;
337
+ /**
338
+ * A `[data-aparte-split-pane]` anywhere on the page switches a split's pane, so a
339
+ * two-button toggle in a header needs no script.
340
+ *
341
+ * The value is `start` or `end` — the pane to show. Any other non-empty value names
342
+ * a split's `id` and TOGGLES that one; empty toggles the nearest split, else the
343
+ * first on the page. Same shape as `[data-aparte-sidebar-toggle]`.
344
+ */
345
+ private _onDocumentClick;
346
+ private _onConfigChange;
347
+ /**
348
+ * The seam's accessible name. A host that wrote its own `aria-label` — or an
349
+ * `aria-labelledby` pointing at a heading — keeps it: `data-own-label` marks the
350
+ * one we set, so a language switch replaces ours and never theirs.
351
+ */
352
+ private _relabel;
353
+ }
354
+ //# sourceMappingURL=aparte-split.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aparte-split.d.ts","sourceRoot":"","sources":["../../../src/components/split/aparte-split.ts"],"names":[],"mappings":"AAGA,uFAAuF;AACvF,MAAM,WAAW,uBAAuB;IACpC,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,OAAO,EAAE,OAAO,CAAC;IACjB,yCAAyC;IACzC,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IACtB,qEAAqE;IACrE,WAAW,EAAE,YAAY,GAAG,UAAU,CAAC;IACvC,sEAAsE;IACtE,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;CAC1C;AAsBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AACH,qBAAa,WAAY,SAAQ,WAAW;IACxC,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,SAAS,CAA+B;IAChD,8EAA8E;IAC9E,OAAO,CAAC,aAAa,CAAuB;IAC5C,qFAAqF;IACrF,OAAO,CAAC,WAAW,CAAK;IAExB,yFAAyF;IACzF,OAAO,CAAC,MAAM,CAAC,UAAU,CAAK;IAE9B,qEAAqE;IACrE,OAAO,CAAC,SAAS,CAAoB;IACrC,sEAAsE;IACtE,OAAO,CAAC,gBAAgB,CAAoB;IAC5C;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB,CAAS;IACjC,mFAAmF;IACnF,OAAO,CAAC,oBAAoB,CAAuB;IAEnD,qFAAqF;IACrF,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,SAAS,CAAgC;IAEjD,sFAAsF;IACtF,OAAO,CAAC,OAAO,CAA4C;IAE3D;;;;;;;;;;OAUG;IACH,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,iFAAiF;IACjF,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,gBAAgB,CAAK;IAC7B,qEAAqE;IACrE,OAAO,CAAC,OAAO,CAAS;IAIxB,qFAAqF;IACrF,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,MAAM,EAMzB;IAED,iFAAiF;IACjF,IAAI,WAAW,IAAI,YAAY,GAAG,UAAU,CAE3C;IAED,IAAI,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,EAE/C;IAED,mCAAmC;IACnC,IAAI,OAAO,IAAI,OAAO,GAAG,KAAK,CAE7B;IAED,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,EAEjC;IAED,iDAAiD;IACjD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;IAED,sDAAsD;IACtD,IAAI,IAAI,IAAI,OAAO,GAAG,KAAK,CAE1B;IAED,IAAI,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,EAE9B;IAED,2DAA2D;IAC3D,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,OAAO,EAE1B;IAED;;;;;;;;;OASG;IACH,IAAI,OAAO,IAAI,OAAO,CAMrB;IAID,yEAAyE;IACzE,QAAQ,IAAI,IAAI;IAIhB,8DAA8D;IAC9D,MAAM,IAAI,IAAI;IAId,cAAc,IAAI,IAAI;IAItB,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI;IAItC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAQb,iBAAiB,IAAI,IAAI;IAyDzB,oBAAoB,IAAI,IAAI;IA0B5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAsD5C;;;;;;;;;OASG;IACH,OAAO,CAAC,aAAa;IAmBrB,2DAA2D;IAC3D,OAAO,CAAC,MAAM;IAMd,OAAO,CAAC,YAAY;IAKpB;;;;;;OAMG;IACH,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,QAAQ;IAKhB;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,cAAc;IAsBtB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,QAAQ;IAIhB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO;IAyBf,iFAAiF;IACjF,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,cAAc,CAoBpB;IAEF;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,cAAc,CAkCpB;IAEF,OAAO,CAAC,YAAY,CAElB;IAEF,OAAO,CAAC,gBAAgB,CAEtB;IAEF,OAAO,CAAC,QAAQ;IAwBhB,OAAO,CAAC,eAAe;IAevB;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IASjB;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,cAAc,CAGpB;IAIF,OAAO,CAAC,UAAU,CA+BhB;IAEF;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAKd;IAEF;;;;;OAKG;IACH,OAAO,CAAC,WAAW,CAIjB;IAIF;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,cAAc,CAAmE;IAEzF;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,aAAa;IAoBrB;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB,CAYtB;IAIF,OAAO,CAAC,eAAe,CAA+B;IAEtD;;;;OAIG;IACH,OAAO,CAAC,QAAQ;CASnB"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The split's arithmetic, with no DOM in it.
3
+ *
4
+ * Separate from the element on purpose: a pointer drag is the path jsdom exercises
5
+ * worst — it has no layout, no `PointerEvent` and no pointer capture — so the numbers
6
+ * are proven here, in plain functions a test can call, and the element is left with
7
+ * the listeners and the attributes.
8
+ *
9
+ * Nothing here parses a CSS unit. `--aparte-split-min` and `--aparte-split-max` are
10
+ * clamp bounds in the grid template, so the browser clamps the pane and this module
11
+ * only ever moves a percentage between 0 and 100.
12
+ */
13
+ /** One step of a drag: where it started, how far the pointer went, and along which axis. */
14
+ export interface SplitStep {
15
+ /** The primary pane's size when the gesture began, as a percentage of the container. */
16
+ startPercent: number;
17
+ /** How far the pointer has travelled since, in CSS pixels, along the split's axis. */
18
+ deltaPx: number;
19
+ /** The container's size along that same axis. */
20
+ containerPx: number;
21
+ /** The computed reading direction is right-to-left. Ignored on the vertical axis. */
22
+ rtl: boolean;
23
+ /** The split's orientation is `vertical` — the panes are stacked, the axis is the block one. */
24
+ vertical: boolean;
25
+ /**
26
+ * `primary="end"`: the sized track is the LAST one, so the seam's distance from the
27
+ * container's start is `100% - handle - position` and a bigger number moves the seam
28
+ * TOWARD the start. Without this the seam runs away from the pointer.
29
+ */
30
+ primaryEnd?: boolean;
31
+ }
32
+ /**
33
+ * The primary pane's new size, as a percentage of the container, clamped to 0..100.
34
+ *
35
+ * A right-to-left drag moves the other way: in `rtl` the start pane is on the right, so
36
+ * a pointer travelling in +x makes it smaller. The block axis never inverts — `rtl` is a
37
+ * writing direction, not a gravity — so it is ignored when `vertical`.
38
+ *
39
+ * `primaryEnd` inverts it too, and for a different reason: the pane being sized is the
40
+ * one the pointer moves AWAY from. The two inversions compose — an `rtl` split whose
41
+ * primary is the end pane reads like a plain one again — so they are XORed, not summed.
42
+ *
43
+ * A container of zero (measured before layout, or while display:none) yields the
44
+ * starting value rather than `Infinity`: the caller gets a number it can write back.
45
+ */
46
+ export declare function nextPosition(step: SplitStep): number;
47
+ /**
48
+ * How far a key moves the seam, in percentage points — or `null` for a key that is not
49
+ * ours, so the handler can leave the page's own scrolling alone.
50
+ *
51
+ * Shift is ×10. That is an ecosystem convention (Shoelace's `×10`, Zag's delta of 10),
52
+ * NOT the APG, which specifies only the single step: it is here because a 1% step across
53
+ * a 1600px window is 16px and nobody arrows a pane across a screen one percent at a time.
54
+ *
55
+ * Home and End are the extremes as ±100: the clamp in `nextPosition` — and then the CSS
56
+ * clamp in the grid — decide where that actually lands, so a `--aparte-split-min` of
57
+ * `20rem` means Home stops at 20rem without this function knowing what a rem is.
58
+ *
59
+ * `primaryEnd` mirrors the ARROWS only, for the same reason `nextPosition` mirrors the
60
+ * pointer: an arrow names a direction the SEAM travels in. Home and End name the primary
61
+ * pane's own extremes — its minimum is its minimum whichever end it sits at — so they are
62
+ * left alone.
63
+ */
64
+ export declare function keyDelta(key: string, shift: boolean, rtl: boolean, vertical: boolean, primaryEnd?: boolean): number | null;
65
+ //# sourceMappingURL=geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../../src/components/split/geometry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,4FAA4F;AAC5F,MAAM,WAAW,SAAS;IACtB,wFAAwF;IACxF,YAAY,EAAE,MAAM,CAAC;IACrB,sFAAsF;IACtF,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,GAAG,EAAE,OAAO,CAAC;IACb,gGAAgG;IAChG,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAQD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAOpD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CACpB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,OAAO,EACjB,UAAU,UAAQ,GACnB,MAAM,GAAG,IAAI,CAYf"}
@@ -0,0 +1,3 @@
1
+ export { AparteSplit } from './aparte-split.js';
2
+ export type { AparteSplitResizeDetail } from './aparte-split.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/split/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}