feat(button): icon button

This commit is contained in:
kunish 2023-09-22 16:05:36 +08:00
parent 9cc99ebb8e
commit 5ef8410da5
No known key found for this signature in database
GPG Key ID: 647A12B4F782C430
6 changed files with 76 additions and 66 deletions

View File

@ -5,13 +5,22 @@ export const Button: ParentComponent<
JSX.ButtonHTMLAttributes<HTMLButtonElement> & { JSX.ButtonHTMLAttributes<HTMLButtonElement> & {
loading?: boolean loading?: boolean
disabled?: boolean disabled?: boolean
icon?: JSX.Element
} }
> = (props) => { > = (props) => {
const [local, others] = splitProps(props, ['class', 'loading', 'disabled']) const [local, others] = splitProps(props, [
'class',
'loading',
'disabled',
'icon',
])
return ( return (
<button <button
class={twMerge('btn', local.loading ? 'btn-disabled' : local.class)} class={twMerge(
'btn flex items-center',
local.loading ? 'btn-disabled' : local.class,
)}
{...others} {...others}
onClick={(e) => { onClick={(e) => {
if (props.disabled) { if (props.disabled) {
@ -27,10 +36,17 @@ export const Button: ParentComponent<
}} }}
> >
<Show when={local.loading}> <Show when={local.loading}>
<span class="loading loading-spinner" /> <div class="loading loading-spinner" />
</Show> </Show>
{props.children} <span
class="truncate"
classList={{
'flex-1': !local.icon,
}}
>
{props.icon || props.children}
</span>
</button> </button>
) )
} }

View File

@ -159,9 +159,8 @@ export const Header = () => {
locale(curLocale === LANG.EN ? LANG.ZH : LANG.EN) locale(curLocale === LANG.EN ? LANG.ZH : LANG.EN)
}} }}
> icon={<IconLanguage />}
<IconLanguage /> />
</Button>
<ThemeSwitcher /> <ThemeSwitcher />
</div> </div>

View File

@ -217,7 +217,7 @@ const ConfigForm = () => {
</For> </For>
</form> </form>
<div class="flex flex-wrap items-center justify-center gap-2"> <div class="grid grid-cols-2 gap-2 sm:grid-cols-3">
<Button <Button
class="btn-primary" class="btn-primary"
loading={reloadingConfigFile()} loading={reloadingConfigFile()}
@ -241,9 +241,7 @@ const ConfigForm = () => {
> >
{t('flushFakeIP')} {t('flushFakeIP')}
</Button> </Button>
</div>
<div class="flex flex-wrap items-center justify-center gap-2">
<Button <Button
class="btn-error" class="btn-error"
loading={upgradingBackend()} loading={upgradingBackend()}

View File

@ -109,9 +109,8 @@ export default () => {
modal?.showModal() modal?.showModal()
}} }}
> icon={<IconInfoSmall size="16" />}
<IconInfoSmall size="16" /> />
</Button>
</div> </div>
), ),
}, },
@ -127,9 +126,8 @@ export default () => {
<Button <Button
class="btn-circle btn-xs" class="btn-circle btn-xs"
onClick={() => closeSingleConnectionAPI(row.original.id)} onClick={() => closeSingleConnectionAPI(row.original.id)}
> icon={<IconX size="16" />}
<IconX size="16" /> />
</Button>
</div> </div>
), ),
}, },
@ -348,7 +346,7 @@ export default () => {
</div> </div>
<select <select
class="join-item select select-bordered select-primary" class="select join-item select-bordered select-primary"
onChange={(e) => setSourceIPFilter(e.target.value)} onChange={(e) => setSourceIPFilter(e.target.value)}
> >
<option value="">{t('all')}</option> <option value="">{t('all')}</option>
@ -380,9 +378,8 @@ export default () => {
<Button <Button
class="join-item btn-sm sm:btn-md" class="join-item btn-sm sm:btn-md"
onClick={() => setPaused((paused) => !paused)} onClick={() => setPaused((paused) => !paused)}
> icon={paused() ? <IconPlayerPlay /> : <IconPlayerPause />}
{paused() ? <IconPlayerPlay /> : <IconPlayerPause />} />
</Button>
<Button <Button
class="join-item btn-sm sm:btn-md" class="join-item btn-sm sm:btn-md"
@ -395,9 +392,8 @@ export default () => {
closeAllConnectionsAPI() closeAllConnectionsAPI()
} }
}} }}
> icon={<IconX />}
<IconX /> />
</Button>
<Button <Button
class="btn join-item btn-sm sm:btn-md" class="btn join-item btn-sm sm:btn-md"
@ -408,9 +404,8 @@ export default () => {
modal?.showModal() modal?.showModal()
}} }}
> icon={<IconSettings />}
<IconSettings /> />
</Button>
</div> </div>
</div> </div>

