aeico-components 0.1.5 → 0.1.6

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 (284) 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 +4 -4
  8. package/dist/chunks/alert.cjs.map +1 -1
  9. package/dist/chunks/alert.js +5 -5
  10. package/dist/chunks/alert.js.map +1 -1
  11. package/dist/chunks/badge.cjs +1 -1
  12. package/dist/chunks/badge.cjs.map +1 -1
  13. package/dist/chunks/badge.js +2 -2
  14. package/dist/chunks/badge.js.map +1 -1
  15. package/dist/chunks/breadcrumb-item.cjs +2 -2
  16. package/dist/chunks/breadcrumb-item.cjs.map +1 -1
  17. package/dist/chunks/breadcrumb-item.js +3 -3
  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 +1 -1
  24. package/dist/chunks/button.cjs.map +1 -1
  25. package/dist/chunks/button.js +2 -2
  26. package/dist/chunks/button.js.map +1 -1
  27. package/dist/chunks/card.cjs +1 -1
  28. package/dist/chunks/card.cjs.map +1 -1
  29. package/dist/chunks/card.js +2 -2
  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/copy-button.cjs +168 -0
  36. package/dist/chunks/copy-button.cjs.map +1 -0
  37. package/dist/chunks/copy-button.js +169 -0
  38. package/dist/chunks/copy-button.js.map +1 -0
  39. package/dist/chunks/detail.cjs +7 -4
  40. package/dist/chunks/detail.cjs.map +1 -1
  41. package/dist/chunks/detail.js +8 -5
  42. package/dist/chunks/detail.js.map +1 -1
  43. package/dist/chunks/dialog.cjs +1 -1
  44. package/dist/chunks/dialog.cjs.map +1 -1
  45. package/dist/chunks/dialog.js +2 -2
  46. package/dist/chunks/dialog.js.map +1 -1
  47. package/dist/chunks/divider.cjs +1 -1
  48. package/dist/chunks/divider.cjs.map +1 -1
  49. package/dist/chunks/divider.js +2 -2
  50. package/dist/chunks/divider.js.map +1 -1
  51. package/dist/chunks/drawer.cjs +180 -0
  52. package/dist/chunks/drawer.cjs.map +1 -0
  53. package/dist/chunks/drawer.js +181 -0
  54. package/dist/chunks/drawer.js.map +1 -0
  55. package/dist/chunks/dropdown-button.cjs +2 -2
  56. package/dist/chunks/dropdown-button.cjs.map +1 -1
  57. package/dist/chunks/dropdown-button.js +3 -3
  58. package/dist/chunks/dropdown-button.js.map +1 -1
  59. package/dist/chunks/icon.cjs +31 -1
  60. package/dist/chunks/icon.cjs.map +1 -1
  61. package/dist/chunks/icon.js +32 -2
  62. package/dist/chunks/icon.js.map +1 -1
  63. package/dist/chunks/menu.cjs +396 -0
  64. package/dist/chunks/menu.cjs.map +1 -0
  65. package/dist/chunks/menu.js +397 -0
  66. package/dist/chunks/menu.js.map +1 -0
  67. package/dist/chunks/navbar.cjs +1 -1
  68. package/dist/chunks/navbar.cjs.map +1 -1
  69. package/dist/chunks/navbar.js +2 -2
  70. package/dist/chunks/navbar.js.map +1 -1
  71. package/dist/chunks/pagination.cjs +475 -0
  72. package/dist/chunks/pagination.cjs.map +1 -0
  73. package/dist/chunks/pagination.js +476 -0
  74. package/dist/chunks/pagination.js.map +1 -0
  75. package/dist/chunks/progress-bar.cjs +101 -0
  76. package/dist/chunks/progress-bar.cjs.map +1 -0
  77. package/dist/chunks/progress-bar.js +102 -0
  78. package/dist/chunks/progress-bar.js.map +1 -0
  79. package/dist/chunks/radio.cjs +11 -7
  80. package/dist/chunks/radio.cjs.map +1 -1
  81. package/dist/chunks/radio.js +11 -7
  82. package/dist/chunks/radio.js.map +1 -1
  83. package/dist/chunks/select.cjs +97 -66
  84. package/dist/chunks/select.cjs.map +1 -1
  85. package/dist/chunks/select.js +97 -66
  86. package/dist/chunks/select.js.map +1 -1
  87. package/dist/chunks/slider.cjs +9 -46
  88. package/dist/chunks/slider.cjs.map +1 -1
  89. package/dist/chunks/slider.js +9 -46
  90. package/dist/chunks/slider.js.map +1 -1
  91. package/dist/chunks/spinner.cjs +102 -0
  92. package/dist/chunks/spinner.cjs.map +1 -0
  93. package/dist/chunks/spinner.js +103 -0
  94. package/dist/chunks/spinner.js.map +1 -0
  95. package/dist/chunks/switch.cjs +110 -16
  96. package/dist/chunks/switch.cjs.map +1 -1
  97. package/dist/chunks/switch.js +111 -17
  98. package/dist/chunks/switch.js.map +1 -1
  99. package/dist/chunks/tab-panel.cjs +3 -3
  100. package/dist/chunks/tab-panel.cjs.map +1 -1
  101. package/dist/chunks/tab-panel.js +4 -4
  102. package/dist/chunks/tab-panel.js.map +1 -1
  103. package/dist/chunks/tag.cjs +1 -1
  104. package/dist/chunks/tag.cjs.map +1 -1
  105. package/dist/chunks/tag.js +2 -2
  106. package/dist/chunks/tag.js.map +1 -1
  107. package/dist/chunks/text-input.cjs +11 -16
  108. package/dist/chunks/text-input.cjs.map +1 -1
  109. package/dist/chunks/text-input.js +11 -16
  110. package/dist/chunks/text-input.js.map +1 -1
  111. package/dist/chunks/textarea.cjs +137 -0
  112. package/dist/chunks/textarea.cjs.map +1 -0
  113. package/dist/chunks/textarea.js +138 -0
  114. package/dist/chunks/textarea.js.map +1 -0
  115. package/dist/chunks/tooltip.cjs +293 -0
  116. package/dist/chunks/tooltip.cjs.map +1 -0
  117. package/dist/chunks/tooltip.js +294 -0
  118. package/dist/chunks/tooltip.js.map +1 -0
  119. package/dist/chunks/tree.cjs +468 -0
  120. package/dist/chunks/tree.cjs.map +1 -0
  121. package/dist/chunks/tree.js +469 -0
  122. package/dist/chunks/tree.js.map +1 -0
  123. package/dist/chunks/variables.cjs +2 -2
  124. package/dist/chunks/variables.js +2 -2
  125. package/dist/copy-button.cjs +6 -0
  126. package/dist/copy-button.cjs.map +1 -0
  127. package/dist/copy-button.js +6 -0
  128. package/dist/copy-button.js.map +1 -0
  129. package/dist/drawer.cjs +6 -0
  130. package/dist/drawer.cjs.map +1 -0
  131. package/dist/drawer.js +6 -0
  132. package/dist/drawer.js.map +1 -0
  133. package/dist/index.cjs +175 -88
  134. package/dist/index.cjs.map +1 -1
  135. package/dist/index.js +186 -99
  136. package/dist/index.js.map +1 -1
  137. package/dist/menu.cjs +6 -0
  138. package/dist/menu.cjs.map +1 -0
  139. package/dist/menu.js +6 -0
  140. package/dist/menu.js.map +1 -0
  141. package/dist/pagination.cjs +6 -0
  142. package/dist/pagination.cjs.map +1 -0
  143. package/dist/pagination.js +6 -0
  144. package/dist/pagination.js.map +1 -0
  145. package/dist/progress-bar.cjs +6 -0
  146. package/dist/progress-bar.cjs.map +1 -0
  147. package/dist/progress-bar.js +6 -0
  148. package/dist/progress-bar.js.map +1 -0
  149. package/dist/select.cjs +1 -1
  150. package/dist/select.cjs.map +1 -1
  151. package/dist/select.js +2 -2
  152. package/dist/select.js.map +1 -1
  153. package/dist/spinner.cjs +6 -0
  154. package/dist/spinner.cjs.map +1 -0
  155. package/dist/spinner.js +6 -0
  156. package/dist/spinner.js.map +1 -0
  157. package/dist/textarea.cjs +5 -0
  158. package/dist/textarea.cjs.map +1 -0
  159. package/dist/textarea.js +5 -0
  160. package/dist/textarea.js.map +1 -0
  161. package/dist/tooltip.cjs +6 -0
  162. package/dist/tooltip.cjs.map +1 -0
  163. package/dist/tooltip.js +6 -0
  164. package/dist/tooltip.js.map +1 -0
  165. package/dist/tree.cjs +6 -0
  166. package/dist/tree.cjs.map +1 -0
  167. package/dist/tree.js +6 -0
  168. package/dist/tree.js.map +1 -0
  169. package/dist/types/aeico-field.d.ts +52 -0
  170. package/dist/types/alert/alert.d.ts +1 -0
  171. package/dist/types/copy-button/copy-button.d.ts +32 -0
  172. package/dist/types/copy-button/defines.d.ts +1 -0
  173. package/dist/types/copy-button/index.d.ts +3 -0
  174. package/dist/types/detail/defines.d.ts +1 -0
  175. package/dist/types/detail/detail.d.ts +3 -1
  176. package/dist/types/detail/index.d.ts +1 -1
  177. package/dist/types/detail-group/detail-group.d.ts +39 -0
  178. package/dist/types/detail-group/index.d.ts +2 -0
  179. package/dist/types/drawer/defines.d.ts +1 -0
  180. package/dist/types/drawer/drawer.d.ts +31 -0
  181. package/dist/types/drawer/index.d.ts +3 -0
  182. package/dist/types/icon/built-in-icons.d.ts +1 -0
  183. package/dist/types/icon/icon.d.ts +1 -0
  184. package/dist/types/icon/registry.d.ts +8 -0
  185. package/dist/types/index.d.ts +17 -0
  186. package/dist/types/menu/defines.d.ts +15 -0
  187. package/dist/types/menu/index.d.ts +5 -0
  188. package/dist/types/menu/menu-item.d.ts +63 -0
  189. package/dist/types/menu/menu.d.ts +34 -0
  190. package/dist/types/number-input/index.d.ts +2 -0
  191. package/dist/types/number-input/number-input.d.ts +35 -0
  192. package/dist/types/pagination/defines.d.ts +2 -0
  193. package/dist/types/pagination/index.d.ts +3 -0
  194. package/dist/types/pagination/pagination.d.ts +77 -0
  195. package/dist/types/select/select.d.ts +2 -2
  196. package/dist/types/spinner/defines.d.ts +3 -0
  197. package/dist/types/spinner/index.d.ts +3 -0
  198. package/dist/types/spinner/spinner.d.ts +35 -0
  199. package/dist/types/switch/defines.d.ts +1 -0
  200. package/dist/types/switch/switch.d.ts +8 -4
  201. package/dist/types/text-input/text-input.d.ts +0 -4
  202. package/dist/types/textarea/index.d.ts +1 -0
  203. package/dist/types/textarea/textarea.d.ts +26 -0
  204. package/dist/types/tooltip/defines.d.ts +2 -0
  205. package/dist/types/tooltip/index.d.ts +4 -0
  206. package/dist/types/tooltip/tooltip.d.ts +48 -0
  207. package/dist/types/tree/defines.d.ts +23 -0
  208. package/dist/types/tree/index.d.ts +5 -0
  209. package/dist/types/tree/tree-item.d.ts +54 -0
  210. package/dist/types/tree/tree.d.ts +64 -0
  211. package/package.json +5 -5
  212. package/src/aeico-field.ts +142 -7
  213. package/src/alert/alert.ts +3 -2
  214. package/src/checkbox/checkbox.ts +17 -2
  215. package/src/copy-button/copy-button.ts +146 -0
  216. package/src/copy-button/defines.ts +5 -0
  217. package/src/copy-button/index.ts +3 -0
  218. package/src/detail/defines.ts +1 -0
  219. package/src/detail/detail.ts +5 -1
  220. package/src/detail/index.ts +1 -1
  221. package/src/detail-group/detail-group.ts +104 -0
  222. package/src/detail-group/index.ts +2 -0
  223. package/src/drawer/defines.ts +1 -0
  224. package/src/drawer/drawer.ts +157 -0
  225. package/src/drawer/index.ts +3 -0
  226. package/src/icon/built-in-icons.ts +21 -0
  227. package/src/icon/icon.ts +1 -0
  228. package/src/icon/registry.ts +22 -0
  229. package/src/index.ts +30 -0
  230. package/src/menu/defines.ts +17 -0
  231. package/src/menu/index.ts +5 -0
  232. package/src/menu/menu-item.ts +315 -0
  233. package/src/menu/menu.ts +81 -0
  234. package/src/number-input/index.ts +2 -0
  235. package/src/number-input/number-input.ts +137 -0
  236. package/src/pagination/defines.ts +2 -0
  237. package/src/pagination/index.ts +3 -0
  238. package/src/pagination/pagination.ts +310 -0
  239. package/src/radio-group/radio-group.ts +11 -4
  240. package/src/select/select.ts +111 -70
  241. package/src/slider/slider.ts +9 -2
  242. package/src/spinner/defines.ts +12 -0
  243. package/src/spinner/index.ts +3 -0
  244. package/src/spinner/spinner.ts +81 -0
  245. package/src/styles/components/action-button.css +37 -0
  246. package/src/styles/components/checkbox.css +4 -26
  247. package/src/styles/components/copy-button.css +119 -0
  248. package/src/styles/components/detail-group.css +10 -0
  249. package/src/styles/components/detail.css +10 -1
  250. package/src/styles/components/drawer.css +161 -0
  251. package/src/styles/components/field-label.css +120 -0
  252. package/src/styles/components/menu-item.css +168 -0
  253. package/src/styles/components/menu.css +17 -0
  254. package/src/styles/components/number-input.css +167 -0
  255. package/src/styles/components/pagination.css +205 -0
  256. package/src/styles/components/radio-group.css +0 -23
  257. package/src/styles/components/select.css +12 -39
  258. package/src/styles/components/slider.css +0 -42
  259. package/src/styles/components/spinner.css +80 -0
  260. package/src/styles/components/switch.css +68 -19
  261. package/src/styles/components/tab-panel.css +1 -1
  262. package/src/styles/components/tabs.css +1 -0
  263. package/src/styles/components/text-input.css +7 -45
  264. package/src/styles/components/textarea.css +75 -0
  265. package/src/styles/components/tooltip.css +103 -0
  266. package/src/styles/components/tree-item.css +152 -0
  267. package/src/styles/components/tree.css +10 -0
  268. package/src/styles/layout.css +457 -25
  269. package/src/switch/defines.ts +1 -0
  270. package/src/switch/switch.ts +61 -12
  271. package/src/text-input/text-input.ts +10 -15
  272. package/src/textarea/index.ts +1 -0
  273. package/src/textarea/textarea.ts +107 -0
  274. package/src/tooltip/defines.ts +11 -0
  275. package/src/tooltip/index.ts +4 -0
  276. package/src/tooltip/tooltip.ts +183 -0
  277. package/src/tree/defines.ts +26 -0
  278. package/src/tree/index.ts +5 -0
  279. package/src/tree/tree-item.ts +258 -0
  280. package/src/tree/tree.ts +237 -0
  281. package/dist/chunks/aeico-field.cjs +0 -179
  282. package/dist/chunks/aeico-field.cjs.map +0 -1
  283. package/dist/chunks/aeico-field.js +0 -180
  284. package/dist/chunks/aeico-field.js.map +0 -1
