Skip to content

Commit

Permalink
Converting UI
Browse files Browse the repository at this point in the history
  • Loading branch information
Acumen-Desktop committed Feb 9, 2025
1 parent eb7669b commit eb9bb6d
Show file tree
Hide file tree
Showing 24 changed files with 453 additions and 51 deletions.
113 changes: 79 additions & 34 deletions acumen/_goose/feature_docs/svelte5_svelteKit2/migration_notes.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,91 @@
# Svelte 5 + SvelteKit 2 Migration Notes

## Key Changes
## ⚠️ CRITICAL CHANGES - READ FIRST

### 1. Svelte 5 Runes
### Event Handling

- Use `$state()` instead of `let` for reactive variables
- Use `$derived()` instead of `$:` for computed values
- Use `$effect()` for side effects
- Use `$props()` for component props
```svelte
// ❌ Svelte 4 (Wrong)
<button on:click={handler}>
<div on:mouseenter={handler}>
// ✅ Svelte 5 (Correct)
<button onclick={handler}>
<div onmouseenter={handler}>
```

### 2. Component Props Pattern
### Content Injection

```svelte
// Old (Svelte 4)
export let prop;
// ❌ Svelte 4 (Wrong)
<slot>Default content</slot>
<slot name="named">Default</slot>
// ✅ Svelte 5 (Correct)
{@render children?.()}
{@render actions?.()}
// Props definition
let {
children = () => null,
actions = () => null
} = $props();
```

### State and Props

// New (Svelte 5)
let { prop } = $props();
```svelte
// ❌ Svelte 4 (Wrong)
export let count = 0;
$: doubled = count * 2;
// ✅ Svelte 5 (Correct)
let { prop = defaultValue } = $props();
let count = $state(0);
let doubled = $derived(count * 2);
let bindable = $bindable(initialValue);
```

### 3. Event Handling
### Effects

```svelte
// Old (Svelte 4)
<button on:click={handler}>
// Svelte 4 (Wrong)
$: if (count > 0) console.log(count);
// New (Svelte 5)
<button onclick={handler}>
// ✅ Svelte 5 (Correct)
$effect(() => {
if (count > 0) console.log(count);
});
```

### 4. shadcn-svelte Integration
## Component Props Pattern

```svelte
let {
// Two-way binding
isOpen = $bindable(false),
// Regular props with defaults
title = "",
class: className = "",
// Render function props
children = () => null,
actions = () => null,
// Rest props
...restProps
} = $props();
```

## shadcn-svelte Integration

- Update to latest version: `npx shadcn-svelte@next update`
- Update bits-ui: `npm i bits-ui@next`
- Remove cmdk-sv (merged into bits-ui)
- Update components.json with new registry

### 5. Project Structure
## Project Structure

