@toife/vue 3.1.2 → 3.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/package.json +1 -1
  2. package/src/components/action/action.html +1 -1
  3. package/src/components/app/app.type.ts +6 -0
  4. package/src/components/app/app.vue +7 -1
  5. package/src/components/avatar/avatar.scss +3 -2
  6. package/src/components/button/button.scss +9 -6
  7. package/src/components/button/button.type.ts +3 -1
  8. package/src/components/card/card/card.scss +3 -1
  9. package/src/components/checkbox/checkbox.scss +9 -14
  10. package/src/components/checkbox/checkbox.type.ts +4 -0
  11. package/src/components/checkbox/checkbox.vue +2 -0
  12. package/src/components/decision-modal/decision-modal.scss +3 -1
  13. package/src/components/divider/divider.type.ts +2 -2
  14. package/src/components/divider/divider.vue +2 -2
  15. package/src/components/divider/index.ts +1 -1
  16. package/src/components/dropdown/dropdown.scss +5 -2
  17. package/src/components/dropdown/dropdown.type.ts +4 -1
  18. package/src/components/dropdown/dropdown.vue +4 -0
  19. package/src/components/field/field.type.ts +2 -2
  20. package/src/components/field/outline/outline.scss +9 -8
  21. package/src/components/form-group/form-group.type.ts +2 -2
  22. package/src/components/form-group/form-group.vue +2 -2
  23. package/src/components/gesture-indicator/gesture-indicator.scss +3 -1
  24. package/src/components/index.ts +1 -0
  25. package/src/components/layout/flex/flex.scss +0 -2
  26. package/src/components/layout/flex/flex.type.ts +3 -1
  27. package/src/components/layout/flex-item/flex-item.html +1 -0
  28. package/src/components/layout/flex-item/flex-item.scss +48 -0
  29. package/src/components/layout/flex-item/flex-item.type.ts +11 -0
  30. package/src/components/layout/flex-item/flex-item.vue +27 -0
  31. package/src/components/layout/flex-item/index.ts +2 -0
  32. package/src/components/layout/grid/grid.scss +0 -2
  33. package/src/components/layout/grid/grid.type.ts +1 -1
  34. package/src/components/layout/grid-item/grid-item.html +1 -0
  35. package/src/components/layout/grid-item/grid-item.scss +49 -0
  36. package/src/components/layout/grid-item/grid-item.type.ts +14 -0
  37. package/src/components/layout/grid-item/grid-item.vue +27 -0
  38. package/src/components/layout/grid-item/index.ts +2 -0
  39. package/src/components/layout/index.ts +2 -1
  40. package/src/components/modal/modal.scss +3 -1
  41. package/src/components/radio/radio/radio.scss +7 -5
  42. package/src/components/radio/radio/radio.type.ts +4 -0
  43. package/src/components/radio/radio/radio.vue +2 -0
  44. package/src/components/radio/radio-group/index.ts +1 -1
  45. package/src/components/radio/radio-group/radio-group.type.ts +2 -2
  46. package/src/components/radio/radio-group/radio-group.vue +2 -2
  47. package/src/components/refresher/refresher.html +4 -4
  48. package/src/components/refresher/refresher.scss +10 -4
  49. package/src/components/refresher/refresher.vue +3 -3
  50. package/src/components/skeleton/skeleton.scss +3 -1
  51. package/src/components/slide-range/index.ts +2 -0
  52. package/src/components/slide-range/slide-range.html +20 -0
  53. package/src/components/slide-range/slide-range.scss +161 -0
  54. package/src/components/slide-range/slide-range.type.ts +16 -0
  55. package/src/components/slide-range/slide-range.vue +229 -0
  56. package/src/components/switch/switch.scss +11 -22
  57. package/src/components/switch/switch.type.ts +5 -0
  58. package/src/components/switch/switch.vue +2 -0
  59. package/src/components/tabs/tabs/tabs.scss +135 -95
  60. package/src/components/tabs/tabs/tabs.type.ts +0 -1
  61. package/src/components/tabs/tabs/tabs.vue +6 -10
  62. package/src/components/toast/toast-content/toast-content.scss +3 -2
  63. package/src/components/toolbar/toolbar.html +1 -3
  64. package/src/components/toolbar/toolbar.scss +25 -40
  65. package/src/components/toolbar/toolbar.type.ts +2 -2
  66. package/src/components/toolbar/toolbar.vue +6 -6
  67. package/src/factory.ts +6 -2
  68. package/src/index.ts +1 -1
  69. package/src/components/action/action.md +0 -115
  70. package/src/components/app/app.md +0 -77
  71. package/src/components/avatar/avatar.md +0 -64
  72. package/src/components/button/button.md +0 -66
  73. package/src/components/cable/cable.md +0 -57
  74. package/src/components/card/card/card.md +0 -57
  75. package/src/components/card/card-body/card-body.md +0 -34
  76. package/src/components/card/card-footer/card-footer.md +0 -42
  77. package/src/components/card/card-header/card-header.md +0 -44
  78. package/src/components/checkbox/checkbox.md +0 -60
  79. package/src/components/collapse/collapse.md +0 -59
  80. package/src/components/container/container.md +0 -38
  81. package/src/components/decision-modal/decision-modal.md +0 -79
  82. package/src/components/divider/divider.md +0 -42
  83. package/src/components/field/field.md +0 -68
  84. package/src/components/field/outline/outline-field.md +0 -44
  85. package/src/components/form-group/form-group.md +0 -41
  86. package/src/components/gesture-indicator/gesture-indicator.md +0 -42
  87. package/src/components/image/image.md +0 -41
  88. package/src/components/layout/cell/cell.html +0 -1
  89. package/src/components/layout/cell/cell.md +0 -47
  90. package/src/components/layout/cell/cell.scss +0 -54
  91. package/src/components/layout/cell/cell.type.ts +0 -19
  92. package/src/components/layout/cell/cell.vue +0 -35
  93. package/src/components/layout/cell/index.ts +0 -2
  94. package/src/components/layout/grid/grid.md +0 -50
  95. package/src/components/modal/modal.md +0 -65
  96. package/src/components/page/page.md +0 -39
  97. package/src/components/present/present.md +0 -60
  98. package/src/components/radio/radio/radio.md +0 -53
  99. package/src/components/radio/radio-group/radio-group.md +0 -62
  100. package/src/components/refresher/refresher.md +0 -53
  101. package/src/components/route/route-navigator/route-navigator.md +0 -50
  102. package/src/components/route/route-outlet/route-outlet.md +0 -30
  103. package/src/components/route/route-provider/route-provider.md +0 -46
  104. package/src/components/route/route-wrapper/route-wrapper.md +0 -45
  105. package/src/components/segmented-field/segmented-field.md +0 -58
  106. package/src/components/skeleton/skeleton.md +0 -47
  107. package/src/components/switch/switch.md +0 -57
  108. package/src/components/tabs/tab/tab.md +0 -52
  109. package/src/components/tabs/tabs/tabs.md +0 -59
  110. package/src/components/toast/toast/toast.md +0 -56
  111. package/src/components/toast/toast-content/toast-content.md +0 -41
  112. package/src/components/toolbar/toolbar.md +0 -57
