pika-ux 1.0.3 → 1.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pika-ux",
3
- "version": "1.0.3",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./pika/*": "./src/pika/*",
package/src/app.css CHANGED
@@ -92,6 +92,7 @@
92
92
  --accent-foreground: oklch(0.514 0.146 255.748);
93
93
  --destructive: oklch(0.577 0.215 27.311);
94
94
  --destructive-foreground: oklch(0.984 0.004 248.227);
95
+ --destructive-bg: oklch(0.95 0.08 25);
95
96
  --ring: var(--bluebright-100);
96
97
  --chart-1: oklch(0.646 0.222 41.116);
97
98
  --chart-2: oklch(0.6 0.118 184.704);
@@ -108,6 +109,21 @@
108
109
  --sidebar-border: oklch(0.873 0.115 95.71);
109
110
  --sidebar-ring: oklch(0.623 0.188 259.803);
110
111
 
112
+ /* Extended semantic colors for status/feedback */
113
+ --success: oklch(0.55 0.16 142);
114
+ --success-foreground: oklch(0.985 0 0);
115
+ --success-bg: oklch(0.95 0.05 142);
116
+ --warning: oklch(0.75 0.15 75);
117
+ --warning-foreground: oklch(0.2 0.02 45);
118
+ --warning-bg: oklch(0.95 0.05 75);
119
+ --info: oklch(0.55 0.15 250);
120
+ --info-foreground: oklch(0.985 0 0);
121
+ --info-bg: oklch(0.93 0.05 250);
122
+ --ai: oklch(0.55 0.2 280);
123
+ --ai-foreground: oklch(0.985 0 0);
124
+ --ai-bg: oklch(0.93 0.05 280);
125
+ --danger-bg: oklch(0.95 0.08 25);
126
+
111
127
  --prominent-50: oklch(0.984 0.018 96.452);
112
128
  --prominent-100: oklch(0.959 0.043 96.701);
113
129
  --prominent-200: oklch(0.926 0.075 96.972);
@@ -120,6 +136,7 @@
120
136
  --prominent-900: oklch(0.359 0.071 95.071);
121
137
 
122
138
  /* Gray color palette */
139
+ --gray-25: oklch(0.9901 0.0013 90);
123
140
  --gray-50: oklch(0.985 0.002 247.858);
124
141
  --gray-100: oklch(0.97 0.005 264.542);
125
142
  --gray-200: oklch(0.929 0.013 255.585);
@@ -151,6 +168,7 @@
151
168
  --accent-foreground: oklch(0.984 0.004 248.227);
152
169
  --destructive: oklch(0.396 0.133 25.712);
153
170
  --destructive-foreground: oklch(0.984 0.004 248.227);
171
+ --destructive-bg: oklch(0.25 0.1 25);
154
172
  --ring: oklch(0.625 0.05 253.665);
155
173
  --chart-1: oklch(0.488 0.243 264.376);
156
174
  --chart-2: oklch(0.696 0.17 162.48);
@@ -166,7 +184,23 @@
166
184
  --sidebar-border: oklch(0.712 0.141 92.714);
167
185
  --sidebar-ring: oklch(0.623 0.188 259.803);
168
186
 
187
+ /* Extended semantic colors for status/feedback (dark mode) */
188
+ --success: oklch(0.65 0.18 142);
189
+ --success-foreground: oklch(0.15 0.02 142);
190
+ --success-bg: oklch(0.25 0.08 142);
191
+ --warning: oklch(0.7 0.15 75);
192
+ --warning-foreground: oklch(0.15 0.02 75);
193
+ --warning-bg: oklch(0.25 0.08 75);
194
+ --info: oklch(0.6 0.16 250);
195
+ --info-foreground: oklch(0.15 0.02 250);
196
+ --info-bg: oklch(0.25 0.08 250);
197
+ --ai: oklch(0.6 0.22 280);
198
+ --ai-foreground: oklch(0.15 0.02 280);
199
+ --ai-bg: oklch(0.25 0.08 280);
200
+ --danger-bg: oklch(0.25 0.1 25);
201
+
169
202
  /* Dark mode gray colors */
203
+ --gray-25: oklch(0.16 0.025 258);
170
204
  --gray-50: oklch(0.221 0.022 256.975);
171
205
  --gray-100: oklch(0.313 0.032 256.627);
172
206
  --gray-200: oklch(0.403 0.041 257.509);
@@ -201,6 +235,7 @@
201
235
  --color-accent-foreground: var(--accent-foreground);
202
236
  --color-destructive: var(--destructive);
203
237
  --color-destructive-foreground: var(--destructive-foreground);
238
+ --color-destructive-bg: var(--destructive-bg);
204
239
  --color-border: var(--border);
205
240
  --color-input: var(--input);
206
241
  --color-ring: var(--ring);
@@ -218,6 +253,21 @@
218
253
  --color-sidebar-border: var(--sidebar-border);
219
254
  --color-sidebar-ring: var(--sidebar-ring);
220
255
 
