@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
@@ -8,7 +8,9 @@ const segmenter =
8
8
 
9
9
  function first(value: string) {
10
10
  if (!value) return ""
11
+
11
12
  if (!segmenter) return Array.from(value)[0] ?? ""
13
+
12
14
  return segmenter.segment(value)[Symbol.iterator]().next().value?.segment ?? Array.from(value)[0] ?? ""
13
15
  }
14
16
 
@@ -33,14 +35,19 @@ const OPENCODE_PROJECT_ID = "4b0ea68d7af9a6031a7ffda7ad66e0cb83315750"
33
35
 
34
36
  export function getProjectAvatarSource(id?: string, icon?: { color?: string; url?: string; override?: string }) {
35
37
  if (id === OPENCODE_PROJECT_ID) return "https://opencode.ai/favicon.svg"
38
+
36
39
  if (icon?.override) return icon.override
40
+
37
41
  if (icon?.color) return undefined
42
+
38
43
  return icon?.url
39
44
  }
40
45
 
41
46
  export function getProjectAvatarVariant(key?: string): ProjectAvatarVariant {
42
47
  if (key === "mint") return "cyan"
48
+
43
49
  if (key === "lime") return "green"
50
+
44
51
  if (
45
52
  key === "orange" ||
46
53
  key === "yellow" ||
@@ -53,12 +60,14 @@ export function getProjectAvatarVariant(key?: string): ProjectAvatarVariant {
53
60
  key === "gray"
54
61
  )
55
62
  return key
63
+
56
64
  return "gray"
57
65
  }
58
66
 
59
67
  export const displayName = (project: { name?: string; worktree: string }) => {
60
68
  const trimmed = project.worktree.replace(/[/\\]+$/, "")
61
69
  const filename = trimmed.slice(Math.max(trimmed.lastIndexOf("/"), trimmed.lastIndexOf("\\")) + 1)
70
+
62
71
  return project.name || filename || project.worktree
63
72
  }
64
73
 
@@ -71,6 +80,7 @@ export interface ProjectAvatarProps extends ComponentProps<"div"> {
71
80
 
72
81
  export function ProjectAvatar(props: ProjectAvatarProps) {
73
82
  const [split, rest] = splitProps(props, ["fallback", "src", "variant", "unread", "class", "classList", "style"])
83
+
74
84
  return (
75
85
  <div
76
86
  {...rest}
@@ -3,6 +3,7 @@ import "./loader.css"
3
3
 
4
4
  export function Loader(props: ComponentProps<"svg">) {
5
5
  const [local, rest] = splitProps(props, ["class", "classList", "width", "height"])
6
+
6
7
  return (
7
8
  <svg
8
9
  {...rest}
@@ -5,5 +5,6 @@ export const toastDescriptionLimit = 2000
5
5
 
6
6
  export function boundToastDescription<T extends { description?: string }>(options: T): T {
7
7
  if (!options.description || options.description.length <= toastDescriptionLimit) return options
8
+
8
9
  return { ...options, description: `${options.description.slice(0, toastDescriptionLimit)}…` }
9
10
  }
@@ -10,6 +10,7 @@ export interface CheckboxProps extends ParentProps<ComponentProps<typeof Root>>
10
10
 
11
11
  export function Checkbox(props: CheckboxProps) {
12
12
  const [local, others] = splitProps(props, ["children", "class", "label", "hideLabel", "description", "icon"])
13
+
13
14
  return (
14
15
  <Root {...others} data-component="checkbox">
15
16
  <Input data-slot="checkbox-checkbox-input" />
@@ -31,9 +31,11 @@ const FieldContext = createContext<FieldContextValue>()
31
31
 
32
32
  function useField() {
33
33
  const ctx = useContext(FieldContext)
34
+
34
35
  if (!ctx) {
35
36
  throw new Error("Field subcomponents must be used within <Field>")
36
37
  }
38
+
37
39
  return ctx
38
40
  }
39
41
 
@@ -72,17 +74,22 @@ function FieldRoot(props: ParentProps<FieldProps>) {
72
74
  unregisterSuffix: () => setSuffixCount((n) => Math.max(0, n - 1)),
73
75
  getDescribedBy: () => {
74
76
  const ids: string[] = []
77
+
75
78
  if (prefixCount() > 0) ids.push(prefixId)
79
+
76
80
  if (suffixCount() > 0) ids.push(suffixId)
81
+
77
82
  return ids.length > 0 ? ids.join(" ") : undefined
78
83
  },
79
84
  }
80
85
 
81
86
  const syncControlA11y = () => {
82
87
  const root = rootRef
88
+
83
89
  if (!root) return
84
90
 
85
91
  const control = root.querySelector(CONTROL_SELECTOR) as HTMLInputElement | HTMLTextAreaElement | null
92
+
86
93
  if (!control) return
87
94
 
88
95
  const shell = control.closest(
@@ -93,6 +100,7 @@ function FieldRoot(props: ParentProps<FieldProps>) {
93
100
  control.setAttribute("aria-labelledby", labelId)
94
101
 
95
102
  const describedBy = ctx.getDescribedBy()
103
+
96
104
  if (describedBy) {
97
105
  control.setAttribute("aria-describedby", describedBy)
98
106
  } else {
@@ -10,11 +10,15 @@ export function InlineInput(props: InlineInputProps) {
10
10
 
11
11
  const style = () => {
12
12
  if (!local.style) return { width: local.width }
13
+
13
14
  if (typeof local.style === "string") {
14
15
  if (!local.width) return local.style
16
+
15
17
  return `${local.style};width:${local.width}`
16
18
  }
19
+
17
20
  if (!local.width) return local.style
21
+
18
22
  return { ...local.style, width: local.width }
19
23
  }
20
24
 
@@ -21,6 +21,7 @@ export interface RadioGroupProps extends ParentProps<ComponentProps<typeof Root>
21
21
 
22
22
  export function RadioGroup(props: RadioGroupProps) {
23
23
  const [local, others] = splitProps(props, ["class", "classList", "children", "label", "description", "hideLabel"])
24
+
24
25
  return (
25
26
  <Root
26
27
  {...others}
@@ -54,6 +55,7 @@ export interface RadioItemProps extends ComponentProps<typeof Item> {
54
55
 
55
56
  export function RadioItem(props: RadioItemProps) {
56
57
  const [local, others] = splitProps(props, ["class", "classList", "label", "description", "hideLabel"])
58
+
57
59
  return (
58
60
  <Item
59
61
  {...others}
@@ -17,13 +17,17 @@ function groupOptions<T>(options: T[], groupBy?: (x: T) => string): { category:
17
17
  if (!groupBy) {
18
18
  return [{ category: "", options }]
19
19
  }
20
+
20
21
  const map = new Map<string, T[]>()
22
+
21
23
  for (const opt of options) {
22
24
  const key = groupBy(opt)
23
25
  const arr = map.get(key)
26
+
24
27
  if (arr) arr.push(opt)
25
28
  else map.set(key, [opt])
26
29
  }
30
+
27
31
  return [...map.entries()].map(([category, opts]) => ({ category, options: opts }))
28
32
  }
29
33
 
@@ -110,11 +114,15 @@ export function Select<T>(props: SelectProps<T>) {
110
114
 
111
115
  const move = (item: T | undefined) => {
112
116
  if (!local.onHighlight) return
117
+
113
118
  if (!item) {
114
119
  stop()
120
+
115
121
  return
116
122
  }
123
+
117
124
  const key = keyFor(item)
125
+
118
126
  if (state.key === key) return
119
127
  state.cleanup?.()
120
128
  state.cleanup = local.onHighlight(item)
@@ -178,6 +186,7 @@ export function Select<T>(props: SelectProps<T>) {
178
186
  }}
179
187
  onOpenChange={(open) => {
180
188
  local.onOpenChange?.(open)
189
+
181
190
  if (!open) stop()
182
191
  }}
183
192
  >
@@ -200,7 +209,9 @@ export function Select<T>(props: SelectProps<T>) {
200
209
  <Value<T> data-slot="select-v2-value-text" class={local.valueClass}>
201
210
  {(st) => {
202
211
  const selected = st.selectedOption()
212
+
203
213
  if (local.label && selected != null) return local.label(selected)
214
+
204
215
  return selected != null ? (selected as string) : ""
205
216
  }}
206
217
  </Value>
@@ -12,6 +12,7 @@ export interface SwitchProps extends ParentProps<ComponentProps<typeof Root>> {
12
12
 
13
13
  export function Switch(props: SwitchProps) {
14
14
  const [local, others] = splitProps(props, ["children", "class", "appearance", "hideLabel", "description"])
15
+
15
16
  return (
16
17
  <Root {...others} class={local.class} data-component="switch" data-appearance={local.appearance ?? "compact"}>
17
18
  <Input data-slot="switch-input" />
@@ -29,6 +29,7 @@ export interface TextInputProps extends Omit<ComponentProps<"input">, "type"> {
29
29
 
30
30
  export function TextInput(props: TextInputProps) {
31
31
  const i18n = useI18n()
32
+
32
33
  const [local, inputProps] = splitProps(props, [
33
34
  "class",
34
35
  "classList",
@@ -89,8 +90,10 @@ export function TextInput(props: TextInputProps) {
89
90
  onClick={(event) => {
90
91
  if (local.showClearButton) {
91
92
  local.onClearClick?.(event)
93
+
92
94
  return
93
95
  }
96
+
94
97
  local.onCopyClick?.(event)
95
98
  }}
96
99
  >
@@ -53,10 +53,12 @@ export function createAutoScroll(options: AutoScrollOptions) {
53
53
 
54
54
  const isAuto = (el: HTMLElement) => {
55
55
  const a = auto
56
+
56
57
  if (!a) return false
57
58
 
58
59
  if (Date.now() - a.time > 1500) {
59
60
  auto = undefined
61
+
60
62
  return false
61
63
  }
62
64
 
@@ -65,10 +67,13 @@ export function createAutoScroll(options: AutoScrollOptions) {
65
67
 
66
68
  const scrollToBottomNow = (behavior: ScrollBehavior) => {
67
69
  const el = store.scrollRef
70
+
68
71
  if (!el) return
69
72
  markAuto(el)
73
+
70
74
  if (behavior === "smooth") {
71
75
  el.scrollTo({ top: el.scrollHeight, behavior })
76
+
72
77
  return
73
78
  }
74
79
 
@@ -82,13 +87,16 @@ export function createAutoScroll(options: AutoScrollOptions) {
82
87
  if (force && store.userScrolled) setStore("userScrolled", false)
83
88
 
84
89
  const el = store.scrollRef
90
+
85
91
  if (!el) return
86
92
 
87
93
  if (!force && store.userScrolled) return
88
94
 
89
95
  const distance = distanceFromBottom(el)
96
+
90
97
  if (distance < 2) {
91
98
  markAuto(el)
99
+
92
100
  return
93
101
  }
94
102
 
@@ -99,11 +107,15 @@ export function createAutoScroll(options: AutoScrollOptions) {
99
107
 
100
108
  const stop = () => {
101
109
  const el = store.scrollRef
110
+
102
111
  if (!el) return
112
+
103
113
  if (!canScroll(el)) {
104
114
  if (store.userScrolled) setStore("userScrolled", false)
115
+
105
116
  return
106
117
  }
118
+
107
119
  if (store.userScrolled) return
108
120
 
109
121
  setStore("userScrolled", true)
@@ -118,27 +130,32 @@ export function createAutoScroll(options: AutoScrollOptions) {
118
130
  const el = store.scrollRef
119
131
  const target = e.target instanceof Element ? e.target : undefined
120
132
  const nested = target?.closest("[data-scrollable]")
133
+
121
134
  if (el && nested && nested !== el) return
122
135
  stop()
123
136
  }
124
137
 
125
138
  const handleScroll = () => {
126
139
  const el = store.scrollRef
140
+
127
141
  if (!el) return
128
142
 
129
143
  if (!canScroll(el)) {
130
144
  if (store.userScrolled) setStore("userScrolled", false)
145
+
131
146
  return
132
147
  }
133
148
 
134
149
  if (distanceFromBottom(el) < threshold()) {
135
150
  if (store.userScrolled) setStore("userScrolled", false)
151
+
136
152
  return
137
153
  }
138
154
 
139
155
  // Ignore scroll events triggered by our own scrollToBottom calls.
140
156
  if (!store.userScrolled && isAuto(el)) {
141
157
  scrollToBottom(false)
158
+
142
159
  return
143
160
  }
144
161
 
@@ -148,6 +165,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
148
165
  const handleInteraction = () => {
149
166
  if (!active()) return
150
167
  const selection = window.getSelection()
168
+
151
169
  if (selection && selection.toString().length > 0) {
152
170
  stop()
153
171
  }
@@ -158,11 +176,13 @@ export function createAutoScroll(options: AutoScrollOptions) {
158
176
 
159
177
  if (mode === "none") {
160
178
  el.style.overflowAnchor = "none"
179
+
161
180
  return
162
181
  }
163
182
 
164
183
  if (mode === "auto") {
165
184
  el.style.overflowAnchor = "auto"
185
+
166
186
  return
167
187
  }
168
188
 
@@ -173,11 +193,15 @@ export function createAutoScroll(options: AutoScrollOptions) {
173
193
  () => store.contentRef,
174
194
  () => {
175
195
  const el = store.scrollRef
196
+
176
197
  if (el && !canScroll(el)) {
177
198
  if (store.userScrolled) setStore("userScrolled", false)
199
+
178
200
  return
179
201
  }
202
+
180
203
  if (!active()) return
204
+
181
205
  if (store.userScrolled) return
182
206
  // ResizeObserver fires after layout, before paint.
183
207
  // Keep the bottom locked in the same frame to avoid visible
@@ -188,20 +212,26 @@ export function createAutoScroll(options: AutoScrollOptions) {
188
212
 
189
213
  createEffect(() => {
190
214
  const el = store.scrollRef
215
+
191
216
  if (!el) return
192
217
  const root = el.closest("main")
218
+
193
219
  if (!root) return
194
220
  let connected = el.isConnected
195
221
  const contains = (node: Node) => node === el || (node instanceof Element && node.contains(el))
222
+
196
223
  const observer = new MutationObserver((records) => {
197
224
  records.forEach((record) => {
198
225
  if ([...record.removedNodes].some(contains)) connected = false
226
+
199
227
  if (!record.addedNodes.length || ![...record.addedNodes].some(contains)) return
200
228
  const reattached = !connected
201
229
  connected = true
230
+
202
231
  if (reattached) scrollToBottom(false)
203
232
  })
204
233
  })
234
+
205
235
  observer.observe(root, { childList: true })
206
236
  onCleanup(() => observer.disconnect())
207
237
  })
@@ -209,11 +239,13 @@ export function createAutoScroll(options: AutoScrollOptions) {
209
239
  createEffect(
210
240
  on(options.working, (working: boolean) => {
211
241
  settling = false
242
+
212
243
  if (settleTimer) clearTimeout(settleTimer)
213
244
  settleTimer = undefined
214
245
 
215
246
  if (working) {
216
247
  if (!store.userScrolled) scrollToBottom(true)
248
+
217
249
  return
218
250
  }
219
251
 
@@ -229,6 +261,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
229
261
  // update overflow anchoring once the element exists.
230
262
  store.userScrolled
231
263
  const el = store.scrollRef
264
+
232
265
  if (!el) return
233
266
  updateOverflowAnchor(el)
234
267
  })
@@ -237,6 +270,7 @@ export function createAutoScroll(options: AutoScrollOptions) {
237
270
 
238
271
  onCleanup(() => {
239
272
  if (settleTimer) clearTimeout(settleTimer)
273
+
240
274
  if (autoTimer) clearTimeout(autoTimer)
241
275
  })
242
276
 
@@ -1,2 +1,3 @@
1
1
  export * from "./use-filtered-list"
2
+
2
3
  export * from "./create-auto-scroll"
@@ -21,6 +21,7 @@ export function useFilteredList<T>(props: FilteredListProps<T>) {
21
21
  const [store, setStore] = createStore<{ filter: string }>({ filter: "" })
22
22
 
23
23
  type Group = { category: string; items: [T, ...T[]] }
24
+
24
25
  const empty: Group[] = []
25
26
 
26
27
  const [grouped, { refetch }] = createResource(
@@ -32,6 +33,7 @@ export function useFilteredList<T>(props: FilteredListProps<T>) {
32
33
  const query = filter ?? ""
33
34
  const needle = query.toLowerCase()
34
35
  const all = (await Promise.resolve(items)) || []
36
+
35
37
  const result = pipe(
36
38
  all,
37
39
  (x) => {
@@ -39,10 +41,12 @@ export function useFilteredList<T>(props: FilteredListProps<T>) {
39
41
  const skipFilter = props.skipFilter
40
42
  const filterable = skipFilter ? x.filter((item) => !skipFilter(item)) : x
41
43
  const skipped = skipFilter ? x.filter(skipFilter) : []
44
+
42
45
  const filtered =
43
46
  !props.filterKeys && Array.isArray(filterable) && filterable.every((e) => typeof e === "string")
44
47
  ? (fuzzysort.go(needle, filterable).map((x) => x.target) as T[])
45
48
  : fuzzysort.go(needle, filterable, { keys: props.filterKeys! }).map((x) => x.obj)
49
+
46
50
  return skipped.length ? [...filtered, ...skipped] : filtered
47
51
  },
48
52
  groupBy((x) => (props.groupBy ? props.groupBy(x) : "")),
@@ -50,6 +54,7 @@ export function useFilteredList<T>(props: FilteredListProps<T>) {
50
54
  map(([k, v]) => ({ category: k, items: props.sortBy ? v.sort(props.sortBy) : v })),
51
55
  (groups) => (props.sortGroupsBy ? groups.sort(props.sortGroupsBy) : groups),
52
56
  )
57
+
53
58
  return result
54
59
  },
55
60
  { initialValue: empty },
@@ -64,10 +69,13 @@ export function useFilteredList<T>(props: FilteredListProps<T>) {
64
69
 
65
70
  function initialActive() {
66
71
  if (props.noInitialSelection) return ""
72
+
67
73
  if (props.current) return props.key(props.current)
68
74
 
69
75
  const items = flat()
76
+
70
77
  if (items.length === 0) return ""
78
+
71
79
  return props.key(items[0])
72
80
  }
73
81
 
@@ -80,9 +88,12 @@ export function useFilteredList<T>(props: FilteredListProps<T>) {
80
88
  const reset = () => {
81
89
  if (props.noInitialSelection) {
82
90
  list.setActive("")
91
+
83
92
  return
84
93
  }
94
+
85
95
  const all = flat()
96
+
86
97
  if (all.length === 0) return
87
98
  list.setActive(props.key(all[0]))
88
99
  }
@@ -92,14 +103,17 @@ export function useFilteredList<T>(props: FilteredListProps<T>) {
92
103
  event.preventDefault()
93
104
  const selectedIndex = flat().findIndex((x) => props.key(x) === list.active())
94
105
  const selected = flat()[selectedIndex]
106
+
95
107
  if (selected) props.onSelect?.(selected, selectedIndex)
96
108
  } else if (event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
97
109
  if (event.key === "n" || event.key === "p") {
98
110
  event.preventDefault()
111
+
99
112
  const navEvent = new KeyboardEvent("keydown", {
100
113
  key: event.key === "n" ? "ArrowDown" : "ArrowUp",
101
114
  bubbles: true,
102
115
  })
116
+
103
117
  list.onKeyDown(navEvent)
104
118
  }
105
119
  } else {
package/src/i18n/en.ts CHANGED
@@ -244,6 +244,7 @@ const source = {
244
244
  "ui.message.forkMessage": "Fork to new session",
245
245
  "ui.message.revertMessage": "Revert message",
246
246
  "ui.message.moveToQueue": "Move to queue",
247
+ "ui.message.pending": "Pending",
247
248
  "ui.message.deletePending": "Delete",
248
249
  "ui.message.copyResponse": "Copy response",
249
250
  "ui.message.copied": "Copied",
package/src/i18n/no.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { dict as en } from "./en"
2
+
2
3
  type Keys = keyof typeof en
3
4
 
4
5
  export const dict: Record<Keys, string> = {
@@ -186,6 +186,38 @@ const icons = {
186
186
  viewBox: "0 0 16 16",
187
187
  body: `<path d="M4.14908 11.0081H1.76282V1.51758H9.1038V2.55588M14.2225 4.99681H6.75397V14.4873H14.2225V4.99681Z" stroke="currentColor"/>`,
188
188
  },
189
+ "outline-arrow-left": {
190
+ viewBox: "0 0 16 16",
191
+ body: `<path d="M2.44442 7.99999H13.5555M6.22221 4.22222L2.44442 7.99999L6.22221 11.7778" stroke="currentColor"/>`,
192
+ },
193
+ "outline-arrow-right": {
194
+ viewBox: "0 0 16 16",
195
+ body: `<path d="M13.5555 7.99999H2.4444M9.77773 11.7778L13.5555 7.99999L9.77773 4.22222" stroke="currentColor"/>`,
196
+ },
197
+ "outline-arrow-up-right": {
198
+ viewBox: "0 0 16 16",
199
+ body: `<path d="M12.5 3.5L3.5 12.5M12.5 9.62L12.5 3.5L6.38 3.5" stroke="currentColor"/>`,
200
+ },
201
+ "outline-rotate-clockwise": {
202
+ viewBox: "0 0 16 16",
203
+ body: `<path d="M14.1992 8C14.1992 9.18669 13.8473 10.3467 13.188 11.3334C12.5288 12.3201 11.5917 13.0892 10.4953 13.5433C9.39897 13.9974 8.19257 14.1162 7.02868 13.8847C5.86479 13.6532 4.7957 13.0818 3.95658 12.2426C3.11747 11.4035 2.54602 10.3344 2.31451 9.17054C2.083 8.00666 2.20182 6.80026 2.65594 5.7039C3.11007 4.60754 3.87911 3.67047 4.8658 3.01118C5.85249 2.35189 7.01253 2 8.19922 2C9.87922 2 11.4859 2.66667 12.6926 3.82667L14.1992 5.33333M10.866 5.33333L14.1992 5.33333L14.1993 2" stroke="currentColor" stroke-linecap="square" stroke-linejoin="round"/>`,
204
+ },
205
+ "outline-globe": {
206
+ viewBox: "0 0 16 16",
207
+ body: `<path d="M8.00001 14.4445C9.47277 14.4445 10.6667 11.5592 10.6667 8.00001C10.6667 4.44085 9.47277 1.55557 8.00001 1.55557M8.00001 14.4445C6.52725 14.4445 5.33335 11.5592 5.33335 8.00001C5.33335 4.44085 6.52725 1.55557 8.00001 1.55557M8.00001 14.4445C11.5592 14.4445 14.4444 11.5592 14.4444 8C14.4444 4.44083 11.5592 1.55557 8.00001 1.55557M8.00001 14.4445C4.44085 14.4445 1.55556 11.5592 1.55556 8C1.55556 4.44083 4.44085 1.55557 8.00001 1.55557M1.87203 6.00001H14.128M2.03555 10.4445H13.9644" stroke="currentColor"/>`,
208
+ },
209
+ "outline-globe-plus": {
210
+ viewBox: "0 0 16 16",
211
+ body: `<path d="M7 12.6667C5.71133 12.6667 4.66667 10.1296 4.66667 7C4.66667 3.87039 5.71133 1.33333 7 1.33333C8.2426 1.33333 9.25833 3.69221 9.32933 6.66667" stroke="currentColor" stroke-miterlimit="10"/><path d="M12.6667 6.66667H1.33333" stroke="currentColor"/><path d="M12.6667 7.72825V7C12.6667 3.87039 10.1296 1.33333 7 1.33333C3.8704 1.33333 1.33333 3.87039 1.33333 7C1.33333 10.1296 3.8704 12.6667 7 12.6667H7.58694" stroke="currentColor" stroke-miterlimit="10"/><path d="M9.5 11.5H13.5M11.5 9.5V13.5" stroke="currentColor" stroke-miterlimit="10" stroke-linecap="square"/>`,
212
+ },
213
+ "outline-cookie": {
214
+ viewBox: "0 0 16 16",
215
+ body: `<path d="M14 8.5A6 6 0 1 1 7.5 2a2 2 0 0 0 2.5 2.5 2 2 0 0 0 2.5 2.5c.4.6.9 1.1 1.5 1.5Z" stroke="currentColor" stroke-linejoin="round"/><path d="M5.5 6.5h.01M5.5 10h.01M8.5 9h.01M10.5 11.5h.01" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>`,
216
+ },
217
+ "outline-browser-annotate": {
218
+ viewBox: "0 0 16 16",
219
+ body: `<path d="M10.6667 2H14V5.33333M2 5.33333V2H5.33333M2 10.6667V14H5.33333" stroke="currentColor" stroke-linecap="square"/><path d="M11.8571 11.8572L14 14M6.50008 6.50033L14.0001 9.00033L9.00008 14.0003L6.50008 6.50033Z" stroke="currentColor" stroke-linecap="square"/>`,
220
+ },
189
221
  "arrow-up-right": {
190
222
  viewBox: "0 0 16 16",
191
223
  body: `<path d="M11 9.56V5H6.44M11 5L5 11" stroke="currentColor"/>`,
@@ -222,6 +254,10 @@ const icons = {
222
254
  viewBox: "0 0 20 20",
223
255
  body: `<path d="M5.83333 4.16406L2.5 7.4974L5.83333 10.8307M3.33333 7.4974H17.9167V15.4141H10" stroke="currentColor" stroke-linecap="square"/>`,
224
256
  },
257
+ "outline-undo": {
258
+ viewBox: "0 0 16 16",
259
+ body: `<path d="M2 10L4.25193 7.76999C7.29213 4.7594 12.4119 5.77372 14.0747 9.71606" stroke="currentColor"/><path d="M2 6V10H6" stroke="currentColor" stroke-linecap="square"/>`,
260
+ },
225
261
  "outline-reset": {
226
262
  viewBox: "0 0 20 20",
227
263
  body: `<path d="M5.83333 4.16406L2.5 7.4974L5.83333 10.8307M3.33333 7.4974H17.9167V15.4141H10" stroke="currentColor" stroke-linecap="square"/>`,
@@ -63,6 +63,8 @@ export function Icon(props: IconProps) {
63
63
  data-directional={
64
64
  iconName() === "arrow-left" ||
65
65
  iconName() === "arrow-right" ||
66
+ iconName() === "outline-arrow-left" ||
67
+ iconName() === "outline-arrow-right" ||
66
68
  iconName() === "chevron-left" ||
67
69
  iconName() === "chevron-right"
68
70
  ? ""
@@ -5,6 +5,7 @@ export interface DividerProps extends ComponentProps<"div"> {}
5
5
 
6
6
  export function Divider(props: DividerProps) {
7
7
  const [local, rest] = splitProps(props, ["class", "classList"])
8
+
8
9
  return (
9
10
  <div
10
11
  {...rest}