betterstart-cli 0.0.16 → 0.0.18

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 (30) hide show
  1. package/dist/assets/adapters/next/plugins/blog/schemas/menus.json +1 -0
  2. package/dist/assets/adapters/next/plugins/blog/schemas/posts.json +132 -99
  3. package/dist/assets/adapters/next/plugins/portfolio/plugin.ts +17 -0
  4. package/dist/assets/adapters/next/plugins/portfolio/schemas/portfolio.json +128 -0
  5. package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/dev-mode-types.ts +2 -2
  6. package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/snippets-tab.tsx +1 -0
  7. package/dist/assets/adapters/next/templates/init/components/shared/dev-mode-integrate.tsx +1 -1
  8. package/dist/assets/adapters/next/templates/init/components/shared/media/media-delete-dialog.tsx +1 -1
  9. package/dist/assets/adapters/next/templates/init/components/shared/media/media-delete-drawer.tsx +1 -1
  10. package/dist/assets/adapters/next/templates/init/components/shared/media/media-grid-item.tsx +17 -7
  11. package/dist/assets/adapters/next/templates/init/data/navigation.ts +2 -1
  12. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-source-mode.tsx +3 -3
  13. package/dist/assets/adapters/next/templates/init/hooks/use-media.ts +2 -1
  14. package/dist/assets/adapters/next/templates/init/pages/profile/profile-form.tsx +3 -3
  15. package/dist/assets/adapters/next/templates/init/types/index.ts +7 -2
  16. package/dist/assets/shared-assets/react-admin/custom/content-editor/media-gallery-block.tsx +2 -2
  17. package/dist/assets/shared-assets/react-admin/custom/content-editor/table-add-controls.tsx +2 -2
  18. package/dist/assets/shared-assets/react-admin/custom/gallery-field.tsx +219 -40
  19. package/dist/assets/shared-assets/react-admin/custom/media-field-empty-state.tsx +99 -0
  20. package/dist/assets/shared-assets/react-admin/custom/media-field.tsx +181 -0
  21. package/dist/assets/shared-assets/react-admin/custom/sortable-gallery-item.tsx +38 -38
  22. package/dist/assets/shared-assets/react-admin/dependencies.ts +1 -0
  23. package/dist/assets/shared-assets/react-admin/schema.json +64 -2
  24. package/dist/assets/shared-assets/react-admin/ui/chart.tsx +1 -1
  25. package/dist/assets/shared-assets/react-admin/ui/pagination.tsx +1 -1
  26. package/dist/cli.js +562 -151
  27. package/dist/cli.js.map +1 -1
  28. package/package.json +1 -1
  29. package/dist/assets/shared-assets/react-admin/custom/gallery-thumbnail.tsx +0 -39
  30. package/dist/assets/shared-assets/react-admin/custom/media-gallery-field.tsx +0 -182
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "name": "menus",
3
+ "type": "entity",
3
4
  "label": "Menus",
4
5
  "description": "Manage Menus",
5
6
  "icon": "Menu",
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "name": "posts",
3
+ "type": "entity",
3
4
  "label": "Posts",
4
5
  "description": "Manage blog posts",
5
6
  "icon": "FileText",
