@marianmeres/stuic 2.1.3 → 2.1.5

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.
@@ -9,10 +9,13 @@
9
9
  import { tick, type Snippet } from "svelte";
10
10
  import { tooltip } from "../../actions/index.js";
11
11
  import { type ValidateOptions } from "../../actions/validate.svelte.js";
12
+ import type { TranslateFn } from "../../types.js";
12
13
  import { getId } from "../../utils/get-id.js";
14
+ import { isPlainObject } from "../../utils/is-plain-object.js";
13
15
  import { maybeJsonParse } from "../../utils/maybe-json-parse.js";
14
16
  import { waitForNextRepaint } from "../../utils/paint.js";
15
17
  import { qsa } from "../../utils/qsa.js";
18
+ import { replaceMap } from "../../utils/replace-map.js";
16
19
  import { strHash } from "../../utils/str-hash.js";
17
20
  import { twMerge } from "../../utils/tw-merge.js";
18
21
  import Button from "../Button/Button.svelte";
@@ -23,9 +26,6 @@
23
26
  import X from "../X/X.svelte";
24
27
  import InputWrap from "./_internal/InputWrap.svelte";
25
28
  import FieldLikeButton from "./FieldLikeButton.svelte";
26
- import { replaceMap } from "../../utils/replace-map.js";
27
- import { isPlainObject } from "../../utils/is-plain-object.js";
28
- import type { TranslateFn } from "../../types.js";
29
29
 
30
30
  export interface Option {
31
31
  label: string;
@@ -248,7 +248,6 @@
248
248
  allowNextPrevCycle: false,
249
249
  sortFn,
250
250
  idPropName: itemIdPropName,
251
- searchable: { getContent: (item) => _renderOptionLabel(item) },
252
251
  });
253
252
 
254
253
  // second, the selected ones
@@ -289,34 +288,29 @@
289
288
  // add_new dance...
290
289
  let addNewBtn: HTMLButtonElement | undefined = $state();
291
290
  let isAddNewBtnActive = $state(false);
291
+ let touch = $state(new Date());
292
292
 
293
293
  // set value on open
294
- watch(
295
- () => modal.visibility().visible,
296
- (isVisible, wasVisible) => {
297
- // modal was just opened
298
- if (!wasVisible && isVisible) {
299
- _selectedColl.clear().addMany(maybeJsonParse(value));
300
- // IMPORTANT: focus first selected so it scrolls into view on open
301
- if (_selectedColl.size) {
302
- waitForNextRepaint().then(() => {
303
- _optionsColl.setActive(_selectedColl.items[0]);
304
- });
305
- }
306
- }
307
- }
308
- );
309
-
310
- // scroll the active option into view
311
- $effect(() => {
312
- if (modal.visibility().visible && options.active?.[itemIdPropName]) {
313
- activeEl = qsa(`#${btn_id(options.active[itemIdPropName])}`, optionsBox)[0] as any;
314
- activeEl?.scrollIntoView({ behavior: "smooth", block: "center" });
315
- activeEl?.focus();
316
- } else {
317
- activeEl = undefined;
318
- }
319
- });
294
+ // watch(
295
+ // () => modal.visibility().visible,
296
+ // (isVisible, wasVisible) => {
297
+ // // modal was just opened
298
+ // if (isVisible) {
299
+ // _selectedColl.clear().addMany(maybeJsonParse(value));
300
+ // console.log(_selectedColl.dump());
301
+ // // IMPORTANT: focus first selected so it scrolls into view on open
302
+ // if (_selectedColl.size) {
303
+ // console.log(1111);
304
+ // waitForNextRepaint().then(() => {
305
+ // _optionsColl.setActive(_selectedColl.items[0]);
306
+ // waitForNextRepaint().then(() => {
307
+ // scrollIntoViewTrigger = new Date();
308
+ // });
309
+ // });
310
+ // }
311
+ // }
312
+ // }
313
+ // );
320
314
 
321
315
  // suggest options as a typeahead feature
322
316
  const debounced = new Debounced(() => innerValue, 150);
@@ -329,10 +323,13 @@
329
323
  .then((res) => {
330
324
  const { found, coll } = res;
331
325
 
332
- // always update the existing with recent server data
333
- _selectedColl.patchMany(found);
334
326
  // continue normally, with (server) provided options...
335
327
  _optionsColl.clear().addMany(found);
328
+ // always update the existing with recent server data
329
+ _selectedColl.patchMany(found);
330
+
331
+ // update signal...
332
+ touch = new Date();
336
333
  })
337
334
  .catch((e) => {
338
335
  console.error(e);
@@ -342,6 +339,29 @@
342
339
  }
343
340
  );
344
341
 