@@ -0,0 +1,35 @@
1
+ import AeicoComponent from '../aeico-component';
2
+ import type { InferProps } from 'aeico';
3
+ import type { SpinnerColor, SpinnerSize, SpinnerVariant } from './defines';
4
+ /**
5
+ * Spinner — animated loading indicator.
6
+ *
7
+ * Supports two visual variants: a rotating ring (`border`, default) and
8
+ * three bouncing dots (`dots`). Size and colour are driven by the shared
9
+ * design-token system.
10
+ *
11
+ * @example
12
+ * ```html
13
+ * <ae-spinner></ae-spinner>
14
+ * <ae-spinner variant="dots" color="primary" size="lg"></ae-spinner>
15
+ * <ae-spinner color="success" speed="0.5s" label="Saving…"></ae-spinner>
16
+ * ```
17
+ */
18
+ declare class Spinner extends AeicoComponent {
19
+ static tagName: string;
20
+ accessor variant: SpinnerVariant;
21
+ accessor size: SpinnerSize;
22
+ accessor color: SpinnerColor;
23
+ accessor label: string;
24
+ accessor speed: string | undefined;
25
+ protected static styles: string[];
26
+ connectedCallback(): void;
27
+ protected render(): import("aeico-view").RenderResult;
28
+ }
29
+ declare global {
30
+ interface HTMLElementTagNameMap {
31
+ 'ae-spinner': Spinner;
32
+ }
33
+ }
34
+ export default Spinner;
35
+ export type SpinnerProps = InferProps<typeof Spinner>;
@@ -0,0 +1 @@
1
+ export type SwitchIconPlacement = 'knob' | 'track';
@@ -1,11 +1,15 @@
1
1
  import AeicoField, { type FieldAction } from '../aeico-field';