256
+ /* Extended semantic colors for status/feedback */
257
+ --color-success: var(--success);
258
+ --color-success-foreground: var(--success-foreground);
259
+ --color-success-bg: var(--success-bg);
260
+ --color-warning: var(--warning);
261
+ --color-warning-foreground: var(--warning-foreground);
262
+ --color-warning-bg: var(--warning-bg);
263
+ --color-info: var(--info);
264
+ --color-info-foreground: var(--info-foreground);
265
+ --color-info-bg: var(--info-bg);
266
+ --color-ai: var(--ai);
267
+ --color-ai-foreground: var(--ai-foreground);
268
+ --color-ai-bg: var(--ai-bg);
269
+ --color-danger-bg: var(--danger-bg);
270
+
221
271
  /* Custom color palettes */
222
272
  --color-gold-50: var(--gold-50);
223
273
  --color-gold-100: var(--gold-100);
@@ -296,6 +346,7 @@
296
346
  --color-prominent-800: var(--prominent-800);
297
347
  --color-prominent-900: var(--prominent-900);
298
348
 
349
+ --color-gray-25: var(--gray-25);
299
350
  --color-gray-50: var(--gray-50);
300
351
  --color-gray-100: var(--gray-100);
301
352
  --color-gray-200: var(--gray-200);
@@ -80,18 +80,18 @@ Props:
80
80
  const firstStepNotDone = stepsInProcess.steps.find((step) => !step.done);
81
81
  if (currentStep?.done) {
82
82
  // This step is done
83
- return { iconColor: 'text-green-600', textColor: 'text-gray-600', icon: Check, titleIcon: undefined };
83
+ return { iconColor: 'text-success', textColor: 'text-muted-foreground', icon: Check, titleIcon: undefined };
84
84
  } else if (firstStepNotDone?.stepId === currentStep?.stepId) {
85
85
  // This is the first step that hasn't been done
86
86
  return {
87
- iconColor: 'text-purple-600',
88
- textColor: 'text-gray-600',
87
+ iconColor: 'text-ai',
88
+ textColor: 'text-muted-foreground',
89
89
  icon: Circle,
90
90
  titleIcon: ArrowBigRight
91
91
  };
92
92
  } else {
93
93
  // You can't do this step yet since it's after the current step
94
- return { iconColor: 'text-yellow-600', textColor: 'text-gray-400', icon: Minus, titleIcon: undefined };
94
+ return { iconColor: 'text-warning', textColor: 'text-muted-foreground/60', icon: Minus, titleIcon: undefined };
95
95
  }
96
96
  }
97
97
 
@@ -14,22 +14,22 @@
14
14
  const typeConfig = {
15
15
  info: {
16
16
  icon: Info,
17
- bgColor: 'bg-blue-50',
18
- iconColor: 'text-blue-500',
19
- borderColor: 'border-blue-100',
17
+ bgColor: 'bg-info-bg',
18
+ iconColor: 'text-info',
19
+ borderColor: 'border-info/20'
20
20
  },
21
21
  warning: {
22
22
  icon: TriangleAlert,
23
- bgColor: 'bg-yellow-50',
24
- iconColor: 'text-yellow-500',
25
- borderColor: 'border-yellow-100',
23
+ bgColor: 'bg-warning-bg',
24
+ iconColor: 'text-warning',
25
+ borderColor: 'border-warning/20'
26
26
  },
27
27
  error: {
28
28
  icon: CircleAlert,
29
- bgColor: 'bg-red-50',
30
- iconColor: 'text-red-500',
31
- borderColor: 'border-red-100',
32
- },
29
+ bgColor: 'bg-danger-bg',
30
+ iconColor: 'text-destructive',
31
+ borderColor: 'border-destructive/20'
32
+ }
33
33
  } as const;
34
34
 
35
35
  const config = typeConfig[type];
@@ -40,7 +40,7 @@
40
40
  {#if config.icon}
41
41
  <config.icon class="w-5 h-5 {config.iconColor}" />
42
42
  {/if}
43
- <div class="text-sm text-gray-700">
43
+ <div class="text-sm text-foreground">
44
44
  {@render children?.()}
45
45
  </div>
46
46
  </div>
@@ -7,7 +7,7 @@
7
7
  default: 'bg-primary text-primary-foreground hover:bg-primary/80 border-transparent shadow',
8
8
  secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent',
9
9
  destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/80 border-transparent shadow',
10
- success: 'bg-green-700 text-white hover:bg-green-700 border-transparent shadow',
10
+ success: 'bg-success text-success-foreground hover:bg-success/90 border-transparent shadow',
11
11
  outline: 'text-foreground'
12
12
  }
13
13
  },
@@ -58,7 +58,7 @@
58
58
  <DropdownMenu.Root bind:open={dropdownOpen}>
59
59
  <DropdownMenu.Trigger>
