@app-studio/web 0.9.80 → 0.9.82

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 (37) hide show
  1. package/dist/components/Accordion/Accordion/Accordion.type.d.ts +1 -1
  2. package/dist/components/Accordion/Accordion/Accordion.view.d.ts +1 -1
  3. package/dist/components/Badge/Badge/Badge.type.d.ts +1 -1
  4. package/dist/components/Card/Card/Card.type.d.ts +1 -1
  5. package/dist/components/ChatInput/ChatInput/ChatInput.type.d.ts +1 -1
  6. package/dist/components/ColorPicker/ColorPicker/ColorPicker.type.d.ts +1 -1
  7. package/dist/components/EmojiPicker/EmojiPicker/EmojiPicker.type.d.ts +1 -1
  8. package/dist/components/Form/ColorInput/ColorInput/ColorInput.type.d.ts +1 -1
  9. package/dist/components/Form/TagInput/TagInput/TagInput.type.d.ts +1 -1
  10. package/dist/components/Form/TextArea/TextArea/TextArea.type.d.ts +1 -1
  11. package/dist/components/Input/Input.type.d.ts +1 -1
  12. package/dist/components/Message/Message/Message.type.d.ts +1 -1
  13. package/dist/components/Modal/Modal/Modal.props.d.ts +2 -2
  14. package/dist/components/Slider/Slider/Slider.type.d.ts +1 -1
  15. package/dist/components/Title/Title/Title.props.d.ts +0 -5
  16. package/dist/components/Toggle/Toggle/Toggle.type.d.ts +1 -1
  17. package/dist/components/ToggleGroup/ToggleGroup/ToggleGroup.type.d.ts +1 -1
  18. package/dist/pages/tabs.page.d.ts +1 -1
  19. package/dist/web.cjs.development.js +61 -77
  20. package/dist/web.cjs.development.js.map +1 -1
  21. package/dist/web.cjs.production.min.js +1 -1
  22. package/dist/web.cjs.production.min.js.map +1 -1
  23. package/dist/web.esm.js +61 -77
  24. package/dist/web.esm.js.map +1 -1
  25. package/dist/web.umd.development.js +61 -77
  26. package/dist/web.umd.development.js.map +1 -1
  27. package/dist/web.umd.production.min.js +1 -1
  28. package/dist/web.umd.production.min.js.map +1 -1
  29. package/docs/components/Background.mdx +133 -134
  30. package/docs/components/Button.mdx +154 -131
  31. package/docs/components/Chart.mdx +93 -368
  32. package/docs/components/ChatWidget.mdx +106 -0
  33. package/docs/components/EditComponent.mdx +76 -0
  34. package/docs/components/ProgressBar.mdx +77 -394
  35. package/docs/components/Title.mdx +102 -290
  36. package/package.json +1 -1
  37. package/docs/components/ChatInput.mdx +0 -1039
@@ -1,342 +1,117 @@
1
1
  # Chart
2
2
 
3
- A component for visualizing data in various chart formats.
3
+ A comprehensive charting component for visualizing data in various formats including bar, line, area, pie, and donut charts.
4
4
 
5
5
  ### **Import**
6
- ```tsx
7
- import { Chart, CHART_COLORS } from '@app-studio/web';
8
- ```
9
-
10
- ### **Bar Chart**
11
6
  ```tsx
12
- import React from 'react';
13
- import { Chart, CHART_COLORS, View } from '@app-studio/web';
14
-
15
- export const BarChartDemo = () => {
16
- const data = {
17
- labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
18
- series: [
19
- {
20
- name: 'Revenue',
21
- data: [30, 40, 35, 50, 49, 60],
22
- color: CHART_COLORS.blue,
23
- },
24
- {
25
- name: 'Expenses',
26
- data: [20, 25, 30, 35, 30, 40],
27
- color: CHART_COLORS.green,
28
- },
29
- {
30
- name: 'Profit',
31
- data: [10, 15, 5, 15, 19, 20],
32
- color: CHART_COLORS.purple,
33
- },
34
- ],
35
- };
36
-
37
- return (
38
- <View height="300px" width="100%">
39
- <Chart
40
- type="bar"
41
- data={data}
42
- title="Monthly Revenue vs Expenses"
43
- showGrid
44
- animated
45
- onSeriesClick={(seriesName, index) => {
46
- console.log(`Clicked on ${seriesName} at index ${index}`);
47
- }}
48
- />
49
- </View>
50
- );
51
- };
7
+ import { Chart, CHART_COLORS } from '@app-studio/web';
52
8
  ```
