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.
Files changed (174) hide show
  1. package/README.md +0 -0
  2. package/dist/index.cjs +4226 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.js +4226 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/types/aeico-component.d.ts +8 -0
  7. package/dist/types/aeico-field.d.ts +132 -0
  8. package/dist/types/alert/alert.d.ts +49 -0
  9. package/dist/types/alert/defines.d.ts +3 -0
  10. package/dist/types/alert/index.d.ts +3 -0
  11. package/dist/types/badge/badge.d.ts +34 -0
  12. package/dist/types/badge/defines.d.ts +3 -0
  13. package/dist/types/badge/index.d.ts +3 -0
  14. package/dist/types/breadcrumb/breadcrumb-item.d.ts +31 -0
  15. package/dist/types/breadcrumb/breadcrumb.d.ts +60 -0
  16. package/dist/types/breadcrumb/defines.d.ts +1 -0
  17. package/dist/types/breadcrumb/index.d.ts +5 -0
  18. package/dist/types/button/button.d.ts +60 -0
  19. package/dist/types/button/defines.d.ts +3 -0
  20. package/dist/types/button/index.d.ts +3 -0
  21. package/dist/types/button-group/button-group.d.ts +56 -0
  22. package/dist/types/button-group/index.d.ts +2 -0
  23. package/dist/types/card/card.d.ts +19 -0
  24. package/dist/types/card/defines.d.ts +2 -0
  25. package/dist/types/card/index.d.ts +3 -0
  26. package/dist/types/checkbox/checkbox.d.ts +37 -0
  27. package/dist/types/checkbox/defines.d.ts +1 -0
  28. package/dist/types/checkbox/index.d.ts +3 -0
  29. package/dist/types/detail/defines.d.ts +2 -0
  30. package/dist/types/detail/detail.d.ts +40 -0
  31. package/dist/types/detail/index.d.ts +3 -0
  32. package/dist/types/dialog/dialog.d.ts +29 -0
  33. package/dist/types/dialog/index.d.ts +2 -0
  34. package/dist/types/divider/divider.d.ts +34 -0
  35. package/dist/types/divider/index.d.ts +2 -0
  36. package/dist/types/dropdown/defines.d.ts +1 -0
  37. package/dist/types/dropdown/dropdown-button.d.ts +60 -0
  38. package/dist/types/dropdown/dropdown-item.d.ts +56 -0
  39. package/dist/types/dropdown/dropdown.d.ts +84 -0
  40. package/dist/types/dropdown/index.d.ts +7 -0
  41. package/dist/types/icon/defines.d.ts +10 -0
  42. package/dist/types/icon/icon.d.ts +21 -0
  43. package/dist/types/icon/index.d.ts +4 -0
  44. package/dist/types/icon/registry.d.ts +8 -0
  45. package/dist/types/icon-button/icon-button.d.ts +32 -0
  46. package/dist/types/icon-button/index.d.ts +2 -0
  47. package/dist/types/index.d.ts +74 -0
  48. package/dist/types/navbar/defines.d.ts +2 -0
  49. package/dist/types/navbar/index.d.ts +3 -0
  50. package/dist/types/navbar/navbar.d.ts +73 -0
  51. package/dist/types/radio-group/defines.d.ts +6 -0
  52. package/dist/types/radio-group/index.d.ts +5 -0
  53. package/dist/types/radio-group/radio-group.d.ts +41 -0
  54. package/dist/types/radio-group/radio.d.ts +47 -0
  55. package/dist/types/select/defines.d.ts +8 -0
  56. package/dist/types/select/index.d.ts +5 -0
  57. package/dist/types/select/select-option.d.ts +20 -0
  58. package/dist/types/select/select.d.ts +60 -0
  59. package/dist/types/slider/defines.d.ts +31 -0
  60. package/dist/types/slider/index.d.ts +3 -0
  61. package/dist/types/slider/slider.d.ts +45 -0
  62. package/dist/types/switch/index.d.ts +2 -0
  63. package/dist/types/switch/switch.d.ts +35 -0
  64. package/dist/types/tabs/defines.d.ts +1 -0
  65. package/dist/types/tabs/index.d.ts +3 -0
  66. package/dist/types/tabs/tab-panel.d.ts +11 -0
  67. package/dist/types/tabs/tab.d.ts +18 -0
  68. package/dist/types/tabs/tabs.d.ts +24 -0
  69. package/dist/types/tag/defines.d.ts +3 -0
  70. package/dist/types/tag/index.d.ts +3 -0
  71. package/dist/types/tag/tag.d.ts +36 -0
  72. package/dist/types/text-input/index.d.ts +2 -0
  73. package/dist/types/text-input/text-input.d.ts +26 -0
  74. package/dist/types/utils.d.ts +2 -0
  75. package/package.json +63 -0
  76. package/src/aeico-component.ts +17 -0
  77. package/src/aeico-field.ts +228 -0
  78. package/src/alert/alert.ts +107 -0
  79. package/src/alert/defines.ts +11 -0
  80. package/src/alert/index.ts +3 -0
  81. package/src/badge/badge.ts +62 -0
  82. package/src/badge/defines.ts +12 -0
  83. package/src/badge/index.ts +3 -0
  84. package/src/breadcrumb/breadcrumb-item.ts +61 -0
  85. package/src/breadcrumb/breadcrumb.ts +138 -0
  86. package/src/breadcrumb/defines.ts +10 -0
  87. package/src/breadcrumb/index.ts +5 -0
  88. package/src/button/button.ts +147 -0
  89. package/src/button/defines.ts +12 -0
  90. package/src/button/index.ts +3 -0
  91. package/src/button-group/button-group.ts +140 -0
  92. package/src/button-group/index.ts +2 -0
  93. package/src/card/card.ts +57 -0
  94. package/src/card/defines.ts +11 -0
  95. package/src/card/index.ts +3 -0
  96. package/src/checkbox/checkbox.ts +90 -0
  97. package/src/checkbox/defines.ts +1 -0
  98. package/src/checkbox/index.ts +3 -0
  99. package/src/detail/defines.ts +11 -0
  100. package/src/detail/detail.ts +122 -0
  101. package/src/detail/index.ts +3 -0
  102. package/src/dialog/dialog.ts +149 -0
  103. package/src/dialog/index.ts +2 -0
  104. package/src/divider/divider.ts +56 -0
  105. package/src/divider/index.ts +2 -0
  106. package/src/dropdown/defines.ts +13 -0
  107. package/src/dropdown/dropdown-button.ts +130 -0
  108. package/src/dropdown/dropdown-item.ts +136 -0
  109. package/src/dropdown/dropdown.ts +211 -0
  110. package/src/dropdown/index.ts +7 -0
  111. package/src/icon/defines.ts +21 -0
  112. package/src/icon/icon.ts +84 -0
  113. package/src/icon/index.ts +4 -0
  114. package/src/icon/registry.ts +25 -0
  115. package/src/icon-button/icon-button.ts +64 -0
  116. package/src/icon-button/index.ts +2 -0
  117. package/src/index.ts +85 -0
  118. package/src/navbar/defines.ts +11 -0
  119. package/src/navbar/index.ts +3 -0
  120. package/src/navbar/navbar.ts +162 -0
  121. package/src/radio-group/defines.ts +5 -0
  122. package/src/radio-group/index.ts +5 -0
  123. package/src/radio-group/radio-group.ts +227 -0
  124. package/src/radio-group/radio.ts +58 -0
  125. package/src/select/defines.ts +12 -0
  126. package/src/select/index.ts +5 -0
  127. package/src/select/select-option.ts +59 -0
  128. package/src/select/select.ts +387 -0
  129. package/src/slider/defines.ts +33 -0
  130. package/src/slider/index.ts +3 -0
  131. package/src/slider/slider.ts +364 -0
  132. package/src/styles/color.css +117 -0
  133. package/src/styles/components/alert.css +104 -0
  134. package/src/styles/components/badge.css +67 -0
  135. package/src/styles/components/breadcrumb-item.css +59 -0
  136. package/src/styles/components/breadcrumb.css +19 -0
  137. package/src/styles/components/button-group.css +25 -0
  138. package/src/styles/components/button.css +213 -0
  139. package/src/styles/components/card.css +64 -0
  140. package/src/styles/components/checkbox.css +78 -0
  141. package/src/styles/components/detail.css +127 -0
  142. package/src/styles/components/dialog.css +103 -0
  143. package/src/styles/components/divider.css +18 -0
  144. package/src/styles/components/dropdown-item.css +91 -0
  145. package/src/styles/components/dropdown.css +179 -0
  146. package/src/styles/components/icon-button.css +116 -0
  147. package/src/styles/components/icon.css +29 -0
  148. package/src/styles/components/navbar.css +250 -0
  149. package/src/styles/components/radio-group.css +360 -0
  150. package/src/styles/components/select-option.css +43 -0
  151. package/src/styles/components/select.css +222 -0
  152. package/src/styles/components/slider.css +326 -0
  153. package/src/styles/components/switch.css +117 -0
  154. package/src/styles/components/tab-panel.css +8 -0
  155. package/src/styles/components/tab.css +44 -0
  156. package/src/styles/components/tabs.css +16 -0
  157. package/src/styles/components/tag.css +107 -0
  158. package/src/styles/components/text-input.css +110 -0
  159. package/src/styles/layout.css +43 -0
  160. package/src/styles/size.css +7 -0
  161. package/src/styles/variables.css +368 -0
  162. package/src/switch/index.ts +2 -0
  163. package/src/switch/switch.ts +88 -0
  164. package/src/tabs/defines.ts +1 -0
  165. package/src/tabs/index.ts +3 -0
  166. package/src/tabs/tab-panel.ts +23 -0
  167. package/src/tabs/tab.ts +62 -0
  168. package/src/tabs/tabs.ts +134 -0
  169. package/src/tag/defines.ts +12 -0
  170. package/src/tag/index.ts +3 -0
  171. package/src/tag/tag.ts +85 -0
  172. package/src/text-input/index.ts +2 -0
  173. package/src/text-input/text-input.ts +75 -0
  174. package/src/utils.ts +6 -0
