aeico-components 0.1.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/README.md +0 -0
- package/dist/index.cjs +4226 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +4226 -0
- package/dist/index.js.map +1 -0
- package/dist/types/aeico-component.d.ts +8 -0
- package/dist/types/aeico-field.d.ts +132 -0
- package/dist/types/alert/alert.d.ts +49 -0
- package/dist/types/alert/defines.d.ts +3 -0
- package/dist/types/alert/index.d.ts +3 -0
- package/dist/types/badge/badge.d.ts +34 -0
- package/dist/types/badge/defines.d.ts +3 -0
- package/dist/types/badge/index.d.ts +3 -0
- package/dist/types/breadcrumb/breadcrumb-item.d.ts +31 -0
- package/dist/types/breadcrumb/breadcrumb.d.ts +60 -0
- package/dist/types/breadcrumb/defines.d.ts +1 -0
- package/dist/types/breadcrumb/index.d.ts +5 -0
- package/dist/types/button/button.d.ts +60 -0
- package/dist/types/button/defines.d.ts +3 -0
- package/dist/types/button/index.d.ts +3 -0
- package/dist/types/button-group/button-group.d.ts +56 -0
- package/dist/types/button-group/index.d.ts +2 -0
- package/dist/types/card/card.d.ts +19 -0
- package/dist/types/card/defines.d.ts +2 -0
- package/dist/types/card/index.d.ts +3 -0
- package/dist/types/checkbox/checkbox.d.ts +37 -0
- package/dist/types/checkbox/defines.d.ts +1 -0
- package/dist/types/checkbox/index.d.ts +3 -0
- package/dist/types/detail/defines.d.ts +2 -0
- package/dist/types/detail/detail.d.ts +40 -0
- package/dist/types/detail/index.d.ts +3 -0
- package/dist/types/dialog/dialog.d.ts +29 -0
- package/dist/types/dialog/index.d.ts +2 -0
- package/dist/types/divider/divider.d.ts +34 -0
- package/dist/types/divider/index.d.ts +2 -0
- package/dist/types/dropdown/defines.d.ts +1 -0
- package/dist/types/dropdown/dropdown-button.d.ts +60 -0
- package/dist/types/dropdown/dropdown-item.d.ts +56 -0
- package/dist/types/dropdown/dropdown.d.ts +84 -0
- package/dist/types/dropdown/index.d.ts +7 -0
- package/dist/types/icon/defines.d.ts +10 -0
- package/dist/types/icon/icon.d.ts +21 -0
- package/dist/types/icon/index.d.ts +4 -0
- package/dist/types/icon/registry.d.ts +8 -0
- package/dist/types/icon-button/icon-button.d.ts +32 -0
- package/dist/types/icon-button/index.d.ts +2 -0
- package/dist/types/index.d.ts +74 -0
- package/dist/types/navbar/defines.d.ts +2 -0
- package/dist/types/navbar/index.d.ts +3 -0
- package/dist/types/navbar/navbar.d.ts +73 -0
- package/dist/types/radio-group/defines.d.ts +6 -0
- package/dist/types/radio-group/index.d.ts +5 -0
- package/dist/types/radio-group/radio-group.d.ts +41 -0
- package/dist/types/radio-group/radio.d.ts +47 -0
- package/dist/types/select/defines.d.ts +8 -0
- package/dist/types/select/index.d.ts +5 -0
- package/dist/types/select/select-option.d.ts +20 -0
- package/dist/types/select/select.d.ts +60 -0
- package/dist/types/slider/defines.d.ts +31 -0
- package/dist/types/slider/index.d.ts +3 -0
- package/dist/types/slider/slider.d.ts +45 -0
- package/dist/types/switch/index.d.ts +2 -0
- package/dist/types/switch/switch.d.ts +35 -0
- package/dist/types/tabs/defines.d.ts +1 -0
- package/dist/types/tabs/index.d.ts +3 -0
- package/dist/types/tabs/tab-panel.d.ts +11 -0
- package/dist/types/tabs/tab.d.ts +18 -0
- package/dist/types/tabs/tabs.d.ts +24 -0
- package/dist/types/tag/defines.d.ts +3 -0
- package/dist/types/tag/index.d.ts +3 -0
- package/dist/types/tag/tag.d.ts +36 -0
- package/dist/types/text-input/index.d.ts +2 -0
- package/dist/types/text-input/text-input.d.ts +26 -0
- package/dist/types/utils.d.ts +2 -0
- package/package.json +63 -0
- package/src/aeico-component.ts +17 -0
- package/src/aeico-field.ts +228 -0
- package/src/alert/alert.ts +107 -0
- package/src/alert/defines.ts +11 -0
- package/src/alert/index.ts +3 -0
- package/src/badge/badge.ts +62 -0
- package/src/badge/defines.ts +12 -0
- package/src/badge/index.ts +3 -0
- package/src/breadcrumb/breadcrumb-item.ts +61 -0
- package/src/breadcrumb/breadcrumb.ts +138 -0
- package/src/breadcrumb/defines.ts +10 -0
- package/src/breadcrumb/index.ts +5 -0
- package/src/button/button.ts +147 -0
- package/src/button/defines.ts +12 -0
- package/src/button/index.ts +3 -0
- package/src/button-group/button-group.ts +140 -0
- package/src/button-group/index.ts +2 -0
- package/src/card/card.ts +57 -0
- package/src/card/defines.ts +11 -0
- package/src/card/index.ts +3 -0
- package/src/checkbox/checkbox.ts +90 -0
- package/src/checkbox/defines.ts +1 -0
- package/src/checkbox/index.ts +3 -0
- package/src/detail/defines.ts +11 -0
- package/src/detail/detail.ts +122 -0
- package/src/detail/index.ts +3 -0
- package/src/dialog/dialog.ts +149 -0
- package/src/dialog/index.ts +2 -0
- package/src/divider/divider.ts +56 -0
- package/src/divider/index.ts +2 -0
- package/src/dropdown/defines.ts +13 -0
- package/src/dropdown/dropdown-button.ts +130 -0
- package/src/dropdown/dropdown-item.ts +136 -0
- package/src/dropdown/dropdown.ts +211 -0
- package/src/dropdown/index.ts +7 -0
- package/src/icon/defines.ts +21 -0
- package/src/icon/icon.ts +84 -0
- package/src/icon/index.ts +4 -0
- package/src/icon/registry.ts +25 -0
- package/src/icon-button/icon-button.ts +64 -0
- package/src/icon-button/index.ts +2 -0
- package/src/index.ts +85 -0
- package/src/navbar/defines.ts +11 -0
- package/src/navbar/index.ts +3 -0
- package/src/navbar/navbar.ts +162 -0
- package/src/radio-group/defines.ts +5 -0
- package/src/radio-group/index.ts +5 -0
- package/src/radio-group/radio-group.ts +227 -0
- package/src/radio-group/radio.ts +58 -0
- package/src/select/defines.ts +12 -0
- package/src/select/index.ts +5 -0
- package/src/select/select-option.ts +59 -0
- package/src/select/select.ts +387 -0
- package/src/slider/defines.ts +33 -0
- package/src/slider/index.ts +3 -0
- package/src/slider/slider.ts +364 -0
- package/src/styles/color.css +117 -0
- package/src/styles/components/alert.css +104 -0
- package/src/styles/components/badge.css +67 -0
- package/src/styles/components/breadcrumb-item.css +59 -0
- package/src/styles/components/breadcrumb.css +19 -0
- package/src/styles/components/button-group.css +25 -0
- package/src/styles/components/button.css +213 -0
- package/src/styles/components/card.css +64 -0
- package/src/styles/components/checkbox.css +78 -0
- package/src/styles/components/detail.css +127 -0
- package/src/styles/components/dialog.css +103 -0
- package/src/styles/components/divider.css +18 -0
- package/src/styles/components/dropdown-item.css +91 -0
- package/src/styles/components/dropdown.css +179 -0
- package/src/styles/components/icon-button.css +116 -0
- package/src/styles/components/icon.css +29 -0
- package/src/styles/components/navbar.css +250 -0
- package/src/styles/components/radio-group.css +360 -0
- package/src/styles/components/select-option.css +43 -0
- package/src/styles/components/select.css +222 -0
- package/src/styles/components/slider.css +326 -0
- package/src/styles/components/switch.css +117 -0
- package/src/styles/components/tab-panel.css +8 -0
- package/src/styles/components/tab.css +44 -0
- package/src/styles/components/tabs.css +16 -0
- package/src/styles/components/tag.css +107 -0
- package/src/styles/components/text-input.css +110 -0
- package/src/styles/layout.css +43 -0
- package/src/styles/size.css +7 -0
- package/src/styles/variables.css +368 -0
- package/src/switch/index.ts +2 -0
- package/src/switch/switch.ts +88 -0
- package/src/tabs/defines.ts +1 -0
- package/src/tabs/index.ts +3 -0
- package/src/tabs/tab-panel.ts +23 -0
- package/src/tabs/tab.ts +62 -0
- package/src/tabs/tabs.ts +134 -0
- package/src/tag/defines.ts +12 -0
- package/src/tag/index.ts +3 -0
- package/src/tag/tag.ts +85 -0
- package/src/text-input/index.ts +2 -0
- package/src/text-input/text-input.ts +75 -0
- package/src/utils.ts +6 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default, default as RadioGroup } from './radio-group';
|
|
2
|
+
export type { RadioGroupProps } from './radio-group';
|
|
3
|
+
export type { RadioGroupMode, RadioGroupOption, RadioGroupOptions } from './defines';
|
|
4
|
+
export { default as Radio } from './radio';
|
|
5
|
+
export type { RadioProps } from './radio';
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import AeicoField from '../aeico-field';
|
|
2
|
+
import type { InferProps, Props } from 'aeico';
|
|
3
|
+
import { html, tags } from 'aeico';
|
|
4
|
+
import type { ButtonColor, ButtonVariant, ButtonSize } from '../button';
|
|
5
|
+
import { t } from 'aeico-localize';
|
|
6
|
+
import type { RadioGroupMode, RadioGroupOption, RadioGroupOptions } from './defines';
|
|
7
|
+
import Radio from './radio';
|
|
8
|
+
import style from '../styles/components/radio-group.css?inline';
|
|
9
|
+
import variables from '../styles/variables.css?inline';
|
|
10
|
+
import sizeCSS from '../styles/size.css?inline';
|
|
11
|
+
import colorCSS from '../styles/color.css?inline';
|
|
12
|
+
|
|
13
|
+
class RadioGroup extends AeicoField {
|
|
14
|
+
protected fieldElement: HTMLInputElement | null = null;
|
|
15
|
+
|
|
16
|
+
private _slotEl: HTMLSlotElement | null = null;
|
|
17
|
+
private _slotOptions: Radio[] = [];
|
|
18
|
+
|
|
19
|
+
private static _instanceCount = 0;
|
|
20
|
+
private readonly _groupName: string;
|
|
21
|
+
|
|
22
|
+
static tagName = 'radio-group';
|
|
23
|
+
|
|
24
|
+
static props: Props = {
|
|
25
|
+
options: { type: Array },
|
|
26
|
+
mode: { type: String },
|
|
27
|
+
color: { type: String },
|
|
28
|
+
variant: { type: String },
|
|
29
|
+
size: { type: String },
|
|
30
|
+
allowEmpty: { type: Boolean },
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
declare options?: RadioGroupOptions;
|
|
34
|
+
declare mode?: RadioGroupMode;
|
|
35
|
+
declare color?: ButtonColor;
|
|
36
|
+
declare variant?: ButtonVariant;
|
|
37
|
+
declare size?: ButtonSize;
|
|
38
|
+
declare allowEmpty?: boolean;
|
|
39
|
+
|
|
40
|
+
protected static styles = [variables, sizeCSS, colorCSS, style];
|
|
41
|
+
|
|
42
|
+
constructor() {
|
|
43
|
+
super();
|
|
44
|
+
this._groupName = `rg-${++RadioGroup._instanceCount}`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private _optLabel(opt: RadioGroupOption): string {
|
|
48
|
+
if (opt !== null && typeof opt === 'object') {
|
|
49
|
+
return t(String(opt.label), String(opt.label));
|
|
50
|
+
}
|
|
51
|
+
return String(opt);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private _optValue(opt: RadioGroupOption): string {
|
|
55
|
+
if (opt !== null && typeof opt === 'object') return String(opt.value);
|
|
56
|
+
return String(opt);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private _allOptions(): Array<{ label: string; value: string; disabled?: boolean }> {
|
|
60
|
+
const from_props = (Array.isArray(this.options) ? this.options : []).map((o) => ({
|
|
61
|
+
label: this._optLabel(o),
|
|
62
|
+
value: this._optValue(o),
|
|
63
|
+
}));
|
|
64
|
+
|
|
65
|
+
const from_slot = this._slotOptions.map((el) => ({
|
|
66
|
+
label: el.textContent?.trim() || el.value,
|
|
67
|
+
value: el.value,
|
|
68
|
+
disabled: el.disabled,
|
|
69
|
+
}));
|
|
70
|
+
|
|
71
|
+
return [...from_props, ...from_slot];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private _onSlotChange(): void {
|
|
75
|
+
if (!this._slotEl) return;
|
|
76
|
+
|
|
77
|
+
this._slotOptions = (this._slotEl.assignedElements({ flatten: true }) as HTMLElement[]).filter(
|
|
78
|
+
(el) => el.tagName.toLowerCase() === 'ae-radio',
|
|
79
|
+
) as Radio[];
|
|
80
|
+
this.update();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Single handler for radio inputs — handles both select and deselect.
|
|
84
|
+
// Only uses `click` (not `change`) because `change` fires before `click`;
|
|
85
|
+
// if we set value in `change`, the `click` handler would see the updated
|
|
86
|
+
// value and immediately deselect.
|
|
87
|
+
private _boundOnRadioClick = (e: Event) => {
|
|
88
|
+
const input = e.target as HTMLInputElement;
|
|
89
|
+
const current = this.value ?? '';
|
|
90
|
+
if (input.value === current) {
|
|
91
|
+
if (this.allowEmpty) {
|
|
92
|
+
input.checked = false;
|
|
93
|
+
this.setValue('', { silent: false, action: 'change' });
|
|
94
|
+
}
|
|
95
|
+
// !allowEmpty: do nothing
|
|
96
|
+
} else {
|
|
97
|
+
this.setValue(input.value, { silent: false, action: 'change' });
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
private _boundOnButtonClick = (e: Event) => {
|
|
102
|
+
const btn = e.currentTarget as HTMLElement;
|
|
103
|
+
const val = btn.dataset.value ?? '';
|
|
104
|
+
const current = this.value ?? '';
|
|
105
|
+
// Toggle off if clicking already-selected option
|
|
106
|
+
if (val === current) {
|
|
107
|
+
if (this.allowEmpty) {
|
|
108
|
+
this.setValue('', { silent: false, action: 'change' });
|
|
109
|
+
}
|
|
110
|
+
// !allowEmpty: already selected, do nothing
|
|
111
|
+
} else {
|
|
112
|
+
this.setValue(val, { silent: false, action: 'change' });
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
protected getValue(): string {
|
|
117
|
+
return this.value ?? '';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
protected writeValue(_value: any): void {
|
|
121
|
+
// All visual state is driven by builder diff on next render;
|
|
122
|
+
// for native radio inputs we need to sync checked immediately.
|
|
123
|
+
// The render() reads this.value, so update handles the rest.
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
protected onReset(): void {
|
|
127
|
+
this.setValue(this.defaultValue ?? '', { silent: false, action: 'reset' });
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
protected onClear(): void {
|
|
131
|
+
this.setValue('', { silent: false, action: 'clear' });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
render() {
|
|
135
|
+
const mode = (this.mode as RadioGroupMode) || 'default';
|
|
136
|
+
const opts = this._allOptions();
|
|
137
|
+
const current = this.value ?? '';
|
|
138
|
+
|
|
139
|
+
return html(({ div, slot }) => {
|
|
140
|
+
div({ className: 'rg-container' }, () => {
|
|
141
|
+
if (mode === 'default') {
|
|
142
|
+
this._renderRadio(opts, current);
|
|
143
|
+
} else {
|
|
144
|
+
this._renderButtons(opts, current, mode);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
if (this.allowEmpty) this.renderClearButton();
|
|
149
|
+
this.renderResetButton();
|
|
150
|
+
|
|
151
|
+
// Hidden slot — captures <option> light DOM children
|
|
152
|
+
this._slotEl = slot({
|
|
153
|
+
style: { display: 'none' },
|
|
154
|
+
'@slotchange': () => this._onSlotChange(),
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
private _renderRadio(
|
|
160
|
+
opts: Array<{ label: string; value: string; disabled?: boolean }>,
|
|
161
|
+
current: string,
|
|
162
|
+
): void {
|
|
163
|
+
const { label, input, span } = tags;
|
|
164
|
+
for (const opt of opts) {
|
|
165
|
+
const isChecked = opt.value === current;
|
|
166
|
+
|
|
167
|
+
label({ key: `opt-${opt.value}`, className: 'rg-radio-option' }, () => {
|
|
168
|
+
const el = input({
|
|
169
|
+
type: 'radio',
|
|
170
|
+
className: 'rg-radio-input',
|
|
171
|
+
name: this._groupName,
|
|
172
|
+
value: opt.value,
|
|
173
|
+
disabled: Boolean(this.disabled) || Boolean(opt.disabled),
|
|
174
|
+
'@click': this._boundOnRadioClick,
|
|
175
|
+
});
|
|
176
|
+
// Sync DOM property directly — setAttribute('checked') doesn't work
|
|
177
|
+
// after user interaction; only the .checked property controls state.
|
|
178
|
+
el.checked = isChecked;
|
|
179
|
+
// Keep fieldElement pointing to first radio for base-class compat
|
|
180
|
+
if (!this.fieldElement) this.fieldElement = el;
|
|
181
|
+
span({ className: 'rg-radio-label', textContent: opt.label });
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private _renderButtons(
|
|
187
|
+
opts: Array<{ label: string; value: string; disabled?: boolean }>,
|
|
188
|
+
current: string,
|
|
189
|
+
mode: RadioGroupMode,
|
|
190
|
+
): void {
|
|
191
|
+
const { button } = tags;
|
|
192
|
+
const count = opts.length;
|
|
193
|
+
for (let i = 0; i < count; i++) {
|
|
194
|
+
const opt = opts[i];
|
|
195
|
+
const isSelected = opt.value === current;
|
|
196
|
+
|
|
197
|
+
// Position class for button-group border-radius (CSS handles all styling)
|
|
198
|
+
let posClass = '';
|
|
199
|
+
if (mode === 'button-group') {
|
|
200
|
+
if (count === 1) posClass = ' only';
|
|
201
|
+
else if (i === 0) posClass = ' first';
|
|
202
|
+
else if (i === count - 1) posClass = ' last';
|
|
203
|
+
else posClass = ' inner';
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
button({
|
|
207
|
+
key: `opt-${opt.value}`,
|
|
208
|
+
className: `rg-btn${isSelected ? ' selected' : ''}${posClass}`,
|
|
209
|
+
textContent: opt.label,
|
|
210
|
+
disabled: Boolean(this.disabled) || Boolean(opt.disabled),
|
|
211
|
+
'data-value': opt.value,
|
|
212
|
+
'@click': this._boundOnButtonClick,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
RadioGroup.register();
|
|
219
|
+
|
|
220
|
+
declare global {
|
|
221
|
+
interface HTMLElementTagNameMap {
|
|
222
|
+
'ae-radio-group': RadioGroup;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export default RadioGroup;
|
|
227
|
+
export type RadioGroupProps = InferProps<typeof RadioGroup>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import AeicoComponent from '../aeico-component';
|
|
2
|
+
import type { InferProps, Props } from 'aeico';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* AeRadio — structured option element for ae-radio-group.
|
|
6
|
+
*
|
|
7
|
+
* Replaces the native `<option>` approach with a custom element that is
|
|
8
|
+
* fully extensible. Current surface:
|
|
9
|
+
* - `value` — option value submitted / matched against radio-group value
|
|
10
|
+
* - `disabled` — disables this individual option (independent of the group)
|
|
11
|
+
* - Light DOM — label content; can be plain text or rich HTML (icons, etc.)
|
|
12
|
+
*
|
|
13
|
+
* This element has **no shadow DOM** — it is a pure data / content carrier.
|
|
14
|
+
* ae-radio-group reads its properties and light-DOM content, then renders
|
|
15
|
+
* the appropriate UI (radio input, button, segmented pill, …).
|
|
16
|
+
*
|
|
17
|
+
* @example Plain text options
|
|
18
|
+
* ```html
|
|
19
|
+
* <ae-radio-group mode="button" color="primary" value="a">
|
|
20
|
+
* <ae-radio value="a">Option A</ae-radio>
|
|
21
|
+
* <ae-radio value="b">Option B</ae-radio>
|
|
22
|
+
* <ae-radio value="c" disabled>Option C</ae-radio>
|
|
23
|
+
* </ae-radio-group>
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example Rich content options (icons)
|
|
27
|
+
* ```html
|
|
28
|
+
* <ae-radio-group mode="button" color="primary" value="list">
|
|
29
|
+
* <ae-radio value="list"><ae-icon name="list"></ae-icon> List</ae-radio>
|
|
30
|
+
* <ae-radio value="grid"><ae-icon name="grid"></ae-icon> Grid</ae-radio>
|
|
31
|
+
* </ae-radio-group>
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
class Radio extends AeicoComponent {
|
|
35
|
+
static tagName = 'radio';
|
|
36
|
+
|
|
37
|
+
/** No shadow DOM — this element is a transparent data/content carrier. */
|
|
38
|
+
static override useShadowDOM = false;
|
|
39
|
+
|
|
40
|
+
static override props: Props = {
|
|
41
|
+
value: { type: String },
|
|
42
|
+
disabled: { type: Boolean },
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
declare value: string;
|
|
46
|
+
declare disabled?: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
Radio.register();
|
|
50
|
+
|
|
51
|
+
declare global {
|
|
52
|
+
interface HTMLElementTagNameMap {
|
|
53
|
+
'ae-radio': Radio;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default Radio;
|
|
58
|
+
export type RadioProps = InferProps<typeof Radio>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type SelectOptionValue = string | number;
|
|
2
|
+
|
|
3
|
+
export type SelectOption = {
|
|
4
|
+
label: string;
|
|
5
|
+
value: SelectOptionValue;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type SelectOptions = SelectOptionValue[] | SelectOption[];
|
|
9
|
+
|
|
10
|
+
export type SelectPosition = 'top' | 'bottom' | 'left' | 'right';
|
|
11
|
+
|
|
12
|
+
export type SelectMultiValue = SelectOptionValue[];
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default, default as Select } from './select';
|
|
2
|
+
export type { SelectProps } from './select';
|
|
3
|
+
export { default as SelectOption } from './select-option';
|
|
4
|
+
export type { SelectOptionProps } from './select-option';
|
|
5
|
+
export type { SelectOptionValue, SelectOptions, SelectPosition } from './defines';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import AeicoComponent from '../aeico-component';
|
|
2
|
+
import type { InferProps } from 'aeico';
|
|
3
|
+
import { html } from 'aeico';
|
|
4
|
+
import style from '../styles/components/select-option.css?inline';
|
|
5
|
+
import variables from '../styles/variables.css?inline';
|
|
6
|
+
import { prop } from 'aeico';
|
|
7
|
+
|
|
8
|
+
class SelectOption extends AeicoComponent {
|
|
9
|
+
static tagName = 'select-option';
|
|
10
|
+
|
|
11
|
+
@prop({ type: String })
|
|
12
|
+
accessor value: string | undefined;
|
|
13
|
+
|
|
14
|
+
@prop({ type: String })
|
|
15
|
+
accessor label: string | undefined;
|
|
16
|
+
|
|
17
|
+
@prop({ type: Boolean })
|
|
18
|
+
accessor disabled: boolean = false;
|
|
19
|
+
|
|
20
|
+
@prop({ type: Boolean })
|
|
21
|
+
accessor selected: boolean | undefined = false;
|
|
22
|
+
|
|
23
|
+
protected static styles = [variables, style];
|
|
24
|
+
|
|
25
|
+
connectedCallback() {
|
|
26
|
+
super.connectedCallback();
|
|
27
|
+
this.listen('click', this._handleClick);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private _handleClick = (e: Event): void => {
|
|
31
|
+
if (this.disabled) {
|
|
32
|
+
e.stopPropagation();
|
|
33
|
+
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const displayLabel = this.label || this.textContent?.trim() || '';
|
|
38
|
+
this.emit('selectoption', { detail: { value: this.value ?? '', label: displayLabel } });
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
render() {
|
|
42
|
+
return html(({ div, slot }) => {
|
|
43
|
+
div({ className: 'option-item' }, () => {
|
|
44
|
+
slot();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
SelectOption.register();
|
|
51
|
+
|
|
52
|
+
declare global {
|
|
53
|
+
interface HTMLElementTagNameMap {
|
|
54
|
+
'ae-select-option': SelectOption;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export default SelectOption;
|
|
59
|
+
export type SelectOptionProps = InferProps<typeof SelectOption>;
|