@sebgroup/green-core 1.2.3 → 1.3.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.
@@ -67,6 +67,15 @@ export declare class GdsDropdown<ValueT = any> extends GdsFormControlElement<Val
67
67
  * ```
68
68
  */
69
69
  searchFilter: (q: string, o: GdsOption) => boolean;
70
+ /**
71
+ * Whether the popover should sync its width to the trigger button. When this is
72
+ * set to `true`, the popover will always have the same width as the trigger button.
73
+ *
74
+ * By default, line-breaks will be applied to the option content if it is wider than
75
+ * the popover width. If you use this option, make sure to verify that your options
76
+ * are still readable and apply appropriate custom layout or truncation if neccecary.
77
+ */
78
+ syncPopoverWidth: boolean;
70
79
  private elTriggerBtn;
71
80
  private elTriggerBtnAsync;
72
81
  private elListbox;
package/index.js CHANGED
@@ -139,7 +139,7 @@ function watchMediaQuery(q) {
139
139
  // libs/core/src/utils/helpers/custom-element-scoping.ts
140
140
  import { html as litHtml } from "lit";
141
141
  import { customElement } from "lit/decorators.js";
142
- var VER_SUFFIX = "-b059fe";
142
+ var VER_SUFFIX = "-f38327";
143
143
  var elementLookupTable = /* @__PURE__ */ new Map();
144
144
  var gdsCustomElement = (tagName) => {
145
145
  if (globalThis.GDS_DISABLE_VERSIONED_ELEMENTS) {
@@ -530,7 +530,7 @@ var GdsOption = class extends Focusable(LitElement2) {
530
530
  }
531
531
  }
532
532
  render() {
533
- const isMultiple = this.parentElement.multiple;
533
+ const isMultiple = this.parentElement?.multiple;
534
534
  const checkbox = html2`<span
535
535
  class="checkbox ${classMap({ checked: this.selected })}"
536
536
  ></span>`;
@@ -585,6 +585,7 @@ GdsOption = __decorateClass([
585
585
  // libs/core/src/primitives/popover/popover.ts
586
586
  import { LitElement as LitElement3, html as html3, unsafeCSS } from "lit";
587
587
  import { property as property3, state } from "lit/decorators.js";
588
+ import { classMap as classMap2 } from "lit/directives/class-map.js";
588
589
  import { msg } from "@lit/localize";
589
590
  import { createRef as createRef2, ref as ref2 } from "lit/directives/ref.js";
590
591
  import {
@@ -754,16 +755,26 @@ function isHTMLElement(value) {
754
755
  // libs/core/src/primitives/popover/popover.styles.ts
755
756
  import { css as css3 } from "lit";
756
757
  var style3 = css3`
