60 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { Binding, Variable } from "astal";
 | 
						|
import { Gtk } from "astal/gtk4";
 | 
						|
import AstalApps from "gi://AstalApps";
 | 
						|
import Pango from "gi://Pango?version=1.0";
 | 
						|
 | 
						|
const MAX_ITEMS = 8;
 | 
						|
 | 
						|
const AppList = ({ hide, query, visible }: { hide: () => void, query: Variable<string>, visible: Binding<Boolean> }) => {
 | 
						|
    const apps = new AstalApps.Apps();
 | 
						|
    const list = query((text) => apps.fuzzy_query(text).slice(0, MAX_ITEMS));
 | 
						|
    return <box>
 | 
						|
        <box
 | 
						|
            spacing={6}
 | 
						|
            vertical
 | 
						|
            cssClasses={["app-list"]}
 | 
						|
            visible={list.as(l => l.length > 0)}
 | 
						|
        >
 | 
						|
            {list.as(l => l.map(app => <AppButton app={app} hide={hide}></AppButton>))}
 | 
						|
        </box>
 | 
						|
        <box
 | 
						|
            halign={Gtk.Align.CENTER}
 | 
						|
            cssClasses={["list-empty"]}
 | 
						|
            vertical
 | 
						|
            visible={list.as(l => l.length === 0)}
 | 
						|
        >
 | 
						|
            <image iconName={"system-search-symbolic"}></image>
 | 
						|
            <label label={"No match found"}></label>
 | 
						|
        </box>
 | 
						|
    </box>
 | 
						|
}
 | 
						|
 | 
						|
const AppButton = ({ app, hide }: { app: AstalApps.Application, hide: () => void }) => {
 | 
						|
    return <button
 | 
						|
        onClicked={() => {
 | 
						|
            hide();
 | 
						|
            app.launch();
 | 
						|
        }}
 | 
						|
        child={
 | 
						|
            <box>
 | 
						|
                <image iconName={app.iconName}></image>
 | 
						|
                <box valign={Gtk.Align.CENTER} vertical>
 | 
						|
                    <label
 | 
						|
                        cssClasses={["title-2"]}
 | 
						|
                        ellipsize={Pango.EllipsizeMode.END}
 | 
						|
                        maxWidthChars={40}
 | 
						|
                        xalign={0}
 | 
						|
                        label={app.name}
 | 
						|
                    ></label>
 | 
						|
                    <label
 | 
						|
                        wrap xalign={0}
 | 
						|
                        label={app.description}
 | 
						|
                    ></label>
 | 
						|
                </box>
 | 
						|
            </box>
 | 
						|
        }>
 | 
						|
    </button>
 | 
						|
}
 | 
						|
 | 
						|
export default AppList;
 |