@toife/vue 3.0.7 → 3.1.3

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 (79) hide show
  1. package/README.md +4 -2
  2. package/package.json +4 -7
  3. package/src/components/action/action.html +1 -1
  4. package/src/components/action/action.scss +1 -1
  5. package/src/components/app/app.scss +1 -1
  6. package/src/components/avatar/avatar.scss +1 -1
  7. package/src/components/button/button.scss +1 -1
  8. package/src/components/cable/cable.scss +1 -1
  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/collapse/collapse.scss +1 -1
  15. package/src/components/container/container.scss +1 -1
  16. package/src/components/decision-modal/decision-modal.scss +6 -1
  17. package/src/components/divider/divider.md +6 -6
  18. package/src/components/divider/divider.scss +1 -1
  19. package/src/components/divider/divider.type.ts +2 -2
  20. package/src/components/divider/divider.vue +2 -2
  21. package/src/components/divider/index.ts +1 -1
  22. package/src/components/dropdown/dropdown.scss +4 -10
  23. package/src/components/field/outline/outline.html +13 -13
  24. package/src/components/field/outline/outline.scss +97 -36
  25. package/src/components/field/outline/outline.vue +59 -16
  26. package/src/components/form-group/form-group.md +4 -4
  27. package/src/components/form-group/form-group.scss +1 -1
  28. package/src/components/form-group/form-group.type.ts +2 -2
  29. package/src/components/form-group/form-group.vue +2 -2
  30. package/src/components/gesture-indicator/gesture-indicator.scss +1 -1
  31. package/src/components/index.ts +1 -0
  32. package/src/components/layout/cell/cell.html +1 -0
  33. package/src/components/layout/cell/cell.md +47 -0
  34. package/src/components/layout/cell/cell.scss +54 -0
  35. package/src/components/layout/cell/cell.type.ts +19 -0
  36. package/src/components/layout/cell/cell.vue +35 -0
  37. package/src/components/layout/cell/index.ts +2 -0
  38. package/src/components/layout/flex/flex.html +1 -0
  39. package/src/components/layout/flex/flex.scss +59 -0
  40. package/src/components/layout/flex/flex.type.ts +15 -0
  41. package/src/components/layout/flex/flex.vue +34 -0
  42. package/src/components/layout/flex/index.ts +2 -0
  43. package/src/components/layout/grid/grid.html +1 -0
  44. package/src/components/layout/grid/grid.md +50 -0
  45. package/src/components/layout/grid/grid.scss +53 -0
  46. package/src/components/layout/grid/grid.type.ts +12 -0
  47. package/src/components/layout/grid/grid.vue +32 -0
  48. package/src/components/layout/grid/index.ts +2 -0
  49. package/src/components/layout/index.ts +3 -0
  50. package/src/components/modal/modal.scss +1 -1
  51. package/src/components/page/page.scss +1 -1
  52. package/src/components/present/present.scss +1 -1
  53. package/src/components/radio/radio/radio.scss +1 -1
  54. package/src/components/radio/radio-group/index.ts +1 -1
  55. package/src/components/radio/radio-group/radio-group.md +10 -10
  56. package/src/components/radio/radio-group/radio-group.scss +1 -1
  57. package/src/components/radio/radio-group/radio-group.type.ts +2 -2
  58. package/src/components/radio/radio-group/radio-group.vue +2 -2
  59. package/src/components/refresher/refresher.scss +1 -1
  60. package/src/components/route/route-navigator/route-navigator.scss +5 -5
  61. package/src/components/route/route-navigator/route-navigator.vue +26 -20
  62. package/src/components/segmented-field/segmented-field.scss +1 -1
  63. package/src/components/select/index.ts +1 -1
  64. package/src/components/select/select.html +9 -6
  65. package/src/components/select/select.scss +82 -11
  66. package/src/components/select/select.type.ts +14 -1
  67. package/src/components/select/select.vue +38 -8
  68. package/src/components/skeleton/skeleton.scss +1 -1
  69. package/src/components/switch/switch.scss +1 -1
  70. package/src/components/tabs/tabs/tabs.scss +6 -6
  71. package/src/components/toast/toast/toast.scss +1 -1
  72. package/src/components/toast/toast-content/toast-content.scss +1 -1
  73. package/src/components/toolbar/toolbar.html +1 -3
  74. package/src/components/toolbar/toolbar.md +5 -8
  75. package/src/components/toolbar/toolbar.scss +25 -40
  76. package/src/components/toolbar/toolbar.type.ts +1 -1
  77. package/src/components/toolbar/toolbar.vue +4 -4
  78. package/src/factory.ts +6 -0
  79. package/src/utils/style/index.ts +1 -1