757
- :host {
758
- position: absolute;
759
- background-color: white;
760
- box-shadow: 0 1rem 1rem 1rem rgba(0, 0, 0, 0.1);
758
+ :host([open]) dialog {
759
+ opacity: 1;
760
+ transform: translate3d(0, 0, 0);
761
+ visibility: visible;
762
+ }
763
+
764
+ dialog {
765
+ inset: auto;
766
+ position: fixed;
767
+ overflow: hidden;
768
+ padding: 0px;
769
+ box-sizing: border-box;
770
+ border-width: 0;
771
+ right: 0;
761
772
  }
762
773
  `;
763
774
  var popover_styles_default = style3;
764
775
 
765
776
  // libs/core/src/primitives/popover/popover.ts
766
- var _dialogElementRef, _handleCloseButton, _registerTriggerEvents, registerTriggerEvents_fn, _unregisterTriggerEvents, unregisterTriggerEvents_fn, _autoPositionCleanup, _registerAutoPositioning, registerAutoPositioning_fn, _triggerKeyDownListener, _focusFirstSlottedChild, _clickOutsideListener;
777
+ var _dialogElementRef, _autoPositionCleanupFn, _isMobileViewport, _handleCloseButton, _registerTriggerEvents, registerTriggerEvents_fn, _unregisterTriggerEvents, unregisterTriggerEvents_fn, _registerAutoPositioning, registerAutoPositioning_fn, _triggerKeyDownListener, _focusFirstSlottedChild, _clickOutsideListener;
767
778
  var GdsPopover = class extends LitElement3 {
768
779
  constructor() {
769
780
  super(...arguments);
@@ -774,15 +785,20 @@ var GdsPopover = class extends LitElement3 {
774
785
  this.triggerRef = Promise.resolve(void 0);
775
786
  this.label = void 0;
776
787
  this.placement = "bottom-start";
788
+ this.calcMaxWidth = (_referenceEl) => `auto`;
777
789
  this._trigger = void 0;
790
+ this._isVirtKbVisible = false;
791
+ // A reference to the dialog element used to make the popover modal
778
792
  __privateAdd(this, _dialogElementRef, createRef2());
793
+ // A function that removes the Floating UI auto positioning. This gets called when we switch to mobile view layout.
794
+ __privateAdd(this, _autoPositionCleanupFn, void 0);
795
+ __privateAdd(this, _isMobileViewport, false);
779
796
  __privateAdd(this, _handleCloseButton, (e) => {
780
797
  e.stopPropagation();
781
798
  e.preventDefault();
782
799
  this.open = false;
783
800
  setTimeout(() => this._trigger?.focus(), 250);
784
801
  });
785
- __privateAdd(this, _autoPositionCleanup, void 0);
786
802
  /**
787
803
  * ArrowDown on the trigger element will trigger the popover by default, and escape will close it.
788
804
  */
@@ -836,13 +852,27 @@ var GdsPopover = class extends LitElement3 {
836
852
  e.stopImmediatePropagation();
837
853
  }
838
854
  });
855
+ this.addEventListener("focusin", (e) => {
856
+ const t = e.target;
857
+ if (t.tagName === "INPUT" || t.tagName === "TEXTAREA") {
858
+ this._isVirtKbVisible = true;
859
+ } else {
860
+ this._isVirtKbVisible = false;
861
+ }
862
+ });
863
+ this.addEventListener("blurin", (_) => {
864
+ this._isVirtKbVisible = false;
865
+ });
839
866
  }
840
867
  disconnectedCallback() {
841
868
  super.disconnectedCallback();
842
869
  __privateMethod(this, _unregisterTriggerEvents, unregisterTriggerEvents_fn).call(this);
843
870
  }
844
871
  render() {
845
- return html3`<dialog ${ref2(__privateGet(this, _dialogElementRef))}>
872
+ return html3`<dialog
873
+ class="${classMap2({ "v-kb-visible": this._isVirtKbVisible })}"
874
+ ${ref2(__privateGet(this, _dialogElementRef))}
875
+ >
846
876
  <header>
847
877
  <h2>${this.label}</h2>
848
878
  <button
@@ -888,10 +918,12 @@ var GdsPopover = class extends LitElement3 {
888
918
  }
889
919
  _handleMobileLayout(matches) {
890
920
  var _a;
921
+ __privateSet(this, _isMobileViewport, matches);
891
922
  if (matches) {
892
- (_a = __privateGet(this, _autoPositionCleanup)) == null ? void 0 : _a.call(this);
923
+ (_a = __privateGet(this, _autoPositionCleanupFn)) == null ? void 0 : _a.call(this);
893
924
  __privateGet(this, _dialogElementRef).value?.style.removeProperty("left");
894
925
  __privateGet(this, _dialogElementRef).value?.style.removeProperty("top");
926
+ __privateGet(this, _dialogElementRef).value?.style.removeProperty("minWidth");
895
927
  this.updateComplete.then(() => {
896
928
  if (this.open)
897
929
  __privateGet(this, _dialogElementRef).value?.showModal();
@@ -904,6 +936,8 @@ var GdsPopover = class extends LitElement3 {
904
936
  }
905
937
  };
906
938
  _dialogElementRef = new WeakMap();
939
+ _autoPositionCleanupFn = new WeakMap();
940
+ _isMobileViewport = new WeakMap();
907
941
  _handleCloseButton = new WeakMap();
908
942
  _registerTriggerEvents = new WeakSet();
909
943
  registerTriggerEvents_fn = function() {
@@ -913,16 +947,18 @@ _unregisterTriggerEvents = new WeakSet();
913
947
  unregisterTriggerEvents_fn = function() {
914
948
  var _a;
915
949
  this._trigger?.removeEventListener("keydown", __privateGet(this, _triggerKeyDownListener));
916
- (_a = __privateGet(this, _autoPositionCleanup)) == null ? void 0 : _a.call(this);
950
+ (_a = __privateGet(this, _autoPositionCleanupFn)) == null ? void 0 : _a.call(this);
917
951
  };
918
- _autoPositionCleanup = new WeakMap();
919
952
  _registerAutoPositioning = new WeakSet();
920
953
  registerAutoPositioning_fn = function() {
921
954
  const referenceEl = this._trigger;
922
955
  const floatingEl = __privateGet(this, _dialogElementRef).value;
923
- if (!referenceEl || !floatingEl)
956
+ if (!referenceEl || !floatingEl || __privateGet(this, _isMobileViewport))
924
957
  return;
925
- __privateSet(this, _autoPositionCleanup, autoUpdate(referenceEl, floatingEl, () => {
958
+ if (__privateGet(this, _autoPositionCleanupFn)) {
959
+ __privateGet(this, _autoPositionCleanupFn).call(this);
960
+ }
961
+ __privateSet(this, _autoPositionCleanupFn, autoUpdate(referenceEl, floatingEl, () => {
926
962
  computePosition(referenceEl, floatingEl, {
927
963
  placement: this.placement,
928
964
  middleware: [offset(8), flip(), topLayerOverTransforms()],
@@ -931,7 +967,8 @@ registerAutoPositioning_fn = function() {
931
967
  ({ x, y }) => Object.assign(floatingEl.style, {
932
968
  left: `${x}px`,
933
969
  top: `${y}px`,
934
- minWidth: `${referenceEl.offsetWidth}px`
970
+ minWidth: `${referenceEl.offsetWidth}px`,
971
+ maxWidth: `${this.calcMaxWidth(referenceEl)}`
935
972
  })
936
973
  );
937
974
  }));
@@ -952,9 +989,15 @@ __decorateClass([
952
989
  __decorateClass([
953
990
  property3()
954
991
  ], GdsPopover.prototype, "placement", 2);
992
+ __decorateClass([
993
+ property3()
994
+ ], GdsPopover.prototype, "calcMaxWidth", 2);
955
995
  __decorateClass([
956
996
  state()
957
997
  ], GdsPopover.prototype, "_trigger", 2);
998
+ __decorateClass([
999
+ state()
1000
+ ], GdsPopover.prototype, "_isVirtKbVisible", 2);
958
1001
  __decorateClass([
959
1002
  watch("triggerRef")
960
1003
  ], GdsPopover.prototype, "_handleTriggerRefChanged", 1);
@@ -1078,6 +1121,7 @@ var style4 = css4`
1078
1121
  color: white;
1079
1122
  padding: 0.7rem 2rem;
1080
1123
  margin: 0.5rem 0;
1124
+ box-sizing: border-box;
1081
1125
  }
