mtrl 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/index.ts +2 -0
  2. package/package.json +14 -3
  3. package/src/components/badge/api.ts +23 -14
  4. package/src/components/badge/badge.ts +2 -2
  5. package/src/components/badge/config.ts +10 -11
  6. package/src/components/badge/features.ts +15 -10
  7. package/src/components/badge/index.ts +27 -2
  8. package/src/components/badge/types.ts +28 -8
  9. package/src/components/bottom-app-bar/bottom-app-bar.ts +2 -44
  10. package/src/components/bottom-app-bar/config.ts +1 -45
  11. package/src/components/bottom-app-bar/index.ts +7 -1
  12. package/src/components/bottom-app-bar/types.ts +7 -1
  13. package/src/components/button/button.ts +0 -1
  14. package/src/components/button/config.ts +1 -2
  15. package/src/components/button/index.ts +10 -2
  16. package/src/components/button/types.ts +14 -2
  17. package/src/components/card/config.ts +17 -9
  18. package/src/components/card/content.ts +8 -10
  19. package/src/components/card/features.ts +4 -6
  20. package/src/components/card/index.ts +29 -2
  21. package/src/components/card/types.ts +6 -23
  22. package/src/components/checkbox/config.ts +3 -4
  23. package/src/components/checkbox/index.ts +1 -2
  24. package/src/components/checkbox/types.ts +12 -3
  25. package/src/components/chip/api.ts +170 -221
  26. package/src/components/chip/chip.ts +34 -302
  27. package/src/components/chip/config.ts +1 -2
  28. package/src/components/chip/index.ts +10 -2
  29. package/src/components/chip/types.ts +224 -35
  30. package/src/components/datepicker/api.ts +18 -25
  31. package/src/components/datepicker/config.ts +9 -12
  32. package/src/components/datepicker/datepicker.ts +7 -12
  33. package/src/components/datepicker/index.ts +10 -7
  34. package/src/components/datepicker/render.ts +16 -18
  35. package/src/components/datepicker/types.ts +164 -35
  36. package/src/components/datepicker/utils.ts +1 -2
  37. package/src/components/dialog/api.ts +7 -8
  38. package/src/components/dialog/config.ts +3 -4
  39. package/src/components/dialog/features.ts +56 -22
  40. package/src/components/dialog/index.ts +38 -8
  41. package/src/components/dialog/types.ts +33 -10
  42. package/src/components/divider/index.ts +5 -1
  43. package/src/components/extended-fab/config.ts +6 -2
  44. package/src/components/extended-fab/index.ts +7 -2
  45. package/src/components/extended-fab/types.ts +21 -4
  46. package/src/components/fab/config.ts +3 -4
  47. package/src/components/fab/fab.ts +1 -1
  48. package/src/components/fab/index.ts +7 -2
  49. package/src/components/fab/types.ts +21 -4
  50. package/src/components/list/config.ts +4 -5
  51. package/src/components/list/features.ts +6 -7
  52. package/src/components/list/index.ts +7 -9
  53. package/src/components/list/list-item.ts +12 -13
  54. package/src/components/list/types.ts +50 -5
  55. package/src/components/list/utils.ts +30 -3
  56. package/src/components/menu/features/items-manager.ts +9 -9
  57. package/src/components/menu/features/positioning.ts +7 -7
  58. package/src/components/menu/features/visibility.ts +7 -7
  59. package/src/components/menu/index.ts +7 -9
  60. package/src/components/menu/menu-item.ts +6 -6
  61. package/src/components/menu/menu.ts +22 -0
  62. package/src/components/menu/types.ts +29 -10
  63. package/src/components/menu/utils.ts +67 -0
  64. package/src/components/navigation/api.ts +131 -96
  65. package/src/components/navigation/config.ts +22 -10
  66. package/src/components/navigation/features/controller.ts +273 -0
  67. package/src/components/navigation/features/items.ts +160 -87
  68. package/src/components/navigation/index.ts +0 -6
  69. package/src/components/navigation/nav-item.ts +12 -24
  70. package/src/components/navigation/navigation.ts +21 -8
  71. package/src/components/navigation/system-types.ts +124 -0
  72. package/src/components/navigation/system.ts +776 -0
  73. package/src/components/navigation/types.ts +228 -203
  74. package/src/components/progress/api.ts +2 -3
  75. package/src/components/progress/config.ts +2 -3
  76. package/src/components/progress/index.ts +0 -1
  77. package/src/components/progress/progress.ts +1 -2
  78. package/src/components/progress/types.ts +186 -33
  79. package/src/components/radios/config.ts +1 -1
  80. package/src/components/radios/index.ts +0 -1
  81. package/src/components/radios/types.ts +0 -7
  82. package/src/components/search/config.ts +1 -2
  83. package/src/components/search/features/search.ts +14 -15
  84. package/src/components/search/features/states.ts +5 -1
  85. package/src/components/search/features/structure.ts +3 -4
  86. package/src/components/search/index.ts +0 -3
  87. package/src/components/search/types.ts +18 -6
  88. package/src/components/segmented-button/config.ts +20 -7
  89. package/src/components/segmented-button/segment.ts +6 -7
  90. package/src/components/segmented-button/segmented-button.ts +4 -5
  91. package/src/components/segmented-button/types.ts +37 -2
  92. package/src/components/slider/config.ts +20 -2
  93. package/src/components/slider/features/controller.ts +761 -0
  94. package/src/components/slider/features/handlers.ts +18 -15
  95. package/src/components/slider/features/index.ts +3 -2
  96. package/src/components/slider/features/range.ts +104 -0
  97. package/src/components/slider/slider.ts +34 -14
  98. package/src/components/slider/structure.ts +152 -0
  99. package/src/components/slider/types.ts +34 -8
  100. package/src/components/snackbar/config.ts +2 -3
  101. package/src/components/snackbar/constants.ts +0 -32
  102. package/src/components/snackbar/index.ts +0 -1
  103. package/src/components/snackbar/position.ts +9 -1
  104. package/src/components/snackbar/types.ts +122 -46
  105. package/src/components/switch/config.ts +2 -3
  106. package/src/components/switch/index.ts +0 -1
  107. package/src/components/switch/types.ts +3 -2
  108. package/src/components/tabs/config.ts +3 -4
  109. package/src/components/tabs/index.ts +0 -15
  110. package/src/components/tabs/tab-api.ts +12 -4
  111. package/src/components/tabs/tab.ts +18 -6
  112. package/src/components/tabs/types.ts +13 -3
  113. package/src/components/textfield/api.ts +53 -0
  114. package/src/components/textfield/config.ts +2 -3
  115. package/src/components/textfield/features.ts +322 -0
  116. package/src/components/textfield/index.ts +0 -1
  117. package/src/components/textfield/textfield.ts +8 -0
  118. package/src/components/textfield/types.ts +29 -6
  119. package/src/components/timepicker/api.ts +1 -1
  120. package/src/components/timepicker/clockdial.ts +2 -5
  121. package/src/components/timepicker/config.ts +102 -4
  122. package/src/components/timepicker/index.ts +1 -6
  123. package/src/components/timepicker/render.ts +1 -1
  124. package/src/components/timepicker/timepicker.ts +1 -1
  125. package/src/components/tooltip/api.ts +1 -1
  126. package/src/components/tooltip/config.ts +27 -6
  127. package/src/components/tooltip/index.ts +0 -1
  128. package/src/components/tooltip/types.ts +13 -3
  129. package/src/core/compose/features/textinput.ts +15 -2
  130. package/src/core/compose/features/textlabel.ts +0 -3
  131. package/src/core/composition/features/dom.ts +33 -0
  132. package/src/core/composition/features/icon.ts +131 -0
  133. package/src/core/composition/features/index.ts +11 -0
  134. package/src/core/composition/features/label.ts +156 -0
  135. package/src/core/composition/features/structure.ts +22 -0
  136. package/src/core/composition/index.ts +26 -0
  137. package/src/core/index.ts +1 -1
  138. package/src/core/structure.ts +288 -0
  139. package/src/index.ts +1 -0
  140. package/src/styles/components/_navigation-mobile.scss +244 -0
  141. package/src/styles/components/_navigation-system.scss +151 -0
  142. package/src/{components/tabs/_styles.scss → styles/components/_tabs.scss} +1 -1
  143. package/src/{components/textfield/_styles.scss → styles/components/_textfield.scss} +314 -72
  144. package/src/styles/main.scss +98 -49
  145. package/src/components/badge/constants.ts +0 -40
  146. package/src/components/button/constants.ts +0 -11
  147. package/src/components/card/constants.ts +0 -84
  148. package/src/components/datepicker/constants.ts +0 -98
  149. package/src/components/dialog/constants.ts +0 -32
  150. package/src/components/extended-fab/constants.ts +0 -36
  151. package/src/components/fab/constants.ts +0 -41
  152. package/src/components/menu/constants.ts +0 -154
  153. package/src/components/navigation/constants.ts +0 -200
  154. package/src/components/progress/constants.ts +0 -29
  155. package/src/components/search/constants.ts +0 -21
  156. package/src/components/segmented-button/constants.ts +0 -42
  157. package/src/components/slider/features/slider.ts +0 -318
  158. package/src/components/slider/features/structure.ts +0 -181
  159. package/src/components/slider/features/ui.ts +0 -388
  160. package/src/components/switch/constants.ts +0 -80
  161. package/src/components/tabs/constants.ts +0 -89
  162. package/src/components/textfield/constants.ts +0 -100
  163. package/src/components/timepicker/constants.ts +0 -138
  164. /package/src/{components/badge/_styles.scss → styles/components/_badge.scss} +0 -0
  165. /package/src/{components/bottom-app-bar/_styles.scss → styles/components/_bottom-app-bar.scss} +0 -0
  166. /package/src/{components/button/_styles.scss → styles/components/_button.scss} +0 -0
  167. /package/src/{components/card/_styles.scss → styles/components/_card.scss} +0 -0
  168. /package/src/{components/carousel/_styles.scss → styles/components/_carousel.scss} +0 -0
  169. /package/src/{components/checkbox/_styles.scss → styles/components/_checkbox.scss} +0 -0
  170. /package/src/{components/chip/_styles.scss → styles/components/_chip.scss} +0 -0
  171. /package/src/{components/datepicker/_styles.scss → styles/components/_datepicker.scss} +0 -0
  172. /package/src/{components/dialog/_styles.scss → styles/components/_dialog.scss} +0 -0
  173. /package/src/{components/divider/_styles.scss → styles/components/_divider.scss} +0 -0
  174. /package/src/{components/extended-fab/_styles.scss → styles/components/_extended-fab.scss} +0 -0
  175. /package/src/{components/fab/_styles.scss → styles/components/_fab.scss} +0 -0
  176. /package/src/{components/list/_styles.scss → styles/components/_list.scss} +0 -0
  177. /package/src/{components/menu/_styles.scss → styles/components/_menu.scss} +0 -0
  178. /package/src/{components/navigation/_styles.scss → styles/components/_navigation.scss} +0 -0
  179. /package/src/{components/progress/_styles.scss → styles/components/_progress.scss} +0 -0
  180. /package/src/{components/radios/_styles.scss → styles/components/_radios.scss} +0 -0
  181. /package/src/{components/search/_styles.scss → styles/components/_search.scss} +0 -0
  182. /package/src/{components/segmented-button/_styles.scss → styles/components/_segmented-button.scss} +0 -0
  183. /package/src/{components/sheet/_styles.scss → styles/components/_sheet.scss} +0 -0
  184. /package/src/{components/slider/_styles.scss → styles/components/_slider.scss} +0 -0
  185. /package/src/{components/snackbar/_styles.scss → styles/components/_snackbar.scss} +0 -0
  186. /package/src/{components/switch/_styles.scss → styles/components/_switch.scss} +0 -0
  187. /package/src/{components/timepicker/_styles.scss → styles/components/_timepicker.scss} +0 -0
  188. /package/src/{components/tooltip/_styles.scss → styles/components/_tooltip.scss} +0 -0
  189. /package/src/{components/top-app-bar/_styles.scss → styles/components/_top-app-bar.scss} +0 -0
  190. /package/src/styles/utilities/{_color.scss → _colors.scss} +0 -0