@@ -2,6 +2,6 @@ export { default as RadioGroup } from "./radio-group.vue";
2
2
  export type {
3
3
  RadioGroupProps,
4
4
  RadioGroupProviderState,
5
- RadioGroupOrientation,
5
+ RadioGroupDirection,
6
6
  } from "./radio-group.type";
7
7
  export { RADIO_GROUP_PROVIDER_STATE_KEY } from "./radio-group.constants";
@@ -16,7 +16,7 @@ Radio group with shared `v-model`; provides variant/readonly/disabled/shadow to
16
16
  ## Basic usage
17
17
 
18
18
  ```vue
19
- <t-radio-group v-model="choice" orientation="vertical">
19
+ <t-radio-group v-model="choice" direction="vertical">
20
20
  <t-radio value="a">A</t-radio>
21
21
  <t-radio value="b">B</t-radio>
22
22
  </t-radio-group>
@@ -24,15 +24,15 @@ Radio group with shared `v-model`; provides variant/readonly/disabled/shadow to
24
24
 
25
25
  ## Props
26
26
 
27
- | Prop | Type | Default | Description |
28
- | ------------- | ---------------------------- | ------------ | ------------------------------------- |
29
- | `modelValue` | `string \| number` | — | Selected value (`v-model`). |
30
- | `role` | `string` | — | Theme; default from app. |
31
- | `variant` | `RadioVariant` | `"fill"` | Default for radios unless overridden. |
32
- | `disabled` | `boolean` | `false` | Whole group. |
33
- | `readonly` | `boolean` | `false` | |
34
- | `shadow` | `boolean` | — | Default from app. |
35
- | `orientation` | `"horizontal" \| "vertical"` | `"vertical"` | Flex layout. |
27
+ | Prop | Type | Default | Description |
28
+ | ------------ | ---------------------------- | ------------ | ------------------------------------- |
29
+ | `modelValue` | `string \| number` | — | Selected value (`v-model`). |
30
+ | `role` | `string` | — | Theme; default from app. |
31
+ | `variant` | `RadioVariant` | `"fill"` | Default for radios unless overridden. |
32
+ | `disabled` | `boolean` | `false` | Whole group. |
33
+ | `readonly` | `boolean` | `false` | |
34
+ | `shadow` | `boolean` | — | Default from app. |
35
+ | `direction` | `"horizontal" \| "vertical"` | `"vertical"` | Flex layout. |
36
36
 
37
37
  **Type source:** `src/components/radio/radio-group/radio-group.type.ts`
38
38
 
@@ -1,4 +1,4 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  $radio-group: sass.fn-naming-prefix("radio-group");
4
4
 
@@ -1,7 +1,7 @@
1
1
  import type { ComputedRef } from "vue";
2
2
  import type { RadioVariant } from "../radio/radio.type";
3
3
 
4
- export type RadioGroupOrientation = "horizontal" | "vertical";
4
+ export type RadioGroupDirection = "horizontal" | "vertical";
5
5
 
6
6
  export type RadioGroupProps = {
7
7
  modelValue?: string | number;
@@ -10,7 +10,7 @@ export type RadioGroupProps = {
10
10
  disabled?: boolean;
11
11
  readonly?: boolean;
12
12
  shadow?: boolean;
13
- orientation?: RadioGroupOrientation;
13
+ direction?: RadioGroupDirection;
14
14
  };
15
15
 
16
16
  export type RadioGroupEmit = {
@@ -13,7 +13,7 @@ const props = withDefaults(defineProps<RadioGroupProps>(), {
13
13
  disabled: false,
14
14
  readonly: false,
15
15
  variant: "fill",
16
- orientation: "vertical",
16
+ direction: "vertical",
17
17
  shadow: undefined,
18
18
  });
19
19
  const emit = defineEmits<RadioGroupEmit>();
@@ -37,7 +37,7 @@ const shadow = computed(() => {
37
37
 
38
38
  const radioGroupAttrs = computed(() => {
39
39
  return {
40
- class: [withPrefix("radio-group"), props.orientation],
40
+ class: [withPrefix("radio-group"), props.direction],
41
41
  };
42
42
  });
43
43
 
@@ -1,4 +1,4 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  // Class
4
4
  $refresher: sass.fn-naming-prefix("refresher");
@@ -1,4 +1,4 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  // Classes
4
4
  $navigator: sass.fn-naming-prefix("route-navigator");
@@ -108,19 +108,19 @@ $backdrop-background-color: sass.fn-naming-var("backdrop", "background-color");
108
108
 
109
109
  &.back {
110
110
  &.right {
111
- transform: translateX(calc(-1 * #{$transform-back}));
111
+ transform: translateX(#{$transform-back});
112
112
  }
113
113
 
114
114
  &.left {
115
- transform: translateX(#{$transform-back});
115
+ transform: translateX(calc(-1 * #{$transform-back}));
116
116
  }
117
117
 
118
118
  &.up {
119
- transform: translateY(#{$transform-back});
119
+ transform: translateY(calc(-1 * #{$transform-back}));
120
120
  }
121
121
 
122
122
  &.down {
123
- transform: translateY(calc(-1 * #{$transform-back}));
123
+ transform: translateY(#{$transform-back});
124
124
  }
125
125
  }
126
126
  }
@@ -26,7 +26,7 @@ import { clone } from "../route.util";
26
26
  // Active uses 0–100%; back uses (peek)*(100−percent)/100, so a peek of 40 makes the
27
27
  // back layer move 2.5× slower than the active layer (parallax). Use 100 for 1:1 motion
28
28
  // (no edge peek at rest: back starts at -100%).
29
- const BACK_LAYER_PEEK_PCT = 40;
29
+ const BACK_LAYER_PEEK_PCT = -40;
30
30
 
31
31
  const props = withDefaults(defineProps<RouteNavigatorProps>(), {
32
32
  direction: "right",
@@ -134,17 +134,23 @@ const changeRoute = (value: RouteStack[]) => {
134
134
  transform.backdrop = 0;
135
135
  emit("transform", transform);
136
136
 
137
- setTimeout(() => {
138
- backdropIndex.value = backdropIndex.value + 1;
139
- transform.duration = undefined;
140
- emit("transform", transform);
141
- }, 10);
142
-
143
- setTimeout(() => {
144
- transform.backdrop = 100;
145
- activeIndex.value = stack.value.length - 1;
146
- emit("transform", transform);
147
- }, 100);
137
+ setTimeout(
138
+ () => {
139
+ backdropIndex.value = backdropIndex.value + 1;
140
+ transform.duration = undefined;
141
+ emit("transform", transform);
142
+ },
143
+ props.variant === "swipe" ? 10 : 0
144
+ );
145
+
146
+ setTimeout(
147
+ () => {
148
+ transform.backdrop = 100;
149
+ activeIndex.value = stack.value.length - 1;
150
+ emit("transform", transform);
151
+ },
152
+ props.variant === "swipe" ? 100 : 0
153
+ );
148
154
  }
149
155
  };
150
156
 
@@ -159,23 +165,24 @@ const resetTransform = () => {
159
165
  transform.back = BACK_LAYER_PEEK_PCT;
160
166
  transform.prepare = 100;
161
167
  transform.active = 0;
162
-
168
+ transform.duration = undefined;
163
169
  emit("transform", transform);
164
170
  };
165
171
 
166
172
  const move = (data: RouteNavigatorGesture) => {
167
173
  const width = navigatorRef.value?.offsetWidth ?? 0;
168
- let percent = 0;
174
+ let activePercent = 0;
169
175
 
170
176
  if (props.direction == "left" || props.direction == "right") {
171
- percent = (Math.abs(data.deltaX) / width) * 100;
177
+ activePercent = (Math.abs(data.deltaX) / width) * 100;
172
178
  } else {
173
- percent = (Math.abs(data.deltaY) / width) * 100;
179
+ activePercent = (Math.abs(data.deltaY) / width) * 100;
174
180
  }
175
181
 
176
- transform.back = ((100 - percent) * BACK_LAYER_PEEK_PCT) / 100;
177
- transform.active = percent;
182
+ transform.back = ((100 - activePercent) * BACK_LAYER_PEEK_PCT) / 100;
183
+ transform.active = activePercent;
178
184
  transform.backdrop = 100 - transform.active;
185
+ transform.duration = "0s";
179
186
 
180
187
  emit("transform", transform);
181
188
  };
@@ -216,14 +223,13 @@ onMounted(() => {
216
223
  beforeEvent(e: Event) {
217
224
  const target = e.target as HTMLElement | null;
218
225
  const isEditable = target?.closest("input, textarea, select, button, [contenteditable]");
219
- if (isEditable || props.variant === "none") return false;
226
+ if (isEditable || props.variant === "none" || !prevPage.value) return false;
220
227
  e.stopPropagation();
221
228
  return prevPage.value;
222
229
  },
223
230
 
224
231
  fast({ initialDirection, event }: { initialDirection: string; event: Event }) {
225
232
  if (initialDirection !== props.direction) return;
226
- event.stopPropagation();
227
233
  event.preventDefault();
228
234
  goBack();
229
235
  },
@@ -1,4 +1,4 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  // Class name
4
4
  $segmented-field-wrapper: sass.fn-naming-prefix("segmented-field-wrapper");
@@ -1,2 +1,2 @@
1
1
  export { default as Select } from "./select.vue";
2
- export type { SelectVariant, SelectSize, SelectProps } from "./select.type";
2
+ export * from "./select.type";
@@ -1,5 +1,5 @@
1
1
  <div v-bind="selectAttrs">
2
- <Dropdown v-bind="dropdownAttrs">
2
+ <Dropdown v-bind="dropdownAttrs" v-model="visible">
3
3
  <template #trigger="{ toggle, isOpen }">
4
4
  <Field
5
5
  :role="role"
@@ -14,13 +14,16 @@
14
14
  </Field>
15
15
  </template>
16
16
  <button
17
- v-for="item in menuItems"
18
- :key="item"
17
+ v-for="option in options"
18
+ :key="option.value"
19
19
  type="button"
20
- class="dropdown-demo-row"
21
- @click="pickMenu(item)"
20
+ :disabled="option.disabled"
21
+ v-bind="selectOptionAttrs"
22
+ @click="pickOption(option)"
22
23
  >
23
- {{ item }}
24
+ {{ option.label }}
24
25
  </button>
25
26
  </Dropdown>
27
+ <div v-bind="selectMessageAttrs" v-if="message">{{ message }}</div>
28
+ <div v-bind="selectHelpAttrs" v-if="help">{{ help }}</div>
26
29
  </div>
@@ -1,26 +1,36 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  // Class name
4
4
  $select: sass.fn-naming-prefix("select");
5
5
  $select-icon: sass.fn-naming-prefix("select-icon");
6
+ $select-option: sass.fn-naming-prefix("select-option");
7
+ $select-message: sass.fn-naming-prefix("select-message");
8
+ $select-help: sass.fn-naming-prefix("select-help");
6
9
  $field: sass.fn-naming-prefix("field");
7
10
  $field-input: sass.fn-naming-prefix("field-input");
8
11
 
9
12
  // Property name
10
13
  $app-color: sass.fn-naming-var("app", "color");
11
14
  $spacing-x: sass.fn-naming-var("spacing", "x");
15
+ $spacing-y: sass.fn-naming-var("spacing", "y");
12
16
  $size-coefficient-x: sass.fn-naming-var("coefficient-x");
17
+ $size-coefficient-y: sass.fn-naming-var("coefficient-y");
13
18
  $transition-duration: sass.fn-naming-var("motion", "duration");
14
19
 
20
+ $select-background-color: sass.fn-naming-var("select", "background-color");
21
+ $select-background-color-hover: sass.fn-naming-var("select", "background-color", "hover");
22
+ $select-background-color-focus: sass.fn-naming-var("select", "background-color", "focus");
23
+ $select-background-color-active: sass.fn-naming-var("select", "background-color", "active");
24
+ $select-color: sass.fn-naming-var("select", "color");
25
+ $select-color-disabled: sass.fn-naming-var("select", "color", "disabled");
26
+ $select-border-color: sass.fn-naming-var("select", "border-color");
27
+ $select-message-color: sass.fn-naming-var("select", "message-color");
28
+
15
29
  .#{$select} {
16
30
  &.disabled {
17
31
  cursor: not-allowed;
18
32
  }
19
33
 
20
- &.readonly {
21
- pointer-events: none;
22
- }
23
-
24
34
  .#{$select-icon} {
25
35
  display: inline-flex;
26
36
  align-items: center;
@@ -48,11 +58,72 @@ $transition-duration: sass.fn-naming-var("motion", "duration");
48
58
  }
49
59
  }
50
60
 
51
- // :deep(.#{$field}.focus .#{$select-icon} svg) {
52
- // transform: rotate(180deg);
53
- // }
61
+ .#{$select-option} {
62
+ display: block;
63
+ width: 100%;
64
+ padding: calc(var(--t-spacing-y)) calc(var(--t-spacing-x) * var(--t-coefficient-x));
65
+ text-align: var(--t-text-align);
66
+ text-overflow: ellipsis;
67
+ white-space: nowrap;
68
+ overflow: hidden;
69
+ background: transparent;
70
+ cursor: pointer;
71
+ color: rgb(#{$select-color});
72
+ background-color: rgb(#{$select-background-color});
73
+ transition:
74
+ box-shadow #{$transition-duration} ease,
75
+ border-color #{$transition-duration} ease,
76
+ background-color #{$transition-duration} ease,
77
+ color #{$transition-duration} ease,
78
+ border-radius #{$transition-duration} ease;
79
+
80
+ &:not(:disabled):not(.disabled):not(.readonly) {
81
+ &:hover,
82
+ &.hover {
83
+ background: rgb(#{$select-background-color-hover});
84
+ }
85
+
86
+ &:focus,
87
+ &.focus {
88
+ background: rgb(#{$select-background-color-focus});
89
+ }
90
+
91
+ &:active,
92
+ &.active {
93
+ background: rgb(#{$select-background-color-active});
94
+ }
95
+ }
96
+
97
+ &:disabled,
98
+ &.disabled {
99
+ cursor: not-allowed;
100
+ color: rgb(#{$select-color-disabled});
101
+ }
102
+ }
103
+
104
+ // Message
105
+ .#{$select-message} {
106
+ color: rgb(#{$select-message-color});
107
+ font-size: 0.9em;
108
+ line-height: 1.5;
109
+ transition:
110
+ box-shadow #{$transition-duration} ease,
111
+ border-color #{$transition-duration} ease,
112
+ background-color #{$transition-duration} ease,
113
+ color #{$transition-duration} ease,
114
+ border-radius #{$transition-duration} ease;
115
+ }
54
116
 
55
- // :deep(.#{$field-input}) {
56
- // cursor: pointer;
57
- // }
117
+ // Help
118
+ .#{$select-help} {
119
+ color: rgb(#{$app-color}, 0.75);
120
+ font-size: 0.8em;
121
+ line-height: 1.5;
122
+ transition:
123
+ box-shadow #{$transition-duration} ease,
124
+ border-color #{$transition-duration} ease,
125
+ background-color #{$transition-duration} ease,
126
+ color #{$transition-duration} ease,
127
+ border-radius #{$transition-duration} ease;
128
+ }
58
129
  }
@@ -4,6 +4,12 @@ import type { AppDirection } from "../app";
4
4
  export type SelectVariant = FieldVariant;
5
5
  export type SelectSize = FieldSize;
6
6
 
7
+ export type SelectOption = {
8
+ label?: string;
9
+ value: string;
10
+ disabled?: boolean;
11
+ };
12
+
7
13
  export type SelectProps = {
8
14
  // Wrapper
9
15
  modelValue?: string;
@@ -20,7 +26,6 @@ export type SelectProps = {
20
26
  value?: string;
21
27
  placeholder?: string;
22
28
  disabled?: boolean;
23
- readonly?: boolean;
24
29
  autocomplete?: string;
25
30
  tabindex?: number | string;
26
31
  line?: number | string;
@@ -29,4 +34,12 @@ export type SelectProps = {
29
34
  // Support
30
35
  message?: string;
31
36
  help?: string;
37
+
38
+ // Data
39
+ options: Array<SelectOption>;
40
+ };
41
+
42
+ export type SelectEmit = {
43
+ (e: "update:modelValue", value: string): void;
44
+ (e: "select", option: SelectOption): void;
32
45
  };
@@ -1,8 +1,8 @@
1
1
  <style lang="scss" src="./select.scss" scoped></style>
2
2
  <template src="./select.html"></template>
3
3
  <script lang="ts" setup>
4
- import { computed, inject } from "vue";
5
- import { type SelectProps } from "./select.type";
4
+ import { computed, inject, ref } from "vue";
5
+ import { type SelectOption, type SelectProps, type SelectEmit } from "./select.type";
6
6
  import { property, withPrefix } from "../../utils";
7
7
  import { type AppProviderState, APP_PROVIDER_STATE_KEY } from "../app";
8
8
  import { Field } from "../field";
@@ -15,15 +15,17 @@ const props = withDefaults(defineProps<SelectProps>(), {
15
15
  type: "text",
16
16
  size: "standard",
17
17
  disabled: false,
18
- readonly: false,
19
18
  message: "",
20
19
  help: "",
21
20
  variant: "outline",
22
21
  placeholder: "",
23
22
  shadow: undefined,
24
23
  direction: undefined,
24
+ options: () => [] as Array<SelectOption>,
25
25
  });
26
26
  const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
27
+ const emit = defineEmits<SelectEmit>();
28
+ const visible = ref(false);
27
29
 
28
30
  // Computed properties
29
31
  // ----------------------------------------------------------------------------
@@ -47,10 +49,12 @@ const selectAttrs = computed(() => {
47
49
  return {
48
50
  class: [
49
51
  withPrefix(["layer", "select"]),
52
+ withPrefix(["role", role.value]),
50
53
  withPrefix("select"),
54
+ withPrefix(["direction", direction.value]),
55
+ withPrefix(["size", props.size]),
51
56
  {
52
57
  disabled: props.disabled,
53
- readonly: props.readonly,
54
58
  },
55
59
  ],
56
60
  };
@@ -63,22 +67,27 @@ const dropdownAttrs = computed(() => {
63
67
  shadow: shadow.value,
64
68
  shape: shape.value,
65
69
  disabled: props.disabled,
66
- readonly: props.readonly,
67
70
  };
68
71
  });
69
72
 
70
73
  const fieldAttrs = computed(() => {
74
+ const propsValue = props.modelValue || props.value;
75
+ let val: string[] = [];
76
+ if (propsValue) val = typeof propsValue === "string" ? [propsValue] : (propsValue as string[]);
77
+ const values: string[] = props.options
78
+ .filter((option): option is SelectOption => (val || []).includes(option.value))
79
+ .map((option) => option.label ?? option.value);
80
+
71
81
  return {
72
- modelValue: props.modelValue,
82
+ modelValue: values.join(","),
73
83
  size: props.size,
74
- message: props.message,
75
- help: props.help,
76
84
  variant: props.variant,
77
85
  placeholder: props.placeholder,
78
86
  direction: direction.value,
79
87
  role: role.value,
80
88
  shape: shape.value,
81
89
  readonly: true,
90
+ disabled: props.disabled,
82
91
  shadow: shadow.value,
83
92
  };
84
93
  });
@@ -86,4 +95,25 @@ const fieldAttrs = computed(() => {
86
95
  const selectIconAttrs = computed(() => ({
87
96
  class: [withPrefix("select-icon")],
88
97
  }));
98
+
99
+ const selectOptionAttrs = computed(() => ({
100
+ class: [withPrefix("select-option")],
101
+ }));
102
+
103
+ const selectMessageAttrs = computed(() => ({
104
+ class: [withPrefix("select-message")],
105
+ }));
106
+
107
+ const selectHelpAttrs = computed(() => ({
108
+ class: [withPrefix("select-help")],
109
+ }));
110
+
111
+ // Methods
112
+ // ----------------------------------------------------------------------------
113
+ const pickOption = (option: SelectOption) => {
114
+ if (option.disabled || option.value === undefined) return;
115
+ emit("update:modelValue", option.value);
116
+ emit("select", option);
117
+ visible.value = false;
118
+ };
89
119
  </script>
@@ -1,4 +1,4 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  // Classes
4
4
  $skeleton: sass.fn-naming-prefix("skeleton");
@@ -1,4 +1,4 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  // Classes
4
4
  $switch: sass.fn-naming-prefix("switch");
@@ -1,4 +1,4 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  // Class name
4
4
  $tabs: sass.fn-naming-prefix("tabs");
@@ -30,7 +30,7 @@ $highlight-space-y: sass.fn-naming-var("highlight", "space-y");
30
30
  position: relative;
31
31
  margin: 0;
32
32
  list-style: none;
33
- border: #{$border-width} solid transparent;
33
+ border: none;
34
34
  transition:
35
35
  box-shadow #{$transition-duration} ease,
36
36
  border-color #{$transition-duration} ease,
@@ -113,25 +113,25 @@ $highlight-space-y: sass.fn-naming-var("highlight", "space-y");
113
113
  &.top-start,
114
114
  &.top-center,
115
115
  &.top-end {
116
- border-bottom-color: rgb(#{$tabs-border-color});
116
+ border-bottom: #{$border-width} solid rgb(#{$tabs-border-color});
117
117
  }
118
118
 
119
119
  &.bottom-start,
120
120
  &.bottom-center,
121
121
  &.bottom-end {
122
- border-top-color: rgb(#{$tabs-border-color});
122
+ border-top: #{$border-width} solid rgb(#{$tabs-border-color});
123
123
  }
124
124
 
125
125
  &.left-start,
126
126
  &.left-center,
127
127
  &.left-end {
128
- border-right-color: rgb(#{$tabs-border-color});
128
+ border-right: #{$border-width} solid rgb(#{$tabs-border-color});
129
129
  }
130
130
 
131
131
  &.right-start,
132
132
  &.right-center,
133
133
  &.right-end {
134
- border-left-color: rgb(#{$tabs-border-color});
134
+ border-left: #{$border-width} solid rgb(#{$tabs-border-color});
135
135
  }
136
136
  }
137
137
 
@@ -1,4 +1,4 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  // Class name
4
4
  $toast: sass.fn-naming-prefix("toast");
@@ -1,4 +1,4 @@
1
- @use "@toife/sass-layer-generator" as sass;
1
+ @use "@toife/sass-layer" as sass;
2
2
 
3
3
  // Class name
4
4
  $toastContent: sass.fn-naming-prefix("toast-content");
@@ -1,5 +1,3 @@
1
1
  <div v-bind="toolbarAttrs">
2
- <div>
3
- <slot />
4
- </div>
2
+ <slot />
5
3
  </div>
@@ -25,12 +25,11 @@ Toolbar surface with height / safe-area; `placement` comes from props or from `t
25
25
 