53
9
 
54
- ### **Line Chart**
10
+ ### **Quick Start (Bar Chart)**
55
11
  ```tsx
56
12
  import React from 'react';
57
13
  import { Chart, CHART_COLORS, View } from '@app-studio/web';
58
14
 
59
- export const LineChartDemo = () => {
60
- const data = {
61
- labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
62
- series: [
63
- {
64
- name: 'Users',
65
- data: [500, 800, 1200, 1800, 2500, 3000],
66
- color: CHART_COLORS.purple,
67
- },
68
- {
69
- name: 'Sessions',
70
- data: [1000, 1600, 2400, 3600, 5000, 6000],
71
- color: CHART_COLORS.teal,
72
- },
73
- ],
74
- };
75
-
76
- return (
77
- <View height="300px" width="100%">
78
- <Chart
79
- type="line"
80
- data={data}
81
- title="Website Traffic"
82
- showGrid
83
- animated
84
- legendPosition="top"
85
- />
15
+ export const SimpleBarChart = () => (
16
+ <View height="300px">
17
+ <Chart
18
+ type="bar"
19
+ title="Monthly Sales"
20
+ data={{
21
+ labels: ['Jan', 'Feb', 'Mar'],
22
+ series: [{ name: 'Sales', data: [30, 50, 40], color: CHART_COLORS.blue }]
23
+ }}
24
+ />
86
25
  </View>
87
- );
88
- };
26
+ );
89
27
  ```
90
28
 
91
- ### **Area Chart**
92
- ```tsx
93
- import React from 'react';
94
- import { Chart, CHART_COLORS, View } from '@app-studio/web';
29
+ ### **Chart Types**
95
30
 
96
- export const AreaChartDemo = () => {
97
- const data = {
98
- labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
99
- series: [
100
- {
101
- name: 'This Week',
102
- data: [10, 15, 12, 20, 18, 25, 22],
103
- color: CHART_COLORS.green,
104
- },
105
- {
106
- name: 'Last Week',
107
- data: [8, 12, 10, 15, 14, 20, 17],
108
- color: CHART_COLORS.blue,
109
- },
110
- ],
111
- };
31
+ #### **Line & Area Charts**
32
+ Useful for showing trends over time.
112
33
 
113
- return (
114
- <View height="300px" width="100%">
115
- <Chart
116
- type="area"
117
- data={data}
118
- title="Weekly Performance"
119
- showGrid
120
- animated
121
- />
122
- </View>
123
- );
124
- };
125
- ```
126
-
127
- ### **Pie Chart**
128
34
  ```tsx
129
- import React from 'react';
130
- import { Chart, CHART_COLORS, View } from '@app-studio/web';
131
-
132
- export const PieChartDemo = () => {
133
- const dataPoints = [
134
- { label: 'Mobile', value: 45, color: CHART_COLORS.blue },
135
- { label: 'Desktop', value: 30, color: CHART_COLORS.green },
136
- { label: 'Tablet', value: 15, color: CHART_COLORS.purple },
137
- { label: 'Other', value: 10, color: CHART_COLORS.orange },
138
- ];
139
-
140
- return (
141
- <View height="300px" width="100%">
142
- <Chart
143
- type="pie"
144
- dataPoints={dataPoints}
145
- title="Device Distribution"
146
- animated
147
- onDataPointClick={(dataPoint, index) => {
148
- console.log(`Clicked on ${dataPoint?.label} at index ${index}`);
35
+ <View height="300px">
36
+ <Chart
37
+ type="line" // or "area"
38
+ title="User Growth"
39
+ showGrid
40
+ showTooltips
41
+ data={{
42
+ labels: ['Q1', 'Q2', 'Q3', 'Q4'],
43
+ series: [
44
+ { name: '2023', data: [100, 120, 140, 180], color: CHART_COLORS.purple },
45
+ { name: '2024', data: [150, 190, 220, 280], color: CHART_COLORS.teal }
46
+ ]
149
47
  }}
150
- />
151
- </View>
152
- );
153
- };
48
+ />
49
+ </View>
154
50
  ```
