@descope-ui/descope-outbound-app-button 0.0.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
+
5
+ ## 0.0.1 (2025-08-20)
6
+
7
+ ### Dependency Updates
8
+
9
+ * `e2e-utils` updated to version `0.0.1`
10
+ * `test-assets` updated to version `0.0.1`
11
+ * `@descope-ui/common` updated to version `0.0.18`
12
+ * `@descope-ui/theme-globals` updated to version `0.0.19`
13
+ * `@descope-ui/descope-icon` updated to version `0.0.17`
14
+ * `@descope-ui/descope-button` updated to version `0.0.19`
15
+ # Changelog
@@ -0,0 +1,91 @@
1
+ import { expect, test } from '@playwright/test';
2
+ import { getStoryUrl, loopConfig, loopPresets } from 'e2e-utils';
3
+
4
+ const componentAttributes = {
5
+ mode: ['primary', 'secondary', 'success', 'error'],
6
+ variant: ['contained', 'outline', 'link'],
7
+ size: ['xs', 'sm', 'md', 'lg'],
8
+ 'full-width': ['true', 'false'],
9
+ iconSrc: ['true', 'false'],
10
+ };
11
+
12
+ const presets = {
13
+ 'direction rtl': { direction: 'rtl', label: '-Click Me' },
14
+ 'direction rtl with icon': {
15
+ direction: 'rtl',
16
+ label: '-Click Me',
17
+ iconSrc: 'true',
18
+ },
19
+ };
20
+
21
+ const storyName = 'descope-outbound-app-button';
22
+ const componentName = 'descope-outbound-app-button';
23
+
24
+ test.describe('theme', () => {
25
+ loopConfig(componentAttributes, (attr, value) => {
26
+ test.describe(`${attr}: ${value}`, () => {
27
+ test.beforeEach(async ({ page }) => {
28
+ await page.goto(getStoryUrl(storyName, { [attr]: value }), {
29
+ waitUntil: 'load',
30
+ });
31
+ });
32
+ test('hover', async ({ page }) => {
33
+ const component = page.locator(componentName);
34
+
35
+ await component.hover();
36
+
37
+ expect(await component.screenshot()).toMatchSnapshot();
38
+ });
39
+
40
+ test('focus', async ({ page }) => {
41
+ const component = page.locator(componentName);
42
+
43
+ await component.focus();
44
+
45
+ expect(await component.screenshot()).toMatchSnapshot();
46
+ });
47
+
48
+ test('active', async ({ page }) => {
49
+ const component = page.locator(componentName);
50
+
51
+ await component.hover();
52
+ await page.mouse.down();
53
+
54
+ expect(await component.screenshot()).toMatchSnapshot();
55
+ });
56
+ });
57
+ });
58
+
59
+ loopPresets(presets, (preset, name) => {
60
+ test(name, async ({ page }) => {
61
+ await page.goto(getStoryUrl(storyName, preset));
62
+ await page.waitForSelector(componentName);
63
+ const component = page.locator(componentName);
64
+ expect(
65
+ await component.screenshot({
66
+ animations: 'disabled',
67
+ timeout: 3000,
68
+ caret: 'hide',
69
+ }),
70
+ ).toMatchSnapshot();
71
+ });
72
+ });
73
+ });
74
+
75
+ test.describe('other', () => {
76
+ test('disabled', async ({ page }) => {
77
+ await page.goto(getStoryUrl(storyName, { disabled: 'true' }), {
78
+ waitUntil: 'networkidle',
79
+ });
80
+ const component = page.locator(componentName);
81
+ expect(await component.screenshot()).toMatchSnapshot();
82
+ });
83
+
84
+ test('square', async ({ page }) => {
85
+ await page.goto(getStoryUrl(storyName, { square: 'true', label: '', iconSrc: true }), {
86
+ waitUntil: 'networkidle',
87
+ });
88
+ const component = page.locator(componentName);
89
+ expect(await component.screenshot()).toMatchSnapshot();
90
+ });
91
+ });
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@descope-ui/descope-outbound-app-button",
3
+ "version": "0.0.1",
4
+ "exports": {
5
+ ".": {
6
+ "import": "./src/component/index.js"
7
+ },
8
+ "./theme": {
9
+ "import": "./src/theme.js"
10
+ },
11
+ "./class": {
12
+ "import": "./src/component/OutboundAppButtonClass.js"
13
+ }
14
+ },
15
+ "devDependencies": {
16
+ "@playwright/test": "1.38.1",
17
+ "e2e-utils": "0.0.1",
18
+ "test-assets": "0.0.1"
19
+ },
20
+ "dependencies": {
21
+ "@descope-ui/common": "0.0.18",
22
+ "@descope-ui/theme-globals": "0.0.19",
23
+ "@descope-ui/descope-icon": "0.0.17",
24
+ "@descope-ui/descope-button": "0.0.19"
25
+ },
26
+ "publishConfig": {
27
+ "link-workspace-packages": false
28
+ },
29
+ "scripts": {
30
+ "test": "echo 'No tests defined' && exit 0",
31
+ "test:e2e": "echo 'No e2e tests defined' && exit 0"
32
+ }
33
+ }
package/project.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@descope-ui/descope-outbound-app-button",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "packages/web-components/components/descope-outbound-app-button/src",
5
+ "projectType": "library",
6
+ "targets": {
7
+ "version": {
8
+ "executor": "@jscutlery/semver:version",
9
+ "options": {
10
+ "trackDeps": true,
11
+ "push": false,
12
+ "preset": "conventional"
13
+ }
14
+ }
15
+ },
16
+ "tags": []
17
+ }
@@ -0,0 +1,85 @@
1
+ import {
2
+ componentNameValidationMixin,
3
+ createStyleMixin,
4
+ draggableMixin,
5
+ } from '@descope-ui/common/components-mixins';
6
+ import {
7
+ forwardAttrs,
8
+ getComponentName,
9
+ injectStyle,
10
+ } from '@descope-ui/common/components-helpers';
11
+ import { compose } from '@descope-ui/common/utils';
12
+ import { createBaseClass } from '@descope-ui/common/base-classes';
13
+
14
+ export const componentName = getComponentName('outbound-app-button');
15
+
16
+ class RawOutboundAppButton extends createBaseClass({
17
+ componentName,
18
+ baseSelector: ':host > descope-button',
19
+ }) {
20
+ static get observedAttributes() {
21
+ return ['label', 'icon-src'];
22
+ }
23
+
24
+ constructor() {
25
+ super();
26
+
27
+ this.attachShadow({ mode: 'open' }).innerHTML = `
28
+ <descope-button>
29
+ <descope-icon class="icon"></descope-icon>
30
+ <span class="label"></span>
31
+ </descope-button>
32
+ `;
33
+
34
+ injectStyle(`
35
+ :host {
36
+ display: inline-block;
37
+ }
38
+ .hidden {
39
+ display: none;
40
+ }
41
+ `, this);
42
+
43
+ this.button = this.shadowRoot.querySelector('descope-button');
44
+ this.icon = this.shadowRoot.querySelector('.icon');
45
+ this.label = this.shadowRoot.querySelector('.label');
46
+ }
47
+
48
+ init() {
49
+ super.init?.();
50
+
51
+ forwardAttrs(this, this.button, { excludeAttrs: ['style', 'class'] });
52
+ }
53
+
54
+ updateLabel(val = '') {
55
+ this.label.textContent = val;
56
+ this.label.classList.toggle('hidden', !val);
57
+ }
58
+
59
+ updateIcon(val = '') {
60
+ this.icon.setAttribute('src', val);
61
+ this.icon.classList.toggle('hidden', !val);
62
+ }
63
+
64
+ attributeChangedCallback(attrName, oldValue, newValue) {
65
+ super.attributeChangedCallback?.(attrName, oldValue, newValue);
66
+
67
+ if (oldValue !== newValue) {
68
+ if (attrName === 'label') {
69
+ this.updateLabel(newValue);
70
+ } else if (attrName === 'icon-src') {
71
+ this.updateIcon(newValue);
72
+ }
73
+ }
74
+ }
75
+ }
76
+
77
+ export const OutboundAppButtonClass = compose(
78
+ createStyleMixin({
79
+ mappings: {
80
+ hostWidth: { selector: () => ':host', property: 'width' },
81
+ },
82
+ }),
83
+ draggableMixin,
84
+ componentNameValidationMixin,
85
+ )(RawOutboundAppButton);
@@ -0,0 +1,10 @@
1
+ import {
2
+ componentName,
3
+ OutboundAppButtonClass,
4
+ } from './OutboundAppButtonClass';
5
+ import '@descope-ui/descope-button';
6
+ import '@descope-ui/descope-icon';
7
+
8
+ customElements.define(componentName, OutboundAppButtonClass);
9
+
10
+ export { OutboundAppButtonClass, componentName };
package/src/theme.js ADDED
@@ -0,0 +1,13 @@
1
+ import { OutboundAppButtonClass } from './component/OutboundAppButtonClass';
2
+
3
+ const compVars = OutboundAppButtonClass.cssVarList;
4
+
5
+ const outboundAppButton = {
6
+ _fullWidth: {
7
+ [compVars.hostWidth]: '100%',
8
+ },
9
+ };
10
+
11
+ export default outboundAppButton;
12
+
13
+ export const vars = compVars;
@@ -0,0 +1,95 @@
1
+ import { componentName } from '../src/component';
2
+ import {
3
+ sizeControl,
4
+ modeControl,
5
+ buttonVariantControl,
6
+ loadingControl,
7
+ fullWidthControl,
8
+ disabledControl,
9
+ directionControl,
10
+ textAlignControl,
11
+ labelSpacingControl,
12
+ } from '@descope-ui/common/sb-controls';
13
+
14
+ import { base64svg, errorMessageIconBase64 } from 'test-assets';
15
+
16
+ const Template = ({
17
+ variant,
18
+ mode,
19
+ size,
20
+ loading,
21
+ square,
22
+ 'full-width': fullWidth,
23
+ disabled,
24
+ direction,
25
+ 'text-align': textAlign,
26
+ 'label-spacing': spacing,
27
+ label,
28
+ iconSrc,
29
+ iconDarkSrc,
30
+ }) => `
31
+ <style nonce="${window.DESCOPE_NONCE}">
32
+ .wrapper {
33
+ --descope-button-icon-color: currentColor;
34
+ }
35
+ </style>
36
+ <div class="wrapper">
37
+ <descope-outbound-app-button
38
+ mode="${mode}"
39
+ variant="${variant}"
40
+ size="${size}"
41
+ loading="${loading || false}"
42
+ disabled="${disabled || false}"
43
+ square="${square || false}"
44
+ full-width="${fullWidth || false}"
45
+ text-align="${textAlign}"
46
+ st-label-spacing="${spacing}px"
47
+ st-host-direction="${direction ?? ''}"
48
+ label="${label || ''}"
49
+ icon-src="${iconSrc ? base64svg : ''}"
50
+ </descope-outbound-app-button>
51
+ </div>
52
+ `;
53
+
54
+ export default {
55
+ component: componentName,
56
+ title: 'descope-outbound-app-button',
57
+ argTypes: {
58
+ ...modeControl,
59
+ ...sizeControl,
60
+ ...buttonVariantControl,
61
+ ...loadingControl,
62
+ ...fullWidthControl,
63
+ ...disabledControl,
64
+ ...directionControl,
65
+ ...textAlignControl,
66
+ ...labelSpacingControl,
67
+ square: {
68
+ name: 'Square',
69
+ control: { type: 'boolean' },
70
+ },
71
+ label: {
72
+ name: 'Label',
73
+ control: { type: 'text' },
74
+ },
75
+ iconSrc: {
76
+ name: 'icon-src',
77
+ control: { type: 'boolean' },
78
+ },
79
+ },
80
+ };
81
+
82
+ export const Default = Template.bind({});
83
+
84
+ Default.args = {
85
+ variant: 'contained',
86
+ mode: 'primary',
87
+ size: 'md',
88
+ loading: false,
89
+ 'full-width': false,
90
+ 'text-align': 'center',
91
+ 'label-spacing': 4,
92
+ label: 'Outbound Application',
93
+ iconSrc: false,
94
+ iconDarkSrc: false
95
+ };