@descope-ui/descope-attachment 3.7.0 → 3.7.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descope-ui/descope-attachment",
3
- "version": "3.7.0",
3
+ "version": "3.7.2",
4
4
  "files": [
5
5
  "src",
6
6
  "stories"
@@ -18,13 +18,14 @@
18
18
  },
19
19
  "devDependencies": {
20
20
  "@playwright/test": "1.58.2",
21
- "e2e-utils": "3.7.0",
22
- "test-assets": "3.7.0",
23
- "test-drivers": "3.7.0"
21
+ "e2e-utils": "3.7.2",
22
+ "test-assets": "3.7.2",
23
+ "test-drivers": "3.7.2"
24
24
  },
25
25
  "dependencies": {
26
- "@descope-ui/common": "3.7.0",
27
- "@descope-ui/theme-globals": "3.7.0"
26
+ "@descope-ui/theme-globals": "3.7.2",
27
+ "@descope-ui/common": "3.7.2",
28
+ "@descope-ui/descope-anchored": "3.7.2"
28
29
  },
29
30
  "publishConfig": {
30
31
  "link-workspace-packages": false
@@ -7,6 +7,7 @@ import { createBaseClass } from '@descope-ui/common/base-classes';
7
7
  import {
8
8
  getComponentName,
9
9
  injectStyle,
10
+ observeAttributes,
10
11
  } from '@descope-ui/common/components-helpers';
11
12
  import { compose } from '@descope-ui/common/utils';
12
13
 
@@ -25,18 +26,18 @@ const DEFAULT_POSITION = ATTACHMENT_POSITIONS[0];
25
26
 
26
27
  class RawAttachment extends createBaseClass({
27
28
  componentName,
28
- baseSelector: ':host > .wrapper',
29
+ baseSelector: 'descope-anchored',
29
30
  }) {
30
31
  constructor() {
31
32
  super();
32
33
 
33
34
  this.attachShadow({ mode: 'open' }).innerHTML = `
34
- <div class="wrapper">
35
+ <descope-anchored>
35
36
  <slot></slot>
36
- <div class="attachment-container">
37
+ <div slot="anchored" class="attachment-container">
37
38
  <slot name="attachment"></slot>
38
39
  </div>
39
- </div>
40
+ </descope-anchored>
40
41
  `;
41
42
 
42
43
  this.defaultSlot = this.shadowRoot.querySelector('slot:not([name])');
@@ -45,6 +46,10 @@ class RawAttachment extends createBaseClass({
45
46
  );
46
47
  }
47
48
 
49
+ get #attachment() {
50
+ return this.attachmentSlot?.assignedElements()[0];
51
+ }
52
+
48
53
  static get observedAttributes() {
49
54
  return [...(super.observedAttributes || []), 'position'];
50
55
  }
@@ -64,9 +69,8 @@ class RawAttachment extends createBaseClass({
64
69
  :host {
65
70
  display: inline-block;
66
71
  }
67
- .wrapper {
68
- position: relative;
69
- display: inline-flex;
72
+ :host(.hidden) {
73
+ display: none;
70
74
  }
71
75
  .attachment-container {
72
76
  position: absolute;
@@ -77,24 +81,43 @@ class RawAttachment extends createBaseClass({
77
81
  align-items: center;
78
82
  container-type: inline-size;
79
83
  }
80
- :host(.hidden) {
81
- display: none;
82
- }
83
- `,
84
+ `,
84
85
  this,
85
86
  );
86
87
 
87
88
  this.#handlePositionChange();
88
89
 
89
- this.defaultSlot.addEventListener('slotchange', () => {
90
- this.#setVisibility();
91
- this.#syncDirection();
90
+ // When descope-anchored forwards st-host-direction from the anchor to this container,
91
+ // propagate it to the attachment elements.
92
+ const container = this.shadowRoot.querySelector('.attachment-container');
93
+ observeAttributes(container, () => this.#syncDirection(), {
94
+ includeAttrs: ['st-host-direction'],
92
95
  });
93
96
 
94
- window.requestAnimationFrame(() => {
97
+ // Re-sync direction when new elements are slotted into the attachment slot.
98
+ this.attachmentSlot.addEventListener('slotchange', () =>
99
+ this.#syncDirection(),
100
+ );
101
+
102
+ this.defaultSlot.addEventListener('slotchange', () => {
95
103
  this.#setVisibility();
96
- this.#syncDirection();
104
+ window.requestAnimationFrame(() => this.#syncAvailableSizeAttr());
97
105
  });
106
+
107
+ window.requestAnimationFrame(() => this.#setVisibility());
108
+ }
109
+
110
+ #syncAvailableSizeAttr() {
111
+ const anchor = this.defaultSlot?.assignedElements()?.[0];
112
+
113
+ const anchorRect = anchor?.getBoundingClientRect();
114
+ if (anchorRect) {
115
+ const availableWidth = anchorRect.width;
116
+ this.#attachment?.setAttribute(
117
+ 'data-attachment-size',
118
+ Number(availableWidth),
119
+ );
120
+ }
98
121
  }
99
122
 
100
123
  #setVisibility() {
@@ -103,16 +126,14 @@ class RawAttachment extends createBaseClass({
103
126
  }
104
127
 
105
128
  #syncDirection() {
106
- const child = this.defaultSlot?.assignedElements()?.[0];
107
- if (!child) return;
108
-
109
- const { direction } = window.getComputedStyle(child);
129
+ const direction = this.shadowRoot
130
+ .querySelector('.attachment-container')
131
+ ?.getAttribute('st-host-direction');
110
132
 
133
+ if (!direction) return;
111
134
  // currently we support direction sync only for web-components-ui
112
135
  // elements, which support st-host-direction attribute.
113
- this.attachmentSlot?.assignedElements().forEach((el) => {
114
- el.setAttribute('st-host-direction', direction);
115
- });
136
+ this.#attachment?.setAttribute('st-host-direction', direction);
116
137
  }
117
138
 
118
139
  get offsetX() {
@@ -1,3 +1,4 @@
1
+ import '@descope-ui/descope-anchored';
1
2
  import { componentName, AttachmentClass } from './AttachmentClass';
2
3
 
3
4
  customElements.define(componentName, AttachmentClass);
@@ -4,12 +4,13 @@ import { base64svg } from 'test-assets';
4
4
 
5
5
  const SIZES = ['xs', 'sm', 'md', 'lg'];
6
6
 
7
- const button = (size, { direction, label } = {}) => `
7
+ const button = (size, { direction, label, 'full-width': fullWidth } = {}) => `
8
8
  <descope-button
9
9
  variant="outline"
10
10
  mode="primary"
11
11
  size="${size}"
12
12
  ${direction ? ` st-host-direction="${direction}"` : ''}
13
+ ${fullWidth ? ' full-width="true"' : ''}
13
14
  ${label ? '' : ' square="true"'}>
14
15
  ${label || `<descope-icon src=${base64svg}></descope-icon>`}
15
16
  </descope-button>
@@ -42,6 +43,13 @@ const Template = ({
42
43
  'offset-y': offsetY,
43
44
  }) => `
44
45
  <div class="item">
46
+ ${attachment(
47
+ position,
48
+ button('md', { direction, label: buttonLabel, 'full-width': true }),
49
+ badgeLabel,
50
+ offsetX,
51
+ offsetY,
52
+ )}
45
53
  ${SIZES.map((size) =>
46
54
  attachment(
47
55
  position,