linked-data-browser 0.0.7 → 0.0.8-alpha.0

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 (101) hide show
  1. package/.env +2 -0
  2. package/.eslintrc.js +1 -0
  3. package/app/index.tsx +3 -0
  4. package/babel.config.js +7 -8
  5. package/components/DataBrowser.tsx +9 -19
  6. package/components/DataBrowserContext.ts +24 -0
  7. package/components/TargetResourceProvider.tsx +1 -1
  8. package/components/ThemeProvider.tsx +2 -4
  9. package/components/common/LoadingBar.tsx +11 -1
  10. package/components/common/ProfileAvatar.tsx +4 -7
  11. package/components/nav/Layout.tsx +20 -4
  12. package/components/nav/header/AddressBox.tsx +104 -48
  13. package/components/nav/header/AvatarMenu.tsx +42 -10
  14. package/components/nav/header/Header.tsx +26 -19
  15. package/components/nav/header/SignInMenu.tsx +63 -36
  16. package/components/nav/header/ThemeToggleMenu.tsx +21 -9
  17. package/components/nav/header/ViewMenu.tsx +79 -71
  18. package/components/sharing/AccessDropdown.tsx +18 -7
  19. package/components/sharing/CopyLink.tsx +15 -3
  20. package/components/sharing/PermissionRow.tsx +17 -2
  21. package/components/sharing/SharingModal.tsx +30 -3
  22. package/components/sharing/WacRuleForm.tsx +12 -3
  23. package/components/sharing/agentPermissions/AgentInformation.tsx +16 -3
  24. package/components/sharing/agentPermissions/AgentInput.tsx +19 -4
  25. package/components/sharing/agentPermissions/AgentPermissionRow.tsx +24 -6
  26. package/components/ui/accordion.tsx +1 -1
  27. package/components/ui/alert.tsx +62 -46
  28. package/components/ui/avatar.tsx +38 -13
  29. package/components/ui/badge.tsx +63 -48
  30. package/components/ui/button.tsx +226 -108
  31. package/components/ui/card.tsx +53 -38
  32. package/components/ui/checkbox.tsx +53 -16
  33. package/components/ui/context-menu.tsx +4 -4
  34. package/components/ui/dialog.tsx +116 -65
  35. package/components/ui/dropdown-menu.tsx +304 -105
  36. package/components/ui/icon.tsx +23 -0
  37. package/components/ui/input-dropdown.tsx +42 -5
  38. package/components/ui/input.tsx +85 -22
  39. package/components/ui/label.tsx +16 -7
  40. package/components/ui/menubar.tsx +4 -4
  41. package/components/ui/navigation-menu.tsx +157 -90
  42. package/components/ui/progress.tsx +38 -24
  43. package/components/ui/select.tsx +139 -67
  44. package/components/ui/separator.tsx +22 -7
  45. package/components/ui/skeleton.tsx +14 -11
  46. package/components/ui/switch.tsx +82 -37
  47. package/components/ui/table.tsx +57 -35
  48. package/components/ui/tabs.tsx +66 -35
  49. package/components/ui/text.tsx +221 -30
  50. package/components/ui/textarea.tsx +34 -10
  51. package/components/ui/typography.tsx +94 -65
  52. package/components/useViewContext.tsx +8 -8
  53. package/global.css +93 -3
  54. package/metro.config.js +1 -3
  55. package/package.json +3 -7
  56. package/resourceViews/Container/ContainerConfig.tsx +1 -1
  57. package/resourceViews/Container/ContainerView.tsx +63 -25
  58. package/resourceViews/Profile/ProfileConfig.tsx +1 -1
  59. package/resourceViews/Profile/ProfileKnows.tsx +17 -9
  60. package/resourceViews/Profile/ProfileView.tsx +21 -4
  61. package/resourceViews/RawCode/RawCodeConfig.tsx +1 -1
  62. package/resourceViews/RawCode/RawCodeView.tsx +20 -6
  63. package/components.json +0 -7
  64. package/lib/icons/ArrowRight.tsx +0 -4
  65. package/lib/icons/Check.tsx +0 -4
  66. package/lib/icons/ChevronDown.tsx +0 -4
  67. package/lib/icons/ChevronRight.tsx +0 -4
  68. package/lib/icons/ChevronUp.tsx +0 -4
  69. package/lib/icons/ChevronsRight.tsx +0 -4
  70. package/lib/icons/CircleSlash.tsx +0 -4
  71. package/lib/icons/CircleX.tsx +0 -4
  72. package/lib/icons/Code.tsx +0 -4
  73. package/lib/icons/EllipsisVertical.tsx +0 -4
  74. package/lib/icons/EyeOff.tsx +0 -4
  75. package/lib/icons/File.tsx +0 -4
  76. package/lib/icons/Fingerprint.tsx +0 -4
  77. package/lib/icons/Folder.tsx +0 -4
  78. package/lib/icons/Folders.tsx +0 -4
  79. package/lib/icons/Info.tsx +0 -4
  80. package/lib/icons/Link.tsx +0 -4
  81. package/lib/icons/Loader.tsx +0 -4
  82. package/lib/icons/LogOut.tsx +0 -4
  83. package/lib/icons/MonitorSmartphone.tsx +0 -4
  84. package/lib/icons/MoonStar.tsx +0 -4
  85. package/lib/icons/OctagonX.tsx +0 -4
  86. package/lib/icons/Plus.tsx +0 -4
  87. package/lib/icons/RefreshCw.tsx +0 -4
  88. package/lib/icons/Save.tsx +0 -4
  89. package/lib/icons/ShieldX.tsx +0 -4
  90. package/lib/icons/Sun.tsx +0 -4
  91. package/lib/icons/TextCursorInput.tsx +0 -4
  92. package/lib/icons/Trash.tsx +0 -4
  93. package/lib/icons/User.tsx +0 -4
  94. package/lib/icons/UserPlus.tsx +0 -4
  95. package/lib/icons/Users.tsx +0 -4
  96. package/lib/icons/ViewIcon.tsx +0 -4
  97. package/lib/icons/X.tsx +0 -4
  98. package/lib/icons/iconWithClassName.ts +0 -14
  99. package/lib/utils.ts +0 -6
  100. package/nativewind-env.d.ts +0 -1
  101. package/tailwind.config.js +0 -69