@@ -0,0 +1,229 @@
1
+ <style lang="scss" src="./slide-range.scss" scoped></style>
2
+ <template src="./slide-range.html"></template>
3
+ <script lang="ts" setup>
4
+ import { gesture } from "@toife/gesture";
5
+ import { computed, onMounted, onUnmounted, ref } from "vue";
6
+ import { property, withPrefix } from "../../utils";
7
+ import type { SlideRangeProps, SlideRangeEmit } from "./slide-range.type";
8
+ import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
9
+ import { inject } from "vue";
10
+
11
+ // Component setup (props, emits, injects)
12
+ // ----------------------------------------------------------------------------
13
+ const props = withDefaults(defineProps<SlideRangeProps>(), {
14
+ modelValue: "",
15
+ min: 0,
16
+ max: 100,
17
+ step: 25,
18
+ unit: "",
19
+ disabled: false,
20
+ readonly: false,
21
+ });
22
+ const emit = defineEmits<SlideRangeEmit>();
23
+ const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
24
+
25
+ // Reactive state
26
+ // ----------------------------------------------------------------------------
27
+ const point = ref<HTMLElement | null>(null);
28
+ const container = ref<HTMLElement | null>(null);
29
+ const isShowTooltip = ref(false);
30
+ let tooltipTimeout: ReturnType<typeof setTimeout> | undefined;
31
+ let gestureCleanup: { destroy: () => void } | null = null;
32
+ let dragStartPercent = 0;
33
+
34
+ // Computed properties
35
+ // ----------------------------------------------------------------------------
36
+ const normalizedValue = computed(() => {
37
+ if (typeof props.modelValue === "number") return props.modelValue;
38
+ if (typeof props.modelValue !== "string") return props.min;
39
+ const parsed = Number.parseFloat(props.modelValue);
40
+ if (Number.isNaN(parsed)) return props.min;
41
+ return parsed;
42
+ });
43
+
44
+ const percent = computed(() => {
45
+ const delta = props.max - props.min;
46
+ if (delta <= 0) return 0;
47
+ const p = ((normalizedValue.value - props.min) / delta) * 100;
48
+ return Math.max(0, Math.min(100, Math.round(p)));
49
+ });
50
+
51
+ const ranges = computed(() => {
52
+ const { min, max, step } = props;
53
+ if (step <= 0 || max < min) return [min, max];
54
+
55
+ const result: number[] = [];
56
+ for (let value = min; value <= max; value += step) {
57
+ result.push(value);
58
+ }
59
+
60
+ if (result.at(-1) !== max) {
61
+ result.push(max);
62
+ }
63
+
64
+ return result;
65
+ });
66
+
67
+ const displayValue = computed(() => {
68
+ const value = getValueFromPercent(percent.value);
69
+ return formatValue(value);
70
+ });
71
+
72
+ const slideRangeAttrs = computed(() => {
73
+ const role = props.role || appState?.role.value || "";
74
+ const shape = props.shape || appState?.shape.value || "";
75
+ return {
76
+ class: [
77
+ withPrefix("slide-range"),
78
+ withPrefix(["layer", "slide-range"]),
79
+ withPrefix(["role", role]),
80
+ withPrefix(["shape", shape]),
81
+ {
82
+ disabled: props.disabled,
83
+ readonly: props.readonly,
84
+ },
85
+ ],
86
+ };
87
+ });
88
+
89
+ const trackContainerAttrs = {
90
+ class: [withPrefix("slide-range-track-container")],
91
+ } as const;
92
+
93
+ const trackBodyAttrs = {
94
+ class: [withPrefix("slide-range-track-body")],
95
+ } as const;
96
+
97
+ const trackBackAttrs = {
98
+ class: [withPrefix("slide-range-track"), "back"],
99
+ } as const;
100
+
101
+ const trackFrontAttrs = computed(() => {
102
+ return {
103
+ class: [withPrefix("slide-range-track"), "front"],
104
+ style: {
105
+ [property(["slide-range", "percent"])]: `${percent.value}%`,
106
+ },
107
+ };
108
+ });
109
+
110
+ const thumbAttrs = computed(() => {
111
+ return {
112
+ class: [withPrefix("slide-range-thumb")],
113
+ style: {
114
+ [property(["slide-range", "percent"])]: `${percent.value}%`,
115
+ },
116
+ };
117
+ });
118
+
119
+ const thumbInnerAttrs = {
120
+ class: [withPrefix("slide-range-thumb-inner")],
121
+ } as const;
122
+
123
+ const tooltipAttrs = {
124
+ class: [withPrefix("slide-range-tooltip")],
125
+ } as const;
126
+
127
+ // Methods
128
+ // ----------------------------------------------------------------------------
129
+ const nodeAttrs = (value: number) => {
130
+ const nodePercent = getPercentFromValue(value);
131
+ return {
132
+ class: [withPrefix("slide-range-node"), { active: percent.value > nodePercent }],
133
+ style: {
134
+ [property(["slide-range", "position"])]: `${nodePercent}%`,
135
+ },
136
+ };
137
+ };
138
+
139
+ const getValueFromPercent = (currentPercent: number) => {
140
+ const { min, max } = props;
141
+ return Math.round(min + (max - min) * (currentPercent / 100));
142
+ };
143
+
144
+ const getPercentFromValue = (value: number) => {
145
+ const { min, max } = props;
146
+ if (max <= min) return 0;
147
+ const p = ((value - min) / (max - min)) * 100;
148
+ return Math.max(0, Math.min(100, p));
149
+ };
150
+
151
+ const formatValue = (value: number) => {
152
+ if (value === 0) return "";
153
+ return `${value}${props.unit || ""}`;
154
+ };
155
+
156
+ const showTooltipTemporarily = () => {
157
+ if (tooltipTimeout) clearTimeout(tooltipTimeout);
158
+ isShowTooltip.value = true;
159
+ tooltipTimeout = setTimeout(() => {
160
+ isShowTooltip.value = false;
161
+ }, 300);
162
+ };
163
+
164
+ const emitValueFromPercent = (currentPercent: number) => {
165
+ if (props.disabled || props.readonly) return;
166
+ const value = getValueFromPercent(currentPercent);
167
+ const payload = formatValue(value);
168
+ emit("update:modelValue", payload);
169
+ emit("change", payload);
170
+ };
171
+
172
+ const onNodeSelect = (value: number) => {
173
+ const nodePercent = getPercentFromValue(value);
174
+ emitValueFromPercent(nodePercent);
175
+ showTooltipTemporarily();
176
+ };
177
+
178
+ const getClientX = (ev: MouseEvent | TouchEvent) => {
179
+ if ("changedTouches" in ev && ev.changedTouches.length > 0) {
180
+ return ev.changedTouches[0].clientX;
181
+ }
182
+ return (ev as MouseEvent).clientX;
183
+ };
184
+
185
+ const onClickPath = (ev: MouseEvent | TouchEvent) => {
186
+ if (props.disabled || props.readonly || !container.value) return;
187
+ const width = container.value.offsetWidth;
188
+ const rect = container.value.getBoundingClientRect();
189
+ const x = getClientX(ev) - rect.left;
190
+ const p = (x / width) * 100;
191
+ emitValueFromPercent(Math.max(0, Math.min(100, p)));
192
+ showTooltipTemporarily();
193
+ };
194
+
195
+ // Lifecycle
196
+ // ----------------------------------------------------------------------------
197
+ onMounted(() => {
198
+ if (!point.value || !container.value) return;
199
+ gestureCleanup = gesture(point.value, {
200
+ down() {
201
+ if (props.disabled || props.readonly) return;
202
+ dragStartPercent = percent.value;
203
+ },
204
+ up() {
205
+ isShowTooltip.value = false;
206
+ },
207
+ cancel() {
208
+ isShowTooltip.value = false;
209
+ },
210
+ move({ initialDirection, deltaX }: { initialDirection: string; deltaX: number }) {
211
+ if (props.disabled || props.readonly) return;
212
+ if (initialDirection !== "right" && initialDirection !== "left") return;
213
+ if (!container.value) return;
214
+
215
+ const width = container.value.offsetWidth;
216
+ const p = (deltaX / width) * 100;
217
+ const nextPercent = Math.max(0, Math.min(100, Math.round(dragStartPercent + p)));
218
+ emitValueFromPercent(nextPercent);
219
+ if (tooltipTimeout) clearTimeout(tooltipTimeout);
220
+ isShowTooltip.value = true;
221
+ },
222
+ });
223
+ });
224
+
225
+ onUnmounted(() => {
226
+ if (tooltipTimeout) clearTimeout(tooltipTimeout);
227
+ gestureCleanup?.destroy();
228
+ });
229
+ </script>
@@ -3,8 +3,6 @@
3
3
  // Classes
