@opencode/ui 2.0.23 → 2.0.25

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 (82) hide show
  1. package/dist/context/marked-parser.d.ts +2 -0
  2. package/dist/i18n/en.d.ts +1 -0
  3. package/dist/icons/catalog.d.ts +36 -0
  4. package/dist/navigation/segmented-control/segmented-control.d.ts +21 -2
  5. package/package.json +2 -1
  6. package/src/actions/button/button.css +11 -9
  7. package/src/actions/button/button.tsx +1 -0
  8. package/src/actions/icon-button/icon-button.css +1 -5
  9. package/src/actions/icon-button/icon-button.tsx +1 -0
  10. package/src/actions/split-button/split-button.tsx +3 -0
  11. package/src/actions/submit.css +14 -12
  12. package/src/components/animated-number.tsx +13 -0
  13. package/src/components/app-icon.tsx +2 -0
  14. package/src/components/card.tsx +21 -0
  15. package/src/components/collapsible.tsx +1 -0
  16. package/src/components/context-menu.tsx +34 -0
  17. package/src/components/dock-surface.tsx +3 -0
  18. package/src/components/file-icon.tsx +12 -0
  19. package/src/components/image-preview.tsx +1 -0
  20. package/src/components/list.tsx +32 -0
  21. package/src/components/motion-spring.tsx +5 -0
  22. package/src/components/popover.tsx +12 -0
  23. package/src/components/provider-icon.tsx +1 -0
  24. package/src/components/resize-handle.tsx +8 -0
  25. package/src/components/scroll-view.tsx +39 -0
  26. package/src/components/spinner.tsx +2 -0
  27. package/src/components/text-field.tsx +6 -0
  28. package/src/components/text-reveal.tsx +19 -0
  29. package/src/components/text-strikethrough.tsx +8 -0
  30. package/src/components/typewriter.tsx +4 -0
  31. package/src/context/dialog.tsx +12 -0
  32. package/src/context/file.tsx +1 -0
  33. package/src/context/helper.tsx +4 -0
  34. package/src/context/i18n.tsx +20 -0
  35. package/src/context/index.ts +3 -0
  36. package/src/context/marked-base.tsx +9 -1
  37. package/src/context/marked-parser.tsx +57 -18
  38. package/src/context/marked.tsx +3 -0
  39. package/src/context/worker-pool.tsx +2 -0
  40. package/src/data-display/avatar/avatar.tsx +4 -0
  41. package/src/data-display/badge/badge.tsx +1 -0
  42. package/src/data-display/diff-changes/diff-changes.tsx +2 -0
  43. package/src/data-display/keybind/keybind.tsx +1 -0
  44. package/src/data-display/line-comment/line-comment.tsx +22 -0
  45. package/src/data-display/project-avatar/project-avatar.tsx +10 -0
  46. package/src/feedback/loader/loader.tsx +1 -0
  47. package/src/feedback/toast/description.ts +1 -0
  48. package/src/forms/checkbox/checkbox.tsx +1 -0
  49. package/src/forms/field/field.tsx +8 -0
  50. package/src/forms/inline-input/inline-input.tsx +4 -0
  51. package/src/forms/radio/radio.tsx +2 -0
  52. package/src/forms/select/select.tsx +11 -0
  53. package/src/forms/switch/switch.tsx +1 -0
  54. package/src/forms/text-input/text-input.tsx +3 -0
  55. package/src/hooks/create-auto-scroll.tsx +34 -0
  56. package/src/hooks/index.ts +1 -0
  57. package/src/hooks/use-filtered-list.tsx +14 -0
  58. package/src/i18n/en.ts +1 -0
  59. package/src/i18n/no.ts +1 -0
  60. package/src/icons/catalog.ts +36 -0
  61. package/src/icons/icon/icon.tsx +2 -0
  62. package/src/layout/divider/divider.tsx +1 -0
  63. package/src/navigation/menu/menu.tsx +13 -0
  64. package/src/navigation/segmented-control/segmented-control.css +37 -4
  65. package/src/navigation/segmented-control/segmented-control.tsx +210 -14
  66. package/src/navigation/tab-state-indicator.tsx +1 -0
  67. package/src/navigation/tabs/tabs-current.css +1 -5
  68. package/src/navigation/tabs/tabs.css +5 -22
  69. package/src/navigation/tabs/tabs.tsx +18 -0
  70. package/src/overlays/dialog/dialog.tsx +3 -0
  71. package/src/overlays/tooltip/tooltip.tsx +15 -0
  72. package/src/storybook/scaffold.tsx +3 -0
  73. package/src/styles/theme.css +1 -1
  74. package/src/theme/color.ts +27 -0
  75. package/src/theme/context.tsx +58 -0
  76. package/src/theme/default-themes.ts +35 -0
  77. package/src/theme/index.ts +3 -0
  78. package/src/theme/loader.ts +11 -0
  79. package/src/theme/resolve.ts +28 -0
  80. package/src/theme/v2/foreground.ts +8 -0
  81. package/src/theme/v2/resolve.ts +10 -0
  82. package/src/typography/text-shimmer/text-shimmer.tsx +1 -0
