@descope/web-components-ui 3.1.12 → 3.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descope/web-components-ui",
3
- "version": "3.1.12",
3
+ "version": "3.2.0",
4
4
  "description": "",
5
5
  "main": "dist/cjs/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -51,10 +51,10 @@
51
51
  "webpack-cli": "^7.0.0",
52
52
  "webpack-dev-server": "^5.0.0",
53
53
  "webpack-subresource-integrity": "5.2.0-rc.1",
54
- "rollup-replace-plugin": "3.1.12",
55
- "test-drivers": "3.1.12",
56
- "webpack-extract-font-loader": "3.1.12",
57
- "webpack-replace-plugin": "3.1.12"
54
+ "rollup-replace-plugin": "3.2.0",
55
+ "webpack-extract-font-loader": "3.2.0",
56
+ "test-drivers": "3.2.0",
57
+ "webpack-replace-plugin": "3.2.0"
58
58
  },
59
59
  "dependencies": {
60
60
  "@vaadin/checkbox": "24.3.4",
@@ -78,32 +78,33 @@
78
78
  "libphonenumber-js": "^1.11.12",
79
79
  "lodash.debounce": "4.0.8",
80
80
  "lodash.merge": "4.6.2",
81
- "@descope-ui/descope-address-field": "3.1.12",
82
- "@descope-ui/descope-country-subdivision-city-field": "3.1.12",
83
- "@descope-ui/descope-apps-list": "3.1.12",
84
- "@descope-ui/descope-autocomplete-field": "3.1.12",
85
- "@descope-ui/descope-avatar": "3.1.12",
86
- "@descope-ui/descope-badge": "3.1.12",
87
- "@descope-ui/descope-button": "3.1.12",
88
- "@descope-ui/descope-combo-box": "3.1.12",
89
- "@descope-ui/descope-enriched-text": "3.1.12",
90
- "@descope-ui/descope-icon": "3.1.12",
91
- "@descope-ui/descope-list": "3.1.12",
92
- "@descope-ui/descope-list-item": "3.1.12",
93
- "@descope-ui/descope-image": "3.1.12",
94
- "@descope-ui/common": "3.1.12",
95
- "@descope-ui/descope-outbound-app-button": "3.1.12",
96
- "@descope-ui/descope-outbound-apps": "3.1.12",
97
- "@descope-ui/descope-password-strength": "3.1.12",
98
- "@descope-ui/descope-ponyhot": "3.1.12",
99
- "@descope-ui/descope-collapsible-container": "3.1.12",
100
- "@descope-ui/descope-timer-button": "3.1.12",
101
- "@descope-ui/descope-link": "3.1.12",
102
- "@descope-ui/descope-recovery-codes": "3.1.12",
103
- "@descope-ui/descope-trusted-devices": "3.1.12",
104
- "@descope-ui/descope-tooltip": "3.1.12",
105
- "@descope-ui/descope-timer": "3.1.12",
106
- "@descope-ui/descope-text": "3.1.12"
81
+ "@descope-ui/common": "3.2.0",
82
+ "@descope-ui/descope-country-subdivision-city-field": "3.2.0",
83
+ "@descope-ui/descope-address-field": "3.2.0",
84
+ "@descope-ui/descope-apps-list": "3.2.0",
85
+ "@descope-ui/descope-autocomplete-field": "3.2.0",
86
+ "@descope-ui/descope-avatar": "3.2.0",
87
+ "@descope-ui/descope-badge": "3.2.0",
88
+ "@descope-ui/descope-button": "3.2.0",
89
+ "@descope-ui/descope-combo-box": "3.2.0",
90
+ "@descope-ui/descope-enriched-text": "3.2.0",
91
+ "@descope-ui/descope-icon": "3.2.0",
92
+ "@descope-ui/descope-image": "3.2.0",
93
+ "@descope-ui/descope-link": "3.2.0",
94
+ "@descope-ui/descope-list": "3.2.0",
95
+ "@descope-ui/descope-list-item": "3.2.0",
96
+ "@descope-ui/descope-outbound-app-button": "3.2.0",
97
+ "@descope-ui/descope-outbound-apps": "3.2.0",
98
+ "@descope-ui/descope-password-strength": "3.2.0",
99
+ "@descope-ui/descope-ponyhot": "3.2.0",
100
+ "@descope-ui/descope-recovery-codes": "3.2.0",
101
+ "@descope-ui/descope-timer": "3.2.0",
102
+ "@descope-ui/descope-timer-button": "3.2.0",
103
+ "@descope-ui/descope-tooltip": "3.2.0",
104
+ "@descope-ui/descope-trusted-devices": "3.2.0",
105
+ "@descope-ui/descope-attachment": "3.2.0",
106
+ "@descope-ui/descope-text": "3.2.0",
107
+ "@descope-ui/descope-collapsible-container": "3.2.0"
107
108
  },
