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

View File

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

View File

@ -217,7 +217,7 @@ const ConfigForm = () => {
</For>
</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
class="btn-primary"
loading={reloadingConfigFile()}
@ -241,9 +241,7 @@ const ConfigForm = () => {
>
{t('flushFakeIP')}
</Button>
</div>
<div class="flex flex-wrap items-center justify-center gap-2">
<Button
class="btn-error"
loading={upgradingBackend()}

View File

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

View File

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

View File

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