4
4
  $switch: sass.fn-naming-prefix("switch");
5
5
  $switch-icon: sass.fn-naming-prefix("switch-icon");
6
- $shape-rounded: sass.fn-naming-prefix("shape-rounded");
7
- $shape-pill: sass.fn-naming-prefix("shape-pill");
8
6
  $switch-wrapper: sass.fn-naming-prefix("switch-wrapper");
9
7
 
10
8
  // Property name - layer: switch (track + thumb; states like button + inactive)
@@ -19,8 +17,11 @@ $switch-color-disabled: sass.fn-naming-var("switch", "color", "disabled");
19
17
  $switch-box-shadow-color-focus: sass.fn-naming-var("switch", "box-shadow-color", "focus");
20
18
 
21
19
  $transition-duration: sass.fn-naming-var("motion", "duration");
22
- $border-radius: sass.fn-naming-var("border-radius");
20
+ $radius-ratio: sass.fn-naming-var("radius-ratio");
23
21
  $spacing-x: sass.fn-naming-var("spacing", "x");
22
+ $size-control-mark-size: sass.fn-naming-var("control-mark-size");
23
+ $radius-size: sass.fn-naming-var("radius-size");
24
+ $icon-size: calc(#{$size-control-mark-size} - #{$size-control-mark-size} * 0.2);
24
25
 
25
26
  .#{$switch-wrapper} {
26
27
  display: inline-flex;
@@ -30,8 +31,8 @@ $spacing-x: sass.fn-naming-var("spacing", "x");
30
31
  box-shadow: none !important;
31
32
 
32
33
  .#{$switch} {
33
- height: 1.5rem;
34
- aspect-ratio: 11/6;
34
+ height: #{$size-control-mark-size};
35
+ aspect-ratio: 14/8;
35
36
  position: relative;
36
37
  transition:
37
38
  background-color #{$transition-duration} ease,
@@ -39,15 +40,15 @@ $spacing-x: sass.fn-naming-var("spacing", "x");
39
40
  border-color #{$transition-duration} ease,
40
41
  border-radius #{$transition-duration} ease,
41
42
  box-shadow #{$transition-duration} ease;
42
- border-radius: #{$border-radius};
43
+ border-radius: calc(min(#{$size-control-mark-size}, #{$radius-size}) * #{$radius-ratio});
43
44
 
44
45
  .#{$switch-icon} {
45
- height: calc(100% - 0.3rem);
46
+ width: #{$icon-size};
47
+ height: #{$icon-size};
46
48
  position: absolute;
47
49
  top: 0;
48
- border-radius: #{$border-radius};
49
- aspect-ratio: 1/1;
50
- margin: 0.15rem;
50
+ border-radius: calc(min(#{$icon-size}, #{$radius-size}) * #{$radius-ratio});
51
+ margin: calc(#{$size-control-mark-size} * 0.1);
51
52
  transition:
52
53
  background-color #{$transition-duration} ease,
53
54
  color #{$transition-duration} ease,
@@ -55,18 +56,6 @@ $spacing-x: sass.fn-naming-var("spacing", "x");
55
56
  border-radius #{$transition-duration} ease,
56
57
  transform #{$transition-duration} ease;
57
58
  }
58
-
59
- &.#{$shape-rounded} {
60
- .#{$switch-icon} {
61
- border-radius: calc(#{$border-radius} - 10%);
62
- }
63
- }
64
-
65
- &.#{$shape-pill} {
66
- .#{$switch-icon} {
67
- border-radius: 50%;
68
- }
69
- }
70
59
  }
71
60
 
72
61
  &.disabled {
@@ -1,7 +1,12 @@
1
+ import { AppSize } from "../app";
2
+
3
+ export type SwitchSize = AppSize;
4
+
1
5
  // Type definitions
2
6
  export type SwitchProps = {
3
7
  modelValue?: boolean;
4
8
  role?: string;
9
+ size?: SwitchSize;
5
10
  shape?: string;
6
11
  disabled?: boolean;
7
12
  readonly?: boolean;
@@ -10,6 +10,7 @@ import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
10
10
  // ----------------------------------------------------------------------------
11
11
  const props = withDefaults(defineProps<SwitchProps>(), {
12
12
  modelValue: false,
13
+ size: "standard",
13
14
  readonly: false,
14
15
  shadow: undefined,
15
16
  });
@@ -47,6 +48,7 @@ const switchAttrs = computed(() => {
47
48
  withPrefix(["layer", "switch"]),
48
49
  withPrefix(["role", role]),
49
50
  withPrefix(["shape", shape]),
51
+ withPrefix(["size", props.size]),
50
52
  withPrefix("switch"),
51
53
  ],
52
54
  };
@@ -6,23 +6,55 @@ $tab: sass.fn-naming-prefix("tab");
6
6
  $button: sass.fn-naming-prefix("button");
7
7
 
8
8
  // Property name - layer: tabs
9
- $tabs-color: sass.fn-naming-var("tabs", "color");
10
- $tabs-background-color: sass.fn-naming-var("tabs", "background-color");
11
- $tabs-border-color: sass.fn-naming-var("tabs", "border-color");
12
-
13
- $space-x: sass.fn-naming-var("spacing", "x");
14
- $space-y: sass.fn-naming-var("spacing", "y");
15
- $border-radius: sass.fn-naming-var("border-radius");
9
+ // Underline
10
+ $tabs-underline-color: sass.fn-naming-var("tabs", "underline", "color");
11
+ $tabs-underline-color-active: sass.fn-naming-var("tabs", "underline", "color", "active");
12
+ $tabs-underline-color-hover: sass.fn-naming-var("tabs", "underline", "color", "hover");
13
+ $tabs-underline-color-focus: sass.fn-naming-var("tabs", "underline", "color", "focus");
14
+ $tabs-underline-color-disabled: sass.fn-naming-var("tabs", "underline", "color", "disabled");
15
+ $tabs-underline-background-color: sass.fn-naming-var("tabs", "underline", "background-color");
16
+
17
+ // Fill
18
+ $tabs-fill-color: sass.fn-naming-var("tabs", "fill", "color");
19
+ $tabs-fill-color-active: sass.fn-naming-var("tabs", "fill", "color", "active");
20
+ $tabs-fill-color-hover: sass.fn-naming-var("tabs", "fill", "color", "hover");
21
+ $tabs-fill-color-focus: sass.fn-naming-var("tabs", "fill", "color", "focus");
22
+ $tabs-fill-color-disabled: sass.fn-naming-var("tabs", "fill", "color", "disabled");
23
+
24
+ $tabs-fill-background-color: sass.fn-naming-var("tabs", "fill", "background-color");
25
+ $tabs-fill-background-color-active: sass.fn-naming-var(
26
+ "tabs",
27
+ "fill",
28
+ "background-color",
29
+ "active"
30
+ );
31
+ $tabs-fill-background-color-hover: sass.fn-naming-var("tabs", "fill", "background-color", "hover");
32
+ $tabs-fill-background-color-focus: sass.fn-naming-var("tabs", "fill", "background-color", "focus");
33
+ $tabs-fill-background-color-disabled: sass.fn-naming-var(
34
+ "tabs",
35
+ "fill",
36
+ "background-color",
37
+ "disabled"
38
+ );
39
+
40
+ // Text
41
+ $tabs-text-color: sass.fn-naming-var("tabs", "text", "color");
42
+ $tabs-text-color-active: sass.fn-naming-var("tabs", "text", "color", "active");
43
+ $tabs-text-color-hover: sass.fn-naming-var("tabs", "text", "color", "hover");
44
+ $tabs-text-color-focus: sass.fn-naming-var("tabs", "text", "color", "focus");
45
+ $tabs-text-color-disabled: sass.fn-naming-var("tabs", "text", "color", "disabled");
46
+
47
+ $radius-ratio: sass.fn-naming-var("radius-ratio");
16
48
  $border-width: sass.fn-naming-var("stroke", "width");
17
49
  $transition-duration: sass.fn-naming-var("motion", "duration");
18
-
50
+ $radius-size: sass.fn-naming-var("radius-size");
19
51
  // layer: highlight (indicator geometry)
20
- $highlight-top: sass.fn-naming-var("highlight", "top");
21
- $highlight-left: sass.fn-naming-var("highlight", "left");
22
- $highlight-width: sass.fn-naming-var("highlight", "width");
23
- $highlight-height: sass.fn-naming-var("highlight", "height");
24
- $highlight-space-x: sass.fn-naming-var("highlight", "space-x");
25
- $highlight-space-y: sass.fn-naming-var("highlight", "space-y");
52
+ $highlight-top: sass.fn-naming-var("tabs", "highlight", "top");
53
+ $highlight-left: sass.fn-naming-var("tabs", "highlight", "left");
54
+ $highlight-width: sass.fn-naming-var("tabs", "highlight", "width");
55
+ $highlight-height: sass.fn-naming-var("tabs", "highlight", "height");
56
+ $highlight-space-x: sass.fn-naming-var("tabs", "highlight", "space-x");
57
+ $highlight-space-y: sass.fn-naming-var("tabs", "highlight", "space-y");
26
58
 
27
59
  .#{$tabs} {
28
60
  display: flex;
@@ -53,8 +85,9 @@ $highlight-space-y: sass.fn-naming-var("highlight", "space-y");
53
85
  height: #{$highlight-height};
54
86
  transform: translate(#{$highlight-left}, #{$highlight-top});
55
87
  box-sizing: border-box;
56
- background-color: rgb(#{$tabs-background-color});
57
- border-radius: #{$border-radius};
88
+ border-radius: calc(
89
+ min(#{$highlight-width}, #{$highlight-height}, #{$radius-size}) * #{$radius-ratio}
90
+ );
58
91
  }
59
92
 
60
93
  &.top-start,
@@ -88,6 +121,8 @@ $highlight-space-y: sass.fn-naming-var("highlight", "space-y");
88
121
  flex-direction: row;
89
122
  height: fit-content;
90
123
  width: 100%;
124
+ padding-top: #{$highlight-space-y};
125
+ padding-bottom: #{$highlight-space-y};
91
126
 
92
127
  > * {
93
128
  height: 100%;
@@ -100,6 +135,8 @@ $highlight-space-y: sass.fn-naming-var("highlight", "space-y");
100
135
  &.right-start,
101
136
  &.right-center,
102
137
  &.right-end {
138
+ padding-left: #{$highlight-space-x};
139
+ padding-right: #{$highlight-space-x};
103
140
  flex-direction: column;
104
141
  width: fit-content;
105
142
  height: 100%;
@@ -109,81 +146,81 @@ $highlight-space-y: sass.fn-naming-var("highlight", "space-y");
109
146
  }
110
147
  }
111
148
 
112
- &.divider {
113
- &.top-start,
114
- &.top-center,
115
- &.top-end {
116
- border-bottom: #{$border-width} solid rgb(#{$tabs-border-color});
149
+ &.underline {
150
+ &::before {
151
+ background-color: rgb(#{$tabs-underline-background-color});
117
152
  }
118
153
 
119
- &.bottom-start,
120
- &.bottom-center,
121
- &.bottom-end {
122
- border-top: #{$border-width} solid rgb(#{$tabs-border-color});
123
- }
154
+ :deep(.#{$tab}) {
155
+ .#{$button} {
156
+ color: rgb(#{$tabs-underline-color});
157
+ }
124
158
 
125
- &.left-start,
126
- &.left-center,
127
- &.left-end {
128
- border-right: #{$border-width} solid rgb(#{$tabs-border-color});
129
- }
159
+ &.active {
160
+ .#{$button} {
161
+ color: rgb(#{$tabs-underline-color-active});
162
+ }
163
+ }
130
164
 
131
- &.right-start,
132
- &.right-center,
133
- &.right-end {
134
- border-left: #{$border-width} solid rgb(#{$tabs-border-color});
135
- }
136
- }
165
+ &:hover,
166
+ &.hover {
167
+ .#{$button} {
168
+ color: rgb(#{$tabs-underline-color-hover});
169
+ }
170
+ }
137
171
 
138
- &.underline {
139
- &.top-start,
140
- &.top-center,
141
- &.top-end,
142
- &.bottom-start,
143
- &.bottom-center,
144
- &.bottom-end {
145
- padding-top: #{$highlight-space-y};
146
- padding-bottom: #{$highlight-space-y};
147
- }
172
+ &:focus,
173
+ &.focus {
174
+ .#{$button} {
175
+ color: rgb(#{$tabs-underline-color-focus});
176
+ }
177
+ }
148
178
 
149
- &.left-start,
150
- &.left-center,
151
- &.left-end,
152
- &.right-start,
153
- &.right-center,
154
- &.right-end {
155
- padding-left: #{$highlight-space-x};
156
- padding-right: #{$highlight-space-x};
179
+ &:disabled,
180
+ &.disabled {
181
+ .#{$button} {
182
+ color: rgb(#{$tabs-underline-color-disabled});
183
+ }
184
+ }
157
185
  }
158
186
  }
159
187
 
160
188
  &.fill {
189
+ &::before {
190
+ background-color: rgb(#{$tabs-fill-background-color});
191
+ }
192
+
161
193
  :deep(.#{$tab}) {
194
+ .#{$button} {
195
+ color: rgb(#{$tabs-fill-color});
196
+ }
197
+
162
198
  &.active {
163
199
  .#{$button} {
164
- color: rgb(#{$tabs-color}) !important;
200
+ color: rgb(#{$tabs-fill-color-active});
165
201
  }
166
202
  }
167
- }
168
203
 
169
- &.top-start,
170
- &.top-center,
171
- &.top-end,
172
- &.bottom-start,
173
- &.bottom-center,
174
- &.bottom-end {
175
- padding-top: calc(#{$highlight-space-y} + #{$space-y});
176
- padding-bottom: calc(#{$highlight-space-y} + #{$space-y});
177
- }
204
+ &:hover,
205
+ &.hover {
206
+ .#{$button} {
207
+ color: rgb(#{$tabs-fill-color-hover});
208
+ }
209
+ }
178
210
 
179
- &.left-start,
180
- &.left-center,
181
- &.left-end,
182
- &.right-start,
183
- &.right-center,
184
- &.right-end {
185
- padding-left: calc(#{$highlight-space-x} + #{$space-x});
186
- padding-right: calc(#{$highlight-space-x} + #{$space-x});
211
+ &:focus,
212
+ &.focus {
213
+ .#{$button} {
214
+ color: rgb(#{$tabs-fill-color-focus});
215
+ }
216
+ }
217
+
218
+ &:disabled,
219
+ &.disabled {
220
+ .#{$button} {
221
+ color: rgb(#{$tabs-fill-color-disabled});
222
+ }
223
+ }
187
224
  }
188
225
  }
189
226
 
@@ -193,32 +230,36 @@ $highlight-space-y: sass.fn-naming-var("highlight", "space-y");
193
230
  }
194
231
 
195
232
  :deep(.#{$tab}) {
233
+ .#{$button} {
234
+ color: rgb(#{$tabs-text-color});
235
+ }
236
+
196
237
  &.active {
197
238
  .#{$button} {
198
- color: rgb(#{$tabs-background-color});
199
- text-shadow: 0 0 rgb(#{$tabs-background-color});
239
+ color: rgb(#{$tabs-text-color-active});
200
240
  }
201
241
  }
202
- }
203
242
 
204
- &.top-start,
205
- &.top-center,
206
- &.top-end,
207
- &.bottom-start,
208
- &.bottom-center,
209
- &.bottom-end {
210
- padding-top: calc(#{$highlight-space-y} + #{$space-y});
211
- padding-bottom: calc(#{$highlight-space-y} + #{$space-y});
212
- }
243
+ &:hover,
244
+ &.hover {
245
+ .#{$button} {
246
+ color: rgb(#{$tabs-text-color-hover});
247
+ }
248
+ }
213
249
 
214
- &.left-start,
215
- &.left-center,
216
- &.left-end,
217
- &.right-start,
218
- &.right-center,
219
- &.right-end {
220
- padding-left: calc(#{$highlight-space-x} + #{$space-x});
221
- padding-right: calc(#{$highlight-space-x} + #{$space-x});
250
+ &:focus,
251
+ &.focus {
252
+ .#{$button} {
253
+ color: rgb(#{$tabs-text-color-focus});
254
+ }
255
+ }
256
+
257
+ &:disabled,
258
+ &.disabled {
259
+ .#{$button} {
260
+ color: rgb(#{$tabs-text-color-disabled});
261
+ }
262
+ }
222
263
  }
223
264
  }
224
265
 
@@ -256,7 +297,6 @@ $highlight-space-y: sass.fn-naming-var("highlight", "space-y");
256
297
  align-items: center;
257
298
 
258
299
  .#{$button} {
259
- padding: #{$space-y} calc(#{$space-x} * 4);
260
300
  color: unset;
261
301
  cursor: pointer;
262
302
  background-color: transparent !important;
@@ -20,7 +20,6 @@ export type TabsProps = {
20
20
  border?: number;
21
21
  margin?: number[];
22
22
  shape?: string;
23
- divider?: boolean;
24
23
  transition?: boolean;
25
24
  };
26
25
 
@@ -13,7 +13,6 @@ const props = withDefaults(defineProps<TabsProps>(), {
13
13
  placement: "top-start",
14
14
  margin: () => [0, 0],
15
15
  border: 2,
16
- divider: undefined,
17
16
  transition: true,
18
17
  });
19
18
  const emit = defineEmits<TabsEmit>();
@@ -42,8 +41,6 @@ const activeValue = computed(() => {
42
41
  });
43
42
 
44
43
  const tabsAttrs = computed(() => {
45
- const divider =
46
- (props.divider !== undefined ? props.divider : appState?.divider.value || false) ?? false;
47
44
  let l = left.value;
48
45
  let t = top.value;
49
46
  let w = width.value;
@@ -91,17 +88,16 @@ const tabsAttrs = computed(() => {
91
88
  props.variant,
92
89
  props.placement,
93
90
  {
94
- divider,
95
91
  transition: props.transition,
96
92
  },
97
93
  ],
98
94
  style: {
99
- [property("highlight-top")]: typeof t === "string" ? t : t + "px",
100
- [property("highlight-left")]: typeof l === "string" ? l : l + "px",
101
- [property("highlight-width")]: typeof w === "string" ? w : w + "px",
102
- [property("highlight-height")]: typeof h === "string" ? h : h + "px",
103
- [property("highlight-space-x")]: (props.margin[1] > 0 ? props.margin[1] : 0) + "px",
104
- [property("highlight-space-y")]: (props.margin[0] > 0 ? props.margin[0] : 0) + "px",
95
+ [property("tabs-highlight-top")]: typeof t === "string" ? t : t + "px",
96
+ [property("tabs-highlight-left")]: typeof l === "string" ? l : l + "px",
97
+ [property("tabs-highlight-width")]: typeof w === "string" ? w : w + "px",
98
+ [property("tabs-highlight-height")]: typeof h === "string" ? h : h + "px",
99
+ [property("tabs-highlight-space-x")]: (props.margin[1] > 0 ? props.margin[1] : 0) + "px",
100
+ [property("tabs-highlight-space-y")]: (props.margin[0] > 0 ? props.margin[0] : 0) + "px",
105
101
  },
106
102
  };
107
103
  });