@fairfox/polly 0.25.0 → 0.26.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.
@@ -240,6 +240,349 @@ function ActionInput(props) {
240
240
  ...common
241
241
  }, undefined, false, undefined, this);
242
242
  }
243
+ // src/polly-ui/Badge.module.css
244
+ var Badge_module_default = {
245
+ badge: "badge_cZd0Aw",
246
+ info: "info_cZd0Aw",
247
+ success: "success_cZd0Aw",
248
+ warning: "warning_cZd0Aw",
249
+ danger: "danger_cZd0Aw"
250
+ };
251
+
252
+ // src/polly-ui/Badge.tsx
253
+ import { jsxDEV as jsxDEV3 } from "preact/jsx-dev-runtime";
254
+ function variantClass(variant) {
255
+ if (variant === "info")
256
+ return Badge_module_default["info"];
257
+ if (variant === "success")
258
+ return Badge_module_default["success"];
259
+ if (variant === "warning")
260
+ return Badge_module_default["warning"];
261
+ if (variant === "danger")
262
+ return Badge_module_default["danger"];
263
+ return;
264
+ }
265
+ function Badge(props) {
266
+ const { children, variant = "default", className, id } = props;
267
+ const parts = [Badge_module_default["badge"]];
268
+ const v = variantClass(variant);
269
+ if (v)
270
+ parts.push(v);
271
+ if (className)
272
+ parts.push(className);
273
+ return /* @__PURE__ */ jsxDEV3("span", {
274
+ id,
275
+ class: parts.join(" "),
276
+ "data-polly-ui": true,
277
+ "data-polly-badge": variant,
278
+ children
279
+ }, undefined, false, undefined, this);
280
+ }
281
+ // src/polly-ui/Button.module.css
282
+ var Button_module_default = {
283
+ btn: "btn_c4HKfA",
284
+ tierPrimary: "tierPrimary_c4HKfA",
285
+ tierSecondary: "tierSecondary_c4HKfA",
286
+ tierTertiary: "tierTertiary_c4HKfA",
287
+ colorInfo: "colorInfo_c4HKfA",
288
+ colorSuccess: "colorSuccess_c4HKfA",
289
+ colorWarning: "colorWarning_c4HKfA",
290
+ colorDanger: "colorDanger_c4HKfA",
291
+ btnSmall: "btnSmall_c4HKfA",
292
+ btnLarge: "btnLarge_c4HKfA",
293
+ btnCircle: "btnCircle_c4HKfA",
294
+ btnFullWidth: "btnFullWidth_c4HKfA"
295
+ };
296
+
297
+ // src/polly-ui/Layout.tsx
298
+ import { createElement } from "preact";
299
+
300
+ // src/polly-ui/Layout.module.css
301
+ var Layout_module_default = {
302
+ layout: "layout_QgwWPg",
303
+ inline: "inline_QgwWPg",
304
+ stackOnMobile: "stackOnMobile_QgwWPg"
305
+ };
306
+
307
+ // src/polly-ui/Layout.tsx
308
+ function Layout(props) {
309
+ const {
310
+ children,
311
+ as = "div",
312
+ rows,
313
+ columns,
314
+ contents,
315
+ subgrid,
316
+ gap,
317
+ padding,
318
+ height,
319
+ minHeight,
320
+ justifyItems,
321
+ alignItems,
322
+ justifyContent,
323
+ alignContent,
324
+ justifySelf,
325
+ alignSelf,
326
+ autoFlow,
327
+ autoRows,
328
+ autoColumns,
329
+ stackOnMobile,
330
+ inline,
331
+ className,
332
+ onClick,
333
+ onKeyDown,
334
+ role,
335
+ tabIndex,
336
+ id
337
+ } = props;
338
+ const style = {};
339
+ if (contents) {
340
+ style["display"] = "contents";
341
+ } else if (subgrid) {
342
+ style["--l-col"] = "1 / -1";
343
+ style["--l-cols"] = "subgrid";
344
+ if (padding)
345
+ style["--l-p"] = padding;
346
+ if (alignItems)
347
+ style["--l-ai"] = alignItems;
348
+ if (gap)
349
+ style["--l-gap"] = gap;
350
+ } else {
351
+ if (padding)
352
+ style["--l-p"] = padding;
353
+ if (height)
354
+ style["--l-h"] = height;
355
+ if (minHeight)
356
+ style["--l-mh"] = minHeight;
357
+ if (rows)
358
+ style["--l-rows"] = rows;
359
+ if (columns)
360
+ style["--l-cols"] = columns;
361
+ if (gap)
362
+ style["--l-gap"] = gap;
363
+ if (justifyItems)
364
+ style["--l-ji"] = justifyItems;
365
+ if (alignItems)
366
+ style["--l-ai"] = alignItems;
367
+ if (justifyContent)
368
+ style["--l-jc"] = justifyContent;
369
+ if (alignContent)
370
+ style["--l-ac"] = alignContent;
371
+ if (autoFlow)
372
+ style["--l-flow"] = autoFlow;
373
+ if (autoRows)
374
+ style["--l-arows"] = autoRows;
375
+ if (autoColumns)
376
+ style["--l-acols"] = autoColumns;
377
+ }
378
+ if (justifySelf)
379
+ style["--l-js"] = justifySelf;
380
+ if (alignSelf)
381
+ style["--l-as"] = alignSelf;
382
+ const baseParts = [Layout_module_default["layout"]];
383
+ if (inline)
384
+ baseParts.push(Layout_module_default["inline"]);
385
+ if (stackOnMobile)
386
+ baseParts.push(Layout_module_default["stackOnMobile"]);
387
+ const baseClass = baseParts.filter(Boolean).join(" ");
388
+ const combined = contents ? className : className ? `${baseClass} ${className}` : baseClass;
389
+ return createElement(as, {
390
+ id,
391
+ className: combined,
392
+ style,
393
+ onClick,
394
+ onKeyDown,
395
+ role,
396
+ tabIndex,
397
+ "aria-label": props["aria-label"],
398
+ "aria-labelledby": props["aria-labelledby"],
399
+ "aria-describedby": props["aria-describedby"],
400
+ "data-polly-layout": true
401
+ }, children);
402
+ }
403
+
404
+ // src/polly-ui/Button.tsx
405
+ import { jsxDEV as jsxDEV4 } from "preact/jsx-dev-runtime";
406
+ function tierClass(tier) {
407
+ if (tier === "primary")
408
+ return Button_module_default["tierPrimary"];
409
+ if (tier === "tertiary")
410
+ return Button_module_default["tierTertiary"];
411
+ return Button_module_default["tierSecondary"];
412
+ }
413
+ function colorClass(color) {
414
+ if (color === "info")
415
+ return Button_module_default["colorInfo"];
416
+ if (color === "success")
417
+ return Button_module_default["colorSuccess"];
418
+ if (color === "warning")
419
+ return Button_module_default["colorWarning"];
420
+ if (color === "danger")
421
+ return Button_module_default["colorDanger"];
422
+ return;
423
+ }
424
+ function sizeClass(size) {
425
+ if (size === "small")
426
+ return Button_module_default["btnSmall"];
427
+ if (size === "large")
428
+ return Button_module_default["btnLarge"];
429
+ return;
430
+ }
431
+ function Button(props) {
432
+ const {
433
+ id,
434
+ tier = "secondary",
435
+ color = "default",
436
+ size = "normal",
437
+ disabled = false,
438
+ fullWidth = false,
439
+ circle = false,
440
+ className,
441
+ title,
442
+ icon,
443
+ label
444
+ } = props;
445
+ const parts = [Button_module_default["btn"] ?? ""];
446
+ const tc = tierClass(tier);
447
+ if (tc)
448
+ parts.push(tc);
449
+ const cc = colorClass(color);
450
+ if (cc)
451
+ parts.push(cc);
452
+ const sc = sizeClass(size);
453
+ if (sc)
454
+ parts.push(sc);
455
+ if (circle)
456
+ parts.push(Button_module_default["btnCircle"] ?? "");
457
+ if (fullWidth)
458
+ parts.push(Button_module_default["btnFullWidth"] ?? "");
459
+ if (className)
460
+ parts.push(className);
461
+ const buttonClass = parts.filter(Boolean).join(" ");
462
+ const content = icon ? /* @__PURE__ */ jsxDEV4(Layout, {
463
+ inline: true,
464
+ columns: "auto auto",
465
+ gap: "0.5em",
466
+ alignItems: "center",
467
+ children: [
468
+ icon,
469
+ /* @__PURE__ */ jsxDEV4("span", {
470
+ children: label
471
+ }, undefined, false, undefined, this)
472
+ ]
473
+ }, undefined, true, undefined, this) : label;
474
+ const dataAction = props["data-action"];
475
+ const ariaLabel = props["aria-label"];
476
+ if ("href" in props && props.href) {
477
+ return /* @__PURE__ */ jsxDEV4("a", {
478
+ id,
479
+ class: buttonClass,
480
+ title,
481
+ href: disabled ? undefined : props.href,
482
+ target: "target" in props ? props.target : undefined,
483
+ rel: "rel" in props ? props.rel : undefined,
484
+ "aria-disabled": disabled,
485
+ "aria-label": ariaLabel,
486
+ "data-polly-ui": true,
487
+ "data-polly-button": tier,
488
+ "data-action": dataAction,
489
+ children: content
490
+ }, undefined, false, undefined, this);
491
+ }
492
+ const resolvedType = "type" in props && props.type ? props.type : "button";
493
+ return /* @__PURE__ */ jsxDEV4("button", {
494
+ id,
495
+ class: buttonClass,
496
+ title,
497
+ type: resolvedType,
498
+ disabled,
499
+ "aria-label": ariaLabel,
500
+ "data-polly-ui": true,
501
+ "data-polly-button": tier,
502
+ "data-action": dataAction,
503
+ children: content
504
+ }, undefined, false, undefined, this);
505
+ }
506
+ // src/polly-ui/Checkbox.module.css
507
+ var Checkbox_module_default = {
508
+ checkbox: "checkbox_EKE5sg",
509
+ disabled: "disabled_EKE5sg",
510
+ input: "input_EKE5sg",
511
+ label: "label_EKE5sg"
512
+ };
513
+
514
+ // src/polly-ui/Checkbox.tsx
515
+ import { jsxDEV as jsxDEV5 } from "preact/jsx-dev-runtime";
516
+ function isSignal(value) {
517
+ return typeof value === "object" && value !== null && "value" in value && "peek" in value;
518
+ }
519
+ function Checkbox(props) {
520
+ const { checked, defaultChecked, name, disabled = false, label, className, id } = props;
521
+ const handleChange = (e) => {
522
+ if (isSignal(checked)) {
523
+ checked.value = e.currentTarget.checked;
524
+ }
525
+ };
526
+ const checkedValue = isSignal(checked) ? checked.value : checked;
527
+ const parts = [Checkbox_module_default["checkbox"]];
528
+ if (disabled)
529
+ parts.push(Checkbox_module_default["disabled"] ?? "");
530
+ if (className)
531
+ parts.push(className);
532
+ return /* @__PURE__ */ jsxDEV5("label", {
533
+ class: parts.filter(Boolean).join(" "),
534
+ "data-polly-ui": true,
535
+ "data-polly-checkbox": true,
536
+ children: [
537
+ /* @__PURE__ */ jsxDEV5("input", {
538
+ id,
539
+ type: "checkbox",
540
+ class: Checkbox_module_default["input"],
541
+ checked: checkedValue,
542
+ defaultChecked,
543
+ name,
544
+ disabled,
545
+ onChange: handleChange
546
+ }, undefined, false, undefined, this),
547
+ label !== undefined && /* @__PURE__ */ jsxDEV5("span", {
548
+ class: Checkbox_module_default["label"],
549
+ children: label
550
+ }, undefined, false, undefined, this)
551
+ ]
552
+ }, undefined, true, undefined, this);
553
+ }
554
+ // src/polly-ui/Collapsible.module.css
555
+ var Collapsible_module_default = {
556
+ collapsible: "collapsible_sEhnPw",
557
+ summary: "summary_sEhnPw",
558
+ content: "content_sEhnPw"
559
+ };
560
+
561
+ // src/polly-ui/Collapsible.tsx
562
+ import { jsxDEV as jsxDEV6 } from "preact/jsx-dev-runtime";
563
+ function Collapsible(props) {
564
+ const { summary, children, defaultOpen = false, className, id } = props;
565
+ const parts = [Collapsible_module_default["collapsible"]];
566
+ if (className)
567
+ parts.push(className);
568
+ return /* @__PURE__ */ jsxDEV6("details", {
569
+ id,
570
+ class: parts.join(" "),
571
+ open: defaultOpen,
572
+ "data-polly-ui": true,
573
+ "data-polly-collapsible": true,
574
+ children: [
575
+ /* @__PURE__ */ jsxDEV6("summary", {
576
+ class: Collapsible_module_default["summary"],
577
+ children: summary
578
+ }, undefined, false, undefined, this),
579
+ /* @__PURE__ */ jsxDEV6("div", {
580
+ class: Collapsible_module_default["content"],
581
+ children
582
+ }, undefined, false, undefined, this)
583
+ ]
584
+ }, undefined, true, undefined, this);
585
+ }
243
586
  // src/polly-ui/ConfirmDialog.tsx