342
+ $effect(() => {
343
+ if (modal.visibility().visible && touch) {
344
+ _selectedColl.clear().addMany(maybeJsonParse(value));
345
+ // IMPORTANT: focus first selected so it scrolls into view on open
346
+ if (_selectedColl.size) {
347
+ waitForNextRepaint().then(() => {
348
+ _optionsColl.setActive(_selectedColl.items[0]);
349
+ });
350
+ }
351
+ }
352
+ });
353
+
354
+ // scroll the active option into view
355
+ $effect(() => {
356
+ if (options.active?.[itemIdPropName]) {
357
+ activeEl = qsa(`#${btn_id(options.active[itemIdPropName])}`, optionsBox)[0] as any;
358
+ activeEl?.scrollIntoView({ behavior: "smooth", block: "center" });
359
+ activeEl?.focus();
360
+ } else {
361
+ activeEl = undefined;
362
+ }
363
+ });
364
+
345
365
  // internal DRY
346
366
  function btn_id(id: string | number, prefix = "btn-") {
347
367
  return prefix + strHash(`${id}`.repeat(3));
@@ -349,11 +369,16 @@
349
369
 
350
370
  // "inner" submit
351
371
  function try_submit(force = false) {
352
- // clog("try_submit", innerValue);
372
+ // clog("try_submit", innerValue, _selectedColl.dump());
353
373
  if (innerValue) {
354
374
  let found = have_option_label_like(_optionsColl.items, innerValue);
375
+ // clog("found", found, allowUnknown, _selectedColl.dump());
355
376
  if (!found && !allowUnknown) {
356
- return notifications?.error(t("select_from_list"), { ttl: 1000 });
377
+ if (isMultiple && _selectedColl.size) {
378
+ // this is actually ok... (not simplifying the outer if so its easily readable)
379
+ } else {
380
+ return notifications?.error(t("select_from_list"), { ttl: 1000 });
381
+ }
357
382
  }
358
383
 
359
384
  if (!found && !_optionsColl.size) {
@@ -1,10 +1,10 @@
1
1
  import { ItemCollection, type Item } from "@marianmeres/item-collection";
2
2
  import { type Snippet } from "svelte";
3
3
  import { type ValidateOptions } from "../../actions/validate.svelte.js";
4
+ import type { TranslateFn } from "../../types.js";
4
5
  import Modal from "../Modal/Modal.svelte";
5
6
  import { NotificationsStack } from "../Notifications/index.js";
6
7
  import type { THC } from "../Thc/Thc.svelte";
7
- import type { TranslateFn } from "../../types.js";
8
8
  export interface Option {
9
9
  label: string;
10
10
  value: any;
@@ -120,7 +120,7 @@
120
120
  )}
121
121
  onkeydown={async (e) => {
122
122
  if (e.key === "Escape" && visible) {
123
- clog("on Escape keydown, preventing default and stopping propagation");
123
+ // clog("on Escape keydown, preventing default and stopping propagation");
124
124
 
125
125
  // do not allow built-in close on escape
126
126
  e.preventDefault();
@@ -37,7 +37,7 @@
37
37
  name,
38
38
  class: classProp,
39
39
  dotClass,
40
- checked = $bindable(false),
40
+ checked = $bindable(),
41
41
  required,
42
42
  disabled,
43
43
  tabindex = 0,
@@ -26,7 +26,7 @@
26
26
  size = "md",
27
27
  class: classProp,
28
28
  dotClass,
29
- checked = $bindable(false),
29
+ checked = $bindable(),
30
30
  disabled,
31
31
  tabindex = 0,
32
32
  label,
@@ -10,6 +10,7 @@ export * from "./is-mac.js";
10
10
  export * from "./is-nullish.js";
11
11
  export * from "./maybe-json-parse.js";
12
12
  export * from "./maybe-json-stringify.js";
13
+ export * from "./nl2br.js";
13
14
  export * from "./omit-pick.js";
14
15
  export * from "./paint.js";
15
16
  export * from "./persistent-state.svelte.js";
@@ -10,6 +10,7 @@ export * from "./is-mac.js";
10
10
  export * from "./is-nullish.js";
11
11
  export * from "./maybe-json-parse.js";
12
12
  export * from "./maybe-json-stringify.js";
13
+ export * from "./nl2br.js";
13
14
  export * from "./omit-pick.js";
14
15
  export * from "./paint.js";
15
16
  export * from "./persistent-state.svelte.js";
@@ -0,0 +1 @@
1
+ export declare function nl2br(str: string): string;
@@ -0,0 +1,3 @@
1
+ export function nl2br(str) {
2
+ return `${str ?? ""}`.replace(/(?:\r\n|\r|\n)/g, "<br />");
3
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",