mnfst 0.5.234 → 0.5.236

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.234';
5
+ const MANIFEST_BUILD_VERSION = '0.5.236';
6
6
 
7
7
  /* Manifest Data Sources - Appwrite Integration */
8
8
 
@@ -0,0 +1,152 @@
1
+ /* Manifest Chat */
2
+
3
+ @layer base, components, utilities;
4
+
5
+ @layer utilities {
6
+
7
+ :where(.chat-wrapper) {
8
+ display: flex;
9
+ flex-direction: column;
10
+ width: 100%;
11
+ height: 100%;
12
+ overflow: hidden;
13
+
14
+ /* Chat log scroll container */
15
+ :where([role="log"]) {
16
+ display: flex;
17
+ flex-direction: column-reverse;
18
+ flex: 1;
19
+ font-size: 0.875rem;
20
+ overflow-y: auto;
21
+
22
+ /* Message column */
23
+ > :where(div) {
24
+ display: flex;
25
+ flex-direction: column;
26
+ justify-content: flex-end;
27
+ gap: 2rem;
28
+ min-height: 100%;
29
+ width: calc(var(--spacing-content-width, 74rem) - 4rem);
30
+ max-width: 100%;
31
+ margin-inline-start: auto;
32
+ margin-inline-end: auto;
33
+ padding-inline-start: 1rem;
34
+ padding-inline-end: 1rem;
35
+ padding-block-end: 3rem
36
+ }
37
+
38
+ /* Messages */
39
+ :where(div div) {
40
+
41
+ /* Markdown spacing */
42
+ :where(p) {
43
+ margin-block: 0.5rem
44
+ }
45
+
46
+ :where(p:first-child) {
47
+ margin-block-start: 0
48
+ }
49
+
50
+ :where(p:last-child) {
51
+ margin-block-end: 0
52
+ }
53
+ }
54
+
55
+ /* Own messages */
56
+ :where(.own) {
57
+ width: 95%;
58
+ max-width: calc(var(--spacing-content-width, 74rem) - 10rem);
59
+ margin-inline-start: auto;
60
+ padding-block: 0.5rem;
61
+ padding-inline: 0.75rem;
62
+ background: color-mix(in oklch, var(--color-surface-2) 50%, transparent);
63
+ border-radius: var(--radius)
64
+ }
65
+
66
+ /* Attachments */
67
+ :where(img, video) {
68
+ display: block;
69
+ max-width: 20rem;
70
+ max-height: 15rem;
71
+ margin-block: 0.5rem;
72
+ border-radius: var(--radius)
73
+ }
74
+
75
+ :where(audio) {
76
+ display: block;
77
+ width: 18rem;
78
+ max-width: 100%;
79
+ margin-block: 0.5rem
80
+ }
81
+
82
+ :where(a[download]) {
83
+ display: inline-flex;
84
+ align-items: center;
85
+ gap: 0.4rem;
86
+ margin-block: 0.5rem;
87
+ padding-block: 0.35rem;
88
+ padding-inline: 0.6rem;
89
+ background: var(--color-surface-2);
90
+ border-radius: var(--radius)
91
+ }
92
+ }
93
+
94
+ /* Chat input */
95
+ :where(form:not(.unstyle)) {
96
+ display: flex;
97
+ flex-flow: row wrap;
98
+ align-items: end;
99
+ gap: 0;
100
+ width: var(--spacing-content-width, 74rem);
101
+ max-width: 100%;
102
+ margin-inline-start: auto;
103
+ margin-inline-end: auto;
104
+
105
+ :where(textarea, .textarea):not(.unstyle) {
106
+ flex: 1;
107
+ width: auto;
108
+ min-height: var(--spacing-field-height, 2.5rem);
109
+ field-sizing: content;
110
+ resize: none
111
+ }
112
+ }
113
+
114
+ /* Pending attachments */
115
+ :where(output:not(.unstyle)) {
116
+ display: flex;
117
+ flex-flow: row wrap;
118
+ gap: 0.325rem;
119
+ width: 100%;
120
+ max-width: 100%;
121
+ height: fit-content;
122
+ padding: calc(var(--spacing) * 2);
123
+
124
+ > :where(:not(template)) {
125
+ position: relative;
126
+ flex: 0 0 auto
127
+ }
128
+
129
+ /* Images */
130
+ :where(img) {
131
+ display: block;
132
+ width: var(--spacing-field-height, 2.5rem);
133
+ height: var(--spacing-field-height, 2.5rem);
134
+ object-fit: cover;
135
+ border-radius: calc(var(--radius, 0.5rem) * 0.75)
136
+ }
137
+
138
+ /* File chips */
139
+ > :where(:not(template))> :where(span) {
140
+ display: flex;
141
+ align-items: center;
142
+ gap: 0.3rem;
143
+ height: fit-content;
144
+ padding-inline: 0.5rem;
145
+ font-size: 0.75rem;
146
+ white-space: nowrap;
147
+ background: var(--color-line);
148
+ border-radius: calc(var(--radius, 0.5rem) * 0.75)
149
+ }
150
+ }
151
+ }
152
+ }
@@ -2,7 +2,7 @@
2
2
 
