@toife/vue 3.1.5 → 3.1.6

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 (48) hide show
  1. package/package.json +4 -4
  2. package/src/components/action/action.scss +1 -1
  3. package/src/components/app/app.scss +1 -1
  4. package/src/components/app/app.type.ts +0 -6
  5. package/src/components/app/app.vue +1 -7
  6. package/src/components/avatar/avatar.scss +1 -1
  7. package/src/components/button/button.scss +16 -8
  8. package/src/components/button/button.type.ts +2 -4
  9. package/src/components/card/card/card.scss +1 -1
  10. package/src/components/card/card-body/card-body.scss +1 -1
  11. package/src/components/card/card-footer/card-footer.scss +1 -1
  12. package/src/components/card/card-header/card-header.scss +1 -1
  13. package/src/components/checkbox/checkbox.scss +1 -1
  14. package/src/components/checkbox/checkbox.type.ts +1 -3
  15. package/src/components/collapse/collapse.scss +2 -5
  16. package/src/components/decision-modal/decision-modal.scss +2 -2
  17. package/src/components/divider/divider.scss +1 -1
  18. package/src/components/dropdown/dropdown.scss +1 -1
  19. package/src/components/dropdown/dropdown.type.ts +2 -2
  20. package/src/components/field/field.html +28 -9
  21. package/src/components/field/{outline/outline.scss → field.scss} +20 -118
  22. package/src/components/field/field.type.ts +2 -2
  23. package/src/components/field/field.vue +83 -46
  24. package/src/components/field/index.ts +1 -1
  25. package/src/components/gesture-indicator/gesture-indicator.scss +1 -1
  26. package/src/components/modal/modal.scss +1 -1
  27. package/src/components/present/present.scss +1 -1
  28. package/src/components/present/present.vue +1 -1
  29. package/src/components/radio/radio/radio.scss +1 -1
  30. package/src/components/radio/radio/radio.type.ts +1 -3
  31. package/src/components/route/route-navigator/route-navigator.html +1 -1
  32. package/src/components/route/route-navigator/route-navigator.scss +1 -1
  33. package/src/components/route/route-navigator/route-navigator.vue +1 -1
  34. package/src/components/segmented-field/segmented-field.scss +1 -1
  35. package/src/components/select/select.scss +1 -1
  36. package/src/components/skeleton/skeleton.scss +1 -1
  37. package/src/components/slide-range/slide-range.scss +7 -4
  38. package/src/components/slide-range/slide-range.vue +1 -0
  39. package/src/components/switch/switch.scss +1 -1
  40. package/src/components/switch/switch.type.ts +1 -3
  41. package/src/components/tabs/tabs/tabs.scss +1 -5
  42. package/src/components/tabs/tabs/tabs.type.ts +1 -2
  43. package/src/components/toast/toast/toast.scss +1 -1
  44. package/src/components/toast/toast-content/toast-content.scss +1 -1
  45. package/src/components/toolbar/toolbar.scss +1 -1
  46. package/src/components/field/outline/index.ts +0 -1
  47. package/src/components/field/outline/outline.html +0 -36
  48. package/src/components/field/outline/outline.vue +0 -294
@@ -1,9 +1,9 @@
1
+ <style lang="scss" src="./field.scss" scoped></style>
1
2
  <template src="./field.html"></template>
2
3
  <script lang="ts" setup>
