aeico-components 0.1.5 → 0.1.7

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 (337) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +0 -0
  3. package/dist/chunks/action-button.cjs +296 -0
  4. package/dist/chunks/action-button.cjs.map +1 -0
  5. package/dist/chunks/action-button.js +297 -0
  6. package/dist/chunks/action-button.js.map +1 -0
  7. package/dist/chunks/alert.cjs +26 -32
  8. package/dist/chunks/alert.cjs.map +1 -1
  9. package/dist/chunks/alert.js +27 -33
  10. package/dist/chunks/alert.js.map +1 -1
  11. package/dist/chunks/badge.cjs +2 -2
  12. package/dist/chunks/badge.cjs.map +1 -1
  13. package/dist/chunks/badge.js +3 -3
  14. package/dist/chunks/badge.js.map +1 -1
  15. package/dist/chunks/breadcrumb-item.cjs +9 -9
  16. package/dist/chunks/breadcrumb-item.cjs.map +1 -1
  17. package/dist/chunks/breadcrumb-item.js +10 -10
  18. package/dist/chunks/breadcrumb-item.js.map +1 -1
  19. package/dist/chunks/button-group.cjs +1 -1
  20. package/dist/chunks/button-group.cjs.map +1 -1
  21. package/dist/chunks/button-group.js +2 -2
  22. package/dist/chunks/button-group.js.map +1 -1
  23. package/dist/chunks/button.cjs +40 -51
  24. package/dist/chunks/button.cjs.map +1 -1
  25. package/dist/chunks/button.js +41 -52
  26. package/dist/chunks/button.js.map +1 -1
  27. package/dist/chunks/card.cjs +2 -2
  28. package/dist/chunks/card.cjs.map +1 -1
  29. package/dist/chunks/card.js +3 -3
  30. package/dist/chunks/card.js.map +1 -1
  31. package/dist/chunks/checkbox.cjs +18 -5
  32. package/dist/chunks/checkbox.cjs.map +1 -1
  33. package/dist/chunks/checkbox.js +18 -5
  34. package/dist/chunks/checkbox.js.map +1 -1
  35. package/dist/chunks/color.cjs +1 -1
  36. package/dist/chunks/color.js +1 -1
  37. package/dist/chunks/copy-button.cjs +171 -0
  38. package/dist/chunks/copy-button.cjs.map +1 -0
  39. package/dist/chunks/copy-button.js +172 -0
  40. package/dist/chunks/copy-button.js.map +1 -0
  41. package/dist/chunks/detail-group.cjs +65 -0
  42. package/dist/chunks/detail-group.cjs.map +1 -0
  43. package/dist/chunks/detail-group.js +66 -0
  44. package/dist/chunks/detail-group.js.map +1 -0
  45. package/dist/chunks/detail.cjs +7 -4
  46. package/dist/chunks/detail.cjs.map +1 -1
  47. package/dist/chunks/detail.js +8 -5
  48. package/dist/chunks/detail.js.map +1 -1
  49. package/dist/chunks/dialog.cjs +2 -2
  50. package/dist/chunks/dialog.cjs.map +1 -1
  51. package/dist/chunks/dialog.js +3 -3
  52. package/dist/chunks/dialog.js.map +1 -1
  53. package/dist/chunks/divider.cjs +2 -2
  54. package/dist/chunks/divider.cjs.map +1 -1
  55. package/dist/chunks/divider.js +3 -3
  56. package/dist/chunks/divider.js.map +1 -1
  57. package/dist/chunks/drawer.cjs +180 -0
  58. package/dist/chunks/drawer.cjs.map +1 -0
  59. package/dist/chunks/drawer.js +181 -0
  60. package/dist/chunks/drawer.js.map +1 -0
  61. package/dist/chunks/dropdown-button.cjs +10 -11
  62. package/dist/chunks/dropdown-button.cjs.map +1 -1
  63. package/dist/chunks/dropdown-button.js +14 -15
  64. package/dist/chunks/dropdown-button.js.map +1 -1
  65. package/dist/chunks/icon.cjs +57 -11
  66. package/dist/chunks/icon.cjs.map +1 -1
  67. package/dist/chunks/icon.js +58 -12
  68. package/dist/chunks/icon.js.map +1 -1
  69. package/dist/chunks/menu.cjs +396 -0
  70. package/dist/chunks/menu.cjs.map +1 -0
  71. package/dist/chunks/menu.js +397 -0
  72. package/dist/chunks/menu.js.map +1 -0
  73. package/dist/chunks/navbar.cjs +2 -2
  74. package/dist/chunks/navbar.cjs.map +1 -1
  75. package/dist/chunks/navbar.js +3 -3
  76. package/dist/chunks/navbar.js.map +1 -1
  77. package/dist/chunks/number-input.cjs +110 -0
  78. package/dist/chunks/number-input.cjs.map +1 -0
  79. package/dist/chunks/number-input.js +111 -0
  80. package/dist/chunks/number-input.js.map +1 -0
  81. package/dist/chunks/pagination.cjs +475 -0
  82. package/dist/chunks/pagination.cjs.map +1 -0
  83. package/dist/chunks/pagination.js +476 -0
  84. package/dist/chunks/pagination.js.map +1 -0
  85. package/dist/chunks/progress-bar.cjs +101 -0
  86. package/dist/chunks/progress-bar.cjs.map +1 -0
  87. package/dist/chunks/progress-bar.js +102 -0
  88. package/dist/chunks/progress-bar.js.map +1 -0
  89. package/dist/chunks/radio.cjs +11 -7
  90. package/dist/chunks/radio.cjs.map +1 -1
  91. package/dist/chunks/radio.js +11 -7
  92. package/dist/chunks/radio.js.map +1 -1
  93. package/dist/chunks/select.cjs +97 -66
  94. package/dist/chunks/select.cjs.map +1 -1
  95. package/dist/chunks/select.js +97 -66
  96. package/dist/chunks/select.js.map +1 -1
  97. package/dist/chunks/size.cjs +1 -1
  98. package/dist/chunks/size.js +1 -1
  99. package/dist/chunks/slider.cjs +35 -75
  100. package/dist/chunks/slider.cjs.map +1 -1
  101. package/dist/chunks/slider.js +35 -75
  102. package/dist/chunks/slider.js.map +1 -1
  103. package/dist/chunks/spinner.cjs +102 -0
  104. package/dist/chunks/spinner.cjs.map +1 -0
  105. package/dist/chunks/spinner.js +103 -0
  106. package/dist/chunks/spinner.js.map +1 -0
  107. package/dist/chunks/switch.cjs +110 -16
  108. package/dist/chunks/switch.cjs.map +1 -1
  109. package/dist/chunks/switch.js +111 -17
  110. package/dist/chunks/switch.js.map +1 -1
  111. package/dist/chunks/tab-panel.cjs +14 -5
  112. package/dist/chunks/tab-panel.cjs.map +1 -1
  113. package/dist/chunks/tab-panel.js +15 -6
  114. package/dist/chunks/tab-panel.js.map +1 -1
  115. package/dist/chunks/tag.cjs +2 -2
  116. package/dist/chunks/tag.cjs.map +1 -1
  117. package/dist/chunks/tag.js +3 -3
  118. package/dist/chunks/tag.js.map +1 -1
  119. package/dist/chunks/text-input.cjs +11 -16
  120. package/dist/chunks/text-input.cjs.map +1 -1
  121. package/dist/chunks/text-input.js +11 -16
  122. package/dist/chunks/text-input.js.map +1 -1
  123. package/dist/chunks/textarea.cjs +137 -0
  124. package/dist/chunks/textarea.cjs.map +1 -0
  125. package/dist/chunks/textarea.js +138 -0
  126. package/dist/chunks/textarea.js.map +1 -0
  127. package/dist/chunks/tooltip.cjs +292 -0
  128. package/dist/chunks/tooltip.cjs.map +1 -0
  129. package/dist/chunks/tooltip.js +293 -0
  130. package/dist/chunks/tooltip.js.map +1 -0
  131. package/dist/chunks/tree.cjs +468 -0
  132. package/dist/chunks/tree.cjs.map +1 -0
  133. package/dist/chunks/tree.js +469 -0
  134. package/dist/chunks/tree.js.map +1 -0
  135. package/dist/chunks/variables.cjs +273 -249
  136. package/dist/chunks/variables.cjs.map +1 -1
  137. package/dist/chunks/variables.js +273 -249
  138. package/dist/chunks/variables.js.map +1 -1
  139. package/dist/copy-button.cjs +6 -0
  140. package/dist/copy-button.cjs.map +1 -0
  141. package/dist/copy-button.js +6 -0
  142. package/dist/copy-button.js.map +1 -0
  143. package/dist/detail-group.cjs +6 -0
  144. package/dist/detail-group.cjs.map +1 -0
  145. package/dist/detail-group.js +6 -0
  146. package/dist/detail-group.js.map +1 -0
  147. package/dist/drawer.cjs +6 -0
  148. package/dist/drawer.cjs.map +1 -0
  149. package/dist/drawer.js +6 -0
  150. package/dist/drawer.js.map +1 -0
  151. package/dist/dropdown.js +4 -4
  152. package/dist/index.cjs +24 -99
  153. package/dist/index.cjs.map +1 -1
  154. package/dist/index.js +41 -116
  155. package/dist/index.js.map +1 -1
  156. package/dist/menu.cjs +6 -0
  157. package/dist/menu.cjs.map +1 -0
  158. package/dist/menu.js +6 -0
  159. package/dist/menu.js.map +1 -0
  160. package/dist/number-input.cjs +6 -0
  161. package/dist/number-input.cjs.map +1 -0
  162. package/dist/number-input.js +6 -0
  163. package/dist/number-input.js.map +1 -0
  164. package/dist/pagination.cjs +6 -0
  165. package/dist/pagination.cjs.map +1 -0
  166. package/dist/pagination.js +6 -0
  167. package/dist/pagination.js.map +1 -0
  168. package/dist/progress-bar.cjs +6 -0
  169. package/dist/progress-bar.cjs.map +1 -0
  170. package/dist/progress-bar.js +6 -0
  171. package/dist/progress-bar.js.map +1 -0
  172. package/dist/select.cjs +2 -2
  173. package/dist/select.cjs.map +1 -1
  174. package/dist/select.js +3 -3
  175. package/dist/select.js.map +1 -1
  176. package/dist/spinner.cjs +6 -0
  177. package/dist/spinner.cjs.map +1 -0
  178. package/dist/spinner.js +6 -0
  179. package/dist/spinner.js.map +1 -0
  180. package/dist/textarea.cjs +5 -0
  181. package/dist/textarea.cjs.map +1 -0
  182. package/dist/textarea.js +5 -0
  183. package/dist/textarea.js.map +1 -0
  184. package/dist/tooltip.cjs +6 -0
  185. package/dist/tooltip.cjs.map +1 -0
  186. package/dist/tooltip.js +6 -0
  187. package/dist/tooltip.js.map +1 -0
  188. package/dist/tree.cjs +6 -0
  189. package/dist/tree.cjs.map +1 -0
  190. package/dist/tree.js +6 -0
  191. package/dist/tree.js.map +1 -0
  192. package/dist/types/aeico-field.d.ts +52 -0
  193. package/dist/types/alert/alert.d.ts +1 -0
  194. package/dist/types/card/defines.d.ts +1 -1
  195. package/dist/types/copy-button/copy-button.d.ts +32 -0
  196. package/dist/types/copy-button/defines.d.ts +1 -0
  197. package/dist/types/copy-button/index.d.ts +3 -0
  198. package/dist/types/detail/defines.d.ts +2 -1
  199. package/dist/types/detail/detail.d.ts +3 -1
  200. package/dist/types/detail/index.d.ts +1 -1
  201. package/dist/types/detail-group/detail-group.d.ts +39 -0
  202. package/dist/types/detail-group/index.d.ts +2 -0
  203. package/dist/types/drawer/defines.d.ts +1 -0
  204. package/dist/types/drawer/drawer.d.ts +31 -0
  205. package/dist/types/drawer/index.d.ts +3 -0
  206. package/dist/types/icon/built-in-icons.d.ts +1 -0
  207. package/dist/types/icon/defines.d.ts +5 -1
  208. package/dist/types/icon/icon.d.ts +1 -0
  209. package/dist/types/icon/index.d.ts +1 -1
  210. package/dist/types/icon/registry.d.ts +8 -0
  211. package/dist/types/index.d.ts +17 -0
  212. package/dist/types/menu/defines.d.ts +15 -0
  213. package/dist/types/menu/index.d.ts +5 -0
  214. package/dist/types/menu/menu-item.d.ts +63 -0
  215. package/dist/types/menu/menu.d.ts +34 -0
  216. package/dist/types/number-input/index.d.ts +2 -0
  217. package/dist/types/number-input/number-input.d.ts +35 -0
  218. package/dist/types/pagination/defines.d.ts +2 -0
  219. package/dist/types/pagination/index.d.ts +3 -0
  220. package/dist/types/pagination/pagination.d.ts +77 -0
  221. package/dist/types/select/select.d.ts +2 -2
  222. package/dist/types/spinner/defines.d.ts +3 -0
  223. package/dist/types/spinner/index.d.ts +3 -0
  224. package/dist/types/spinner/spinner.d.ts +35 -0
  225. package/dist/types/switch/defines.d.ts +1 -0
  226. package/dist/types/switch/switch.d.ts +8 -4
  227. package/dist/types/tabs/defines.d.ts +1 -0
  228. package/dist/types/tabs/tabs.d.ts +3 -0
  229. package/dist/types/text-input/text-input.d.ts +0 -4
  230. package/dist/types/textarea/index.d.ts +1 -0
  231. package/dist/types/textarea/textarea.d.ts +26 -0
  232. package/dist/types/tooltip/defines.d.ts +2 -0
  233. package/dist/types/tooltip/index.d.ts +4 -0
  234. package/dist/types/tooltip/tooltip.d.ts +48 -0
  235. package/dist/types/tree/defines.d.ts +23 -0
  236. package/dist/types/tree/index.d.ts +5 -0
  237. package/dist/types/tree/tree-item.d.ts +54 -0
  238. package/dist/types/tree/tree.d.ts +64 -0
  239. package/package.json +5 -5
  240. package/src/aeico-field.ts +142 -7
  241. package/src/alert/alert.ts +3 -2
  242. package/src/card/defines.ts +1 -1
  243. package/src/checkbox/checkbox.ts +17 -2
  244. package/src/copy-button/copy-button.ts +150 -0
  245. package/src/copy-button/defines.ts +5 -0
  246. package/src/copy-button/index.ts +3 -0
  247. package/src/detail/defines.ts +2 -1
  248. package/src/detail/detail.ts +5 -1
  249. package/src/detail/index.ts +1 -1
  250. package/src/detail-group/detail-group.ts +104 -0
  251. package/src/detail-group/index.ts +2 -0
  252. package/src/drawer/defines.ts +1 -0
  253. package/src/drawer/drawer.ts +157 -0
  254. package/src/drawer/index.ts +3 -0
  255. package/src/icon/built-in-icons.ts +21 -0
  256. package/src/icon/defines.ts +6 -1
  257. package/src/icon/icon.ts +29 -10
  258. package/src/icon/index.ts +1 -1
  259. package/src/icon/registry.ts +23 -1
  260. package/src/index.ts +30 -0
  261. package/src/menu/defines.ts +17 -0
  262. package/src/menu/index.ts +5 -0
  263. package/src/menu/menu-item.ts +315 -0
  264. package/src/menu/menu.ts +81 -0
  265. package/src/number-input/index.ts +2 -0
  266. package/src/number-input/number-input.ts +137 -0
  267. package/src/pagination/defines.ts +2 -0
  268. package/src/pagination/index.ts +3 -0
  269. package/src/pagination/pagination.ts +310 -0
  270. package/src/radio-group/radio-group.ts +11 -4
  271. package/src/select/select.ts +111 -70
  272. package/src/slider/slider.ts +9 -2
  273. package/src/spinner/defines.ts +12 -0
  274. package/src/spinner/index.ts +3 -0
  275. package/src/spinner/spinner.ts +81 -0
  276. package/src/styles/color.css +91 -91
  277. package/src/styles/components/action-button.css +37 -0
  278. package/src/styles/components/alert.css +22 -28
  279. package/src/styles/components/badge.css +13 -20
  280. package/src/styles/components/breadcrumb-item.css +7 -7
  281. package/src/styles/components/button.css +39 -50
  282. package/src/styles/components/card.css +45 -30
  283. package/src/styles/components/checkbox.css +9 -36
  284. package/src/styles/components/copy-button.css +108 -0
  285. package/src/styles/components/detail-group.css +10 -0
  286. package/src/styles/components/detail.css +56 -35
  287. package/src/styles/components/dialog.css +11 -11
  288. package/src/styles/components/divider.css +3 -3
  289. package/src/styles/components/drawer.css +152 -0
  290. package/src/styles/components/dropdown-item.css +7 -8
  291. package/src/styles/components/dropdown.css +3 -4
  292. package/src/styles/components/field-label.css +120 -0
  293. package/src/styles/components/icon-button.css +25 -36
  294. package/src/styles/components/icon.css +1 -1
  295. package/src/styles/components/menu-item.css +167 -0
  296. package/src/styles/components/menu.css +17 -0
  297. package/src/styles/components/navbar.css +16 -16
  298. package/src/styles/components/number-input.css +158 -0
  299. package/src/styles/components/pagination.css +205 -0
  300. package/src/styles/components/progress-bar.css +2 -3
  301. package/src/styles/components/radio-group.css +69 -106
  302. package/src/styles/components/select-option.css +5 -5
  303. package/src/styles/components/select.css +30 -69
  304. package/src/styles/components/slider.css +26 -71
  305. package/src/styles/components/spinner.css +78 -0
  306. package/src/styles/components/switch.css +64 -27
  307. package/src/styles/components/tab-panel.css +1 -1
  308. package/src/styles/components/tab.css +4 -5
  309. package/src/styles/components/tabs.css +49 -1
  310. package/src/styles/components/tag.css +14 -21
  311. package/src/styles/components/text-input.css +17 -64
  312. package/src/styles/components/textarea.css +66 -0
  313. package/src/styles/components/tooltip.css +102 -0
  314. package/src/styles/components/tree-item.css +152 -0
  315. package/src/styles/components/tree.css +10 -0
  316. package/src/styles/layout.css +457 -25
  317. package/src/styles/radius.css +10 -0
  318. package/src/styles/size.css +7 -7
  319. package/src/styles/variables.css +271 -247
  320. package/src/switch/defines.ts +1 -0
  321. package/src/switch/switch.ts +61 -12
  322. package/src/tabs/defines.ts +1 -0
  323. package/src/tabs/tabs.ts +12 -0
  324. package/src/text-input/text-input.ts +10 -15
  325. package/src/textarea/index.ts +1 -0
  326. package/src/textarea/textarea.ts +107 -0
  327. package/src/tooltip/defines.ts +11 -0
  328. package/src/tooltip/index.ts +4 -0
  329. package/src/tooltip/tooltip.ts +183 -0
  330. package/src/tree/defines.ts +26 -0
  331. package/src/tree/index.ts +5 -0
  332. package/src/tree/tree-item.ts +258 -0
  333. package/src/tree/tree.ts +237 -0
  334. package/dist/chunks/aeico-field.cjs +0 -179
  335. package/dist/chunks/aeico-field.cjs.map +0 -1
  336. package/dist/chunks/aeico-field.js +0 -180
  337. package/dist/chunks/aeico-field.js.map +0 -1