26
26
  ## Props
27
27
 
28
- | Prop | Type | Default | Description |
29
- | ----------- | ------------------ | -------- | ------------------------------------------------- |
30
- | `placement` | `string \| null` | `null` | Placement class; if null, uses `cable.placement`. |
31
- | `safeArea` | `boolean` | `true` | Safe-area padding (notch, home indicator). |
32
- | `size` | `string \| number` | `"50px"` | Toolbar height. |
33
- | `role` | `string` | — | Theme. |
28
+ | Prop | Type | Default | Description |
29
+ | ----------- | ---------------- | ------- | ------------------------------------------------- |
30
+ | `placement` | `string \| null` | `null` | Placement class; if null, uses `cable.placement`. |
31
+ | `safeArea` | `boolean` | `true` | Safe-area padding (notch, home indicator). |
32
+ | `role` | `string` | | Theme. |
34
33
 
35
34
  **Type source:** `src/components/toolbar/toolbar.type.ts`
36
35
 
@@ -50,8 +49,6 @@ Optional inject `CABLE_PROVIDER_STATE_KEY` and `APP_PROVIDER_STATE_KEY`.
50
49
 
51
50
  ## Style / class notes
52
51
 
53
- Variable `--<prefix>-toolbar-size`; classes `with-safe-area`, placement.
54
-
55
52
  ## See also
56
53
 
57
54
  - Source: `src/components/toolbar`