@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.
Files changed (69) hide show
  1. package/custom-elements.json +117 -28
  2. package/dist/button/forge-button.css +6 -1
  3. package/dist/chips/forge-chips.css +1 -0
  4. package/dist/dialog/forge-dialog.css +483 -0
  5. package/dist/field/forge-field.css +2 -0
  6. package/dist/inline-message/forge-inline-message.css +2 -0
  7. package/dist/lib.js +1 -1
  8. package/dist/lib.js.map +4 -4
  9. package/dist/vscode.css-custom-data.json +20 -0
  10. package/dist/vscode.html-custom-data.json +12 -2
  11. package/esm/app-bar/app-bar/app-bar.d.ts +2 -0
  12. package/esm/app-bar/app-bar/app-bar.js +2 -0
  13. package/esm/app-bar/search/app-bar-search-adapter.js +0 -3
  14. package/esm/app-bar/search/app-bar-search.js +1 -1
  15. package/esm/autocomplete/autocomplete-adapter.d.ts +1 -1
  16. package/esm/autocomplete/autocomplete-adapter.js +8 -14
  17. package/esm/autocomplete/autocomplete-core.js +4 -1
  18. package/esm/bottom-sheet/bottom-sheet.js +1 -1
  19. package/esm/button/base/base-button-adapter.js +1 -1
  20. package/esm/button/button.d.ts +3 -0
  21. package/esm/button/button.js +4 -1
  22. package/esm/chip-field/chip-field.js +1 -1
  23. package/esm/chips/chip/chip.d.ts +1 -0
  24. package/esm/chips/chip/chip.js +2 -1
  25. package/esm/circular-progress/circular-progress.js +1 -1
  26. package/esm/deprecated/button/deprecated-button.js +1 -1
  27. package/esm/dialog/dialog.js +1 -1
  28. package/esm/field/field-adapter.d.ts +2 -0
  29. package/esm/field/field-adapter.js +4 -0
  30. package/esm/field/field-core.js +1 -0
  31. package/esm/field/field.js +1 -1
  32. package/esm/inline-message/inline-message.js +1 -1
  33. package/esm/list-dropdown/list-dropdown-utils.js +1 -0
  34. package/esm/paginator/paginator.js +1 -1
  35. package/esm/popover/popover-core.js +1 -1
  36. package/esm/select/select/select.js +1 -1
  37. package/esm/skip-link/skip-link-constants.d.ts +2 -0
  38. package/esm/skip-link/skip-link-constants.js +2 -1
  39. package/esm/skip-link/skip-link.d.ts +36 -12
  40. package/esm/skip-link/skip-link.js +55 -12
  41. package/esm/tabs/tab/tab-constants.d.ts +1 -3
  42. package/esm/tabs/tab/tab-constants.js +1 -3
  43. package/esm/tabs/tab/tab.d.ts +1 -1
  44. package/esm/tabs/tab/tab.js +1 -1
  45. package/esm/tabs/tab-bar/tab-bar-core.js +2 -1
  46. package/esm/tabs/tab-bar/tab-bar.d.ts +1 -1
  47. package/esm/tabs/tab-bar/tab-bar.js +1 -1
  48. package/esm/text-field/text-field-adapter.d.ts +8 -4
  49. package/esm/text-field/text-field-adapter.js +9 -4
  50. package/esm/text-field/text-field-constants.d.ts +2 -0
  51. package/esm/text-field/text-field-constants.js +2 -0
  52. package/esm/text-field/text-field-core.d.ts +2 -0
  53. package/esm/text-field/text-field-core.js +10 -3
  54. package/package.json +1 -1
  55. package/sass/button/_core.scss +5 -0
  56. package/sass/button/button.scss +6 -0
  57. package/sass/button/forge-button.scss +5 -0
  58. package/sass/chip-field/chip-field.scss +2 -1
  59. package/sass/chips/chip/chip.scss +1 -1
  60. package/sass/circular-progress/_core.scss +2 -2
  61. package/sass/core/styles/tokens/button/_tokens.scss +3 -1
  62. package/sass/core/styles/tokens/chips/chip/_tokens.scss +1 -0
  63. package/sass/dialog/_animations.scss +6 -6
  64. package/sass/dialog/dialog.scss +10 -10
  65. package/sass/field/_core.scss +1 -0
  66. package/sass/field/_core.theme.scss +4 -0
  67. package/sass/field/field.scss +5 -1
  68. package/sass/field/forge-field.scss +3 -1
  69. 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({
@@ -24,9 +24,7 @@ export declare const TAB_CONSTANTS: {
24
24
  selectors: {
25
25
  INDICATOR: string;
26
26
  };
27
- classes: {
28
- SELECTED: string;
29
- };
27
+ classes: {};
30
28
  events: {
31
29
  SELECT: string;
32
30
  };
@@ -19,9 +19,7 @@ const attributes = {
19
19
  const selectors = {
20
20
  INDICATOR: '.indicator'
21
21
  };
22
- const classes = {
23
- SELECTED: 'selected'
24
- };
22
+ const classes = {};
25
23
  const events = {
26
24
  SELECT: `${elementName}-select`
27
25
  };
@@ -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.
@@ -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
- tab.disabled = this._disabled;
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] - The disabled state of the tab bar.
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] - The disabled state of the tab bar.
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(slot: HTMLSlotElement, listener: TextFieldInputAttributeObserver): void;
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(slot: HTMLSlotElement): void;
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(slot: HTMLSlotElement, listener: TextFieldInputAttributeObserver): void;
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(slot: HTMLSlotElement): void;
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(slot, listener) {
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 = slot.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(slot) {
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 = slot.assignedElements({ flatten: true });
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 @@ export declare const TEXT_FIELD_CONSTANTS: {
14
14
  };
15
15
  selectors: {
16
16
  FIELD: string;
17
+ DEFAULT_SLOT: string;
18
+ LABEL_SLOT: string;
17
19
  CLEAR_BUTTON_SLOT: string;
18
20
  FORGE_LABEL: "forge-label";
19
21
  INPUT: string;
@@ -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
- switch (target.name) {
39
+ this._handleSlotChange(target.name);
40
+ }
41
+ _handleSlotChange(name) {
42
+ switch (name) {
36
43
  case 'label':
37
- this._adapter.tryConnectSlottedLabel(target);
44
+ this._adapter.tryConnectSlottedLabel();
38
45
  break;
39
46
  case '':
40
- this._adapter.handleDefaultSlotChange(target, this._inputAttributeListener);
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
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tylertech/forge",
3
3
  "description": "Tyler Forge™ Web Components library",
4
- "version": "3.2.0",
4
+ "version": "3.3.1",
5
5
  "author": "Tyler Technologies, Inc.",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -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);
@@ -136,6 +136,12 @@ forge-focus-indicator {
136
136
  // Variants
137
137
  //
138
138
 
139
+ :host(:where(:not([variant]), [variant='text'])) {
140
+ .forge-button {
141
+ @include text;
142
+ }
143
+ }
144
+
139
145
  :host([variant='filled']) {
140
146
  .forge-button {
141
147
  @include filled;
@@ -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
  }
@@ -64,7 +64,7 @@
64
64
  forge-focus-indicator {
65
65
  @include focus-indicator.provide-theme(
66
66
  (
67
- color: #{token(color)},
67
+ color: #{token(focus-indicator-color)},
68
68
  shape: #{token(shape)}
69
69
  )
70
70
  );
@@ -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
- min-block-size: #{token(size)};
18
- min-inline-size: #{token(size)};
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, 8px),
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;
@@ -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
  }