108
109
  "overrides": {
109
110
  "@vaadin/avatar": "24.3.4",
package/src/constants.js CHANGED
@@ -1,4 +1,3 @@
1
1
  export const DESCOPE_PREFIX = 'descope';
2
2
  export const CSS_SELECTOR_SPECIFIER_MULTIPLY = 5;
3
3
  export const BASE_THEME_SECTION = 'host';
4
- export const PORTAL_THEME_PREFIX = '@';
@@ -1,5 +1,5 @@
1
1
  import merge from 'lodash.merge';
2
- import { BASE_THEME_SECTION, DESCOPE_PREFIX, PORTAL_THEME_PREFIX } from '../../constants';
2
+ import { BASE_THEME_SECTION, DESCOPE_PREFIX } from '../../constants';
3
3
  import { isUrl, kebabCase } from '..';
4
4
  import { getComponentName, getCssVarName } from '../componentHelpers';
5
5
 
@@ -69,6 +69,13 @@ function splitAmpersands(str) {
69
69
  return [match[1] || '', match[2] || ''];
70
70
  }
71
71
 
72
+ const CONTAINER_QUERY_PREFIX = '@container';
73
+ const isContainerQuery = (key) => key.startsWith(CONTAINER_QUERY_PREFIX);
74
+
75
+ const BREAKPOINTS_KEY = '$breakpoints';
76
+ const BREAKPOINTS_REF_PREFIX = '$breakpoints.';
77
+ const isBreakpointRef = (key) => key.startsWith(BREAKPOINTS_REF_PREFIX);
78
+
72
79
  // st attributes are also using selector multiplication
73
80
  // so we need to limit the multiplication
74
81
  const MAX_SELECTOR_MULTIPLY = 3;
@@ -76,6 +83,10 @@ const MAX_SELECTOR_MULTIPLY = 3;
76
83
  const componentsThemeToStyleObj = (componentsTheme) =>
77
84
  transformTheme(componentsTheme, [], (path, val) => {
78
85
  const [component, ...restPath] = path;
86
+
87
+ // skip $breakpoints definitions — they are metadata, not CSS output
88
+ if (restPath[0] === BREAKPOINTS_KEY) return {};
89
+
79
90
  const property = restPath.pop();
80
91
  const componentName = getComponentName(component);
81
92
 
@@ -84,15 +95,27 @@ const componentsThemeToStyleObj = (componentsTheme) =>
84
95
  console.warn(componentName, `theme value: "${val}" is mapped to an invalid property`);
85
96
  }
86
97
 
87
- // we need a support for portal components theme (e.g. overlay)
88
- // this allows us to generate those themes under different sections
89
- // if the theme has root level attribute that starts with #
90
- // we are generating a new theme
91
- let themeName = BASE_THEME_SECTION;
92
-
93
- if (restPath[0] && restPath[0].startsWith(PORTAL_THEME_PREFIX)) {
94
- themeName = restPath.shift();
98
+ const themeName = BASE_THEME_SECTION;
99
+
100
+ // extract @container queries from restPath at any position,
101
+ // resolving breakpoints.X references via the component's $breakpoints map
102
+ const componentBreakpoints = componentsTheme[component]?.[BREAKPOINTS_KEY] || {};
103
+ const resolveKey = (key) =>
104
+ isBreakpointRef(key)
105
+ ? `${CONTAINER_QUERY_PREFIX} ${componentBreakpoints[key.slice(BREAKPOINTS_REF_PREFIX.length)]}`
106
+ : key;
107
+ const breakpointRefs = restPath.filter(isBreakpointRef);
108
+ const missingRef = breakpointRefs.find(
109
+ (key) => !componentBreakpoints[key.slice(BREAKPOINTS_REF_PREFIX.length)]
110
+ );
111
+ if (missingRef) {
112
+ // eslint-disable-next-line no-console
113
+ console.warn(componentName, `theme references undefined breakpoint "${missingRef}"`);
114
+ return {};
95
115
  }
116
+ const containerQueries = breakpointRefs.map(resolveKey);
117
+ // remove breakpoint refs from restPath so the remaining parts are processed as attribute selectors
118
+ restPath.splice(0, restPath.length, ...restPath.filter((s) => !isBreakpointRef(s)));
96
119
 
97
120
  // do not start with underscore -> key:value, must have 2 no underscore attrs in a row
98
121
  // starts with underscore -> attribute selector
@@ -131,25 +154,29 @@ const componentsThemeToStyleObj = (componentsTheme) =>
131
154
 
132
155
  const selector = `:host${attrsSelector ? `(${attrsSelector})` : ''}`;
133
156
 
157
+ // wrap the selector rule in container queries from innermost to outermost
158
+ // e.g. ['@container (max-width: 80px)'] + { ':host': { prop: val } }
159
+ // => { '@container (max-width: 80px)': { ':host': { prop: val } } }
160
+ const leaf = containerQueries.reduceRight((acc, query) => ({ [query]: acc }), {
161
+ [selector]: { [property]: getCssVarValue(val) },
162
+ });
163
+
134
164
  return {
135
165
  [componentName]: {
136
- [themeName]: {
137
- [selector]: {
138
- [property]: getCssVarValue(val),
139
- },
140
- },
166
+ [themeName]: leaf,
141
167
  },
142
168
  };
143
169
  });
144
170
 
145
171
  const componentsThemeToStyle = (componentsTheme) =>
146
- Object.entries(componentsTheme).reduce(
147
- (acc, [selector, vars]) =>
148
- `${acc}${selector} { \n${Object.entries(vars)
149
- .map(([key, val]) => `${key}: ${val}`)
150
- .join(';\n')} \n}\n\n`,
151
- ''
152
- );
172
+ Object.entries(componentsTheme).reduce((acc, [key, value]) => {
173
+ if (isContainerQuery(key)) {
174
+ return `${acc}${key} {\n${componentsThemeToStyle(value)}}\n\n`;
175
+ }
176
+ return `${acc}${key} { \n${Object.entries(value)
177
+ .map(([prop, val]) => `${prop}: ${val}`)
178
+ .join(';\n')} \n}\n\n`;
179
+ }, '');
153
180
 
154
181
  export const createComponentsTheme = (componentsTheme) => {
155
182
  const styleObj = componentsThemeToStyleObj(componentsTheme);
@@ -22,6 +22,7 @@ import * as outboundAppButton from '@descope-ui/descope-outbound-app-button/them
22
22
  import * as trustedDevices from '@descope-ui/descope-trusted-devices/theme';
23
23
  import * as tooltip from '@descope-ui/descope-tooltip/theme';
24
24
  import * as countrySubdivisionCityField from '@descope-ui/descope-country-subdivision-city-field/theme';
25
+ import * as attachment from '@descope-ui/descope-attachment/theme';
25
26
  import * as textField from './textField';
26
27
  import * as password from './password';
27
28
  import * as numberField from './numberField';
@@ -135,6 +136,7 @@ const components = {
135
136
  outboundAppButton,
136
137
  trustedDevices,
137
138
  tooltip,
139
+ attachment,
138
140
  };
139
141
 
140
142
  const theme = Object.keys(components).reduce(
@@ -35,10 +35,6 @@ const phoneField = {
35
35
  [vars.errorMessageIconRepeat]: refs.errorMessageIconRepeat,
36
36
  [vars.errorMessageIconPosition]: refs.errorMessageIconPosition,
37
37
  [vars.errorMessageFontSize]: refs.errorMessageFontSize,
38
-
39
- // '@overlay': {
40
- // overlayItemBackgroundColor: 'red'
41
- // }
42
38
  };
43
39
 
44
40
  export default phoneField;