@@ -0,0 +1,62 @@
1
+ import type { Props } from 'aeico';
2
+ import tabStyle from '../styles/components/tab.css?inline';
3
+ import AeicoComponent from '../aeico-component';
4
+ import { html } from 'aeico';
5
+
6
+ class Tab extends AeicoComponent {
7
+ static props: Props = {
8
+ active: { type: Boolean },
9
+ disabled: { type: Boolean },
10
+ panel: { type: String },
11
+ };
12
+
13
+ declare active?: boolean;
14
+ declare disabled?: boolean;
15
+ declare panel?: string;
16
+
17
+ protected static styles = [tabStyle];
18
+
19
+ connectedCallback() {
20
+ this.setAttribute('slot', 'tab');
21
+ super.connectedCallback();
22
+ this.listen('click', this._handleClick);
23
+ }
24
+
25
+ private _handleClick = () => {
26
+ if (this.disabled) return;
27
+ this.dispatchEvent(
28
+ new CustomEvent('_tab-click', {
29
+ bubbles: true,
30
+ composed: true,
31
+ }),
32
+ );
33
+ };
34
+
35
+ protected render() {
36
+ return html(({ button, slot }) => {
37
+ button(
38
+ {
39
+ part: 'tab',
40
+ type: 'button',
41
+ role: 'tab',
42
+ 'aria-selected': this.active,
43
+ 'aria-disabled': this.disabled,
44
+ disabled: this.disabled,
45
+ },
46
+ () => {
47
+ slot();
48
+ },
49
+ );
50
+ });
51
+ }
52
+ }
53
+
54
+ Tab.register();
55
+
56
+ declare global {
57
+ interface HTMLElementTagNameMap {
58
+ 'ae-tab': Tab;
59
+ }
60
+ }
61
+
62
+ export default Tab;
@@ -0,0 +1,134 @@
1
+ import type { Props } from 'aeico';
2
+ import styleVariables from '../styles/variables.css?inline';
3
+ import tabsStyle from '../styles/components/tabs.css?inline';
4
+ import AeicoComponent from '../aeico-component';
5
+ import { html } from 'aeico';
6
+ import type Tab from './tab';
7
+
8
+ class Tabs extends AeicoComponent {
9
+ static props: Props = {
10
+ activeIndex: { type: Number },
11
+ };
12
+
13
+ declare activeIndex?: number;
14
+
15
+ protected static styles = [styleVariables, tabsStyle];
16
+
17
+ private _observer: MutationObserver | null = null;
18
+
19
+ private get _tabs(): Tab[] {
20
+ return [...this.children].filter(
21
+ (el) => el.tagName.toLowerCase() === 'ae-tab',
22
+ ) as unknown as Tab[];
23
+ }
24
+
25
+ private get _panels(): HTMLElement[] {
26
+ return [...this.children].filter(
27
+ (el) => el.tagName.toLowerCase() === 'ae-tab-panel',
28
+ ) as HTMLElement[];
29
+ }
30
+
31
+ private _getPairs(): [Tab, HTMLElement | null][] {
32
+ const tabs = this._tabs;
33
+ const panels = this._panels;
34
+
35
+ const idMap = new Map<string, HTMLElement>();
36
+ for (const panel of panels) {
37
+ const id = panel.id;
38
+ if (id) idMap.set(id, panel);
39
+ }
40
+
41
+ const usedPanels = new Set<HTMLElement>();
42
+ const pairs: [Tab, HTMLElement | null][] = [];
43
+
44
+ // First pass: ID-matched tabs
45
+ for (const tab of tabs) {
46
+ const panelId = tab.panel;
47
+ if (panelId) {
48
+ const panel = idMap.get(panelId) ?? null;
49
+ if (panel) usedPanels.add(panel);
50
+ pairs.push([tab, panel]);
51
+ }
52
+ }
53
+
54
+ // Second pass: position-matched tabs (no panel attr)
55
+ const unmatchedPanels = panels.filter((p) => !usedPanels.has(p));
56
+ let posIndex = 0;
57
+ for (const tab of tabs) {
58
+ if (!tab.panel) {
59
+ pairs.push([tab, unmatchedPanels[posIndex] ?? null]);
60
+ posIndex++;
61
+ }
62
+ }
63
+
64
+ return pairs;
65
+ }
66
+
67
+ connectedCallback() {
68
+ super.connectedCallback();
69
+ this.listen('_tab-click', this._handleTabClick);
70
+ this._observer = new MutationObserver(() => this.update());
71
+ this._observer.observe(this, { childList: true });
72
+ }
73
+
74
+ disconnectedCallback() {
75
+ super.disconnectedCallback();
76
+ this._observer?.disconnect();
77
+ this._observer = null;
78
+ }
79
+
80
+ protected onUpdated() {
81
+ this._syncActive();
82
+ }
83
+
84
+ private _handleTabClick = (e: Event) => {
85
+ const pairs = this._getPairs();
86
+ const target = e.target as Element;
87
+ const index = pairs.findIndex(([tab]) => tab === target);
88
+ if (index !== -1) this.selectTab(index);
89
+ };
90
+
91
+ private _syncActive() {
92
+ const activeIndex = this.activeIndex ?? 0;
93
+ const pairs = this._getPairs();
94
+
95
+ pairs.forEach(([tab, panel], i) => {
96
+ const isActive = i === activeIndex;
97
+ if (isActive) {
98
+ tab.setAttribute('active', '');
99
+ panel?.setAttribute('active', '');
100
+ } else {
101
+ tab.removeAttribute('active');
102
+ panel?.removeAttribute('active');
103
+ }
104
+ });
105
+ }
106
+
107
+ selectTab(index: number): void {
108
+ const pairs = this._getPairs();
109
+ if (index === (this.activeIndex ?? 0) || index >= pairs.length) return;
110
+ this.activeIndex = index;
111
+ this.emit('change', { detail: { index } });
112
+ }
113
+
114
+ protected render() {
115
+ return html(({ nav, div, slot }) => {
116
+ nav({ part: 'tab-nav', role: 'tablist' }, () => {
117
+ slot({ name: 'tab' });
118
+ });
119
+ div({ part: 'panels' }, () => {
120
+ slot();
121
+ });
122
+ });
123
+ }
124
+ }
125
+
126
+ Tabs.register();
127
+
128
+ declare global {
129
+ interface HTMLElementTagNameMap {
130
+ 'ae-tabs': Tabs;
131
+ }
132
+ }
133
+
134
+ export default Tabs;
@@ -0,0 +1,12 @@
1
+ export type TagColor =
2
+ | 'default'
3
+ | 'primary'
4
+ | 'secondary'
5
+ | 'success'
6
+ | 'danger'
7
+ | 'warning'
8
+ | 'info'
9
+ | 'light'
10
+ | 'dark';
11
+ export type TagVariant = 'filled' | 'outlined' | 'faint' | 'subtle' | 'text';
12
+ export type TagSize = '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg';
@@ -0,0 +1,3 @@
1
+ export { default } from './tag';
2
+ export type { TagProps } from './tag';
3
+ export type { TagColor, TagVariant, TagSize } from './defines';
package/src/tag/tag.ts ADDED
@@ -0,0 +1,85 @@
1
+ import type { InferProps } from 'aeico';
2
+ import styleVariables from '../styles/variables.css?inline';
3
+ import sizeCSS from '../styles/size.css?inline';
4
+ import colorCSS from '../styles/color.css?inline';
5
+ import tagStyle from '../styles/components/tag.css?inline';
6
+ import AeicoComponent from '../aeico-component';
7
+ import { html } from 'aeico';
8
+ import type { TagColor, TagSize, TagVariant } from './defines';
9
+ import { prop } from 'aeico';
10
+
11
+ /**
12
+ * Tag Component
13
+ *
14
+ * An inline label component with optional dismiss button.
15
+ * Supports the same color, variant, and size options as Button.
16
+ *
17
+ * @example
18
+ * ```html
19
+ * <ae-tag color="primary" variant="faint">Label</ae-tag>
20
+ * <ae-tag color="success" variant="outlined" dismissible>Removable</ae-tag>
21
+ * <ae-tag color="danger" size="sm">
22
+ * <ae-icon slot="start" name="warning"></ae-icon>
23
+ * Error
24
+ * </ae-tag>
25
+ * ```
26
+ */
27
+ class Tag extends AeicoComponent {
28
+ protected static styles = [styleVariables, sizeCSS, colorCSS, tagStyle];
29
+
30
+ @prop({ type: String })
31
+ accessor color: TagColor | undefined;
32
+
33
+ @prop({ type: String })
34
+ accessor variant: TagVariant | undefined;
35
+
36
+ @prop({ type: String })
37
+ accessor size: TagSize | undefined;
38
+
39
+ @prop({ type: Boolean })
40
+ accessor dismissible: boolean = false;
41
+
42
+ @prop({ type: Boolean })
43
+ accessor disabled: boolean = false;
44
+
45
+ @prop({ type: Boolean })
46
+ accessor pill: boolean = false;
47
+
48
+ protected render() {
49
+ return html(({ span, button, slot }) => {
50
+ span({ part: 'tag', className: 'tag' }, () => {
51
+ slot({ name: 'start' });
52
+ span({ className: 'tag-content' }, () => {
53
+ slot();
54
+ });
55
+ slot({ name: 'end' });
56
+ button(
57
+ {
58
+ type: 'button',
59
+ className: 'tag-dismiss',
60
+ 'aria-label': 'dismiss',
61
+ '@click': (e: Event) => {
62
+ e.stopPropagation();
63
+ if (this.disabled) return;
64
+ this.emit('dismiss');
65
+ },
66
+ },
67
+ () => {
68
+ span({ textContent: '\u00d7' });
69
+ },
70
+ );
71
+ });
72
+ });
73
+ }
74
+ }
75
+
76
+ Tag.register();
77
+
78
+ declare global {
79
+ interface HTMLElementTagNameMap {
80
+ 'ae-tag': Tag;
81
+ }
82
+ }
83
+
84
+ export default Tag;
85
+ export type TagProps = InferProps<typeof Tag>;
@@ -0,0 +1,2 @@
1
+ export { default, default as TextInput } from './text-input';
2
+ export type { TextInputProps } from './text-input';
@@ -0,0 +1,75 @@
1
+ import AeicoField from '../aeico-field';
2
+ import type { InferProps, Props } from 'aeico';
3
+ import { html } from 'aeico';
4
+ import variables from '../styles/variables.css?inline';
5
+ import sizeCSS from '../styles/size.css?inline';
6
+ import style from '../styles/components/text-input.css?inline';
7
+
8
+ class TextInput extends AeicoField {
9
+ protected fieldElement: HTMLInputElement | null = null;
10
+
11
+ static tagName = 'text-input';
12
+
13
+ static props: Props = {
14
+ placeholder: { type: String },
15
+ type: { type: String },
16
+ };
17
+
18
+ declare placeholder?: string;
19
+ declare type?: string;
20
+
21
+ protected static styles = [variables, sizeCSS, style];
22
+
23
+ render() {
24
+ return html(({ div, input }) => {
25
+ div({ className: 'input-container' }, () => {
26
+ this.fieldElement = input({
27
+ type: this.type || 'text',
28
+ placeholder: this.placeholder || '',
29
+ '@input': this.boundOnChange,
30
+ });
31
+
32
+ this.renderActionButtons();
33
+ });
34
+
35
+ if (this.fieldElement && this.value != null) {
36
+ this.fieldElement.value = String(this.value);
37
+ }
38
+ this.updateClearButtonVisibility();
39
+ });
40
+ }
41
+
42
+ /**
43
+ * Update clear button visibility based on input value
44
+ */
45
+ private updateClearButtonVisibility() {
46
+ if (this.clearBtn && this.fieldElement) {
47
+ const hasValue = this.fieldElement.value.length > 0;
48
+ this.clearBtn.style.display = hasValue ? '' : 'none';
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Write value to the input element (DOM only)
54
+ */
55
+ protected writeValue(value: string): void {
56
+ const strValue = String(value || '');
57
+
58
+ if (this.fieldElement) {
59
+ this.fieldElement.value = strValue;
60
+ }
61
+
62
+ this.updateClearButtonVisibility();
63
+ }
64
+ }
65
+
66
+ TextInput.register();
67
+
68
+ declare global {
69
+ interface HTMLElementTagNameMap {
70
+ 'ae-text-input': TextInput;
71
+ }
72
+ }
73
+
74
+ export default TextInput;
75
+ export type TextInputProps = InferProps<typeof TextInput>;
package/src/utils.ts ADDED
@@ -0,0 +1,6 @@
1
+ export const SVG_NS = 'http://www.w3.org/2000/svg';
2
+
3
+ export function toKebab(str: string): string {
4
+ const cleaned = str.replace(/^[_\d]+/, '');
5
+ return cleaned.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
6
+ }