```
src/
Expand Down Expand Up @@ -64,7 +113,7 @@ src/

## Common Patterns

### 1. State Management
### State Management

```svelte
<script lang="ts">
Expand All @@ -77,7 +126,7 @@ src/
</script>
```

### 2. Event Dispatching
### Event Dispatching

```svelte
<script lang="ts">
Expand All @@ -87,7 +136,7 @@ src/
</script>
```

### 3. shadcn-svelte Components
### shadcn-svelte Components

```svelte
<script lang="ts">
Expand Down Expand Up @@ -124,17 +173,13 @@ src/
}
```

4. Update components to use runes

4. Update components:
- Convert state to `$state()`
- Update props to use `$props()`
- Replace `$:` with `$derived()`
- Use `$effect()` for side effects

5. Update event handling
- Review all event handlers
- Update to new syntax where needed
- Ensure proper event forwarding
- Replace `on:event` with `onevent`
- Replace `<slot>` with `{@render}`

## Common Issues

Expand All @@ -146,8 +191,8 @@ src/

2. Event Handling

- Check event forwarding in custom components
- Use proper event types from 'svelte/elements'
- Use `onclick`, `onmouseenter`, etc.
- Use proper event types
- Handle keyboard events appropriately

3. State Management
Expand All @@ -156,10 +201,10 @@ src/
- Update computed values to `$derived()`
- Check for proper cleanup in effects

4. shadcn Integration
- Verify component imports
- Check for proper event forwarding
- Update to latest component versions
4. Content Injection
- Replace all slots with render functions
- Provide default values `() => null`
- Use optional chaining with `{@render prop?.()}`

## Resources

Expand Down
149 changes: 142 additions & 7 deletions acumen/features/svelte-electron-ui/re-create_React_components.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,155 @@
- Svelte 5 components: `ui-svelte/src-renderer/lib/components/shadcn-ui`
- Raw SVG icons moved to: `ui-svelte/src-renderer/lib/assets/icons-svg`

## SVG Conversion Process

When encountering React components that are just SVG wrappers:

1. Create a new .svg file in `ui-svelte/src-renderer/lib/assets/icons-svg`
2. Extract the SVG content from the React component
3. For dynamic props (like size), use CSS variables in the SVG:
```svg
<svg width="var(--size, 24)" height="var(--size, 24)" ...>
```
4. Use the `Icon` component to render with props:
```svelte
<Icon name="icon-name" style="--size: {size}px" />
```

## React Components List

Here is a list of all potential "shadcn-react" components:
Accordion, Alert, Alert Dialog, Aspect Ratio, Avatar, Badge, Breadcrumb, Button, Calendar, Card, Carousel, Chart, Checkbox, Collapsible, Combobox, Command, Context Menu, Data Table, Date Picker, Dialog, Drawer, Dropdown Menu, Form, Hover Card, Input, Input OTP, Label, Menubar, Navigation Menu, Pagination, Popover, Progress, Radio Group, Resizable, Scroll Area, Select, Separator, Sheet, Sidebar, Skeleton, Slider, Sonner, Switch, Table, Tabs, Textarea, Toast, Toggle, Toggle Group, Tooltip.
accordion, alert, alert dialog, aspect ratio, avatar, badge, breadcrumb, button, calendar, card, carousel, chart, checkbox, collapsible, combobox, command, context menu, data table, date picker, dialog, drawer, dropdown menu, form, hover card, input, input otp, label, menubar, navigation menu, pagination, popover, progress, radio group, resizable, scroll area, select, separator, sheet, sidebar, skeleton, slider, sonner, switch, table, tabs, textarea, toast, toggle, toggle group, tooltip.

## Svelte 5 Components List

Here is a list of "shadcn-svelte" components:
Accordion, Alert, Alert Dialog, Aspect Ratio, Avatar, Badge, Breadcrumb, Button, Calendar, Card, Carousel, Checkbox, Collapsible, Combobox, Command, Context Menu, Data Table, Date Picker, Dialog, Drawer, Dropdown Menu, Form, Hover Card, Input, Input OTP, Label, Menubar, Pagination, Popover, Progress, Radio Group, Range Calendar, Resizable, Scroll Area, Select, Separator, Sheet, Sidebar, Skeleton, Slider, Sonner, Switch, Table, Tabs, Textarea, Toggle, Toggle Group, Tooltip
accordion, alert, alert dialog, aspect ratio, avatar, badge, breadcrumb, button, calendar, card, carousel, checkbox, collapsible, combobox, command, context menu, data table, date picker, dialog, drawer, dropdown menu, form, hover card, input, input otp, label, menubar, pagination, popover, progress, radio group, range calendar, resizable, scroll area, select, separator, sheet, sidebar, skeleton, slider, sonner, switch, table, tabs, textarea, toggle, toggle group, tooltip

Shadcn-svelte includes "Range Calendar", but not "Navigation Menu".

Go one by one through: 'ui/desktop/src/components/ui'. If it is a 'shadcn-react' component, create a 'shadcn-svelte' component in: 'ui-svelte/src-renderer/lib/components/shadcn-ui'. Else, create a compound svelte component in: 'ui-svelte/src-renderer/lib/components/basic-ui'. Keep the same file naming convention. It may be that shadcn components start with a lowercase letter, and basic components start with an uppercase letter.
### Custom Components to Convert

Status:
✅ = Converted
⏳ = In Progress
❌ = Not Started
🚫 = Skipped (using shadcn or not needed)
📝 = Converted to SVG

#### Basic UI Components

- [✅] BackButton.tsx

- Lessons:
- Use `Icon` component for SVGs
- Use `onclick` instead of `on:click`
- Use `$bindable` for props that need two-way binding

- [✅] BaseModal.tsx

- Lessons:
- Use native `<dialog>` element instead of custom modal
- Use CSS animations instead of Svelte transitions for better performance
- Use `{@render}` instead of `<slot>`
- Props should be render functions: `children = () => null`

- [📝] Box.tsx

- Status: Done
- Lessons:
- React component was just an SVG wrapper
- Should be converted to a raw SVG file with CSS variables
- Use `Icon` component for rendering

- [🚫] card.tsx

- Lessons:
- Using shadcn-svelte's Card component instead
- No need to recreate as it's part of shadcn-ui

- [❌] select-styles.ts
- Status: Not a component, just styles
- Used by shadcn-svelte Select component

#### SVG Icons to Convert

All of these should be converted to .svg files:

- [📝] Plus.tsx

- Lessons:
- Use `currentColor` instead of hardcoded colors for theme support
- Make opacity configurable with CSS variables
- Default size should be a common icon size (18px)
- Fix attribute names to kebab-case
- Remove unnecessary style attributes

- [✅] Send.tsx
- [✅] Stop.tsx
- [✅] VertDots.tsx
- [✅] X.tsx
- [✅] icons.tsx (contains multiple icons to extract)

#### shadcn Components (Skip)

These are already available in shadcn-svelte:

- [🚫] avatar.tsx
- [🚫] button.tsx
- [🚫] input.tsx
- [🚫] label.tsx
- [🚫] popover.tsx
- [🚫] scroll-area.tsx
- [🚫] switch.tsx

#### Custom Components to Create

These need custom Svelte implementations:

- [ ] ConfirmationModal.tsx (extends BaseModal)
- [ ] modal.tsx (different from BaseModal, check if needed)
- [ ] Tooltip.tsx (check if different from shadcn)

#### Remaining Components to Process

- [ ] BaseButton.tsx
- [ ] BaseCheckbox.tsx
- [ ] BaseInput.tsx
- [ ] BaseRadio.tsx
- [ ] BaseSelect.tsx
- [ ] BaseTextArea.tsx
- [ ] Button.tsx
- [ ] Checkbox.tsx
- [ ] ContextMenu.tsx
- [ ] Dialog.tsx
- [ ] DropdownMenu.tsx
- [ ] Form.tsx
- [ ] Input.tsx
- [ ] Label.tsx
- [ ] Popover.tsx
- [ ] Radio.tsx
- [ ] RadioGroup.tsx
- [ ] ScrollArea.tsx
- [ ] Select.tsx
- [ ] Separator.tsx
- [ ] Sheet.tsx
- [ ] Switch.tsx
- [ ] Table.tsx
- [ ] Tabs.tsx
- [ ] TextArea.tsx
- [ ] Toast.tsx
- [ ] Tooltip.tsx

## STEPS

Go through the files one by one in: 'ui/desktop/src/components/ui'.

There is also on 'ts' file, 'ui/desktop/src/components/ui/select-styles.ts', I am not sure what this is for. Review it and suggest a sub-folder for 'dependencies' etc.?
If the react component is in the React Components List, check if it is also in the Svelte 5 Components List, and if so, skip.

Use Svelte 5!
If the react component is NOT in the Svelte 5 Components List, analyze the component and create a Svelte 5 equivalent component in: 'ui-svelte/src-renderer/lib/components/basic-ui'. Keep the same file naming convention. Use raw SVG icons from: 'ui-svelte/src-renderer/lib/assets/icons-svg', if they exist, else create new ones. Check if they exist first.

Do the first 4 components, and then review.
Use the latest Svelte 5! Not older Svelte. You made Svelte 5 notes here:
'acumen/\_goose/feature_docs/svelte5_svelteKit2/migration_notes.md', update it as needed.

If the 'component' is actually a 'route', check and update the sveltekit 2 routes here: 'ui-svelte/src-renderer/routes'.
Stop after each component is converted for review.
32 changes: 32 additions & 0 deletions ui-svelte/src-renderer/lib/assets/icons-svg/Icon.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<script lang="ts">
let { name, size = 22, class: className = "" } = $props();
let svg = $state("");
async function loadIcon(iconName: string) {
try {
const response = await fetch(`$lib/assets/icons-svg/${iconName}.svg`);
svg = await response.text();
} catch (error) {
console.error(`Failed to load icon: ${iconName}`, error);
}
}
$effect(() => {
loadIcon(name);
});
</script>

<div
class="inline-block {className}"
style="width: {size}px; height: {size}px;"
>
{@html svg}
</div>

<style>
div :global(svg) {
width: 100%;
height: 100%;
}
</style>
7 changes: 4 additions & 3 deletions ui-svelte/src-renderer/lib/assets/icons-svg/Send.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions ui-svelte/src-renderer/lib/assets/icons-svg/attachment.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit eb9bb6d

Please sign in to comment.