@tylertech/forge 3.2.0 → 3.3.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/custom-elements.json +117 -28
- package/dist/button/forge-button.css +6 -1
- package/dist/chips/forge-chips.css +1 -0
- package/dist/dialog/forge-dialog.css +483 -0
- package/dist/field/forge-field.css +2 -0
- package/dist/inline-message/forge-inline-message.css +2 -0
- package/dist/lib.js +1 -1
- package/dist/lib.js.map +4 -4
- package/dist/vscode.css-custom-data.json +20 -0
- package/dist/vscode.html-custom-data.json +12 -2
- package/esm/app-bar/app-bar/app-bar.d.ts +2 -0
- package/esm/app-bar/app-bar/app-bar.js +2 -0
- package/esm/app-bar/search/app-bar-search-adapter.js +0 -3
- package/esm/app-bar/search/app-bar-search.js +1 -1
- package/esm/autocomplete/autocomplete-adapter.d.ts +1 -1
- package/esm/autocomplete/autocomplete-adapter.js +8 -14
- package/esm/autocomplete/autocomplete-core.js +4 -1
- package/esm/bottom-sheet/bottom-sheet.js +1 -1
- package/esm/button/base/base-button-adapter.js +1 -1
- package/esm/button/button.d.ts +3 -0
- package/esm/button/button.js +4 -1
- package/esm/chip-field/chip-field.js +1 -1
- package/esm/chips/chip/chip.d.ts +1 -0
- package/esm/chips/chip/chip.js +2 -1
- package/esm/circular-progress/circular-progress.js +1 -1
- package/esm/deprecated/button/deprecated-button.js +1 -1
- package/esm/dialog/dialog.js +1 -1
- package/esm/field/field-adapter.d.ts +2 -0
- package/esm/field/field-adapter.js +4 -0
- package/esm/field/field-core.js +1 -0
- package/esm/field/field.js +1 -1
- package/esm/inline-message/inline-message.js +1 -1
- package/esm/list-dropdown/list-dropdown-utils.js +1 -0
- package/esm/paginator/paginator.js +1 -1
- package/esm/popover/popover-core.js +1 -1
- package/esm/select/select/select.js +1 -1
- package/esm/skip-link/skip-link-constants.d.ts +2 -0
- package/esm/skip-link/skip-link-constants.js +2 -1
- package/esm/skip-link/skip-link.d.ts +36 -12
- package/esm/skip-link/skip-link.js +55 -12
- package/esm/tabs/tab/tab-constants.d.ts +1 -3
- package/esm/tabs/tab/tab-constants.js +1 -3
- package/esm/tabs/tab/tab.d.ts +1 -1
- package/esm/tabs/tab/tab.js +1 -1
- package/esm/tabs/tab-bar/tab-bar-core.js +2 -1
- package/esm/tabs/tab-bar/tab-bar.d.ts +1 -1
- package/esm/tabs/tab-bar/tab-bar.js +1 -1
- package/esm/text-field/text-field-adapter.d.ts +8 -4
- package/esm/text-field/text-field-adapter.js +9 -4
- package/esm/text-field/text-field-constants.d.ts +2 -0
- package/esm/text-field/text-field-constants.js +2 -0
- package/esm/text-field/text-field-core.d.ts +2 -0
- package/esm/text-field/text-field-core.js +10 -3
- package/package.json +1 -1
- package/sass/button/_core.scss +5 -0
- package/sass/button/button.scss +6 -0
- package/sass/button/forge-button.scss +5 -0
- package/sass/chip-field/chip-field.scss +2 -1
- package/sass/chips/chip/chip.scss +1 -1
- package/sass/circular-progress/_core.scss +2 -2
- package/sass/core/styles/tokens/button/_tokens.scss +3 -1
- package/sass/core/styles/tokens/chips/chip/_tokens.scss +1 -0
- package/sass/dialog/_animations.scss +6 -6
- package/sass/dialog/dialog.scss +10 -10
- package/sass/field/_core.scss +1 -0
- package/sass/field/_core.theme.scss +4 -0
- package/sass/field/field.scss +5 -1
- package/sass/field/forge-field.scss +3 -1
- package/sass/inline-message/_core.scss +2 -0
|
@@ -11,6 +11,7 @@ export interface ISkipLinkComponent extends IBaseComponent {
|
|
|
11
11
|
muted: boolean;
|
|
12
12
|
persistent: boolean;
|
|
13
13
|
inline: boolean;
|
|
14
|
+
skipUrlChange: boolean;
|
|
14
15
|
}
|
|
15
16
|
declare global {
|
|
16
17
|
interface HTMLElementTagNameMap {
|
|
@@ -22,18 +23,6 @@ declare global {
|
|
|
22
23
|
*
|
|
23
24
|
* @summary The Forge Skip Link component is used to provide a way for users to skip repetitive content and navigate directly to a section of the page.
|
|
24
25
|
*
|
|
25
|
-
* @property {string} [target=''] - The IDREF of the element to which the skip link should navigate.
|
|
26
|
-
* @property {SkipLinkTheme} [theme='default'] - The theme applied to the skip link.
|
|
27
|
-
* @property {boolean} [muted=false] - Whether or not the skip link uses a muted color scheme.
|
|
28
|
-
* @property {boolean} [persistent=false] - Whether or not the skip link should remain visible when not focused.
|
|
29
|
-
* @property {boolean} [inline=false] - Whether or not the skip link renders within its container.
|
|
30
|
-
*
|
|
31
|
-
* @attribute {string} [target=''] - The IDREF of the element to which the skip link should navigate.
|
|
32
|
-
* @attribute {SkipLinkTheme} [theme='default'] - The theme applied to the skip link.
|
|
33
|
-
* @attribute {boolean} [muted=false] - Whether or not the skip link uses a muted color scheme.
|
|
34
|
-
* @attribute {boolean} [persistent=false] - Whether or not the skip link should remain visible when not focused.
|
|
35
|
-
* @attribute {boolean} [inline=false] - Whether or not the skip link renders within its container.
|
|
36
|
-
*
|
|
37
26
|
* @cssproperty --forge-skip-link-background - The background color of the skip link.
|
|
38
27
|
* @cssproperty --forge-skip-link-color - The text color of the skip link.
|
|
39
28
|
* @cssproperty --forge-skip-link-shape - The border radius of the skip link.
|
|
@@ -62,17 +51,52 @@ export declare class SkipLinkComponent extends BaseComponent implements ISkipLin
|
|
|
62
51
|
private _muted;
|
|
63
52
|
private _persistent;
|
|
64
53
|
private _inline;
|
|
54
|
+
private _skipUrlChange;
|
|
65
55
|
private _anchorElement;
|
|
56
|
+
private _clickListener;
|
|
66
57
|
constructor();
|
|
67
58
|
attributeChangedCallback(name: string, oldValue: string, newValue: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* The IDREF of the element to which the skip link should navigate.
|
|
61
|
+
* @default ''
|
|
62
|
+
* @attribute
|
|
63
|
+
*/
|
|
68
64
|
get target(): string;
|
|
69
65
|
set target(value: string);
|
|
66
|
+
/**
|
|
67
|
+
* The theme applied to the skip link.
|
|
68
|
+
* @default 'default'
|
|
69
|
+
* @attribute
|
|
70
|
+
*/
|
|
70
71
|
get theme(): SkipLinkTheme;
|
|
71
72
|
set theme(value: SkipLinkTheme);
|
|
73
|
+
/**
|
|
74
|
+
* Whether or not the skip link uses a muted color scheme.
|
|
75
|
+
* @default false
|
|
76
|
+
* @attribute
|
|
77
|
+
*/
|
|
72
78
|
get muted(): boolean;
|
|
73
79
|
set muted(value: boolean);
|
|
80
|
+
/**
|
|
81
|
+
* Whether or not the skip link should remain visible when not focused.
|
|
82
|
+
* @default false
|
|
83
|
+
* @attribute
|
|
84
|
+
*/
|
|
74
85
|
get persistent(): boolean;
|
|
75
86
|
set persistent(value: boolean);
|
|
87
|
+
/**
|
|
88
|
+
* Whether or not the skip link renders within its container.
|
|
89
|
+
* @default false
|
|
90
|
+
* @attribute
|
|
91
|
+
*/
|
|
76
92
|
get inline(): boolean;
|
|
77
93
|
set inline(value: boolean);
|
|
94
|
+
/**
|
|
95
|
+
* Sets the skip link to skip browser navigation and scroll to the target element.
|
|
96
|
+
* @default false
|
|
97
|
+
* @attribute
|
|
98
|
+
*/
|
|
99
|
+
get skipUrlChange(): boolean;
|
|
100
|
+
set skipUrlChange(value: boolean);
|
|
101
|
+
private _handleClick;
|
|
78
102
|
}
|
|
@@ -16,18 +16,6 @@ const style = ':host{--_skip-link-inset:var(--forge-skip-link-inset, var(--forge
|
|
|
16
16
|
*
|
|
17
17
|
* @summary The Forge Skip Link component is used to provide a way for users to skip repetitive content and navigate directly to a section of the page.
|
|
18
18
|
*
|
|
19
|
-
* @property {string} [target=''] - The IDREF of the element to which the skip link should navigate.
|
|
20
|
-
* @property {SkipLinkTheme} [theme='default'] - The theme applied to the skip link.
|
|
21
|
-
* @property {boolean} [muted=false] - Whether or not the skip link uses a muted color scheme.
|
|
22
|
-
* @property {boolean} [persistent=false] - Whether or not the skip link should remain visible when not focused.
|
|
23
|
-
* @property {boolean} [inline=false] - Whether or not the skip link renders within its container.
|
|
24
|
-
*
|
|
25
|
-
* @attribute {string} [target=''] - The IDREF of the element to which the skip link should navigate.
|
|
26
|
-
* @attribute {SkipLinkTheme} [theme='default'] - The theme applied to the skip link.
|
|
27
|
-
* @attribute {boolean} [muted=false] - Whether or not the skip link uses a muted color scheme.
|
|
28
|
-
* @attribute {boolean} [persistent=false] - Whether or not the skip link should remain visible when not focused.
|
|
29
|
-
* @attribute {boolean} [inline=false] - Whether or not the skip link renders within its container.
|
|
30
|
-
*
|
|
31
19
|
* @cssproperty --forge-skip-link-background - The background color of the skip link.
|
|
32
20
|
* @cssproperty --forge-skip-link-color - The text color of the skip link.
|
|
33
21
|
* @cssproperty --forge-skip-link-shape - The border radius of the skip link.
|
|
@@ -60,6 +48,8 @@ let SkipLinkComponent = class SkipLinkComponent extends BaseComponent {
|
|
|
60
48
|
this._muted = false;
|
|
61
49
|
this._persistent = false;
|
|
62
50
|
this._inline = false;
|
|
51
|
+
this._skipUrlChange = false;
|
|
52
|
+
this._clickListener = (evt) => this._handleClick(evt);
|
|
63
53
|
attachShadowTemplate(this, template, style);
|
|
64
54
|
this._anchorElement = getShadowElement(this, SKIP_LINK_CONSTANTS.selectors.ANCHOR);
|
|
65
55
|
}
|
|
@@ -80,8 +70,16 @@ let SkipLinkComponent = class SkipLinkComponent extends BaseComponent {
|
|
|
80
70
|
case SKIP_LINK_CONSTANTS.observedAttributes.INLINE:
|
|
81
71
|
this.inline = coerceBoolean(newValue);
|
|
82
72
|
break;
|
|
73
|
+
case SKIP_LINK_CONSTANTS.observedAttributes.SKIP_URL_CHANGE:
|
|
74
|
+
this.skipUrlChange = coerceBoolean(newValue);
|
|
75
|
+
break;
|
|
83
76
|
}
|
|
84
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* The IDREF of the element to which the skip link should navigate.
|
|
80
|
+
* @default ''
|
|
81
|
+
* @attribute
|
|
82
|
+
*/
|
|
85
83
|
get target() {
|
|
86
84
|
return this._target;
|
|
87
85
|
}
|
|
@@ -92,6 +90,11 @@ let SkipLinkComponent = class SkipLinkComponent extends BaseComponent {
|
|
|
92
90
|
this._anchorElement.href = `#${this._target}`;
|
|
93
91
|
}
|
|
94
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* The theme applied to the skip link.
|
|
95
|
+
* @default 'default'
|
|
96
|
+
* @attribute
|
|
97
|
+
*/
|
|
95
98
|
get theme() {
|
|
96
99
|
return this._theme;
|
|
97
100
|
}
|
|
@@ -101,6 +104,11 @@ let SkipLinkComponent = class SkipLinkComponent extends BaseComponent {
|
|
|
101
104
|
this.setAttribute(SKIP_LINK_CONSTANTS.attributes.THEME, this._theme);
|
|
102
105
|
}
|
|
103
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Whether or not the skip link uses a muted color scheme.
|
|
109
|
+
* @default false
|
|
110
|
+
* @attribute
|
|
111
|
+
*/
|
|
104
112
|
get muted() {
|
|
105
113
|
return this._muted;
|
|
106
114
|
}
|
|
@@ -110,6 +118,11 @@ let SkipLinkComponent = class SkipLinkComponent extends BaseComponent {
|
|
|
110
118
|
this.toggleAttribute(SKIP_LINK_CONSTANTS.attributes.MUTED, this._muted);
|
|
111
119
|
}
|
|
112
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Whether or not the skip link should remain visible when not focused.
|
|
123
|
+
* @default false
|
|
124
|
+
* @attribute
|
|
125
|
+
*/
|
|
113
126
|
get persistent() {
|
|
114
127
|
return this._persistent;
|
|
115
128
|
}
|
|
@@ -119,6 +132,11 @@ let SkipLinkComponent = class SkipLinkComponent extends BaseComponent {
|
|
|
119
132
|
this.toggleAttribute(SKIP_LINK_CONSTANTS.attributes.PERSISTENT, this._persistent);
|
|
120
133
|
}
|
|
121
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Whether or not the skip link renders within its container.
|
|
137
|
+
* @default false
|
|
138
|
+
* @attribute
|
|
139
|
+
*/
|
|
122
140
|
get inline() {
|
|
123
141
|
return this._inline;
|
|
124
142
|
}
|
|
@@ -128,6 +146,31 @@ let SkipLinkComponent = class SkipLinkComponent extends BaseComponent {
|
|
|
128
146
|
this.toggleAttribute(SKIP_LINK_CONSTANTS.attributes.INLINE, this._inline);
|
|
129
147
|
}
|
|
130
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Sets the skip link to skip browser navigation and scroll to the target element.
|
|
151
|
+
* @default false
|
|
152
|
+
* @attribute
|
|
153
|
+
*/
|
|
154
|
+
get skipUrlChange() {
|
|
155
|
+
return this._skipUrlChange;
|
|
156
|
+
}
|
|
157
|
+
set skipUrlChange(value) {
|
|
158
|
+
if (this._skipUrlChange !== value) {
|
|
159
|
+
this._skipUrlChange = value;
|
|
160
|
+
this.toggleAttribute(SKIP_LINK_CONSTANTS.attributes.SKIP_URL_CHANGE, this._skipUrlChange);
|
|
161
|
+
if (this._skipUrlChange) {
|
|
162
|
+
this._anchorElement.addEventListener('click', this._clickListener);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
this._anchorElement.removeEventListener('click', this._clickListener);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
_handleClick(evt) {
|
|
169
|
+
evt.preventDefault();
|
|
170
|
+
const targetElement = document.getElementById(this._target);
|
|
171
|
+
targetElement?.focus();
|
|
172
|
+
targetElement?.scrollIntoView({ behavior: 'smooth' });
|
|
173
|
+
}
|
|
131
174
|
};
|
|
132
175
|
SkipLinkComponent = __decorate([
|
|
133
176
|
customElement({
|
package/esm/tabs/tab/tab.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ declare global {
|
|
|
26
26
|
* @dependency forge-focus-indicator
|
|
27
27
|
* @dependency forge-state-layer
|
|
28
28
|
*
|
|
29
|
-
* @property {boolean} [disabled=false] - The disabled state of the tab.
|
|
29
|
+
* @property {boolean} [disabled=false] - The disabled state of the tab. Should not be set if using the disabled property on `forge-tab-bar`.
|
|
30
30
|
* @property {boolean} [selected=false] - The selected state of the tab.
|
|
31
31
|
* @property {boolean} [vertical=false] - Controls whether the tab is vertical or horizontal.
|
|
32
32
|
* @property {boolean} [stacked=false] - Controls whether the tab is taller to allow for slotted leading/trailing elements.
|
package/esm/tabs/tab/tab.js
CHANGED
|
@@ -19,7 +19,7 @@ const styles = ':host{display:inline-flex;outline:0;-webkit-tap-highlight-color:
|
|
|
19
19
|
* @dependency forge-focus-indicator
|
|
20
20
|
* @dependency forge-state-layer
|
|
21
21
|
*
|
|
22
|
-
* @property {boolean} [disabled=false] - The disabled state of the tab.
|
|
22
|
+
* @property {boolean} [disabled=false] - The disabled state of the tab. Should not be set if using the disabled property on `forge-tab-bar`.
|
|
23
23
|
* @property {boolean} [selected=false] - The selected state of the tab.
|
|
24
24
|
* @property {boolean} [vertical=false] - Controls whether the tab is vertical or horizontal.
|
|
25
25
|
* @property {boolean} [stacked=false] - Controls whether the tab is taller to allow for slotted leading/trailing elements.
|
|
@@ -139,7 +139,8 @@ export class TabBarCore {
|
|
|
139
139
|
_syncTabState() {
|
|
140
140
|
this._tabs.forEach((tab, index) => {
|
|
141
141
|
tab.selected = index === this._activeTab;
|
|
142
|
-
|
|
142
|
+
if (this._disabled)
|
|
143
|
+
tab.disabled = this._disabled;
|
|
143
144
|
tab.vertical = this._vertical;
|
|
144
145
|
tab.stacked = this._stacked;
|
|
145
146
|
tab.secondary = this._secondary;
|
|
@@ -38,7 +38,7 @@ declare global {
|
|
|
38
38
|
* @dependency forge-icon-button
|
|
39
39
|
* @dependency forge-icon
|
|
40
40
|
*
|
|
41
|
-
* @property {boolean} [disabled=false] -
|
|
41
|
+
* @property {boolean} [disabled=false] - Sets the disabled state of all child tabs. If true, any new tabs added to the DOM will be disabled by default. This can be used instead of setting individual tab disabled properties, mixing the two methods of disabling is not supported.
|
|
42
42
|
* @property {number} [activeTab=null] - The index of the active tab.
|
|
43
43
|
* @property {boolean} [vertical=false] - Controls whether the tab bar is vertical or horizontal.
|
|
44
44
|
* @property {boolean} [clustered=false] - Controls whether the tabs stretch the full width of their container or cluster together at their minimum width.
|
|
@@ -29,7 +29,7 @@ const styles = ':host{position:relative;display:block}:host([hidden]){display:no
|
|
|
29
29
|
* @dependency forge-icon-button
|
|
30
30
|
* @dependency forge-icon
|
|
31
31
|
*
|
|
32
|
-
* @property {boolean} [disabled=false] -
|
|
32
|
+
* @property {boolean} [disabled=false] - Sets the disabled state of all child tabs. If true, any new tabs added to the DOM will be disabled by default. This can be used instead of setting individual tab disabled properties, mixing the two methods of disabling is not supported.
|
|
33
33
|
* @property {number} [activeTab=null] - The index of the active tab.
|
|
34
34
|
* @property {boolean} [vertical=false] - Controls whether the tab bar is vertical or horizontal.
|
|
35
35
|
* @property {boolean} [clustered=false] - Controls whether the tabs stretch the full width of their container or cluster together at their minimum width.
|
|
@@ -12,19 +12,22 @@ export interface ITextFieldAdapter extends IBaseFieldAdapter {
|
|
|
12
12
|
addRootListener(name: keyof HTMLElementEventMap, listener: EventListener): void;
|
|
13
13
|
removeRootListener(name: keyof HTMLElementEventMap, listener: EventListener): void;
|
|
14
14
|
disableInput(disabled: boolean): void;
|
|
15
|
-
handleDefaultSlotChange(
|
|
15
|
+
handleDefaultSlotChange(listener: TextFieldInputAttributeObserver): void;
|
|
16
16
|
tryAddValueChangeListener(context: unknown, listener: TextFieldValueChangeListener): void;
|
|
17
17
|
removeValueChangeListener(): void;
|
|
18
18
|
tryFloatLabel(force?: boolean): void;
|
|
19
|
-
tryConnectSlottedLabel(
|
|
19
|
+
tryConnectSlottedLabel(): void;
|
|
20
20
|
connectClearButton(listener: EventListener): void;
|
|
21
21
|
disconnectClearButton(listener: EventListener): void;
|
|
22
22
|
toggleClearButtonVisibility(visible: boolean): void;
|
|
23
23
|
clearInput(): void;
|
|
24
|
+
getAllSlotElements(): HTMLSlotElement[];
|
|
24
25
|
}
|
|
25
26
|
export declare class TextFieldAdapter extends BaseFieldAdapter implements ITextFieldAdapter {
|
|
26
27
|
protected readonly _fieldElement: IFieldComponent;
|
|
27
28
|
private readonly _clearButtonSlotElement;
|
|
29
|
+
private readonly _defaultSlotElement;
|
|
30
|
+
private readonly _labelSlotElement;
|
|
28
31
|
private _popoverTargetElement;
|
|
29
32
|
private _inputElements;
|
|
30
33
|
private _inputMutationObserver?;
|
|
@@ -39,13 +42,14 @@ export declare class TextFieldAdapter extends BaseFieldAdapter implements ITextF
|
|
|
39
42
|
inputIsDisabled(): boolean;
|
|
40
43
|
click(): void;
|
|
41
44
|
applyLabel(value: string | null): void;
|
|
42
|
-
handleDefaultSlotChange(
|
|
45
|
+
handleDefaultSlotChange(listener: TextFieldInputAttributeObserver): void;
|
|
43
46
|
tryAddValueChangeListener(context: unknown, listener: TextFieldValueChangeListener): void;
|
|
44
47
|
removeValueChangeListener(): void;
|
|
45
48
|
tryFloatLabel(force?: boolean): void;
|
|
46
|
-
tryConnectSlottedLabel(
|
|
49
|
+
tryConnectSlottedLabel(): void;
|
|
47
50
|
connectClearButton(listener: EventListener): void;
|
|
48
51
|
disconnectClearButton(listener: EventListener): void;
|
|
49
52
|
toggleClearButtonVisibility(visible: boolean): void;
|
|
50
53
|
clearInput(): void;
|
|
54
|
+
getAllSlotElements(): HTMLSlotElement[];
|
|
51
55
|
}
|
|
@@ -26,6 +26,8 @@ export class TextFieldAdapter extends BaseFieldAdapter {
|
|
|
26
26
|
this._destroyValueChangerListeners = [];
|
|
27
27
|
this._fieldElement = getShadowElement(component, TEXT_FIELD_CONSTANTS.selectors.FIELD);
|
|
28
28
|
this._clearButtonSlotElement = getShadowElement(component, TEXT_FIELD_CONSTANTS.selectors.CLEAR_BUTTON_SLOT);
|
|
29
|
+
this._defaultSlotElement = getShadowElement(component, TEXT_FIELD_CONSTANTS.selectors.DEFAULT_SLOT);
|
|
30
|
+
this._labelSlotElement = getShadowElement(component, TEXT_FIELD_CONSTANTS.selectors.LABEL_SLOT);
|
|
29
31
|
this._fieldElement.setAttribute('exportparts', Object.values(FIELD_CONSTANTS.parts).join(', '));
|
|
30
32
|
this._clearButtonSlotElement.remove();
|
|
31
33
|
}
|
|
@@ -49,11 +51,11 @@ export class TextFieldAdapter extends BaseFieldAdapter {
|
|
|
49
51
|
toggleAttribute(inputElement, !!value, 'aria-label', value ?? '');
|
|
50
52
|
});
|
|
51
53
|
}
|
|
52
|
-
handleDefaultSlotChange(
|
|
54
|
+
handleDefaultSlotChange(listener) {
|
|
53
55
|
// Destroy the mutation observer if it exists
|
|
54
56
|
this._inputMutationObserver?.disconnect();
|
|
55
57
|
// If there are no assigned elements, return
|
|
56
|
-
const assignedElements =
|
|
58
|
+
const assignedElements = this._defaultSlotElement.assignedElements();
|
|
57
59
|
if (!assignedElements.length) {
|
|
58
60
|
return;
|
|
59
61
|
}
|
|
@@ -106,14 +108,14 @@ export class TextFieldAdapter extends BaseFieldAdapter {
|
|
|
106
108
|
// Float the label if no input has a value or a placeholder
|
|
107
109
|
this._fieldElement.floatLabel = this.hasValue || this.hasPlaceholder;
|
|
108
110
|
}
|
|
109
|
-
tryConnectSlottedLabel(
|
|
111
|
+
tryConnectSlottedLabel() {
|
|
110
112
|
// Only one input can be automatically connected to a label, return if there are no or more
|
|
111
113
|
// than one inputs or if the input is already labelled
|
|
112
114
|
if (this._inputElements.length !== 1 || this._inputElements[0].labels?.length) {
|
|
113
115
|
return;
|
|
114
116
|
}
|
|
115
117
|
const inputElement = this._inputElements[0];
|
|
116
|
-
const elements =
|
|
118
|
+
const elements = this._labelSlotElement.assignedElements({ flatten: true });
|
|
117
119
|
// Attempt to find and connect a `<forge-label>` element
|
|
118
120
|
const forgeLabel = elements.find(el => el.matches(TEXT_FIELD_CONSTANTS.selectors.FORGE_LABEL));
|
|
119
121
|
if (forgeLabel) {
|
|
@@ -151,4 +153,7 @@ export class TextFieldAdapter extends BaseFieldAdapter {
|
|
|
151
153
|
this._inputElements.forEach(el => (el.value = ''));
|
|
152
154
|
this._inputElements[0].focus();
|
|
153
155
|
}
|
|
156
|
+
getAllSlotElements() {
|
|
157
|
+
return Array.from(this._component.shadowRoot?.querySelectorAll('slot') ?? []);
|
|
158
|
+
}
|
|
154
159
|
}
|
|
@@ -14,6 +14,8 @@ const attributes = {
|
|
|
14
14
|
};
|
|
15
15
|
const selectors = {
|
|
16
16
|
FIELD: '#field',
|
|
17
|
+
DEFAULT_SLOT: 'slot:not([name])',
|
|
18
|
+
LABEL_SLOT: 'slot[name=label]',
|
|
17
19
|
CLEAR_BUTTON_SLOT: 'slot[name=clear-button]',
|
|
18
20
|
FORGE_LABEL: LABEL_CONSTANTS.elementName,
|
|
19
21
|
INPUT: ':where(input:not([type=button], [type=checkbox], [type=color], [type=hidden], [type=image], [type=radio], [type=range], [type=reset], [type=submit]), textarea)'
|
|
@@ -22,7 +22,9 @@ export declare class TextFieldCore extends BaseFieldCore<ITextFieldAdapter> impl
|
|
|
22
22
|
initialize(): void;
|
|
23
23
|
destroy(): void;
|
|
24
24
|
get popoverTargetElement(): HTMLElement;
|
|
25
|
+
private _initializeSlots;
|
|
25
26
|
private _onSlotChange;
|
|
27
|
+
private _handleSlotChange;
|
|
26
28
|
private _onInputAttributeChange;
|
|
27
29
|
private _onClearButtonClick;
|
|
28
30
|
private _onValueChange;
|
|
@@ -21,6 +21,7 @@ export class TextFieldCore extends BaseFieldCore {
|
|
|
21
21
|
this._adapter.tryApplyGlobalConfiguration(['labelPosition', 'variant']);
|
|
22
22
|
this._adapter.addRootListener('slotchange', this._slotChangeListener);
|
|
23
23
|
this._adapter.addRootListener('input', this._inputListener);
|
|
24
|
+
this._initializeSlots();
|
|
24
25
|
}
|
|
25
26
|
destroy() {
|
|
26
27
|
this._adapter.removeRootListener('slotchange', this._slotChangeListener);
|
|
@@ -30,14 +31,20 @@ export class TextFieldCore extends BaseFieldCore {
|
|
|
30
31
|
get popoverTargetElement() {
|
|
31
32
|
return this._adapter.popoverTargetElement;
|
|
32
33
|
}
|
|
34
|
+
_initializeSlots() {
|
|
35
|
+
this._adapter.getAllSlotElements().forEach(slot => this._handleSlotChange(slot.name));
|
|
36
|
+
}
|
|
33
37
|
_onSlotChange(evt) {
|
|
34
38
|
const target = evt.target;
|
|
35
|
-
|
|
39
|
+
this._handleSlotChange(target.name);
|
|
40
|
+
}
|
|
41
|
+
_handleSlotChange(name) {
|
|
42
|
+
switch (name) {
|
|
36
43
|
case 'label':
|
|
37
|
-
this._adapter.tryConnectSlottedLabel(
|
|
44
|
+
this._adapter.tryConnectSlottedLabel();
|
|
38
45
|
break;
|
|
39
46
|
case '':
|
|
40
|
-
this._adapter.handleDefaultSlotChange(
|
|
47
|
+
this._adapter.handleDefaultSlotChange(this._inputAttributeListener);
|
|
41
48
|
this._adapter.tryAddValueChangeListener(this, this._valueChangeListener);
|
|
42
49
|
this._tryFloatLabel();
|
|
43
50
|
break;
|
package/package.json
CHANGED
package/sass/button/_core.scss
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
display: #{token(display)};
|
|
13
13
|
position: relative;
|
|
14
14
|
outline: none;
|
|
15
|
+
vertical-align: middle;
|
|
15
16
|
-webkit-tap-highlight-color: transparent;
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -101,6 +102,10 @@
|
|
|
101
102
|
text-decoration: none;
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
@mixin text {
|
|
106
|
+
@include override(padding-inline, text-padding-inline);
|
|
107
|
+
}
|
|
108
|
+
|
|
104
109
|
@mixin filled {
|
|
105
110
|
@include override(background, filled-background);
|
|
106
111
|
@include override(color, filled-color);
|
package/sass/button/button.scss
CHANGED
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
pointer-events: initial;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
&:where(:not(.forge-button--outlined, .forge-button--tonal, .forge-button--filled, .forge-button--raised, .forge-button--link)),
|
|
47
|
+
&--text {
|
|
48
|
+
@include core.text;
|
|
49
|
+
}
|
|
50
|
+
|
|
46
51
|
&--outlined {
|
|
47
52
|
@include core.outlined;
|
|
48
53
|
|
|
@@ -77,7 +77,8 @@ $themes: (primary, secondary, tertiary, success, warning, error, info);
|
|
|
77
77
|
@include chip.provide-theme(
|
|
78
78
|
(
|
|
79
79
|
field-background: theme.variable($theme),
|
|
80
|
-
field-color: theme.variable(on-#{$theme})
|
|
80
|
+
field-color: theme.variable(on-#{$theme}),
|
|
81
|
+
focus-indicator-color: theme.variable($theme)
|
|
81
82
|
)
|
|
82
83
|
);
|
|
83
84
|
}
|
|
@@ -14,8 +14,8 @@ $_cycle-duration: calc(4 * #{token(arc-duration)});
|
|
|
14
14
|
@mixin container {
|
|
15
15
|
display: inline-flex;
|
|
16
16
|
vertical-align: middle;
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
block-size: #{token(size)};
|
|
18
|
+
inline-size: #{token(size)};
|
|
19
19
|
position: relative;
|
|
20
20
|
align-items: center;
|
|
21
21
|
justify-content: center;
|
|
@@ -18,7 +18,7 @@ $tokens: (
|
|
|
18
18
|
primary-color: utils.module-val(button, primary-color, theme.variable(primary)),
|
|
19
19
|
text-color: utils.module-ref(button, text-color, primary-color),
|
|
20
20
|
disabled-color: utils.module-val(button, disabled-color, theme.variable(surface-container)),
|
|
21
|
-
padding: utils.module-val(button, padding,
|
|
21
|
+
padding: utils.module-val(button, padding, spacing.variable(medium)),
|
|
22
22
|
display: utils.module-val(button, display, inline-flex),
|
|
23
23
|
justify: utils.module-val(button, justify, center),
|
|
24
24
|
shape: utils.module-val(button, shape, shape.variable(medium)),
|
|
@@ -46,6 +46,8 @@ $tokens: (
|
|
|
46
46
|
cursor: utils.module-val(button, cursor, pointer),
|
|
47
47
|
transition-duration: utils.module-val(button, transition-duration, animation.variable(duration-short3)),
|
|
48
48
|
transition-timing: utils.module-val(button, transition-timing, animation.variable(easing-standard)),
|
|
49
|
+
// Text
|
|
50
|
+
text-padding-inline: utils.module-val(button, text-padding-inline, spacing.variable(xsmall)),
|
|
49
51
|
// Outlined
|
|
50
52
|
outlined-background: utils.module-val(button, outlined-background, transparent),
|
|
51
53
|
outlined-color: utils.module-ref(button, outlined-color, primary-color),
|
|
@@ -22,6 +22,7 @@ $tokens: (
|
|
|
22
22
|
padding-block: utils.module-val(chip, padding-block, 0),
|
|
23
23
|
cursor: utils.module-val(chip, cursor, pointer),
|
|
24
24
|
icon-font-size: utils.module-val(chip, icon-font-size, 1.5rem),
|
|
25
|
+
focus-indicator-color: utils.module-ref(chip, focus-indicator-color, color),
|
|
25
26
|
// Disabled
|
|
26
27
|
disabled-opacity: utils.module-val(chip, disabled-opacity, theme.emphasis(medium-low)),
|
|
27
28
|
disabled-cursor: utils.module-val(chip, disabled-cursor, not-allowed),
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// Zoom (default)
|
|
10
10
|
//
|
|
11
11
|
|
|
12
|
-
@keyframes zoom-in {
|
|
12
|
+
@keyframes forge-dialog-zoom-in {
|
|
13
13
|
from {
|
|
14
14
|
opacity: #{token(zoom-opacity)};
|
|
15
15
|
scale: #{token(zoom-scale)};
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
@keyframes zoom-out {
|
|
23
|
+
@keyframes forge-dialog-zoom-out {
|
|
24
24
|
from {
|
|
25
25
|
opacity: 1;
|
|
26
26
|
scale: 1;
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
// Fade
|
|
36
36
|
//
|
|
37
37
|
|
|
38
|
-
@keyframes fade-in {
|
|
38
|
+
@keyframes forge-dialog-fade-in {
|
|
39
39
|
from {
|
|
40
40
|
opacity: #{token(fade-opacity)};
|
|
41
41
|
}
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
@keyframes fade-out {
|
|
47
|
+
@keyframes forge-dialog-fade-out {
|
|
48
48
|
from {
|
|
49
49
|
opacity: 1;
|
|
50
50
|
}
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
// Slide
|
|
58
58
|
//
|
|
59
59
|
|
|
60
|
-
@keyframes slide-in {
|
|
60
|
+
@keyframes forge-dialog-slide-in {
|
|
61
61
|
from {
|
|
62
62
|
opacity: #{token(slide-opacity)};
|
|
63
63
|
translate: #{token(slide-translate)};
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
@keyframes slide-out {
|
|
72
|
+
@keyframes forge-dialog-slide-out {
|
|
73
73
|
from {
|
|
74
74
|
opacity: 1;
|
|
75
75
|
translate: 0 0;
|
package/sass/dialog/dialog.scss
CHANGED
|
@@ -173,10 +173,10 @@ $can-animate: '[visible]:not([animation-type=none])';
|
|
|
173
173
|
:host(#{$can-animate}:is(:not([animation-type]), [animation-type='zoom'])) {
|
|
174
174
|
dialog.forge-dialog[open] {
|
|
175
175
|
.surface {
|
|
176
|
-
animation-name: zoom-in;
|
|
176
|
+
animation-name: forge-dialog-zoom-in;
|
|
177
177
|
|
|
178
178
|
&.exiting {
|
|
179
|
-
animation-name: zoom-out;
|
|
179
|
+
animation-name: forge-dialog-zoom-out;
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
}
|
|
@@ -186,10 +186,10 @@ $can-animate: '[visible]:not([animation-type=none])';
|
|
|
186
186
|
:host(#{$can-animate}[animation-type='fade']) {
|
|
187
187
|
dialog.forge-dialog[open] {
|
|
188
188
|
.surface {
|
|
189
|
-
animation-name: fade-in;
|
|
189
|
+
animation-name: forge-dialog-fade-in;
|
|
190
190
|
|
|
191
191
|
&.exiting {
|
|
192
|
-
animation-name: fade-out;
|
|
192
|
+
animation-name: forge-dialog-fade-out;
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
}
|
|
@@ -199,10 +199,10 @@ $can-animate: '[visible]:not([animation-type=none])';
|
|
|
199
199
|
:host(#{$can-animate}[animation-type='slide']) {
|
|
200
200
|
dialog.forge-dialog[open] {
|
|
201
201
|
.surface {
|
|
202
|
-
animation-name: slide-in;
|
|
202
|
+
animation-name: forge-dialog-slide-in;
|
|
203
203
|
|
|
204
204
|
&.exiting {
|
|
205
|
-
animation-name: slide-out;
|
|
205
|
+
animation-name: forge-dialog-slide-out;
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
208
|
}
|
|
@@ -252,10 +252,10 @@ $can-animate: '[visible]:not([animation-type=none])';
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
.surface {
|
|
255
|
-
animation-name: slide-in;
|
|
255
|
+
animation-name: forge-dialog-slide-in;
|
|
256
256
|
|
|
257
257
|
&.exiting {
|
|
258
|
-
animation-name: slide-out;
|
|
258
|
+
animation-name: forge-dialog-slide-out;
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
261
|
}
|
|
@@ -358,10 +358,10 @@ $can-animate: '[visible]:not([animation-type=none])';
|
|
|
358
358
|
@layer media {
|
|
359
359
|
@media (prefers-reduced-motion: reduce) {
|
|
360
360
|
.surface {
|
|
361
|
-
animation-name: fade-in;
|
|
361
|
+
animation-name: forge-dialog-fade-in;
|
|
362
362
|
|
|
363
363
|
&.exiting {
|
|
364
|
-
animation-name: fade-out;
|
|
364
|
+
animation-name: forge-dialog-fade-out;
|
|
365
365
|
}
|
|
366
366
|
}
|
|
367
367
|
}
|