3
- import { computed, inject } from "vue";
4
- import type { FieldProps } from "./field.type";
5
- import type { FieldEmit } from "./field.type";
6
- import { OutlineField } from "./outline";
4
+ import { computed, inject, nextTick, onMounted, ref, watch } from "vue";
5
+ import type { FieldProps, FieldEmit } from "./field.type";
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)
@@ -12,6 +12,8 @@ const props = withDefaults(defineProps<FieldProps>(), {
12
12
  modelValue: "",
13
13
  type: "text",
14
14
  size: "standard",
15
+ role: undefined,
16
+ shape: undefined,
15
17
  disabled: false,
16
18
  readonly: false,
17
19
  message: "",
@@ -21,66 +23,101 @@ const props = withDefaults(defineProps<FieldProps>(), {
21
23
  shadow: undefined,
22
24
  direction: undefined,
23
25
  line: 1,
26
+ maxLine: 1,
24
27
  });
25
28
  const emit = defineEmits<FieldEmit>();
26
29
  const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
27
30
 
31
+ // Reactive state
32
+ // ----------------------------------------------------------------------------
33
+ const isFocus = ref(false);
34
+ const caret = ref(0);
35
+ const content = ref("");
36
+
28
37
  // Computed properties
29
38
  // ----------------------------------------------------------------------------
30
- const role = computed(() => {
31
- return props.role || appState?.role.value || "";
32
- });
39
+ const fieldAttrs = computed(() => {
40
+ const role = props.role || appState?.role?.value || "";
41
+ const shape = props.shape || appState?.shape?.value || "";
42
+ const shadow = (props?.shadow !== undefined ? props.shadow : appState?.shadow?.value) ?? false;
43
+ const direction = props.direction || appState?.direction?.value || "left";
33
44
 
34
- const shape = computed(() => {
35
- return props.shape || appState?.shape.value || "";
45
+ return {
46
+ class: [
47
+ cssPrefix(["layer", "field"]),
48
+ cssPrefix(["role", role]),
49
+ cssPrefix(["shape", shape]),
50
+ cssPrefix("field"),
51
+ cssPrefix(["size", props.size]),
52
+ cssPrefix(["direction", direction]),
53
+ props.variant,
54
+ props.type,
55
+ {
56
+ disabled: props.disabled,
57
+ focus: isFocus.value,
58
+ shadow,
59
+ readonly: props.readonly,
60
+ },
61
+ ],
62
+ style: {
63
+ [cssProperty(["field", "line"])]: props.line,
64
+ [cssProperty(["field", "max-line"])]: props.maxLine || props.line,
65
+ },
66
+ };
36
67
  });
37
68
 
38
- const shadow = computed(() => {
39
- return (props?.shadow !== undefined ? props.shadow : appState?.shadow.value) ?? false;
69
+ const rawContent = computed(() => {
70
+ return props.modelValue ?? props.value ?? "";
40
71
  });
41
72
 
42
- const direction = computed(() => {
43
- return props.direction || appState?.direction?.value || "left";
44
- });
73
+ const fieldContentAttrs = computed(() => ({
74
+ class: [cssPrefix("field-content")],
75
+ }));
45
76
 
46
- const fieldAttrs = computed(() => {
47
- return {
48
- ...props,
49
- direction: direction.value,
50
- role: role.value,
51
- shape: shape.value,
52
- shadow: shadow.value,
53
- onInput,
54
- onFocus,
55
- onBlur,
56
- onBeforeinput,
57
- };
58
- });
77
+ const fieldInputAttrs = computed(() => ({
78
+ class: [cssPrefix("field-input")],
79
+ name: props.name,
80
+ id: props.id,
81
+ placeholder: props.placeholder,
82
+ autocomplete: props.autocomplete,
83
+ type: props.type,
84
+ readonly: props.readonly,
85
+ disabled: props.disabled,
86
+ }));
87
+
88
+ const fieldMessageAttrs = computed(() => ({
89
+ class: [cssPrefix("field-message")],
90
+ }));
91
+
92
+ const fieldHelpAttrs = computed(() => ({
93
+ class: [cssPrefix("field-help")],
94
+ }));
59
95
 
60
96
  // Methods
61
97
  // ----------------------------------------------------------------------------
62
- const onInput = (event: Event) => {
63
- let raw = "";
64
- // Outline variant uses contenteditable for non-password types; password uses a real input
65
- if (props.type !== "password") {
66
- raw = (event.target as HTMLElement).innerText;
67
- } else {
68
- raw = (event.target as HTMLInputElement).value;
69
- }
70
- const value = raw.trim() === "" ? "" : raw;
71
- emit("update:modelValue", value as string);
72
- emit("input", event);
98
+ const onFocus = (ev: FocusEvent) => {
99
+ if (props.disabled) return;
100
+ isFocus.value = true;
101
+ emit("focus", ev);
73
102
  };
74
103
 
75
- const onFocus = (event: FocusEvent) => {
76
- emit("focus", event);
104
+ const onBlur = (ev: FocusEvent) => {
105
+ if (props.disabled) return;
106
+ isFocus.value = false;
107
+ emit("blur", ev);
77
108
  };
78
109
 
79
- const onBlur = (event: FocusEvent) => {
80
- emit("blur", event);
81
- };
110
+ watch(
111
+ () => rawContent.value,
112
+ (value) => {
113
+ content.value = value.toString();
114
+ }
115
+ );
82
116
 
83
- const onBeforeinput = (event: Event) => {
84
- emit("beforeinput", event);
85
- };
117
+ watch(
118
+ () => content.value,
119
+ (value) => {
120
+ emit("update:modelValue", value.toString());
121
+ }
122
+ );
86
123
  </script>
@@ -1,2 +1,2 @@
1
1
  export { default as Field } from "./field.vue";
2
- export type { FieldVariant, FieldSize, FieldProps, FieldEmit } from "./field.type";
2
+ export * from "./field.type";
@@ -7,7 +7,7 @@ $gesture-indicator: sass.fn-naming-prefix("gesture-indicator");
7
7
  $gesture-indicator-border-color: sass.fn-naming-var("gesture-indicator", "border-color");
8
8
  $radius-ratio: sass.fn-naming-var("radius-ratio");
9
9
  $radius-size: sass.fn-naming-var("radius-size");
10
- $transition-duration: sass.fn-naming-var("motion", "duration");
10
+ $transition-duration: sass.fn-naming-var("duration");
11
11
 
12
12
  .#{$gesture-indicator} {
13
13
  background-color: rgba(#{$gesture-indicator-border-color});
@@ -15,7 +15,7 @@ $safe-area-top: sass.fn-naming-var("safe-area", "top");
15
15
  $safe-area-bottom: sass.fn-naming-var("safe-area", "bottom");
16
16
  $safe-area-left: sass.fn-naming-var("safe-area", "left");
17
17
  $safe-area-right: sass.fn-naming-var("safe-area", "right");
18
- $transition-duration: sass.fn-naming-var("motion", "duration");
18
+ $transition-duration: sass.fn-naming-var("duration");
19
19
  $border-radius: calc(min(#{$viewport-width}, #{$radius-size}) * #{$radius-ratio});
20
20
 
21
21
  .#{$modal} {
@@ -7,7 +7,7 @@ $backdrop: sass.fn-naming-prefix("present-backdrop");
7
7
  // Property name
8
8
  $transition-duration: sass.fn-naming-dvar(
9
9
  ("transition", "duration"),
10
- sass.fn-naming-var("motion", "duration")
10
+ sass.fn-naming-var("duration")
11
11
  );
12
12
 
13
13
  $backdrop-background-color: sass.fn-naming-var("backdrop", "background-color");
@@ -28,7 +28,7 @@ const zIndex = ref(0);
28
28
  const isShow = ref(false);
29
29
  const styles = reactive({
30
30
  backdropTransitionDuration: "0.2s",
31
- backdropOpacity: undefined,
31
+ backdropOpacity: undefined as number | undefined,
32
32
  presentTransitionDuration: "0.2s",
33
33
  presentTranslate: "0px",
34
34
  presentOpacity: 1,
@@ -25,7 +25,7 @@ $radio-border-color-disabled: sass.fn-naming-var("radio", "border-color", "disab
25
25
 
26
26
  $radio-box-shadow-color-focus: sass.fn-naming-var("radio", "box-shadow-color", "focus");
27
27
 
28
- $transition-duration: sass.fn-naming-var("motion", "duration");
28
+ $transition-duration: sass.fn-naming-var("duration");
29
29
  $radius-ratio: sass.fn-naming-var("radius-ratio");
30
30
 
31
31
  $size-control-mark-size: sass.fn-naming-var("control-mark-size");
@@ -1,7 +1,5 @@
1
- import { AppSize } from "../../app";
2
-
3
1
  export type RadioVariant = "fill" | "outline";
4
- export type RadioSize = AppSize;
2
+ export type RadioSize = string;
5
3
 
6
4
  // Type definitions
7
5
  export type RadioProps = {
@@ -3,7 +3,7 @@
3
3
  v-for="(item, index) in stack"
4
4
  :key="item.name"
5
5
  v-bind="componentAttrs"
6
- :style="{zIndex: index * 2}"
6
+ :style="{zIndex: index * 2 + 100}"
7
7
  :name="item.name"
8
8
  :class="{
9
9
  active: index === activeIndex,
@@ -9,7 +9,7 @@ $navigator-backdrop: sass.fn-naming-prefix("route-navigator-backdrop");
9
9
  $background-color: sass.fn-naming-var("app", "background-color");
10
10
  $transition-duration: sass.fn-naming-dvar(
11
11
  ("route-navigator-transition-duration"),
12
- sass.fn-naming-var("motion", "duration")
12
+ sass.fn-naming-var("duration")
13
13
  );
14
14
  $transform-back: sass.fn-naming-var("route-navigator-transform", "back");
15
15
  $transform-prepare: sass.fn-naming-var("route-navigator-transform", "prepare");
@@ -84,7 +84,7 @@ const backdropAttrs = computed(() => {
84
84
  return {
85
85
  class: [cssPrefix("route-navigator-backdrop"), cssPrefix(["layer", "backdrop"])],
86
86
  style: {
87
- zIndex: backdropIndex.value * 2 - 1,
87
+ zIndex: backdropIndex.value * 2 + 99,
88
88
  },
89
89
  };
90
90
  });
@@ -10,7 +10,7 @@ $segmented-field-help: sass.fn-naming-prefix("segmented-field-help");
10
10
  $segmented-field-color: sass.fn-naming-var("segmented-field", "color");
11
11
 
12
12
  $spacing-x: sass.fn-naming-var("spacing", "x");
13
- $transition-duration: sass.fn-naming-var("motion", "duration");
13
+ $transition-duration: sass.fn-naming-var("duration");
14
14
  $app-color: sass.fn-naming-var("app", "color");
15
15
 
16
16
  .#{$segmented-field-wrapper} {
@@ -15,7 +15,7 @@ $spacing-x: sass.fn-naming-var("spacing", "x");
15
15
  $spacing-y: sass.fn-naming-var("spacing", "y");
16
16
  $size-coefficient-x: sass.fn-naming-var("coefficient-x");
17
17
  $size-coefficient-y: sass.fn-naming-var("coefficient-y");
18
- $transition-duration: sass.fn-naming-var("motion", "duration");
18
+ $transition-duration: sass.fn-naming-var("duration");
19
19
 
20
20
  $select-background-color: sass.fn-naming-var("select", "background-color");
21
21
  $select-background-color-hover: sass.fn-naming-var("select", "background-color", "hover");
@@ -9,7 +9,7 @@ $skeleton-height: sass.fn-naming-var("skeleton", "height");
9
9
  $skeleton-background-color: sass.fn-naming-var("skeleton", "background-color");
10
10
 
11
11
  $radius-ratio: sass.fn-naming-var("radius-ratio");
12
- $transition-duration: sass.fn-naming-var("motion", "duration");
12
+ $transition-duration: sass.fn-naming-var("duration");
13
13
  $radius-size: sass.fn-naming-var("radius-size");
14
14
  $border-radius: calc(#{$radius-size} * #{$radius-ratio});
15
15
 
@@ -132,17 +132,20 @@ $slide-range-tooltip-color: sass.fn-naming-var("slide-range", "tooltip-color");
132
132
  .#{$slide-range-thumb} {
133
133
  position: absolute;
134
134
  left: #{$slide-range-percent};
135
- top: 2px;
136
- height: 100%;
135
+ height: 25px;
136
+ width: 25px;
137
+ transform: translate(-9px, -5px);
138
+ display: flex;
139
+ justify-content: center;
140
+ align-items: center;
137
141
 
138
142
  .#{$slide-range-thumb-inner} {
139
- position: absolute;
140
143
  width: 12px;
141
144
  height: 12px;
142
145
  border: 1px solid rgba(#{$slide-range-border-color-active});
143
146
  border-radius: calc(12px * #{$radius-ratio});
144
147
  background-color: rgba(#{$slide-range-background-color});
145
- transform: translateX(calc(-50% + 2px)) rotate(45deg);
148
+ transform: rotate(45deg);
146
149
  }
147
150
 
148
151
  .#{$slide-range-tooltip} {
@@ -197,6 +197,7 @@ const onClickPath = (ev: MouseEvent | TouchEvent) => {
197
197
  onMounted(() => {
198
198
  if (!point.value || !container.value) return;
199
199
  gestureCleanup = gesture(point.value, {
200
+ options: { trackOutsideElement: true },
200
201
  down() {
201
202
  if (props.disabled || props.readonly) return;
202
203
  dragStartPercent = percent.value;
@@ -16,7 +16,7 @@ $switch-color-disabled: sass.fn-naming-var("switch", "color", "disabled");
16
16
 
17
17
  $switch-box-shadow-color-focus: sass.fn-naming-var("switch", "box-shadow-color", "focus");
18
18
 
19
- $transition-duration: sass.fn-naming-var("motion", "duration");
19
+ $transition-duration: sass.fn-naming-var("duration");
20
20
  $radius-ratio: sass.fn-naming-var("radius-ratio");
21
21
  $spacing-x: sass.fn-naming-var("spacing", "x");
22
22
  $size-control-mark-size: sass.fn-naming-var("control-mark-size");
@@ -1,6 +1,4 @@
1
- import { AppSize } from "../app";
2
-
3
- export type SwitchSize = AppSize;
1
+ export type SwitchSize = string;
4
2
 
5
3
  // Type definitions
6
4
  export type SwitchProps = {
@@ -74,7 +74,7 @@ $tabs-text-color-disabled: sass.fn-naming-var("tabs", "text", "color", "disabled
74
74
 
75
75
  $radius-ratio: sass.fn-naming-var("radius-ratio");
76
76
  $border-width: sass.fn-naming-var("stroke", "width");
77
- $transition-duration: sass.fn-naming-var("motion", "duration");
77
+ $transition-duration: sass.fn-naming-var("duration");
78
78
  $radius-size: sass.fn-naming-var("radius-size");
79
79
  // layer: highlight (indicator geometry)
80
80
  $highlight-top: sass.fn-naming-var("tabs", "highlight", "top");
@@ -314,10 +314,6 @@ $highlight-space-y: sass.fn-naming-var("tabs", "highlight", "space-y");
314
314
  }
315
315
 
316
316
  :deep(.#{$tab}) {
317
- display: flex;
318
- justify-content: center;
319
- align-items: center;
320
-
321
317
  .#{$button} {
322
318
  transition:
323
319
  box-shadow #{$transition-duration} ease,
@@ -1,8 +1,7 @@
1
1
  import { ComputedRef } from "vue";
2
- import { AppSize } from "../../app";
3
2
 
4
3
  export type TabsVariant = "fill" | "underline" | "text";
5
- export type TabsSize = AppSize;
4
+ export type TabsSize = string;
6
5
  export type TabsPlacement =
7
6
  | "top-start"
8
7
  | "top-end"
@@ -17,7 +17,7 @@ $safe-area-top: sass.fn-naming-var("safe-area", "top");
17
17
  height: fit-content;
18
18
  max-width: #{$max-width};
19
19
  position: absolute;
20
- z-index: 999;
20
+ z-index: 10000;
21
21
  font-size: 0.8em;
22
22
  line-height: 0.8em;
23
23
  display: flex;
@@ -9,7 +9,7 @@ $toast-color: sass.fn-naming-var("toast", "color");
9
9
  $toast-border-color: sass.fn-naming-var("toast", "border-color");
10
10
 
11
11
  $space-x: sass.fn-naming-var("spacing", "x");
12
- $transition-duration: sass.fn-naming-var("motion", "duration");
12
+ $transition-duration: sass.fn-naming-var("duration");
13
13
  $radius-ratio: sass.fn-naming-var("radius-ratio");
14
14
  $radius-size: sass.fn-naming-var("radius-size");
15
15
  $border-width: sass.fn-naming-var("stroke", "width");
@@ -11,7 +11,7 @@ $safe-area-right: sass.fn-naming-var("safe-area", "right");
11
11
  $safe-area-left: sass.fn-naming-var("safe-area", "left");
12
12
  $safe-area-bottom: sass.fn-naming-var("safe-area", "bottom");
13
13
  $safe-area-top: sass.fn-naming-var("safe-area", "top");
14
- $transition-duration: sass.fn-naming-var("motion", "duration");
14
+ $transition-duration: sass.fn-naming-var("duration");
15
15
 
16
16
  $border-width: sass.fn-naming-var("stroke", "width");
17
17
  $border: #{$border-width} solid rgba(#{$toolbar-border-color});
@@ -1 +0,0 @@
1
- export { default as OutlineField } from "./outline.vue";
@@ -1,36 +0,0 @@
1
- <div v-bind="fieldAttrs">
2
- <div v-bind="fieldContentAttrs">
3
- <slot name="start-input"></slot>
4
- <slot name="input">
5
- <div v-bind="fieldInputShellAttrs" v-if="type !== 'password'">
6
- <div
7
- v-bind="fieldEditableAttrs"
8
- @input="onInput"
9
- @compositionstart="onCompositionStart"
10
- @compositionend="onCompositionEnd"
11
- @focus="onFocus"
12
- @blur="onBlur"
13
- @beforeinput="onBeforeinput"
14
- ref="contentRef"
15
- ></div>
16
- </div>
17
- <input
18
- v-bind="fieldPasswordInputAttrs"
19
- @input="onInput"
20
- @compositionstart="onCompositionStart"
21
- @compositionend="onCompositionEnd"
22
- @focus="onFocus"
23
- @blur="onBlur"
24
- @beforeinput="onBeforeinput"
25
- ref="contentRef"
26
- :value="content"
27
- type="password"
28
- v-else
29
- />
30
- </slot>
31
- <slot name="end-input"></slot>
32
- </div>
33
- <div v-bind="fieldMessageAttrs" v-if="message">{{ message }}</div>
34
- <div v-bind="fieldHelpAttrs" v-if="help">{{ help }}</div>
35
- <slot></slot>
36
- </div>