3
3
  (function () {
4
4
 
5
- const MANIFEST_BUILD_VERSION = '0.5.234';
5
+ const MANIFEST_BUILD_VERSION = '0.5.236';
6
6
 
7
7
  /* Manifest Data Sources - Configuration */
8
8
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "manifest.appwrite.auth.js": "sha384-dsIWnH0qCAGSzAXMGrd8fvOrVl4tOIE6j5tC35JPTrQXZ56qLD36ARyvhR7vi3Id",
3
- "manifest.appwrite.data.js": "sha384-pj/2ZCUMXz3zTWPZyICJHfCPnz5srho9URrw0Sl0nfWuvh5KqvoT/g3Kg4uyv7yl",
3
+ "manifest.appwrite.data.js": "sha384-XmiMot6d4B5dZk6/UlO2ex93ArmIWQeB1XWFYhhHoxhalUuBIvBonyto6hkegwZU",
4
4
  "manifest.appwrite.presences.js": "sha384-JyVDWFT69b7Svq8J8p9tNWe2v9PZNQBY5UyhtOl1vnuHFAX0CRQ3MA9SiKq5wzNh",
5
5
  "manifest.bindings.js": "sha384-lPtMf8Ykaic9gNVZKq8Scia1881ZeMAyxer3WCIkUNwwrgzGBWto1OXADUwjvORF",
6
6
  "manifest.charts.js": "sha384-gEAv/98+29RbhvNkiNWTNyBPbLTFr2Ld15wLu29FLCL57j1cwGChRrL9Pfk7dBtT",
@@ -11,7 +11,7 @@
11
11
  "manifest.combobox.js": "sha384-MILTkrgsTzsYUjGo4ZuADqV85Xs4GmfB4xexfe9vbJMIoQTZ42W4zs+DTaVSPEsx",
12
12
  "manifest.components.js": "sha384-JalISaBBWNFl3ggx92Hb3B52EpwwG3gzgra6Q+js0OgZ8vrFKMD48CuBox2N9A5T",
13
13
  "manifest.computed.js": "sha384-GYML/e81gQfN+iDbqhPUgny8bINCyL+SrbTofoGk4hlCnLLjv51mCv42JMqq+ku5",
14
- "manifest.data.js": "sha384-+wRqEd8FFPqaSX5gZhb66OgkAHTiSQDFK6W1agFMceKtd5nVL7OLh6p5gC96AJ3Z",
14
+ "manifest.data.js": "sha384-FxpJUmH7kVnRqTpehhWHCxUYVW6AWuv50jxN+qZe9T5l4W0hvmr7BD+ubj42CGAo",
15
15
  "manifest.datepicker.js": "sha384-XnbeURni2X91ozVzatQcSjYYIS4MoW12dBRJnYAGBr0nCQ624heH5s+xtQSpLZX6",
16
16
  "manifest.defer.js": "sha384-pMRGqQKiEoJhpUcD40QeM4jEHau7sz9Xn/YCpiUamT1T4xJBZDSiYX+xnVrSWoq+",
17
17
  "manifest.device.js": "sha384-g+txmrEszYtuOvRelTp/c1wSNR2AtllVI9rx5NPPD7DzhVUnMNughonZykv2xlBW",
@@ -23,12 +23,12 @@
23
23
  "manifest.markdown.js": "sha384-heyDR40LXHaAmAuA+fa381uFwShk1oAqpFFY6E2Qq4T3VN0TQfRqyc++MF40K5Hj",
24
24
  "manifest.native.js": "sha384-g+txmrEszYtuOvRelTp/c1wSNR2AtllVI9rx5NPPD7DzhVUnMNughonZykv2xlBW",
25
25
  "manifest.payments.js": "sha384-8pofk2zhxtapPMpwnFyTelPMrYhShNhDCE722uQh/EYFvZFuPLmSdgunqsarVQjv",
26
- "manifest.rich.text.js": "sha384-yJNb+EIumFIJx2KiKmLojwyHLCKwIn+48noxh3gUuZ10YZOvJJoanzAU7NLIBF1s",
26
+ "manifest.rich.text.js": "sha384-SeqwIXW01/FD39kMHLjCMaFKheVK/JxHOR/eDkePhvgaFH8Rl2y3mzZoqHuu8UH8",
27
27
  "manifest.router.js": "sha384-QkKhRaCbdXEOxhj+ojT4jeLUCtQepBnqP+QWTIWdb6kUWD+mVzPN8hf6jhgschpW",
28
28
  "manifest.slides.js": "sha384-3uRTkyK9XPLmnxI2+igZlpi4EyPlU/7IHj5j3BZJJ2KN455vXyk99fiXV3feO/XY",
29
29
  "manifest.status.js": "sha384-MBO345ab7H6Uq1X2dZLt4Ge1Gcra+Z2qYApvlAeIV8CJhDDJrz2FPXpp+Kcp8zcM",
30
30
  "manifest.svg.js": "sha384-qr/8H9+2cIhSXNbRWRtIdrDlTOxKlNJqwEefHvCYoiBNW/kKhPTFa109Orv/EBnb",
31
- "manifest.sw.js": "sha384-alPjmWaugQV/aCb6l7hVITwZ6Z5k47SJ9jHXmNUN093iUu8ikbVggwLSGNb84Ib1",
31
+ "manifest.sw.js": "sha384-gc7W73Hluo/LQjOFCKrEpEkrBEkMKsOzRgzRQ00UkO00WuEZkTQUHB3rE9qGTWHv",
32
32
  "manifest.tabs.js": "sha384-OIIcyaQnGS0eNYk4zgAFEDboNYect7THvUd9D0V6nqCeDOxQcoiqLrBEmmWVTTet",
33
33
  "manifest.tailwind.js": "sha384-r/Jvqb+Piz21jUts10BbVAJoKkShOdJRVFpywyi4HPIi/OfOJq5CtPyWAPbdkMgt",
34
34
  "manifest.toasts.js": "sha384-3zkWxzw693pxg3QDFsoYCA3CqYaLKmBaMArULXODD66Utolpewl0OAeTB92aWUVv",
@@ -0,0 +1,368 @@
1
+ /* Manifest Reset - browser style normalizer */
2
+
3
+ @layer base, components, utilities;
4
+
5
+ @layer base {
6
+
7
+ *,
8
+ ::after,
9
+ ::before,
10
+ ::backdrop,
11
+ ::file-selector-button {
12
+ box-sizing: border-box;
13
+ margin: 0;
14
+ padding: 0;
15
+ border: 0 solid
16
+ }
17
+
18
+ :where(:root) {
19
+ -webkit-tap-highlight-color: transparent;
20
+ -webkit-text-size-adjust: 100%;
21
+ -moz-text-size-adjust: 100%;
22
+ text-size-adjust: 100%;
23
+ text-rendering: optimizeLegibility;
24
+ overflow-wrap: break-word;
25
+ -moz-tab-size: 4;
26
+ -o-tab-size: 4;
27
+ tab-size: 4;
28
+
29
+ /* Device safe-area insets (0 unless viewport-fit=cover on a notched screen) */
30
+ --safe-top: env(safe-area-inset-top, 0px);
31
+ --safe-right: env(safe-area-inset-right, 0px);
32
+ --safe-bottom: env(safe-area-inset-bottom, 0px);
33
+ --safe-left: env(safe-area-inset-left, 0px)
34
+ }
35
+
36
+ :where(html),
37
+ :host {
38
+ width: 100vw;
39
+ max-width: 100vw;
40
+ overflow-x: hidden;
41
+ line-height: 1.5;
42
+ tab-size: 4;
43
+ font-family: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
44
+ font-feature-settings: normal;
45
+ font-variation-settings: normal;
46
+ -webkit-text-size-adjust: 100%;
47
+ -webkit-tap-highlight-color: transparent;
48
+ scroll-behavior: smooth;
49
+ -ms-overflow-style: none;
50
+ scrollbar-width: none;
51
+
52
+ &::-webkit-scrollbar {
53
+ display: none
54
+ }
55
+
56
+ &:has(dialog:popover-open) {
57
+ overflow: hidden
58
+ }
59
+ }
60
+
61
+ :where(body) {
62
+ max-width: 100vw;
63
+ min-height: 100vh;
64
+ margin: 0;
65
+ line-height: inherit
66
+ }
67
+
68
+ :where(a) {
69
+ color: inherit;
70
+ -webkit-text-decoration: inherit;
71
+ text-decoration: inherit;
72
+ }
73
+
74
+ :where(abbr[title]) {
75
+ -webkit-text-decoration: underline dotted;
76
+ text-decoration: underline dotted
77
+ }
78
+
79
+ :where([aria-controls]) {
80
+ cursor: pointer
81
+ }
82
+
83
+ :where([aria-hidden=false][hidden]) {
84
+ display: initial
85
+ }
86
+
87
+ :where([aria-hidden=false][hidden]:not(:focus)) {
88
+ clip: rect(0, 0, 0, 0);
89
+ position: absolute
90
+ }
91
+
92
+ :where(audio:not([controls])) {
93
+ display: none;
94
+ height: 0
95
+ }
96
+
97
+ :where(b, strong) {
98
+ font-weight: bolder
99
+ }
100
+
101
+ :where(button, input, optgroup, select, textarea) {
102
+ margin: 0;
103
+ padding: 0;
104
+ font-family: inherit;
105
+ font-feature-settings: inherit;
106
+ font-variation-settings: inherit;
107
+ font-size: 100%;
108
+ font-weight: inherit;
109
+ line-height: inherit;
110
+ letter-spacing: inherit;
111
+ color: inherit
112
+ }
113
+
114
+ :where(button, select) {
115
+ text-transform: none
116
+ }
117
+
118
+ :where(button, input:where([type='button'], [type='reset'], [type='submit']), ::file-selector-button) {
119
+ appearance: button;
120
+ background-color: transparent;
121
+ background-image: none
122
+ }
123
+
124
+ :where(::-webkit-file-upload-button) {
125
+ -webkit-appearance: button;
126
+ font: inherit
127
+ }
128
+
129
+ :where(::-webkit-inner-spin-button, ::-webkit-outer-spin-button) {
130
+ height: auto
131
+ }
132
+
133
+ :where(::-webkit-search-decoration) {
134
+ -webkit-appearance: none
135
+ }
136
+
137
+ :where(button, [role=button]) {
138
+ cursor: pointer
139
+ }
140
+
141
+ :where(code, samp, pre) {
142
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
143
+ font-size: 1em;
144
+ font-feature-settings: normal;
145
+ font-variation-settings: normal;
146
+ }
147
+
148
+ :where([dir=rtl]) {
149
+ direction: rtl
150
+ }
151
+
152
+ :where([disabled], :disabled, [aria-disabled=true], .disabled) {
153
+ opacity: .5;
154
+ cursor: default;
155
+ pointer-events: none
156
+ }
157
+
158
+ :where(figcaption) {
159
+ font-size: 75%
160
+ }
161
+
162
+ :where(figure) {
163
+ display: block;
164
+ padding: 0
165
+ }
166
+
167
+ :where(::file-selector-button) {
168
+ margin-inline-end: 4px
169
+ }
170
+
171
+ :where(h1, h2, h3, h4, h5, h6) {
172
+ font-size: inherit;
173
+ font-weight: inherit
174
+ }
175
+
176
+ :where(hr) {
177
+ height: 1px;
178
+ color: inherit;
179
+ background-color: var(--color-line, color-mix(in oklch, oklch(20.5% 0 0) 12%, transparent));
180
+ border: 0 none
181
+ }
182
+
183
+ :where(img, svg, video, canvas, audio, iframe, embed, object) {
184
+ display: block
185
+ }
186
+
187
+ :where(img, video) {
188
+ max-width: 100%;
189
+ height: auto
190
+ }
191
+
192
+ :where(::-webkit-autofill, :-webkit-autofill:focus) {
193
+ transition: background-color 0s 600000s, color 0s 600000s
194
+ }
195
+
196
+ :where(::-webkit-date-and-time-value) {
197
+ min-height: 1lh;
198
+ text-align: inherit
199
+ }
200
+
201
+ :where(::-webkit-datetime-edit) {
202
+ display: inline-flex
203
+ }
204
+
205
+ :where(::-webkit-datetime-edit-fields-wrapper) {
206
+ padding: 0
207
+ }
208
+
209
+ :where(::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field) {
210
+ padding-block: 0
211
+ }
212
+
213
+ :where(select:is([multiple], [size])) optgroup {
214
+ font-weight: bolder
215
+ }
216
+
217
+ :where(select:is([multiple], [size])) optgroup option {
218
+ padding-inline-start: 20px
219
+ }
220
+
221
+ :where(small) {
222
+ font-size: 80%
223
+ }
224
+
225
+ :where(span) {
226
+ color: inherit
227
+ }
228
+
229
+ :where(sub, sup) {
230
+ font-size: 50%;
231
+ line-height: 0;
232
+ position: relative;
233
+ vertical-align: baseline
234
+ }
235
+
236
+ :where(sub) {
237
+ bottom: -0.25em
238
+ }
239
+
240
+ :where(sup) {
241
+ top: -0.5em
242
+ }
243
+
244
+ :where(svg):not([fill]) {
245
+ fill: currentColor
246
+ }
247
+
248
+ :where(svg):not(:root) {
249
+ overflow: hidden
250
+ }
251
+
252
+ :where(table) {
253
+ text-indent: 0;
254
+ border-color: inherit;
255
+ border-collapse: collapse
256
+ }
257
+
258
+ :-moz-focusring {
259
+ outline: auto
260
+ }
261
+
262
+ :-moz-ui-invalid {
263
+ box-shadow: none
264
+ }
265
+
266
+ :where(::placeholder) {
267
+ opacity: 1;
268
+ color: color-mix(in oklab, currentcolor 50%, transparent)
269
+ }
270
+
271
+ /* Animates `scale`, not `transform`: a transform animation with fill `both`
272
+ keeps its final value and would override any transform an author sets on
273
+ a popover of their own. */
274
+ @keyframes mnfst-popover-in {
275
+ from {
276
+ scale: .9;
277
+ }
278
+
279
+ to {
280
+ scale: 1;
281
+ }
282
+ }
283
+
284
+ :where([popover]):not(.unstyle):popover-open {
285
+ display: flex;
286
+ animation: mnfst-popover-in .15s ease-in both;
287
+ }
288
+
289
+ :where(progress) {
290
+ vertical-align: baseline
291
+ }
292
+
293
+ :where([type='search']) {
294
+ -webkit-appearance: textfield;
295
+ appearance: textfield;
296
+ outline-offset: -2px
297
+ }
298
+
299
+ :where(summary) {
300
+ display: list-item
301
+ }
302
+
303
+ :where(textarea) {
304
+ resize: vertical
305
+ }
306
+
307
+ [hidden],
308
+ [un-cloak],
309
+ [v-cloak],
310
+ [x-cloak] {
311
+ display: none
312
+ }
313
+
314
+ /* @ rule - font smoothing for iOS and Mac */
315
+ @media (-webkit-min-device-pixel-ratio: 2) {
316
+ :where(html) {
317
+ -webkit-font-smoothing: antialiased;
318
+ -moz-osx-font-smoothing: grayscale
319
+ }
320
+ }
321
+
322
+ /* @ rule - reduced motion */
323
+ @media (prefers-reduced-motion:reduce) {
324
+
325
+ :not([aria-busy=true]),
326
+ :not([aria-busy=true])::after,
327
+ :not([aria-busy=true])::before {
328
+ background-attachment: initial !important;
329
+ animation-duration: 1ms !important;
330
+ animation-delay: -1ms !important;
331
+ animation-iteration-count: 1 !important;
332
+ scroll-behavior: auto !important;
333
+ transition-delay: 0s !important;
334
+ transition-duration: 0s !important
335
+ }
336
+ }
337
+
338
+ /* @ rule - reverse animation direction for rtl mode */
339
+ @media (prefers-reduced-motion:no-preference) {
340
+ [dir=rtl] progress:indeterminate {
341
+ animation-direction: reverse
342
+ }
343
+ }
344
+
345
+ /* View transition styles */
346
+ ::view-transition-group(*) {
347
+ animation-duration: var(--view-transition-duration, 200ms);
348
+ animation-timing-function: var(--view-transition-easing, cubic-bezier(0.4, 0, 0.2, 1))
349
+ }
350
+
351
+ /* Skip view transition for live/non-rasterizable content */
352
+ iframe,
353
+ video,
354
+ canvas,
355
+ [data-no-view-transition] {
356
+ view-transition-name: none
357
+ }
358
+ }
359
+
360
+ /* Cross-document view transitions opt-in */
361
+ @view-transition {
362
+ navigation: auto
363
+ }
364
+
365
+ /* Unlayered on purpose: a closed popover must beat layer-based layout classes. */
366
+ [popover]:not(.unstyle):not(:popover-open) {
367
+ display: none;
368
+ }
@@ -987,6 +987,8 @@
987
987
  const have = (grid[r] || []).filter(Boolean).length;
988
988
  for (let i = have; i < width; i++) row.appendChild(emptyCell(rowCellTag(row)));
989
989
  });