@@ -112,14 +112,14 @@ export interface TextInputComponent extends ElementComponent {
112
112
  */
113
113
  export const withTextInput = <T extends TextInputConfig>(config: T = {} as T) =>
114
114
  <C extends ElementComponent>(component: C): C & TextInputComponent => {
115
- const input = document.createElement(config.multiline ? 'textarea' : 'input') as
115
+ const isMultiline = config.multiline || config.type === 'multiline';
116
+ const input = document.createElement(isMultiline ? 'textarea' : 'input') as
116
117
  HTMLInputElement | HTMLTextAreaElement;
117
118
 
118
119
  input.className = `${component.getClass('textfield')}-input`;
119
120
 
120
121
  // Set input attributes
121
122
  const attributes: Record<string, string | number | boolean | undefined> = {
122
- type: config.multiline ? undefined : (config.type || 'text'),
123
123
  name: config.name,
124
124
  required: config.required,
125
125
  disabled: config.disabled,
@@ -129,6 +129,14 @@ export const withTextInput = <T extends TextInputConfig>(config: T = {} as T) =>
129
129
  value: config.value || ''
130
130
  };
131
131
 
132
+ // Only set type attribute for input elements, not for textarea
133
+ if (!isMultiline) {
134
+ attributes.type = config.type || 'text';
135
+ } else {
136
+ // For textarea, add a data attribute to identify it as multiline
137
+ attributes['data-type'] = 'multiline';
138
+ }
139
+
132
140
  Object.entries(attributes).forEach(([key, value]) => {
133
141
  if (value !== null && value !== undefined) {
134
142
  if (typeof value === 'boolean') {
@@ -188,6 +196,11 @@ export const withTextInput = <T extends TextInputConfig>(config: T = {} as T) =>
188
196
  // Initial state
189
197
  updateInputState();
190
198
 
199
+ // Add multiline class to the component if it's a textarea
200
+ if (isMultiline) {
201
+ component.element.classList.add(`${component.getClass('textfield')}--multiline`);
202
+ }
203
+
191
204
  component.element.appendChild(input);
192
205
 
193
206
  // Cleanup
@@ -89,9 +89,6 @@ export const withTextLabel = <T extends TextLabelConfig>(config: T = {} as T) =>
89
89
  component.element.appendChild(labelElement);
90
90
  }
91
91
 
92
- console.log('componentName', component.componentName)
93
- console.log('position', position)
94
-
95
92
  if (position && component.componentName !== 'slider') {
96
93
  component.element.classList.add(`${config.prefix}-${config.componentName}--label-${position}`);
97
94
  }
@@ -0,0 +1,33 @@
1
+ // src/core/composition/features/dom.ts
2
+ import { createStructure, flattenStructure } from '../../structure';
3
+
4
+ /**
5
+ * Creates DOM elements from structure definition using the core createStructure utility
6
+ * This is a key feature that bridges the gap between declarative structure and actual DOM
7
+ *
8
+ * @returns Component enhancer that creates DOM structure
9
+ */
10
+ export const withDom = () => component => {
11
+ // Return unmodified component if no structure definition
12
+ if (!component.structureDefinition) {
13
+ return component;
14
+ }
15
+
16
+ try {
17
+ // Use the existing createStructure function to build the DOM
18
+ const structure = createStructure(component.structureDefinition);
19
+
20
+ // Use the existing flattenStructure function to create a flat reference map
21
+ const components = structure.getAll();
22
+
23
+ // Return enhanced component with DOM structure
24
+ return {
25
+ ...component,
26
+ element: structure.element, // Root element
27
+ components // All component elements
28
+ };
29
+ } catch (error) {
30
+ console.error('Failed to create DOM structure:', error);
31
+ throw new Error(`Failed to create slider DOM: ${error.message}`);
32
+ }
33
+ };
@@ -0,0 +1,131 @@
1
+ // src/core/composition/features/icon.ts
2
+ import { createElement } from '../../dom/create';
3
+
4
+ /**
5
+ * Configuration for icon feature
6
+ */
7
+ export interface IconConfig {
8
+ /**
9
+ * Icon HTML content
10
+ */
11
+ icon?: string;
12
+
13
+ /**
14
+ * Position of the icon ('start' or 'end')
15
+ */
16
+ iconPosition?: 'start' | 'end';
17
+
18
+ /**
19
+ * Size variant for the icon
20
+ */
21
+ iconSize?: string;
22
+
23
+ /**
24
+ * CSS class prefix
25
+ */
26
+ prefix?: string;
27
+
28
+ /**
29
+ * Component name for class generation
30
+ */
31
+ componentName?: string;
32
+
33
+ [key: string]: any;
34
+ }
35
+
36
+ /**
37
+ * Enhances structure definition with an icon element
38
+ * Unlike the traditional withIcon, this modifies the structure definition
39
+ * without creating actual DOM elements.
40
+ *
41
+ * @param config Configuration containing icon information
42
+ * @returns Component enhancer that adds icon to structure definition
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * // Add icon to a structure definition
47
+ * const component = pipe(
48
+ * createBase,
49
+ * withStructure(config),
50
+ * withIcon(config)
51
+ * )(config);
52
+ * ```
53
+ */
54
+ export const withIcon = (config: IconConfig) => component => {
55
+ // If no icon or missing structure definition, return unmodified
56
+ if (!config.icon || !component.structureDefinition) {
57
+ return component;
58
+ }
59
+
60
+ try {
61
+ // Get component details for class names
62
+ const prefix = config.prefix || component.config?.prefix || 'mtrl';
63
+ const componentName = config.componentName || component.componentName || 'component';
64
+
65
+ // Clone the structure definition
66
+ const structureDefinition = JSON.parse(JSON.stringify(component.structureDefinition));
67
+
68
+ // Determine icon position
69
+ const position = config.iconPosition || 'start';
70
+
71
+ // Add the --icon modifier class to the main element
72
+ const elementClasses = structureDefinition.element.options.className || [];
73
+ const iconModifierClass = `${prefix}-${componentName}--icon`;
74
+
75
+ if (Array.isArray(elementClasses)) {
76
+ if (!elementClasses.includes(iconModifierClass)) {
77
+ elementClasses.push(iconModifierClass);
78
+ }
79
+ } else if (typeof elementClasses === 'string') {
80
+ if (!elementClasses.includes(iconModifierClass)) {
81
+ structureDefinition.element.options.className = `${elementClasses} ${iconModifierClass}`.trim();
82
+ }
83
+ } else {
84
+ structureDefinition.element.options.className = [iconModifierClass];
85
+ }
86
+
87
+ // Create icon element definition with component-specific class
88
+ const iconDef = {
89
+ name: 'icon',
90
+ creator: createElement,
91
+ options: {
92
+ tag: 'span',
93
+ className: [
94
+ `${prefix}-${componentName}-icon`,
95
+ `${prefix}-${componentName}-icon--${position}`
96
+ ],
97
+ html: config.icon
98
+ }
99
+ };
100
+
101
+ // Add size class if specified
102
+ if (config.iconSize) {
103
+ const classes = iconDef.options.className;
104
+ if (Array.isArray(classes)) {
105
+ classes.push(`${prefix}-${componentName}-icon--${config.iconSize}`);
106
+ }
107
+ }
108
+
109
+ // Add icon directly to the main element's children
110
+ if (position === 'start') {
111
+ // Create new children object with icon first
112
+ const existingChildren = { ...structureDefinition.element.children };
113
+ structureDefinition.element.children = {
114
+ icon: iconDef,
115
+ ...existingChildren
116
+ };
117
+ } else {
118
+ // Add icon after existing children
119
+ structureDefinition.element.children.icon = iconDef;
120
+ }
121
+
122
+ // Return component with updated structure definition
123
+ return {
124
+ ...component,
125
+ structureDefinition
126
+ };
127
+ } catch (error) {
128
+ console.warn('Error enhancing structure with icon:', error);
129
+ return component;
130
+ }
131
+ };
@@ -0,0 +1,11 @@
1
+ // src/core/composition/features/index.ts
2
+
3
+ // Export composition features
4
+ export { withIcon } from './icon';
5
+ export { withLabel } from './label';
6
+ export { withDom } from './dom';
7
+ export { withStructure } from './structure';
8
+
9
+ // Re-export interface types for better developer experience
10
+ export type { IconConfig } from './icon';
11
+ export type { LabelConfig } from './label';
@@ -0,0 +1,156 @@
1
+ // src/core/composition/features/label.ts
2
+ import { createElement } from '../../dom/create';
3
+
4
+ /**
5
+ * Configuration for label feature
6
+ */
7
+ export interface LabelConfig {
8
+ /**
9
+ * Label text content
10
+ */
11
+ label?: string;
12
+
13
+ /**
14
+ * Position of the label ('start', 'end', 'top', or 'bottom')
15
+ */
16
+ labelPosition?: 'start' | 'end' | 'top' | 'bottom';
17
+
18
+ /**
19
+ * CSS class prefix
20
+ */
21
+ prefix?: string;
22
+
23
+ /**
24
+ * Component name for class generation
25
+ */
26
+ componentName?: string;
27
+
28
+ /**
29
+ * ID for the input element this label is associated with
30
+ */
31
+ id?: string;
32
+
33
+ /**
34
+ * Whether the labeled element is required
35
+ */
36
+ required?: boolean;
37
+
38
+ [key: string]: any;
39
+ }
40
+
41
+ /**
42
+ * Enhances structure definition with a label element
43
+ * Unlike the traditional withLabel, this modifies the structure definition
44
+ * without creating actual DOM elements.
45
+ *
46
+ * @param config Configuration containing label information
47
+ * @returns Component enhancer that adds label to structure definition
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * // Add label to a structure definition
52
+ * const component = pipe(
53
+ * createBase,
54
+ * withStructure(config),
55
+ * withLabel(config)
56
+ * )(config);
57
+ * ```
58
+ */
59
+ export const withLabel = (config: LabelConfig) => component => {
60
+ // If no label or missing structure definition, return unmodified
61
+
62
+ if (!config.label || !component.structureDefinition) {
63
+ return component;
64
+ }
65
+
66
+ try {
67
+ // Get class name generator
68
+ const getClass = (className) => {
69
+ if (typeof component.getClass === 'function') {
70
+ return component.getClass(className);
71
+ }
72
+ const prefix = config.prefix || 'mtrl';
73
+ return `${prefix}-${className}`;
74
+ };
75
+
76
+ // Get component details
77
+ const prefix = config.prefix || component.config?.prefix || 'mtrl';
78
+ const componentName = config.componentName || component.componentName || 'component';
79
+
80
+ // Clone the structure definition
81
+ const structureDefinition = JSON.parse(JSON.stringify(component.structureDefinition));
82
+
83
+ // Determine position (default to 'start')
84
+ const position = config.labelPosition || 'start';
85
+
86
+ // Create the label element definition
87
+ let labelContent = config.label;
88
+ let labelChildren = null;
89
+
90
+ // Add required indicator if specified
91
+ if (config.required) {
92
+ // For structure definition we need to define a child element
93
+ labelChildren = {
94
+ requiredIndicator: {
95
+ name: 'requiredIndicator',
96
+ creator: createElement,
97
+ options: {
98
+ tag: 'span',
99
+ className: `${prefix}-${componentName}-label-required`,
100
+ text: '*',
101
+ attrs: {
102
+ 'aria-hidden': 'true'
103
+ }
104
+ }
105
+ }
106
+ };
107
+
108
+ // Clear the content since we'll use children instead
109
+ labelContent = config.label;
110
+ }
111
+
112
+ // Create label element definition
113
+ const labelDef = {
114
+ name: 'label',
115
+ creator: createElement,
116
+ options: {
117
+ tag: 'label',
118
+ className: [
119
+ `${prefix}-${componentName}-label`,
120
+ `${prefix}-${componentName}-label--${position}`
121
+ ],
122
+ attrs: {
123
+ 'for': config.id // Optional connection to input by ID
124
+ },
125
+ text: labelContent
126
+ }
127
+ };
128
+
129
+ // Add children if we have them
130
+ if (labelChildren) {
131
+ labelDef.children = labelChildren;
132
+ }
133
+
134
+ // Add label to root element's children
135
+ if (position === 'end' || position === 'bottom') {
136
+ // Add at end of root element
137
+ structureDefinition.element.children.label = labelDef;
138
+ } else {
139
+ // Add at beginning of root element (start/top)
140
+ const existingChildren = { ...structureDefinition.element.children };
141
+ structureDefinition.element.children = {
142
+ label: labelDef,
143
+ ...existingChildren
144
+ };
145
+ }
146
+
147
+ // Return component with updated structure definition
148
+ return {
149
+ ...component,
150
+ structureDefinition
151
+ };
152
+ } catch (error) {
153
+ console.warn('Error enhancing structure with label:', error);
154
+ return component;
155
+ }
156
+ };
@@ -0,0 +1,22 @@
1
+ // src/core/composition/features/structure.ts
2
+
3
+ /**
4
+ * Adds structure definition to component without creating DOM
5
+ * Now uses the structure from the baseConfig
6
+ *
7
+ * @param configuration
8
+ * @returns Component enhancer with structure definition
9
+ */
10
+ export const withStructure = (config: SliderConfig) => component => {
11
+ // Use the structure definition from the config
12
+ if (!config.structureDefinition) {
13
+ console.warn('No structure definition found in slider config');
14
+ return component;
15
+ }
16
+
17
+ // Return enhanced component with structure definition
18
+ return {
19
+ ...component,
20
+ structureDefinition: config.structureDefinition
21
+ };
22
+ };
@@ -0,0 +1,26 @@
1
+ // src/core/composition/index.ts
2
+
3
+ /**
4
+ * @module core/composition
5
+ * @description Composition utilities for creating components using the structure-based approach
6
+ *
7
+ * The composition module provides features that work with the structure definition
8
+ * mechanism. Unlike traditional features that directly modify the DOM, these
9
+ * features modify a structure definition that is later used to create DOM elements.
10
+ *
11
+ * This approach provides several advantages:
12
+ * - Clearer separation between structure definition and DOM creation
13
+ * - More predictable component creation process
14
+ * - Better support for server-side rendering
15
+ * - Enhanced testability
16
+ */
17
+
18
+ // Export features
19
+ export {
20
+ withStructure
21
+ withDom
22
+ withIcon,
23
+ withLabel,
24
+ } from './features';
25
+
26
+ export type { IconConfig, LabelConfig } from './features';
package/src/core/index.ts CHANGED
@@ -11,7 +11,7 @@ export type {
11
11
  ComponentConfig,
12
12
  ThemedComponentConfig,
13
13
  VariantComponentConfig,
14
- StateComponentConfig
14
+ StateComponentConfig
15
15
  } from './config';
16
16
 
17
17
  // Build