blob: 6cfd7f126a8f1984d12ed39e8de1c2c9365e7699 [file]
import 'dart:async';
import 'package:jaspr/dom.dart';
import 'package:jaspr/jaspr.dart';
import '../../../utils/styles.dart';
class TextButton extends StatelessComponent {
const TextButton({
required this.label,
this.onClick,
this.disabled = false,
this.isLoading = false,
this.tooltip,
this.classes,
this.icon,
this.iconSize = 18.0,
this.primary = true,
super.key,
});
final String label;
final FutureOr<void> Function()? onClick;
final bool disabled;
final bool isLoading;
final String? tooltip;
final String? classes;
final Component? icon;
final double iconSize;
final bool primary;
@override
Component build(BuildContext context) {
final isDisabled = disabled || isLoading;
final classNames = [
'text-button',
if (primary) 'primary',
if (classes case final extraClasses? when extraClasses.isNotEmpty) extraClasses,
].join(' ');
final attributes = <String, String>{};
if (tooltip != null) {
attributes['title'] = tooltip!;
}
if (isDisabled) {
attributes['disabled'] = 'true';
}
final displayIcon = isLoading ? const div(classes: 'text-button-spinner', []) : icon;
return button(
classes: classNames,
attributes: attributes,
onClick: isDisabled ? null : onClick,
[
?displayIcon,
.text(label),
],
);
}
@css
static List<StyleRule> get styles => [
css('.text-button', [
css('&').styles(
display: .inlineFlex,
padding: .symmetric(vertical: 5.px, horizontal: 8.px),
border: .all(color: colorBorder, width: 1.px),
radius: .circular(6.px),
outline: const Outline(style: .none),
cursor: .pointer,
transition: Transition.combine([
Transition('background-color', duration: 200.ms, curve: .ease),
Transition('border-color', duration: 200.ms, curve: .ease),
Transition('color', duration: 200.ms, curve: .ease),
]),
justifyContent: .center,
alignItems: .center,
gap: Gap.all(6.px),
color: colorOnSurface,
fontSize: 13.px,
fontWeight: .w500,
whiteSpace: .noWrap,
backgroundColor: colorContainer,
),
css('&:not(:disabled):hover').styles(
backgroundColor: colorContainerHigh,
),
css('&.primary:not(:disabled):hover').styles(
border: .all(color: colorPrimary, width: 1.px),
),
css('&:disabled').styles(
opacity: 0.5,
cursor: .notAllowed,
),
]),
css('.text-button-spinner').styles(
raw: {
'width': '12px',
'height': '12px',
'border': '2px solid currentColor',
'border-top-color': 'transparent',
'border-radius': '50%',
'animation': 'text-button-spin 0.8s linear infinite',
},
),
css.keyframes('text-button-spin', {
'0%': const Styles(raw: {'transform': 'rotate(0deg)'}),
'100%': const Styles(raw: {'transform': 'rotate(360deg)'}),
}),
];
}