@@ -1 +1,3 @@
1
+ import type { MarkedExtension } from "marked";
1
2
  export declare function createMarkdownParser(highlight: (code: string, language: string) => string | Promise<string>): import("marked").Marked<string, string>;
3
+ export declare const markdownMath: MarkedExtension;
package/dist/i18n/en.d.ts CHANGED
@@ -221,6 +221,7 @@ declare const source: {
221
221
  "ui.message.forkMessage": string;
222
222
  "ui.message.revertMessage": string;
223
223
  "ui.message.moveToQueue": string;
224
+ "ui.message.pending": string;
224
225
  "ui.message.deletePending": string;
225
226
  "ui.message.copyResponse": string;
226
227
  "ui.message.copied": string;
@@ -184,6 +184,38 @@ declare const icons: {
184
184
  viewBox: string;
185
185
  body: string;
186
186
  };
187
+ "outline-arrow-left": {
188
+ viewBox: string;
189
+ body: string;
190
+ };
191
+ "outline-arrow-right": {
192
+ viewBox: string;
193
+ body: string;
194
+ };
195
+ "outline-arrow-up-right": {
196
+ viewBox: string;
197
+ body: string;
198
+ };
199
+ "outline-rotate-clockwise": {
200
+ viewBox: string;
201
+ body: string;
202
+ };
203
+ "outline-globe": {
204
+ viewBox: string;
205
+ body: string;
206
+ };
207
+ "outline-globe-plus": {
208
+ viewBox: string;
209
+ body: string;
210
+ };
211
+ "outline-cookie": {
212
+ viewBox: string;
213
+ body: string;
214
+ };
215
+ "outline-browser-annotate": {
216
+ viewBox: string;
217
+ body: string;
218
+ };
187
219
  "arrow-up-right": {
188
220
  viewBox: string;
189
221
  body: string;
@@ -220,6 +252,10 @@ declare const icons: {
220
252
  viewBox: string;
221
253
  body: string;
222
254
  };
255
+ "outline-undo": {
256
+ viewBox: string;
257
+ body: string;
258
+ };
223
259
  "outline-reset": {
224
260
  viewBox: string;
225
261
  body: string;
@@ -1,7 +1,20 @@
1
- import { type JSX, type ParentProps } from "solid-js";
2
- import type { ComponentProps } from "solid-js";
1
+ import { type Transition } from "@kitlangton/solid-motion";
2
+ import { type ComponentProps, type JSX, type ParentProps } from "solid-js";
3
3
  import "./segmented-control.css";
4
4
  type OnChange = (value: string | null) => void;
5
+ export declare const SEGMENTED_CONTROL_SPRING: Transition;
6
+ export type OffsetElement = {
7
+ offsetLeft: number;
8
+ offsetWidth: number;
9
+ offsetParent: Element | OffsetElement | null;
10
+ getBoundingClientRect: () => {
11
+ left: number;
12
+ };
13
+ };
14
+ export declare function measureOffset(root: OffsetElement, button: OffsetElement): {
15
+ x: number;
16
+ width: number;
17
+ };
5
18
  export type SegmentedControlProps = Omit<ComponentProps<"div">, "onChange"> & ParentProps<{
6
19
  /** Selected value when controlled (including `null` when empty). Omit key for uncontrolled. */
7
20
  value?: string | null;
@@ -11,6 +24,8 @@ export type SegmentedControlProps = Omit<ComponentProps<"div">, "onChange"> & Pa
11
24
  /** When true, clicking the active segment clears selection (`onChange(null)`). Default false. */
12
25
  allowDeselect?: boolean;
13
26
  disabled?: boolean;
27
+ /** Motion transition for the active indicator pill. */
28
+ transition?: Transition;
14
29
  }>;
15
30
  export declare function SegmentedControl(props: SegmentedControlProps): JSX.Element;
16
31
  export type SegmentedControlItemProps = Omit<ComponentProps<"button">, "type" | "children"> & ParentProps<{
@@ -18,4 +33,8 @@ export type SegmentedControlItemProps = Omit<ComponentProps<"button">, "type" |
18
33
  children: JSX.Element;
19
34
  }>;
20
35
  export declare function SegmentedControlItem(props: SegmentedControlItemProps): JSX.Element;
36
+ export declare const SegmentedControlV2: typeof SegmentedControl;
37
+ export declare const SegmentedControlItemV2: typeof SegmentedControlItem;
38
+ export type SegmentedControlV2Props = SegmentedControlProps;
39
+ export type SegmentedControlItemV2Props = SegmentedControlItemProps;
21
40
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencode/ui",
3
- "version": "2.0.23",
3
+ "version": "2.0.25",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -244,6 +244,7 @@
244
244
  "vite-plugin-solid": "2.11.10"
245
245
  },
246
246
  "dependencies": {
247
+ "@kitlangton/solid-motion": "0.2.2",
247
248
  "@kobalte/core": "0.13.13",
248
249
  "@pierre/diffs": "1.5.1",
249
250
  "@solid-primitives/event-listener": "2.4.6",
@@ -1,12 +1,8 @@
1
1
  @import "../submit.css";
2
2
 
3
- * {
3
+ [data-component="button-v2"] {
4
4
  -webkit-font-smoothing: antialiased;
5
5
  -moz-osx-font-smoothing: grayscale;
6
- text-rendering: geometricPrecision;
7
- }
8
-
9
- [data-component="button-v2"] {
10
6
  position: relative;
11
7
  display: inline-flex;
12
8
  align-items: center;
@@ -26,6 +22,10 @@
26
22
  outline: none;
27
23
  }
28
24
 
25
+ [data-component="button-v2"] > * {
26
+ pointer-events: none;
27
+ }
28
+
29
29
  [data-component="button-v2"]:focus {
30
30
  outline: none;
31
31
  }
@@ -240,10 +240,12 @@
240
240
  color: var(--v2-icon-icon-muted);
241
241
  }
242
242
 
243
- [data-component="button-v2"][data-variant="ghost-muted"]:is(:hover, [data-state="hover"]):not(:disabled):not(
244
- [data-expanded]
245
- ) {
246
- background-color: var(--v2-overlay-simple-overlay-hover);
243
+ @media (hover: hover) {
244
+ [data-component="button-v2"][data-variant="ghost-muted"]:is(:hover, [data-state="hover"]):not(:disabled):not(
245
+ [data-expanded]
246
+ ) {
247
+ background-color: var(--v2-overlay-simple-overlay-hover);
248
+ }
247
249
  }
248
250
 
249
251
  [data-component="button-v2"][data-variant="ghost-muted"]:is(:active, [data-state="pressed"]):not(:disabled) {
@@ -23,6 +23,7 @@ export interface ButtonProps
23
23
 
24
24
  export function Button(props: ButtonProps) {
25
25
  const [split, rest] = splitProps(props, ["variant", "size", "icon", "class", "classList"])
26
+
26
27
  return (
27
28
  <Root
28
29
  {...rest}
@@ -1,12 +1,8 @@
1
1
  @import "../submit.css";
2
2
 
3
- * {
3
+ [data-component="icon-button-v2"] {
4
4
  -webkit-font-smoothing: antialiased;
5
5
  -moz-osx-font-smoothing: grayscale;
6
- text-rendering: geometricPrecision;
7
- }
8
-
9
- [data-component="icon-button-v2"] {
10
6
  display: inline-flex;
11
7
  align-items: center;
12
8
  justify-content: center;
@@ -14,6 +14,7 @@ export interface IconButtonProps
14
14
 
15
15
  export function IconButton(props: ComponentProps<"button"> & IconButtonProps) {
16
16
  const [local, rest] = splitProps(props, ["variant", "size", "icon", "class", "classList", "state"])
17
+
17
18
  return (
18
19
  <Root
19
20
  {...rest}
@@ -3,6 +3,7 @@ import "./split-button.css"
3
3
 
4
4
  export function SplitButton(props: ParentProps<ComponentProps<"div">>) {
5
5
  const [split, rest] = splitProps(props, ["class", "classList", "children"])
6
+
6
7
  return (
7
8
  <div
8
9
  data-component="split-button-v2"
@@ -19,6 +20,7 @@ export function SplitButton(props: ParentProps<ComponentProps<"div">>) {
19
20
 
20
21
  export function SplitButtonAction(props: ComponentProps<"button">) {
21
22
  const [split, rest] = splitProps(props, ["class", "classList"])
23
+
22
24
  return (
23
25
  <button
24
26
  type="button"
@@ -34,6 +36,7 @@ export function SplitButtonAction(props: ComponentProps<"button">) {
34
36
 
35
37
  export function SplitButtonMenuTrigger(props: ComponentProps<"button">) {
36
38
  const [split, rest] = splitProps(props, ["class", "classList"])
39
+
37
40
  return (
38
41
  <button
39
42
  type="button"
@@ -33,18 +33,20 @@
33
33
  color: var(--v2-icon-icon-inverse);
34
34
  }
35
35
 
36
- :is(
37
- [data-component="button-v2"][data-variant="submit"],
38
- [data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"])
39
- ):is(:hover, [data-state="hover"]):not(:disabled) {
40
- background-image:
41
- linear-gradient(90deg, var(--submit-hover) 0%, var(--submit-hover) 100%),
42
- linear-gradient(180deg, var(--submit-highlight) 0%, var(--v2-alpha-light-0) 100%),
43
- linear-gradient(
44
- 90deg,
45
- var(--v2-background-bg-icon-button-contrast) 0%,
46
- var(--v2-background-bg-icon-button-contrast) 100%
47
- );
36
+ @media (hover: hover) {
37
+ :is(
38
+ [data-component="button-v2"][data-variant="submit"],
39
+ [data-component="icon-button-v2"]:is([data-variant="submit"], [data-variant="contrast"])
40
+ ):is(:hover, [data-state="hover"]):not(:disabled) {
41
+ background-image:
42
+ linear-gradient(90deg, var(--submit-hover) 0%, var(--submit-hover) 100%),
43
+ linear-gradient(180deg, var(--submit-highlight) 0%, var(--v2-alpha-light-0) 100%),
44
+ linear-gradient(
45
+ 90deg,
46
+ var(--v2-background-bg-icon-button-contrast) 0%,
47
+ var(--v2-background-bg-icon-button-contrast) 100%
48
+ );
49
+ }
48
50
  }
49
51
 
50
52
  :is(
@@ -2,6 +2,7 @@ import { For, Index, createEffect, createMemo, on } from "solid-js"
2
2
  import { createStore } from "solid-js/store"
3
3
 
4
4
  const TRACK = Array.from({ length: 30 }, (_, index) => index % 10)
5
+
5
6
  const DURATION = 600
6
7
 
7
8
  function normalize(value: number) {
@@ -10,7 +11,9 @@ function normalize(value: number) {
10
11
 
11
12
  function spin(from: number, to: number, direction: 1 | -1) {
12
13
  if (from === to) return 0
14
+
13
15
  if (direction > 0) return (to - from + 10) % 10
16
+
14
17
  return -((from - to + 10) % 10)
15
18
  }
16
19
 
@@ -19,6 +22,7 @@ function Digit(props: { value: number; direction: 1 | -1 }) {
19
22
  step: props.value + 10,
20
23
  animating: false,
21
24
  })
25
+
22
26
  const step = () => state.step
23
27
  const animating = () => state.animating
24
28
  let last = props.value
@@ -29,9 +33,11 @@ function Digit(props: { value: number; direction: 1 | -1 }) {
29
33
  (next) => {
30
34
  const delta = spin(last, next, props.direction)
31
35
  last = next
36
+
32
37
  if (!delta) {
33
38
  setState("animating", false)
34
39
  setState("step", next + 10)
40
+
35
41
  return
36
42
  }
37
43
 
@@ -65,6 +71,7 @@ function Digit(props: { value: number; direction: 1 | -1 }) {
65
71
  export function AnimatedNumber(props: { value: number; class?: string }) {
66
72
  const target = createMemo(() => {
67
73
  if (!Number.isFinite(props.value)) return 0
74
+
68
75
  return Math.max(0, Math.round(props.value))
69
76
  })
70
77
 
@@ -72,6 +79,7 @@ export function AnimatedNumber(props: { value: number; class?: string }) {
72
79
  value: target(),
73
80
  direction: 1 as 1 | -1,
74
81
  })
82
+
75
83
  const value = () => state.value
76
84
  const direction = () => state.direction
77
85
 
@@ -80,6 +88,7 @@ export function AnimatedNumber(props: { value: number; class?: string }) {
80
88
  target,
81
89
  (next) => {
82
90
  const current = value()
91
+
83
92
  if (next === current) return
84
93
 
85
94
  setState("direction", next > current ? 1 : -1)
@@ -90,13 +99,17 @@ export function AnimatedNumber(props: { value: number; class?: string }) {
90
99
  )
91
100
 
92
101
  const label = createMemo(() => value().toString())
102
+
93
103
  const digits = createMemo(() =>
94
104
  Array.from(label(), (char) => {
95
105
  const code = char.charCodeAt(0) - 48
106
+
96
107
  if (code < 0 || code > 9) return 0
108
+
97
109
  return code
98
110
  }).reverse(),
99
111
  )
112
+
100
113
  const width = createMemo(() => `${digits().length}ch`)
101
114
 
102
115
  return (
@@ -46,7 +46,9 @@ const themed: Partial<Record<IconName, { light: string; dark: string }>> = {
46
46
 
47
47
  const scheme = () => {
48
48
  if (typeof document !== "object") return "light" as const
49
+
49
50
  if (document.documentElement.dataset.colorScheme === "dark") return "dark" as const
51
+
50
52
  return "light" as const
51
53
  }
52
54
 
@@ -22,30 +22,44 @@ export interface CardTitleProps extends ComponentProps<"div"> {
22
22
 
23
23
  function pick(variant: Variant) {
24
24
  if (variant === "error") return "circle-ban-sign" as const
25
+
25
26
  if (variant === "warning") return "warning" as const
27
+
26
28
  if (variant === "success") return "circle-check" as const
29
+
27
30
  if (variant === "info") return "help" as const
31
+
28
32
  return
29
33
  }
30
34
 
31
35
  function mix(style: ComponentProps<"div">["style"], value?: string) {
32
36
  if (!value) return style
37
+
33
38
  if (!style) return { "--card-accent": value }
39
+
34
40
  if (typeof style === "string") return `${style};--card-accent:${value};`
41
+
35
42
  return { ...(style as Record<string, string | number>), "--card-accent": value }
36
43
  }
37
44
 
38
45
  export function Card(props: CardProps) {
39
46
  const [split, rest] = splitProps(props, ["variant", "style", "class", "classList"])
40
47
  const variant = () => split.variant ?? "normal"
48
+
41
49
  const accent = () => {
42
50
  const v = variant()
51
+
43
52
  if (v === "error") return "var(--v2-state-fg-danger)"
53
+
44
54
  if (v === "warning") return "var(--icon-warning-active)"
55
+
45
56
  if (v === "success") return "var(--icon-success-active)"
57
+
46
58
  if (v === "info") return "var(--icon-info-active)"
59
+
47
60
  return
48
61
  }
62
+
49
63
  return (
50
64
  <div
51
65
  {...rest}
@@ -65,12 +79,17 @@ export function Card(props: CardProps) {
65
79
  export function CardTitle(props: CardTitleProps) {
66
80
  const [split, rest] = splitProps(props, ["variant", "icon", "class", "classList", "children"])
67
81
  const show = () => split.icon !== false && split.icon !== null
82
+
68
83
  const name = () => {
69
84
  if (split.icon === false || split.icon === null) return
85
+
70
86
  if (typeof split.icon === "string") return split.icon
87
+
71
88
  return pick(split.variant ?? "normal")
72
89
  }
90
+
73
91
  const placeholder = () => !name()
92
+
74
93
  return (
75
94
  <div
76
95
  {...rest}
@@ -92,6 +111,7 @@ export function CardTitle(props: CardTitleProps) {
92
111
 
93
112
  export function CardDescription(props: ComponentProps<"div">) {
94
113
  const [split, rest] = splitProps(props, ["class", "classList", "children"])
114
+
95
115
  return (
96
116
  <div
97
117
  {...rest}
@@ -108,6 +128,7 @@ export function CardDescription(props: ComponentProps<"div">) {
108
128
 
109
129
  export function CardActions(props: ComponentProps<"div">) {
110
130
  const [split, rest] = splitProps(props, ["class", "classList", "children"])
131
+
111
132
  return (
112
133
  <div
113
134
  {...rest}
@@ -10,6 +10,7 @@ export interface CollapsibleProps extends ParentProps<CollapsibleRootProps> {
10
10
 
11
11
  function CollapsibleRoot(props: CollapsibleProps) {
12
12
  const [local, others] = splitProps(props, ["class", "classList", "variant"])
13
+
13
14
  return (
14
15
  <Kobalte
15
16
  data-component="collapsible"
@@ -3,23 +3,41 @@ import { splitProps } from "solid-js"
3
3
  import type { ComponentProps, ParentProps } from "solid-js"
4
4
 
5
5
  export interface ContextMenuProps extends ComponentProps<typeof Kobalte> {}
6
+
6
7
  export interface ContextMenuTriggerProps extends ComponentProps<typeof Kobalte.Trigger> {}
8
+
7
9
  export interface ContextMenuIconProps extends ComponentProps<typeof Kobalte.Icon> {}
10
+
8
11
  export interface ContextMenuPortalProps extends ComponentProps<typeof Kobalte.Portal> {}
12
+
9
13
  export interface ContextMenuContentProps extends ComponentProps<typeof Kobalte.Content> {}
14
+
10
15
  export interface ContextMenuArrowProps extends ComponentProps<typeof Kobalte.Arrow> {}
16
+
11
17
  export interface ContextMenuSeparatorProps extends ComponentProps<typeof Kobalte.Separator> {}
18
+
12
19
  export interface ContextMenuGroupProps extends ComponentProps<typeof Kobalte.Group> {}
20
+
13
21
  export interface ContextMenuGroupLabelProps extends ComponentProps<typeof Kobalte.GroupLabel> {}
22
+
14
23
  export interface ContextMenuItemProps extends ComponentProps<typeof Kobalte.Item> {}
24
+
15
25
  export interface ContextMenuItemLabelProps extends ComponentProps<typeof Kobalte.ItemLabel> {}
26
+
16
27
  export interface ContextMenuItemDescriptionProps extends ComponentProps<typeof Kobalte.ItemDescription> {}
28
+
17
29
  export interface ContextMenuItemIndicatorProps extends ComponentProps<typeof Kobalte.ItemIndicator> {}
30
+
18
31
  export interface ContextMenuRadioGroupProps extends ComponentProps<typeof Kobalte.RadioGroup> {}
32
+
19
33
  export interface ContextMenuRadioItemProps extends ComponentProps<typeof Kobalte.RadioItem> {}
34
+
20
35
  export interface ContextMenuCheckboxItemProps extends ComponentProps<typeof Kobalte.CheckboxItem> {}
36
+
21
37
  export interface ContextMenuSubProps extends ComponentProps<typeof Kobalte.Sub> {}
38
+
22
39
  export interface ContextMenuSubTriggerProps extends ComponentProps<typeof Kobalte.SubTrigger> {}
40
+
23
41
  export interface ContextMenuSubContentProps extends ComponentProps<typeof Kobalte.SubContent> {}
24
42
 
25
43
  function ContextMenuRoot(props: ContextMenuProps) {
@@ -28,6 +46,7 @@ function ContextMenuRoot(props: ContextMenuProps) {
28
46
 
29
47
  function ContextMenuTrigger(props: ParentProps<ContextMenuTriggerProps>) {
30
48
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
49
+
31
50
  return (
32
51
  <Kobalte.Trigger
33
52
  {...rest}
@@ -44,6 +63,7 @@ function ContextMenuTrigger(props: ParentProps<ContextMenuTriggerProps>) {
44
63
 
45
64
  function ContextMenuIcon(props: ParentProps<ContextMenuIconProps>) {
46
65
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
66
+
47
67
  return (
48
68
  <Kobalte.Icon
49
69
  {...rest}
@@ -64,6 +84,7 @@ function ContextMenuPortal(props: ContextMenuPortalProps) {
64
84
 
65
85
  function ContextMenuContent(props: ParentProps<ContextMenuContentProps>) {
66
86
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
87
+
67
88
  return (
68
89
  <Kobalte.Content
69
90
  {...rest}
@@ -80,6 +101,7 @@ function ContextMenuContent(props: ParentProps<ContextMenuContentProps>) {
80
101
 
81
102
  function ContextMenuArrow(props: ContextMenuArrowProps) {
82
103
  const [local, rest] = splitProps(props, ["class", "classList"])
104
+
83
105
  return (
84
106
  <Kobalte.Arrow
85
107
  {...rest}
@@ -94,6 +116,7 @@ function ContextMenuArrow(props: ContextMenuArrowProps) {
94
116
 
95
117
  function ContextMenuSeparator(props: ContextMenuSeparatorProps) {
96
118
  const [local, rest] = splitProps(props, ["class", "classList"])
119
+
97
120
  return (
98
121
  <Kobalte.Separator
99
122
  {...rest}
@@ -108,6 +131,7 @@ function ContextMenuSeparator(props: ContextMenuSeparatorProps) {
108
131
 
109
132
  function ContextMenuGroup(props: ParentProps<ContextMenuGroupProps>) {
110
133
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
134
+
111
135
  return (
112
136
  <Kobalte.Group
113
137
  {...rest}
@@ -124,6 +148,7 @@ function ContextMenuGroup(props: ParentProps<ContextMenuGroupProps>) {
124
148
 
125
149
  function ContextMenuGroupLabel(props: ParentProps<ContextMenuGroupLabelProps>) {
126
150
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
151
+
127
152
  return (
128
153
  <Kobalte.GroupLabel
129
154
  {...rest}
@@ -140,6 +165,7 @@ function ContextMenuGroupLabel(props: ParentProps<ContextMenuGroupLabelProps>) {
140
165
 
141
166
  function ContextMenuItem(props: ParentProps<ContextMenuItemProps>) {
142
167
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
168
+
143
169
  return (
144
170
  <Kobalte.Item
145
171
  {...rest}
@@ -156,6 +182,7 @@ function ContextMenuItem(props: ParentProps<ContextMenuItemProps>) {
156
182
 
157
183
  function ContextMenuItemLabel(props: ParentProps<ContextMenuItemLabelProps>) {
158
184
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
185
+
159
186
  return (
160
187
  <Kobalte.ItemLabel
161
188
  {...rest}
@@ -172,6 +199,7 @@ function ContextMenuItemLabel(props: ParentProps<ContextMenuItemLabelProps>) {
172
199
 
173
200
  function ContextMenuItemDescription(props: ParentProps<ContextMenuItemDescriptionProps>) {
174
201
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
202
+
175
203
  return (
176
204
  <Kobalte.ItemDescription
177
205
  {...rest}
@@ -188,6 +216,7 @@ function ContextMenuItemDescription(props: ParentProps<ContextMenuItemDescriptio
188
216
 
189
217
  function ContextMenuItemIndicator(props: ParentProps<ContextMenuItemIndicatorProps>) {
190
218
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
219
+
191
220
  return (
192
221
  <Kobalte.ItemIndicator
193
222
  {...rest}
@@ -204,6 +233,7 @@ function ContextMenuItemIndicator(props: ParentProps<ContextMenuItemIndicatorPro
204
233
 
205
234
  function ContextMenuRadioGroup(props: ParentProps<ContextMenuRadioGroupProps>) {
206
235
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
236
+
207
237
  return (
208
238
  <Kobalte.RadioGroup
209
239
  {...rest}
@@ -220,6 +250,7 @@ function ContextMenuRadioGroup(props: ParentProps<ContextMenuRadioGroupProps>) {
220
250
 
221
251
  function ContextMenuRadioItem(props: ParentProps<ContextMenuRadioItemProps>) {
222
252
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
253
+
223
254
  return (
224
255
  <Kobalte.RadioItem
225
256
  {...rest}
@@ -236,6 +267,7 @@ function ContextMenuRadioItem(props: ParentProps<ContextMenuRadioItemProps>) {
236
267
 
237
268
  function ContextMenuCheckboxItem(props: ParentProps<ContextMenuCheckboxItemProps>) {
238
269
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
270
+
239
271
  return (
240
272
  <Kobalte.CheckboxItem
241
273
  {...rest}
@@ -256,6 +288,7 @@ function ContextMenuSub(props: ContextMenuSubProps) {
256
288
 
257
289
  function ContextMenuSubTrigger(props: ParentProps<ContextMenuSubTriggerProps>) {
258
290
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
291
+
259
292
  return (
260
293
  <Kobalte.SubTrigger
261
294
  {...rest}
@@ -272,6 +305,7 @@ function ContextMenuSubTrigger(props: ParentProps<ContextMenuSubTriggerProps>) {
272
305
 
273
306
  function ContextMenuSubContent(props: ParentProps<ContextMenuSubContentProps>) {
274
307
  const [local, rest] = splitProps(props, ["class", "classList", "children"])
308
+
275
309
  return (
276
310
  <Kobalte.SubContent
277
311
  {...rest}
@@ -6,6 +6,7 @@ export interface DockTrayProps extends ComponentProps<"div"> {
6
6
 
7
7
  export function DockShell(props: ComponentProps<"div">) {
8
8
  const [split, rest] = splitProps(props, ["children", "class", "classList"])
9
+
9
10
  return (
10
11
  <div
11
12
  {...rest}
@@ -22,6 +23,7 @@ export function DockShell(props: ComponentProps<"div">) {
22
23
 
23
24
  export function DockShellForm(props: ComponentProps<"form">) {
24
25
  const [split, rest] = splitProps(props, ["children", "class", "classList"])
26
+
25
27
  return (
26
28
  <form
27
29
  {...rest}
@@ -38,6 +40,7 @@ export function DockShellForm(props: ComponentProps<"form">) {
38
40
 
39
41
  export function DockTray(props: DockTrayProps) {
40
42
  const [split, rest] = splitProps(props, ["attach", "children", "class", "classList"])
43
+
41
44
  return (
42
45
  <div
43
46
  {...rest}
@@ -13,6 +13,7 @@ export const FileIcon: Component<FileIconProps> = (props) => {
13
13
  const [local, rest] = splitProps(props, ["node", "class", "classList", "expanded", "mono"])
14
14
  const name = createMemo(() => chooseIconName(local.node.path, local.node.type, local.expanded || false))
15
15
  const id = `file-icon-mono-${createUniqueId()}`
16
+
16
17
  return (
17
18
  <svg
18
19
  data-component="file-icon"
@@ -542,8 +543,11 @@ const ICON_MAPS: IconMaps = {
542
543
 
543
544
  const toOpenVariant = (icon: IconName): IconName => {
544
545
  if (!icon.startsWith("Folder")) return icon
546
+
545
547
  if (icon.endsWith("_light")) return icon.replace("_light", "Open_light") as IconName
548
+
546
549
  if (!icon.endsWith("Open")) return (icon + "Open") as IconName
550
+
547
551
  return icon
548
552
  }
549
553
 
@@ -551,16 +555,20 @@ const basenameOf = (p: string) => p.split("\\").join("/").split("/").filter(Bool
551
555
 
552
556
  const folderNameVariants = (name: string) => {
553
557
  const n = name.toLowerCase()
558
+
554
559
  return [n, `.${n}`, `_${n}`, `__${n}__`]
555
560
  }
556
561
 
557
562
  const dottedSuffixesDesc = (name: string) => {
558
563
  const n = name.toLowerCase()
559
564
  const idxs: number[] = []
565
+
560
566
  for (let i = 0; i < n.length; i++) if (n[i] === ".") idxs.push(i)
561
567
  const out = new Set<string>()
562
568
  out.add(n) // allow exact whole-name "extensions" like "dockerfile"
569
+
563
570
  for (const i of idxs) if (i + 1 < n.length) out.add(n.slice(i + 1))
571
+
564
572
  return Array.from(out).sort((a, b) => b.length - a.length) // longest first
565
573
  }
566
574
 
@@ -571,16 +579,20 @@ export function chooseIconName(path: string, type: "directory" | "file", expande
571
579
  if (type === "directory") {
572
580
  for (const cand of folderNameVariants(baseLower)) {
573
581
  const icon = ICON_MAPS.folderNames[cand]
582
+
574
583
  if (icon) return expanded ? toOpenVariant(icon) : icon
575
584
  }
585
+
576
586
  return expanded ? ICON_MAPS.defaults.folderOpen : ICON_MAPS.defaults.folder
577
587
  }
578
588
 
579
589
  const byName = ICON_MAPS.fileNames[baseLower]
590
+
580
591
  if (byName) return byName
581
592
 
582
593
  for (const ext of dottedSuffixesDesc(baseLower)) {
583
594
  const icon = ICON_MAPS.fileExtensions[ext]
595
+
584
596
  if (icon) return icon
585
597
  }
586
598