990
+ const group = table.querySelector(':scope > colgroup');
991
+ if (group && group.children.length !== width) rebalanceCols(table);
990
992
  if (!table.querySelector('tbody, thead')) {
991
993
  const body = document.createElement('tbody');
992
994
  while (table.firstChild) body.appendChild(table.firstChild);
@@ -995,6 +997,43 @@
995
997
  });
996
998
  }
997
999
 
1000
+ // A table whose column widths were set by resizing keeps them adding up to 100% as its columns
1001
+ // change: an added column takes an equal share (the others scale down), a removed one's share
1002
+ // goes to all the others in proportion, and no column falls under the minimum. Tables without widths are left alone.
1003
+ function rebalanceCols(table, change) {
1004
+ const group = table.querySelector(':scope > colgroup'); if (!group) return;
1005
+ let w = [...group.children].map(c => /%$/.test(c.style.width) ? parseFloat(c.style.width) : NaN);
1006
+ if (!w.length || w.some(isNaN)) return;
1007
+ const n = columnCount(table);
1008
+ if (change && change.add != null) {
1009
+ const share = 100 / (w.length + 1);
1010
+ w = w.map(v => v * (100 - share) / 100);
1011
+ w.splice(Math.min(change.add, w.length), 0, share);
1012
+ } else if (change && change.remove != null && change.remove < w.length) {
1013
+ // its share goes to every remaining column, in proportion to its width
1014
+ const [gone] = w.splice(change.remove, 1), base = w.reduce((a, v) => a + v, 0);
1015
+ w = w.map(v => v + gone * (base ? v / base : 1 / w.length));
1016
+ }
1017
+ // Any other mismatch (merges, splits, padding): columns added at the end take equal shares, extras go
1018
+ while (w.length < n) { const share = 100 / (w.length + 1); w = w.map(v => v * (100 - share) / 100); w.push(share); }
1019
+ if (w.length > n) { const extra = w.splice(n).reduce((a, b) => a + b, 0); if (w.length) w[w.length - 1] += extra; }
1020
+ if (!w.length) return;
1021
+ // The minimum, taken from the widest columns
1022
+ const px = table.getBoundingClientRect().width, min = px ? MIN_COL / px * 100 : 0;
1023
+ if (min && min * w.length > 100) w = w.map(() => 100 / w.length); // too narrow for the minimum: equal shares
1024
+ else if (min) {
1025
+ for (let guard = 0; guard < 20 && w.some(v => v < min - 1e-6); guard++) {
1026
+ const need = w.reduce((a, v) => a + Math.max(0, min - v), 0), room = w.reduce((a, v) => a + Math.max(0, v - min), 0);
1027
+ w = w.map(v => v < min ? min : v - (v - min) / room * need);
1028
+ }
1029
+ }
1030
+ const total = w.reduce((a, b) => a + b, 0), pct = (v) => Math.round(v * 100) / 100;
1031
+ while (group.children.length < w.length) group.appendChild(document.createElement('col'));
1032
+ while (group.children.length > w.length) group.lastElementChild.remove();
1033
+ let used = 0;
1034
+ [...group.children].forEach((col, i) => { const v = i === w.length - 1 ? pct(100 - used) : pct(w[i] / total * 100); used += v; col.style.width = v + '%'; });
1035
+ }
1036
+
998
1037
  function addRow(where) {
999
1038
  const cell = cellAt(); if (!cell) return;
1000
1039
  const row = cell.parentElement, table = row.closest('table');
@@ -1016,6 +1055,7 @@
1016
1055
  fresh.appendChild(document.createElement('br'));
1017
1056
  if (where < 0) at.before(fresh); else at.after(fresh);
1018
1057
  });
