@synergy-design-system/mcp 2.6.1 → 2.7.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/CHANGELOG.md +22 -0
- package/dist/utilities/storybook/scraper.js +14 -3
- package/metadata/checksum.txt +1 -1
- package/metadata/packages/components/components/syn-checkbox/component.angular.ts +13 -0
- package/metadata/packages/components/components/syn-checkbox/component.styles.ts +99 -39
- package/metadata/packages/components/components/syn-checkbox/component.ts +13 -10
- package/metadata/packages/components/components/syn-checkbox/component.vue +5 -0
- package/metadata/packages/components/components/syn-combobox/component.angular.ts +13 -0
- package/metadata/packages/components/components/syn-combobox/component.styles.ts +216 -193
- package/metadata/packages/components/components/syn-combobox/component.ts +68 -39
- package/metadata/packages/components/components/syn-combobox/component.vue +5 -0
- package/metadata/packages/components/components/syn-file/component.angular.ts +13 -0
- package/metadata/packages/components/components/syn-file/component.styles.ts +20 -3
- package/metadata/packages/components/components/syn-file/component.ts +19 -5
- package/metadata/packages/components/components/syn-file/component.vue +5 -0
- package/metadata/packages/components/components/syn-input/component.ts +1 -2
- package/metadata/packages/components/components/syn-radio/component.angular.ts +13 -0
- package/metadata/packages/components/components/syn-radio/component.styles.ts +91 -29
- package/metadata/packages/components/components/syn-radio/component.ts +19 -10
- package/metadata/packages/components/components/syn-radio/component.vue +5 -0
- package/metadata/packages/components/components/syn-radio-group/component.styles.ts +30 -9
- package/metadata/packages/components/components/syn-radio-group/component.ts +61 -32
- package/metadata/packages/components/components/syn-range/component.angular.ts +13 -0
- package/metadata/packages/components/components/syn-range/component.styles.ts +27 -3
- package/metadata/packages/components/components/syn-range/component.ts +17 -5
- package/metadata/packages/components/components/syn-range/component.vue +5 -0
- package/metadata/packages/components/components/syn-select/component.angular.ts +13 -0
- package/metadata/packages/components/components/syn-select/component.styles.ts +222 -151
- package/metadata/packages/components/components/syn-select/component.ts +30 -15
- package/metadata/packages/components/components/syn-select/component.vue +5 -0
- package/metadata/packages/components/components/syn-switch/component.angular.ts +13 -0
- package/metadata/packages/components/components/syn-switch/component.styles.ts +145 -63
- package/metadata/packages/components/components/syn-switch/component.ts +16 -4
- package/metadata/packages/components/components/syn-switch/component.vue +5 -0
- package/metadata/packages/components/components/syn-textarea/component.styles.ts +55 -27
- package/metadata/packages/components/components/syn-textarea/component.ts +1 -3
- package/metadata/packages/components/static/CHANGELOG.md +27 -0
- package/metadata/packages/tokens/CHANGELOG.md +22 -0
- package/metadata/packages/tokens/dark.css +7 -1
- package/metadata/packages/tokens/index.js +31 -1
- package/metadata/packages/tokens/light.css +7 -1
- package/metadata/packages/tokens/sick2018_dark.css +7 -1
- package/metadata/packages/tokens/sick2018_light.css +7 -1
- package/metadata/packages/tokens/sick2025_dark.css +7 -1
- package/metadata/packages/tokens/sick2025_light.css +7 -1
- package/metadata/static/components/syn-checkbox/docs.md +36 -0
- package/metadata/static/components/syn-combobox/docs.md +138 -0
- package/metadata/static/components/syn-file/docs.md +24 -0
- package/metadata/static/components/syn-input/docs.md +1 -1
- package/metadata/static/components/syn-radio/docs.md +21 -0
- package/metadata/static/components/syn-radio-group/docs.md +46 -0
- package/metadata/static/components/syn-range/docs.md +19 -0
- package/metadata/static/components/syn-select/docs.md +81 -0
- package/metadata/static/components/syn-switch/docs.md +22 -0
- package/metadata/static/components/syn-textarea/docs.md +1 -1
- package/metadata/static/components/syn-tooltip/docs.md +73 -0
- package/package.json +4 -4
- package/metadata/packages/components/components/syn-checkbox/component.custom.styles.ts +0 -86
- package/metadata/packages/components/components/syn-combobox/component.custom.styles.ts +0 -122
- package/metadata/packages/components/components/syn-radio/component.custom.styles.ts +0 -86
- package/metadata/packages/components/components/syn-radio-group/component.custom.styles.ts +0 -25
- package/metadata/packages/components/components/syn-select/component.custom.styles.ts +0 -175
- package/metadata/packages/components/components/syn-switch/component.custom.styles.ts +0 -141
- package/metadata/packages/components/components/syn-textarea/component.custom.styles.ts +0 -48
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
1
|
import { classMap } from 'lit/directives/class-map.js';
|
|
3
2
|
import { html } from 'lit';
|
|
3
|
+
import type { CSSResultGroup } from 'lit';
|
|
4
4
|
import { property, state } from 'lit/decorators.js';
|
|
5
5
|
import { watch } from '../../internal/watch.js';
|
|
6
6
|
import componentStyles from '../../styles/component.styles.js';
|
|
7
7
|
import SynergyElement from '../../internal/synergy-element.js';
|
|
8
8
|
import SynIcon from '../icon/icon.component.js';
|
|
9
9
|
import styles from './radio.styles.js';
|
|
10
|
-
import customStyles from './radio.custom.styles.js';
|
|
11
|
-
import type { CSSResultGroup } from 'lit';
|
|
12
10
|
import { enableDefaultSettings } from '../../utilities/defaultSettings/decorator.js';
|
|
13
11
|
|
|
14
12
|
/**
|
|
@@ -32,10 +30,12 @@ import { enableDefaultSettings } from '../../utilities/defaultSettings/decorator
|
|
|
32
30
|
*/
|
|
33
31
|
@enableDefaultSettings('SynRadio')
|
|
34
32
|
export default class SynRadio extends SynergyElement {
|
|
35
|
-
static styles: CSSResultGroup = [componentStyles, styles
|
|
33
|
+
static styles: CSSResultGroup = [componentStyles, styles];
|
|
34
|
+
|
|
36
35
|
static dependencies = { 'syn-icon': SynIcon };
|
|
37
36
|
|
|
38
37
|
@state() checked = false;
|
|
38
|
+
|
|
39
39
|
@state() protected hasFocus = false;
|
|
40
40
|
|
|
41
41
|
/** The radio's value. When selected, the radio group will receive this value. */
|
|
@@ -48,7 +48,10 @@ export default class SynRadio extends SynergyElement {
|
|
|
48
48
|
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
|
|
49
49
|
|
|
50
50
|
/** Disables the radio. */
|
|
51
|
-
@property({
|
|
51
|
+
@property({ reflect: true, type: Boolean }) disabled = false;
|
|
52
|
+
|
|
53
|
+
/** Sets the radio to a readonly state. */
|
|
54
|
+
@property({ reflect: true, type: Boolean }) readonly = false;
|
|
52
55
|
|
|
53
56
|
constructor() {
|
|
54
57
|
super();
|
|
@@ -68,6 +71,11 @@ export default class SynRadio extends SynergyElement {
|
|
|
68
71
|
};
|
|
69
72
|
|
|
70
73
|
private handleClick = () => {
|
|
74
|
+
if (this.readonly) {
|
|
75
|
+
this.focus();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
71
79
|
if (!this.disabled) {
|
|
72
80
|
this.checked = true;
|
|
73
81
|
}
|
|
@@ -81,7 +89,7 @@ export default class SynRadio extends SynergyElement {
|
|
|
81
89
|
private setInitialAttributes() {
|
|
82
90
|
this.setAttribute('role', 'radio');
|
|
83
91
|
this.setAttribute('tabindex', '-1');
|
|
84
|
-
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
|
92
|
+
this.setAttribute('aria-disabled', (this.disabled || this.readonly) ? 'true' : 'false');
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
@watch('checked')
|
|
@@ -90,9 +98,9 @@ export default class SynRadio extends SynergyElement {
|
|
|
90
98
|
this.setAttribute('tabindex', this.checked ? '0' : '-1');
|
|
91
99
|
}
|
|
92
100
|
|
|
93
|
-
@watch('disabled', { waitUntilFirstUpdate: true })
|
|
101
|
+
@watch(['disabled', 'readonly'], { waitUntilFirstUpdate: true })
|
|
94
102
|
handleDisabledChange() {
|
|
95
|
-
this.setAttribute('aria-disabled', this.disabled ? 'true' : 'false');
|
|
103
|
+
this.setAttribute('aria-disabled', (this.disabled || this.readonly) ? 'true' : 'false');
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
render() {
|
|
@@ -104,9 +112,10 @@ export default class SynRadio extends SynergyElement {
|
|
|
104
112
|
'radio--checked': this.checked,
|
|
105
113
|
'radio--disabled': this.disabled,
|
|
106
114
|
'radio--focused': this.hasFocus,
|
|
107
|
-
'radio--
|
|
115
|
+
'radio--large': this.size === 'large',
|
|
108
116
|
'radio--medium': this.size === 'medium',
|
|
109
|
-
'radio--
|
|
117
|
+
'radio--readonly': this.readonly,
|
|
118
|
+
'radio--small': this.size === 'small',
|
|
110
119
|
})}
|
|
111
120
|
>
|
|
112
121
|
<span part="${`control${this.checked ? ' control--checked' : ''}`}" class="radio__control">
|
|
@@ -57,6 +57,11 @@ attribute can typically be omitted.
|
|
|
57
57
|
* Disables the radio.
|
|
58
58
|
*/
|
|
59
59
|
disabled?: SynRadio['disabled'];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Sets the radio to a readonly state.
|
|
63
|
+
*/
|
|
64
|
+
readonly?: SynRadio['readonly'];
|
|
60
65
|
}>();
|
|
61
66
|
|
|
62
67
|
// Make sure prop binding only forwards the props that are actually there.
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
1
|
import { css } from 'lit';
|
|
3
2
|
|
|
4
3
|
export default css`
|
|
5
|
-
/* stylelint-disable */
|
|
6
4
|
:host {
|
|
7
5
|
display: block;
|
|
8
6
|
}
|
|
9
7
|
|
|
8
|
+
:host([data-user-invalid]) {
|
|
9
|
+
--syn-input-border-color: var(--syn-input-border-color-focus-error);
|
|
10
|
+
--syn-input-border-color-hover: var(--syn-input-border-color-focus-error);
|
|
11
|
+
--syn-color-primary-600: var(--syn-input-border-color-focus-error);
|
|
12
|
+
--syn-color-primary-900: var(--syn-color-error-900);
|
|
13
|
+
--syn-color-primary-950: var(--syn-color-error-950);
|
|
14
|
+
--syn-color-neutral-1000: var(--syn-input-border-color-focus-error);
|
|
15
|
+
--syn-interactive-emphasis-color: var(--syn-input-border-color-focus-error);
|
|
16
|
+
--syn-interactive-emphasis-color-hover: var(--syn-input-border-color-focus-error);
|
|
17
|
+
--syn-interactive-emphasis-color-active: var(--syn-input-border-color-focus-error);
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
.form-control {
|
|
11
|
-
position: relative;
|
|
12
21
|
border: none;
|
|
13
|
-
padding: 0;
|
|
14
22
|
margin: 0;
|
|
23
|
+
padding: 0;
|
|
24
|
+
position: relative;
|
|
15
25
|
}
|
|
16
26
|
|
|
17
27
|
.form-control__label {
|
|
@@ -24,14 +34,25 @@ export default css`
|
|
|
24
34
|
}
|
|
25
35
|
|
|
26
36
|
.visually-hidden {
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
border: 0;
|
|
38
|
+
/* stylelint-disable-next-line property-no-deprecated */
|
|
39
|
+
clip: rect(0, 0, 0, 0);
|
|
29
40
|
height: 1px;
|
|
30
|
-
padding: 0;
|
|
31
41
|
margin: -1px;
|
|
32
42
|
overflow: hidden;
|
|
33
|
-
|
|
43
|
+
padding: 0;
|
|
44
|
+
position: absolute;
|
|
34
45
|
white-space: nowrap;
|
|
35
|
-
|
|
46
|
+
width: 1px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.form-control-input {
|
|
50
|
+
display: flex;
|
|
51
|
+
flex-direction: column;
|
|
52
|
+
gap: var(--syn-spacing-x-small);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.form-control--has-help-text.form-control--radio-group .form-control__help-text {
|
|
56
|
+
margin-top: var(--syn-spacing-x-small);
|
|
36
57
|
}
|
|
37
58
|
`;
|
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-floating-promises */
|
|
2
|
+
/* eslint-disable no-param-reassign */
|
|
2
3
|
import { classMap } from 'lit/directives/class-map.js';
|
|
4
|
+
import { html } from 'lit';
|
|
5
|
+
import { property, query, state } from 'lit/decorators.js';
|
|
6
|
+
import type { CSSResultGroup } from 'lit';
|
|
3
7
|
import {
|
|
4
|
-
customErrorValidityState,
|
|
5
8
|
FormControlController,
|
|
9
|
+
customErrorValidityState,
|
|
6
10
|
validValidityState,
|
|
7
|
-
valueMissingValidityState
|
|
11
|
+
valueMissingValidityState,
|
|
8
12
|
} from '../../internal/form.js';
|
|
9
13
|
import { HasSlotController } from '../../internal/slot.js';
|
|
10
|
-
import { html } from 'lit';
|
|
11
|
-
import { property, query, state } from 'lit/decorators.js';
|
|
12
14
|
import { watch } from '../../internal/watch.js';
|
|
13
15
|
import componentStyles from '../../styles/component.styles.js';
|
|
14
16
|
import formControlStyles from '../../styles/form-control.styles.js';
|
|
15
|
-
import formControlCustomStyles from '../../styles/form-control.custom.styles.js';
|
|
16
17
|
import SynergyElement from '../../internal/synergy-element.js';
|
|
17
18
|
import SynButtonGroup from '../button-group/button-group.component.js';
|
|
18
19
|
import styles from './radio-group.styles.js';
|
|
19
|
-
import customStyles from './radio-group.custom.styles.js';
|
|
20
|
-
import type { CSSResultGroup } from 'lit';
|
|
21
20
|
import type { SynergyFormControl } from '../../internal/synergy-element.js';
|
|
22
21
|
import type SynRadio from '../radio/radio.js';
|
|
23
22
|
import type SynRadioButton from '../radio-button/radio-button.js';
|
|
@@ -49,19 +48,26 @@ import { enableDefaultSettings } from '../../utilities/defaultSettings/decorator
|
|
|
49
48
|
*/
|
|
50
49
|
@enableDefaultSettings('SynRadioGroup')
|
|
51
50
|
export default class SynRadioGroup extends SynergyElement implements SynergyFormControl {
|
|
52
|
-
static styles: CSSResultGroup = [componentStyles, formControlStyles, styles
|
|
51
|
+
static styles: CSSResultGroup = [componentStyles, formControlStyles, styles];
|
|
52
|
+
|
|
53
53
|
static dependencies = { 'syn-button-group': SynButtonGroup };
|
|
54
54
|
|
|
55
55
|
protected readonly formControlController = new FormControlController(this);
|
|
56
|
+
|
|
56
57
|
private readonly hasSlotController = new HasSlotController(this, 'help-text', 'label');
|
|
58
|
+
|
|
57
59
|
private customValidityMessage = '';
|
|
60
|
+
|
|
58
61
|
private validationTimeout: number;
|
|
59
62
|
|
|
60
63
|
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
|
64
|
+
|
|
61
65
|
@query('.radio-group__validation-input') validationInput: HTMLInputElement;
|
|
62
66
|
|
|
63
67
|
@state() private hasButtonGroup = false;
|
|
68
|
+
|
|
64
69
|
@state() private errorMessage = '';
|
|
70
|
+
|
|
65
71
|
@state() defaultValue: string | number = '';
|
|
66
72
|
|
|
67
73
|
/**
|
|
@@ -90,7 +96,7 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
90
96
|
@property({ reflect: true }) form = '';
|
|
91
97
|
|
|
92
98
|
/** Ensures a child radio is checked before allowing the containing form to submit. */
|
|
93
|
-
@property({
|
|
99
|
+
@property({ reflect: true, type: Boolean }) required = false;
|
|
94
100
|
|
|
95
101
|
/** Gets the validity state object */
|
|
96
102
|
get validity() {
|
|
@@ -99,7 +105,9 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
99
105
|
|
|
100
106
|
if (hasCustomValidityMessage) {
|
|
101
107
|
return customErrorValidityState;
|
|
102
|
-
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (isRequiredAndEmpty) {
|
|
103
111
|
return valueMissingValidityState;
|
|
104
112
|
}
|
|
105
113
|
|
|
@@ -113,7 +121,9 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
113
121
|
|
|
114
122
|
if (hasCustomValidityMessage) {
|
|
115
123
|
return this.customValidityMessage;
|
|
116
|
-
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (isRequiredAndEmpty) {
|
|
117
127
|
return this.validationInput.validationMessage;
|
|
118
128
|
}
|
|
119
129
|
|
|
@@ -138,12 +148,15 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
138
148
|
const radios = this.getAllRadios();
|
|
139
149
|
const oldValue = this.value;
|
|
140
150
|
|
|
141
|
-
if
|
|
151
|
+
// #1174: If we have a radio, also do nothing if the radio is readonly
|
|
152
|
+
if (!target || target.disabled || (target as SynRadio).readonly) {
|
|
142
153
|
return;
|
|
143
154
|
}
|
|
144
155
|
|
|
145
156
|
this.value = target.value;
|
|
146
|
-
radios.forEach(radio =>
|
|
157
|
+
radios.forEach(radio => {
|
|
158
|
+
radio.checked = radio === target;
|
|
159
|
+
});
|
|
147
160
|
|
|
148
161
|
if (this.value !== oldValue) {
|
|
149
162
|
this.emit('syn-change');
|
|
@@ -156,21 +169,26 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
156
169
|
return;
|
|
157
170
|
}
|
|
158
171
|
|
|
159
|
-
|
|
160
|
-
const
|
|
172
|
+
// #1174: Filter out elements that are either disabled or readonly
|
|
173
|
+
const availableRadios = this.getAllRadios().filter(radio => (!radio.disabled && !(radio as SynRadio).readonly));
|
|
174
|
+
const checkedRadio = availableRadios.find(radio => radio.checked) ?? availableRadios[0];
|
|
175
|
+
|
|
176
|
+
// eslint-disable-next-line no-nested-ternary
|
|
161
177
|
const incr = event.key === ' ' ? 0 : ['ArrowUp', 'ArrowLeft'].includes(event.key) ? -1 : 1;
|
|
162
178
|
const oldValue = this.value;
|
|
163
|
-
let index =
|
|
179
|
+
let index = availableRadios.indexOf(checkedRadio) + incr;
|
|
164
180
|
|
|
165
181
|
if (index < 0) {
|
|
166
|
-
index =
|
|
182
|
+
index = availableRadios.length - 1;
|
|
167
183
|
}
|
|
168
184
|
|
|
169
|
-
if (index >
|
|
185
|
+
if (index > availableRadios.length - 1) {
|
|
170
186
|
index = 0;
|
|
171
187
|
}
|
|
172
188
|
|
|
173
|
-
this.getAllRadios()
|
|
189
|
+
const allRadios = this.getAllRadios();
|
|
190
|
+
|
|
191
|
+
allRadios.forEach(radio => {
|
|
174
192
|
radio.checked = false;
|
|
175
193
|
|
|
176
194
|
if (!this.hasButtonGroup) {
|
|
@@ -178,14 +196,19 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
178
196
|
}
|
|
179
197
|
});
|
|
180
198
|
|
|
181
|
-
|
|
182
|
-
|
|
199
|
+
// #1175: If all radios are readonly, skip and focus the first one and do not change the value
|
|
200
|
+
if (!availableRadios[index]) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
this.value = availableRadios[index].value;
|
|
205
|
+
availableRadios[index].checked = true;
|
|
183
206
|
|
|
184
207
|
if (!this.hasButtonGroup) {
|
|
185
|
-
|
|
186
|
-
|
|
208
|
+
availableRadios[index].setAttribute('tabindex', '0');
|
|
209
|
+
availableRadios[index].focus();
|
|
187
210
|
} else {
|
|
188
|
-
|
|
211
|
+
availableRadios[index].shadowRoot!.querySelector('button')!.focus();
|
|
189
212
|
}
|
|
190
213
|
|
|
191
214
|
if (this.value !== oldValue) {
|
|
@@ -214,7 +237,7 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
214
237
|
await radio.updateComplete;
|
|
215
238
|
radio.checked = radio.value === this.value;
|
|
216
239
|
radio.size = this.size;
|
|
217
|
-
})
|
|
240
|
+
}),
|
|
218
241
|
);
|
|
219
242
|
|
|
220
243
|
this.hasButtonGroup = radios.some(radio => radio.tagName.toLowerCase() === 'syn-radio-button');
|
|
@@ -262,7 +285,9 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
262
285
|
|
|
263
286
|
private updateCheckedRadio() {
|
|
264
287
|
const radios = this.getAllRadios();
|
|
265
|
-
radios.forEach(radio =>
|
|
288
|
+
radios.forEach(radio => {
|
|
289
|
+
radio.checked = radio.value === this.value;
|
|
290
|
+
});
|
|
266
291
|
this.formControlController.setValidity(this.validity.valid);
|
|
267
292
|
}
|
|
268
293
|
|
|
@@ -309,7 +334,9 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
309
334
|
// Show the browser's constraint validation message
|
|
310
335
|
this.validationInput.hidden = false;
|
|
311
336
|
this.validationInput.reportValidity();
|
|
312
|
-
this.validationTimeout = setTimeout(() =>
|
|
337
|
+
this.validationTimeout = setTimeout(() => {
|
|
338
|
+
this.validationInput.hidden = true;
|
|
339
|
+
}, 10000) as unknown as number;
|
|
313
340
|
}
|
|
314
341
|
|
|
315
342
|
return isValid;
|
|
@@ -338,6 +365,7 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
338
365
|
}
|
|
339
366
|
|
|
340
367
|
render() {
|
|
368
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
341
369
|
const hasLabelSlot = this.hasSlotController.test('label');
|
|
342
370
|
const hasHelpTextSlot = this.hasSlotController.test('help-text');
|
|
343
371
|
const hasLabel = this.label ? true : !!hasLabelSlot;
|
|
@@ -351,12 +379,12 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
351
379
|
part="form-control"
|
|
352
380
|
class=${classMap({
|
|
353
381
|
'form-control': true,
|
|
354
|
-
'form-control--
|
|
355
|
-
'form-control--
|
|
382
|
+
'form-control--has-help-text': hasHelpText,
|
|
383
|
+
'form-control--has-label': hasLabel,
|
|
356
384
|
'form-control--large': this.size === 'large',
|
|
385
|
+
'form-control--medium': this.size === 'medium',
|
|
357
386
|
'form-control--radio-group': true,
|
|
358
|
-
'form-control--
|
|
359
|
-
'form-control--has-help-text': hasHelpText
|
|
387
|
+
'form-control--small': this.size === 'small',
|
|
360
388
|
})}
|
|
361
389
|
role="radiogroup"
|
|
362
390
|
aria-labelledby="label"
|
|
@@ -407,5 +435,6 @@ export default class SynRadioGroup extends SynergyElement implements SynergyForm
|
|
|
407
435
|
</div>
|
|
408
436
|
</fieldset>
|
|
409
437
|
`;
|
|
438
|
+
/* eslint-enable @typescript-eslint/unbound-method */
|
|
410
439
|
}
|
|
411
440
|
}
|
|
@@ -177,6 +177,19 @@ export class SynRangeComponent {
|
|
|
177
177
|
return this.nativeElement.disabled;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
/**
|
|
181
|
+
* Sets the range to a readonly state.
|
|
182
|
+
*/
|
|
183
|
+
@Input()
|
|
184
|
+
set readonly(v: '' | SynRange['readonly']) {
|
|
185
|
+
this._ngZone.runOutsideAngular(
|
|
186
|
+
() => (this.nativeElement.readonly = v === '' || v),
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
get readonly(): SynRange['readonly'] {
|
|
190
|
+
return this.nativeElement.readonly;
|
|
191
|
+
}
|
|
192
|
+
|
|
180
193
|
/**
|
|
181
194
|
* The minimum acceptable value of the range.
|
|
182
195
|
*/
|
|
@@ -213,20 +213,26 @@ export default css`
|
|
|
213
213
|
cursor: not-allowed;
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
+
:host([readonly]) .track__wrapper,
|
|
217
|
+
:host([readonly]) .thumb,
|
|
218
|
+
:host([readonly]) .thumb.grabbed {
|
|
219
|
+
cursor: default;
|
|
220
|
+
}
|
|
221
|
+
|
|
216
222
|
/*
|
|
217
223
|
* Guard against mobile devices not removing the transform
|
|
218
224
|
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/@media/any-hover
|
|
219
225
|
*/
|
|
220
226
|
@media (any-hover: hover) {
|
|
221
|
-
:host(:not([disabled])) .thumb:hover {
|
|
227
|
+
:host(:not([disabled]):not([readonly])) .thumb:hover {
|
|
222
228
|
transform: scale(var(--thumb-hit-area-size));
|
|
223
229
|
}
|
|
224
230
|
|
|
225
|
-
:host(:not([disabled])) .thumb:not(.grabbed):hover {
|
|
231
|
+
:host(:not([disabled]):not([readonly])) .thumb:not(.grabbed):hover {
|
|
226
232
|
background: var(--syn-interactive-emphasis-color-hover);
|
|
227
233
|
}
|
|
228
234
|
|
|
229
|
-
:host(:not([disabled])) .thumb:hover::after {
|
|
235
|
+
:host(:not([disabled]):not([readonly])) .thumb:hover::after {
|
|
230
236
|
/* Unset the area of the thumb click and drag area space, so it does not scale with the hover */
|
|
231
237
|
inset: unset;
|
|
232
238
|
}
|
|
@@ -282,4 +288,22 @@ export default css`
|
|
|
282
288
|
:host([data-user-invalid]) .thumb {
|
|
283
289
|
background-color: var(--syn-range-error-color);
|
|
284
290
|
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* #1176: Readonly state
|
|
294
|
+
*/
|
|
295
|
+
:host([readonly]) {
|
|
296
|
+
--track-color-active: var(--syn-readonly-indicator-color);
|
|
297
|
+
--track-color-inactive: var(--syn-readonly-background-color);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
:host([readonly]) .thumb {
|
|
301
|
+
background-color: var(--syn-readonly-indicator-color);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
:host([readonly]) .thumb:focus {
|
|
305
|
+
background-color: var(--syn-readonly-indicator-color);
|
|
306
|
+
outline: var(--syn-focus-ring);
|
|
307
|
+
outline-offset: 0;
|
|
308
|
+
}
|
|
285
309
|
`;
|
|
@@ -11,7 +11,6 @@ import { HasSlotController } from '../../internal/slot.js';
|
|
|
11
11
|
import { LocalizeController } from '../../utilities/localize.js';
|
|
12
12
|
import componentStyles from '../../styles/component.styles.js';
|
|
13
13
|
import formControlStyles from '../../styles/form-control.styles.js';
|
|
14
|
-
import formControlCustomStyles from '../../styles/form-control.custom.styles.js';
|
|
15
14
|
import SynergyElement from '../../internal/synergy-element.js';
|
|
16
15
|
import SynTooltip from '../tooltip/tooltip.component.js';
|
|
17
16
|
import {
|
|
@@ -78,7 +77,6 @@ export default class SynRange extends SynergyElement implements SynergyFormContr
|
|
|
78
77
|
static styles: CSSResultGroup = [
|
|
79
78
|
componentStyles,
|
|
80
79
|
formControlStyles,
|
|
81
|
-
formControlCustomStyles,
|
|
82
80
|
styles,
|
|
83
81
|
];
|
|
84
82
|
|
|
@@ -98,6 +96,9 @@ export default class SynRange extends SynergyElement implements SynergyFormContr
|
|
|
98
96
|
/** Disables the range. */
|
|
99
97
|
@property({ reflect: true, type: Boolean }) disabled = false;
|
|
100
98
|
|
|
99
|
+
/** Sets the range to a readonly state. */
|
|
100
|
+
@property({ reflect: true, type: Boolean }) readonly = false;
|
|
101
|
+
|
|
101
102
|
/** The minimum acceptable value of the range. */
|
|
102
103
|
@property({ type: Number }) min = 0;
|
|
103
104
|
|
|
@@ -354,6 +355,12 @@ export default class SynRange extends SynergyElement implements SynergyFormContr
|
|
|
354
355
|
|
|
355
356
|
#onClickTrack(event: PointerEvent, focusThumb = true) {
|
|
356
357
|
if (this.disabled) return;
|
|
358
|
+
if (this.readonly) {
|
|
359
|
+
event.preventDefault();
|
|
360
|
+
this.focus();
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
357
364
|
const { clientX } = event;
|
|
358
365
|
|
|
359
366
|
const thumbs = Array.from(this.thumbs);
|
|
@@ -443,7 +450,7 @@ export default class SynRange extends SynergyElement implements SynergyFormContr
|
|
|
443
450
|
}
|
|
444
451
|
|
|
445
452
|
async #onClickThumb(event: PointerEvent) {
|
|
446
|
-
if (this.disabled) return;
|
|
453
|
+
if (this.disabled || this.readonly) return;
|
|
447
454
|
|
|
448
455
|
const thumb = event.target as HTMLDivElement;
|
|
449
456
|
this.#updateTooltip(thumb);
|
|
@@ -460,7 +467,7 @@ export default class SynRange extends SynergyElement implements SynergyFormContr
|
|
|
460
467
|
}
|
|
461
468
|
|
|
462
469
|
#onDragThumb(event: PointerEvent) {
|
|
463
|
-
if (this.disabled) return;
|
|
470
|
+
if (this.disabled || this.readonly) return;
|
|
464
471
|
|
|
465
472
|
const thumb = event.target as HTMLDivElement;
|
|
466
473
|
const rangeId = +thumb.dataset.rangeId!;
|
|
@@ -509,6 +516,8 @@ export default class SynRange extends SynergyElement implements SynergyFormContr
|
|
|
509
516
|
}
|
|
510
517
|
|
|
511
518
|
async #onReleaseThumb(event: PointerEvent) {
|
|
519
|
+
if (this.disabled || this.readonly) return;
|
|
520
|
+
|
|
512
521
|
const thumb = event.target as HTMLDivElement;
|
|
513
522
|
if (!thumb.dataset.pointerId || event.pointerId !== +thumb.dataset.pointerId) return;
|
|
514
523
|
|
|
@@ -569,6 +578,8 @@ export default class SynRange extends SynergyElement implements SynergyFormContr
|
|
|
569
578
|
}
|
|
570
579
|
|
|
571
580
|
#onKeyPress(event: KeyboardEvent) {
|
|
581
|
+
if (this.readonly) return;
|
|
582
|
+
|
|
572
583
|
const thumb = event.target as HTMLDivElement;
|
|
573
584
|
const rangeId = +thumb.dataset.rangeId!;
|
|
574
585
|
|
|
@@ -756,7 +767,7 @@ export default class SynRange extends SynergyElement implements SynergyFormContr
|
|
|
756
767
|
trigger="focus"
|
|
757
768
|
>
|
|
758
769
|
<div
|
|
759
|
-
aria-disabled=${ifDefined(this.disabled ? 'true' : undefined)}
|
|
770
|
+
aria-disabled=${ifDefined((this.disabled || this.readonly) ? 'true' : undefined)}
|
|
760
771
|
aria-labelledby=${ariaLabeledBy}
|
|
761
772
|
aria-label=${ariaLabel}
|
|
762
773
|
aria-valuemax="${this.max}"
|
|
@@ -802,6 +813,7 @@ export default class SynRange extends SynergyElement implements SynergyFormContr
|
|
|
802
813
|
'form-control--has-prefix': hasPrefixSlot,
|
|
803
814
|
'form-control--has-suffix': hasSuffixSlot,
|
|
804
815
|
'form-control--is-disabled': this.disabled,
|
|
816
|
+
'form-control--is-readonly': this.readonly,
|
|
805
817
|
'form-control--large': this.size === 'large',
|
|
806
818
|
'form-control--medium': this.size === 'medium',
|
|
807
819
|
'form-control--small': this.size === 'small',
|
|
@@ -235,6 +235,19 @@ indicate the number of additional items that are selected.
|
|
|
235
235
|
return this.nativeElement.disabled;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Sets the select to a readonly state.
|
|
240
|
+
*/
|
|
241
|
+
@Input()
|
|
242
|
+
set readonly(v: '' | SynSelect['readonly']) {
|
|
243
|
+
this._ngZone.runOutsideAngular(
|
|
244
|
+
() => (this.nativeElement.readonly = v === '' || v),
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
get readonly(): SynSelect['readonly'] {
|
|
248
|
+
return this.nativeElement.readonly;
|
|
249
|
+
}
|
|
250
|
+
|
|
238
251
|
/**
|
|
239
252
|
* Adds a clear button when the select is not empty.
|
|
240
253
|
*/
|