155
51
 
156
- ### **Donut Chart**
157
- ```tsx
158
- import React from 'react';
159
- import { Chart, CHART_COLORS, View } from '@app-studio/web';
160
-
161
- export const DonutChartDemo = () => {
162
- const dataPoints = [
163
- { label: 'Completed', value: 65, color: CHART_COLORS.green },
164
- { label: 'In Progress', value: 25, color: CHART_COLORS.blue },
165
- { label: 'Pending', value: 10, color: CHART_COLORS.orange },
166
- ];
167
-
168
- return (
169
- <View height="300px" width="100%">
170
- <Chart
171
- type="donut"
172
- dataPoints={dataPoints}
173
- title="Task Status"
174
- animated
175
- />
176
- </View>
177
- );
178
- };
179
- ```
52
+ #### **Pie & Donut Charts**
53
+ Useful for showing proportional data.
180
54
 
181
- ### **Custom Styling**
182
55
  ```tsx
183
- import React from 'react';
184
- import { Chart, CHART_COLORS, View } from '@app-studio/web';
185
-
186
- export const CustomChartDemo = () => {
187
- const data = {
188
- labels: ['Q1', 'Q2', 'Q3', 'Q4'],
189
- series: [
190
- {
191
- name: 'Sales',
192
- data: [120, 180, 150, 210],
193
- color: CHART_COLORS.blue,
194
- },
195
- ],
196
- };
197
-
198
- return (
199
- <View height="300px" width="100%">
200
- <Chart
201
- type="bar"
202
- data={data}
203
- title="Quarterly Sales"
204
- animated
205
- views={{
206
- container: {
207
- backgroundColor: 'color.gray.50',
208
- padding: '16px',
209
- borderRadius: '8px',
210
- boxShadow: '0 2px 8px rgba(0, 0, 0, 0.1)',
211
- },
212
- chart: {
213
- margin: '16px 0',
214
- },
215
- bar: {
216
- rx: '4px',
217
- ry: '4px',
218
- fill: 'color.blue',
219
- },
220
- grid: {
221
- stroke: 'color.gray.300',
222
- strokeDasharray: '4',
223
- },
224
- axis: {
225
- stroke: 'color.gray.400',
226
- strokeWidth: '2px',
227
- },
228
- legend: {
229
- backgroundColor: 'color.white',
230
- padding: '8px',
231
- borderRadius: '4px',
232
- },
233
- }}
234
- />
235
- </View>
236
- );
237
- };
56
+ <View height="300px">
57
+ <Chart
58
+ type="donut" // or "pie"
59
+ title="Device Usage"
60
+ dataPoints={[
61
+ { label: 'Mobile', value: 60, color: CHART_COLORS.indigo },
62
+ { label: 'Desktop', value: 30, color: CHART_COLORS.cyan },
63
+ { label: 'Tablet', value: 10, color: CHART_COLORS.gray }
64
+ ]}
65
+ onDataPointClick={(point, index) => alert(`Clicked ${point.label}`)}
66
+ />
67
+ </View>
238
68
  ```
239
69
 
240
- ### **Chart States**
241
-
242
- The Chart component supports loading, error, and no data states:
70
+ ### **States (Loading, Error, No Data)**
71
+ Handle various UI states gracefully with built-in props.
243
72
 
