diff --git a/.changeset/button-tag-speeddial-timepicker-improvements.md b/.changeset/button-tag-speeddial-timepicker-improvements.md
new file mode 100644
index 00000000..089522a8
--- /dev/null
+++ b/.changeset/button-tag-speeddial-timepicker-improvements.md
@@ -0,0 +1,6 @@
+---
+"@tiny-design/react": minor
+"@tiny-design/tokens": minor
+---
+
+Add hover/focus/active state styles for button status types (success, info, warning, danger), add status color presets to Tag component, fix SpeedDial to use theme-aware CSS custom properties, and improve TimePicker with pending selection state committed on OK
diff --git a/packages/react/src/button/style/_index.scss b/packages/react/src/button/style/_index.scss
index d74a0bd2..31563757 100755
--- a/packages/react/src/button/style/_index.scss
+++ b/packages/react/src/button/style/_index.scss
@@ -24,7 +24,7 @@ $btn-prefix: #{$prefix}-btn;
line-height: $btn-line-height;
&__loader {
- @include loader();
+ @include loader;
}
&__icon-container, &__loader {
@@ -91,19 +91,27 @@ $btn-prefix: #{$prefix}-btn;
}
&_info {
- @include button-style(#fff, var(--ty-color-info), var(--ty-color-info));
+ @include button-style(#fff, var(--ty-color-info), var(--ty-color-info),
+ var(--ty-color-info-hover), var(--ty-color-info-hover), #fff,
+ var(--ty-color-info-active), var(--ty-color-info-active), #fff);
}
&_success {
- @include button-style(#fff, var(--ty-color-success), var(--ty-color-success));
+ @include button-style(#fff, var(--ty-color-success), var(--ty-color-success),
+ var(--ty-color-success-hover), var(--ty-color-success-hover), #fff,
+ var(--ty-color-success-active), var(--ty-color-success-active), #fff);
}
&_warning {
- @include button-style(#fff, var(--ty-color-warning), var(--ty-color-warning));
+ @include button-style(#fff, var(--ty-color-warning), var(--ty-color-warning),
+ var(--ty-color-warning-hover), var(--ty-color-warning-hover), #fff,
+ var(--ty-color-warning-active), var(--ty-color-warning-active), #fff);
}
&_danger {
- @include button-style(#fff, var(--ty-color-danger), var(--ty-color-danger));
+ @include button-style(#fff, var(--ty-color-danger), var(--ty-color-danger),
+ var(--ty-color-danger-hover), var(--ty-color-danger-hover), #fff,
+ var(--ty-color-danger-active), var(--ty-color-danger-active), #fff);
}
// Sizes
@@ -135,13 +143,10 @@ $btn-prefix: #{$prefix}-btn;
position: relative;
pointer-events: none;
- &:before {
+ &::before {
content: '';
position: absolute;
- top: -1px;
- right: -1px;
- bottom: -1px;
- left: -1px;
+ inset: -1px;
z-index: 1;
display: block;
background: var(--ty-btn-loading-bg);
@@ -208,7 +213,7 @@ $btn-prefix: #{$prefix}-btn;
&_danger {
.#{$btn-prefix} {
&:not(:first-child) {
- border-left-color: rgba(255, 255, 255, 0.2);
+ border-left-color: rgb(255 255 255 / 20%);
}
}
}
diff --git a/packages/react/src/pop-confirm/style/_index.scss b/packages/react/src/pop-confirm/style/_index.scss
index 5a83799b..0b44b8d9 100755
--- a/packages/react/src/pop-confirm/style/_index.scss
+++ b/packages/react/src/pop-confirm/style/_index.scss
@@ -15,6 +15,10 @@
}
&__buttons {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 8px;
text-align: right;
}
diff --git a/packages/react/src/slider/style/_index.scss b/packages/react/src/slider/style/_index.scss
index b6200a5f..97f0e46f 100644
--- a/packages/react/src/slider/style/_index.scss
+++ b/packages/react/src/slider/style/_index.scss
@@ -5,21 +5,13 @@
box-sizing: border-box;
cursor: pointer;
- &_horizontal.#{$prefix}-slider {
- margin-bottom: $slider-margin-bottom-with-marks;
- }
-
- &_vertical.#{$prefix}-slider {
- margin-right: $slider-margin-bottom-with-marks;
- }
-
&_horizontal {
+ width: 100%;
min-height: $slider-size;
margin: 13px 7px;
padding: 4px 0;
.#{$prefix}-slider {
-
&__rail {
width: 100%;
height: $slider-track-size;
diff --git a/packages/react/src/speed-dial/style/_index.scss b/packages/react/src/speed-dial/style/_index.scss
index 7261c2e3..dd56239f 100644
--- a/packages/react/src/speed-dial/style/_index.scss
+++ b/packages/react/src/speed-dial/style/_index.scss
@@ -1,5 +1,4 @@
@use "../../style/variables" as *;
-@use "sass:color";
$speed-dial-fab-size: 56px;
$speed-dial-action-size: 40px;
@@ -18,8 +17,8 @@ $speed-dial-actions-gap: 16px;
height: $speed-dial-fab-size;
border-radius: 50%;
border: none;
- background-color: var(--ty-speed-dial-bg, #{$primary-color});
- color: var(--ty-speed-dial-color, #{$white-color});
+ background-color: var(--ty-speed-dial-bg, var(--ty-color-primary));
+ color: var(--ty-speed-dial-color, #fff);
font-size: 24px;
cursor: pointer;
box-shadow: $box-shadow;
@@ -27,11 +26,11 @@ $speed-dial-actions-gap: 16px;
outline: none;
&:hover:not(.#{$prefix}-speed-dial__button_disabled) {
- background-color: var(--ty-speed-dial-bg-hover, #{color.adjust($primary-color, $lightness: -8%)});
+ background-color: var(--ty-speed-dial-bg-hover, var(--ty-color-primary-active));
}
&:focus-visible {
- box-shadow: 0 0 0 3px rgba($primary-color, 0.3), $box-shadow;
+ box-shadow: 0 0 0 3px var(--ty-input-focus-shadow, rgb(110 65 191 / 20%)), $box-shadow;
}
&_open {
@@ -59,7 +58,7 @@ $speed-dial-actions-gap: 16px;
position: absolute;
top: 50%;
left: 50%;
- background-color: currentColor;
+ background-color: currentcolor;
border-radius: 1px;
translate: -50% -50%;
}
@@ -183,7 +182,7 @@ $speed-dial-actions-gap: 16px;
}
&:focus-visible {
- box-shadow: 0 0 0 3px rgba($primary-color, 0.3), $box-shadow-sm;
+ box-shadow: 0 0 0 3px var(--ty-input-focus-shadow, rgb(110 65 191 / 20%)), $box-shadow-sm;
}
&_disabled {
diff --git a/packages/react/src/tag/demo/Status.tsx b/packages/react/src/tag/demo/Status.tsx
new file mode 100644
index 00000000..c9c744a7
--- /dev/null
+++ b/packages/react/src/tag/demo/Status.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import { Tag } from '@tiny-design/react';
+
+export default function StatusDemo() {
+ return (
+
+ success
+ info
+ warning
+ danger
+
+ );
+}
diff --git a/packages/react/src/tag/index.md b/packages/react/src/tag/index.md
index 08fc2ae9..cd4e60a9 100755
--- a/packages/react/src/tag/index.md
+++ b/packages/react/src/tag/index.md
@@ -8,6 +8,8 @@ import ControlledDemo from './demo/Controlled';
import ControlledSource from './demo/Controlled.tsx?raw';
import DynamicDemo from './demo/Dynamic';
import DynamicSource from './demo/Dynamic.tsx?raw';
+import StatusDemo from './demo/Status';
+import StatusSource from './demo/Status.tsx?raw';
# Tag
@@ -71,6 +73,15 @@ We preset a series of colorful tag styles for use in different situations. You c
+### Status
+
+Status tags use semantic colors that match the button component's status types.
+
+
+
+
+
+
### Controlled
By using the `visible` prop, you can control the close state of Tag.
@@ -98,6 +109,8 @@ By using the `visible` prop, you can control the close state of Tag.
Preset colors: `magenta`, `red`, `volcano`, `orange`, `gold`, `lime`, `green`, `cyan`, `blue`, `geekblue`, `purple`.
+Status colors: `success`, `info`, `warning`, `danger`.
+
### Tag.CheckableTag
| Property | Description | Type | Default |
diff --git a/packages/react/src/tag/index.zh_CN.md b/packages/react/src/tag/index.zh_CN.md
index c4e9e90c..5b48f4f2 100644
--- a/packages/react/src/tag/index.zh_CN.md
+++ b/packages/react/src/tag/index.zh_CN.md
@@ -8,6 +8,8 @@ import ControlledDemo from './demo/Controlled';
import ControlledSource from './demo/Controlled.tsx?raw';
import DynamicDemo from './demo/Dynamic';
import DynamicSource from './demo/Dynamic.tsx?raw';
+import StatusDemo from './demo/Status';
+import StatusSource from './demo/Status.tsx?raw';
# Tag
@@ -71,6 +73,15 @@ const { CheckableTag } = Tag;
+### 状态标签
+
+状态标签使用与按钮组件状态类型一致的语义化颜色。
+
+
+
+
+
+
### 受控显示
通过 `visible` 属性控制标签的显示与隐藏。
@@ -98,6 +109,8 @@ const { CheckableTag } = Tag;
预设颜色:`magenta`、`red`、`volcano`、`orange`、`gold`、`lime`、`green`、`cyan`、`blue`、`geekblue`、`purple`。
+状态颜色:`success`、`info`、`warning`、`danger`。
+
### Tag.CheckableTag
| 属性 | 说明 | 类型 | 默认值 |
diff --git a/packages/react/src/tag/style/_index.scss b/packages/react/src/tag/style/_index.scss
index 3e0667dd..36b0dd9c 100755
--- a/packages/react/src/tag/style/_index.scss
+++ b/packages/react/src/tag/style/_index.scss
@@ -102,6 +102,30 @@
background: var(--ty-tag-purple-bg);
border-color: var(--ty-tag-purple-border);
}
+
+ &_success {
+ color: var(--ty-color-success);
+ background: var(--ty-color-success-bg);
+ border-color: var(--ty-color-success-border);
+ }
+
+ &_info {
+ color: var(--ty-color-info);
+ background: var(--ty-color-info-bg);
+ border-color: var(--ty-color-info-border);
+ }
+
+ &_warning {
+ color: var(--ty-color-warning);
+ background: var(--ty-color-warning-bg);
+ border-color: var(--ty-color-warning-border);
+ }
+
+ &_danger {
+ color: var(--ty-color-danger);
+ background: var(--ty-color-danger-bg);
+ border-color: var(--ty-color-danger-border);
+ }
}
.#{$prefix}-checkable-tag {
diff --git a/packages/react/src/tag/types.ts b/packages/react/src/tag/types.ts
index c17838b3..7bd3816f 100644
--- a/packages/react/src/tag/types.ts
+++ b/packages/react/src/tag/types.ts
@@ -8,6 +8,10 @@ export interface CheckableTagProps extends BaseProps {
children?: React.ReactNode;
}
+export type StatusColor = 'success' | 'warning' | 'info' | 'danger';
+
+export const StatusColors: StatusColor[] = ['success', 'info', 'warning', 'danger'];
+
export const PresetColors = [
'magenta',
'red',
@@ -20,10 +24,11 @@ export const PresetColors = [
'blue',
'geekblue',
'purple',
+ ...StatusColors,
];
export interface TagProps extends BaseProps, React.PropsWithoutRef {
- color?: string;
+ color?: string | StatusColor;
closable?: boolean;
onClose?: React.MouseEventHandler;
onClick?: React.MouseEventHandler;
diff --git a/packages/react/src/time-picker/style/_index.scss b/packages/react/src/time-picker/style/_index.scss
index 51ab974a..07c4ea60 100755
--- a/packages/react/src/time-picker/style/_index.scss
+++ b/packages/react/src/time-picker/style/_index.scss
@@ -29,6 +29,10 @@ $tp: #{$prefix}-time-picker;
box-shadow: var(--ty-input-focus-shadow);
}
+ &_pending &__input-field {
+ color: var(--ty-color-text-tertiary);
+ }
+
&__input-field {
flex: 1;
border: none;
@@ -191,6 +195,15 @@ $tp: #{$prefix}-time-picker;
}
}
+ &_pending {
+ background: var(--ty-color-primary-bg);
+ color: var(--ty-color-text-tertiary);
+
+ &:hover {
+ background: var(--ty-color-primary-bg-hover);
+ }
+ }
+
&_disabled {
color: var(--ty-color-text-quaternary);
cursor: not-allowed;
diff --git a/packages/react/src/time-picker/time-panel.tsx b/packages/react/src/time-picker/time-panel.tsx
index 06d1ebbb..b14b5652 100755
--- a/packages/react/src/time-picker/time-panel.tsx
+++ b/packages/react/src/time-picker/time-panel.tsx
@@ -2,7 +2,8 @@ import { useRef, useEffect, useCallback } from 'react';
import classNames from 'classnames';
export interface TimePanelProps {
- value: number;
+ value: number | null;
+ pendingValue: number | null;
items: number[];
disabledItems?: number[];
loop?: boolean;
@@ -13,16 +14,20 @@ export interface TimePanelProps {
const ITEM_HEIGHT = 28; // 4px padding-top + 20px line-height + 4px padding-bottom
const TimePanel = (props: TimePanelProps): React.ReactElement => {
- const { prefixCls, value, items, disabledItems = [], loop = false, onChange } = props;
+ const { prefixCls, value, pendingValue, items, disabledItems = [], loop = false, onChange } = props;
const panelRef = useRef(null);
const itemRefs = useRef