2
- import type { InferProps, Props } from 'aeico';
2
+ import type { InferProps } from 'aeico';
3
+ import type { SwitchIconPlacement } from './defines';
4
+ import '../icon/icon';
3
5
  declare class Switch extends AeicoField<boolean> {
4
6
  protected fieldElement: HTMLInputElement | null;
5
7
  static tagName: string;
6
- static props: Props;
7
- checked?: boolean;
8
- defaultChecked?: boolean;
8
+ accessor checked: boolean | undefined;
9
+ accessor defaultChecked: boolean | undefined;
10
+ accessor icon: string | undefined;
11
+ accessor iconChecked: string | undefined;
12
+ accessor iconPlacement: SwitchIconPlacement | undefined;
9
13
  protected static styles: string[];
10
14
  protected getValue(): boolean;
11
15
  protected writeValue(checked: boolean): void;
@@ -8,10 +8,6 @@ declare class TextInput extends AeicoField {
8
8
  type?: string;
9
9
  protected static styles: string[];
10
10
  render(): import("aeico-view").RenderResult;
11
- /**
12
- * Update clear button visibility based on input value
13
- */
14
- private updateClearButtonVisibility;
15
11
  /**
16
12
  * Write value to the input element (DOM only)
17
13
  */
@@ -0,0 +1 @@
1
+ export { default, type TextareaProps, type TextareaResize } from './textarea';
@@ -0,0 +1,26 @@
1
+ import AeicoField from '../aeico-field';
2
+ import type { InferProps } from 'aeico';
3
+ export type TextareaResize = 'none' | 'vertical' | 'horizontal' | 'both';
4
+ declare class Textarea extends AeicoField {
5
+ protected fieldElement: HTMLTextAreaElement | null;
6
+ static tagName: string;
7
+ accessor placeholder: string | undefined;
8
+ accessor rows: number | undefined;
9
+ accessor maxlength: number | undefined;
10
+ accessor minlength: number | undefined;
11
+ accessor resize: TextareaResize | undefined;
12
+ accessor autoResize: boolean;
13
+ protected static styles: string[];
14
+ private readonly _boundOnInput;
15
+ render(): import("aeico-view").RenderResult;
16
+ private _syncAutoResize;
17
+ private _updateClearButtonVisibility;
18
+ protected writeValue(value: string): void;
19
+ }
20
+ declare global {
21
+ interface HTMLElementTagNameMap {
22
+ 'ae-textarea': Textarea;
23
+ }
24
+ }
25
+ export default Textarea;
26
+ export type TextareaProps = InferProps<typeof Textarea>;
@@ -0,0 +1,2 @@
1
+ export type TooltipPlacement = 'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'left' | 'right';
2
+ 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,48 @@
1
+ import type { InferProps } from 'aeico';
2
+ import AeicoComponent from '../aeico-component';
3
+ import type { TooltipPlacement, TooltipTrigger } from './defines';
4
+ /**
5
+ * Tooltip Component
6
+ *
7
+ * A floating label that appears on hover or focus around its trigger content.
8
+ * Wrap any element in `<ae-tooltip>` and provide content via the `content`
9
+ * attribute (plain text) or the `tooltip` named slot (rich HTML).
10
+ *
11
+ * @example
12
+ * ```html
13
+ * <ae-tooltip content="Save file">
14
+ * <ae-button>Save</ae-button>
15
+ * </ae-tooltip>
16
+ *
17
+ * <ae-tooltip placement="bottom-start">
18
+ * <span slot="tooltip"><strong>Bold</strong> tip</span>
19
+ * <ae-icon-button name="info"></ae-icon-button>
20
+ * </ae-tooltip>
21
+ * ```
22
+ */
23
+ declare class Tooltip extends AeicoComponent {
24
+ protected static styles: string[];
25
+ accessor content: string | undefined;
26
+ accessor placement: TooltipPlacement;
27
+ accessor disabled: boolean;
28
+ accessor trigger: TooltipTrigger;
29
+ accessor open: boolean;
30
+ private _outsideClickHandler;
31
+ connectedCallback(): void;
32
+ disconnectedCallback(): void;
33
+ private _handleMouseEnter;
34
+ private _handleMouseLeave;
35
+ private _handleFocusin;
36
+ private _handleFocusout;
37
+ private _handleClick;
38
+ private _updatePosition;
39
+ protected onUpdated(changedProps: Map<string, unknown>): void;
40
+ protected render(): import("aeico-view").RenderResult;
41
+ }
42
+ declare global {
43
+ interface HTMLElementTagNameMap {
44
+ 'ae-tooltip': Tooltip;
45
+ }
46
+ }
47
+ export type TooltipProps = InferProps<typeof Tooltip>;
48
+ export default Tooltip;
@@ -0,0 +1,23 @@
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
+ export interface TreeSelectDetail {
10
+ key: string;
11
+ selected: boolean;
12
+ selectedKeys: string[];
13
+ }
14
+ export interface TreeExpandDetail {
15
+ key: string;
16
+ expanded: boolean;
17
+ expandedKeys: string[];
18
+ }
19
+ export interface TreeCheckDetail {
20
+ key: string;
21
+ checked: boolean;
22
+ checkedKeys: string[];
23
+ }
@@ -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';
@@ -0,0 +1,54 @@
1
+ import AeicoComponent from '../aeico-component';
2
+ import type { InferProps } from 'aeico';
3
+ import '../icon';
4
+ /**
5
+ * Tree item — used as a direct child of `<ae-tree>` or nested inside another
6
+ * `<ae-tree-item>` to create a multi-level tree.
7
+ *
8
+ * - **Parent item**: nest `<ae-tree-item>` children inside; an expand toggle is shown.
9
+ * - **Leaf item**: no `<ae-tree-item>` children; no expand toggle is shown.
10
+ *
11
+ * @prop {string} key - Unique identifier for this item.
12
+ * @prop {string} icon - Icon name (uses `<ae-icon>`). Optional.
13
+ * @prop {boolean} disabled - Disables interaction.
14
+ * @prop {boolean} expanded - Whether children are visible.
15
+ * @prop {boolean} selected - Whether this item is visually selected.
16
+ * @prop {boolean} checked - Checkbox state (checkable mode).
17
+ * @prop {boolean} indeterminate - Checkbox partial state (checkable mode, JS-only).
18
+ *
19
+ * @slot default - Child `<ae-tree-item>` elements.
20
+ * @slot label - Custom label content (falls back to the `label` attribute text).
21
+ */
22
+ declare class TreeItem extends AeicoComponent {
23
+ static tagName: string;
24
+ protected static styles: string[];
25
+ accessor key: string | undefined;
26
+ accessor icon: string | undefined;
27
+ /** Stable auto-generated key used when `key` prop is not set. */
28
+ private readonly _autoKey;
29
+ private get _effectiveKey();
30
+ accessor disabled: boolean;
31
+ accessor expanded: boolean;
32
+ accessor selected: boolean;
33
+ accessor checked: boolean;
34
+ accessor indeterminate: boolean;
35
+ private _checkboxEl;
36
+ connectedCallback(): void;
37
+ protected onMounted(): void;
38
+ private get _parentTree();
39
+ private get _isCheckable();
40
+ private get _hasChildren();
41
+ private _handleExpandClick;
42
+ private _handleLabelClick;
43
+ private _handleCheckChange;
44
+ private _handleKeydown;
45
+ protected onUpdated(): void;
46
+ protected render(): import("aeico-view").RenderResult;
47
+ }
48
+ declare global {
49
+ interface HTMLElementTagNameMap {
50
+ 'ae-tree-item': TreeItem;
51
+ }
52
+ }
53
+ export default TreeItem;
54
+ export type TreeItemProps = InferProps<typeof TreeItem>;
@@ -0,0 +1,64 @@
1
+ import AeicoComponent from '../aeico-component';
2
+ import type { InferProps } from 'aeico';
3
+ import './tree-item';
4
+ /**
5
+ * Tree component. Renders a hierarchical tree of `<ae-tree-item>` elements.
6
+ *
7
+ * @prop {boolean} checkable - Enable checkbox selection mode with parent-child sync.
8
+ * @prop {boolean} multiple - Allow multi-select (click to toggle). Ignored when checkable.
9
+ * @prop {boolean} showLine - Show dashed connecting lines between items.
10
+ * @prop {boolean} defaultExpandAll - Expand all items on initial connect.
11
+ * @prop {string} selectedKey - Currently selected key (single-select convenience prop).
12
+ *
13
+ * @property {string[]} selectedKeys - Currently selected keys (multi-select).
14
+ * @property {string[]} checkedKeys - Currently checked keys (checkable mode).
15
+ * @property {string[]} expandedKeys - Currently expanded keys.
16
+ *
17
+ * @event {CustomEvent<TreeSelectDetail>} select - Fires when an item is selected/deselected.
18
+ * @event {CustomEvent<TreeExpandDetail>} expand - Fires when an item is expanded/collapsed.
19
+ * @event {CustomEvent<TreeCheckDetail>} check - Fires when an item checkbox changes.
20
+ *
21
+ * @example
22
+ * ```html
23
+ * <ae-tree>
24
+ * <ae-tree-item key="1" label="Parent">
25
+ * <ae-tree-item key="1-1" label="Child A"></ae-tree-item>
26
+ * <ae-tree-item key="1-2" label="Child B"></ae-tree-item>
27
+ * </ae-tree-item>
28
+ * </ae-tree>
29
+ * ```
30
+ */
31
+ declare class Tree extends AeicoComponent {
32
+ static tagName: string;
33
+ protected static styles: string[];
34
+ accessor checkable: boolean;
35
+ accessor multiple: boolean;
36
+ accessor showLine: boolean;
37
+ accessor defaultExpandAll: boolean;
38
+ accessor selectedKey: string | undefined;
39
+ /** Icon name used for the expand/collapse toggle on all items (overridable per item). */
40
+ accessor icon: string | undefined;
41
+ /** Currently selected keys (multi-select). Set programmatically. */
42
+ selectedKeys: string[];
43
+ /** Currently checked keys (checkable mode). Set programmatically. */
44
+ checkedKeys: string[];
45
+ /** Currently expanded keys. Set programmatically. */
46
+ expandedKeys: string[];
47
+ connectedCallback(): void;
48
+ private _getAllItems;
49
+ private _getDirectChildren;
50
+ private _computeCheckedKeys;
51
+ private _handleItemToggleExpand;
52
+ private _handleItemSelect;
53
+ private _handleItemCheck;
54
+ private _setCheckedRecursive;
55
+ private _syncAncestors;
56
+ protected render(): import("aeico-view").RenderResult;
57
+ }
58
+ declare global {
59
+ interface HTMLElementTagNameMap {
60
+ 'ae-tree': Tree;
61
+ }
62
+ }
63
+ export default Tree;
64
+ export type TreeProps = InferProps<typeof Tree>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aeico-components",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Built-in UI components for the Aeico Web Components framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -24,6 +24,7 @@
24
24
  "src"
25
25
  ],
26
26
  "sideEffects": [
27
+ "./src/icon/built-in-icons.ts",
27
28
  "./dist/*.js",
28
29
  "./dist/*.cjs",
29
30
  "./dist/chunks/*.js",
@@ -49,11 +50,10 @@
49
50
  "components",
50
51
  "aeico"
51
52
  ],
52
- "author": "",
53
- "license": "ISC",
53
+ "author": "Eowl",
54
+ "license": "MIT",
54
55
  "peerDependencies": {
55
- "aeico": "^0.1.5",
56
- "aeico-localize": "^0.1.1"
56
+ "aeico": "^0.1.5"
57
57
  },
58
58
  "devDependencies": {
59
59
  "aeico": "^0.1.5",
@@ -1,10 +1,10 @@
1
1
  import type { InferProps, Props, Watchers } from 'aeico';
2
2
  import { tags } from 'aeico';
3
3
  import AeicoComponent from './aeico-component';
4
- import { t } from 'aeico-localize';
5
4
 
6
5
  export type FieldAction = 'clear' | 'reset' | 'change';
7
6
  export type FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
7
+ export type ActionButtonStyle = 'standalone' | 'integrated';
8
8
 
9
9
  /**
10
10
  * Base class for form field components
@@ -25,10 +25,18 @@ class AeicoField<TValue = string> extends AeicoComponent {
25
25
  defaultValue: { type: String },
26
26
  resettable: { type: Boolean },
27
27
  resetText: { type: String },
28
+ resetTitle: { type: String },
28
29
  clearable: { type: Boolean },
29
30
  clearText: { type: String },
31
+ clearTitle: { type: String },
32
+ actionButtonStyle: { type: String },
30
33
  size: { type: String },
31
34
  disabled: { type: Boolean },
35
+ label: { type: String },
36
+ labelPlacement: { type: String },
37
+ required: { type: Boolean },
38
+ helperText: { type: String },
39
+ error: { type: String },
32
40
  };
33
41
 
34
42
  /**
@@ -36,8 +44,17 @@ class AeicoField<TValue = string> extends AeicoComponent {
36
44
  */
37
45
  static watchers: Watchers = {
38
46
  disabled: 'onDisabledChanged',
47
+ error: 'onErrorChanged',
39
48
  };
40
49
 
50
+ private static _fieldIdCounter = 0;
51
+ private readonly _fieldId: string;
52
+
53
+ constructor() {
54
+ super();
55
+ this._fieldId = `ae-field-${++AeicoField._fieldIdCounter}`;
56
+ }
57
+
41
58
  /**
42
59
  * The underlying form control element (input, select, etc.)
43
60
  * Subclasses should set this to their specific element
@@ -58,10 +75,18 @@ class AeicoField<TValue = string> extends AeicoComponent {
58
75
  declare defaultValue?: TValue | string;
59
76
  declare resettable?: boolean;
60
77
  declare resetText?: string;
78
+ declare resetTitle?: string;
61
79
  declare clearable?: boolean;
62
80
  declare clearText?: string;
81
+ declare clearTitle?: string;
82
+ declare actionButtonStyle?: ActionButtonStyle;
63
83
  declare size?: string;
64
84
  declare disabled?: boolean;
85
+ declare label?: string;
86
+ declare labelPlacement?: 'top' | 'left';
87
+ declare required?: boolean;
88
+ declare helperText?: string;
89
+ declare error?: string;
65
90
 
66
91
  /**
67
92
  * Lifecycle: Component connected to DOM
@@ -82,18 +107,30 @@ class AeicoField<TValue = string> extends AeicoComponent {
82
107
  * Must be called from within a build() callback.
83
108
  */
84
109
  protected renderActionButtons(force: boolean = false) {
85
- this.renderClearButton(force);
86
- this.renderResetButton(force);
110
+ const style = this.actionButtonStyle || 'integrated';
111
+ const hasActions = force || this.clearable || this.resettable;
112
+
113
+ if (hasActions && style === 'integrated') {
114
+ tags.div({ className: 'action-controls' }, () => {
115
+ this.renderClearButton(force);
116
+ this.renderResetButton(force);
117
+ });
118
+ } else {
119
+ this.renderClearButton(force);
120
+ this.renderResetButton(force);
121
+ }
87
122
  }
88
123
 
89
124
  protected renderResetButton(force: boolean = false) {
90
125
  const { button } = tags;
126
+ const style = this.actionButtonStyle || 'integrated';
91
127
 
92
128
  if (force || this.resettable) {
129
+ const className = style === 'integrated' ? 'reset-btn action-btn' : 'reset-btn';
93
130
  this.resetBtn = button({
94
- className: 'reset-btn',
131
+ className,
95
132
  textContent: this.resetText || '↺',
96
- title: t('buttons.reset', '↺'),
133
+ title: this.resetTitle || '↺',
97
134
  '@click': this.boundOnReset,
98
135
  });
99
136
  }
@@ -101,17 +138,63 @@ class AeicoField<TValue = string> extends AeicoComponent {
101
138
 
102
139
  protected renderClearButton(force: boolean = false) {
103
140
  const { button } = tags;
141
+ const style = this.actionButtonStyle || 'integrated';
104
142
 
105
143
  if (force || this.clearable) {
144
+ const className = style === 'integrated' ? 'clear-btn action-btn' : 'clear-btn';
106
145
  this.clearBtn = button({
107
- className: 'clear-btn',
146
+ className,
108
147
  textContent: this.clearText || '✕',
109
- title: t('buttons.clear', '✕'),
148
+ title: this.clearTitle || '✕',
110
149
  '@click': this.boundOnClear,
111
150
  });
112
151
  }
113
152
  }
114
153
 
154
+ /**
155
+ * Returns a stable unique ID for this field instance,
156
+ * used to associate <label htmlFor> with the underlying input.
157
+ */
158
+ protected getFieldId(): string {
159
+ return this._fieldId;
160
+ }
161
+
162
+ /**
163
+ * Renders a <label> element when the `label` prop is set.
164
+ * Call this as the first statement inside the render() html() callback.
165
+ * @param fieldId - The id to set on the underlying form control element (pass to input via id prop)
166
+ */
167
+ protected renderLabel(fieldId: string): void {
168
+ if (!this.label) return;
169
+ const { span } = tags;
170
+ tags.label({ id: `${fieldId}-label`, className: 'field-label', for: fieldId }, () => {
171
+ span({ textContent: this.label! });
172
+ if (this.required) {
173
+ span({ className: 'field-required', 'aria-hidden': 'true', textContent: ' *' });
174
+ }
175
+ });
176
+ }
177
+
178
+ /**
179
+ * Renders helper text below the field. Hidden when `error` is set.
180
+ * Call this after the field-body div in render().
181
+ */
182
+ protected renderHelperText(): void {
183
+ if (!this.helperText || this.error) return;
184
+ const { span } = tags;
185
+ span({ className: 'field-helper', textContent: this.helperText });
186
+ }
187
+
188
+ /**
189
+ * Renders an error message below the field when `error` is set.
190
+ * Call this after renderHelperText() in render().
191
+ */
192
+ protected renderError(): void {
193
+ if (!this.error) return;
194
+ const { span } = tags;
195
+ span({ className: 'field-error', textContent: this.error });
196
+ }
197
+
115
198
  /**
116
199
  * Watcher for disabled property
117
200
  */
@@ -121,6 +204,58 @@ class AeicoField<TValue = string> extends AeicoComponent {
121
204
  }
122
205
  }
123
206
 
207
+ /**
208
+ * Watcher for error property — syncs aria-invalid on the field element
209
+ */
210
+ protected onErrorChanged(newValue: string | undefined): void {
211
+ if (this.fieldElement) {
212
+ if (newValue) {
213
+ this.fieldElement.setAttribute('aria-invalid', 'true');
214
+ } else {
215
+ this.fieldElement.removeAttribute('aria-invalid');
216
+ }
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Lifecycle: called after every render update.
222
+ * Keeps aria-invalid on fieldElement in sync regardless of watcher timing.
223
+ */
224
+ protected onUpdated(_changedProps: Map<string, unknown>): void {
225
+ if (!this.fieldElement) return;
226
+ if (this.error) {
227
+ this.fieldElement.setAttribute('aria-invalid', 'true');
228
+ } else {
229
+ this.fieldElement.removeAttribute('aria-invalid');
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Returns true if the field passes constraint validation.
235
+ * Delegates to the underlying fieldElement when available;
236
+ * falls back to a manual required-check otherwise.
237
+ */
238
+ public checkValidity(): boolean {
239
+ if (this.fieldElement) {
240
+ return this.fieldElement.checkValidity();
241
+ }
242
+ if (this.required) {
243
+ const v = this.value;
244
+ return v !== undefined && v !== '' && v !== null;
245
+ }
246
+ return true;
247
+ }
248
+
249
+ /**
250
+ * Reports validity, showing the browser's built-in validation UI when possible.
251
+ */
252
+ public reportValidity(): boolean {
253
+ if (this.fieldElement) {
254
+ return this.fieldElement.reportValidity();
255
+ }
256
+ return this.checkValidity();
257
+ }
258
+
124
259
  /**
125
260
  * Render the field component
126
261
  * Override in subclass to provide custom rendering
@@ -4,7 +4,6 @@ import colorCSS from '../styles/color.css?inline';
4
4
  import alertStyle from '../styles/components/alert.css?inline';
5
5
  import AeicoComponent from '../aeico-component';
6
6
  import { html } from 'aeico';
7
- import { t } from 'aeico-localize';
8
7
  import type { AlertColor, AlertSize, AlertVariant } from './defines';
9
8
 
10
9
  /**
@@ -39,6 +38,7 @@ class Alert extends AeicoComponent {
39
38
  size: { type: String },
40
39
  dismissible: { type: Boolean },
41
40
  invisible: { type: Boolean },
41
+ closeText: { type: String },
42
42
  };
43
43
 
44
44
  protected static useStyles = ['alert'];
@@ -49,6 +49,7 @@ class Alert extends AeicoComponent {
49
49
  declare size?: AlertSize;
50
50
  declare dismissible?: boolean;
51
51
  declare invisible?: boolean;
52
+ declare closeText?: string;
52
53
 
53
54
  protected render() {
54
55
  return html(({ div, slot, button, span }) => {
@@ -67,7 +68,7 @@ class Alert extends AeicoComponent {
67
68
  {
68
69
  className: 'alert-close',
69
70
  '@click': () => this._handleClose(),
70
- title: t('alert.close', 'Close alert'),
71
+ title: this.closeText || 'Close alert',
71
72
  },
72
73
  () => {
73
74
  span({ 'aria-hidden': 'true', textContent: '\u00d7' });
@@ -4,6 +4,8 @@ import { html } from 'aeico';
4
4
  import styleVariables from '../styles/variables.css?inline';
5
5
  import sizeCSS from '../styles/size.css?inline';
6
6
  import colorCSS from '../styles/color.css?inline';
7
+ import fieldLabelCSS from '../styles/components/field-label.css?inline';
8
+ import actionButtonCSS from '../styles/components/action-button.css?inline';
7
9
  import styles from '../styles/components/checkbox.css?inline';
8
10
  import { CheckboxVariant } from './defines';
9
11
 
@@ -22,7 +24,14 @@ class Checkbox extends AeicoField<boolean> {
22
24
  declare defaultChecked?: boolean;
23
25
  declare variant?: CheckboxVariant;
24
26
 
25
- protected static styles = [styleVariables, sizeCSS, colorCSS, styles];
27
+ protected static styles = [
28
+ styleVariables,
29
+ sizeCSS,
30
+ colorCSS,
31
+ fieldLabelCSS,
32
+ actionButtonCSS,
33
+ styles,
34
+ ];
26
35
 
27
36
  protected getValue(): boolean {
28
37
  return this.fieldElement?.checked ?? false;
@@ -62,18 +71,24 @@ class Checkbox extends AeicoField<boolean> {
62
71
 
63
72
  render() {
64
73
  return html(({ div, input }) => {
65
- div({ className: 'checkbox-container', variant: this.variant }, () => {
74
+ const id = this.getFieldId();
75
+ this.renderLabel(id);
76
+ div({ className: 'checkbox-container field-body', variant: this.variant }, () => {
66
77
  div({ className: 'checkbox-wrapper' }, () => {
67
78
  this.fieldElement = input({
79
+ id,
68
80
  type: 'checkbox',
69
81
  className: 'field-input',
70
82
  checked: Boolean(this.checked),
71
83
  disabled: Boolean(this.disabled),
84
+ required: Boolean(this.required),
72
85
  '@change': this.boundOnChange,
73
86
  });
74
87
  });
75
88
  this.renderActionButtons();
76
89
  });
90
+ this.renderHelperText();
91
+ this.renderError();
77
92
  });
78
93
  }
79
94
  }