244
73
  ```tsx
245
74
  import React, { useState } from 'react';
246
- import { Chart, CHART_COLORS, View, Button, Horizontal } from '@app-studio/web';
247
-
248
- export const ChartStatesDemo = () => {
249
- const [state, setState] = useState<'normal' | 'loading' | 'error' | 'noData'>('normal');
250
-
251
- const data = {
252
- labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
253
- series: [
254
- {
255
- name: 'Revenue',
256
- data: [30, 40, 35, 50, 49, 60],
257
- color: CHART_COLORS.blue,
258
- },
259
- ],
260
- };
261
-
262
- return (
263
- <View>
264
- <Horizontal gap="8px" marginBottom="16px">
265
- <Button onClick={() => setState('normal')}>Normal</Button>
266
- <Button onClick={() => setState('loading')}>Loading</Button>
267
- <Button onClick={() => setState('error')}>Error</Button>
268
- <Button onClick={() => setState('noData')}>No Data</Button>
269
- </Horizontal>
270
-
271
- <View height="300px" width="100%">
272
- <Chart
273
- type="bar"
274
- data={data}
275
- title="Revenue Chart"
276
- showGrid
277
- animated
278
- isLoading={state === 'loading'}
279
- error={state === 'error' ? 'Failed to load chart data' : undefined}
280
- noData={state === 'noData'}
281
- />
282
- </View>
283
- </View>
284
- );
285
- };
286
- ```
287
-
288
- ### **Zero Values**
289
-
290
- The Chart component handles cases where all values are zero by displaying the axes with a default scale, ensuring the chart structure remains visible.
291
-
292
- ```tsx
293
- import React from 'react';
294
- import { Chart, CHART_COLORS, View } from '@app-studio/web';
295
-
296
- export const ZeroValuesDemo = () => {
297
- const data = {
298
- labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
299
- series: [
300
- {
301
- name: 'Revenue',
302
- data: [0, 0, 0, 0, 0, 0],
303
- color: CHART_COLORS.blue,
304
- },
305
- ],
306
- };
307
-
308
- return (
309
- <View height="300px" width="100%">
310
- <Chart
311
- type="bar"
312
- data={data}
313
- title="Zero Revenue Chart"
314
- showGrid
315
- animated
316
- />
317
- </View>
318
- );
75
+ import { Chart, Button, Vertical, Horizontal } from '@app-studio/web';
76
+
77
+ export const ChartStateDemo = () => {
78
+ const [status, setStatus] = useState('normal');
79
+
80
+ return (
81
+ <Vertical gap={20}>
82
+ <Horizontal gap={10}>
83
+ <Button onClick={() => setStatus('loading')}>Load</Button>
84
+ <Button onClick={() => setStatus('error')}>Error</Button>
85
+ <Button onClick={() => setStatus('empty')}>Empty</Button>
86
+ </Horizontal>
87
+
88
+ <View height="300px">
89
+ <Chart
90
+ type="bar"
91
+ title="Revenue"
92
+ isLoading={status === 'loading'}
93
+ error={status === 'error' ? 'Connection Failed' : undefined}
94
+ noData={status === 'empty'}
95
+ data={{ labels: ['A', 'B'], series: [{ name: 'Val', data: [1, 2] }] }}
96
+ />
97
+ </View>
98
+ </Vertical>
99
+ );
319
100
  };
320
101
  ```
321
102
 
322
- ### **Available Colors**
323
-
324
- The Chart component provides a set of predefined colors through `CHART_COLORS`:
103
+ ### **Interactive Events**
104
+ - **onSeriesClick**: Called when a bar (bar chart) or point (line/area) is clicked.
105
+ - **onDataPointClick**: Called when a slice (pie/donut) is clicked.
325
106
 
326
107
  ```tsx
327
- import { CHART_COLORS } from '@app-studio/web';
328
-
329
- // Available colors:
330
- CHART_COLORS.blue // 'color.blue.500'
331
- CHART_COLORS.green // 'color.green.500'
332
- CHART_COLORS.purple // 'color.purple.500'
333
- CHART_COLORS.orange // 'color.orange.500'
334
- CHART_COLORS.red // 'color.red.500'
335
- CHART_COLORS.teal // 'color.teal.500'
336
- CHART_COLORS.pink // 'color.pink.500'
337
- CHART_COLORS.indigo // 'color.indigo.500'
338
- CHART_COLORS.yellow // 'color.yellow.500'
339
- CHART_COLORS.cyan // 'color.cyan.500'
108
+ <Chart
109
+ type="bar"
110
+ data={data}
111
+ onSeriesClick={(seriesName, index) => {
112
+ console.log(`Series: ${seriesName}, Index: ${index}`);
113
+ }}
114
+ />
340
115
  ```
