@toife/vue 3.1.4 → 3.1.5

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 (92) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/components/action/action.scss +1 -1
  4. package/src/components/action/action.vue +5 -5
  5. package/src/components/app/app.scss +2 -2
  6. package/src/components/app/app.vue +5 -5
  7. package/src/components/avatar/avatar.scss +3 -2
  8. package/src/components/avatar/avatar.vue +6 -6
  9. package/src/components/button/button.scss +13 -13
  10. package/src/components/button/button.vue +7 -7
  11. package/src/components/cable/cable.vue +2 -2
  12. package/src/components/card/card/card.scss +2 -2
  13. package/src/components/card/card/card.vue +5 -5
  14. package/src/components/card/card-body/card-body.scss +2 -2
  15. package/src/components/card/card-body/card-body.vue +2 -2
  16. package/src/components/card/card-footer/card-footer.scss +3 -3
  17. package/src/components/card/card-footer/card-footer.vue +2 -2
  18. package/src/components/card/card-header/card-header.scss +3 -3
  19. package/src/components/card/card-header/card-header.vue +2 -2
  20. package/src/components/checkbox/checkbox.html +1 -1
  21. package/src/components/checkbox/checkbox.scss +18 -13
  22. package/src/components/checkbox/checkbox.vue +7 -7
  23. package/src/components/collapse/collapse.html +1 -1
  24. package/src/components/collapse/collapse.scss +2 -2
  25. package/src/components/collapse/collapse.vue +9 -9
  26. package/src/components/container/container.vue +2 -2
  27. package/src/components/decision-modal/decision-modal.scss +9 -9
  28. package/src/components/decision-modal/decision-modal.vue +8 -8
  29. package/src/components/divider/divider.scss +2 -2
  30. package/src/components/divider/divider.vue +4 -4
  31. package/src/components/dropdown/dropdown.scss +3 -3
  32. package/src/components/dropdown/dropdown.vue +7 -9
  33. package/src/components/field/field.type.ts +2 -2
  34. package/src/components/field/outline/outline.scss +15 -13
  35. package/src/components/field/outline/outline.vue +26 -18
  36. package/src/components/form-group/form-group.vue +2 -2
  37. package/src/components/gesture-indicator/gesture-indicator.scss +1 -1
  38. package/src/components/gesture-indicator/gesture-indicator.vue +4 -4
  39. package/src/components/image/image.vue +12 -5
  40. package/src/components/layout/flex/flex.vue +8 -8
  41. package/src/components/layout/flex-item/flex-item.vue +6 -6
  42. package/src/components/layout/grid/grid.vue +6 -6
  43. package/src/components/layout/grid-item/grid-item.vue +6 -6
  44. package/src/components/modal/modal.scss +1 -1
  45. package/src/components/modal/modal.vue +68 -5
  46. package/src/components/page/page.vue +2 -2
  47. package/src/components/present/present.scss +3 -3
  48. package/src/components/present/present.vue +14 -14
  49. package/src/components/radio/radio/radio.html +1 -1
  50. package/src/components/radio/radio/radio.scss +18 -13
  51. package/src/components/radio/radio/radio.type.ts +1 -1
  52. package/src/components/radio/radio/radio.vue +6 -6
  53. package/src/components/radio/radio-group/radio-group.vue +2 -2
  54. package/src/components/refresher/refresher.html +0 -3
  55. package/src/components/refresher/refresher.scss +1 -25
  56. package/src/components/refresher/refresher.vue +2 -16
  57. package/src/components/route/route-navigator/route-navigator.scss +2 -2
  58. package/src/components/route/route-navigator/route-navigator.vue +10 -13
  59. package/src/components/route/route-wrapper/route-wrapper.composable.ts +5 -15
  60. package/src/components/route/route-wrapper/route-wrapper.type.ts +0 -4
  61. package/src/components/route/route-wrapper/route-wrapper.vue +4 -12
  62. package/src/components/route/route.type.ts +0 -1
  63. package/src/components/segmented-field/segmented-field.html +1 -1
  64. package/src/components/segmented-field/segmented-field.scss +2 -2
  65. package/src/components/segmented-field/segmented-field.vue +8 -8
  66. package/src/components/select/select.html +2 -2
  67. package/src/components/select/select.scss +10 -10
  68. package/src/components/select/select.vue +10 -10
  69. package/src/components/skeleton/skeleton.vue +7 -7
  70. package/src/components/slide-range/slide-range.html +3 -4
  71. package/src/components/slide-range/slide-range.scss +10 -10
  72. package/src/components/slide-range/slide-range.vue +16 -16
  73. package/src/components/switch/switch.html +1 -1
  74. package/src/components/switch/switch.scss +22 -20
  75. package/src/components/switch/switch.type.ts +1 -0
  76. package/src/components/switch/switch.vue +23 -9
  77. package/src/components/tabs/tab/tab.html +1 -1
  78. package/src/components/tabs/tab/tab.scss +13 -0
  79. package/src/components/tabs/tab/tab.vue +4 -2
  80. package/src/components/tabs/tabs/index.ts +1 -0
  81. package/src/components/tabs/tabs/tabs.scss +81 -49
  82. package/src/components/tabs/tabs/tabs.type.ts +5 -1
  83. package/src/components/tabs/tabs/tabs.vue +47 -23
  84. package/src/components/toast/toast/toast.vue +2 -2
  85. package/src/components/toast/toast-content/toast-content.scss +3 -3
  86. package/src/components/toast/toast-content/toast-content.vue +5 -5
  87. package/src/components/toolbar/toolbar.scss +3 -3
  88. package/src/components/toolbar/toolbar.vue +5 -5
  89. package/src/factory.ts +105 -51
  90. package/src/type.ts +2 -1
  91. package/src/utils/style/index.ts +9 -9
  92. package/src/utils/style.md +9 -9