1082
1126
  `;
1083
1127
  var dropdown_styles_default = style4;
@@ -1101,6 +1145,7 @@ var GdsDropdown = class extends GdsFormControlElement {
1101
1145
  this.multiple = false;
1102
1146
  this.compareWith = (a, b) => a === b;
1103
1147
  this.searchFilter = (q, o) => o.innerHTML.toLowerCase().includes(q.toLowerCase());
1148
+ this.syncPopoverWidth = false;
1104
1149
  // Private members
1105
1150
  __privateAdd(this, _optionElements, void 0);
1106
1151
  /**
@@ -1237,6 +1282,7 @@ var GdsDropdown = class extends GdsFormControlElement {
1237
1282
  .label=${this.label}
1238
1283
  .open=${this.open}
1239
1284
  .triggerRef=${this.elTriggerBtnAsync}
1285
+ .calcMaxWidth=${(trigger) => this.syncPopoverWidth ? `${trigger.offsetWidth}px` : `auto`}
1240
1286
  @gds-ui-state=${(e) => this.open = e.detail.open}
1241
1287
  >
1242
1288
  ${when2(
@@ -1368,6 +1414,9 @@ __decorateClass([
1368
1414
  __decorateClass([
1369
1415
  property5()
1370
1416
  ], GdsDropdown.prototype, "searchFilter", 2);
1417
+ __decorateClass([
1418
+ property5({ type: Boolean })
1419
+ ], GdsDropdown.prototype, "syncPopoverWidth", 2);
1371
1420
  __decorateClass([
1372
1421
  query("#trigger")
1373
1422
  ], GdsDropdown.prototype, "elTriggerBtn", 2);
@@ -1396,7 +1445,7 @@ GdsDropdown = __decorateClass([
1396
1445
  // libs/core/src/components/context-menu/context-menu.ts
1397
1446
  import { LitElement as LitElement6 } from "lit";
1398
1447
  import { msg as msg3 } from "@lit/localize";
1399
- import { classMap as classMap2 } from "lit-html/directives/class-map.js";
1448
+ import { classMap as classMap3 } from "lit-html/directives/class-map.js";
1400
1449
  import { property as property6, queryAsync as queryAsync2 } from "lit/decorators.js";
1401
1450
 
1402
1451
  // libs/core/src/primitives/menu/menu.ts
@@ -1462,7 +1511,7 @@ var GdsContextMenu = class extends LitElement6 {
1462
1511
  render() {
1463
1512
  return html`<button