@@ -1,9 +1,13 @@
1
1
  import AeicoField, { type FieldAction } from '../aeico-field';
2
- import type { InferProps, Props } from 'aeico';
3
- import { html } from 'aeico';
2
+ import type { InferProps } from 'aeico';
3
+ import { html, prop } from 'aeico';
4
+ import type { SwitchIconPlacement } from './defines';
5
+ import '../icon/icon';
4
6
  import styleVariables from '../styles/variables.css?inline';
5
7
  import sizeCSS from '../styles/size.css?inline';
6
8
  import colorCSS from '../styles/color.css?inline';
9
+ import fieldLabelCSS from '../styles/components/field-label.css?inline';
10
+ import actionButtonCSS from '../styles/components/action-button.css?inline';
7
11
  import styles from '../styles/components/switch.css?inline';
8
12
 
9
13
  class Switch extends AeicoField<boolean> {
@@ -11,15 +15,29 @@ class Switch extends AeicoField<boolean> {
11
15
 
12
16
  static tagName = 'switch';
13
17
 
14
- static props: Props = {
15
- checked: { type: Boolean },
16
- defaultChecked: { type: Boolean },
17
- };
18
+ @prop({ type: Boolean })
19
+ accessor checked: boolean | undefined;
18
20
 
19
- declare checked?: boolean;
20
- declare defaultChecked?: boolean;
21
+ @prop({ type: Boolean })
22
+ accessor defaultChecked: boolean | undefined;
21
23
 
22
- protected static styles = [styleVariables, sizeCSS, colorCSS, styles];
24
+ @prop({ type: String })
25
+ accessor icon: string | undefined;
26
+
27
+ @prop({ type: String })
28
+ accessor iconChecked: string | undefined;
29
+
30
+ @prop({ type: String })
31
+ accessor iconPlacement: SwitchIconPlacement | undefined;
32
+
33
+ protected static styles = [
34
+ styleVariables,
35
+ sizeCSS,
36
+ colorCSS,
37
+ fieldLabelCSS,
38
+ actionButtonCSS,
39
+ styles,
40
+ ];
23
41
 
24
42
  protected getValue(): boolean {
25
43
  return this.fieldElement?.checked ?? false;
@@ -58,20 +76,51 @@ class Switch extends AeicoField<boolean> {
58
76
  }
59
77
 
60
78
  render() {
61
- return html(({ div, input, span }) => {
62
- div({ className: 'switch-container' }, () => {
79
+ return html(({ div, input, span, aeIcon }) => {
80
+ const id = this.getFieldId();
81
+ this.renderLabel(id);
82
+ div({ className: 'switch-container field-body' }, () => {
63
83
  div({ className: 'switch-wrapper' }, () => {
64
84
  this.fieldElement = input({
85
+ id,
65
86
  type: 'checkbox',
66
87
  className: 'field-input',
67
88
  checked: Boolean(this.checked),
68
89
  disabled: Boolean(this.disabled),
90
+ required: Boolean(this.required),
69
91
  '@change': this.boundOnChange,
70
92
  });
71
- span({ className: 'toggle-slider' });
93
+ const hasIcon = this.icon || this.iconChecked;
94
+ const placement = this.iconPlacement ?? 'knob';
95
+ span({ className: 'toggle-slider' }, () => {
96
+ if (!hasIcon) return;
97
+ if (placement === 'track') {
98
+ span({ className: 'track-icon track-icon-left' }, () => {
99
+ aeIcon({ name: this.iconChecked ?? this.icon! });
100
+ });
101
+ span({ className: 'track-icon track-icon-right' }, () => {
102
+ aeIcon({ name: this.icon ?? this.iconChecked! });
103
+ });
104
+ } else {
105
+ if (this.icon && this.iconChecked) {
106
+ span({ className: 'toggle-knob-icon icon-unchecked' }, () => {
107
+ aeIcon({ name: this.icon! });
108
+ });
109
+ span({ className: 'toggle-knob-icon icon-checked' }, () => {
110
+ aeIcon({ name: this.iconChecked! });
111
+ });
112
+ } else {
113
+ span({ className: 'toggle-knob-icon' }, () => {
114
+ aeIcon({ name: (this.icon ?? this.iconChecked)! });
115
+ });
116
+ }
117
+ }
118
+ });
72
119
  });
73
120
  this.renderActionButtons();
74
121
  });
122
+ this.renderHelperText();
123
+ this.renderError();
75
124
  });
76
125
  }
77
126
  }
@@ -1 +1,2 @@
1
1
  export type TabActiveIndex = number;
2
+ export type TabVariant = 'subtle' | 'faint' | 'filled' | 'outlined' | 'text';
package/src/tabs/tabs.ts CHANGED
@@ -4,13 +4,16 @@ import tabsStyle from '../styles/components/tabs.css?inline';
4
4
  import AeicoComponent from '../aeico-component';
5
5
  import { html } from 'aeico';
6
6
  import type Tab from './tab';
7
+ import type { TabVariant } from './defines';
7
8
 
8
9
  class Tabs extends AeicoComponent {
9
10
  static props: Props = {
10
11
  activeIndex: { type: Number },
12
+ variant: { type: String },
11
13
  };
12
14
 
13
15
  declare activeIndex?: number;
16
+ declare variant?: TabVariant;
14
17
 
15
18
  protected static styles = [styleVariables, tabsStyle];
16
19
 
@@ -77,9 +80,18 @@ class Tabs extends AeicoComponent {
77
80
  }
78
81
 
79
82
  protected onUpdated() {
83
+ this._syncVariant();
80
84
  this._syncActive();
81
85
  }
82
86
 
87
+ private _syncVariant() {
88
+ const variant = this.variant ?? 'text';
89
+ this.setAttribute('variant', variant);
90
+ for (const tab of this._tabs) {
91
+ tab.setAttribute('variant', variant);
92
+ }
93
+ }
94
+
83
95
  private _handleTabClick = (e: Event) => {
84
96
  const pairs = this._getPairs();
85
97
  const target = e.target as Element;
@@ -3,6 +3,8 @@ import type { InferProps, Props } from 'aeico';
3
3
  import { html } from 'aeico';
4
4
  import variables from '../styles/variables.css?inline';
5
5
  import sizeCSS from '../styles/size.css?inline';
6
+ import fieldLabelCSS from '../styles/components/field-label.css?inline';
7
+ import actionButtonCSS from '../styles/components/action-button.css?inline';
6
8
  import style from '../styles/components/text-input.css?inline';
7
9
 
8
10
  class TextInput extends AeicoField {
@@ -18,37 +20,32 @@ class TextInput extends AeicoField {
18
20
  declare placeholder?: string;
19
21
  declare type?: string;
20
22
 
21
- protected static styles = [variables, sizeCSS, style];
23
+ protected static styles = [variables, sizeCSS, fieldLabelCSS, actionButtonCSS, style];
22
24
 
23
25
  render() {
24
26
  return html(({ div, input }) => {
25
- div({ className: 'input-container' }, () => {
27
+ const id = this.getFieldId();
28
+ this.renderLabel(id);
29
+ div({ className: 'input-container field-body' }, () => {
26
30
  this.fieldElement = input({
31
+ id,
27
32
  type: this.type || 'text',
28
33
  placeholder: this.placeholder || '',
34
+ required: Boolean(this.required),
29
35
  '@input': this.boundOnChange,
30
36
  });
31
37
 
32
38
  this.renderActionButtons();
33
39
  });
40
+ this.renderHelperText();
41
+ this.renderError();
34
42
 
35
43
  if (this.fieldElement && this.value != null) {
36
44
  this.fieldElement.value = String(this.value);
37
45
  }
38
- this.updateClearButtonVisibility();
39
46
  });
40
47
  }
41
48
 
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
49
  /**
53
50
  * Write value to the input element (DOM only)
54
51
  */
@@ -58,8 +55,6 @@ class TextInput extends AeicoField {
58
55
  if (this.fieldElement) {
59
56
  this.fieldElement.value = strValue;
60
57
  }
61
-
62
- this.updateClearButtonVisibility();
63
58
  }
64
59
  }
65
60
 
@@ -0,0 +1 @@
1
+ export { default, type TextareaProps, type TextareaResize } from './textarea';
@@ -0,0 +1,107 @@
1
+ import AeicoField from '../aeico-field';
2
+ import type { InferProps } from 'aeico';
3
+ import { html, prop } from 'aeico';
4
+ import variables from '../styles/variables.css?inline';
5
+ import sizeCSS from '../styles/size.css?inline';
6
+ import fieldLabelCSS from '../styles/components/field-label.css?inline';
7
+ import actionButtonCSS from '../styles/components/action-button.css?inline';
8
+ import style from '../styles/components/textarea.css?inline';
9
+
10
+ export type TextareaResize = 'none' | 'vertical' | 'horizontal' | 'both';
11
+
12
+ class Textarea extends AeicoField {
13
+ protected fieldElement: HTMLTextAreaElement | null = null;
14
+
15
+ static tagName = 'textarea';
16
+
17
+ @prop({ type: String })
18
+ accessor placeholder: string | undefined;
19
+
20
+ @prop({ type: Number })
21
+ accessor rows: number | undefined;
22
+
23
+ @prop({ type: Number })
24
+ accessor maxlength: number | undefined;
25
+
26
+ @prop({ type: Number })
27
+ accessor minlength: number | undefined;
28
+
29
+ @prop({ type: String })
30
+ accessor resize: TextareaResize | undefined;
31
+
32
+ @prop({ type: Boolean })
33
+ accessor autoResize: boolean = false;
34
+
35
+ protected static styles = [variables, sizeCSS, fieldLabelCSS, actionButtonCSS, style];
36
+
37
+ private readonly _boundOnInput = () => {
38
+ if (this.autoResize && this.fieldElement) {
39
+ this._syncAutoResize(this.fieldElement);
40
+ }
41
+ this.setValue(this.getValue(), { silent: false, action: 'change' });
42
+ };
43
+
44
+ render() {
45
+ return html(({ div, textarea }) => {
46
+ const id = this.getFieldId();
47
+ this.renderLabel(id);
48
+ div({ className: 'textarea-container field-body' }, () => {
49
+ this.fieldElement = textarea({
50
+ id,
51
+ placeholder: this.placeholder || '',
52
+ rows: this.rows ?? 3,
53
+ required: Boolean(this.required),
54
+ '@input': this._boundOnInput,
55
+ });
56
+ this.renderActionButtons();
57
+ });
58
+ this.renderHelperText();
59
+ this.renderError();
60
+
61
+ if (this.fieldElement) {
62
+ if (this.value != null) {
63
+ this.fieldElement.value = String(this.value);
64
+ }
65
+ if (this.maxlength != null) this.fieldElement.maxLength = this.maxlength;
66
+ if (this.minlength != null) this.fieldElement.minLength = this.minlength;
67
+ this.fieldElement.style.resize = this.autoResize ? 'none' : (this.resize ?? 'vertical');
68
+ if (this.autoResize) {
69
+ this._syncAutoResize(this.fieldElement);
70
+ }
71
+ this._updateClearButtonVisibility();
72
+ }
73
+ });
74
+ }
75
+
76
+ private _syncAutoResize(ta: HTMLTextAreaElement): void {
77
+ ta.style.height = 'auto';
78
+ ta.style.height = `${ta.scrollHeight}px`;
79
+ }
80
+
81
+ private _updateClearButtonVisibility(): void {
82
+ if (this.clearBtn && this.fieldElement) {
83
+ this.clearBtn.style.display = this.fieldElement.value.length > 0 ? '' : 'none';
84
+ }
85
+ }
86
+
87
+ protected writeValue(value: string): void {
88
+ if (this.fieldElement) {
89
+ this.fieldElement.value = String(value || '');
90
+ if (this.autoResize) {
91
+ this._syncAutoResize(this.fieldElement);
92
+ }
93
+ this._updateClearButtonVisibility();
94
+ }
95
+ }
96
+ }
97
+
98
+ Textarea.register();
99
+
100
+ declare global {
101
+ interface HTMLElementTagNameMap {
102
+ 'ae-textarea': Textarea;
103
+ }
104
+ }
105
+
106
+ export default Textarea;
107
+ export type TextareaProps = InferProps<typeof Textarea>;
@@ -0,0 +1,11 @@
1
+ export type TooltipPlacement =
2
+ | 'top'
3
+ | 'top-start'
4
+ | 'top-end'
5
+ | 'bottom'
6
+ | 'bottom-start'
7
+ | 'bottom-end'
8
+ | 'left'
9
+ | 'right';
10
+
11
+ export type TooltipTrigger = 'hover' | 'click';
@@ -0,0 +1,4 @@
1
+ export { default } from './tooltip';
2
+ export { default as Tooltip } from './tooltip';
3
+ export type { TooltipProps } from './tooltip';
4
+ export type { TooltipPlacement, TooltipTrigger } from './defines';
@@ -0,0 +1,183 @@
1
+ import type { InferProps } from 'aeico';
2
+ import styleVariables from '../styles/variables.css?inline';
3
+ import tooltipStyle from '../styles/components/tooltip.css?inline';
4
+ import AeicoComponent from '../aeico-component';
5
+ import { html, prop } from 'aeico';
6
+ import type { TooltipPlacement, TooltipTrigger } from './defines';
7
+
8
+ /**
9
+ * Tooltip Component
10
+ *
11
+ * A floating label that appears on hover or focus around its trigger content.
12
+ * Wrap any element in `<ae-tooltip>` and provide content via the `content`
13
+ * attribute (plain text) or the `tooltip` named slot (rich HTML).
14
+ *
15
+ * @example
16
+ * ```html
17
+ * <ae-tooltip content="Save file">
18
+ * <ae-button>Save</ae-button>
19
+ * </ae-tooltip>
20
+ *
21
+ * <ae-tooltip placement="bottom-start">
22
+ * <span slot="tooltip"><strong>Bold</strong> tip</span>
23
+ * <ae-icon-button name="info"></ae-icon-button>
24
+ * </ae-tooltip>
25
+ * ```
26
+ */
27
+ class Tooltip extends AeicoComponent {
28
+ protected static styles = [styleVariables, tooltipStyle];
29
+
30
+ @prop({ type: String })
31
+ accessor content: string | undefined;
32
+
33
+ @prop({ type: String })
34
+ accessor placement: TooltipPlacement = 'top';
35
+
36
+ @prop({ type: Boolean })
37
+ accessor disabled: boolean = false;
38
+
39
+ @prop({ type: String })
40
+ accessor trigger: TooltipTrigger = 'hover';
41
+
42
+ @prop({ type: Boolean })
43
+ accessor open: boolean = false;
44
+
45
+ private _outsideClickHandler: ((e: MouseEvent) => void) | null = null;
46
+
47
+ connectedCallback() {
48
+ super.connectedCallback();
49
+ this.listen('mouseenter', this._handleMouseEnter);
50
+ this.listen('mouseleave', this._handleMouseLeave);
51
+ this.listen('focusin', this._handleFocusin);
52
+ this.listen('focusout', this._handleFocusout);
53
+ this.listen('click', this._handleClick);
54
+
55
+ this._outsideClickHandler = (e: MouseEvent) => {
56
+ if (!this.open) return;
57
+ if (!e.composedPath().includes(this)) this.open = false;
58
+ };
59
+ document.addEventListener('click', this._outsideClickHandler);
60
+ }
61
+
62
+ disconnectedCallback() {
63
+ super.disconnectedCallback();
64
+ if (this._outsideClickHandler) {
65
+ document.removeEventListener('click', this._outsideClickHandler);
66
+ this._outsideClickHandler = null;
67
+ }
68
+ }
69
+
70
+ private _handleMouseEnter = () => {
71
+ if (this.trigger !== 'hover') return;
72
+ if (this.disabled) return;
73
+ this.open = true;
74
+ };
75
+
76
+ private _handleMouseLeave = () => {
77
+ if (this.trigger !== 'hover') return;
78
+ this.open = false;
79
+ };
80
+
81
+ private _handleFocusin = () => {
82
+ if (this.trigger !== 'hover') return;
83
+ if (this.disabled) return;
84
+ this.open = true;
85
+ };
86
+
87
+ private _handleFocusout = () => {
88
+ if (this.trigger !== 'hover') return;
89
+ this.open = false;
90
+ };
91
+
92
+ private _handleClick = () => {
93
+ if (this.trigger !== 'click') return;
94
+ if (this.disabled) return;
95
+ this.open = !this.open;
96
+ };
97
+
98
+ private _updatePosition() {
99
+ const panel = this.shadowRoot?.querySelector<HTMLElement>('.tooltip-panel');
100
+ if (!panel) return;
101
+
102
+ const host = this.getBoundingClientRect();
103
+ const panelRect = panel.getBoundingClientRect();
104
+ const gap = 6; // Match --ae-tooltip-gap: 6px
105
+ const pw = panelRect.width;
106
+ const ph = panelRect.height;
107
+
108
+ let top: number;
109
+ let left: number;
110
+
111
+ switch (this.placement) {
112
+ case 'top-start':
113
+ top = host.top - ph - gap;
114
+ left = host.left;
115
+ break;
116
+ case 'top-end':
117
+ top = host.top - ph - gap;
118
+ left = host.right - pw;
119
+ break;
120
+ case 'bottom':
121
+ top = host.bottom + gap;
122
+ left = host.left + host.width / 2 - pw / 2;
123
+ break;
124
+ case 'bottom-start':
125
+ top = host.bottom + gap;
126
+ left = host.left;
127
+ break;
128
+ case 'bottom-end':
129
+ top = host.bottom + gap;
130
+ left = host.right - pw;
131
+ break;
132
+ case 'left':
133
+ top = host.top + host.height / 2 - ph / 2;
134
+ left = host.left - pw - gap;
135
+ break;
136
+ case 'right':
137
+ top = host.top + host.height / 2 - ph / 2;
138
+ left = host.right + gap;
139
+ break;
140
+ default: // 'top'
141
+ top = host.top - ph - gap;
142
+ left = host.left + host.width / 2 - pw / 2;
143
+ }
144
+
145
+ panel.style.top = `${top}px`;
146
+ panel.style.left = `${left}px`;
147
+ }
148
+
149
+ protected onUpdated(changedProps: Map<string, unknown>) {
150
+ if (changedProps.has('open') && this.open) {
151
+ this._updatePosition();
152
+ }
153
+ }
154
+
155
+ protected render() {
156
+ return html(({ div, span, slot }) => {
157
+ slot();
158
+ div(
159
+ {
160
+ className: `tooltip-panel placement-${this.placement ?? 'top'}`,
161
+ role: 'tooltip',
162
+ 'aria-hidden': String(!this.open),
163
+ },
164
+ () => {
165
+ slot({ name: 'tooltip' }, () => {
166
+ span({ textContent: this.content ?? '' });
167
+ });
168
+ },
169
+ );
170
+ });
171
+ }
172
+ }
173
+
174
+ Tooltip.register();
175
+
176
+ declare global {
177
+ interface HTMLElementTagNameMap {
178
+ 'ae-tooltip': Tooltip;
179
+ }
180
+ }
181
+
182
+ export type TooltipProps = InferProps<typeof Tooltip>;
183
+ export default Tooltip;
@@ -0,0 +1,26 @@
1
+ /** Minimal interface used by tree-item to read config from its parent ae-tree. */
2
+ export interface ParentTreeLike extends Element {
3
+ checkable?: boolean;
4
+ multiple?: boolean;
5
+ showLine?: boolean;
6
+ defaultExpandAll?: boolean;
7
+ icon?: string;
8
+ }
9
+
10
+ export interface TreeSelectDetail {
11
+ key: string;
12
+ selected: boolean;
13
+ selectedKeys: string[];
14
+ }
15
+
16
+ export interface TreeExpandDetail {
17
+ key: string;
18
+ expanded: boolean;
19
+ expandedKeys: string[];
20
+ }
21
+
22
+ export interface TreeCheckDetail {
23
+ key: string;
24
+ checked: boolean;
25
+ checkedKeys: string[];
26
+ }
@@ -0,0 +1,5 @@
1
+ export { default as Tree } from './tree';
2
+ export { default as TreeItem } from './tree-item';
3
+ export type { TreeProps } from './tree';
4
+ export type { TreeItemProps } from './tree-item';
5
+ export type { TreeSelectDetail, TreeExpandDetail, TreeCheckDetail } from './defines';