mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: improve UI design on Desktop (#5792)
* fix: only show collapse page button when the children of the page is not emtpy * chore: set minimum sidebar width to 268 * chore: replace space lock icon and pin & unpin icon * chore: change divider color * chore: update divider color * chore: improve create space color * feat: highlight delete button when hovering * chore: update translations * fix: icon align issue * feat: highlight sidebar resizer when hovering * feat: add border to popover * feat: optimize scroll bar * feat: improve scrollbar hover color * feat: support creating a new page via cmd+n * chore: improve scrollbar color * feat: improve tooltip style * chore: fix unit test * chore: bump version 0.6.6
This commit is contained in:
parent
a2e211555e
commit
29fb4af40a
@ -26,7 +26,7 @@ CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true
|
||||
CARGO_MAKE_CRATE_FS_NAME = "dart_ffi"
|
||||
CARGO_MAKE_CRATE_NAME = "dart-ffi"
|
||||
LIB_NAME = "dart_ffi"
|
||||
APPFLOWY_VERSION = "0.6.5"
|
||||
APPFLOWY_VERSION = "0.6.6"
|
||||
FLUTTER_DESKTOP_FEATURES = "dart"
|
||||
PRODUCT_NAME = "AppFlowy"
|
||||
MACOSX_DEPLOYMENT_TARGET = "11.0"
|
||||
|
@ -1,16 +1,14 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/shared/window_title_bar.dart';
|
||||
import 'package:appflowy/util/theme_extension.dart';
|
||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class CocoaWindowChannel {
|
||||
@ -104,19 +102,17 @@ class MoveWindowDetectorState extends State<MoveWindowDetector> {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final color = Theme.of(context).isLightMode ? Colors.white : Colors.black;
|
||||
final textSpan = TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${LocaleKeys.sideBar_openSidebar.tr()}\n',
|
||||
style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: color),
|
||||
style: context.tooltipTextStyle(),
|
||||
),
|
||||
TextSpan(
|
||||
text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyMedium!
|
||||
.copyWith(color: Theme.of(context).hintColor),
|
||||
style: context
|
||||
.tooltipTextStyle()
|
||||
?.copyWith(color: Theme.of(context).hintColor),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -1,5 +1,3 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/plugins/database/application/calculations/calculation_type_ext.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/field_info.dart';
|
||||
import 'package:appflowy/plugins/database/application/field/type_option/number_format_bloc.dart';
|
||||
@ -16,6 +14,7 @@ import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class CalculateCell extends StatefulWidget {
|
||||
@ -141,11 +140,14 @@ class _CalculateCellState extends State<CalculateCell> {
|
||||
TextSpan(
|
||||
text: widget.calculation!.calculationType.shortLabel
|
||||
.toUpperCase(),
|
||||
style: context.tooltipTextStyle(),
|
||||
),
|
||||
const TextSpan(text: ' '),
|
||||
TextSpan(
|
||||
text: calculateValue,
|
||||
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||
style: context
|
||||
.tooltipTextStyle()
|
||||
?.copyWith(fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -91,10 +91,8 @@ class _AlignmentButtonsState extends State<_AlignmentButtons> {
|
||||
margin: const EdgeInsets.all(4),
|
||||
direction: PopoverDirection.bottomWithCenterAligned,
|
||||
offset: const Offset(0, 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.onTertiary,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
),
|
||||
decorationColor: Theme.of(context).colorScheme.onTertiary,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||
popupBuilder: (_) {
|
||||
keepEditorFocusNotifier.increase();
|
||||
return _AlignButtons(onAlignChanged: widget.onAlignChanged);
|
||||
|
@ -12,7 +12,6 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/decoration.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:provider/provider.dart';
|
||||
@ -118,10 +117,6 @@ class _SmartEditBlockComponentWidgetState
|
||||
triggerActions: PopoverTriggerFlags.none,
|
||||
margin: EdgeInsets.zero,
|
||||
constraints: BoxConstraints(maxWidth: width),
|
||||
decoration: FlowyDecoration.decoration(
|
||||
Colors.transparent,
|
||||
Colors.transparent,
|
||||
),
|
||||
child: const SizedBox(
|
||||
width: double.infinity,
|
||||
),
|
||||
|
@ -1,9 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DesktopAppearance extends BaseAppearance {
|
||||
@override
|
||||
@ -75,18 +74,12 @@ class DesktopAppearance extends BaseAppearance {
|
||||
contentTextStyle: TextStyle(color: colorScheme.onSurface),
|
||||
),
|
||||
scrollbarTheme: ScrollbarThemeData(
|
||||
thumbColor: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.any(scrollbarInteractiveStates.contains)) {
|
||||
return theme.shader3;
|
||||
}
|
||||
return theme.shader5;
|
||||
}),
|
||||
thickness: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.any(scrollbarInteractiveStates.contains)) {
|
||||
return 4;
|
||||
}
|
||||
return 3.0;
|
||||
}),
|
||||
thumbColor: WidgetStateProperty.resolveWith(
|
||||
(states) => states.any(scrollbarInteractiveStates.contains)
|
||||
? theme.scrollbarHoverColor
|
||||
: theme.scrollbarColor,
|
||||
),
|
||||
thickness: WidgetStateProperty.resolveWith((_) => 4.0),
|
||||
crossAxisMargin: 0.0,
|
||||
mainAxisMargin: 6.0,
|
||||
radius: Corners.s10Radius,
|
||||
@ -147,6 +140,9 @@ class DesktopAppearance extends BaseAppearance {
|
||||
),
|
||||
onBackground: theme.text,
|
||||
background: theme.surface,
|
||||
borderColor: theme.borderColor,
|
||||
scrollbarColor: theme.scrollbarColor,
|
||||
scrollbarHoverColor: theme.scrollbarHoverColor,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -1,11 +1,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// ThemeData in mobile
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mobile_toolbar_v3/aa_menu/_toolbar_theme.dart';
|
||||
import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MobileAppearance extends BaseAppearance {
|
||||
static const _primaryColor = Color(0xFF00BCF0); //primary 100
|
||||
@ -276,6 +275,9 @@ class MobileAppearance extends BaseAppearance {
|
||||
),
|
||||
onBackground: onBackground,
|
||||
background: background,
|
||||
borderColor: theme.borderColor,
|
||||
scrollbarColor: theme.scrollbarColor,
|
||||
scrollbarHoverColor: theme.scrollbarHoverColor,
|
||||
),
|
||||
ToolbarColorExtension.fromBrightness(brightness),
|
||||
],
|
||||
|
@ -1,6 +1,3 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/plugins/blank/blank.dart';
|
||||
import 'package:appflowy/startup/plugin/plugin.dart';
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
@ -27,12 +24,13 @@ import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
|
||||
show UserProfilePB;
|
||||
import 'package:flowy_infra_ui/style_widget/container.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:sized_context/sized_context.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
import '../widgets/edit_panel/edit_panel.dart';
|
||||
|
||||
import '../widgets/sidebar_resizer.dart';
|
||||
import 'home_layout.dart';
|
||||
import 'home_stack.dart';
|
||||
|
||||
@ -164,7 +162,9 @@ class DesktopHomeScreen extends StatelessWidget {
|
||||
userProfile: userProfile,
|
||||
workspaceSetting: workspaceSetting,
|
||||
);
|
||||
final homeMenuResizer = _buildHomeMenuResizer(context, layout: layout);
|
||||
|
||||
final homeMenuResizer =
|
||||
layout.showMenu ? const SidebarResizer() : const SizedBox.shrink();
|
||||
final editPanel = _buildEditPanel(context, layout: layout);
|
||||
|
||||
return _layoutWidgets(
|
||||
@ -218,39 +218,6 @@ class DesktopHomeScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildHomeMenuResizer(
|
||||
BuildContext context, {
|
||||
required HomeLayout layout,
|
||||
}) {
|
||||
if (!layout.showMenu) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.resizeLeftRight,
|
||||
child: GestureDetector(
|
||||
dragStartBehavior: DragStartBehavior.down,
|
||||
onHorizontalDragStart: (details) => context
|
||||
.read<HomeSettingBloc>()
|
||||
.add(const HomeSettingEvent.editPanelResizeStart()),
|
||||
onHorizontalDragUpdate: (details) => context
|
||||
.read<HomeSettingBloc>()
|
||||
.add(HomeSettingEvent.editPanelResized(details.localPosition.dx)),
|
||||
onHorizontalDragEnd: (details) => context
|
||||
.read<HomeSettingBloc>()
|
||||
.add(const HomeSettingEvent.editPanelResizeEnd()),
|
||||
onHorizontalDragCancel: () => context
|
||||
.read<HomeSettingBloc>()
|
||||
.add(const HomeSettingEvent.editPanelResizeEnd()),
|
||||
behavior: HitTestBehavior.translucent,
|
||||
child: SizedBox(
|
||||
width: 10,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _layoutWidgets({
|
||||
required HomeLayout layout,
|
||||
required Widget sidebar,
|
||||
@ -296,7 +263,7 @@ class DesktopHomeScreen extends StatelessWidget {
|
||||
)
|
||||
.positioned(left: 0, top: 0, width: layout.menuWidth, bottom: 0),
|
||||
homeMenuResizer
|
||||
.positioned(left: layout.menuWidth - 5)
|
||||
.positioned(left: layout.menuWidth)
|
||||
.animate(layout.animDuration, Curves.easeOutQuad),
|
||||
],
|
||||
);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'dart:io' show Platform;
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
@ -16,6 +17,8 @@ class HomeLayout {
|
||||
menuWidth = Sizes.sideBarWidth;
|
||||
menuWidth += homeSetting.resizeOffset;
|
||||
|
||||
menuWidth = max(menuWidth, HomeSizes.minimumSidebarWidth);
|
||||
|
||||
final screenWidthPx = context.widthPx;
|
||||
context
|
||||
.read<HomeSettingBloc>()
|
||||
|
@ -8,6 +8,7 @@ class HomeSizes {
|
||||
static const double workspaceSectionHeight = 32;
|
||||
static const double searchSectionHeight = 30;
|
||||
static const double newPageSectionHeight = 30;
|
||||
static const double minimumSidebarWidth = 268;
|
||||
}
|
||||
|
||||
class HomeInsets {
|
||||
|
@ -1,7 +1,5 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/startup/startup.dart';
|
||||
import 'package:appflowy/startup/tasks/app_window_size_manager.dart';
|
||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||
@ -11,6 +9,7 @@ import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/sidebar_setting.dart';
|
||||
import 'package:appflowy_backend/log.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/user_profile.pb.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hotkey_manager/hotkey_manager.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:scaled_app/scaled_app.dart';
|
||||
@ -18,6 +17,7 @@ import 'package:scaled_app/scaled_app.dart';
|
||||
typedef KeyDownHandler = void Function(HotKey hotKey);
|
||||
|
||||
ValueNotifier<int> switchToTheNextSpace = ValueNotifier(0);
|
||||
ValueNotifier<int> createNewPageNotifier = ValueNotifier(0);
|
||||
|
||||
/// Helper class that utilizes the global [HotKeyManager] to easily
|
||||
/// add a [HotKey] with different handlers.
|
||||
@ -180,6 +180,16 @@ class _HomeHotKeysState extends State<HomeHotKeys> {
|
||||
keyDownHandler: (_) => switchToTheNextSpace.value++,
|
||||
),
|
||||
|
||||
// Create a new page
|
||||
HotKeyItem(
|
||||
hotKey: HotKey(
|
||||
KeyCode.keyN,
|
||||
modifiers: [Platform.isMacOS ? KeyModifier.meta : KeyModifier.control],
|
||||
scope: HotKeyScope.inapp,
|
||||
),
|
||||
keyDownHandler: (_) => createNewPageNotifier.value++,
|
||||
),
|
||||
|
||||
// Open settings dialog
|
||||
openSettingsHotKey(context, widget.userProfile),
|
||||
];
|
||||
|
@ -11,7 +11,6 @@ import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/decoration.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@ -172,11 +171,6 @@ class FavoriteMoreButton extends StatelessWidget {
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: minWidth,
|
||||
),
|
||||
decoration: FlowyDecoration.decoration(
|
||||
Theme.of(context).cardColor,
|
||||
Theme.of(context).colorScheme.shadow,
|
||||
borderRadius: 10.0,
|
||||
),
|
||||
popupBuilder: (_) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
|
@ -137,6 +137,7 @@ class _FavoriteGroups extends StatelessWidget {
|
||||
state.otherViews,
|
||||
LocaleKeys.sideBar_others.tr(),
|
||||
);
|
||||
|
||||
return Container(
|
||||
width: minWidth - 2 * _kHorizontalPadding,
|
||||
constraints: const BoxConstraints(
|
||||
@ -149,15 +150,14 @@ class _FavoriteGroups extends StatelessWidget {
|
||||
children: [
|
||||
if (today.isNotEmpty) ...[
|
||||
...today,
|
||||
const VSpace(8),
|
||||
const Divider(height: 1),
|
||||
const VSpace(8),
|
||||
const FlowyDivider(),
|
||||
const VSpace(16),
|
||||
],
|
||||
if (thisWeek.isNotEmpty) ...[
|
||||
...thisWeek,
|
||||
const VSpace(8),
|
||||
const Divider(height: 1),
|
||||
const VSpace(8),
|
||||
const FlowyDivider(),
|
||||
const VSpace(16),
|
||||
],
|
||||
...others.isNotEmpty && (today.isNotEmpty || thisWeek.isNotEmpty)
|
||||
? others
|
||||
@ -182,13 +182,10 @@ class _FavoriteGroups extends StatelessWidget {
|
||||
return [
|
||||
if (views.isNotEmpty) ...[
|
||||
if (showHeader)
|
||||
SizedBox(
|
||||
height: 24,
|
||||
child: FlowyText(
|
||||
title,
|
||||
fontSize: 12.0,
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
FlowyText(
|
||||
title,
|
||||
fontSize: 12.0,
|
||||
color: Theme.of(context).hintColor,
|
||||
),
|
||||
const VSpace(2),
|
||||
_FavoriteGroupedViews(views: views),
|
||||
|
@ -21,8 +21,8 @@ class FavoritePinAction extends StatelessWidget {
|
||||
: LocaleKeys.favorite_addToSidebar.tr();
|
||||
final icon = FlowySvg(
|
||||
view.isPinned
|
||||
? FlowySvgs.favorite_section_pin_s
|
||||
: FlowySvgs.favorite_section_unpin_s,
|
||||
? FlowySvgs.favorite_section_unpin_s
|
||||
: FlowySvgs.favorite_section_pin_s,
|
||||
);
|
||||
return FlowyTooltip(
|
||||
message: tooltip,
|
||||
|
@ -3,7 +3,6 @@ import 'dart:io' show Platform;
|
||||
import 'package:appflowy/core/frameless_window.dart';
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/util/theme_extension.dart';
|
||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
|
||||
@ -65,20 +64,17 @@ class SidebarTopMenu extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildCollapseMenuButton(BuildContext context) {
|
||||
final color = Theme.of(context).isLightMode ? Colors.white : Colors.black;
|
||||
final textSpan = TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${LocaleKeys.sideBar_closeSidebar.tr()}\n',
|
||||
style:
|
||||
Theme.of(context).tooltipTheme.textStyle!.copyWith(color: color),
|
||||
style: context.tooltipTextStyle(),
|
||||
),
|
||||
TextSpan(
|
||||
text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\',
|
||||
style: Theme.of(context)
|
||||
.tooltipTheme
|
||||
.textStyle!
|
||||
.copyWith(color: Theme.of(context).hintColor),
|
||||
style: context
|
||||
.tooltipTextStyle()
|
||||
?.copyWith(color: Theme.of(context).hintColor),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/folder/folder_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/space/space_search_bloc.dart';
|
||||
@ -5,9 +6,12 @@ import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_widget.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/protobuf.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
@ -123,12 +127,15 @@ class _MovePageMenuState extends State<MovePageMenu> {
|
||||
expand: true,
|
||||
height: 30,
|
||||
showCreateButton: false,
|
||||
child: CurrentSpace(
|
||||
onTapBlankArea: () {
|
||||
// move the page to current space
|
||||
widget.onSelected(space, space);
|
||||
},
|
||||
space: space,
|
||||
child: FlowyTooltip(
|
||||
message: LocaleKeys.space_switchSpace.tr(),
|
||||
child: CurrentSpace(
|
||||
onTapBlankArea: () {
|
||||
// move the page to current space
|
||||
widget.onSelected(space, space);
|
||||
},
|
||||
space: space,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
|
@ -4,6 +4,7 @@ import 'package:appflowy/workspace/application/menu/sidebar_sections_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/user/user_workspace_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/hotkeys.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/shared/rename_view_dialog.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@ -11,18 +12,35 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class SidebarNewPageButton extends StatelessWidget {
|
||||
class SidebarNewPageButton extends StatefulWidget {
|
||||
const SidebarNewPageButton({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<SidebarNewPageButton> createState() => _SidebarNewPageButtonState();
|
||||
}
|
||||
|
||||
class _SidebarNewPageButtonState extends State<SidebarNewPageButton> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
createNewPageNotifier.addListener(_createNewPage);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
createNewPageNotifier.removeListener(_createNewPage);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
height: HomeSizes.newPageSectionHeight,
|
||||
child: FlowyButton(
|
||||
onTap: () async => _createNewPage(context),
|
||||
onTap: () async => _createNewPage(),
|
||||
leftIcon: const FlowySvg(
|
||||
FlowySvgs.new_app_m,
|
||||
blendMode: null,
|
||||
@ -38,7 +56,7 @@ class SidebarNewPageButton extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _createNewPage(BuildContext context) async {
|
||||
Future<void> _createNewPage() async {
|
||||
return createViewAndShowRenameDialogIfNeeded(
|
||||
context,
|
||||
LocaleKeys.newPageText.tr(),
|
||||
|
@ -1,7 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/blank/blank.dart';
|
||||
@ -35,9 +33,8 @@ import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
|
||||
show UserProfilePB;
|
||||
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
Loading? _duplicateSpaceLoading;
|
||||
@ -333,10 +330,7 @@ class _SidebarState extends State<_Sidebar> {
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: const Divider(
|
||||
color: Color(0x141F2329),
|
||||
height: 0.5,
|
||||
),
|
||||
child: const FlowyDivider(),
|
||||
),
|
||||
),
|
||||
|
||||
@ -346,7 +340,7 @@ class _SidebarState extends State<_Sidebar> {
|
||||
Padding(
|
||||
padding: menuHorizontalInset +
|
||||
const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
child: const Divider(height: 0.5, color: Color(0x141F2329)),
|
||||
child: const FlowyDivider(),
|
||||
),
|
||||
const VSpace(8),
|
||||
|
||||
@ -403,13 +397,16 @@ class _SidebarState extends State<_Sidebar> {
|
||||
: Expanded(
|
||||
child: Padding(
|
||||
padding: menuHorizontalInset - const EdgeInsets.only(right: 6),
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(right: 6),
|
||||
child: FlowyScrollbar(
|
||||
controller: _scrollController,
|
||||
physics: const ClampingScrollPhysics(),
|
||||
child: SidebarSpace(
|
||||
userProfile: widget.userProfile,
|
||||
isHoverEnabled: !_isScrolling,
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(right: 6),
|
||||
controller: _scrollController,
|
||||
physics: const ClampingScrollPhysics(),
|
||||
child: SidebarSpace(
|
||||
userProfile: widget.userProfile,
|
||||
isHoverEnabled: !_isScrolling,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -0,0 +1,8 @@
|
||||
import 'package:appflowy/util/theme_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension SpacePermissionColorExtension on BuildContext {
|
||||
Color get enableBorderColor => Theme.of(this).isLightMode
|
||||
? const Color(0x1E171717)
|
||||
: const Color(0xFF3A3F49);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/_extension.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/shared_widget.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_icon_popup.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
@ -24,19 +25,22 @@ class _CreateSpacePopupState extends State<CreateSpacePopup> {
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
|
||||
width: 500,
|
||||
width: 524,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
FlowyText(
|
||||
LocaleKeys.space_createNewSpace.tr(),
|
||||
fontSize: 18.0,
|
||||
figmaLineHeight: 24.0,
|
||||
),
|
||||
const VSpace(6.0),
|
||||
FlowyText.regular(
|
||||
const VSpace(2.0),
|
||||
FlowyText(
|
||||
LocaleKeys.space_createSpaceDescription.tr(),
|
||||
fontSize: 14.0,
|
||||
fontWeight: FontWeight.w300,
|
||||
color: Theme.of(context).hintColor,
|
||||
figmaLineHeight: 18.0,
|
||||
maxLines: 2,
|
||||
),
|
||||
const VSpace(16.0),
|
||||
@ -106,14 +110,16 @@ class _SpaceNameTextField extends StatelessWidget {
|
||||
LocaleKeys.space_spaceName.tr(),
|
||||
fontSize: 14.0,
|
||||
color: Theme.of(context).hintColor,
|
||||
figmaLineHeight: 18.0,
|
||||
),
|
||||
const VSpace(6.0),
|
||||
SizedBox(
|
||||
height: 40,
|
||||
child: FlowyTextField(
|
||||
hintText: LocaleKeys.space_spaceName.tr(),
|
||||
hintText: LocaleKeys.space_spaceNamePlaceholder.tr(),
|
||||
onChanged: onChanged,
|
||||
onSubmitted: onSubmitted,
|
||||
enableBorderColor: context.enableBorderColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -1,7 +1,3 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/util/theme_extension.dart';
|
||||
@ -10,6 +6,7 @@ import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_bloc.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_ext.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/_extension.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/sidebar_space_menu.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/space_icon.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/view/view_item.dart';
|
||||
@ -19,9 +16,11 @@ import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/decoration.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class SpacePermissionSwitch extends StatefulWidget {
|
||||
@ -55,6 +54,7 @@ class _SpacePermissionSwitchState extends State<SpacePermissionSwitch> {
|
||||
LocaleKeys.space_permission.tr(),
|
||||
fontSize: 14.0,
|
||||
color: Theme.of(context).hintColor,
|
||||
figmaLineHeight: 18.0,
|
||||
),
|
||||
const VSpace(6.0),
|
||||
AppFlowyPopover(
|
||||
@ -63,16 +63,11 @@ class _SpacePermissionSwitchState extends State<SpacePermissionSwitch> {
|
||||
constraints: const BoxConstraints(maxWidth: 500),
|
||||
offset: const Offset(0, 4),
|
||||
margin: EdgeInsets.zero,
|
||||
decoration: FlowyDecoration.decoration(
|
||||
Theme.of(context).cardColor,
|
||||
Theme.of(context).colorScheme.shadow,
|
||||
borderRadius: 10,
|
||||
),
|
||||
popupBuilder: (_) => _buildPermissionButtons(),
|
||||
child: DecoratedBox(
|
||||
decoration: ShapeDecoration(
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(color: Theme.of(context).colorScheme.outline),
|
||||
side: BorderSide(color: context.enableBorderColor),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
@ -148,9 +143,13 @@ class SpacePermissionButton extends StatelessWidget {
|
||||
radius: BorderRadius.circular(10),
|
||||
iconPadding: 16.0,
|
||||
leftIcon: FlowySvg(icon),
|
||||
leftIconSize: const Size.square(20),
|
||||
rightIcon: showArrow
|
||||
? const FlowySvg(FlowySvgs.space_permission_dropdown_s)
|
||||
: null,
|
||||
borderColor: Theme.of(context).isLightMode
|
||||
? const Color(0x1E171717)
|
||||
: const Color(0xFF3A3F49),
|
||||
text: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -462,32 +461,29 @@ class CurrentSpace extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final child = FlowyTooltip(
|
||||
message: LocaleKeys.space_switchSpace.tr(),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SpaceIcon(
|
||||
dimension: 20,
|
||||
space: space,
|
||||
cornerRadius: 6.0,
|
||||
final child = Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SpaceIcon(
|
||||
dimension: 20,
|
||||
space: space,
|
||||
cornerRadius: 6.0,
|
||||
),
|
||||
const HSpace(10),
|
||||
Flexible(
|
||||
child: FlowyText.medium(
|
||||
space.name,
|
||||
fontSize: 14.0,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const HSpace(10),
|
||||
Flexible(
|
||||
child: FlowyText.medium(
|
||||
space.name,
|
||||
fontSize: 14.0,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
const HSpace(4.0),
|
||||
FlowySvg(
|
||||
context.read<SpaceBloc>().state.isExpanded
|
||||
? FlowySvgs.workspace_drop_down_menu_show_s
|
||||
: FlowySvgs.workspace_drop_down_menu_hide_s,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const HSpace(4.0),
|
||||
FlowySvg(
|
||||
context.read<SpaceBloc>().state.isExpanded
|
||||
? FlowySvgs.workspace_drop_down_menu_show_s
|
||||
: FlowySvgs.workspace_drop_down_menu_hide_s,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
if (onTapBlankArea != null) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/util/theme_extension.dart';
|
||||
import 'package:appflowy/workspace/application/sidebar/space/space_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/home_sizes.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/menu/sidebar/space/manage_space_popup.dart';
|
||||
@ -105,20 +104,17 @@ class _SidebarSpaceHeaderState extends State<SidebarSpaceHeader> {
|
||||
}
|
||||
|
||||
Widget _buildChild() {
|
||||
final color = Theme.of(context).isLightMode ? Colors.white : Colors.black;
|
||||
final textSpan = TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${LocaleKeys.space_quicklySwitch.tr()}\n',
|
||||
style:
|
||||
Theme.of(context).tooltipTheme.textStyle!.copyWith(color: color),
|
||||
style: context.tooltipTextStyle(),
|
||||
),
|
||||
TextSpan(
|
||||
text: Platform.isMacOS ? '⌘+O' : 'Ctrl+O',
|
||||
style: Theme.of(context)
|
||||
.tooltipTheme
|
||||
.textStyle!
|
||||
.copyWith(color: Theme.of(context).hintColor),
|
||||
style: context
|
||||
.tooltipTextStyle()
|
||||
?.copyWith(color: Theme.of(context).hintColor),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -40,9 +40,7 @@ class SidebarSpaceMenu extends StatelessWidget {
|
||||
if (showCreateButton) ...[
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Divider(
|
||||
height: 0.5,
|
||||
),
|
||||
child: FlowyDivider(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: HomeSpaceViewSizes.viewHeight,
|
||||
|
@ -36,24 +36,24 @@ extension ViewMoreActionTypeExtension on SpaceMoreActionType {
|
||||
}
|
||||
}
|
||||
|
||||
Widget get leftIcon {
|
||||
FlowySvgData get leftIconSvg {
|
||||
switch (this) {
|
||||
case SpaceMoreActionType.delete:
|
||||
return const FlowySvg(FlowySvgs.trash_s, blendMode: null);
|
||||
return FlowySvgs.trash_s;
|
||||
case SpaceMoreActionType.rename:
|
||||
return const FlowySvg(FlowySvgs.view_item_rename_s);
|
||||
return FlowySvgs.view_item_rename_s;
|
||||
case SpaceMoreActionType.changeIcon:
|
||||
return const FlowySvg(FlowySvgs.change_icon_s);
|
||||
return FlowySvgs.change_icon_s;
|
||||
case SpaceMoreActionType.collapseAllPages:
|
||||
return const FlowySvg(FlowySvgs.collapse_all_page_s);
|
||||
return FlowySvgs.collapse_all_page_s;
|
||||
case SpaceMoreActionType.addNewSpace:
|
||||
return const FlowySvg(FlowySvgs.space_add_s);
|
||||
return FlowySvgs.space_add_s;
|
||||
case SpaceMoreActionType.manage:
|
||||
return const FlowySvg(FlowySvgs.space_manage_s);
|
||||
return FlowySvgs.space_manage_s;
|
||||
case SpaceMoreActionType.duplicate:
|
||||
return const FlowySvg(FlowySvgs.duplicate_s);
|
||||
return FlowySvgs.duplicate_s;
|
||||
case SpaceMoreActionType.divider:
|
||||
return const SizedBox.shrink();
|
||||
throw UnsupportedError('Divider does not have an icon');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/decoration.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
final builtInSpaceColors = [
|
||||
@ -59,11 +58,6 @@ class _SpaceIconPopupState extends State<SpaceIconPopup> {
|
||||
Widget build(BuildContext context) {
|
||||
return AppFlowyPopover(
|
||||
offset: const Offset(0, 4),
|
||||
decoration: FlowyDecoration.decoration(
|
||||
Theme.of(context).cardColor,
|
||||
Theme.of(context).colorScheme.shadow,
|
||||
borderRadius: 10,
|
||||
),
|
||||
constraints: const BoxConstraints(maxWidth: 220),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 14.0, vertical: 12.0),
|
||||
direction: PopoverDirection.bottomWithCenterAligned,
|
||||
|
@ -129,7 +129,7 @@ class SpaceMoreActionTypeWrapper extends CustomActionCell {
|
||||
Widget _buildDivider() {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Divider(height: 1.0),
|
||||
child: FlowyDivider(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -158,22 +158,24 @@ class SpaceMoreActionTypeWrapper extends CustomActionCell {
|
||||
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
||||
child: Opacity(
|
||||
opacity: disable ? 0.3 : 1.0,
|
||||
child: FlowyButton(
|
||||
child: FlowyIconTextButton(
|
||||
disable: disable,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 6),
|
||||
leftIcon: inner.leftIcon,
|
||||
rightIcon: inner.rightIcon,
|
||||
iconPadding: 10.0,
|
||||
text: SizedBox(
|
||||
// height: 16.0,
|
||||
child: FlowyText.regular(
|
||||
inner.name,
|
||||
color: inner == SpaceMoreActionType.delete
|
||||
? Theme.of(context).colorScheme.error
|
||||
: null,
|
||||
),
|
||||
),
|
||||
onTap: onTap,
|
||||
leftIconBuilder: (onHover) => FlowySvg(
|
||||
inner.leftIconSvg,
|
||||
color: inner == SpaceMoreActionType.delete && onHover
|
||||
? Theme.of(context).colorScheme.error
|
||||
: null,
|
||||
),
|
||||
rightIconBuilder: (_) => inner.rightIcon,
|
||||
textBuilder: (onHover) => FlowyText.regular(
|
||||
inner.name,
|
||||
color: inner == SpaceMoreActionType.delete && onHover
|
||||
? Theme.of(context).colorScheme.error
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -49,32 +49,31 @@ extension ViewMoreActionTypeExtension on ViewMoreActionType {
|
||||
}
|
||||
}
|
||||
|
||||
Widget get leftIcon {
|
||||
FlowySvgData get leftIconSvg {
|
||||
switch (this) {
|
||||
case ViewMoreActionType.delete:
|
||||
return const FlowySvg(FlowySvgs.trash_s, blendMode: null);
|
||||
return FlowySvgs.trash_s;
|
||||
case ViewMoreActionType.favorite:
|
||||
return const FlowySvg(FlowySvgs.favorite_s);
|
||||
return FlowySvgs.favorite_s;
|
||||
case ViewMoreActionType.unFavorite:
|
||||
return const FlowySvg(FlowySvgs.unfavorite_s);
|
||||
return FlowySvgs.unfavorite_s;
|
||||
case ViewMoreActionType.duplicate:
|
||||
return const FlowySvg(FlowySvgs.duplicate_s);
|
||||
case ViewMoreActionType.copyLink:
|
||||
return const Icon(Icons.copy);
|
||||
return FlowySvgs.duplicate_s;
|
||||
case ViewMoreActionType.rename:
|
||||
return const FlowySvg(FlowySvgs.view_item_rename_s);
|
||||
return FlowySvgs.view_item_rename_s;
|
||||
case ViewMoreActionType.moveTo:
|
||||
return const FlowySvg(FlowySvgs.move_to_s);
|
||||
return FlowySvgs.move_to_s;
|
||||
case ViewMoreActionType.openInNewTab:
|
||||
return const FlowySvg(FlowySvgs.view_item_open_in_new_tab_s);
|
||||
return FlowySvgs.view_item_open_in_new_tab_s;
|
||||
case ViewMoreActionType.changeIcon:
|
||||
return const FlowySvg(FlowySvgs.change_icon_s);
|
||||
return FlowySvgs.change_icon_s;
|
||||
case ViewMoreActionType.collapseAllPages:
|
||||
return const FlowySvg(FlowySvgs.collapse_all_page_s);
|
||||
return FlowySvgs.collapse_all_page_s;
|
||||
case ViewMoreActionType.divider:
|
||||
case ViewMoreActionType.lastModified:
|
||||
case ViewMoreActionType.copyLink:
|
||||
case ViewMoreActionType.created:
|
||||
return const SizedBox.shrink();
|
||||
throw UnsupportedError('No left icon for $this');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -491,6 +491,7 @@ class _SingleInnerViewItemState extends State<SingleInnerViewItem> {
|
||||
final name = FlowyText.regular(
|
||||
widget.view.name,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
// figmaLineHeight: 18.0,
|
||||
);
|
||||
final children = [
|
||||
const HSpace(2),
|
||||
|
@ -101,7 +101,8 @@ class ViewMoreActionButton extends StatelessWidget {
|
||||
]);
|
||||
|
||||
// Chat doesn't change collapse
|
||||
if (view.layout != ViewLayoutPB.Chat) {
|
||||
// Only show collapse all pages if the view has child views
|
||||
if (view.layout != ViewLayoutPB.Chat && view.childViews.isNotEmpty) {
|
||||
actionTypes.add(ViewMoreActionType.collapseAllPages);
|
||||
actionTypes.add(ViewMoreActionType.divider);
|
||||
}
|
||||
@ -204,7 +205,7 @@ class ViewMoreActionTypeWrapper extends CustomActionCell {
|
||||
Widget _buildDivider() {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Divider(height: 1.0),
|
||||
child: FlowyDivider(),
|
||||
);
|
||||
}
|
||||
|
||||
@ -237,18 +238,24 @@ class ViewMoreActionTypeWrapper extends CustomActionCell {
|
||||
return Container(
|
||||
height: 34,
|
||||
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
||||
child: FlowyButton(
|
||||
child: FlowyIconTextButton(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 6),
|
||||
leftIcon: inner.leftIcon,
|
||||
rightIcon: inner.rightIcon,
|
||||
iconPadding: 10.0,
|
||||
text: FlowyText.regular(
|
||||
inner.name,
|
||||
color: inner == ViewMoreActionType.delete
|
||||
onTap: onTap,
|
||||
// show the error color when delete is hovered
|
||||
leftIconBuilder: (onHover) => FlowySvg(
|
||||
inner.leftIconSvg,
|
||||
color: inner == ViewMoreActionType.delete && onHover
|
||||
? Theme.of(context).colorScheme.error
|
||||
: null,
|
||||
),
|
||||
rightIconBuilder: (_) => inner.rightIcon,
|
||||
iconPadding: 10.0,
|
||||
textBuilder: (onHover) => FlowyText.regular(
|
||||
inner.name,
|
||||
color: inner == ViewMoreActionType.delete && onHover
|
||||
? Theme.of(context).colorScheme.error
|
||||
: null,
|
||||
),
|
||||
onTap: onTap,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ import 'dart:io';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/util/theme_extension.dart';
|
||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||
import 'package:appflowy/workspace/presentation/home/home_stack.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
@ -65,23 +64,17 @@ class FlowyNavigation extends StatelessWidget {
|
||||
buildWhen: (p, c) => p.isMenuCollapsed != c.isMenuCollapsed,
|
||||
builder: (context, state) {
|
||||
if (!PlatformExtension.isWindows && state.isMenuCollapsed) {
|
||||
final color =
|
||||
Theme.of(context).isLightMode ? Colors.white : Colors.black;
|
||||
final textSpan = TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${LocaleKeys.sideBar_openSidebar.tr()}\n',
|
||||
style: Theme.of(context)
|
||||
.tooltipTheme
|
||||
.textStyle!
|
||||
.copyWith(color: color),
|
||||
style: context.tooltipTextStyle(),
|
||||
),
|
||||
TextSpan(
|
||||
text: Platform.isMacOS ? '⌘+.' : 'Ctrl+\\',
|
||||
style: Theme.of(context)
|
||||
.tooltipTheme
|
||||
.textStyle!
|
||||
.copyWith(color: Theme.of(context).hintColor),
|
||||
style: context
|
||||
.tooltipTextStyle()
|
||||
?.copyWith(color: Theme.of(context).hintColor),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -1,7 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/application/document_appearance_cubit.dart';
|
||||
@ -45,6 +43,7 @@ import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
@ -879,16 +878,7 @@ class _FontSelectorDropdownState extends State<_FontSelectorDropdown> {
|
||||
maxHeight: 150,
|
||||
maxWidth: constraints.maxWidth - 90,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).cardColor,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4.0)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black.withOpacity(0.10),
|
||||
blurRadius: 6,
|
||||
),
|
||||
],
|
||||
),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(4.0)),
|
||||
popupBuilder: (_) => _FontListPopup(
|
||||
currentFont: appearance.font,
|
||||
scrollController: _scrollController,
|
||||
|
@ -1,8 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
class PopoverActionList<T extends PopoverAction> extends StatefulWidget {
|
||||
@ -54,7 +53,6 @@ class _PopoverActionListState<T extends PopoverAction>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final child = widget.buildChild(popoverController);
|
||||
|
||||
return AppFlowyPopover(
|
||||
asBarrier: widget.asBarrier,
|
||||
controller: popoverController,
|
||||
|
@ -0,0 +1,84 @@
|
||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class SidebarResizer extends StatefulWidget {
|
||||
const SidebarResizer({super.key});
|
||||
|
||||
@override
|
||||
State<SidebarResizer> createState() => _SidebarResizerState();
|
||||
}
|
||||
|
||||
class _SidebarResizerState extends State<SidebarResizer> {
|
||||
final ValueNotifier<bool> isHovered = ValueNotifier(false);
|
||||
final ValueNotifier<bool> isDragging = ValueNotifier(false);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
isHovered.dispose();
|
||||
isDragging.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.resizeLeftRight,
|
||||
onEnter: (_) => isHovered.value = true,
|
||||
onExit: (_) => isHovered.value = false,
|
||||
child: GestureDetector(
|
||||
dragStartBehavior: DragStartBehavior.down,
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onHorizontalDragStart: (details) {
|
||||
isDragging.value = true;
|
||||
|
||||
context
|
||||
.read<HomeSettingBloc>()
|
||||
.add(const HomeSettingEvent.editPanelResizeStart());
|
||||
},
|
||||
onHorizontalDragUpdate: (details) {
|
||||
isDragging.value = true;
|
||||
|
||||
context
|
||||
.read<HomeSettingBloc>()
|
||||
.add(HomeSettingEvent.editPanelResized(details.localPosition.dx));
|
||||
},
|
||||
onHorizontalDragEnd: (details) {
|
||||
isDragging.value = false;
|
||||
|
||||
context
|
||||
.read<HomeSettingBloc>()
|
||||
.add(const HomeSettingEvent.editPanelResizeEnd());
|
||||
},
|
||||
onHorizontalDragCancel: () {
|
||||
isDragging.value = false;
|
||||
|
||||
context
|
||||
.read<HomeSettingBloc>()
|
||||
.add(const HomeSettingEvent.editPanelResizeEnd());
|
||||
},
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: isHovered,
|
||||
builder: (context, isHovered, _) {
|
||||
return ValueListenableBuilder(
|
||||
valueListenable: isDragging,
|
||||
builder: (context, isDragging, _) {
|
||||
return Container(
|
||||
width: 2,
|
||||
// increase the width of the resizer to make it easier to drag
|
||||
margin: const EdgeInsets.only(right: 2.0),
|
||||
height: MediaQuery.of(context).size.height,
|
||||
color: isHovered || isDragging
|
||||
? const Color(0xFF00B5FF)
|
||||
: Colors.transparent,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -246,6 +246,7 @@ class _ViewTitleState extends State<_ViewTitle> {
|
||||
opacity: isEditable ? 1.0 : 0.5,
|
||||
child: FlowyText.regular(
|
||||
state.name,
|
||||
fontSize: 14.0,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flowy_infra/theme.dart';
|
||||
import 'package:flowy_infra/utils/color_converter.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'dandelion.dart';
|
||||
@ -87,6 +86,9 @@ class FlowyColorScheme {
|
||||
required this.toggleButtonBGColor,
|
||||
required this.calendarWeekendBGColor,
|
||||
required this.gridRowCountColor,
|
||||
required this.borderColor,
|
||||
required this.scrollbarColor,
|
||||
required this.scrollbarHoverColor,
|
||||
});
|
||||
|
||||
final Color surface;
|
||||
@ -145,6 +147,11 @@ class FlowyColorScheme {
|
||||
//grid bottom count color
|
||||
final Color gridRowCountColor;
|
||||
|
||||
final Color borderColor;
|
||||
|
||||
final Color scrollbarColor;
|
||||
final Color scrollbarHoverColor;
|
||||
|
||||
factory FlowyColorScheme.fromJson(Map<String, dynamic> json) =>
|
||||
_$FlowyColorSchemeFromJson(json);
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:flowy_infra/colorscheme/default_colorscheme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'colorscheme.dart';
|
||||
@ -81,6 +82,9 @@ class DandelionColorScheme extends FlowyColorScheme {
|
||||
toggleButtonBGColor: _lightDandelionYellow,
|
||||
calendarWeekendBGColor: const Color(0xFFFBFBFC),
|
||||
gridRowCountColor: _black,
|
||||
borderColor: ColorSchemeConstants.lightBorderColor,
|
||||
scrollbarColor: const Color(0x3F171717),
|
||||
scrollbarHoverColor: const Color(0x7F171717),
|
||||
);
|
||||
|
||||
const DandelionColorScheme.dark()
|
||||
@ -135,5 +139,8 @@ class DandelionColorScheme extends FlowyColorScheme {
|
||||
toggleButtonBGColor: _darkShader1,
|
||||
calendarWeekendBGColor: const Color(0xff121212),
|
||||
gridRowCountColor: _darkMain1,
|
||||
borderColor: ColorSchemeConstants.darkBorderColor,
|
||||
scrollbarColor: const Color(0x40FFFFFF),
|
||||
scrollbarHoverColor: const Color(0x80FFFFFF),
|
||||
);
|
||||
}
|
||||
|
@ -2,44 +2,48 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import 'colorscheme.dart';
|
||||
|
||||
const _white = Color(0xFFFFFFFF);
|
||||
const _lightHover = Color(0xFFe0f8FF);
|
||||
const _lightSelector = Color(0xFFf2fcFF);
|
||||
const _lightBg1 = Color(0xFFf7f8fc);
|
||||
const _lightBg2 = Color(0x0F1F2329);
|
||||
const _lightShader1 = Color(0xFF333333);
|
||||
const _lightShader3 = Color(0xFF828282);
|
||||
const _lightShader5 = Color(0xFFe0e0e0);
|
||||
const _lightShader6 = Color(0xFFf2f2f2);
|
||||
const _lightMain1 = Color(0xFF00bcf0);
|
||||
const _lightTint9 = Color(0xFFe1fbFF);
|
||||
const _darkShader1 = Color(0xFF131720);
|
||||
const _darkShader2 = Color(0xFF1A202C);
|
||||
const _darkShader3 = Color(0xFF363D49);
|
||||
const _darkShader5 = Color(0xFFBBC3CD);
|
||||
const _darkShader6 = Color(0xFFF2F2F2);
|
||||
const _darkMain1 = Color(0xFF00BCF0);
|
||||
const _darkMain2 = Color(0xFF00BCF0);
|
||||
const _darkInput = Color(0xFF282E3A);
|
||||
class ColorSchemeConstants {
|
||||
static const white = Color(0xFFFFFFFF);
|
||||
static const lightHover = Color(0xFFe0f8FF);
|
||||
static const lightSelector = Color(0xFFf2fcFF);
|
||||
static const lightBg1 = Color(0xFFf7f8fc);
|
||||
static const lightBg2 = Color(0x0F1F2329);
|
||||
static const lightShader1 = Color(0xFF333333);
|
||||
static const lightShader3 = Color(0xFF828282);
|
||||
static const lightShader5 = Color(0xFFe0e0e0);
|
||||
static const lightShader6 = Color(0xFFf2f2f2);
|
||||
static const lightMain1 = Color(0xFF00bcf0);
|
||||
static const lightTint9 = Color(0xFFe1fbFF);
|
||||
static const darkShader1 = Color(0xFF131720);
|
||||
static const darkShader2 = Color(0xFF1A202C);
|
||||
static const darkShader3 = Color(0xFF363D49);
|
||||
static const darkShader5 = Color(0xFFBBC3CD);
|
||||
static const darkShader6 = Color(0xFFF2F2F2);
|
||||
static const darkMain1 = Color(0xFF00BCF0);
|
||||
static const darkMain2 = Color(0xFF00BCF0);
|
||||
static const darkInput = Color(0xFF282E3A);
|
||||
static const lightBorderColor = Color(0xFFEDEDEE);
|
||||
static const darkBorderColor = Color(0xFF3A3F49);
|
||||
}
|
||||
|
||||
class DefaultColorScheme extends FlowyColorScheme {
|
||||
const DefaultColorScheme.light()
|
||||
: super(
|
||||
surface: _white,
|
||||
hover: _lightHover,
|
||||
selector: _lightSelector,
|
||||
surface: ColorSchemeConstants.white,
|
||||
hover: ColorSchemeConstants.lightHover,
|
||||
selector: ColorSchemeConstants.lightSelector,
|
||||
red: const Color(0xFFfb006d),
|
||||
yellow: const Color(0xFFFFd667),
|
||||
green: const Color(0xFF66cf80),
|
||||
shader1: _lightShader1,
|
||||
shader1: ColorSchemeConstants.lightShader1,
|
||||
shader2: const Color(0xFF4f4f4f),
|
||||
shader3: _lightShader3,
|
||||
shader3: ColorSchemeConstants.lightShader3,
|
||||
shader4: const Color(0xFFbdbdbd),
|
||||
shader5: _lightShader5,
|
||||
shader6: _lightShader6,
|
||||
shader7: _lightShader1,
|
||||
bg1: _lightBg1,
|
||||
bg2: _lightBg2,
|
||||
shader5: ColorSchemeConstants.lightShader5,
|
||||
shader6: ColorSchemeConstants.lightShader6,
|
||||
shader7: ColorSchemeConstants.lightShader1,
|
||||
bg1: ColorSchemeConstants.lightBg1,
|
||||
bg2: ColorSchemeConstants.lightBg2,
|
||||
bg3: const Color(0xFFe2e4eb),
|
||||
bg4: const Color(0xFF2c144b),
|
||||
tint1: const Color(0xFFe8e0FF),
|
||||
@ -50,51 +54,54 @@ class DefaultColorScheme extends FlowyColorScheme {
|
||||
tint6: const Color(0xFFf5FFdc),
|
||||
tint7: const Color(0xFFddFFd6),
|
||||
tint8: const Color(0xFFdeFFf1),
|
||||
tint9: _lightTint9,
|
||||
main1: _lightMain1,
|
||||
tint9: ColorSchemeConstants.lightTint9,
|
||||
main1: ColorSchemeConstants.lightMain1,
|
||||
main2: const Color(0xFF00b7ea),
|
||||
shadow: const Color.fromRGBO(0, 0, 0, 0.15),
|
||||
sidebarBg: _lightBg1,
|
||||
divider: _lightShader6,
|
||||
topbarBg: _white,
|
||||
icon: _lightShader1,
|
||||
text: _lightShader1,
|
||||
sidebarBg: ColorSchemeConstants.lightBg1,
|
||||
divider: ColorSchemeConstants.lightShader6,
|
||||
topbarBg: ColorSchemeConstants.white,
|
||||
icon: ColorSchemeConstants.lightShader1,
|
||||
text: ColorSchemeConstants.lightShader1,
|
||||
secondaryText: const Color(0xFF4f4f4f),
|
||||
strongText: Colors.black,
|
||||
input: _white,
|
||||
hint: _lightShader3,
|
||||
primary: _lightMain1,
|
||||
onPrimary: _white,
|
||||
hoverBG1: _lightBg2,
|
||||
hoverBG2: _lightHover,
|
||||
hoverBG3: _lightShader6,
|
||||
hoverFG: _lightShader1,
|
||||
questionBubbleBG: _lightSelector,
|
||||
progressBarBGColor: _lightTint9,
|
||||
toolbarColor: _lightShader1,
|
||||
toggleButtonBGColor: _lightShader5,
|
||||
input: ColorSchemeConstants.white,
|
||||
hint: ColorSchemeConstants.lightShader3,
|
||||
primary: ColorSchemeConstants.lightMain1,
|
||||
onPrimary: ColorSchemeConstants.white,
|
||||
hoverBG1: ColorSchemeConstants.lightBg2,
|
||||
hoverBG2: ColorSchemeConstants.lightHover,
|
||||
hoverBG3: ColorSchemeConstants.lightShader6,
|
||||
hoverFG: ColorSchemeConstants.lightShader1,
|
||||
questionBubbleBG: ColorSchemeConstants.lightSelector,
|
||||
progressBarBGColor: ColorSchemeConstants.lightTint9,
|
||||
toolbarColor: ColorSchemeConstants.lightShader1,
|
||||
toggleButtonBGColor: ColorSchemeConstants.lightShader5,
|
||||
calendarWeekendBGColor: const Color(0xFFFBFBFC),
|
||||
gridRowCountColor: _lightShader1,
|
||||
gridRowCountColor: ColorSchemeConstants.lightShader1,
|
||||
borderColor: ColorSchemeConstants.lightBorderColor,
|
||||
scrollbarColor: const Color(0x3F171717),
|
||||
scrollbarHoverColor: const Color(0x7F171717),
|
||||
);
|
||||
|
||||
const DefaultColorScheme.dark()
|
||||
: super(
|
||||
surface: _darkShader2,
|
||||
hover: _darkMain1,
|
||||
selector: _darkShader2,
|
||||
surface: ColorSchemeConstants.darkShader2,
|
||||
hover: ColorSchemeConstants.darkMain1,
|
||||
selector: ColorSchemeConstants.darkShader2,
|
||||
red: const Color(0xFFfb006d),
|
||||
yellow: const Color(0xFFF7CF46),
|
||||
green: const Color(0xFF66CF80),
|
||||
shader1: _darkShader1,
|
||||
shader2: _darkShader2,
|
||||
shader3: _darkShader3,
|
||||
shader1: ColorSchemeConstants.darkShader1,
|
||||
shader2: ColorSchemeConstants.darkShader2,
|
||||
shader3: ColorSchemeConstants.darkShader3,
|
||||
shader4: const Color(0xFF505469),
|
||||
shader5: _darkShader5,
|
||||
shader6: _darkShader6,
|
||||
shader7: _white,
|
||||
shader5: ColorSchemeConstants.darkShader5,
|
||||
shader6: ColorSchemeConstants.darkShader6,
|
||||
shader7: ColorSchemeConstants.white,
|
||||
bg1: const Color(0xFF1A202C),
|
||||
bg2: const Color(0xFFEDEEF2),
|
||||
bg3: _darkMain1,
|
||||
bg3: ColorSchemeConstants.darkMain1,
|
||||
bg4: const Color(0xFF2C144B),
|
||||
tint1: const Color(0x4d9327FF),
|
||||
tint2: const Color(0x66FC0088),
|
||||
@ -105,29 +112,32 @@ class DefaultColorScheme extends FlowyColorScheme {
|
||||
tint7: const Color(0x5900BD2A),
|
||||
tint8: const Color(0x80008890),
|
||||
tint9: const Color(0x4d0029FF),
|
||||
main1: _darkMain2,
|
||||
main1: ColorSchemeConstants.darkMain2,
|
||||
main2: const Color(0xFF00B7EA),
|
||||
shadow: const Color(0xFF0F131C),
|
||||
sidebarBg: const Color(0xFF232B38),
|
||||
divider: _darkShader3,
|
||||
topbarBg: _darkShader1,
|
||||
icon: _darkShader5,
|
||||
text: _darkShader5,
|
||||
secondaryText: _darkShader5,
|
||||
divider: ColorSchemeConstants.darkShader3,
|
||||
topbarBg: ColorSchemeConstants.darkShader1,
|
||||
icon: ColorSchemeConstants.darkShader5,
|
||||
text: ColorSchemeConstants.darkShader5,
|
||||
secondaryText: ColorSchemeConstants.darkShader5,
|
||||
strongText: Colors.white,
|
||||
input: _darkInput,
|
||||
input: ColorSchemeConstants.darkInput,
|
||||
hint: const Color(0xFF59647a),
|
||||
primary: _darkMain2,
|
||||
onPrimary: _darkShader1,
|
||||
primary: ColorSchemeConstants.darkMain2,
|
||||
onPrimary: ColorSchemeConstants.darkShader1,
|
||||
hoverBG1: const Color(0x1AFFFFFF),
|
||||
hoverBG2: _darkMain1,
|
||||
hoverBG3: _darkShader3,
|
||||
hoverBG2: ColorSchemeConstants.darkMain1,
|
||||
hoverBG3: ColorSchemeConstants.darkShader3,
|
||||
hoverFG: const Color(0xE5FFFFFF),
|
||||
questionBubbleBG: _darkShader3,
|
||||
progressBarBGColor: _darkShader3,
|
||||
toolbarColor: _darkInput,
|
||||
questionBubbleBG: ColorSchemeConstants.darkShader3,
|
||||
progressBarBGColor: ColorSchemeConstants.darkShader3,
|
||||
toolbarColor: ColorSchemeConstants.darkInput,
|
||||
toggleButtonBGColor: const Color(0xFF828282),
|
||||
calendarWeekendBGColor: _darkShader1,
|
||||
gridRowCountColor: _darkShader5,
|
||||
calendarWeekendBGColor: ColorSchemeConstants.darkShader1,
|
||||
gridRowCountColor: ColorSchemeConstants.darkShader5,
|
||||
borderColor: ColorSchemeConstants.darkBorderColor,
|
||||
scrollbarColor: const Color(0x40FFFFFF),
|
||||
scrollbarHoverColor: const Color(0x80FFFFFF),
|
||||
);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:flowy_infra/colorscheme/default_colorscheme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'colorscheme.dart';
|
||||
@ -77,6 +78,9 @@ class LavenderColorScheme extends FlowyColorScheme {
|
||||
toggleButtonBGColor: _lightSelector,
|
||||
calendarWeekendBGColor: const Color(0xFFFBFBFC),
|
||||
gridRowCountColor: _black,
|
||||
borderColor: ColorSchemeConstants.lightBorderColor,
|
||||
scrollbarColor: const Color(0x3F171717),
|
||||
scrollbarHoverColor: const Color(0x7F171717),
|
||||
);
|
||||
|
||||
const LavenderColorScheme.dark()
|
||||
@ -131,5 +135,8 @@ class LavenderColorScheme extends FlowyColorScheme {
|
||||
toggleButtonBGColor: _darkShader1,
|
||||
calendarWeekendBGColor: const Color(0xff121212),
|
||||
gridRowCountColor: _darkMain1,
|
||||
borderColor: ColorSchemeConstants.darkBorderColor,
|
||||
scrollbarColor: const Color(0x40FFFFFF),
|
||||
scrollbarHoverColor: const Color(0x80FFFFFF),
|
||||
);
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import 'package:flowy_infra/colorscheme/default_colorscheme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'colorscheme.dart';
|
||||
@ -83,6 +84,9 @@ class LemonadeColorScheme extends FlowyColorScheme {
|
||||
toggleButtonBGColor: _lightDandelionYellow,
|
||||
calendarWeekendBGColor: const Color(0xFFFBFBFC),
|
||||
gridRowCountColor: _black,
|
||||
borderColor: ColorSchemeConstants.lightBorderColor,
|
||||
scrollbarColor: const Color(0x3F171717),
|
||||
scrollbarHoverColor: const Color(0x7F171717),
|
||||
);
|
||||
|
||||
const LemonadeColorScheme.dark()
|
||||
@ -137,5 +141,8 @@ class LemonadeColorScheme extends FlowyColorScheme {
|
||||
toggleButtonBGColor: _darkShader1,
|
||||
calendarWeekendBGColor: const Color(0xff121212),
|
||||
gridRowCountColor: _darkMain1,
|
||||
borderColor: ColorSchemeConstants.darkBorderColor,
|
||||
scrollbarColor: const Color(0x40FFFFFF),
|
||||
scrollbarHoverColor: const Color(0x80FFFFFF),
|
||||
);
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ class AFThemeExtension extends ThemeExtension<AFThemeExtension> {
|
||||
required this.gridRowCountColor,
|
||||
required this.background,
|
||||
required this.onBackground,
|
||||
required this.borderColor,
|
||||
required this.scrollbarColor,
|
||||
required this.scrollbarHoverColor,
|
||||
});
|
||||
|
||||
final Color? warning;
|
||||
@ -74,6 +77,14 @@ class AFThemeExtension extends ThemeExtension<AFThemeExtension> {
|
||||
final Color background;
|
||||
final Color onBackground;
|
||||
|
||||
/// The color of the border of the widget.
|
||||
///
|
||||
/// This is used in the divider, outline border, etc.
|
||||
final Color borderColor;
|
||||
|
||||
final Color scrollbarColor;
|
||||
final Color scrollbarHoverColor;
|
||||
|
||||
@override
|
||||
AFThemeExtension copyWith({
|
||||
Color? warning,
|
||||
@ -105,6 +116,9 @@ class AFThemeExtension extends ThemeExtension<AFThemeExtension> {
|
||||
TextStyle? caption,
|
||||
Color? background,
|
||||
Color? onBackground,
|
||||
Color? borderColor,
|
||||
Color? scrollbarColor,
|
||||
Color? scrollbarHoverColor,
|
||||
}) =>
|
||||
AFThemeExtension(
|
||||
warning: warning ?? this.warning,
|
||||
@ -137,6 +151,9 @@ class AFThemeExtension extends ThemeExtension<AFThemeExtension> {
|
||||
caption: caption ?? this.caption,
|
||||
onBackground: onBackground ?? this.onBackground,
|
||||
background: background ?? this.background,
|
||||
borderColor: borderColor ?? this.borderColor,
|
||||
scrollbarColor: scrollbarColor ?? this.scrollbarColor,
|
||||
scrollbarHoverColor: scrollbarHoverColor ?? this.scrollbarHoverColor,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -188,6 +205,10 @@ class AFThemeExtension extends ThemeExtension<AFThemeExtension> {
|
||||
caption: other.caption,
|
||||
onBackground: Color.lerp(onBackground, other.onBackground, t)!,
|
||||
background: Color.lerp(background, other.background, t)!,
|
||||
borderColor: Color.lerp(borderColor, other.borderColor, t)!,
|
||||
scrollbarColor: Color.lerp(scrollbarColor, other.scrollbarColor, t)!,
|
||||
scrollbarHoverColor:
|
||||
Color.lerp(scrollbarHoverColor, other.scrollbarHoverColor, t)!,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,9 @@ export 'src/flowy_overlay/option_overlay.dart';
|
||||
export 'src/keyboard/keyboard_visibility_detector.dart';
|
||||
export 'style_widget/button.dart';
|
||||
export 'style_widget/color_picker.dart';
|
||||
export 'style_widget/divider.dart';
|
||||
export 'style_widget/icon_button.dart';
|
||||
export 'style_widget/scrollbar.dart';
|
||||
export 'style_widget/scrolling/styled_list.dart';
|
||||
export 'style_widget/scrolling/styled_scroll_bar.dart';
|
||||
export 'style_widget/text.dart';
|
||||
|
@ -1,5 +1,5 @@
|
||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/decoration.dart';
|
||||
import 'package:flowy_infra/colorscheme/default_colorscheme.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AppFlowyPopover extends StatelessWidget {
|
||||
@ -17,7 +17,8 @@ class AppFlowyPopover extends StatelessWidget {
|
||||
final bool asBarrier;
|
||||
final EdgeInsets margin;
|
||||
final EdgeInsets windowPadding;
|
||||
final Decoration? decoration;
|
||||
final Color? decorationColor;
|
||||
final BorderRadius? borderRadius;
|
||||
|
||||
/// The widget that will be used to trigger the popover.
|
||||
///
|
||||
@ -46,9 +47,10 @@ class AppFlowyPopover extends StatelessWidget {
|
||||
this.asBarrier = false,
|
||||
this.margin = const EdgeInsets.all(6),
|
||||
this.windowPadding = const EdgeInsets.all(8.0),
|
||||
this.decoration,
|
||||
this.clickHandler = PopoverClickHandler.listener,
|
||||
this.skipTraversal = false,
|
||||
this.decorationColor,
|
||||
this.borderRadius,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -70,7 +72,8 @@ class AppFlowyPopover extends StatelessWidget {
|
||||
return _PopoverContainer(
|
||||
constraints: constraints,
|
||||
margin: margin,
|
||||
decoration: decoration,
|
||||
decorationColor: decorationColor,
|
||||
borderRadius: borderRadius,
|
||||
child: popupBuilder(context),
|
||||
);
|
||||
},
|
||||
@ -81,33 +84,79 @@ class AppFlowyPopover extends StatelessWidget {
|
||||
|
||||
class _PopoverContainer extends StatelessWidget {
|
||||
const _PopoverContainer({
|
||||
this.decorationColor,
|
||||
this.borderRadius,
|
||||
required this.child,
|
||||
required this.margin,
|
||||
required this.constraints,
|
||||
required this.decoration,
|
||||
});
|
||||
|
||||
final Widget child;
|
||||
final BoxConstraints constraints;
|
||||
final EdgeInsets margin;
|
||||
final Decoration? decoration;
|
||||
final Color? decorationColor;
|
||||
final BorderRadius? borderRadius;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final decoration = this.decoration ??
|
||||
FlowyDecoration.decoration(
|
||||
Theme.of(context).cardColor,
|
||||
Theme.of(context).colorScheme.shadow,
|
||||
);
|
||||
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Container(
|
||||
padding: margin,
|
||||
decoration: decoration,
|
||||
decoration: context.getPopoverDecoration(
|
||||
color: decorationColor,
|
||||
borderRadius: borderRadius,
|
||||
),
|
||||
constraints: constraints,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension on BuildContext {
|
||||
/// The decoration of the popover.
|
||||
///
|
||||
/// Don't customize the entire decoration of the popover,
|
||||
/// use the built-in popoverDecoration instead and ask the designer before changing it.
|
||||
ShapeDecoration getPopoverDecoration({
|
||||
Color? color,
|
||||
BorderRadius? borderRadius,
|
||||
}) {
|
||||
final borderColor = Theme.of(this).brightness == Brightness.light
|
||||
? ColorSchemeConstants.lightBorderColor
|
||||
: ColorSchemeConstants.darkBorderColor;
|
||||
final shadows = [
|
||||
const BoxShadow(
|
||||
color: Color(0x0A1F2329),
|
||||
blurRadius: 24,
|
||||
offset: Offset(0, 8),
|
||||
spreadRadius: 8,
|
||||
),
|
||||
const BoxShadow(
|
||||
color: Color(0x0A1F2329),
|
||||
blurRadius: 12,
|
||||
offset: Offset(0, 6),
|
||||
spreadRadius: 0,
|
||||
),
|
||||
const BoxShadow(
|
||||
color: Color(0x0F1F2329),
|
||||
blurRadius: 8,
|
||||
offset: Offset(0, 4),
|
||||
spreadRadius: -8,
|
||||
)
|
||||
];
|
||||
return ShapeDecoration(
|
||||
color: color ?? Theme.of(this).cardColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
width: 1,
|
||||
strokeAlign: BorderSide.strokeAlignOutside,
|
||||
color: borderColor,
|
||||
),
|
||||
borderRadius: borderRadius ?? BorderRadius.circular(10),
|
||||
),
|
||||
shadows: shadows,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,141 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/style_widget/hover.dart';
|
||||
import 'package:flowy_infra_ui/widget/flowy_tooltip.dart';
|
||||
import 'package:flowy_infra_ui/widget/ignore_parent_gesture.dart';
|
||||
import 'package:flowy_infra_ui/widget/spacing.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FlowyIconTextButton extends StatelessWidget {
|
||||
final Widget Function(bool onHover) textBuilder;
|
||||
final VoidCallback? onTap;
|
||||
final VoidCallback? onSecondaryTap;
|
||||
final void Function(bool)? onHover;
|
||||
final EdgeInsets? margin;
|
||||
final Widget Function(bool onHover)? leftIconBuilder;
|
||||
final Widget Function(bool onHover)? rightIconBuilder;
|
||||
final Color? hoverColor;
|
||||
final bool isSelected;
|
||||
final BorderRadius? radius;
|
||||
final BoxDecoration? decoration;
|
||||
final bool useIntrinsicWidth;
|
||||
final bool disable;
|
||||
final double disableOpacity;
|
||||
final Size? leftIconSize;
|
||||
final bool expandText;
|
||||
final MainAxisAlignment mainAxisAlignment;
|
||||
final bool showDefaultBoxDecorationOnMobile;
|
||||
final double iconPadding;
|
||||
final bool expand;
|
||||
final Color? borderColor;
|
||||
|
||||
const FlowyIconTextButton({
|
||||
super.key,
|
||||
required this.textBuilder,
|
||||
this.onTap,
|
||||
this.onSecondaryTap,
|
||||
this.onHover,
|
||||
this.margin,
|
||||
this.leftIconBuilder,
|
||||
this.rightIconBuilder,
|
||||
this.hoverColor,
|
||||
this.isSelected = false,
|
||||
this.radius,
|
||||
this.decoration,
|
||||
this.useIntrinsicWidth = false,
|
||||
this.disable = false,
|
||||
this.disableOpacity = 0.5,
|
||||
this.leftIconSize = const Size.square(16),
|
||||
this.expandText = true,
|
||||
this.mainAxisAlignment = MainAxisAlignment.center,
|
||||
this.showDefaultBoxDecorationOnMobile = false,
|
||||
this.iconPadding = 6,
|
||||
this.expand = false,
|
||||
this.borderColor,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final color = hoverColor ?? Theme.of(context).colorScheme.secondary;
|
||||
|
||||
return GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: disable ? null : onTap,
|
||||
onSecondaryTap: disable ? null : onSecondaryTap,
|
||||
child: FlowyHover(
|
||||
cursor:
|
||||
disable ? SystemMouseCursors.forbidden : SystemMouseCursors.click,
|
||||
style: HoverStyle(
|
||||
borderRadius: radius ?? Corners.s6Border,
|
||||
hoverColor: color,
|
||||
borderColor: borderColor ?? Colors.transparent,
|
||||
),
|
||||
onHover: disable ? null : onHover,
|
||||
isSelected: () => isSelected,
|
||||
builder: (context, onHover) => _render(context, onHover),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _render(BuildContext context, bool onHover) {
|
||||
final List<Widget> children = [];
|
||||
|
||||
if (leftIconBuilder != null) {
|
||||
children.add(
|
||||
SizedBox.fromSize(
|
||||
size: leftIconSize,
|
||||
child: leftIconBuilder!(onHover),
|
||||
),
|
||||
);
|
||||
children.add(HSpace(iconPadding));
|
||||
}
|
||||
|
||||
if (expandText) {
|
||||
children.add(Expanded(child: textBuilder(onHover)));
|
||||
} else {
|
||||
children.add(textBuilder(onHover));
|
||||
}
|
||||
|
||||
if (rightIconBuilder != null) {
|
||||
children.add(HSpace(iconPadding));
|
||||
// No need to define the size of rightIcon. Just use its intrinsic width
|
||||
children.add(rightIconBuilder!(onHover));
|
||||
}
|
||||
|
||||
Widget child = Row(
|
||||
mainAxisAlignment: mainAxisAlignment,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: expand ? MainAxisSize.max : MainAxisSize.min,
|
||||
children: children,
|
||||
);
|
||||
|
||||
if (useIntrinsicWidth) {
|
||||
child = IntrinsicWidth(child: child);
|
||||
}
|
||||
|
||||
final decoration = this.decoration ??
|
||||
(showDefaultBoxDecorationOnMobile &&
|
||||
(Platform.isIOS || Platform.isAndroid)
|
||||
? BoxDecoration(
|
||||
border: Border.all(
|
||||
color: borderColor ??
|
||||
Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
width: 1.0,
|
||||
))
|
||||
: null);
|
||||
|
||||
return Container(
|
||||
decoration: decoration,
|
||||
child: Padding(
|
||||
padding:
|
||||
margin ?? const EdgeInsets.symmetric(horizontal: 6, vertical: 4),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FlowyButton extends StatelessWidget {
|
||||
final Widget text;
|
||||
@ -30,6 +158,7 @@ class FlowyButton extends StatelessWidget {
|
||||
final bool showDefaultBoxDecorationOnMobile;
|
||||
final double iconPadding;
|
||||
final bool expand;
|
||||
final Color? borderColor;
|
||||
|
||||
const FlowyButton({
|
||||
super.key,
|
||||
@ -53,6 +182,7 @@ class FlowyButton extends StatelessWidget {
|
||||
this.showDefaultBoxDecorationOnMobile = false,
|
||||
this.iconPadding = 6,
|
||||
this.expand = false,
|
||||
this.borderColor,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -80,6 +210,7 @@ class FlowyButton extends StatelessWidget {
|
||||
style: HoverStyle(
|
||||
borderRadius: radius ?? Corners.s6Border,
|
||||
hoverColor: color,
|
||||
borderColor: borderColor ?? Colors.transparent,
|
||||
),
|
||||
onHover: disable ? null : onHover,
|
||||
isSelected: () => isSelected,
|
||||
@ -129,7 +260,8 @@ class FlowyButton extends StatelessWidget {
|
||||
(Platform.isIOS || Platform.isAndroid)
|
||||
? BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
color: borderColor ??
|
||||
Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
width: 1.0,
|
||||
))
|
||||
: null);
|
||||
|
@ -8,6 +8,7 @@ class FlowyDecoration {
|
||||
double blurRadius = 20,
|
||||
Offset offset = Offset.zero,
|
||||
double borderRadius = 6,
|
||||
BoxBorder? border,
|
||||
}) {
|
||||
return BoxDecoration(
|
||||
color: boxColor,
|
||||
@ -20,6 +21,7 @@ class FlowyDecoration {
|
||||
offset: offset,
|
||||
),
|
||||
],
|
||||
border: border,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FlowyDivider extends StatelessWidget {
|
||||
const FlowyDivider({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Divider(
|
||||
height: 1.0,
|
||||
thickness: 1.0,
|
||||
color: AFThemeExtension.of(context).borderColor,
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class FlowyScrollbar extends StatefulWidget {
|
||||
const FlowyScrollbar({
|
||||
super.key,
|
||||
this.controller,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
final ScrollController? controller;
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
State<FlowyScrollbar> createState() => _FlowyScrollbarState();
|
||||
}
|
||||
|
||||
class _FlowyScrollbarState extends State<FlowyScrollbar> {
|
||||
final ValueNotifier<bool> isHovered = ValueNotifier(false);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
isHovered.dispose();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
onEnter: (_) => isHovered.value = true,
|
||||
onExit: (_) => isHovered.value = false,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: isHovered,
|
||||
builder: (context, isHovered, child) {
|
||||
return Scrollbar(
|
||||
thumbVisibility: isHovered,
|
||||
// the radius should be fixed to 12
|
||||
radius: const Radius.circular(12),
|
||||
controller: widget.controller,
|
||||
child: ScrollConfiguration(
|
||||
behavior: ScrollConfiguration.of(context).copyWith(
|
||||
scrollbars: false,
|
||||
),
|
||||
child: child!,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: widget.child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,12 +1,11 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:async/async.dart';
|
||||
import 'package:flowy_infra/size.dart';
|
||||
import 'package:flowy_infra/theme_extension.dart';
|
||||
import 'package:flowy_infra_ui/widget/mouse_hover_builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
class StyledScrollbar extends StatefulWidget {
|
||||
@ -120,11 +119,6 @@ class ScrollbarState extends State<StyledScrollbar> {
|
||||
? false
|
||||
: contentExtent > _viewExtent && contentExtent > 0;
|
||||
|
||||
// Handle color
|
||||
var handleColor = widget.handleColor ??
|
||||
(Theme.of(context).brightness == Brightness.dark
|
||||
? AFThemeExtension.of(context).lightGreyHover
|
||||
: AFThemeExtension.of(context).greyHover);
|
||||
// Track color
|
||||
var trackColor = widget.trackColor ??
|
||||
(Theme.of(context).brightness == Brightness.dark
|
||||
@ -161,18 +155,24 @@ class ScrollbarState extends State<StyledScrollbar> {
|
||||
onHorizontalDragUpdate: _handleHorizontalDrag,
|
||||
// HANDLE SHAPE
|
||||
child: MouseHoverBuilder(
|
||||
builder: (_, isHovered) => Container(
|
||||
width: widget.axis == Axis.vertical
|
||||
? widget.size
|
||||
: handleExtent,
|
||||
height: widget.axis == Axis.horizontal
|
||||
? widget.size
|
||||
: handleExtent,
|
||||
decoration: BoxDecoration(
|
||||
color: handleColor.withOpacity(isHovered ? 1 : .85),
|
||||
borderRadius: Corners.s3Border,
|
||||
),
|
||||
),
|
||||
builder: (_, isHovered) {
|
||||
final handleColor =
|
||||
Theme.of(context).scrollbarTheme.thumbColor?.resolve(
|
||||
isHovered ? {WidgetState.dragged} : {},
|
||||
);
|
||||
return Container(
|
||||
width: widget.axis == Axis.vertical
|
||||
? widget.size
|
||||
: handleExtent,
|
||||
height: widget.axis == Axis.horizontal
|
||||
? widget.size
|
||||
: handleExtent,
|
||||
decoration: BoxDecoration(
|
||||
color: handleColor,
|
||||
borderRadius: Corners.s3Border,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -1,7 +1,6 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
class FlowyText extends StatelessWidget {
|
||||
@ -20,6 +19,7 @@ class FlowyText extends StatelessWidget {
|
||||
final bool withTooltip;
|
||||
final StrutStyle? strutStyle;
|
||||
final bool isEmoji;
|
||||
final double? figmaLineHeight;
|
||||
|
||||
const FlowyText(
|
||||
this.text, {
|
||||
@ -38,6 +38,7 @@ class FlowyText extends StatelessWidget {
|
||||
this.withTooltip = false,
|
||||
this.isEmoji = false,
|
||||
this.strutStyle,
|
||||
this.figmaLineHeight,
|
||||
});
|
||||
|
||||
FlowyText.small(
|
||||
@ -55,6 +56,7 @@ class FlowyText extends StatelessWidget {
|
||||
this.withTooltip = false,
|
||||
this.isEmoji = false,
|
||||
this.strutStyle,
|
||||
this.figmaLineHeight,
|
||||
}) : fontWeight = FontWeight.w400,
|
||||
fontSize = (Platform.isIOS || Platform.isAndroid) ? 14 : 12;
|
||||
|
||||
@ -74,6 +76,7 @@ class FlowyText extends StatelessWidget {
|
||||
this.withTooltip = false,
|
||||
this.isEmoji = false,
|
||||
this.strutStyle,
|
||||
this.figmaLineHeight,
|
||||
}) : fontWeight = FontWeight.w400;
|
||||
|
||||
const FlowyText.medium(
|
||||
@ -92,6 +95,7 @@ class FlowyText extends StatelessWidget {
|
||||
this.withTooltip = false,
|
||||
this.isEmoji = false,
|
||||
this.strutStyle,
|
||||
this.figmaLineHeight,
|
||||
}) : fontWeight = FontWeight.w500;
|
||||
|
||||
const FlowyText.semibold(
|
||||
@ -110,6 +114,7 @@ class FlowyText extends StatelessWidget {
|
||||
this.withTooltip = false,
|
||||
this.isEmoji = false,
|
||||
this.strutStyle,
|
||||
this.figmaLineHeight,
|
||||
}) : fontWeight = FontWeight.w600;
|
||||
|
||||
// Some emojis are not supported on Linux and Android, fallback to noto color emoji
|
||||
@ -128,6 +133,7 @@ class FlowyText extends StatelessWidget {
|
||||
this.strutStyle = const StrutStyle(forceStrutHeight: true),
|
||||
this.isEmoji = true,
|
||||
this.fontFamily,
|
||||
this.figmaLineHeight,
|
||||
}) : fontWeight = FontWeight.w400,
|
||||
fallbackFontFamily = null;
|
||||
|
||||
@ -150,6 +156,13 @@ class FlowyText extends StatelessWidget {
|
||||
fontSize = fontSize * 0.8;
|
||||
}
|
||||
|
||||
double? lineHeight;
|
||||
if (this.lineHeight != null) {
|
||||
lineHeight = this.lineHeight!;
|
||||
} else if (figmaLineHeight != null) {
|
||||
lineHeight = figmaLineHeight! / fontSize;
|
||||
}
|
||||
|
||||
final textStyle = Theme.of(context).textTheme.bodyMedium!.copyWith(
|
||||
fontSize: fontSize,
|
||||
fontWeight: fontWeight,
|
||||
|
@ -26,21 +26,47 @@ class FlowyTooltip extends StatelessWidget {
|
||||
return child ?? const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final isLightMode = Theme.of(context).brightness == Brightness.light;
|
||||
return Tooltip(
|
||||
margin: margin,
|
||||
verticalOffset: 16.0,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12.0,
|
||||
right: 12.0,
|
||||
top: 5.0,
|
||||
bottom: 8.0,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: isLightMode ? const Color(0xE5171717) : const Color(0xE5E5E5E5),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
color: context.tooltipBackgroundColor(),
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
),
|
||||
waitDuration: _tooltipWaitDuration,
|
||||
message: message,
|
||||
textStyle: message != null ? context.tooltipTextStyle() : null,
|
||||
richMessage: richMessage,
|
||||
showDuration: showDuration,
|
||||
preferBelow: preferBelow,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
extension FlowyToolTipExtension on BuildContext {
|
||||
double tooltipFontSize() => 13.0;
|
||||
double tooltipHeight() => 18.0 / tooltipFontSize();
|
||||
Color tooltipFontColor() => Theme.of(this).brightness == Brightness.light
|
||||
? Colors.white
|
||||
: Colors.black;
|
||||
|
||||
TextStyle? tooltipTextStyle({Color? fontColor}) {
|
||||
return Theme.of(this).textTheme.bodyMedium?.copyWith(
|
||||
color: fontColor ?? tooltipFontColor(),
|
||||
fontSize: tooltipFontSize(),
|
||||
fontWeight: FontWeight.w400,
|
||||
height: tooltipHeight(),
|
||||
);
|
||||
}
|
||||
|
||||
Color tooltipBackgroundColor() =>
|
||||
Theme.of(this).brightness == Brightness.light
|
||||
? const Color(0xFF1D2129)
|
||||
: const Color(0xE5E5E5E5);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
version: 0.6.5
|
||||
version: 0.6.6
|
||||
|
||||
environment:
|
||||
flutter: ">=3.22.0"
|
||||
|
@ -1,5 +1,5 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.5">
|
||||
<path d="M8.38274 2.1912C8.61919 1.95467 8.99451 1.91977 9.2623 2.18766L14.145 7.07205C14.3765 7.30363 14.411 7.68431 14.1468 7.94865C13.9854 8.11011 13.5919 8.23414 13.2876 7.92972L12.5611 7.20735L10.6204 9.1481C10.5628 9.20571 10.5477 9.30158 10.5477 9.38042L10.2799 13.2031C10.2799 13.285 10.2475 13.3638 10.1899 13.4214L9.84485 13.7657C9.60524 14.0063 9.21857 14.0071 8.98279 13.7713L6.20394 10.9936L3.37596 13.8224C3.1392 14.0592 2.75536 14.0592 2.51861 13.8224L2.5096 13.8134C2.27301 13.5767 2.27282 13.193 2.50916 12.9561L5.33522 10.1233L2.5568 7.34311C2.31101 7.09723 2.31763 6.71613 2.55769 6.47598L2.90214 6.13221C2.95976 6.07459 3.03787 6.04124 3.11932 6.04124L6.94541 5.77806C7.02695 5.77806 7.13094 5.77049 7.18854 5.71288L9.12891 3.77213L8.40493 3.04532C8.17437 2.81725 8.15367 2.42036 8.38274 2.1912Z" fill="#171717"/>
|
||||
<path d="M4.21594 1C3.79948 1 3.53477 1.31897 3.53477 1.68668C3.53477 2.04293 3.85938 2.33534 4.21594 2.33333L5.34384 2.33534L5.3436 5.35268C5.3436 5.44225 5.26862 5.52899 5.20522 5.59239L2.43472 8.77204C2.37139 8.83537 2.33657 8.92204 2.33655 9.01163L2.33594 9.54668C2.33594 9.92001 2.62702 10.2214 3.00927 10.2214L7.33078 10.2221L7.33526 14.4C7.33563 14.7679 7.634 15 8.00193 15H8.01594C8.38412 15 8.68259 14.7682 8.6826 14.4L8.68275 10.223L13.0026 10.2213C13.3693 10.2213 13.6693 9.92001 13.6686 9.54668L13.6693 9.01078C13.6693 8.92122 13.6332 8.83471 13.5696 8.77107L10.8064 5.59145C10.7452 5.53017 10.6824 5.4439 10.6824 5.35433L10.6829 2.33676L11.8093 2.33334C12.2825 2.33334 12.492 1.93102 12.492 1.68001C12.492 1.26906 12.1693 1.00001 11.8093 1H4.21594ZM6.70711 2.33483L9.37687 2.33333L9.38048 5.94579L11.9314 8.89026L4.13249 8.88794L6.70923 5.93339L6.70711 2.33483Z" fill="#2B2F36"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 960 B After Width: | Height: | Size: 1019 B |
@ -1,5 +1,7 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.5">
|
||||
<path d="M9.2623 2.18766C8.99451 1.91977 8.61919 1.95467 8.38274 2.1912C8.15367 2.42036 8.17437 2.81725 8.40493 3.04532L9.12891 3.77213L7.18854 5.71288C7.13094 5.77049 7.02695 5.77806 6.94541 5.77806L3.11932 6.04124C3.03787 6.04124 2.95976 6.07459 2.90214 6.13221L2.55769 6.47598C2.31763 6.71613 2.31101 7.09723 2.5568 7.34311L5.33522 10.1233L2.50916 12.9561C2.27282 13.193 2.27301 13.5767 2.5096 13.8134L2.51861 13.8224C2.75536 14.0592 3.1392 14.0592 3.37596 13.8224L6.20394 10.9936L8.98279 13.7713C9.21857 14.0071 9.60524 14.0063 9.84485 13.7657L10.1899 13.4214C10.2475 13.3638 10.2799 13.285 10.2799 13.2031L10.5477 9.38042C10.5477 9.30159 10.5628 9.20571 10.6204 9.1481L12.5611 7.20735L13.2876 7.92972C13.5919 8.23414 13.9854 8.11011 14.1468 7.94865C14.411 7.68431 14.3765 7.30363 14.145 7.07205L9.2623 2.18766ZM10.0059 4.64872L11.7235 6.36508L9.40296 8.69111L9.14988 12.226L4.1365 7.20788L7.69325 6.96485L10.0059 4.64872Z" fill="#171717"/>
|
||||
<path d="M2.42691 8.77204L4.58617 6.2939L5.54809 7.25582L4.12467 8.88794L7.18111 8.88885L8.67493 10.3827L8.67479 14.6208C8.67478 14.989 8.37631 15.2875 8.00813 15.2875H7.99411C7.62619 15.2875 7.32782 14.9894 7.32745 14.6215L7.32297 10.2221L3.00146 10.2214C2.61921 10.2214 2.32812 9.92001 2.32812 9.54668L2.32874 9.01163C2.32876 8.92204 2.36357 8.83537 2.42691 8.77204Z" fill="#171717"/>
|
||||
<path d="M11.9236 8.89026L11.9012 8.89025L13.1997 10.1888C13.4669 10.1012 13.6613 9.8473 13.6608 9.54668L13.6615 9.01078C13.6615 8.92122 13.6254 8.83471 13.5618 8.77107L10.7986 5.59145C10.7374 5.53017 10.6746 5.4439 10.6746 5.35433L10.675 2.33675L11.8015 2.33334C12.2747 2.33334 12.4842 1.93102 12.4842 1.68001C12.4842 1.26906 12.1615 1.00001 11.8015 1H4.20813C4.14572 1 4.08673 1.00716 4.03152 1.02058L6.70009 3.68915L6.6993 2.33483L9.36906 2.33333L9.37267 5.94579L11.9236 8.89026Z" fill="#171717"/>
|
||||
</g>
|
||||
<path opacity="0.5" d="M1.79688 1.2002L14.1712 13.5746" stroke="#171717" stroke-width="1.2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.1 KiB |
@ -1,3 +1,3 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M8.78714 4.75039V4.16515C8.78714 3.42984 8.6 1.25 5.99904 1.25C3.3 1.25 3.21094 3.42984 3.21094 4.16515V4.75039L3.38817 4.73529L3.2119 4.75123C2.30484 4.99873 2 5.7229 2 7.29041V8.20709C2 10.2238 2.50558 10.9996 4.14127 10.9996H7.85873C9.49442 10.9996 10 10.2238 10 8.20709V7.29041C10 5.7229 9.69516 4.99873 8.7881 4.75123L8.64331 4.73813L8.78714 4.75039ZM4.32618 4.16515V4.65048L7.6719 4.65039V4.16515C7.6719 3.0108 7.3 2.3002 5.99904 2.3002C4.65 2.3002 4.32618 3.0108 4.32618 4.16515ZM6.00078 8.95078C6.66352 8.95078 7.20078 8.41352 7.20078 7.75078C7.20078 7.08804 6.66352 6.55078 6.00078 6.55078C5.33804 6.55078 4.80078 7.08804 4.80078 7.75078C4.80078 8.41352 5.33804 8.95078 6.00078 8.95078Z" fill="#171717"/>
|
||||
</svg>
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.4" fill-rule="evenodd" clip-rule="evenodd" d="M10.2465 5.5418V4.85902C10.2465 4.00116 10.0281 1.45801 6.99367 1.45801C3.84479 1.45801 3.74089 4.00116 3.74089 4.85902V5.5418L3.94766 5.52418L3.74201 5.54277C2.68377 5.83152 2.32812 6.67639 2.32812 8.50516V9.57461C2.32812 11.9274 2.91797 12.8326 4.82627 12.8326H9.16331C11.0716 12.8326 11.6615 11.9274 11.6615 9.57461V8.50516C11.6615 6.67639 11.3058 5.83152 10.2476 5.54277L10.0787 5.5275L10.2465 5.5418ZM5.042 4.85902V5.42523L8.94534 5.42513V4.85902C8.94534 3.51227 8.51146 2.68324 6.99367 2.68324C5.41979 2.68324 5.042 3.51227 5.042 4.85902ZM6.99115 10.4423C7.76434 10.4423 8.39115 9.81545 8.39115 9.04225C8.39115 8.26905 7.76434 7.64225 6.99115 7.64225C6.21795 7.64225 5.59115 8.26905 5.59115 9.04225C5.59115 9.81545 6.21795 10.4423 6.99115 10.4423Z" fill="#171717"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 880 B After Width: | Height: | Size: 937 B |
@ -272,7 +272,7 @@
|
||||
"recent": "Recent",
|
||||
"today": "Today",
|
||||
"thisWeek": "This week",
|
||||
"others": "Other favorites",
|
||||
"others": "Earlier favorites",
|
||||
"justNow": "just now",
|
||||
"minutesAgo": "{count} minutes ago",
|
||||
"lastViewed": "Last viewed",
|
||||
@ -2159,6 +2159,7 @@
|
||||
"createNewSpace": "Create a new space",
|
||||
"createSpaceDescription": "Create multiple public and private spaces to better organize your work.",
|
||||
"spaceName": "Space name",
|
||||
"spaceNamePlaceholder": "e.g. Marketing, Engineering, HR",
|
||||
"permission": "Permission",
|
||||
"publicPermission": "Public",
|
||||
"publicPermissionDescription": "All workspace members with full access",
|
||||
|
Loading…
Reference in New Issue
Block a user