@@ -1,5 +1,5 @@
1
1
  <div v-bind="wrapperAttrs">
2
- <div v-bind="contentAttrs" @click="onFieldClick">
2
+ <div v-bind="contentAttrs" @pointerup="onFieldClick">
3
3
  <Field
4
4
  v-for="(_, index) in props.length"
5
5
  :key="index"
@@ -21,7 +21,7 @@ $app-color: sass.fn-naming-var("app", "color");
21
21
 
22
22
  // Message
23
23
  .#{$segmented-field-message} {
24
- color: rgb(#{$segmented-field-color});
24
+ color: rgba(#{$segmented-field-color});
25
25
  font-size: 0.9em;
26
26
  line-height: 1.5;
27
27
  transition:
@@ -34,7 +34,7 @@ $app-color: sass.fn-naming-var("app", "color");
34
34
 
35
35
  // Help
36
36
  .#{$segmented-field-help} {
37
- color: rgb(#{$app-color}, 0.75);
37
+ color: rgba(#{$app-color}, 0.75);
38
38
  font-size: 0.8em;
39
39
  line-height: 1.5;
40
40
  transition:
@@ -4,7 +4,7 @@
4
4
  import { computed, inject, nextTick, ref } from "vue";
5
5
  import { Field } from "../field";
6
6
  import type { SegmentedFieldProps, SegmentedFieldEmit } from "./segmented-field.type";
7
- import { withPrefix } from "../../utils";
7
+ import { cssPrefix } from "../../utils";
8
8
  import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
9
9
 
10
10
  // Component setup (props, emits, injects)
@@ -46,10 +46,10 @@ const wrapperAttrs = computed(() => {
46
46
  const shape = props.shape || appState?.shape.value || "";
47
47
  return {
48
48
  class: [
49
- withPrefix("segmented-field-wrapper"),
50
- withPrefix(["layer", "segmented-field"]),
51
- withPrefix(["role", role]),
52
- withPrefix(["shape", shape]),
49
+ cssPrefix("segmented-field-wrapper"),
50
+ cssPrefix(["layer", "segmented-field"]),
51
+ cssPrefix(["role", role]),
52
+ cssPrefix(["shape", shape]),
53
53
  props.variant,
54
54
  props.size,
55
55
  { disabled: props.disabled },
@@ -58,7 +58,7 @@ const wrapperAttrs = computed(() => {
58
58
  });
59
59
 
60
60
  const contentAttrs = {
61
- class: [withPrefix("segmented-field-content")],
61
+ class: [cssPrefix("segmented-field-content")],
62
62
  } as const;
63
63
 
64
64
  const fieldAttrs = computed(() => {
@@ -78,11 +78,11 @@ const fieldAttrs = computed(() => {
78
78
  });
79
79
 
80
80
  const messageAttrs = {
81
- class: [withPrefix("segmented-field-message")],
81
+ class: [cssPrefix("segmented-field-message")],
82
82
  } as const;
83
83
 
84
84
  const helpAttrs = {
85
- class: [withPrefix("segmented-field-help")],
85
+ class: [cssPrefix("segmented-field-help")],
86
86
  } as const;
87
87
 
88
88
  const nextIndex = computed(() => {
@@ -4,7 +4,7 @@
4
4
  <Field
5
5
  :role="role"
6
6
  variant="outline"
7
- @click="toggle"
7
+ @pointerup="toggle"
8
8
  v-bind="fieldAttrs"
9
9
  :class="{focus: isOpen}"
10
10
  >
@@ -19,7 +19,7 @@
19
19
  type="button"
20
20
  :disabled="option.disabled"
21
21
  v-bind="selectOptionAttrs"
22
- @click="pickOption(option)"
22
+ @pointerup="pickOption(option)"
23
23
  >
24
24
  {{ option.label }}
25
25
  </button>
@@ -42,8 +42,8 @@ $select-message-color: sass.fn-naming-var("select", "message-color");
42
42
  width: 0.6rem;
43
43
  height: 0.6rem;
44
44
  border-radius: 0.1rem;
45
- border-right: 2px solid rgb(var(--t-app-color));
46
- border-bottom: 2px solid rgb(var(--t-app-color));
45
+ border-right: 2px solid rgba(var(--t-app-color));
46
+ border-bottom: 2px solid rgba(var(--t-app-color));
47
47
  margin: calc(var(--t-spacing-y) * var(--t-coefficient-y))
48
48
  calc(var(--t-spacing-x) * var(--t-coefficient-x));
49
49
  transition: transform #{$transition-duration} ease;
@@ -68,8 +68,8 @@ $select-message-color: sass.fn-naming-var("select", "message-color");
68
68
  overflow: hidden;
69
69
  background: transparent;
70
70
  cursor: pointer;
71
- color: rgb(#{$select-color});
72
- background-color: rgb(#{$select-background-color});
71
+ color: rgba(#{$select-color});
72
+ background-color: rgba(#{$select-background-color});
73
73
  transition:
74
74
  box-shadow #{$transition-duration} ease,
75
75
  border-color #{$transition-duration} ease,
@@ -80,30 +80,30 @@ $select-message-color: sass.fn-naming-var("select", "message-color");
80
80
  &:not(:disabled):not(.disabled):not(.readonly) {
81
81
  &:hover,
82
82
  &.hover {
83
- background: rgb(#{$select-background-color-hover});
83
+ background: rgba(#{$select-background-color-hover});
84
84
  }
85
85
 
86
86
  &:focus,
87
87
  &.focus {
88
- background: rgb(#{$select-background-color-focus});
88
+ background: rgba(#{$select-background-color-focus});
89
89
  }
90
90
 
91
91
  &:active,
92
92
  &.active {
93
- background: rgb(#{$select-background-color-active});
93
+ background: rgba(#{$select-background-color-active});
94
94
  }
95
95
  }
96
96
 
97
97
  &:disabled,
98
98
  &.disabled {
99
99
  cursor: not-allowed;
100
- color: rgb(#{$select-color-disabled});
100
+ color: rgba(#{$select-color-disabled});
101
101
  }
102
102
  }
103
103
 
104
104
  // Message
105
105
  .#{$select-message} {
106
- color: rgb(#{$select-message-color});
106
+ color: rgba(#{$select-message-color});
107
107
  font-size: 0.9em;
108
108
  line-height: 1.5;
109
109
  transition:
@@ -116,7 +116,7 @@ $select-message-color: sass.fn-naming-var("select", "message-color");
116
116
 
117
117
  // Help
118
118
  .#{$select-help} {
119
- color: rgb(#{$app-color}, 0.75);
119
+ color: rgba(#{$app-color}, 0.75);
120
120
  font-size: 0.8em;
121
121
  line-height: 1.5;
122
122
  transition:
@@ -3,7 +3,7 @@
3
3
  <script lang="ts" setup>
4
4
  import { computed, inject, ref } from "vue";
5
5
  import { type SelectOption, type SelectProps, type SelectEmit } from "./select.type";
6
- import { property, withPrefix } from "../../utils";
6
+ import { cssProperty, cssPrefix } from "../../utils";
7
7
  import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
8
8
  import { Field } from "../field";
9
9
  import { Dropdown } from "../dropdown";
@@ -48,11 +48,11 @@ const shape = computed(() => {
48
48
  const selectAttrs = computed(() => {
49
49
  return {
50
50
  class: [
51
- withPrefix(["layer", "select"]),
52
- withPrefix(["role", role.value]),
53
- withPrefix("select"),
54
- withPrefix(["direction", direction.value]),
55
- withPrefix(["size", props.size]),
51
+ cssPrefix(["layer", "select"]),
52
+ cssPrefix(["role", role.value]),
53
+ cssPrefix("select"),
54
+ cssPrefix(["direction", direction.value]),
55
+ cssPrefix(["size", props.size]),
56
56
  {
57
57
  disabled: props.disabled,
58
58
  },
@@ -93,19 +93,19 @@ const fieldAttrs = computed(() => {
93
93
  });
94
94
 
95
95
  const selectIconAttrs = computed(() => ({
96
- class: [withPrefix("select-icon")],
96
+ class: [cssPrefix("select-icon")],
97
97
  }));
98
98
 
99
99
  const selectOptionAttrs = computed(() => ({
100
- class: [withPrefix("select-option")],
100
+ class: [cssPrefix("select-option")],
101
101
  }));
102
102
 
103
103
  const selectMessageAttrs = computed(() => ({
104
- class: [withPrefix("select-message")],
104
+ class: [cssPrefix("select-message")],
105
105
  }));
106
106
 
107
107
  const selectHelpAttrs = computed(() => ({
108
- class: [withPrefix("select-help")],
108
+ class: [cssPrefix("select-help")],
109
109
  }));
110
110
 
111
111
  // Methods
@@ -3,7 +3,7 @@
3
3
  <script lang="ts" setup>
4
4
  import { computed, inject } from "vue";
5
5
  import { type SkeletonProps } from "./skeleton.type";
6
- import { property, withPrefix } from "../../utils";
6
+ import { cssProperty, cssPrefix } from "../../utils";
7
7
  import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
8
8
 
9
9
  // Component setup (props, emits, injects)
@@ -22,15 +22,15 @@ const skeletonAttrs = computed(() => {
22
22
 
23
23
  return {
24
24
  class: [
25
- withPrefix(["layer", "skeleton"]),
26
- withPrefix(["role", role]),
27
- withPrefix(["shape", shape]),
28
- withPrefix("skeleton"),
25
+ cssPrefix(["layer", "skeleton"]),
26
+ cssPrefix(["role", role]),
27
+ cssPrefix(["shape", shape]),
28
+ cssPrefix("skeleton"),
29
29
  ],
30
30
  style: {
31
- [property(["skeleton", "width"])]:
31
+ [cssProperty(["skeleton", "width"])]:
32
32
  props.width + (typeof props.width === "number" ? "px" : ""),
33
- [property(["skeleton", "height"])]:
33
+ [cssProperty(["skeleton", "height"])]:
34
34
  props.height + (typeof props.height === "number" ? "px" : ""),
35
35
  },
36
36
  };
@@ -1,14 +1,13 @@
1
1
  <div v-bind="slideRangeAttrs">
2
2
  <div v-bind="trackContainerAttrs" ref="container">
3
3
  <div v-bind="trackBodyAttrs">
4
- <div v-bind="trackBackAttrs" @click="onClickPath" @touchend="onClickPath"></div>
5
- <div v-bind="trackFrontAttrs" @click="onClickPath" @touchend="onClickPath"></div>
4
+ <div v-bind="trackBackAttrs" @pointerup="onClickPath"></div>
5
+ <div v-bind="trackFrontAttrs" @pointerup="onClickPath"></div>
6
6
  <div
7
7
  v-for="value in ranges"
8
8
  :key="value"
9
9
  v-bind="nodeAttrs(value)"
10
- @click="onNodeSelect(value)"
11
- @touchend="onNodeSelect(value)"
10
+ @pointerup="onNodeSelect(value)"
12
11
  ></div>
13
12
  </div>
14
13
 
@@ -103,12 +103,12 @@ $slide-range-tooltip-color: sass.fn-naming-var("slide-range", "tooltip-color");
103
103
 
104
104
  &.back {
105
105
  width: 100%;
106
- background-color: rgb(#{$slide-range-border-color});
106
+ background-color: rgba(#{$slide-range-border-color});
107
107
  }
108
108
 
109
109
  &.front {
110
110
  width: #{$slide-range-percent};
111
- background-color: rgb(#{$slide-range-border-color-active});
111
+ background-color: rgba(#{$slide-range-border-color-active});
112
112
  }
113
113
  }
114
114
 
@@ -120,12 +120,12 @@ $slide-range-tooltip-color: sass.fn-naming-var("slide-range", "tooltip-color");
120
120
  width: 8px;
121
121
  border-radius: calc(min(8px, #{$radius-size}) * #{$radius-ratio});
122
122
  transform: rotate(45deg);
123
- background-color: rgb(#{$slide-range-background-color});
124
- border: 1px solid rgb(#{$slide-range-border-color});
123
+ background-color: rgba(#{$slide-range-background-color});
124
+ border: 1px solid rgba(#{$slide-range-border-color});
125
125
 
126
126
  &.active {
127
- border-color: rgb(#{$slide-range-border-color-active});
128
- background-color: rgb(#{$slide-range-background-color-active});
127
+ border-color: rgba(#{$slide-range-border-color-active});
128
+ background-color: rgba(#{$slide-range-background-color-active});
129
129
  }
130
130
  }
131
131
 
@@ -139,9 +139,9 @@ $slide-range-tooltip-color: sass.fn-naming-var("slide-range", "tooltip-color");
139
139
  position: absolute;
140
140
  width: 12px;
141
141
  height: 12px;
142
- border: 1px solid rgb(#{$slide-range-border-color-active});
142
+ border: 1px solid rgba(#{$slide-range-border-color-active});
143
143
  border-radius: calc(12px * #{$radius-ratio});
144
- background-color: rgb(#{$slide-range-background-color});
144
+ background-color: rgba(#{$slide-range-background-color});
145
145
  transform: translateX(calc(-50% + 2px)) rotate(45deg);
146
146
  }
147
147
 
@@ -154,8 +154,8 @@ $slide-range-tooltip-color: sass.fn-naming-var("slide-range", "tooltip-color");
154
154
  font-size: 0.6rem;
155
155
  line-height: 0.9rem;
156
156
  white-space: nowrap;
157
- color: rgb(#{$slide-range-tooltip-color});
158
- background-color: rgb(#{$slide-range-tooltip-background-color});
157
+ color: rgba(#{$slide-range-tooltip-color});
158
+ background-color: rgba(#{$slide-range-tooltip-background-color});
159
159
  }
160
160
  }
161
161
  }
@@ -3,7 +3,7 @@
3
3
  <script lang="ts" setup>
4
4
  import { gesture } from "@toife/gesture";
5
5
  import { computed, onMounted, onUnmounted, ref } from "vue";
6
- import { property, withPrefix } from "../../utils";
6
+ import { cssProperty, cssPrefix } from "../../utils";
7
7
  import type { SlideRangeProps, SlideRangeEmit } from "./slide-range.type";
8
8
  import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
9
9
  import { inject } from "vue";
@@ -74,10 +74,10 @@ const slideRangeAttrs = computed(() => {
74
74
  const shape = props.shape || appState?.shape.value || "";
75
75
  return {
76
76
  class: [
77
- withPrefix("slide-range"),
78
- withPrefix(["layer", "slide-range"]),
79
- withPrefix(["role", role]),
80
- withPrefix(["shape", shape]),
77
+ cssPrefix("slide-range"),
78
+ cssPrefix(["layer", "slide-range"]),
79
+ cssPrefix(["role", role]),
80
+ cssPrefix(["shape", shape]),
81
81
  {
82
82
  disabled: props.disabled,
83
83
  readonly: props.readonly,
@@ -87,41 +87,41 @@ const slideRangeAttrs = computed(() => {
87
87
  });
88
88
 
89
89
  const trackContainerAttrs = {
90
- class: [withPrefix("slide-range-track-container")],
90
+ class: [cssPrefix("slide-range-track-container")],
91
91
  } as const;
92
92
 
93
93
  const trackBodyAttrs = {
94
- class: [withPrefix("slide-range-track-body")],
94
+ class: [cssPrefix("slide-range-track-body")],
95
95
  } as const;
96
96
 
97
97
  const trackBackAttrs = {
98
- class: [withPrefix("slide-range-track"), "back"],
98
+ class: [cssPrefix("slide-range-track"), "back"],
99
99
  } as const;
100
100
 
101
101
  const trackFrontAttrs = computed(() => {
102
102
  return {
103
- class: [withPrefix("slide-range-track"), "front"],
103
+ class: [cssPrefix("slide-range-track"), "front"],
104
104
  style: {
105
- [property(["slide-range", "percent"])]: `${percent.value}%`,
105
+ [cssProperty(["slide-range", "percent"])]: `${percent.value}%`,
106
106
  },
107
107
  };
108
108
  });
109
109
 
110
110
  const thumbAttrs = computed(() => {
111
111
  return {
112
- class: [withPrefix("slide-range-thumb")],
112
+ class: [cssPrefix("slide-range-thumb")],
113
113
  style: {
114
- [property(["slide-range", "percent"])]: `${percent.value}%`,
114
+ [cssProperty(["slide-range", "percent"])]: `${percent.value}%`,
115
115
  },
116
116
  };
117
117
  });
118
118
 
119
119
  const thumbInnerAttrs = {
120
- class: [withPrefix("slide-range-thumb-inner")],
120
+ class: [cssPrefix("slide-range-thumb-inner")],
121
121
  } as const;
122
122
 
123
123
  const tooltipAttrs = {
124
- class: [withPrefix("slide-range-tooltip")],
124
+ class: [cssPrefix("slide-range-tooltip")],
125
125
  } as const;
126
126
 
127
127
  // Methods
@@ -129,9 +129,9 @@ const tooltipAttrs = {
129
129
  const nodeAttrs = (value: number) => {
130
130
  const nodePercent = getPercentFromValue(value);
131
131
  return {
132
- class: [withPrefix("slide-range-node"), { active: percent.value > nodePercent }],
132
+ class: [cssPrefix("slide-range-node"), { active: percent.value > nodePercent }],
133
133
  style: {
134
- [property(["slide-range", "position"])]: `${nodePercent}%`,
134
+ [cssProperty(["slide-range", "position"])]: `${nodePercent}%`,
135
135
  },
136
136
  };
137
137
  };
@@ -2,7 +2,7 @@
2
2
  v-bind="switchWrapperAttrs"
3
3
  :tabindex="disabled ? -1 : 0"
4
4
  :aria-checked="props.modelValue"
5
- @click="onSwitch"
5
+ @pointerup="onSwitch"
6
6
  @focus="onFocus"
7
7
  @blur="onBlur"
8
8
  @keydown="onKeydown"
@@ -22,6 +22,7 @@ $spacing-x: sass.fn-naming-var("spacing", "x");
22
22
  $size-control-mark-size: sass.fn-naming-var("control-mark-size");
23
23
  $radius-size: sass.fn-naming-var("radius-size");
24
24
  $icon-size: calc(#{$size-control-mark-size} - #{$size-control-mark-size} * 0.2);
25
+ $bounce-ratio: sass.fn-naming-var("switch", "bounce", "ratio");
25
26
 
26
27
  .#{$switch-wrapper} {
27
28
  display: inline-flex;
@@ -30,16 +31,23 @@ $icon-size: calc(#{$size-control-mark-size} - #{$size-control-mark-size} * 0.2);
30
31
  cursor: pointer;
31
32
  box-shadow: none !important;
32
33
 
34
+ &.transition {
35
+ .#{$switch},
36
+ .#{$switch-icon} {
37
+ transition:
38
+ background-color #{$transition-duration} ease,
39
+ color #{$transition-duration} ease,
40
+ border-color #{$transition-duration} ease,
41
+ border-radius #{$transition-duration} ease,
42
+ box-shadow #{$transition-duration} ease,
43
+ transform #{$transition-duration} ease;
44
+ }
45
+ }
46
+
33
47
  .#{$switch} {
34
48
  height: #{$size-control-mark-size};
35
49
  aspect-ratio: 14/8;
36
50
  position: relative;
37
- transition:
38
- background-color #{$transition-duration} ease,
39
- color #{$transition-duration} ease,
40
- border-color #{$transition-duration} ease,
41
- border-radius #{$transition-duration} ease,
42
- box-shadow #{$transition-duration} ease;
43
51
  border-radius: calc(min(#{$size-control-mark-size}, #{$radius-size}) * #{$radius-ratio});
44
52
 
45
53
  .#{$switch-icon} {
@@ -49,12 +57,6 @@ $icon-size: calc(#{$size-control-mark-size} - #{$size-control-mark-size} * 0.2);
49
57
  top: 0;
50
58
  border-radius: calc(min(#{$icon-size}, #{$radius-size}) * #{$radius-ratio});
51
59
  margin: calc(#{$size-control-mark-size} * 0.1);
52
- transition:
53
- background-color #{$transition-duration} ease,
54
- color #{$transition-duration} ease,
55
- border-color #{$transition-duration} ease,
56
- border-radius #{$transition-duration} ease,
57
- transform #{$transition-duration} ease;
58
60
  }
59
61
  }
60
62
 
@@ -62,12 +64,12 @@ $icon-size: calc(#{$size-control-mark-size} - #{$size-control-mark-size} * 0.2);
62
64
  cursor: not-allowed;
63
65
 
64
66
  .#{$switch} {
65
- background-color: rgb(#{$switch-background-color-disabled});
67
+ background-color: rgba(#{$switch-background-color-disabled});
66
68
  cursor: not-allowed;
67
69
  opacity: 0.3;
68
70
 
69
71
  .#{$switch-icon} {
70
- background-color: rgb(#{$switch-color-disabled});
72
+ background-color: rgba(#{$switch-color-disabled});
71
73
  }
72
74
  }
73
75
  }
@@ -82,10 +84,10 @@ $icon-size: calc(#{$size-control-mark-size} - #{$size-control-mark-size} * 0.2);
82
84
 
83
85
  &:not(.on) {
84
86
  .#{$switch} {
85
- background-color: rgb(#{$switch-background-color-off});
87
+ background-color: rgba(#{$switch-background-color-off});
86
88
 
87
89
  .#{$switch-icon} {
88
- background-color: rgb(#{$switch-color-off});
90
+ background-color: rgba(#{$switch-color-off});
89
91
  left: 0;
90
92
  }
91
93
  }
@@ -93,13 +95,13 @@ $icon-size: calc(#{$size-control-mark-size} - #{$size-control-mark-size} * 0.2);
93
95
 
94
96
  &.on {
95
97
  .#{$switch} {
96
- background-color: rgb(#{$switch-background-color-on});
98
+ background-color: rgba(#{$switch-background-color-on});
97
99
 
98
100
  .#{$switch-icon} {
99
101
  right: 0;
100
102
  animation: shrink #{$transition-duration} linear;
101
103
  animation-fill-mode: forwards;
102
- background-color: rgb(#{$switch-color-on});
104
+ background-color: rgba(#{$switch-color-on});
103
105
  }
104
106
  }
105
107
  }
@@ -107,7 +109,7 @@ $icon-size: calc(#{$size-control-mark-size} - #{$size-control-mark-size} * 0.2);
107
109
  &.focus {
108
110
  &.shadow {
109
111
  .#{$switch} {
110
- box-shadow: 0 0 0 0.25rem rgb(#{$switch-box-shadow-color-focus}, 0.25);
112
+ box-shadow: 0 0 0 0.25rem rgba(#{$switch-box-shadow-color-focus}, 0.25);
111
113
  }
112
114
  }
113
115
  }
@@ -118,7 +120,7 @@ $icon-size: calc(#{$size-control-mark-size} - #{$size-control-mark-size} * 0.2);
118
120
  transform: scale(1);
119
121
  }
120
122
  50% {
121
- transform: scale(1.5);
123
+ transform: scale(#{$bounce-ratio});
122
124
  }
123
125
  100% {
124
126
  transform: scale(1);
@@ -11,6 +11,7 @@ export type SwitchProps = {
11
11
  disabled?: boolean;
12
12
  readonly?: boolean;
13
13
  shadow?: boolean;
14
+ bounce?: number | string;
14
15
  };
15
16
 
16
17
  export type SwitchEmit = {
@@ -1,9 +1,9 @@
1
1
  <style lang="scss" src="./switch.scss" scoped></style>
2
2
  <template src="./switch.html"></template>
3
3
  <script lang="ts" setup>
4
- import { computed, inject, ref } from "vue";
4
+ import { computed, inject, ref, onMounted } from "vue";
5
5
  import type { SwitchProps, SwitchEmit } from "./switch.type";
6
- import { withPrefix } from "../../utils";
6
+ import { cssPrefix, cssProperty } from "../../utils";
7
7
  import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
8
8
 
9
9
  // Component setup (props, emits, injects)
@@ -13,6 +13,7 @@ const props = withDefaults(defineProps<SwitchProps>(), {
13
13
  size: "standard",
14
14
  readonly: false,
15
15
  shadow: undefined,
16
+ bounce: 1.5,
16
17
  });
17
18
  const emit = defineEmits<SwitchEmit>();
18
19
  const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
@@ -20,6 +21,7 @@ const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
20
21
  // Reactive state
21
22
  // ----------------------------------------------------------------------------
22
23
  const isFocused = ref(false);
24
+ const isFirstRender = ref(true);
23
25
 
24
26
  // Computed properties
25
27
  // ----------------------------------------------------------------------------
@@ -27,7 +29,7 @@ const switchWrapperAttrs = computed(() => {
27
29
  const shadow = (props?.shadow !== undefined ? props.shadow : appState?.shadow.value) ?? false;
28
30
  return {
29
31
  class: [
30
- withPrefix("switch-wrapper"),
32
+ cssPrefix("switch-wrapper"),
31
33
  {
32
34
  disabled: props.disabled,
33
35
  readonly: props.readonly,
@@ -35,7 +37,13 @@ const switchWrapperAttrs = computed(() => {
35
37
  focus: isFocused.value,
36
38
  on: props.modelValue,
37
39
  },
40
+ {
41
+ transition: isFirstRender.value ? false : true,
42
+ },
38
43
  ],
44
+ style: {
45
+ [cssProperty(["switch", "bounce", "ratio"])]: props.bounce,
46
+ },
39
47
  };
40
48
  });
41
49
 
@@ -45,17 +53,17 @@ const switchAttrs = computed(() => {
45
53
  const role = props.role || baseRole;
46
54
  return {
47
55
  class: [
48
- withPrefix(["layer", "switch"]),
49
- withPrefix(["role", role]),
50
- withPrefix(["shape", shape]),
51
- withPrefix(["size", props.size]),
52
- withPrefix("switch"),
56
+ cssPrefix(["layer", "switch"]),
57
+ cssPrefix(["role", role]),
58
+ cssPrefix(["shape", shape]),
59
+ cssPrefix(["size", props.size]),
60
+ cssPrefix("switch"),
53
61
  ],
54
62
  };
55
63
  });
56
64
 
57
65
  const switchIconAttrs = {
58
- class: [withPrefix("switch-icon")],
66
+ class: [cssPrefix("switch-icon")],
59
67
  } as const;
60
68
 
61
69
  // Methods
@@ -80,4 +88,10 @@ const onKeydown = (e: KeyboardEvent) => {
80
88
  e.preventDefault();
81
89
  onSwitch();
82
90
  };
91
+
92
+ onMounted(() => {
93
+ setTimeout(() => {
94
+ isFirstRender.value = false;
95
+ }, 500);
96
+ });
83
97
  </script>
@@ -1,5 +1,5 @@
1
1
  <li v-bind="tabAttrs">
2
- <CustomButton block :role="role" :shape="shape" @click="handleClick">
2
+ <CustomButton block :role="role" :shape="shape" :size="size" @click="handleClick">
3
3
  <slot />
4
4
  </CustomButton>
5
5
  </li>
@@ -0,0 +1,13 @@
1
+ @use "@toife/sass-layer" as sass;
2
+
3
+ $button: sass.fn-naming-prefix("button");
4
+
5
+ .#{$button} {
6
+ background-color: none;
7
+ border: none;
8
+
9
+ &:focus,
10
+ &:active {
11
+ outline: none;
12
+ }
13
+ }
@@ -1,9 +1,10 @@
1
1
  <template src="./tab.html"></template>
2
+ <style lang="scss" src="./tab.scss" scoped></style>
2
3
  <script lang="ts" setup>
3
4
  import { computed, inject } from "vue";
4
5
  import { Button as CustomButton } from "../../button";
5
6
  import { type TabProps } from "./tab.type";
6
- import { withPrefix } from "../../../utils";
7
+ import { cssPrefix } from "../../../utils";
7
8
  import { type TabsProviderState, TABS_PROVIDER_STATE_KEY } from "../tabs";
8
9
 
9
10
  // Component setup (props, emits, injects)
@@ -17,11 +18,12 @@ const tabsState = inject<TabsProviderState>(TABS_PROVIDER_STATE_KEY);
17
18
  // ----------------------------------------------------------------------------
18
19
  const role = computed(() => tabsState?.role.value || "");
19
20
  const shape = computed(() => tabsState?.shape.value || "");
21
+ const size = computed(() => tabsState?.size.value || "standard");
20
22
  const isActive = computed(() => tabsState?.activeValue.value === props.value);
21
23
  const tabAttrs = computed(() => {
22
24
  return {
23
25
  class: [
24
- withPrefix("tab"),
26
+ cssPrefix("tab"),
25
27
  {
26
28
  active: isActive.value,
27
29
  },
@@ -5,5 +5,6 @@ export type {
5
5
  TabsProviderState,
6
6
  TabsVariant,
7
7
  TabsPlacement,
8
+ TabsSize,
8
9
  } from "./tabs.type";
9
10
  export { TABS_PROVIDER_STATE_KEY } from "./tabs.constants";