Skip to content

Commit ea75c92

Browse files
authored
release: v0.2.0 (#34)
* feat: resizeable cols (#31) * ✨ resizeable * ♻️ use js resizeable * 🏗️ common code * ✨ close modal after command * ✨ split command * 📝 release note * 🔥 remove useless styles * ✨ npm readme (#33) * ✨ npm readme * 🔇 debug console * ➕ lodash-es * 📝 update screenshot and feature list * 📝 update image link
1 parent 7aaa787 commit ea75c92

25 files changed

+2773
-1909
lines changed

.changeset/purple-eggs-yawn.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"vsit": minor
3+
---
4+
5+
resizeable commands

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212

13-
![vsit-screenshot](https://user-images.githubusercontent.com/6839576/283995715-d376f1d5-03be-494d-8b80-15cd6239e442.png)
13+
![vsit-screenshot](https://raw.githubusercontent.com/JiangWeixian/vsit/main/assets/vsit.png)
1414

1515

1616
```
@@ -21,6 +21,9 @@ vsit
2121
## features
2222

2323
- 💞 Import packages from [`esm.sh`](https://esm.sh/) without installed
24+
- 🎹 Manage window, run code, format code with commands
25+
- 💪 Typescript support
26+
2427
## development
2528

2629
- **Setup** - `pnpm i`

assets/vsit.png

1.27 MB
Loading

eslint.config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
const { aiou } = require('@aiou/eslint-config')
22

3-
module.exports = aiou([
3+
module.exports = aiou({ ssr: false }, [
44
{
55
ignores: ['**/dist/**', '**/dist-client/**', '**/vendors/**'],
66
},
77
{
8-
files: ['**/**'],
8+
files: ['**/**.ts'],
99
rules: {
1010
'import/no-extraneous-dependencies': 'off',
1111
'ssr-friendly/no-dom-globals-in-module-scope': 'off',

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@
3838
"**/**/*.{js,ts,tsx,vue,json}": ["eslint --fix"]
3939
},
4040
"devDependencies": {
41-
"@aiou/eslint-config": "^1.0.6",
41+
"@aiou/eslint-config": "1.3.0",
4242
"@changesets/cli": "^2.24.4",
4343
"@types/fs-extra": "^11.0.1",
4444
"@types/node": "^20.1.3",
4545
"cz-emoji": "1.3.2-canary.2",
46-
"eslint": "^8.23.0",
46+
"eslint": "8.57.0",
4747
"esno": "^0.16.3",
4848
"fs-extra": "^11.1.1",
4949
"husky": "^8.0.1",

packages/client/package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,30 @@
3838
"@codemirror/state": "6.2.1",
3939
"@codemirror/view": "6.13.0",
4040
"@lezer/highlight": "1.1.6",
41+
"@solid-primitives/scheduled": "1.4.3",
4142
"@tailwindcss/typography": "0.5.7",
4243
"@uiw/codemirror-theme-atomone": "^4.21.2",
4344
"clsx": "1.2.1",
4445
"console-feed": "3.5.0",
46+
"css.gg": "^2.1.1",
4547
"daisyui": "2.24.0",
4648
"focus-if-need": "^0.1.0",
4749
"lodash-es": "^4.17.21",
50+
"markdown-it": "^14.1.0",
4851
"prettier": "^3.0.0",
49-
"solid-js": "1.7.6",
52+
"solid-js": "1.8.17",
5053
"workbox-routing": "7.0.0",
5154
"workbox-strategies": "7.0.0"
5255
},
5356
"devDependencies": {
5457
"@svgr-rs/svgrs-plugin": "^0.1.0",
5558
"@types/debug": "^4.1.8",
5659
"@types/lodash-es": "^4.17.8",
60+
"@types/markdown-it": "^14.0.1",
5761
"@types/node": "^20.1.3",
5862
"autoprefixer": "10.4.8",
5963
"postcss": "8.4.16",
60-
"tailwind-cssgg": "^0.0.1",
64+
"tailwind-cssgg": "^0.2.0",
6165
"tailwindcss": "3.3.2",
6266
"typescript": "4.4.4",
6367
"vite": "^4.3.8",

packages/client/src/components/cmdk/cmdk.tsx

+45-32
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
Show,
1919
useContext,
2020
} from 'solid-js'
21+
import { createStore } from 'solid-js/store'
2122

2223
import { commandScore } from './command-score'
2324

@@ -131,6 +132,7 @@ interface Context {
131132
interface State {
132133
search: string
133134
value: string
135+
enter: string
134136
filtered: { count: number; items: Map<string, number>; groups: Set<string> }
135137
}
136138
interface Store {
@@ -150,7 +152,6 @@ const GROUP_ITEMS_SELECTOR = '[cmdk-group-items=""]'
150152
const GROUP_HEADING_SELECTOR = '[cmdk-group-heading=""]'
151153
const ITEM_SELECTOR = '[cmdk-item=""]'
152154
const VALID_ITEM_SELECTOR = `${ITEM_SELECTOR}:not([aria-disabled="true"])`
153-
const SELECT_EVENT = 'cmdk-item-select'
154155
const VALUE_ATTR = 'data-value'
155156
const defaultFilter: CommandProps['filter'] = (value, search) => commandScore(value, search)
156157

@@ -163,6 +164,8 @@ const StoreContext = createContext<Store>({
163164
search: '',
164165
/** Currently selected item value. */
165166
value: '',
167+
/** Currently item value when press key enter. */
168+
enter: '',
166169
filtered: {
167170
/** The count of all visible items. */
168171
count: 0,
@@ -216,6 +219,7 @@ export const Command = (props: CommandProps) => {
216219
search: '',
217220
/** Currently selected item value. */
218221
value: props.value ?? props.defaultValue?.toLowerCase() ?? '',
222+
enter: '',
219223
filtered: {
220224
/** The count of all visible items. */
221225
count: 0,
@@ -240,7 +244,7 @@ export const Command = (props: CommandProps) => {
240244
const schedule = useScheduleLayoutEffect()
241245

242246
// TODO
243-
const [store] = createSignal<Store>({
247+
const [store] = createStore<Store>({
244248
subscribe: (cb) => {
245249
listeners.current?.add(cb)
246250
return () => listeners.current?.delete(cb)
@@ -273,7 +277,7 @@ export const Command = (props: CommandProps) => {
273277
}
274278

275279
// Notify subscribers that state has changed
276-
store().emit()
280+
store.emit()
277281
},
278282
emit: () => {
279283
listeners.current.forEach(l => l())
@@ -286,19 +290,19 @@ export const Command = (props: CommandProps) => {
286290
const v = value.trim().toLowerCase()
287291
state.current.value = v
288292
schedule(6, scrollSelectedIntoView)
289-
store().emit()
293+
store.emit()
290294
}
291295
}, [value])
292296

293-
const [context] = createSignal<Context>({
297+
const [context] = createStore<Context>({
294298
// Keep id → value mapping up-to-date
295299
value: (id, value) => {
296300
if (value !== ids.current.get(id)) {
297301
ids.current.set(id, value)
298302
state.current.filtered.items.set(id, score(value))
299303
schedule(2, () => {
300304
sort()
301-
store().emit()
305+
store.emit()
302306
})
303307
}
304308
},
@@ -326,7 +330,7 @@ export const Command = (props: CommandProps) => {
326330
selectFirstItem()
327331
}
328332

329-
store().emit()
333+
store.emit()
330334
})
331335

332336
return () => {
@@ -345,7 +349,7 @@ export const Command = (props: CommandProps) => {
345349
selectFirstItem()
346350
}
347351

348-
store().emit()
352+
store.emit()
349353
})
350354
}
351355
},
@@ -436,7 +440,7 @@ export const Command = (props: CommandProps) => {
436440
function selectFirstItem() {
437441
const item = getValidItems().find(item => !item.ariaDisabled)!
438442
const value = item.getAttribute(VALUE_ATTR)!
439-
store().setState('value', value || undefined)
443+
store.setState('value', value || undefined)
440444
}
441445

442446
/** Filters the current items. */
@@ -508,7 +512,7 @@ export const Command = (props: CommandProps) => {
508512
const items = getValidItems()
509513
const item = items[index]
510514
if (item) {
511-
store().setState('value', item.getAttribute(VALUE_ATTR))
515+
store.setState('value', item.getAttribute(VALUE_ATTR))
512516
}
513517
}
514518

@@ -530,7 +534,7 @@ export const Command = (props: CommandProps) => {
530534
}
531535

532536
if (newSelected) {
533-
store().setState('value', newSelected.getAttribute(VALUE_ATTR))
537+
store.setState('value', newSelected.getAttribute(VALUE_ATTR))
534538
}
535539
}
536540

@@ -545,7 +549,7 @@ export const Command = (props: CommandProps) => {
545549
}
546550

547551
if (item) {
548-
store().setState('value', item.getAttribute(VALUE_ATTR)!)
552+
store.setState('value', item.getAttribute(VALUE_ATTR)!)
549553
} else {
550554
updateSelectedByChange(change)
551555
}
@@ -634,8 +638,8 @@ export const Command = (props: CommandProps) => {
634638
e.preventDefault()
635639
const item = getSelectedItem()
636640
if (item) {
637-
const event = new Event(SELECT_EVENT)
638-
item.dispatchEvent(event)
641+
const value = item.getAttribute(VALUE_ATTR)!
642+
store.setState('enter', value)
639643
}
640644
}
641645
}
@@ -644,15 +648,15 @@ export const Command = (props: CommandProps) => {
644648
>
645649
<label
646650
cmdk-label=""
647-
for={context().inputId}
648-
id={context().labelId}
651+
for={context.inputId}
652+
id={context.labelId}
649653
// Screen reader only
650654
style={srOnlyStyles}
651655
>
652656
{label}
653657
</label>
654-
<StoreContext.Provider value={store()}>
655-
<CommandContext.Provider value={context()}>{props.children}</CommandContext.Provider>
658+
<StoreContext.Provider value={store}>
659+
<CommandContext.Provider value={context}>{props.children}</CommandContext.Provider>
656660
</StoreContext.Provider>
657661
</div>
658662
)
@@ -678,27 +682,34 @@ export const CommandItem = (props: ItemProps) => {
678682
const value = useValue(id, ref, [props.value, props.children, ref])
679683

680684
const store = useStore()!
681-
const selected = useCmdk(state => state?.value && state?.value === value.current)
682-
const render = useCmdk(state =>
683-
forceMount ? true : context.filter?.() === false ? true : !state.search ? true : (state.filtered?.items?.get?.(id) as number) > 0,
684-
)
685+
const selected = useCmdk((state) => {
686+
return state?.value && state?.value === value()
687+
})
688+
const entered = useCmdk(state => state?.enter)
689+
const render = useCmdk((state) => {
690+
return forceMount
691+
? true
692+
: context.filter?.() === false
693+
? true
694+
: !state.search
695+
? true
696+
: (state.filtered?.items?.get?.(id) as number) > 0
697+
})
685698

686699
createEffect(() => {
687-
const element = ref.current
688-
if (!element || props.disabled) {
689-
return
700+
if (entered() === value()) {
701+
onSelect()
702+
store.setState('enter', '')
690703
}
691-
element.addEventListener(SELECT_EVENT, onSelect)
692-
onCleanup(() => element.removeEventListener(SELECT_EVENT, onSelect))
693704
})
694705

695706
function onSelect() {
696707
select()
697-
propsRef.current?.onSelect?.(value.current!)
708+
propsRef.current?.onSelect?.(value()!)
698709
}
699710

700711
function select() {
701-
store.setState('value', value.current!, true)
712+
store.setState('value', value()!, true)
702713
}
703714

704715
const { disabled, value: _, onSelect: __, forwardedRef, ...etc } = props
@@ -717,6 +728,7 @@ export const CommandItem = (props: ItemProps) => {
717728
data-selected={selected() || undefined}
718729
onPointerMove={disabled ? undefined : select}
719730
onClick={disabled ? undefined : onSelect}
731+
data-value={value()}
720732
>
721733
{props.children}
722734
</div>
@@ -1016,7 +1028,7 @@ function useValue(
10161028
ref: ReactRef<HTMLElement>,
10171029
deps: (JSX.Element | ReactRef<HTMLElement> | string)[],
10181030
) {
1019-
const valueRef: ReactRef<string> = {}
1031+
const [v, setValue] = createSignal<string>()
10201032
const context = useCommand()
10211033

10221034
onMount(() => {
@@ -1033,9 +1045,10 @@ function useValue(
10331045
})()
10341046

10351047
context.value?.(id, value!)
1048+
// TODO: looks like we do not need update ref data-value
10361049
ref.current?.setAttribute(VALUE_ATTR, value!)
1037-
valueRef.current = value
1050+
setValue(value)
10381051
})
10391052

1040-
return valueRef
1053+
return v
10411054
}

0 commit comments

Comments
 (0)