341
116
 
342
117
  ### **Props Reference**
@@ -348,64 +123,14 @@ CHART_COLORS.cyan // 'color.cyan.500'
348
123
  | `dataPoints` | `ChartDataPoint[]` | - | Data points for single series charts (pie, donut) |
349
124
  | `title` | `string` | - | The title of the chart |
350
125
  | `showLegend` | `boolean` | `true` | Whether to show the legend |
351
- | `legendPosition` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'bottom'` | Position of the legend |
352
- | `showGrid` | `boolean` | `true` | Whether to show grid lines |
353
- | `showTooltips` | `boolean` | `true` | Whether to show tooltips on hover |
354
- | `animated` | `boolean` | `true` | Whether the chart is animated |
355
- | `animationDuration` | `number` | `500` | Duration of the animation in milliseconds |
356
- | `responsive` | `boolean` | `true` | Whether the chart is responsive |
357
- | `aspectRatio` | `number` | `16/9` | The aspect ratio of the chart (width/height) |
358
- | `width` | `number \| string` | `200` | The width of the chart |
359
- | `height` | `number \| string` | `200` | The height of the chart |
360
- | `views` | `ChartStyles` | - | Custom styles for different parts of the chart |
361
- | `onDataPointClick` | `(dataPoint, index) => void` | - | Callback when a data point is clicked (pie/donut) |
362
- | `onSeriesClick` | `(seriesName, index) => void` | - | Callback when a series is clicked (bar/line/area) |
363
- | `isLoading` | `boolean` | `false` | If true, displays a loading indicator overlay |
364
- | `error` | `React.ReactNode` | - | If provided, displays an error message overlay |
365
- | `noData` | `boolean \| React.ReactNode` | - | If true, displays a "no data" message |
366
- | `loadingIndicator` | `React.ReactNode` | - | Custom placeholder for the loading state |
367
- | `errorIndicator` | `React.ReactNode` | - | Custom placeholder for the error state |
368
- | `noDataIndicator` | `React.ReactNode` | - | Custom placeholder for the no data state |
369
- | `aria-label` | `string` | - | Aria-label for the chart region (defaults to title) |
370
-
371
- ### **Type Definitions**
372
-
373
- ```tsx
374
- interface ChartData {
375
- labels: string[];
376
- series: ChartSeries[];
377
- }
378
-
379
- interface ChartSeries {
380
- name: string;
381
- data: number[];
382
- color?: string;
383
- }
384
-
385
- interface ChartDataPoint {
386
- label: string;
387
- value: number;
388
- color?: string;
389
- }
390
-
391
- interface ChartStyles {
392
- container?: ViewProps;
393
- chart?: ViewProps;
394
- legend?: ViewProps;
395
- legendItem?: ViewProps;
396
- tooltip?: ViewProps;
397
- axis?: ViewProps;
398
- grid?: ViewProps;
399
- bar?: ViewProps;
400
- line?: ViewProps;
401
- point?: ViewProps;
402
- pie?: ViewProps;
403
- area?: ViewProps;
404
- axisLabel?: ViewProps;
405
- axisLine?: ViewProps;
406
- axisTick?: ViewProps;
407
- loadingOverlay?: ViewProps;
408
- errorOverlay?: ViewProps;
409
- noDataOverlay?: ViewProps;
410
- }
411
- ```
126
+ | `showGrid` | `boolean` | `true` | Show background grid (cartesian charts) |
127
+ | `showTooltips` | `boolean` | `true` | Show tooltips on hover |
128
+ | `animated` | `boolean` | `true` | Animate entry |
129
+ | `isLoading` | `boolean` | `false` | Show loading overlay |
130
+ | `error` | `ReactNode` | - | Show error message overlay |
131
+ | `noData` | `boolean \| ReactNode` | - | Show no data message overlay |
132
+ | `height` / `width` | `number \| string` | `200` | Dimensions of the chart container |
133
+ | `views` | `ChartStyles` | - | Custom styles override object |
134
+
135
+ ### **Available Colors (CHART_COLORS)**
136
+ `blue`, `green`, `purple`, `orange`, `red`, `teal`, `pink`, `indigo`, `yellow`, `cyan`.
@@ -0,0 +1,106 @@
1
+ ---
2
+ title: ChatWidget
3
+ description: A comprehensive chat interface component with support for various message types, attachments, and context integration.
4
+ ---
5
+
6
+ # ChatWidget
7
+
8
+ The `ChatWidget` provides a polished, interactive chat UI. It supports user and assistant messages, rich content types (including reasoning blocks and tool outputs), file attachments, and context-aware inputs.
9
+
10
+ ## Usage
11
+
12
+ ```tsx
13
+ import { ChatWidget } from 'app-studio';
14
+ import { useState } from 'react';
15
+
16
+ const MyChat = () => {
17
+ const [messages, setMessages] = useState([
18
+ { id: '1', role: 'assistant', content: 'Hello! How can I help you?', timestamp: new Date() }
19
+ ]);
20
+
21
+ const handleSend = (text: string) => {
22
+ // Add user message
23
+ const userMsg = { id: Date.now().toString(), role: 'user', content: text, timestamp: new Date() };
24
+ setMessages(prev => [...prev, userMsg]);
25
+
26
+ // Simulate reponse
27
+ setTimeout(() => {
28
+ setMessages(prev => [...prev, {
29
+ id: (Date.now() + 1).toString(),
30
+ role: 'assistant',
31
+ content: 'I received your message!',
32
+ timestamp: new Date()
33
+ }]);
34
+ }, 1000);
35
+ };
36
+
37
+ return (
38
+ <div style={{ height: 500, width: 400 }}>
39
+ <ChatWidget
40
+ messages={messages}
41
+ onSubmit={handleSend}
42
+ variant="default"
43
+ inputPlaceholder="Type a message..."
44
+ />
45
+ </div>
46
+ );
47
+ };
48
+ ```
49
+
50
+ ## Props
51
+
52
+ | Prop | Type | Default | Description |
53
+ | :--- | :--- | :--- | :--- |
54
+ | `messages` | `Message[]` | `[]` | Array of message objects to display. |
55
+ | `inputValue` | `string` | - | Value for the message input (controlled mode). |
56
+ | `onInputChange` | `(value: string) => void` | - | Callback when input value changes. |
57
+ | `onSubmit` | `(message: string) => void` | - | Callback when a message is sent. |
58
+ | `inputPlaceholder` | `string` | - | Placeholder text for the input area. |
59
+ | `disableInput` | `boolean` | `false` | Whether the input area is disabled. |
60
+ | `variant` | `'default' \| 'glassy' \| 'minimal'` | `'default'` | Visual style variant of the widget. |
61
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | General size scale of the widget. |
62
+ | `showTimestamps` | `boolean` | `false` | Whether to display timestamps below messages. |
63
+ | `enableAttachments` | `boolean` | `false` | Shows the attachment (paperclip) button. |
64
+ | `enableContextPicker` | `boolean` | `false` | Shows the context picker (+ button) in the input area. |
65
+ | `selectedContextElements` | `ContextElement[]` | `[]` | List of context elements currently selected/attached to the input. |
66
+ | `isLoading` | `boolean` | `false` | Displays a loading indicator if true. |
67
+ | `loadingText` | `string` | - | Text to display alongside the loading indicator. |
68
+ | `maxHeight` | `string \| number` | - | Maximum height for the messages display area. |
69
+
70
+ ## Types
71
+
72
+ ### Message
73
+
74
+ ```typescript
75
+ type MessageRole = 'user' | 'assistant';
76
+ type MessageType = 'text' | 'error' | 'system' | 'tool';
77
+
78
+ interface Message {
79
+ id: string;
80
+ role: MessageRole;
81
+ content: string;
82
+ timestamp: Date;
83
+ reasoning?: string; // Collapsible "thinking" process block
84
+ messageType?: MessageType; // Defaults to 'text'
85
+ attachments?: Attachment[];
86
+ contextElements?: ContextElement[];
87
+ }
88
+ ```
89
+
90
+ ### ContextElement
91
+
92
+ ```typescript
93
+ interface ContextElement {
94
+ id: string;
95
+ name: string;
96
+ tagName: string;
97
+ rect?: DOMRect;
98
+ }
99
+ ```
100
+
101
+ ## Variants
102
+
103
+ - **default**: Standard solid background appearance.
104
+ - **glassy**: Semi-transparent background with blur effects (requires appropriate container/background).
105
+ - **minimal**: Stripped down appearance, suitable for embedding in tighter spaces.
106
+
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: EditComponent
3
+ description: A floating or overlay toolbar designed for contextual editing of elements, with support for custom tools and positioning.
4
+ ---
5
+
6
+ # EditComponent
7
+
8
+ The `EditComponent` is a versatile toolbar that positions itself relative to a target element. It is commonly used for inline editing interfaces, providing a set of tools (icons) that can trigger actions or open sub-panels.
9
+
10
+ ## Usage
11
+
12
+ ```tsx
13
+ import { EditComponent } from 'app-studio';
14
+ import { useRef, useState } from 'react';
15
+
16
+ const MyComponent = () => {
17
+ const [target, setTarget] = useState<HTMLElement | null>(null);
18
+
19
+ return (
20
+ <>
21
+ <div
22
+ onClick={(e) => setTarget(e.currentTarget)}
23
+ style={{ width: 100, height: 100, background: 'red' }}
24
+ >
25
+ Click me
26
+ </div>
27
+
28
+ <EditComponent
29
+ targetElement={target}
30
+ onClose={() => setTarget(null)}
31
+ side="right"
32
+ sideOffset={12}
33
+ variant="floating"
34
+ onToolAction={(toolId) => console.log('Action:', toolId)}
35
+ />
36
+ </>
37
+ );
38
+ };
39
+ ```
40
+
41
+ ## Props
42
+
43
+ | Prop | Type | Default | Description |
44
+ | :--- | :--- | :--- | :--- |
45
+ | `targetElement` | `HTMLElement \| null` | - | The DOM element to which the toolbar should be anchored. If `null`, the component is hidden. |
46
+ | `defaultToolId` | `string` | - | The ID of the tool that should be active/open by default. |
47
+ | `onClose` | `() => void` | - | Callback function triggered when the toolbar or its active panel requests to close. |
48
+ | `side` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'right'` | The preferred side of the target element to place the toolbar. |
49
+ | `sideOffset` | `number` | `12` | The distance (in pixels) between the target element and the toolbar. |
50
+ | `variant` | `'floating' \| 'overlay'` | `'floating'` | The display mode. `'floating'` places the toolbar outside the element, while `'overlay'` positions it inside/on top of the element. |
51
+ | `items` | `ToolbarItem[]` | `[...]` | Configuration for the toolbar items/icons. See `ToolbarItem` definition. |
52
+ | `onToolAction` | `(id: string) => void` | - | Callback triggered when a tool with `actionOnly: true` is clicked. |
53
+
54
+ ### ToolbarItem Interface
55
+
56
+ ```typescript
57
+ interface ToolbarItem {
58
+ id: string; // Unique identifier for the tool
59
+ icon: string; // Icon name to display
60
+ label?: string; // Optional tooltip label
61
+ special?: boolean; // If true, applies special styling (e.g., dark background)
62
+ actionOnly?: boolean; // If true, clicking triggers onToolAction without opening a panel
63
+ }
64
+ ```
65
+
66
+ ## Positioning Behavior
67
+
68
+ The component uses an intelligent positioning system (`useElementPosition`) that tracks the target element's position on scroll and resize.
69
+
70
+ - **Floating**: Attempts to stick to the specified `side`. If there isn't enough space, it may flip or adjust (though currently typically locks to the initial best side upon opening).
71
+ - **Overlay**: Fixed positioning relative to the top-left of the target element (plus offset).
72
+
73
+ ## Panels
74
+
75
+ When a tool is selected (and is not `actionOnly`), the `EditComponent` renders an `EditPanel` component. This panel is positioned adjacent to the toolbar based on the toolbar's orientation and position.
76
+