244
587
  import { signal as signal2 } from "@preact/signals";
245
588
 
@@ -403,7 +746,7 @@ var OverlayRoot_module_default = {
403
746
  };
404
747
 
405
748
  // src/polly-ui/OverlayRoot.tsx
406
- import { jsxDEV as jsxDEV3 } from "preact/jsx-dev-runtime";
749
+ import { jsxDEV as jsxDEV7 } from "preact/jsx-dev-runtime";
407
750
  function OverlayRoot() {
408
751
  const ref = useRef2(null);
409
752
  useEffect2(() => {
@@ -422,7 +765,7 @@ function OverlayRoot() {
422
765
  release?.();
423
766
  };
424
767
  }, []);
425
- return /* @__PURE__ */ jsxDEV3("div", {
768
+ return /* @__PURE__ */ jsxDEV7("div", {
426
769
  ref,
427
770
  class: OverlayRoot_module_default["root"],
428
771
  "data-polly-ui": true,
@@ -434,7 +777,7 @@ function getOverlayRootNode() {
434
777
  }
435
778
 
436
779
  // src/polly-ui/Modal.tsx
437
- import { jsxDEV as jsxDEV4 } from "preact/jsx-dev-runtime";
780
+ import { jsxDEV as jsxDEV8 } from "preact/jsx-dev-runtime";
438
781
  var Ctx = createContext(null);
439
782
  function useModal() {
440
783
  const ctx = useContext(Ctx);
@@ -474,9 +817,9 @@ function Root({ when, onClose, children, "aria-label": ariaLabel }) {
474
817
  onClose?.();
475
818
  };
476
819
  const ctx = { id, titleId, descId, close };
477
- const content = /* @__PURE__ */ jsxDEV4(Ctx.Provider, {
820
+ const content = /* @__PURE__ */ jsxDEV8(Ctx.Provider, {
478
821
  value: ctx,
479
- children: /* @__PURE__ */ jsxDEV4("div", {
822
+ children: /* @__PURE__ */ jsxDEV8("div", {
480
823
  ref: mountRef,
481
824
  class: Modal_module_default["container"],
482
825
  "data-polly-ui": true,
@@ -495,7 +838,7 @@ function Root({ when, onClose, children, "aria-label": ariaLabel }) {
495
838
  }
496
839
  function Backdrop() {
497
840
  const { close } = useModal();
498
- return /* @__PURE__ */ jsxDEV4("div", {
841
+ return /* @__PURE__ */ jsxDEV8("div", {
499
842
  class: Modal_module_default["backdrop"],
500
843
  "data-polly-modal-backdrop": true,
501
844
  onClick: close,
@@ -503,14 +846,14 @@ function Backdrop() {
503
846
  }, undefined, false, undefined, this);
504
847
  }
505
848
  function Content({ children }) {
506
- return /* @__PURE__ */ jsxDEV4("div", {
849
+ return /* @__PURE__ */ jsxDEV8("div", {
507
850
  class: Modal_module_default["surface"],
508
851
  "data-polly-modal-surface": true,
509
852
  children
510
853
  }, undefined, false, undefined, this);
511
854
  }
512
855
  function Header({ children }) {
513
- return /* @__PURE__ */ jsxDEV4("header", {
856
+ return /* @__PURE__ */ jsxDEV8("header", {
514
857
  class: Modal_module_default["header"],
515
858
  "data-polly-modal-header": true,
516
859
  children
@@ -518,7 +861,7 @@ function Header({ children }) {
518
861
  }
519
862
  function Title({ children }) {
520
863
  const { titleId } = useModal();
521
- return /* @__PURE__ */ jsxDEV4("h2", {
864
+ return /* @__PURE__ */ jsxDEV8("h2", {
522
865
  id: titleId,
523
866
  class: Modal_module_default["title"],
524
867
  "data-polly-modal-title": true,
@@ -527,7 +870,7 @@ function Title({ children }) {
527
870
  }
528
871
  function Body({ children }) {
529
872
  const { descId } = useModal();
530
- return /* @__PURE__ */ jsxDEV4("div", {
873
+ return /* @__PURE__ */ jsxDEV8("div", {
531
874
  id: descId,
532
875
  class: Modal_module_default["body"],
533
876
  "data-polly-modal-body": true,
@@ -535,7 +878,7 @@ function Body({ children }) {
535
878
  }, undefined, false, undefined, this);
536
879
  }
537
880
  function Footer({ children }) {
538
- return /* @__PURE__ */ jsxDEV4("footer", {
881
+ return /* @__PURE__ */ jsxDEV8("footer", {
539
882
  class: Modal_module_default["footer"],
540
883
  "data-polly-modal-footer": true,
541
884
  children
@@ -544,7 +887,7 @@ function Footer({ children }) {
544
887
  function Close({ children, action }) {
545
888
  const { close } = useModal();
546
889
  if (action) {
547
- return /* @__PURE__ */ jsxDEV4("button", {
890
+ return /* @__PURE__ */ jsxDEV8("button", {
548
891
  type: "button",
549
892
  class: Modal_module_default["close"],
550
893
  "data-polly-ui": true,
@@ -554,7 +897,7 @@ function Close({ children, action }) {
554
897
  children
555
898
  }, undefined, false, undefined, this);
556
899
  }
557
- return /* @__PURE__ */ jsxDEV4("button", {
900
+ return /* @__PURE__ */ jsxDEV8("button", {
558
901
  type: "button",
559
902
  class: Modal_module_default["close"],
560
903
  "data-polly-ui": true,
@@ -576,7 +919,7 @@ var Modal = {
576
919
  };
577
920
 
578
921
  // src/polly-ui/ConfirmDialog.tsx
579
- import { jsxDEV as jsxDEV5 } from "preact/jsx-dev-runtime";
922
+ import { jsxDEV as jsxDEV9 } from "preact/jsx-dev-runtime";
580
923
  var pending = signal2(null);
581
924
  var isOpen = signal2(false);
582
925
  var nextId = 0;
@@ -607,27 +950,27 @@ function Host() {
607
950
  const current = pending.value;
608
951
  if (!current)
609
952
  return null;
610
- return /* @__PURE__ */ jsxDEV5(Modal.Root, {
953
+ return /* @__PURE__ */ jsxDEV9(Modal.Root, {
611
954
  when: isOpen,
612
955
  onClose: () => close(false),
613
956
  children: [
614
- /* @__PURE__ */ jsxDEV5(Modal.Backdrop, {}, undefined, false, undefined, this),
615
- /* @__PURE__ */ jsxDEV5(Modal.Content, {
957
+ /* @__PURE__ */ jsxDEV9(Modal.Backdrop, {}, undefined, false, undefined, this),
958
+ /* @__PURE__ */ jsxDEV9(Modal.Content, {
616
959
  children: [
617
- /* @__PURE__ */ jsxDEV5(Modal.Header, {
618
- children: /* @__PURE__ */ jsxDEV5(Modal.Title, {
960
+ /* @__PURE__ */ jsxDEV9(Modal.Header, {
961
+ children: /* @__PURE__ */ jsxDEV9(Modal.Title, {
619
962
  children: current.title
620
963
  }, undefined, false, undefined, this)
621
964
  }, undefined, false, undefined, this),
622
- current.body ? /* @__PURE__ */ jsxDEV5(Modal.Body, {
965
+ current.body ? /* @__PURE__ */ jsxDEV9(Modal.Body, {
623
966
  children: current.body
624
967
  }, undefined, false, undefined, this) : null,
625
- /* @__PURE__ */ jsxDEV5(Modal.Footer, {
626
- children: /* @__PURE__ */ jsxDEV5("div", {
968
+ /* @__PURE__ */ jsxDEV9(Modal.Footer, {
969
+ children: /* @__PURE__ */ jsxDEV9("div", {
627
970
  class: ConfirmDialog_module_default["actions"],
628
971
  "data-polly-confirm-actions": true,
629
972
  children: [
630
- /* @__PURE__ */ jsxDEV5("button", {
973
+ /* @__PURE__ */ jsxDEV9("button", {
631
974
  type: "button",
632
975
  class: ConfirmDialog_module_default["cancel"],
633
976
  "data-polly-ui": true,
@@ -636,7 +979,7 @@ function Host() {
636
979
  onClick: () => close(false),
637
980
  children: current.cancelLabel ?? "Cancel"
638
981
  }, undefined, false, undefined, this),
639
- /* @__PURE__ */ jsxDEV5("button", {
982
+ /* @__PURE__ */ jsxDEV9("button", {
640
983
  type: "button",
641
984
  class: current.danger ? ConfirmDialog_module_default["confirmDanger"] : ConfirmDialog_module_default["confirm"],
642
985
  "data-polly-ui": true,
@@ -654,104 +997,331 @@ function Host() {
654
997
  }, undefined, true, undefined, this);
655
998
  }
656
999
  var ConfirmDialog = { Host, confirm };
657
- // src/polly-ui/Layout.tsx
658
- import { createElement } from "preact";
1000
+ // src/polly-ui/Dropdown.tsx
1001
+ import { useSignalEffect } from "@preact/signals";
1002
+ import { useEffect as useEffect4, useRef as useRef4 } from "preact/hooks";
659
1003
 
660
- // src/polly-ui/Layout.module.css
661
- var Layout_module_default = {
662
- layout: "layout_QgwWPg",
663
- stackOnMobile: "stackOnMobile_QgwWPg"
1004
+ // src/polly-ui/Dropdown.module.css
1005
+ var Dropdown_module_default = {
1006
+ dropdown: "dropdown_HX48zA",
1007
+ trigger: "trigger_HX48zA",
1008
+ menu: "menu_HX48zA",
1009
+ alignRight: "alignRight_HX48zA"
664
1010
  };
665
1011
 
666
- // src/polly-ui/Layout.tsx
667
- function Layout(props) {
1012
+ // src/polly-ui/Dropdown.tsx
1013
+ import { jsxDEV as jsxDEV10 } from "preact/jsx-dev-runtime";
1014
+ var dropdownCounter = 0;
1015
+ function Dropdown(props) {
1016
+ const { isOpen: isOpen2, trigger, children, align = "left", multiSelect = false, className, id } = props;
1017
+ const menuRef = useRef4(null);
1018
+ const triggerRef = useRef4(null);
1019
+ const idRef = useRef4(`polly-dropdown-${++dropdownCounter}`);
1020
+ const popoverId = idRef.current;
1021
+ useEffect4(() => {
1022
+ triggerRef.current?.setAttribute("popovertarget", popoverId);
1023
+ }, [popoverId]);
1024
+ useEffect4(() => {
1025
+ const menu = menuRef.current;
1026
+ if (!menu)
1027
+ return;
1028
+ const onOverlayClose = (e) => {
1029
+ if (e instanceof CustomEvent && e.detail?.id === popoverId) {
1030
+ isOpen2.value = false;
1031
+ }
1032
+ };
1033
+ menu.addEventListener("overlay:close", onOverlayClose);
1034
+ return () => {
1035
+ menu.removeEventListener("overlay:close", onOverlayClose);
1036
+ };
1037
+ }, [popoverId, isOpen2]);
1038
+ useSignalEffect(() => {
1039
+ const menu = menuRef.current;
1040
+ if (!menu)
1041
+ return;
1042
+ if (isOpen2.value && !menu.matches(":popover-open")) {
1043
+ menu.showPopover();
1044
+ } else if (!isOpen2.value && menu.matches(":popover-open")) {
1045
+ menu.hidePopover();
1046
+ }
1047
+ });
1048
+ const handleToggle = (e) => {
1049
+ if ("newState" in e) {
1050
+ isOpen2.value = e.newState === "open";
1051
+ }
1052
+ };
1053
+ const handleMenuClick = () => {
1054
+ if (!multiSelect) {
1055
+ isOpen2.value = false;
1056
+ }
1057
+ };
1058
+ const handleKeyDown = (e) => {
1059
+ if (e.key === "Escape") {
1060
+ isOpen2.value = false;
1061
+ }
1062
+ };
1063
+ const parts = [Dropdown_module_default["dropdown"] ?? ""];
1064
+ if (className)
1065
+ parts.push(className);
1066
+ const menuParts = [Dropdown_module_default["menu"] ?? ""];
1067
+ if (align === "right")
1068
+ menuParts.push(Dropdown_module_default["alignRight"] ?? "");
1069
+ return /* @__PURE__ */ jsxDEV10("div", {
1070
+ id,
1071
+ class: parts.filter(Boolean).join(" "),
1072
+ "data-polly-ui": true,
1073
+ "data-polly-dropdown": true,
1074
+ children: [
1075
+ /* @__PURE__ */ jsxDEV10("button", {
1076
+ ref: triggerRef,
1077
+ type: "button",
1078
+ class: Dropdown_module_default["trigger"],
1079
+ children: trigger
1080
+ }, undefined, false, undefined, this),
1081
+ /* @__PURE__ */ jsxDEV10("div", {
1082
+ ref: menuRef,
1083
+ id: popoverId,
1084
+ role: "listbox",
1085
+ class: menuParts.filter(Boolean).join(" "),
1086
+ popover: "auto",
1087
+ "data-overlay-id": popoverId,
1088
+ onToggle: handleToggle,
1089
+ onClick: handleMenuClick,
1090
+ onKeyDown: handleKeyDown,
1091
+ children: /* @__PURE__ */ jsxDEV10(Layout, {
1092
+ rows: "auto",
1093
+ gap: "0",
1094
+ children
1095
+ }, undefined, false, undefined, this)
1096
+ }, undefined, false, undefined, this)
1097
+ ]
1098
+ }, undefined, true, undefined, this);
1099
+ }
1100
+ // src/polly-ui/Select.tsx
1101
+ import { useComputed, useSignal } from "@preact/signals";
1102
+
1103
+ // src/polly-ui/Select.module.css
1104
+ var Select_module_default = {
1105
+ select: "select_daofbw",
1106
+ label: "label_daofbw",
1107
+ trigger: "trigger_daofbw",
1108
+ placeholder: "placeholder_daofbw",
1109
+ actions: "actions_daofbw",
1110
+ actionBtn: "actionBtn_daofbw",
1111
+ option: "option_daofbw",
1112
+ optionSelected: "optionSelected_daofbw",
1113
+ optionCheck: "optionCheck_daofbw"
1114
+ };
1115
+
1116
+ // src/polly-ui/Select.tsx
1117
+ import { jsxDEV as jsxDEV11 } from "preact/jsx-dev-runtime";
1118
+ function formatSelected(options, selected) {
1119
+ if (selected.size === 0)
1120
+ return "";
1121
+ const labels = [];
1122
+ for (const opt of options) {
1123
+ if (selected.has(opt.value))
1124
+ labels.push(opt.label);
1125
+ }
1126
+ return labels.join(", ");
1127
+ }
1128
+ function Select(props) {
668
1129
  const {
669
- children,
670
- as = "div",
671
- rows,
672
- columns,
673
- contents,
674
- subgrid,
675
- gap,
676
- padding,
677
- height,
678
- minHeight,
679
- justifyItems,
680
- alignItems,
681
- justifyContent,
682
- alignContent,
683
- justifySelf,
684
- alignSelf,
685
- autoFlow,
686
- autoRows,
687
- autoColumns,
688
- stackOnMobile,
1130
+ options,
1131
+ selected,
1132
+ label,
1133
+ placeholder = "Select…",
1134
+ multiSelect = false,
1135
+ disabled = false,
689
1136
  className,
690
- onClick,
691
- onKeyDown,
692
- role,
693
- tabIndex,
694
1137
  id
695
1138
  } = props;
696
- const style = {};
697
- if (contents) {
698
- style["display"] = "contents";
699
- } else if (subgrid) {
700
- style["--l-col"] = "1 / -1";
701
- style["--l-cols"] = "subgrid";
702
- if (padding)
703
- style["--l-p"] = padding;
704
- if (alignItems)
705
- style["--l-ai"] = alignItems;
706
- if (gap)
707
- style["--l-gap"] = gap;
708
- } else {
709
- if (padding)
710
- style["--l-p"] = padding;
711
- if (height)
712
- style["--l-h"] = height;
713
- if (minHeight)
714
- style["--l-mh"] = minHeight;
715
- if (rows)
716
- style["--l-rows"] = rows;
717
- if (columns)
718
- style["--l-cols"] = columns;
719
- if (gap)
720
- style["--l-gap"] = gap;
721
- if (justifyItems)
722
- style["--l-ji"] = justifyItems;
723
- if (alignItems)
724
- style["--l-ai"] = alignItems;
725
- if (justifyContent)
726
- style["--l-jc"] = justifyContent;
727
- if (alignContent)
728
- style["--l-ac"] = alignContent;
729
- if (autoFlow)
730
- style["--l-flow"] = autoFlow;
731
- if (autoRows)
732
- style["--l-arows"] = autoRows;
733
- if (autoColumns)
734
- style["--l-acols"] = autoColumns;
735
- }
736
- if (justifySelf)
737
- style["--l-js"] = justifySelf;
738
- if (alignSelf)
739
- style["--l-as"] = alignSelf;
740
- const baseClass = stackOnMobile ? `${Layout_module_default["layout"]} ${Layout_module_default["stackOnMobile"]}` : Layout_module_default["layout"];
741
- const combined = contents ? className : className ? `${baseClass} ${className}` : baseClass;
742
- return createElement(as, {
1139
+ const isOpen2 = useSignal(false);
1140
+ const displayText = useComputed(() => {
1141
+ const text = formatSelected(options, selected.value);
1142
+ return text.length > 0 ? text : placeholder;
1143
+ });
1144
+ const isEmpty = useComputed(() => selected.value.size === 0);
1145
+ const handleOptionClick = (value) => {
1146
+ if (multiSelect) {
1147
+ const next = new Set(selected.value);
1148
+ if (next.has(value))
1149
+ next.delete(value);
1150
+ else
1151
+ next.add(value);
1152
+ selected.value = next;
1153
+ } else {
1154
+ selected.value = new Set([value]);
1155
+ isOpen2.value = false;
1156
+ }
1157
+ };
1158
+ const handleSelectAll = () => {
1159
+ selected.value = new Set(options.map((o) => o.value));
1160
+ };
1161
+ const handleClear = () => {
1162
+ selected.value = new Set;
1163
+ };
1164
+ const triggerClass = isEmpty.value ? `${Select_module_default["trigger"]} ${Select_module_default["placeholder"]}` : Select_module_default["trigger"];
1165
+ const triggerButton = /* @__PURE__ */ jsxDEV11("button", {
1166
+ type: "button",
1167
+ class: triggerClass,
1168
+ disabled,
1169
+ children: displayText.value
1170
+ }, undefined, false, undefined, this);
1171
+ const parts = [Select_module_default["select"] ?? ""];
1172
+ if (className)
1173
+ parts.push(className);
1174
+ return /* @__PURE__ */ jsxDEV11("div", {
743
1175
  id,
744
- className: combined,
1176
+ class: parts.filter(Boolean).join(" "),
1177
+ "data-polly-ui": true,
1178
+ "data-polly-select": true,
1179
+ children: [
1180
+ label !== undefined && /* @__PURE__ */ jsxDEV11("span", {
1181
+ class: Select_module_default["label"],
1182
+ children: label
1183
+ }, undefined, false, undefined, this),
1184
+ /* @__PURE__ */ jsxDEV11(Dropdown, {
1185
+ isOpen: isOpen2,
1186
+ trigger: triggerButton,
1187
+ multiSelect,
1188
+ children: [
1189
+ multiSelect && /* @__PURE__ */ jsxDEV11("div", {
1190
+ class: Select_module_default["actions"],
1191
+ children: /* @__PURE__ */ jsxDEV11(Layout, {
1192
+ columns: "1fr 1fr",
1193
+ gap: "var(--polly-space-xs)",
1194
+ children: [
1195
+ /* @__PURE__ */ jsxDEV11("button", {
1196
+ type: "button",
1197
+ class: Select_module_default["actionBtn"],
1198
+ onClick: handleSelectAll,
1199
+ children: "Select All"
1200
+ }, undefined, false, undefined, this),
1201
+ /* @__PURE__ */ jsxDEV11("button", {
1202
+ type: "button",
1203
+ class: Select_module_default["actionBtn"],
1204
+ onClick: handleClear,
1205
+ children: "Clear"
1206
+ }, undefined, false, undefined, this)
1207
+ ]
1208
+ }, undefined, true, undefined, this)
1209
+ }, undefined, false, undefined, this),
1210
+ options.map((opt) => {
1211
+ const isSelected = selected.value.has(opt.value);
1212
+ const optClass = isSelected ? `${Select_module_default["option"]} ${Select_module_default["optionSelected"]}` : Select_module_default["option"];
1213
+ return /* @__PURE__ */ jsxDEV11("button", {
1214
+ type: "button",
1215
+ class: optClass,
1216
+ onClick: () => handleOptionClick(opt.value),
1217
+ children: [
1218
+ multiSelect && /* @__PURE__ */ jsxDEV11("input", {
1219
+ type: "checkbox",
1220
+ class: Select_module_default["optionCheck"],
1221
+ checked: isSelected,
1222
+ tabIndex: -1,
1223
+ readOnly: true
1224
+ }, undefined, false, undefined, this),
1225
+ /* @__PURE__ */ jsxDEV11("span", {
1226
+ children: opt.label
1227
+ }, undefined, false, undefined, this)
1228
+ ]
1229
+ }, String(opt.value), true, undefined, this);
1230
+ })
1231
+ ]
1232
+ }, undefined, true, undefined, this)
1233
+ ]
1234
+ }, undefined, true, undefined, this);
1235
+ }
1236
+ // src/polly-ui/Skeleton.module.css
1237
+ var Skeleton_module_default = {
1238
+ skeleton: "skeleton_Jrgo0g",
1239
+ text: "text_Jrgo0g",
1240
+ rect: "rect_Jrgo0g",
1241
+ circle: "circle_Jrgo0g"
1242
+ };
1243
+
1244
+ // src/polly-ui/Skeleton.tsx
1245
+ import { jsxDEV as jsxDEV12 } from "preact/jsx-dev-runtime";
1246
+ function resolveSize(value) {
1247
+ if (value === undefined)
1248
+ return;
1249
+ if (typeof value === "number")
1250
+ return `${value}px`;
1251
+ return value;
1252
+ }
1253
+ function variantClass2(variant) {
1254
+ if (variant === "circle")
1255
+ return Skeleton_module_default["circle"];
1256
+ if (variant === "rect")
1257
+ return Skeleton_module_default["rect"];
1258
+ return Skeleton_module_default["text"];
1259
+ }
1260
+ function Skeleton(props) {
1261
+ const { variant = "text", width, height, className } = props;
1262
+ const style = {};
1263
+ const w = resolveSize(width);
1264
+ const h = resolveSize(height);
1265
+ if (w !== undefined)
1266
+ style["width"] = w;
1267
+ if (h !== undefined)
1268
+ style["height"] = h;
1269
+ const parts = [];
1270
+ const base = Skeleton_module_default["skeleton"];
1271
+ if (base)
1272
+ parts.push(base);
1273
+ const vClass = variantClass2(variant);
1274
+ if (vClass)
1275
+ parts.push(vClass);
1276
+ if (className)
1277
+ parts.push(className);
1278
+ return /* @__PURE__ */ jsxDEV12("span", {
1279
+ class: parts.join(" "),
745
1280
  style,
746
- onClick,
747
- onKeyDown,
748
- role,
749
- tabIndex,
1281
+ "data-polly-ui": true,
1282
+ "data-polly-skeleton": variant,
1283
+ "aria-hidden": "true"
1284
+ }, undefined, false, undefined, this);
1285
+ }
1286
+ // src/polly-ui/Tabs.module.css
1287
+ var Tabs_module_default = {
1288
+ tabs: "tabs_xKO6GA",
1289
+ tab: "tab_xKO6GA",
1290
+ active: "active_xKO6GA"
1291
+ };
1292
+
1293
+ // src/polly-ui/Tabs.tsx
1294
+ import { jsxDEV as jsxDEV13 } from "preact/jsx-dev-runtime";
1295
+ function Tabs(props) {
1296
+ const { tabs, activeTab, action, className, id } = props;
1297
+ const parts = [Tabs_module_default["tabs"] ?? ""];
1298
+ if (className)
1299
+ parts.push(className);
1300
+ return /* @__PURE__ */ jsxDEV13("nav", {
1301
+ id,
1302
+ class: parts.filter(Boolean).join(" "),
750
1303
  "aria-label": props["aria-label"],
751
- "aria-labelledby": props["aria-labelledby"],
752
- "aria-describedby": props["aria-describedby"],
753
- "data-polly-layout": true
754
- }, children);
1304
+ "data-polly-ui": true,
1305
+ "data-polly-tabs": true,
1306
+ children: /* @__PURE__ */ jsxDEV13(Layout, {
1307
+ columns: `repeat(${tabs.length}, auto)`,
1308
+ gap: "0",
1309
+ alignItems: "end",
1310
+ children: tabs.map((tab) => {
1311
+ const isActive = activeTab === tab.id;
1312
+ const tabClass = isActive ? `${Tabs_module_default["tab"]} ${Tabs_module_default["active"]}` : Tabs_module_default["tab"];
1313
+ return /* @__PURE__ */ jsxDEV13("button", {
1314
+ type: "button",
1315
+ class: tabClass,
1316
+ disabled: tab.disabled,
1317
+ "aria-current": isActive ? "page" : undefined,
1318
+ "data-action": action,
1319
+ "data-action-id": tab.id,
1320
+ children: tab.label
1321
+ }, tab.id, false, undefined, this);
1322
+ })
1323
+ }, undefined, false, undefined, this)
1324
+ }, undefined, false, undefined, this);
755
1325
  }
756
1326
  // src/polly-ui/internal/input-base.ts
757
1327
  function buildInputA11y(props) {
@@ -778,8 +1348,8 @@ var TextInput_module_default = {
778
1348
  };
779
1349
 
780
1350
  // src/polly-ui/TextInput.tsx
781
- import { jsxDEV as jsxDEV6 } from "preact/jsx-dev-runtime";
782
- function isSignal(v) {
1351
+ import { jsxDEV as jsxDEV14 } from "preact/jsx-dev-runtime";
1352
+ function isSignal2(v) {
783
1353
  return typeof v === "object" && v !== null && "value" in v && "peek" in v;
784
1354
  }
785
1355
  function TextInput(props) {
@@ -794,12 +1364,12 @@ function TextInput(props) {
794
1364
  disabled: props.disabled,
795
1365
  readOnly: props.readOnly
796
1366
  });
797
- const controlled = isSignal(props.value);
1367
+ const controlled = isSignal2(props.value);
798
1368
  const stringValue = controlled ? props.value.value : undefined;
799
1369
  const defaultValue = controlled ? undefined : props.value ?? "";
800
1370
  const className = props.className ? `${TextInput_module_default["input"]} ${props.className}` : TextInput_module_default["input"];
801
1371
  if (variant === "multi") {
802
- return /* @__PURE__ */ jsxDEV6("textarea", {
1372
+ return /* @__PURE__ */ jsxDEV14("textarea", {
803
1373
  ...a11y,
804
1374
  class: className,
805
1375
  "data-polly-input-variant": "multi",
@@ -814,7 +1384,7 @@ function TextInput(props) {
814
1384
  }
815
1385
  }, undefined, false, undefined, this);
816
1386
  }
817
- return /* @__PURE__ */ jsxDEV6("input", {
1387
+ return /* @__PURE__ */ jsxDEV14("input", {
818
1388
  ...a11y,
819
1389
  type: "text",
820
1390
  class: className,
@@ -831,7 +1401,7 @@ function TextInput(props) {
831
1401
  }
832
1402
  // src/polly-ui/Toast.tsx
833
1403
  import { createPortal as createPortal2 } from "preact/compat";
834
- import { useEffect as useEffect4, useRef as useRef4, useState as useState3 } from "preact/hooks";
1404
+ import { useEffect as useEffect5, useRef as useRef5, useState as useState3 } from "preact/hooks";
835
1405
 
836
1406
  // src/actions/error.ts
837
1407
  import { signal as signal3 } from "@preact/signals";
@@ -873,16 +1443,16 @@ var Toast_module_default = {
873
1443
  };
874
1444
 
875
1445
  // src/polly-ui/Toast.tsx
876
- import { jsxDEV as jsxDEV7 } from "preact/jsx-dev-runtime";
1446
+ import { jsxDEV as jsxDEV15 } from "preact/jsx-dev-runtime";
877
1447
  function Viewport(props) {
878
1448
  const autoDismissMs = props.autoDismissMs ?? 5000;
879
1449
  const [portalNode, setPortalNode] = useState3(null);
880
1450
  const [paused, setPaused] = useState3(false);
881
1451
  const entries = errorState.value;
882
- useEffect4(() => {
1452
+ useEffect5(() => {
883
1453
  setPortalNode(getOverlayRootNode());
884
1454
  }, []);
885
- useEffect4(() => {
1455
+ useEffect5(() => {
886
1456
  if (paused || entries.length === 0)
887
1457
  return;
888
1458
  const head = entries[0];
@@ -895,13 +1465,13 @@ function Viewport(props) {
895
1465
  }, [paused, entries, autoDismissMs]);
896
1466
  if (!portalNode)
897
1467
  return null;
898
- const content = /* @__PURE__ */ jsxDEV7("div", {
1468
+ const content = /* @__PURE__ */ jsxDEV15("div", {
899
1469
  class: `${Toast_module_default["viewport"]} ${props.className ?? ""}`.trim(),
900
1470
  "data-polly-ui": true,
901
1471
  "data-polly-toast-viewport": true,
902
1472
  onMouseEnter: () => setPaused(true),
903
1473
  onMouseLeave: () => setPaused(false),
904
- children: entries.map((entry) => /* @__PURE__ */ jsxDEV7(ToastItem, {
1474
+ children: entries.map((entry) => /* @__PURE__ */ jsxDEV15(ToastItem, {
905
1475
  entry
906
1476
  }, entry.id, false, undefined, this))
907
1477
  }, undefined, false, undefined, this);
@@ -909,8 +1479,8 @@ function Viewport(props) {
909
1479
  }
910
1480
  function ToastItem({ entry }) {
911
1481
  const liveness = entry.severity === "error" ? "assertive" : "polite";
912
- const ref = useRef4(null);
913
- return /* @__PURE__ */ jsxDEV7("div", {
1482
+ const ref = useRef5(null);
1483
+ return /* @__PURE__ */ jsxDEV15("div", {
914
1484
  ref,
915
1485
  class: Toast_module_default["item"],
916
1486
  "data-polly-ui": true,
@@ -919,11 +1489,11 @@ function ToastItem({ entry }) {
919
1489
  role: entry.severity === "error" ? "alert" : "status",
920
1490
  "aria-live": liveness,
921
1491
  children: [
922
- /* @__PURE__ */ jsxDEV7("span", {
1492
+ /* @__PURE__ */ jsxDEV15("span", {
923
1493
  class: Toast_module_default["message"],
924
1494
  children: entry.message
925
1495
  }, undefined, false, undefined, this),
926
- /* @__PURE__ */ jsxDEV7("button", {
1496
+ /* @__PURE__ */ jsxDEV15("button", {
927
1497
  type: "button",
928
1498
  class: Toast_module_default["close"],
929
1499
  "data-polly-ui": true,
@@ -937,17 +1507,75 @@ function ToastItem({ entry }) {
937
1507
  }, undefined, true, undefined, this);
938
1508
  }
939
1509
  var Toast = { Viewport };
1510
+ // src/polly-ui/Toggle.module.css
1511
+ var Toggle_module_default = {
1512
+ toggle: "toggle_rnf-SQ",
1513
+ disabled: "disabled_rnf-SQ",
1514
+ input: "input_rnf-SQ",
1515
+ track: "track_rnf-SQ",
1516
+ trackChecked: "trackChecked_rnf-SQ",
1517
+ thumb: "thumb_rnf-SQ",
1518
+ thumbChecked: "thumbChecked_rnf-SQ",
1519
+ label: "label_rnf-SQ"
1520
+ };
1521
+
1522
+ // src/polly-ui/Toggle.tsx
1523
+ import { jsxDEV as jsxDEV16 } from "preact/jsx-dev-runtime";
1524
+ function Toggle(props) {
1525
+ const { checked = false, disabled = false, label, name, className, id } = props;
1526
+ const parts = [Toggle_module_default["toggle"]];
1527
+ if (disabled)
1528
+ parts.push(Toggle_module_default["disabled"]);
1529
+ if (className)
1530
+ parts.push(className);
1531
+ return /* @__PURE__ */ jsxDEV16("label", {
1532
+ class: parts.join(" "),
1533
+ "data-polly-ui": true,
1534
+ "data-polly-toggle": true,
1535
+ children: [
1536
+ /* @__PURE__ */ jsxDEV16("input", {
1537
+ id,
1538
+ type: "checkbox",
1539
+ role: "switch",
1540
+ name,
1541
+ "aria-checked": checked,
1542
+ class: Toggle_module_default["input"],
1543
+ checked,
1544
+ disabled
1545
+ }, undefined, false, undefined, this),
1546
+ /* @__PURE__ */ jsxDEV16("span", {
1547
+ class: checked ? `${Toggle_module_default["track"]} ${Toggle_module_default["trackChecked"]}` : Toggle_module_default["track"],
1548
+ children: /* @__PURE__ */ jsxDEV16("span", {
1549
+ class: checked ? `${Toggle_module_default["thumb"]} ${Toggle_module_default["thumbChecked"]}` : Toggle_module_default["thumb"]
1550
+ }, undefined, false, undefined, this)
1551
+ }, undefined, false, undefined, this),
1552
+ label !== undefined && /* @__PURE__ */ jsxDEV16("span", {
1553
+ class: Toggle_module_default["label"],
1554
+ children: label
1555
+ }, undefined, false, undefined, this)
1556
+ ]
1557
+ }, undefined, true, undefined, this);
1558
+ }
940
1559
  export {
941
1560
  getOverlayRootNode,
942
1561
  confirm,
1562
+ Toggle,
943
1563
  Toast,
944
1564
  TextInput,
1565
+ Tabs,
1566
+ Skeleton,
1567
+ Select,
945
1568
  OverlayRoot,
946
1569
  Modal,
947
1570
  Layout,
1571
+ Dropdown,
948
1572
  ConfirmDialog,
1573
+ Collapsible,
1574
+ Checkbox,
1575
+ Button,
1576
+ Badge,
949
1577
  ActionInput,
950
1578
  ActionForm
951
1579
  };
952
1580
 
953
- //# debugId=17892EC9C7CDCA6D64756E2164756E21
1581
+ //# debugId=E8BC12017CFEA66464756E2164756E21