1464
1513
  id="trigger"
1465
- class="ghost border-0 small ${classMap2({ highlighted: this.open })}"
1514
+ class="ghost border-0 small ${classMap3({ highlighted: this.open })}"
1466
1515
  aria-label="${this.buttonLabel}"
1467
1516
  aria-haspopup="menu"
1468
1517
  aria-controls="menu"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sebgroup/green-core",
3
3
  "description": "A carefully crafted set of Web Components, laying the foundation of the Green Design System.",
4
- "version": "1.2.3",
4
+ "version": "1.3.0",
5
5
  "main": "index.js",
6
6
  "module": "index.js",
7
7
  "type": "module",
@@ -33,7 +33,13 @@ export declare class GdsPopover extends LitElement {
33
33
  * Accepts any of the placements supported by Floating UI.
34
34
  */
35
35
  placement: Placement;
36
+ /**
37
+ * A callback that returns the maximum width of the popover.
38
+ * By default, the popover maxWidth will be set to `auto` and will grow as needed.
39
+ */
40
+ calcMaxWidth: (_referenceEl: HTMLElement) => string;
36
41
  private _trigger;
42
+ private _isVirtKbVisible;
37
43
  private _handleTriggerRefChanged;
38
44
  private _handleTriggerChanged;
39
45
  connectedCallback(): void;
@@ -3800,6 +3800,7 @@ a.button.tertiary.danger:focus-visible {
3800
3800
  }
3801
3801
 
3802
3802
  :host([open]) dialog {
3803
+ box-sizing: border-box;
3803
3804
  opacity: 1;
3804
3805
  transform: translate3d(0, 0, 0);
3805
3806
  visibility: visible;
@@ -3808,13 +3809,16 @@ a.button.tertiary.danger:focus-visible {
3808
3809
  header {
3809
3810
  border-bottom: 1px solid var(--border-color);
3810
3811
  display: flex;
3811
- padding: 0.5rem 0.75rem;
3812
+ padding: 0.25rem 0.75rem;
3812
3813
  }
3813
3814
  @media (min-width: 36em) {
3814
3815
  header {
3815
3816
  display: none;
3816
3817
  }
3817
3818
  }
3819
+ header button.close {
3820
+ margin: -0.25rem;
3821
+ }
3818
3822
 
3819
3823
  header h2 {
3820
3824
  flex-grow: 1;
@@ -3885,7 +3889,13 @@ dialog .close {
3885
3889
  }
3886
3890
  @media (max-width: 35.98em) {
3887
3891
  dialog {
3888
- border-radius: 1rem;
3892
+ border-radius: 0.5rem;
3893
+ max-height: 80svh;
3894
+ }
3895
+ dialog.v-kb-visible {
3896
+ inset-block-end: auto;
3897
+ max-height: 50svh;
3898
+ top: 1rem;
3889
3899
  }
3890
3900
  }
3891
3901
  @media (min-width: 36em) {
@@ -6347,7 +6357,7 @@ function register4() {
6347
6357
  // libs/core/src/utils/helpers/custom-element-scoping.ts
6348
6358
  import { html as litHtml } from "lit";
6349
6359
  import { customElement } from "lit/decorators.js";
6350
- var VER_SUFFIX = "-b059fe";
6360
+ var VER_SUFFIX = "-f38327";
6351
6361
  var elementLookupTable = /* @__PURE__ */ new Map();
6352
6362
  var templateCache = /* @__PURE__ */ new WeakMap();
6353
6363
  function applyElementScoping(strings, ...values) {