60
60
  {#snippet child({ props })}
61
- <Button {...props} variant="ghost" size="icon" class="data-[state=open]:bg-blue-200 h-8 w-8 p-0 hover:bg-blue-200 {dropdownOpen ? 'bg-blue-200' : ''} ">
61
+ <Button {...props} variant="ghost" size="icon" class="data-[state=open]:bg-accent h-8 w-8 p-0 hover:bg-accent {dropdownOpen ? 'bg-accent' : ''} ">
62
62
  <EllipsisVertical class="text-muted-foreground/70 size-3.5" />
63
63
  </Button>
64
64
  {/snippet}
@@ -302,7 +302,7 @@ PikaTable - A reusable table component with server-side pagination, sorting, and
302
302
  <Table.Root class="h-full">
303
303
  <Table.Header>
304
304
  {#each table.getHeaderGroups() as headerGroup (headerGroup.id)}
305
- <Table.Row class="sticky top-0 bg-gray-50 shadow-[inset_0_-1px_0_#ededed]">
305
+ <Table.Row class="sticky top-0 bg-muted shadow-[inset_0_-1px_0_var(--border)]">
306
306
  {#each headerGroup.headers as header (header.id)}
307
307
  <Table.Head colspan={header.colSpan}>
308
308
  {#if !header.isPlaceholder}
@@ -5,19 +5,40 @@
5
5
  let { ref = $bindable(null), class: className, value, ...restProps }: TabsPrimitive.TriggerProps = $props();
6
6
  </script>
7
7
 
8
- <!--
9
- Modified from standard shadcn tabs trigger component:
10
- Added 'data-[state=inactive]:hover:text-primary' to provide visual feedback
11
- when hovering over unselected tabs. This changes the text color to the theme's
12
- primary color on hover for better UX, indicating that the tabs are clickable.
8
+ <!--
9
+ Uses explicit CSS for styling because Tailwind v4's @tailwindcss/vite plugin only generates
10
+ CSS for classes found in the consuming app's src/ directory. Classes unique to external
11
+ packages (like this one) won't have CSS generated unless they're also used in the main app.
12
+
13
+ This means Tailwind utility classes from this component only work if the same class is
14
+ already used somewhere in apps/pika-chat/src/. The CSS block below ensures consistent
15
+ styling regardless of what classes the consuming app happens to use.
13
16
  -->
14
17
 
15
18
  <TabsPrimitive.Trigger
16
19
  bind:ref
17
20
  class={cn(
18
- 'ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=inactive]:hover:text-primary inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow',
21
+ 'pika-tab-trigger ring-offset-background focus-visible:ring-ring inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
19
22
  className
20
23
  )}
21
24
  {value}
22
25
  {...restProps}
23
26
  />
27
+
28
+ <style>
29
+ :global(.pika-tab-trigger[data-state='active']) {
30
+ background-color: var(--card);
31
+ color: var(--foreground);
32
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
33
+ border-bottom: 2px solid var(--primary);
34
+ }
35
+
36
+ :global(.pika-tab-trigger[data-state='inactive']) {
37
+ color: var(--muted-foreground);
38
+ }
39
+
40
+ :global(.pika-tab-trigger[data-state='inactive']:hover) {
41
+ color: var(--primary);
42
+ background-color: color-mix(in oklch, var(--foreground) 5%, transparent);
43
+ }
44
+ </style>
@@ -11,9 +11,24 @@
11
11
  children?: Snippet<[]>;
12
12
  delayDuration?: number;
13
13
  allowHoverOverTooltip?: boolean;
14
+ /** Position of the tooltip relative to the trigger */
15
+ side?: 'top' | 'right' | 'bottom' | 'left';
16
+ /** Offset from the trigger element in pixels */
17
+ sideOffset?: number;
18
+ /** Additional CSS classes to apply to the tooltip content */
19
+ contentClass?: string;
14
20
  }
15
21
 
16
- const { tooltip, hotKey, children, delayDuration, allowHoverOverTooltip = false }: Props = $props();
22
+ const {
23
+ tooltip,
24
+ hotKey,
25
+ children,
26
+ delayDuration,
27
+ allowHoverOverTooltip = false,
28
+ side = 'top',
29
+ sideOffset,
30
+ contentClass
31
+ }: Props = $props();
17
32
 
18
33
  const appState = getContext<AppState>('appState');
19
34
  let hideTooltip = $derived(appState.settings.data.hideTooltips || !tooltip);
@@ -25,7 +40,7 @@
25
40
  <Tooltip.Trigger>
26
41
  {@render children?.()}
27
42
  </Tooltip.Trigger>
28
- <Tooltip.Content>
43
+ <Tooltip.Content {side} {sideOffset} class={contentClass}>
29
44
  {#if typeof tooltip === 'string'}
30
45
  {tooltip}
31
46
  {:else}
@@ -11,7 +11,8 @@
11
11
  <CommandPrimitive.Input
12
12
  data-slot="command-input"
13
13
  class={cn(
14
- 'placeholder:text-muted-foreground outline-hidden flex h-10 w-full rounded-md bg-transparent py-3 text-sm disabled:cursor-not-allowed disabled:opacity-50',
14
+ // PIKA CUSTOMIZATION: Added px-2 for padding inside focus ring (not in upstream shadcn-svelte)
15
+ 'placeholder:text-muted-foreground outline-hidden flex h-10 w-full rounded-md bg-transparent px-2 py-3 text-sm disabled:cursor-not-allowed disabled:opacity-50',
15
16
  className
16
17
  )}
17
18
  bind:ref