@aquera/nile-elements 0.0.4-8 → 0.0.4-9
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/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/index.d.ts +2 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/index.js +2 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/index.js.map +1 -1
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-link/nile-link.css.js +2 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-link/nile-link.css.js.map +1 -1
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button/index.d.ts +1 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button/index.js +2 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button/index.js.map +1 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button/nile-radio-button.css.d.ts +12 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button/nile-radio-button.css.js +173 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button/nile-radio-button.css.js.map +1 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button/nile-radio-button.d.ts +57 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button/nile-radio-button.js +145 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button/nile-radio-button.js.map +1 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button-group/index.d.ts +1 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button-group/index.js +2 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button-group/index.js.map +1 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button-group/nile-radio-button-group.css.d.ts +12 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button-group/nile-radio-button-group.css.js +70 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button-group/nile-radio-button-group.css.js.map +1 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button-group/nile-radio-button-group.d.ts +66 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button-group/nile-radio-button-group.js +308 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/src/nile-radio-button-group/nile-radio-button-group.js.map +1 -0
- package/.rollup.cache/opt/atlassian/pipelines/agent/build/packages/nile-elements/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.iife.js +370 -76
- package/dist/nile-link/nile-link.css.cjs.js +1 -1
- package/dist/nile-link/nile-link.css.cjs.js.map +1 -1
- package/dist/nile-link/nile-link.css.esm.js +2 -0
- package/dist/nile-radio-button/index.cjs.js +2 -0
- package/dist/nile-radio-button/index.cjs.js.map +1 -0
- package/dist/nile-radio-button/index.esm.js +1 -0
- package/dist/nile-radio-button/nile-radio-button.cjs.js +2 -0
- package/dist/nile-radio-button/nile-radio-button.cjs.js.map +1 -0
- package/dist/nile-radio-button/nile-radio-button.css.cjs.js +2 -0
- package/dist/nile-radio-button/nile-radio-button.css.cjs.js.map +1 -0
- package/dist/nile-radio-button/nile-radio-button.css.esm.js +161 -0
- package/dist/nile-radio-button/nile-radio-button.esm.js +21 -0
- package/dist/nile-radio-button-group/index.cjs.js +2 -0
- package/dist/nile-radio-button-group/index.cjs.js.map +1 -0
- package/dist/nile-radio-button-group/index.esm.js +1 -0
- package/dist/nile-radio-button-group/nile-radio-button-group.cjs.js +2 -0
- package/dist/nile-radio-button-group/nile-radio-button-group.cjs.js.map +1 -0
- package/dist/nile-radio-button-group/nile-radio-button-group.css.cjs.js +2 -0
- package/dist/nile-radio-button-group/nile-radio-button-group.css.cjs.js.map +1 -0
- package/dist/nile-radio-button-group/nile-radio-button-group.css.esm.js +58 -0
- package/dist/nile-radio-button-group/nile-radio-button-group.esm.js +56 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/nile-link/nile-link.css.js +2 -0
- package/dist/src/nile-link/nile-link.css.js.map +1 -1
- package/dist/src/nile-radio-button/index.d.ts +1 -0
- package/dist/src/nile-radio-button/index.js +2 -0
- package/dist/src/nile-radio-button/index.js.map +1 -0
- package/dist/src/nile-radio-button/nile-radio-button.css.d.ts +12 -0
- package/dist/src/nile-radio-button/nile-radio-button.css.js +173 -0
- package/dist/src/nile-radio-button/nile-radio-button.css.js.map +1 -0
- package/dist/src/nile-radio-button/nile-radio-button.d.ts +57 -0
- package/dist/src/nile-radio-button/nile-radio-button.js +145 -0
- package/dist/src/nile-radio-button/nile-radio-button.js.map +1 -0
- package/dist/src/nile-radio-button-group/index.d.ts +1 -0
- package/dist/src/nile-radio-button-group/index.js +2 -0
- package/dist/src/nile-radio-button-group/index.js.map +1 -0
- package/dist/src/nile-radio-button-group/nile-radio-button-group.css.d.ts +12 -0
- package/dist/src/nile-radio-button-group/nile-radio-button-group.css.js +70 -0
- package/dist/src/nile-radio-button-group/nile-radio-button-group.css.js.map +1 -0
- package/dist/src/nile-radio-button-group/nile-radio-button-group.d.ts +66 -0
- package/dist/src/nile-radio-button-group/nile-radio-button-group.js +308 -0
- package/dist/src/nile-radio-button-group/nile-radio-button-group.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/nile-link/nile-link.css.ts +2 -0
- package/src/nile-radio-button/index.ts +1 -0
- package/src/nile-radio-button/nile-radio-button.css.ts +175 -0
- package/src/nile-radio-button/nile-radio-button.ts +151 -0
- package/src/nile-radio-button-group/index.ts +1 -0
- package/src/nile-radio-button-group/nile-radio-button-group.css.ts +72 -0
- package/src/nile-radio-button-group/nile-radio-button-group.ts +337 -0
@@ -0,0 +1,337 @@
|
|
1
|
+
import { classMap } from 'lit/directives/class-map.js';
|
2
|
+
import { customElement, property, query, state } from 'lit/decorators.js';
|
3
|
+
import { HasSlotController } from '../internal/slot';
|
4
|
+
import { html } from 'lit';
|
5
|
+
import { watch } from '../internal/watch';
|
6
|
+
import NileElement from '../internal/nile-element';
|
7
|
+
import styles from './nile-radio-button-group.css';
|
8
|
+
import type { CSSResultGroup } from 'lit';
|
9
|
+
import type NileRadioButton from '../nile-radio-button/nile-radio-button';
|
10
|
+
|
11
|
+
/**
|
12
|
+
* @summary Radio groups are used to group multiple [radios](/components/radio) or [radio buttons](/components/radio-button) so they function as a single form control.
|
13
|
+
*
|
14
|
+
* @dependency nile-button-group
|
15
|
+
*
|
16
|
+
* @slot - The default slot where `<nile-radio>` or `<nile-radio-button>` elements are placed.
|
17
|
+
* @slot label - The radio group's label. Required for proper accessibility. Alternatively, you can use the `label`
|
18
|
+
* attribute.
|
19
|
+
*
|
20
|
+
* @event change - Emitted when the radio group's selected value changes.
|
21
|
+
* @event input - Emitted when the radio group receives user input.
|
22
|
+
* @event invalid - Emitted when the form control has been checked for validity and its constraints aren't satisfied.
|
23
|
+
* @csspart button-group - The button group that wraps radio buttons.
|
24
|
+
* @csspart button-group__base - The button group's `base` part.
|
25
|
+
*/
|
26
|
+
@customElement('nile-radio-button-group')
|
27
|
+
export class NileRadioButtonGroup extends NileElement {
|
28
|
+
static styles: CSSResultGroup = styles;
|
29
|
+
|
30
|
+
private readonly hasSlotController = new HasSlotController(
|
31
|
+
this,
|
32
|
+
'help-text',
|
33
|
+
'label'
|
34
|
+
);
|
35
|
+
private customValidityMessage = '';
|
36
|
+
|
37
|
+
@query('slot:not([name])') defaultSlot: HTMLSlotElement;
|
38
|
+
|
39
|
+
@state() private hasButtonGroup = false;
|
40
|
+
|
41
|
+
@state() defaultValue = '';
|
42
|
+
|
43
|
+
/**
|
44
|
+
* The radio group's label. Required for proper accessibility. If you need to display HTML, use the `label` slot
|
45
|
+
* instead.
|
46
|
+
*/
|
47
|
+
@property() label = '';
|
48
|
+
|
49
|
+
/** The name of the radio group, submitted as a name/value pair with form data. */
|
50
|
+
@property() name = 'option';
|
51
|
+
|
52
|
+
/** The current value of the radio group, submitted as a name/value pair with form data. */
|
53
|
+
@property({ reflect: true }) value = '';
|
54
|
+
|
55
|
+
/**
|
56
|
+
* By default, form controls are associated with the nearest containing `<form>` element. This attribute allows you
|
57
|
+
* to place the form control outside of a form and associate it with the form that has this `id`. The form must be in
|
58
|
+
* the same document or shadow root for this to work.
|
59
|
+
*/
|
60
|
+
@property({ reflect: true }) form = '';
|
61
|
+
|
62
|
+
/** Ensures a child radio is checked before allowing the containing form to submit. */
|
63
|
+
@property({ type: Boolean, reflect: true }) required = false;
|
64
|
+
|
65
|
+
/** Used to show radio in inline or not */
|
66
|
+
@property({ type: Boolean, reflect: true }) labelInline = false;
|
67
|
+
|
68
|
+
/** Used to disabled or not */
|
69
|
+
@property({ type: Boolean, reflect: true }) disabled = false;
|
70
|
+
|
71
|
+
@property({ attribute: 'help-text' }) helpText = '';
|
72
|
+
|
73
|
+
@property({ attribute: 'error-message' }) errorMessage = '';
|
74
|
+
|
75
|
+
connectedCallback() {
|
76
|
+
super.connectedCallback();
|
77
|
+
this.defaultValue = this.value;
|
78
|
+
this.handleInitialDisabledState();
|
79
|
+
}
|
80
|
+
|
81
|
+
private getAllRadios() {
|
82
|
+
return [...this.querySelectorAll<NileRadioButton>('nile-radio-button')];
|
83
|
+
}
|
84
|
+
|
85
|
+
private handleRadioClick(event: MouseEvent) {
|
86
|
+
const target = (event.target as HTMLElement).closest<NileRadioButton>(
|
87
|
+
'nile-radio-button'
|
88
|
+
)!;
|
89
|
+
const radios = this.getAllRadios();
|
90
|
+
const oldValue = this.value;
|
91
|
+
|
92
|
+
if (target.disabled) {
|
93
|
+
return;
|
94
|
+
}
|
95
|
+
|
96
|
+
this.value = target.value;
|
97
|
+
radios.forEach(radio => (radio.checked = radio === target));
|
98
|
+
|
99
|
+
if (this.value !== oldValue) {
|
100
|
+
this.emit('nile-change', { value: this.value });
|
101
|
+
this.emit('input');
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
@watch('disabled', { waitUntilFirstUpdate: true })
|
106
|
+
handleDisabledChange() {
|
107
|
+
this.getAllRadios().forEach(radio => {
|
108
|
+
radio.disabled = this.disabled;
|
109
|
+
});
|
110
|
+
}
|
111
|
+
|
112
|
+
private handleInitialDisabledState() {
|
113
|
+
this.getAllRadios().forEach(radio => {
|
114
|
+
radio.disabled = radio.hasAttribute('disabled')
|
115
|
+
? radio.disabled
|
116
|
+
: this.disabled;
|
117
|
+
});
|
118
|
+
}
|
119
|
+
|
120
|
+
private handleKeyDown(event: KeyboardEvent) {
|
121
|
+
if (
|
122
|
+
!['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' '].includes(
|
123
|
+
event.key
|
124
|
+
)
|
125
|
+
) {
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
|
129
|
+
const radios = this.getAllRadios().filter(radio => !radio.disabled);
|
130
|
+
const checkedRadio = radios.find(radio => radio.checked) ?? radios[0];
|
131
|
+
const incr =
|
132
|
+
event.key === ' '
|
133
|
+
? 0
|
134
|
+
: ['ArrowUp', 'ArrowLeft'].includes(event.key)
|
135
|
+
? -1
|
136
|
+
: 1;
|
137
|
+
const oldValue = this.value;
|
138
|
+
let index = radios.indexOf(checkedRadio) + incr;
|
139
|
+
|
140
|
+
if (index < 0) {
|
141
|
+
index = radios.length - 1;
|
142
|
+
}
|
143
|
+
|
144
|
+
if (index > radios.length - 1) {
|
145
|
+
index = 0;
|
146
|
+
}
|
147
|
+
|
148
|
+
this.getAllRadios().forEach(radio => {
|
149
|
+
radio.checked = false;
|
150
|
+
|
151
|
+
if (!this.hasButtonGroup) {
|
152
|
+
radio.tabIndex = -1;
|
153
|
+
}
|
154
|
+
});
|
155
|
+
|
156
|
+
this.value = radios[index].value;
|
157
|
+
radios[index].checked = true;
|
158
|
+
|
159
|
+
if (!this.hasButtonGroup) {
|
160
|
+
radios[index].tabIndex = 0;
|
161
|
+
radios[index].focus();
|
162
|
+
} else {
|
163
|
+
radios[index].shadowRoot!.querySelector('button')!.focus();
|
164
|
+
}
|
165
|
+
|
166
|
+
if (this.value !== oldValue) {
|
167
|
+
this.emit('change');
|
168
|
+
this.emit('input');
|
169
|
+
}
|
170
|
+
|
171
|
+
event.preventDefault();
|
172
|
+
}
|
173
|
+
|
174
|
+
private handleLabelClick() {
|
175
|
+
const radios = this.getAllRadios();
|
176
|
+
const checked = radios.find(radio => radio.checked);
|
177
|
+
const radioToFocus = checked || radios[0];
|
178
|
+
|
179
|
+
// Move focus to the checked radio (or the first one if none are checked) when clicking the label
|
180
|
+
if (radioToFocus) {
|
181
|
+
radioToFocus.focus();
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
private handleSlotChange() {
|
186
|
+
const radios = this.getAllRadios();
|
187
|
+
|
188
|
+
radios.forEach(radio => (radio.checked = radio.value === this.value));
|
189
|
+
|
190
|
+
this.hasButtonGroup = radios.some(
|
191
|
+
radio => radio.tagName.toLowerCase() === 'nile-radio-button'
|
192
|
+
);
|
193
|
+
|
194
|
+
if (!radios.some(radio => radio.checked)) {
|
195
|
+
if (this.hasButtonGroup) {
|
196
|
+
const buttonRadio = radios[0].shadowRoot!.querySelector('button')!;
|
197
|
+
buttonRadio.tabIndex = 0;
|
198
|
+
} else {
|
199
|
+
radios[0].tabIndex = 0;
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
if (this.hasButtonGroup) {
|
204
|
+
const buttonGroup = this.shadowRoot?.querySelector('nile-button-group');
|
205
|
+
}
|
206
|
+
|
207
|
+
const slottedElements = [
|
208
|
+
...this.defaultSlot.assignedElements({ flatten: true }),
|
209
|
+
] as HTMLElement[];
|
210
|
+
|
211
|
+
// console.log(slottedElements);
|
212
|
+
|
213
|
+
slottedElements.forEach(el => {
|
214
|
+
const index = slottedElements.indexOf(el);
|
215
|
+
const button = this.findButton(el);
|
216
|
+
|
217
|
+
if (button !== null) {
|
218
|
+
button.classList.toggle('nile-radio-button--first', index === 0);
|
219
|
+
button.classList.toggle(
|
220
|
+
'nile-radio-button--inner',
|
221
|
+
index > 0 && index < slottedElements.length - 1
|
222
|
+
);
|
223
|
+
button.classList.toggle(
|
224
|
+
'nile-radio-button--last',
|
225
|
+
index === slottedElements.length - 1
|
226
|
+
);
|
227
|
+
}
|
228
|
+
});
|
229
|
+
}
|
230
|
+
|
231
|
+
private findButton(el: HTMLElement) {
|
232
|
+
const selector = 'nile-radio-button';
|
233
|
+
|
234
|
+
return el.closest(selector) ?? el.querySelector(selector);
|
235
|
+
}
|
236
|
+
|
237
|
+
private updateCheckedRadio() {
|
238
|
+
const radios = this.getAllRadios();
|
239
|
+
radios.forEach(radio => (radio.checked = radio.value === this.value));
|
240
|
+
}
|
241
|
+
|
242
|
+
@watch('value')
|
243
|
+
handleValueChange() {
|
244
|
+
if (this.hasUpdated) {
|
245
|
+
this.updateCheckedRadio();
|
246
|
+
}
|
247
|
+
}
|
248
|
+
|
249
|
+
render() {
|
250
|
+
const hasLabelSlot = this.hasSlotController.test('label');
|
251
|
+
const hasHelpTextSlot = this.hasSlotController.test('help-text');
|
252
|
+
const hasLabel = this.label ? true : !!hasLabelSlot;
|
253
|
+
const hasHelpText = this.helpText ? true : false;
|
254
|
+
const hasErrorMessage = this.errorMessage ? true : false;
|
255
|
+
|
256
|
+
const defaultSlot = html`
|
257
|
+
<slot
|
258
|
+
@click=${this.handleRadioClick}
|
259
|
+
@keydown=${this.handleKeyDown}
|
260
|
+
@slotchange=${this.handleSlotChange}
|
261
|
+
role="presentation"
|
262
|
+
></slot>
|
263
|
+
`;
|
264
|
+
|
265
|
+
return html`
|
266
|
+
<fieldset
|
267
|
+
part="form-control"
|
268
|
+
class=${classMap({
|
269
|
+
'form-control': true,
|
270
|
+
'form-control--medium': true,
|
271
|
+
'form-control--radio-group': true,
|
272
|
+
'form-control--has-label': hasLabel,
|
273
|
+
'form-control--has-help-text': hasHelpText,
|
274
|
+
})}
|
275
|
+
role="radiogroup"
|
276
|
+
aria-labelledby="label"
|
277
|
+
aria-describedby="help-text"
|
278
|
+
aria-errormessage="error-message"
|
279
|
+
>
|
280
|
+
<label
|
281
|
+
part="form-control-label"
|
282
|
+
id="label"
|
283
|
+
class="form-control__label"
|
284
|
+
aria-hidden=${hasLabel ? 'false' : 'true'}
|
285
|
+
@click=${this.handleLabelClick}
|
286
|
+
>
|
287
|
+
<slot name="label">${this.label}</slot>
|
288
|
+
</label>
|
289
|
+
|
290
|
+
<div part="form-control-input" class="form-control-input">
|
291
|
+
<div class="visually-hidden">
|
292
|
+
<label class="radio-group__validation">
|
293
|
+
<input
|
294
|
+
type="text"
|
295
|
+
class="radio-group__validation-input"
|
296
|
+
?required=${this.required}
|
297
|
+
tabindex="-1"
|
298
|
+
hidden
|
299
|
+
/>
|
300
|
+
</label>
|
301
|
+
</div>
|
302
|
+
|
303
|
+
${this.hasButtonGroup
|
304
|
+
? html` ${defaultSlot} `
|
305
|
+
: html`
|
306
|
+
<div
|
307
|
+
class="${this.labelInline
|
308
|
+
? `form-control--inline-radio`
|
309
|
+
: ``}"
|
310
|
+
>
|
311
|
+
${defaultSlot}
|
312
|
+
</div>
|
313
|
+
`}
|
314
|
+
</div>
|
315
|
+
|
316
|
+
${hasHelpText
|
317
|
+
? html` <nile-form-help-text>${this.helpText}</nile-form-help-text> `
|
318
|
+
: ``}
|
319
|
+
${hasErrorMessage
|
320
|
+
? html`
|
321
|
+
<nile-form-error-message
|
322
|
+
>${this.errorMessage}</nile-form-error-message
|
323
|
+
>
|
324
|
+
`
|
325
|
+
: ``}
|
326
|
+
</fieldset>
|
327
|
+
`;
|
328
|
+
}
|
329
|
+
}
|
330
|
+
|
331
|
+
export default NileRadioButtonGroup;
|
332
|
+
|
333
|
+
declare global {
|
334
|
+
interface HTMLElementTagNameMap {
|
335
|
+
'nile-radio-button-group': NileRadioButtonGroup;
|
336
|
+
}
|
337
|
+
}
|