1058
+ rebalanceCols(table, { add: where < 0 ? col : col + 1 });
1019
1059
  normalizeTables(table.parentElement || table);
1020
1060
  caretIn(cellCovering(rowsOf(table)[gridPosition(cell).row], where < 0 ? col : col + 1), 0);
1021
1061
  }
@@ -1035,6 +1075,7 @@
1035
1075
  if (columnCount(table) <= 1) return removeTable();
1036
1076
  const seen = new Set();
1037
1077
  grid.forEach(row => { const at = row[col]; if (!at || seen.has(at)) return; seen.add(at); at.remove(); });
1078
+ rebalanceCols(table, { remove: col });
1038
1079
  normalizeTables(table.parentElement || table);
1039
1080
  caretIn(cellCovering(rowsOf(table)[0], Math.max(0, col - 1)), 0);
1040
1081
  }
@@ -1172,21 +1213,34 @@
1172
1213
  Widths on a <colgroup>, heights on the row. */
1173
1214
  const EDGE = 5;
1174
1215
 
1175
- function ensureCols(table) {
1216
+ const MIN_COL = 28;
1217
+ // Each column's rendered width: a cell spanning it alone, else a spanning cell's share
1218
+ function columnWidths(table) {
1219
+ const grid = tableGrid(table), n = columnCount(table), out = [];
1220
+ for (let i = 0; i < n; i++) {
1221
+ let w = null;
1222
+ for (const row of grid) { const c = row[i]; if (c && (c.colSpan || 1) === 1) { w = c.getBoundingClientRect().width; break; } }
1223
+ if (w == null) { const c = grid.map(r => r[i]).find(Boolean); w = c ? c.getBoundingClientRect().width / (c.colSpan || 1) : 0; }
1224
+ out.push(w);
1225
+ }
1226
+ return out;
1227
+ }
1228
+ // Widths as percentages: of the table for its columns (they add up to 100%), and of the field
1229
+ // for the table, so what is stored is what renders, whatever width the field has
1230
+ function writeWidths(table, widths, tableWidth, fieldWidth) {
1176
1231
  let group = table.querySelector(':scope > colgroup');
1177
1232
  if (!group) { group = document.createElement('colgroup'); table.prepend(group); }
1178
- const want = columnCount(table);
1179
- while (group.children.length < want) group.appendChild(document.createElement('col'));
1180
- while (group.children.length > want) group.lastElementChild.remove();
1181
- // Freeze current widths so one drag doesn't reflow the rest
1233
+ while (group.children.length < widths.length) group.appendChild(document.createElement('col'));
1234
+ while (group.children.length > widths.length) group.lastElementChild.remove();
1235
+ const total = widths.reduce((a, b) => a + b, 0) || 1, pct = (v) => Math.round(v * 100) / 100;
1236
+ let used = 0;
1182
1237
  [...group.children].forEach((col, i) => {
1183
- if (col.style.width) return;
1184
- const at = (tableGrid(table)[0] || [])[i];
1185
- if (at) col.style.width = Math.round(at.getBoundingClientRect().width / (at.colSpan || 1)) + 'px';
1238
+ const v = i === widths.length - 1 ? pct(100 - used) : pct(widths[i] / total * 100);
1239
+ used += v; col.style.width = v + '%';
1186
1240
  });
1187
- return group;
1241
+ table.style.width = pct(Math.min(100, tableWidth / fieldWidth * 100)) + '%';
1242
+ table.style.tableLayout = 'fixed'; // stored widths are the rendered ones, with or without the plugin's stylesheet
1188
1243
  }
1189
-
1190
1244
  function borderAt(x, y) {
1191
1245
  const el = document.elementFromPoint(x, y);
1192
1246
  let cell = el && el.closest && el.closest('td, th');
@@ -1223,19 +1277,27 @@
1223
1277
  const begin = () => {
1224
1278
  area.setAttribute('data-rich-text-resizing', hit.axis);
1225
1279
  if (hit.axis === 'x') {
1226
- const group = ensureCols(table);
1280
+ // As a spreadsheet does: a border between columns moves width from one to the other (the
1281
+ // table keeps its width); the outer border sizes the last column and the table, within the field
1227
1282
  const { col } = gridPosition(cell);
1228
- const index = Math.min(col + (cell.colSpan || 1) - 1, group.children.length - 1);
1229
- const target = group.children[index];
1230
- const start = parseFloat(target.style.width) || cell.getBoundingClientRect().width;
1231
- // The outer border sizes the table too
1232
- const outer = index === group.children.length - 1;
1283
+ const widths = columnWidths(table), last = widths.length - 1;
1284
+ const index = Math.min(col + (cell.colSpan || 1) - 1, last);
1233
1285
  const tableStart = table.getBoundingClientRect().width;
1234
- if (outer) table.style.width = Math.round(tableStart) + 'px';
1286
+ const cs = getComputedStyle(area), field = Math.max(1, area.clientWidth - (parseFloat(cs.paddingLeft) || 0) - (parseFloat(cs.paddingRight) || 0));
1287
+ const room = Math.max(field, tableStart) - (tableStart - widths.reduce((a, b) => a + b, 0)); // columns' room, borders aside
1235
1288
  return (ev) => {
1236
- const delta = ev.clientX - fromX;
1237
- target.style.width = Math.max(28, Math.round(start + delta)) + 'px';
1238
- if (outer) table.style.width = Math.max(60, Math.round(tableStart + delta)) + 'px';
1289
+ const delta = ev.clientX - fromX, w = widths.slice();
1290
+ if (index < last) {
1291
+ const pair = widths[index] + widths[index + 1];
1292
+ if (pair < 2 * MIN_COL) return;
1293
+ w[index] = Math.min(pair - MIN_COL, Math.max(MIN_COL, widths[index] + delta));
1294
+ w[index + 1] = pair - w[index];
1295
+ writeWidths(table, w, tableStart, field);
1296
+ } else {
1297
+ const others = widths.reduce((a, b) => a + b, 0) - widths[last];
1298
+ w[last] = Math.max(MIN_COL, Math.min(widths[last] + delta, room - others));
1299
+ writeWidths(table, w, tableStart - widths[last] + w[last], field);
1300
+ }
1239
1301
  };
1240
1302
  }
1241
1303
  const row = cell.parentElement, start = row.getBoundingClientRect().height;
@@ -16,7 +16,7 @@
16
16
 
17
17
  // Build stamps the published version here; unstamped (dev) falls back to the
18
18
  // registration URL's `v`, then 'dev'.
19
- const BUILD_VERSION = '0.5.234';
19
+ const BUILD_VERSION = '0.5.236';
20
20
  const CACHE_PREFIX = 'mnfst-sw:';
21
21
  const META_CACHE = CACHE_PREFIX + 'meta';
22
22
  // Sized to hold a full precache.json warm-up (PRECACHE_MAX_ENTRIES server-side)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnfst",
3
- "version": "0.5.234",
3
+ "version": "0.5.236",
4
4
  "private": false,
5
5
  "workspaces": [
6
6
  "templates/starter",