@@ -1,157 +1,186 @@
1
1
  import * as Slot from '@rn-primitives/slot';
2
2
  import * as React from 'react';
3
- import { Platform, Text as RNText } from 'react-native';
4
- import { cn } from '../../lib/utils';
3
+ import { Platform, Text as RNText, StyleSheet } from 'react-native';
5
4
 
6
5
  type TypographyProps = React.ComponentProps<typeof RNText> & {
7
6
  ref?: React.RefObject<RNText>;
8
7
  asChild?: boolean;
9
8
  };
10
9
 
11
- function H1({ className, asChild = false, ...props }: TypographyProps) {
10
+ function H1({ style, asChild = false, ...props }: TypographyProps) {
12
11
  const Component = asChild ? Slot.Text : RNText;
13
12
  return (
14
13
  <Component
15
14
  role="heading"
16
15
  aria-level="1"
17
- className={cn(
18
- 'web:scroll-m-20 text-4xl text-foreground font-extrabold tracking-tight lg:text-5xl web:select-text',
19
- className,
20
- )}
16
+ style={StyleSheet.flatten([styles.h1, style])}
21
17
  {...props}
22
18
  />
23
19
  );
24
20
  }
25
21
 
26
- function H2({ className, asChild = false, ...props }: TypographyProps) {
22
+ function H2({ style, asChild = false, ...props }: TypographyProps) {
27
23
  const Component = asChild ? Slot.Text : RNText;
28
24
  return (
29
25
  <Component
30
26
  role="heading"
31
27
  aria-level="2"
32
- className={cn(
33
- 'web:scroll-m-20 border-b border-border pb-2 text-3xl text-foreground font-semibold tracking-tight first:mt-0 web:select-text',
34
- className,
35
- )}
28
+ style={StyleSheet.flatten([styles.h2, style])}
36
29
  {...props}
37
30
  />
38
31
  );
39
32
  }
40
33
 
41
- function H3({ className, asChild = false, ...props }: TypographyProps) {
34
+ function H3({ style, asChild = false, ...props }: TypographyProps) {
42
35
  const Component = asChild ? Slot.Text : RNText;
43
36
  return (
44
37
  <Component
45
38
  role="heading"
46
39
  aria-level="3"
47
- className={cn(
48
- 'web:scroll-m-20 text-2xl text-foreground font-semibold tracking-tight web:select-text',
49
- className,
50
- )}
40
+ style={StyleSheet.flatten([styles.h3, style])}
51
41
  {...props}
52
42
  />
53
43
  );
54
44
  }
55
45
 
56
- function H4({ className, asChild = false, ...props }: TypographyProps) {
46
+ function H4({ style, asChild = false, ...props }: TypographyProps) {
57
47
  const Component = asChild ? Slot.Text : RNText;
58
48
  return (
59
49
  <Component
60
50
  role="heading"
61
51
  aria-level="4"
62
- className={cn(
63
- 'web:scroll-m-20 text-xl text-foreground font-semibold tracking-tight web:select-text',
64
- className,
65
- )}
52
+ style={StyleSheet.flatten([styles.h4, style])}
66
53
  {...props}
67
54
  />
68
55
  );
69
56
  }
70
57
 
71
- function P({ className, asChild = false, ...props }: TypographyProps) {
58
+ function P({ style, asChild = false, ...props }: TypographyProps) {
72
59
  const Component = asChild ? Slot.Text : RNText;
73
- return (
74
- <Component
75
- className={cn('text-base text-foreground web:select-text', className)}
76
- {...props}
77
- />
78
- );
60
+ return <Component style={StyleSheet.flatten([styles.p, style])} {...props} />;
79
61
  }
80
62
 
81
- function BlockQuote({ className, asChild = false, ...props }: TypographyProps) {
63
+ function BlockQuote({ style, asChild = false, ...props }: TypographyProps) {
82
64
  const Component = asChild ? Slot.Text : RNText;
83
65
  return (
84
66
  <Component
85
67
  // @ts-ignore - role of blockquote renders blockquote element on the web
86
68
  role={Platform.OS === 'web' ? 'blockquote' : undefined}
87
- className={cn(
88
- 'mt-6 native:mt-4 border-l-2 border-border pl-6 native:pl-3 text-base text-foreground italic web:select-text',
89
- className,
90
- )}
69
+ style={StyleSheet.flatten([styles.blockquote, style])}
91
70
  {...props}
92
71
  />
93
72
  );
94
73
  }
95
74
 
96
- function Code({ className, asChild = false, ...props }: TypographyProps) {
75
+ function Code({ style, asChild = false, ...props }: TypographyProps) {
97
76
  const Component = asChild ? Slot.Text : RNText;
98
77
  return (
99
78
  <Component
100
79
  // @ts-ignore - role of code renders code element on the web
101
80
  role={Platform.OS === 'web' ? 'code' : undefined}
102
- className={cn(
103
- 'relative rounded-md bg-muted px-[0.3rem] py-[0.2rem] text-sm text-foreground font-semibold web:select-text',
104
- className,
105
- )}
81
+ style={StyleSheet.flatten([styles.code, style])}
106
82
  {...props}
107
83
  />
108
84
  );
109
85
  }
110
86
 
111
- function Lead({ className, asChild = false, ...props }: TypographyProps) {
87
+ function Lead({ style, asChild = false, ...props }: TypographyProps) {
112
88
  const Component = asChild ? Slot.Text : RNText;
113
89
  return (
114
- <Component
115
- className={cn('text-xl text-muted-foreground web:select-text', className)}
116
- {...props}
117
- />
90
+ <Component style={StyleSheet.flatten([styles.lead, style])} {...props} />
118
91
  );
119
92
  }
120
93
 
121
- function Large({ className, asChild = false, ...props }: TypographyProps) {
94
+ function Large({ style, asChild = false, ...props }: TypographyProps) {
122
95
  const Component = asChild ? Slot.Text : RNText;
123
96
  return (
124
- <Component
125
- className={cn(
126
- 'text-xl text-foreground font-semibold web:select-text',
127
- className,
128
- )}
129
- {...props}
130
- />
97
+ <Component style={StyleSheet.flatten([styles.large, style])} {...props} />
131
98
  );
132
99
  }
133
100
 
134
- function Small({ className, asChild = false, ...props }: TypographyProps) {
101
+ function Small({ style, asChild = false, ...props }: TypographyProps) {
135
102
  const Component = asChild ? Slot.Text : RNText;
136
103
  return (
137
- <Component
138
- className={cn(
139
- 'text-sm text-foreground font-medium leading-none web:select-text',
140
- className,
141
- )}
142
- {...props}
143
- />
104
+ <Component style={StyleSheet.flatten([styles.small, style])} {...props} />
144
105
  );
145
106
  }
146
107
 
147
- function Muted({ className, asChild = false, ...props }: TypographyProps) {
108
+ function Muted({ style, asChild = false, ...props }: TypographyProps) {
148
109
  const Component = asChild ? Slot.Text : RNText;
149
110
  return (
150
- <Component
151
- className={cn('text-sm text-muted-foreground web:select-text', className)}
152
- {...props}
153
- />
111
+ <Component style={StyleSheet.flatten([styles.muted, style])} {...props} />
154
112
  );
155
113
  }
156
114
 
115
+ const styles = StyleSheet.create({
116
+ h1: {
117
+ fontSize: 36,
118
+ color: 'hsl(var(--foreground))',
119
+ fontWeight: '800',
120
+ letterSpacing: -0.025,
121
+ },
122
+ h2: {
123
+ fontSize: 30,
124
+ color: 'hsl(var(--foreground))',
125
+ fontWeight: '600',
126
+ letterSpacing: -0.025,
127
+ borderBottomWidth: 1,
128
+ borderBottomColor: 'hsl(var(--border))',
129
+ paddingBottom: 8,
130
+ },
131
+ h3: {
132
+ fontSize: 24,
133
+ color: 'hsl(var(--foreground))',
134
+ fontWeight: '600',
135
+ letterSpacing: -0.025,
136
+ },
137
+ h4: {
138
+ fontSize: 20,
139
+ color: 'hsl(var(--foreground))',
140
+ fontWeight: '600',
141
+ letterSpacing: -0.025,
142
+ },
143
+ p: {
144
+ fontSize: 16,
145
+ color: 'hsl(var(--foreground))',
146
+ },
147
+ blockquote: {
148
+ marginTop: 24,
149
+ borderLeftWidth: 2,
150
+ borderLeftColor: 'hsl(var(--border))',
151
+ paddingLeft: 24,
152
+ fontSize: 16,
153
+ color: 'hsl(var(--foreground))',
154
+ fontStyle: 'italic',
155
+ },
156
+ code: {
157
+ borderRadius: 6,
158
+ backgroundColor: 'hsl(var(--muted))',
159
+ paddingHorizontal: 4.8,
160
+ paddingVertical: 3.2,
161
+ fontSize: 14,
162
+ color: 'hsl(var(--foreground))',
163
+ fontWeight: '600',
164
+ },
165
+ lead: {
166
+ fontSize: 20,
167
+ color: 'hsl(var(--muted-foreground))',
168
+ },
169
+ large: {
170
+ fontSize: 20,
171
+ color: 'hsl(var(--foreground))',
172
+ fontWeight: '600',
173
+ },
174
+ small: {
175
+ fontSize: 14,
176
+ color: 'hsl(var(--foreground))',
177
+ fontWeight: '500',
178
+ lineHeight: 14,
179
+ },
180
+ muted: {
181
+ fontSize: 14,
182
+ color: 'hsl(var(--muted-foreground))',
183
+ },
184
+ });
185
+
157
186
  export { BlockQuote, Code, H1, H2, H3, H4, Large, Lead, Muted, P, Small };
@@ -1,15 +1,15 @@
1
1
  import createContainer from 'constate';
2
2
  import React, { useEffect, useMemo, useState } from 'react';
3
- import { useDataBrowserConfig } from './DataBrowser';
3
+ import { useDataBrowserConfig } from './DataBrowserContext';
4
4
  import { useTargetResource } from './TargetResourceProvider';
5
5
  import { ResourceViewConfig } from './ResourceView';
6
- import { EyeOff } from '../lib/icons/EyeOff';
7
- import { OctagonX } from '../lib/icons/OctagonX';
8
- import { CircleSlash } from '../lib/icons/CircleSlash';
9
- import { TextCursorInput } from '../lib/icons/TextCursorInput';
10
- import { ShieldX } from '../lib/icons/ShieldX';
11
- import { CircleX } from '../lib/icons/CircleX';
12
- import { Loader } from '../lib/icons/Loader';
6
+ import { EyeOff } from 'lucide-react-native';
7
+ import { OctagonX } from 'lucide-react-native';
8
+ import { CircleSlash } from 'lucide-react-native';
9
+ import { TextCursorInput } from 'lucide-react-native';
10
+ import { ShieldX } from 'lucide-react-native';
11
+ import { CircleX } from 'lucide-react-native';
12
+ import { Loader } from 'lucide-react-native';
13
13
  import { ErrorMessageResourceView } from './utilityResourceViews/ErrorMessageResourceView';
14
14
  import { SolidContainer, SolidLeaf } from '@ldo/connected-solid';
15
15
  import { LucideIcon } from 'lucide-react-native';
package/global.css CHANGED
@@ -1,6 +1,96 @@
1
- @tailwind base;
2
- @tailwind components;
3
- @tailwind utilities;
1
+ /* =========================================================
2
+ Global Focus Ring Baseline for Radix + Native Controls
3
+ ========================================================= */
4
+
5
+ /* ---- Design tokens (tweak these to your brand) ---- */
6
+ :root {
7
+ --focus-ring-color: hsl(221 83% 53%);
8
+ /* accent color */
9
+ --focus-ring-width: 2px;
10
+ /* thickness */
11
+ --focus-ring-offset: 2px;
12
+ /* gap from element */
13
+ --focus-ring-shadow:
14
+ 0 0 0 var(--focus-ring-offset) transparent,
15
+ 0 0 0 calc(var(--focus-ring-offset) + var(--focus-ring-width)) var(--focus-ring-color);
16
+ }
17
+
18
+ /* ---- What counts as "focusable control" ---- */
19
+ /* Includes native controls + common Radix roles */
20
+ :where(button,
21
+ a[href],
22
+ area[href],
23
+ input:not([type="hidden"]),
24
+ select,
25
+ textarea,
26
+ summary,
27
+ [role="button"],
28
+ [role="link"],
29
+ [role="menuitem"],
30
+ [role="menuitemradio"],
31
+ [role="menuitemcheckbox"],
32
+ [role="option"],
33
+ [role="treeitem"],
34
+ [role="tab"],
35
+ [role="switch"],
36
+ [role="checkbox"],
37
+ [role="radio"],
38
+ [role="slider"],
39
+ [role="spinbutton"],
40
+ [role="textbox"],
41
+ [role="combobox"],
42
+ [role="gridcell"],
43
+ [role="rowheader"],
44
+ [role="columnheader"],
45
+ [tabindex]:not([tabindex^="-"])) {
46
+ outline: none;
47
+ box-shadow: none;
48
+ }
49
+
50
+ /* ---- Disabled states: suppress rings ---- */
51
+ :where(button, a[href], area[href], input:not([type="hidden"]), select, textarea, summary,
52
+ [role="button"], [role="link"], [role="menuitem"], [role="menuitemradio"],
53
+ [role="menuitemcheckbox"], [role="option"], [role="treeitem"], [role="tab"],
54
+ [role="switch"], [role="checkbox"], [role="radio"], [role="slider"],
55
+ [role="spinbutton"], [role="textbox"], [role="combobox"], [role="gridcell"],
56
+ [role="rowheader"], [role="columnheader"], [tabindex]:not([tabindex^="-"]))[disabled],
57
+ :where([aria-disabled="true"], [data-disabled], [data-state="disabled"]) {
58
+ box-shadow: none !important;
59
+ outline: none !important;
60
+ }
61
+
62
+ /* ---- Keyboard-visible focus only ---- */
63
+ /* :where(button, a[href], area[href], input:not([type="hidden"]), select, textarea, summary,
64
+ [role="button"], [role="link"], [role="menuitem"], [role="menuitemradio"],
65
+ [role="menuitemcheckbox"], [role="option"], [role="treeitem"], [role="tab"],
66
+ [role="switch"], [role="checkbox"], [role="radio"], [role="slider"],
67
+ [role="spinbutton"], [role="textbox"], [role="combobox"], [role="gridcell"],
68
+ [role="rowheader"], [role="columnheader"], [tabindex]:not([tabindex^="-"])):focus-visible {
69
+ box-shadow: var(--focus-ring-shadow);
70
+ border-radius: inherit;
71
+ } */
72
+
73
+ /* ---- Suppress mouse/pointer focus rings ---- */
74
+ :where(button, a[href], area[href], input:not([type="hidden"]), select, textarea, summary,
75
+ [role="button"], [role="link"], [role="menuitem"], [role="menuitemradio"],
76
+ [role="menuitemcheckbox"], [role="option"], [role="treeitem"], [role="tab"],
77
+ [role="switch"], [role="checkbox"], [role="radio"], [role="slider"],
78
+ [role="spinbutton"], [role="textbox"], [role="combobox"], [role="gridcell"],
79
+ [role="rowheader"], [role="columnheader"], [tabindex]:not([tabindex^="-"])):focus:not(:focus-visible) {
80
+ outline: none !important;
81
+ box-shadow: none !important;
82
+ }
83
+
84
+ /* ---- Firefox UA quirks ---- */
85
+ button::-moz-focus-inner {
86
+ border: 0;
87
+ padding: 0;
88
+ }
89
+
90
+ button:-moz-focusring:not(:focus-visible) {
91
+ outline: none;
92
+ }
93
+
4
94
 
5
95
  @layer base {
6
96
  :root {
package/metro.config.js CHANGED
@@ -1,6 +1,4 @@
1
1
  const { getDefaultConfig } = require('expo/metro-config');
2
- const { withNativeWind } = require('nativewind/metro');
3
-
4
2
  const config = getDefaultConfig(__dirname);
5
3
 
6
4
  // Add support for ES modules and import.meta
@@ -23,4 +21,4 @@ config.transformer.minifierConfig = {
23
21
  },
24
22
  };
25
23
 
26
- module.exports = withNativeWind(config, { input: './global.css' });
24
+ module.exports = config;
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "name": "linked-data-browser",
3
3
  "main": "index.js",
4
- "version": "0.0.7",
4
+ "version": "0.0.8-alpha.0",
5
5
  "scripts": {
6
6
  "dev:ios": "expo start -c --ios",
7
7
  "dev:web": "concurrently \"npm run solid-server\" \"expo start -c --web\"",
8
8
  "dev:android": "expo start -c --android",
9
9
  "dev:server-hosted": "concurrently \"npm run solid-server\" \"npm run build:server:watch\"",
10
10
  "clean": "rm -rf .expo node_modules dist-standalone dist-server",
11
- "postinstall": "npx tailwindcss -i ./global.css -o ./node_modules/.cache/nativewind/global.css",
12
11
  "build:standalone": "expo export -p web --output-dir dist-standalone && node scripts/adjust-standalone-paths.js",
13
12
  "build:server": "EXPO_PUBLIC_IS_SERVER_HOSTED=true expo export -p web --output-dir dist-server && node scripts/adjust-server-paths.js",
14
13
  "build:server:watch": "npx chokidar '**/*' -i 'dist-standalone/**' -i 'dist-server/**' -i 'node_modules/**' -i 'data/**' -c 'npm run build:server'",
@@ -72,20 +71,17 @@
72
71
  "expo-system-ui": "~5.0.7",
73
72
  "lodash": "^4.17.21",
74
73
  "lucide-react-native": "^0.511.0",
75
- "nativewind": "^4.1.23",
76
74
  "react": "19.0.0",
77
75
  "react-dom": "19.0.0",
78
76
  "react-native": "0.79.2",
79
77
  "react-native-notifier": "^2.0.0",
80
78
  "react-native-progress": "^5.0.1",
81
- "react-native-reanimated": "~3.17.5",
79
+ "react-native-reanimated": "~3.17.4",
82
80
  "react-native-safe-area-context": "^5.4.0",
83
81
  "react-native-screens": "~4.10.0",
84
82
  "react-native-svg": "15.11.2",
85
83
  "react-native-web": "~0.20.0",
86
- "tailwind-merge": "^2.2.1",
87
- "tailwindcss": "3.3.5",
88
- "tailwindcss-animate": "^1.0.7"
84
+ "react-native-worklets": "^0.6.0"
89
85
  },
90
86
  "devDependencies": {
91
87
  "@babel/core": "^7.26.0",
@@ -1,5 +1,5 @@
1
1
  import { ResourceViewConfig } from '../../components/ResourceView';
2
- import { Folders } from '../../lib/icons/Folders';
2
+ import { Folders } from 'lucide-react-native';
3
3
  import { ContainerView } from './ContainerView';
4
4
 
5
5
  export const ContainerConfig: ResourceViewConfig = {
@@ -1,5 +1,5 @@
1
1
  import React, { FunctionComponent, useCallback } from 'react';
2
- import { View, FlatList, TouchableWithoutFeedback } from 'react-native';
2
+ import { View, FlatList, StyleSheet, Pressable } from 'react-native';
3
3
  import { Text } from '../../components/ui/text';
4
4
  import { Button } from '../../components/ui/button';
5
5
  import {
@@ -9,12 +9,12 @@ import {
9
9
  DropdownMenuItem,
10
10
  } from '../../components/ui/dropdown-menu';
11
11
  import { ErrorMessageResourceView } from '../../components/utilityResourceViews/ErrorMessageResourceView';
12
- import { CircleX } from '../../lib/icons/CircleX';
13
- import { Folder } from '../../lib/icons/Folder';
14
- import { Code } from '../../lib/icons/Code';
15
- import { File } from '../../lib/icons/File';
16
- import { Trash } from '../../lib/icons/Trash';
17
- import { Plus } from '../../lib/icons/Plus';
12
+ import { CircleX } from 'lucide-react-native';
13
+ import { Folder } from 'lucide-react-native';
14
+ import { Code } from 'lucide-react-native';
15
+ import { File } from 'lucide-react-native';
16
+ import { Trash } from 'lucide-react-native';
17
+ import { Plus } from 'lucide-react-native';
18
18
  import { Separator } from '../../components/ui/separator';
19
19
  import { useDialog } from '../../components/nav/DialogProvider';
20
20
  import {
@@ -24,10 +24,13 @@ import {
24
24
  } from '@ldo/connected-solid';
25
25
  import { Notifier } from 'react-native-notifier';
26
26
  import { useViewContext } from '../../components/useViewContext';
27
+ import { useTheme } from '@react-navigation/native';
28
+ import { Icon } from '../../components/ui/icon';
27
29
 
28
30
  export const ContainerView: FunctionComponent = () => {
29
31
  const { targetResource, navigateTo } = useViewContext();
30
32
  const { prompt } = useDialog();
33
+ const { colors } = useTheme();
31
34
 
32
35
  const onCreateContainer = useCallback(async () => {
33
36
  if (targetResource?.type !== 'SolidContainer') return;
@@ -83,12 +86,12 @@ export const ContainerView: FunctionComponent = () => {
83
86
  }
84
87
 
85
88
  return (
86
- <View className="flex-1 flex-row">
89
+ <View style={styles.mainContainer}>
87
90
  {/* Left Panel */}
88
- <View className="max-w-[200px] flex-1 p-4">
91
+ <View style={styles.leftPanel}>
89
92
  <DropdownMenu>
90
93
  <DropdownMenuTrigger asChild>
91
- <Button text='Create' iconLeft={<Plus />} />
94
+ <Button text="Create" iconLeft={Plus} />
92
95
  </DropdownMenuTrigger>
93
96
  <DropdownMenuContent>
94
97
  <DropdownMenuItem onPress={onCreateContainer}>
@@ -105,12 +108,12 @@ export const ContainerView: FunctionComponent = () => {
105
108
  </View>
106
109
 
107
110
  {/* Right Panel */}
108
- <View className="flex-[3] py-4 pr-4">
111
+ <View style={styles.rightPanel}>
109
112
  <FlatList
110
113
  data={targetResource.children()}
111
114
  keyExtractor={(item) => item.uri}
112
115
  renderItem={({ item, index }) => {
113
- const Icon =
116
+ const TypeIcon =
114
117
  item.type === 'SolidContainer'
115
118
  ? Folder
116
119
  : item.uri.endsWith('.ttl')
@@ -119,23 +122,25 @@ export const ContainerView: FunctionComponent = () => {
119
122
  return (
120
123
  <>
121
124
  {index === 0 && <Separator />}
122
- <TouchableWithoutFeedback onPress={() => navigateTo(item.uri)}>
123
- <View className="flex flex-row p-4 hover:bg-secondary rounded-sm cursor-pointer justify-between">
124
- <Text className="flex flex-row gap-3">
125
- <Icon />
126
- {item.uri.replace(targetResource.uri, '')}
127
- </Text>
125
+ <Pressable
126
+ onPress={() => navigateTo(item.uri)}
127
+ style={({ hovered }) => ({
128
+ backgroundColor: hovered ? colors.border : undefined,
129
+ })}
130
+ >
131
+ <View style={styles.listItem}>
132
+ <View style={styles.listItemText}>
133
+ <Icon icon={TypeIcon} />
134
+ <Text>{item.uri.replace(targetResource.uri, '')}</Text>
135
+ </View>
128
136
  <Button
129
137
  variant="ghost"
130
- className="h-6 p-0"
138
+ style={styles.deleteButton}
131
139
  onPress={() => onDelete(item)}
132
- >
133
- <Text>
134
- <Trash size={20} />
135
- </Text>
136
- </Button>
140
+ iconLeft={Trash}
141
+ />
137
142
  </View>
138
- </TouchableWithoutFeedback>
143
+ </Pressable>
139
144
  <Separator />
140
145
  </>
141
146
  );
@@ -145,3 +150,36 @@ export const ContainerView: FunctionComponent = () => {
145
150
  </View>
146
151
  );
147
152
  };
153
+
154
+ const styles = StyleSheet.create({
155
+ mainContainer: {
156
+ flex: 1,
157
+ flexDirection: 'row',
158
+ },
159
+ leftPanel: {
160
+ maxWidth: 200,
161
+ flex: 1,
162
+ padding: 16,
163
+ },
164
+ rightPanel: {
165
+ flex: 3,
166
+ paddingTop: 16,
167
+ paddingBottom: 16,
168
+ paddingRight: 16,
169
+ },
170
+ listItem: {
171
+ flexDirection: 'row',
172
+ padding: 16,
173
+ borderRadius: 4,
174
+ justifyContent: 'space-between',
175
+ alignItems: 'center',
176
+ },
177
+ listItemText: {
178
+ flexDirection: 'row',
179
+ gap: 12,
180
+ },
181
+ deleteButton: {
182
+ height: 24,
183
+ padding: 0,
184
+ },
185
+ });
@@ -1,6 +1,6 @@
1
1
  import { SolidProfileShapeType } from '../../.ldo/profile.shapeTypes';
2
2
  import { ResourceViewConfig } from '../../components/ResourceView';
3
- import { User } from '../../lib/icons/User';
3
+ import { User } from 'lucide-react-native';
4
4
  import { ProfileView } from './ProfileView';
5
5
 
6
6
  export const ProfileConfig: ResourceViewConfig = {
@@ -1,19 +1,22 @@
1
1
  import { Input } from '../../components/ui/input';
2
2
  import React, { FunctionComponent, useCallback, useState } from 'react';
3
- import { Plus } from '../../lib/icons/Plus';
3
+ import { Plus } from 'lucide-react-native';
4
4
  import { SolidProfile } from '../../.ldo/profile.typings';
5
5
  import { AgentInformation } from '../../components/sharing/agentPermissions/AgentInformation';
6
- import { View } from 'react-native';
6
+ import { View, StyleSheet } from 'react-native';
7
7
  import { useChangeSetData } from '@ldo/react';
8
8
  import { SolidLeaf } from '@ldo/connected-solid';
9
9
  import { Button } from '../../components/ui/button';
10
- import { Trash } from '../../lib/icons/Trash';
10
+ import { Trash } from 'lucide-react-native';
11
11
  import { ConnectedPlugin } from '@ldo/connected';
12
12
 
13
13
  export interface ProfileKnowsProps {
14
14
  resource: SolidLeaf;
15
15
  profile: SolidProfile;
16
- setProfile: useChangeSetData<SolidProfile, ConnectedPlugin<any, any, any, any, any>[]>;
16
+ setProfile: useChangeSetData<
17
+ SolidProfile,
18
+ ConnectedPlugin<any, any, any, any, any>[]
19
+ >;
17
20
  }
18
21
 
19
22
  export const ProfileKnows: FunctionComponent<ProfileKnowsProps> = ({
@@ -21,8 +24,6 @@ export const ProfileKnows: FunctionComponent<ProfileKnowsProps> = ({
21
24
  profile,
22
25
  setProfile,
23
26
  }) => {
24
- console.log(profile.knows?.size);
25
-
26
27
  const [newContact, setNewContact] = useState('');
27
28
  const addNewContact = useCallback(() => {
28
29
  setProfile(resource, (cProfile) => {
@@ -32,12 +33,12 @@ export const ProfileKnows: FunctionComponent<ProfileKnowsProps> = ({
32
33
  }, [newContact, resource, setProfile]);
33
34
 
34
35
  return (
35
- <View className="gap-4">
36
+ <View style={styles.container}>
36
37
  <Input
37
38
  placeholder="https://example.pod/john/profile/card#me"
38
39
  label="New Contact WebId"
39
40
  buttonRight={{
40
- iconRight: <Plus />,
41
+ iconRight: Plus,
41
42
  onPress: addNewContact,
42
43
  variant: 'secondary',
43
44
  }}
@@ -47,11 +48,12 @@ export const ProfileKnows: FunctionComponent<ProfileKnowsProps> = ({
47
48
  />
48
49
  {profile.knows?.map((friend) => (
49
50
  <AgentInformation
51
+ key={friend['@id']}
50
52
  webId={friend['@id']}
51
53
  accessoryRight={
52
54
  <Button
53
55
  variant="ghost"
54
- iconRight={<Trash />}
56
+ iconRight={Trash}
55
57
  onPress={() => {
56
58
  setProfile(resource, (cProfile) => {
57
59
  cProfile.knows?.delete(friend);
@@ -64,3 +66,9 @@ export const ProfileKnows: FunctionComponent<ProfileKnowsProps> = ({
64
66
  </View>
65
67
  );
66
68
  };
69
+
70
+ const styles = StyleSheet.create({
71
+ container: {
72
+ gap: 16, // gap-4 equivalent (4 * 4px = 16px)
73
+ },
74
+ });