View File

@ -146,9 +146,8 @@ export default () => {
modal?.showModal() modal?.showModal()
}} }}
> icon={<IconSettings />}
<IconSettings /> />
</Button>
</div> </div>
<div class="overflow-x-auto whitespace-nowrap rounded-md bg-base-300"> <div class="overflow-x-auto whitespace-nowrap rounded-md bg-base-300">

View File

@ -98,7 +98,7 @@ export default () => {
return ( return (
<div class="flex h-full flex-col gap-2"> <div class="flex h-full flex-col gap-2">
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<div class="tabs-boxed tabs gap-2"> <div class="tabs tabs-boxed gap-2">
<For each={tabs()}> <For each={tabs()}>
{(tab) => ( {(tab) => (
<button <button
@ -120,13 +120,14 @@ export default () => {
class="btn btn-circle btn-sm" class="btn btn-circle btn-sm"
disabled={isAllProviderUpdating()} disabled={isAllProviderUpdating()}
onClick={(e) => onUpdateAllProviderClick(e)} onClick={(e) => onUpdateAllProviderClick(e)}
> icon={
<IconReload <IconReload
class={twMerge( class={twMerge(
isAllProviderUpdating() && 'animate-spin text-success', isAllProviderUpdating() && 'animate-spin text-success',
)} )}
/> />
</Button> }
/>
</Show> </Show>
<div class="ml-auto"> <div class="ml-auto">
@ -139,9 +140,8 @@ export default () => {
modal?.showModal() modal?.showModal()
}} }}
> icon={<IconSettings />}
<IconSettings /> />
</Button>
</div> </div>
</div> </div>
@ -176,14 +176,15 @@ export default () => {
class="btn-circle btn-sm" class="btn-circle btn-sm"
disabled={latencyTestingMap()[proxyGroup.name]} disabled={latencyTestingMap()[proxyGroup.name]}
onClick={(e) => onLatencyTestClick(e, proxyGroup.name)} onClick={(e) => onLatencyTestClick(e, proxyGroup.name)}
> icon={
<IconBrandSpeedtest <IconBrandSpeedtest
class={twMerge( class={twMerge(
latencyTestingMap()[proxyGroup.name] && latencyTestingMap()[proxyGroup.name] &&
'animate-pulse text-success', 'animate-pulse text-success',
)} )}
/> />
</Button> }
/>
</div> </div>
<div class="text-sm text-slate-500"> <div class="text-sm text-slate-500">
@ -242,21 +243,22 @@ export default () => {
</div> </div>
</div> </div>
<div> <div class="flex items-center gap-2">
<Button <Button
class="btn btn-circle btn-sm mr-2" class="btn btn-circle btn-sm"
disabled={updatingMap()[proxyProvider.name]} disabled={updatingMap()[proxyProvider.name]}
onClick={(e) => onClick={(e) =>
onUpdateProviderClick(e, proxyProvider.name) onUpdateProviderClick(e, proxyProvider.name)
} }
> icon={
<IconReload <IconReload
class={twMerge( class={twMerge(
updatingMap()[proxyProvider.name] && updatingMap()[proxyProvider.name] &&
'animate-spin text-success', 'animate-spin text-success',
)} )}
/> />
</Button> }
/>
<Button <Button
class="btn btn-circle btn-sm" class="btn btn-circle btn-sm"
@ -264,14 +266,15 @@ export default () => {
onClick={(e) => onClick={(e) =>
onHealthCheckClick(e, proxyProvider.name) onHealthCheckClick(e, proxyProvider.name)
} }
> icon={
<IconBrandSpeedtest <IconBrandSpeedtest
class={twMerge( class={twMerge(
healthCheckingMap()[proxyProvider.name] && healthCheckingMap()[proxyProvider.name] &&
'animate-pulse text-success', 'animate-pulse text-success',
)} )}
/> />
</Button> }
/>
</div> </div>
</div> </div>