@@ -12,110 +13,142 @@
12
13
  "main": {
13
14
  "fields": [
14
15
  {
15
- "name": "title",
16
- "type": "string",
17
- "label": "Title",
18
- "required": true
19
- },
20
- {
21
- "name": "slug",
22
- "type": "string",
23
- "label": "Slug",
24
- "hint": "URL-friendly identifier (auto-generated from title)"
25
- },
26
- {
27
- "name": "excerpt",
28
- "type": "text",
29
- "label": "Excerpt",
30
- "hint": "Short summary for the content"
31
- },
32
- {
33
- "name": "content",
34
- "type": "richtext",
35
- "output": "html",
36
- "height": "fill"
37
- }
38
- ]
39
- },
40
- "sidebar": {
41
- "fields": [
42
- {
43
- "name": "generalSidebar",
44
- "type": "section",
45
- "heading": {
46
- "icon": "bolt",
47
- "title": "General"
48
- },
49
- "fields": [
16
+ "name": "postTabs",
17
+ "type": "tabs",
18
+ "tabs": [
50
19
  {
51
- "name": "coverImage",
52
- "type": "image",
53
- "label": "Cover Image"
54
- },
55
- {
56
- "name": "categories",
57
- "type": "select",
58
- "label": "Categories",
59
- "placeholder": "Select categories",
60
- "hint": "Assign one or more categories",
61
- "default": "category-1",
62
- "creatable": true,
63
- "multiple": true,
64
- "previewLimit": 1,
65
- "options": [
66
- {
67
- "label": "Category 1",
68
- "value": "category-1"
20
+ "name": "content",
21
+ "label": "Content",
22
+ "icon": "file-text",
23
+ "slot": {
24
+ "main": {
25
+ "fields": [
26
+ {
27
+ "name": "title",
28
+ "type": "string",
29
+ "label": "Title",
30
+ "required": true
31
+ },
32
+ {
33
+ "name": "slug",
34
+ "type": "string",
35
+ "label": "Slug",
36
+ "hint": "URL-friendly identifier (auto-generated from title)"
37
+ },
38
+ {
39
+ "name": "excerpt",
40
+ "type": "text",
41
+ "label": "Excerpt",
42
+ "hint": "Short summary for the content"
43
+ },
44
+ {
45
+ "name": "content",
46
+ "type": "richtext",
47
+ "output": "html",
48
+ "height": "fill"
49
+ }
50
+ ]
69
51
  },
70
- {
71
- "label": "Category 2",
72
- "value": "category-2"
52
+ "sidebar": {
53
+ "fields": [
54
+ {
55
+ "name": "generalSidebar",
56
+ "type": "section",
57
+ "heading": {
58
+ "icon": "bolt",
59
+ "title": "General"
60
+ },
61
+ "fields": [
62
+ {
63
+ "name": "coverImage",
64
+ "type": "image",
65
+ "label": "Cover Image"
66
+ },
67
+ {
68
+ "name": "categories",
69
+ "type": "select",
70
+ "label": "Categories",
71
+ "placeholder": "Select categories",
72
+ "hint": "Assign one or more categories",
73
+ "default": "category-1",
74
+ "creatable": true,
75
+ "multiple": true,
76
+ "previewLimit": 1,
77
+ "options": [
78
+ {
79
+ "label": "Category 1",
80
+ "value": "category-1"
81
+ },
82
+ {
83
+ "label": "Category 2",
84
+ "value": "category-2"
85
+ }
86
+ ]
87
+ }
88
+ ]
89
+ }
90
+ ]
73
91
  }
74
- ]
75
- }
76
- ]
77
- },
78
- {
79
- "name": "seoSidebar",
80
- "type": "section",
81
- "heading": {
82
- "icon": "globe",
83
- "title": "SEO Settings"
84
- },
85
- "fields": [
86
- {
87
- "name": "openGraphImage",
88
- "type": "image",
89
- "label": "OpenGraph Image"
92
+ }
90
93
  },
91
94
  {
92
- "name": "seoTitle",
93
- "type": "string",
94
- "label": "SEO Title",
95
- "defaultValueFrom": "title",
96
- "hint": "Overrides the post title in search results",
97
- "length": 70
98
- },
99
- {
100
- "name": "seoDescription",
101
- "type": "text",
102
- "label": "SEO Description",
103
- "defaultValueFrom": "excerpt",
104
- "hint": "Overrides the excerpt in search result snippets"
105
- },
106
- {
107
- "name": "noIndex",
108
- "type": "boolean",
109
- "label": "No Index",
110
- "hint": "Ask search engines not to index this post",
111
- "default": false
112
- },
113
- {
114
- "name": "noFollow",
115
- "type": "boolean",
116
- "label": "No Follow",
117
- "hint": "Ask search engines not to follow links on this post",
118
- "default": false
95
+ "name": "seo",
96
+ "label": "SEO",
97
+ "icon": "globe",
98
+ "slot": {
99
+ "main": {
100
+ "fields": [
101
+ {
102
+ "name": "seoTitle",
103
+ "type": "string",
104
+ "label": "SEO Title",
105
+ "defaultValueFrom": "title",
106
+ "hint": "Overrides the post title in search results",
107
+ "length": 70
108
+ },
109
+ {
110
+ "name": "seoDescription",
111
+ "type": "text",
112
+ "label": "SEO Description",
113
+ "defaultValueFrom": "excerpt",
114
+ "hint": "Overrides the excerpt in search result snippets"
115
+ },
116
+ {
117
+ "name": "noIndex",
118
+ "type": "boolean",
119
+ "label": "No Index",
120
+ "hint": "Ask search engines not to index this post",
121
+ "default": false
122
+ },
123
+ {
124
+ "name": "noFollow",
125
+ "type": "boolean",
126
+ "label": "No Follow",
127
+ "hint": "Ask search engines not to follow links on this post",
128
+ "default": false
129
+ }
130
+ ]
131
+ },
132
+ "sidebar": {
133
+ "fields": [
134
+ {
135
+ "name": "seoSidebar",
136
+ "type": "section",
137
+ "heading": {
138
+ "icon": "globe",
139
+ "title": "SEO Settings"
140
+ },
141
+ "fields": [
142
+ {
143
+ "name": "openGraphImage",
144
+ "type": "image",
145
+ "label": "OpenGraph Image"
146
+ }
147
+ ]
148
+ }
149
+ ]
150
+ }
151
+ }
119
152
  }
120
153
  ]
121
154
  }
@@ -0,0 +1,17 @@
1
+ import type { BetterstartPluginDefinition } from '@plugin-engine/types.js'
2
+
3
+ export const portfolioPlugin: BetterstartPluginDefinition = {
4
+ id: 'portfolio',
5
+ title: 'Portfolio',
6
+ description: 'Portfolio content module',
7
+ kind: 'content',
8
+ version: '1.0.0',
9
+ dependencies: [],
10
+ conflicts: [],
11
+ schemaFiles: ['portfolio.json'],
12
+ files: [],
13
+ packageDependencies: [],
14
+ devDependencies: [],
15
+ envSections: [],
16
+ configure: 'none'
17
+ }
@@ -0,0 +1,128 @@
1
+ {
2
+ "name": "portfolio",
3
+ "type": "entity",
4
+ "label": "Portfolio",
5
+ "description": "Manage portfolio items",
6
+ "icon": "Briefcase",
7
+ "navGroup": {
8
+ "label": "Collections",
9
+ "position": 0
10
+ },
11
+ "navPosition": 1,
12
+ "slot": {
13
+ "main": {
14
+ "fields": [
15
+ {
16
+ "name": "title",
17
+ "type": "string",
18
+ "label": "Title",
19
+ "required": true
20
+ },
21
+ {
22
+ "name": "eyebrow",
23
+ "type": "string",
24
+ "label": "Eyebrow",
25
+ "required": true
26
+ },
27
+ {
28
+ "name": "brandLink",
29
+ "type": "string",
30
+ "label": "Brand Link",
31
+ "required": false
32
+ },
33
+ {
34
+ "name": "gallery",
35
+ "type": "gallery",
36
+ "label": "Gallery"
37
+ },
38
+ {
39
+ "name": "description",
40
+ "type": "richtext",
41
+ "label": "Description",
42
+ "required": false,
43
+ "output": "html",
44
+ "height": "fill"
45
+ }
46
+ ]
47
+ },
48
+ "sidebar": {
49
+ "fields": [
50
+ {
51
+ "name": "generalSidebar",
52
+ "type": "section",
53
+ "heading": {
54
+ "icon": "bolt",
55
+ "title": "General"
56
+ },
57
+ "fields": [
58
+ {
59
+ "name": "coverImage",
60
+ "type": "image",
61
+ "label": "Cover Image"
62
+ },
63
+ {
64
+ "name": "categories",
65
+ "type": "select",
66
+ "label": "Categories",
67
+ "placeholder": "Select categories",
68
+ "hint": "Assign one or more categories",
69
+ "default": "category-1",
70
+ "creatable": true,
71
+ "multiple": true,
72
+ "previewLimit": 1,
73
+ "options": [
74
+ {
75
+ "label": "Category 1",
76
+ "value": "category-1"
77
+ },
78
+ {
79
+ "label": "Category 2",
80
+ "value": "category-2"
81
+ }
82
+ ]
83
+ }
84
+ ]
85
+ }
86
+ ]
87
+ }
88
+ },
89
+ "columns": [
90
+ {
91
+ "accessorKey": "title",
92
+ "header": "Title",
93
+ "type": "text",
94
+ "sortable": true,
95
+ "size": "xl"
96
+ },
97
+ {
98
+ "accessorKey": "published",
99
+ "header": "Status",
100
+ "type": "boolean",
101
+ "sortable": true,
102
+ "size": "sm"
103
+ },
104
+ {
105
+ "accessorKey": "updatedAt",
106
+ "header": "Updated",
107
+ "type": "date",
108
+ "sortable": true,
109
+ "size": "sm"
110
+ },
111
+ {
112
+ "accessorKey": "createdAt",
113
+ "header": "Created",
114
+ "type": "date",
115
+ "sortable": true,
116
+ "size": "sm"
117
+ }
118
+ ],
119
+ "actions": {
120
+ "create": true,
121
+ "edit": true,
122
+ "delete": true,
123
+ "draft": true
124
+ },
125
+ "search": {
126
+ "fields": ["title", "excerpt"]
127
+ }
128
+ }
@@ -10,7 +10,7 @@ export type DevModeSnippetIcon =
10
10
  | 'save'
11
11
  | 'send'
12
12
  | 'trash'
13
- export type DevModeSnippetKind = 'query' | 'mutation'
13
+ export type DevModeSnippetKind = 'jsx' | 'query' | 'mutation'
14
14
  export type DevModeLifecycleHookPhase = 'before' | 'after'
15
15
  export type DevModeLifecycleHookEvent =
16
16
  | 'beforeCreate'
@@ -33,7 +33,7 @@ export interface DevModeSnippet {
33
33
  code: string
34
34
  codeTabs?: DevModeSnippetCodeTab[]
35
35
  payloadExample?: DevModeSnippetExample
36
- responseExample: DevModeSnippetExample
36
+ responseExample?: DevModeSnippetExample
37
37
  }
38
38
 
39
39
  export interface DevModeSnippetCodeTab {
@@ -40,6 +40,7 @@ const SNIPPET_ICONS = {
40
40
  } satisfies Record<DevModeSnippetIcon, LucideIcon>
41
41
 
42
42
  const SNIPPET_KIND_LABELS = {
43
+ jsx: 'JSX',
43
44
  query: 'Query',
44
45
  mutation: 'Mutation'
45
46
  } satisfies Record<DevModeSnippetKind, string>
@@ -49,7 +49,7 @@ export function DevModeIntegrateButton({
49
49
  <Drawer direction="right" handleOnly onOpenChange={handleOpenChange}>
50
50
  <DrawerTrigger asChild>
51
51
  <Button type="button" variant="outline">
52
- <Code2 data-icon="inline-start" />
52
+ <Code2 />
53
53
  <span className="hidden sm:inline">Dev Mode</span>
54
54
  </Button>
55
55
  </DrawerTrigger>
@@ -53,7 +53,7 @@ export function MediaDeleteDialog({ media, disabled = false, onDeleted }: MediaD
53
53
  <AlertDialog>
54
54
  <AlertDialogTrigger asChild>
55
55
  <Button variant="destructive" disabled={disabled || isPending}>
56
- <Trash2 data-icon="inline-start" />
56
+ <Trash2 />
57
57
  Delete media
58
58
  </Button>
59
59
  </AlertDialogTrigger>
@@ -97,7 +97,7 @@ export function MediaDeleteDrawer({
97
97
  >
98
98
  <DrawerPrimitive.Trigger asChild>
99
99
  <Button variant="destructive" disabled={disabled || isPending || !container}>
100
- <Trash2 data-icon="inline-start" />
100
+ <Trash2 />
101
101
  Delete File
102
102
  </Button>
103
103
  </DrawerPrimitive.Trigger>
@@ -11,7 +11,7 @@ interface MediaGridItemProps {
11
11
  item: AdminMedia
12
12
  selected?: boolean
13
13
  isSelectMode?: boolean
14
- onClick: (item: AdminMedia) => void
14
+ onClick?: (item: AdminMedia) => void
15
15
  }
16
16
 
17
17
  export const MediaGridItem = React.memo(function MediaGridItem({
@@ -21,10 +21,16 @@ export const MediaGridItem = React.memo(function MediaGridItem({
21
21
  onClick
22
22
  }: MediaGridItemProps) {
23
23
  return (
24
- <Card className="relative group cursor-pointer" onClick={() => onClick(item)}>
24
+ <Card
25
+ className={cn('relative group', {
26
+ 'cursor-pointer': Boolean(onClick)
27
+ })}
28
+ onClick={onClick ? () => onClick(item) : undefined}
29
+ >
25
30
  <CardContent
26
- aria-pressed={isSelectMode ? selected : undefined}
27
- className={cn('p-2 flex flex-col hover:border-highlight', {
31
+ aria-pressed={isSelectMode && onClick ? selected : undefined}
32
+ className={cn('p-2 flex flex-col', {
33
+ 'hover:border-highlight': Boolean(onClick),
28
34
  'border-highlight': selected
29
35
  })}
30
36
  >
@@ -32,7 +38,7 @@ export const MediaGridItem = React.memo(function MediaGridItem({
32
38
  <MediaPreview media={item} isFilled />
33
39
  </div>
34
40
 
35
- {isSelectMode && (
41
+ {isSelectMode && onClick ? (
36
42
  <Checkbox
37
43
  aria-label={selected ? `Deselect ${item.filename}` : `Select ${item.filename}`}
38
44
  tabIndex={-1}
@@ -42,10 +48,14 @@ export const MediaGridItem = React.memo(function MediaGridItem({
42
48
  checked={selected}
43
49
  onCheckedChange={() => onClick(item)}
44
50
  />
45
- )}
51
+ ) : null}
46
52
  </CardContent>
47
53
  <CardFooter>
48
- <span className="w-full truncate text-sm text-muted-foreground group-hover:text-foreground">
54
+ <span
55
+ className={cn('w-full truncate text-sm text-muted-foreground', {
56
+ 'group-hover:text-foreground': Boolean(onClick)
57
+ })}
58
+ >
49
59
  {item.filename}
50
60
  </span>
51
61
  </CardFooter>
@@ -1,6 +1,7 @@
1
1
  import type { AdminNavigationItem } from '@admin/types/navigation'
2
2
  import { House, ImagePlay } from 'lucide-react'
3
3
  import { menusNav } from './navigation/menus'
4
+ import { portfolioNav } from './navigation/portfolio'
4
5
  import { postsNav } from './navigation/posts'
5
6
 
6
7
  export type { AdminNavigationItem } from '@admin/types/navigation'
@@ -29,7 +30,7 @@ function comparePositions(a?: number, b?: number): number {
29
30
  return 0
30
31
  }
31
32
 
32
- const combinedNavigation = [...coreNav, ...menusNav, ...postsNav]
33
+ const combinedNavigation = [...coreNav, ...menusNav, ...portfolioNav, ...postsNav]
33
34
 
34
35
  const dashboard = combinedNavigation.find((item) => item.href === '/admin')
35
36
  const others = combinedNavigation.filter((item) => item.href !== '/admin')
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
 
3
- import { MediaGalleryField } from '@admin/components/custom/media-gallery-field'
3
+ import { MediaField } from '@admin/components/custom/media-field'
4
4
  import { useTheme } from '@admin/hooks/use-admin-theme'
5
5
  import type { ContentEditorSelectionRequest } from '@admin/utils/editor/content-editor'
6
6
  import {
@@ -73,7 +73,7 @@ class MarkdownMediaGalleryWidget extends WidgetType {
73
73
  root.render(
74
74
  <QueryClientProvider client={this.props.queryClient}>
75
75
  <NuqsAdapter>
76
- <MediaGalleryField
76
+ <MediaField
77
77
  value=""
78
78
  valueMode="url"
79
79
  accept="image/*"
@@ -95,7 +95,7 @@ class MarkdownMediaGalleryWidget extends WidgetType {
95
95
  root.render(
96
96
  <QueryClientProvider client={this.props.queryClient}>
97
97
  <NuqsAdapter>
98
- <MediaGalleryField
98
+ <MediaField
99
99
  value=""
100
100
  valueMode="url"
101
101
  accept="image/*"
@@ -97,6 +97,7 @@ export function useMediaByIds(ids: string[]) {
97
97
  return useQuery<(AdminMedia | null)[]>({
98
98
  queryKey: ['media', 'batch', ids],
99
99
  queryFn: () => (ids.length > 0 ? getMediaByIds(ids) : []),
100
- enabled: ids.length > 0
100
+ enabled: ids.length > 0,
101
+ placeholderData: (previousData) => previousData
101
102
  })
102
103
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { invalidateUsersCache, isEmailConfigured, updateEmail } from '@admin/actions/profile'
4
4
  import { authClient } from '@admin/auth/client'
5
- import { MediaGalleryField } from '@admin/components/custom/media-gallery-field'
5
+ import { MediaField } from '@admin/components/custom/media-field'
6
6
  import { Avatar, AvatarFallback, AvatarImage } from '@admin/components/ui/avatar'
7
7
  import { Button } from '@admin/components/ui/button'
8
8
  import {
@@ -157,7 +157,7 @@ export function ProfileForm({ user }: ProfileFormProps) {
157
157
  </div>
158
158
  </div>
159
159
  </CardHeader>
160
- <CardContent className="space-y-6">
160
+ <CardContent className="space-y-5">
161
161
  <FormField
162
162
  control={profileForm.control}
163
163
  name="image"
@@ -165,7 +165,7 @@ export function ProfileForm({ user }: ProfileFormProps) {
165
165
  <FormItem>
166
166
  <FormLabel>Profile Picture</FormLabel>
167
167
  <FormControl>
168
- <MediaGalleryField
168
+ <MediaField
169
169
  value={formField.value}
170
170
  onChange={formField.onChange}
171
171
  onBlur={formField.onBlur}
@@ -91,12 +91,17 @@ export interface PaginatedResponse<T> {
91
91
  totalPages: number
92
92
  }
93
93
 
94
+ type TableRowId<TData extends import('@tanstack/react-table').RowData> = TData extends {
95
+ id: infer TId
96
+ }
97
+ ? TId
98
+ : string
99
+
94
100
  /** TanStack Table meta augmentation */
95
101
  declare module '@tanstack/react-table' {
96
- // biome-ignore lint/correctness/noUnusedVariables: augmenting module
97
102
  interface TableMeta<TData extends import('@tanstack/react-table').RowData> {
98
103
  reorderMode?: boolean
99
- onMoveRow?: (id: string, direction: 'up' | 'down') => void
104
+ onMoveRow?: (id: TableRowId<TData>, direction: 'up' | 'down') => void
100
105
  currentUser?: {
101
106
  id: string
102
107
  email: string
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
 
3
- import { MediaGalleryField } from '@admin/components/custom/media-gallery-field'
3
+ import { MediaField } from '@admin/components/custom/media-field'
4
4
 
5
5
  export interface ContentEditorMediaGalleryBlockProps {
6
6
  accept?: string
@@ -16,7 +16,7 @@ export function ContentEditorMediaGalleryBlock({
16
16
  onRemove
17
17
  }: ContentEditorMediaGalleryBlockProps) {
18
18
  return (
19
- <MediaGalleryField
19
+ <MediaField
20
20
  value=""
21
21
  onChange={(url) => {
22
22
  if (url) onMediaSelected(url)
@@ -24,7 +24,7 @@ export function TableAddControls({ controls }: TableAddControlsProps) {
24
24
  variant="outline"
25
25
  >
26
26
  <span className="pointer-events-none inline-flex size-6 shrink-0 items-center justify-center rounded-md border border-border bg-input text-foreground transition-colors group-hover:bg-secondary group-focus-visible:bg-secondary">
27
- <PlusIcon aria-hidden="true" data-icon="inline-start" />
27
+ <PlusIcon aria-hidden="true" />
28
28
  </span>
29
29
  </Button>
30
30
  <Button
@@ -37,7 +37,7 @@ export function TableAddControls({ controls }: TableAddControlsProps) {
37
37
  variant="outline"
38
38
  >
39
39
  <span className="pointer-events-none inline-flex size-6 shrink-0 items-center justify-center rounded-md border border-border bg-input text-foreground transition-colors group-hover:bg-secondary group-focus-visible:bg-secondary">
40
- <PlusIcon aria-hidden="true" data-icon="inline-start" />
40
+ <PlusIcon aria-hidden="true" />
41
41
  </span>
42
42
  </Button>
43
43
  </div>,