@toife/vue 3.0.0 → 3.0.2

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 (98) hide show
  1. package/README.md +54 -1
  2. package/package.json +7 -7
  3. package/src/components/action/action.md +115 -0
  4. package/src/components/action/action.scss +1 -2
  5. package/src/components/action/action.vue +9 -21
  6. package/src/components/app/app.md +77 -0
  7. package/src/components/app/app.scss +3 -3
  8. package/src/components/app/app.vue +1 -1
  9. package/src/components/avatar/avatar.md +64 -0
  10. package/src/components/avatar/avatar.scss +2 -2
  11. package/src/components/avatar/avatar.vue +1 -1
  12. package/src/components/button/button.md +66 -0
  13. package/src/components/button/button.scss +13 -13
  14. package/src/components/button/button.vue +6 -11
  15. package/src/components/cable/cable.md +57 -0
  16. package/src/components/cable/cable.vue +1 -1
  17. package/src/components/card/card/card.md +57 -0
  18. package/src/components/card/card/card.scss +3 -3
  19. package/src/components/card/card/card.vue +1 -1
  20. package/src/components/card/card-body/card-body.md +34 -0
  21. package/src/components/card/card-body/card-body.scss +3 -3
  22. package/src/components/card/card-body/card-body.vue +3 -8
  23. package/src/components/card/card-footer/card-footer.md +42 -0
  24. package/src/components/card/card-footer/card-footer.scss +4 -4
  25. package/src/components/card/card-footer/card-footer.vue +2 -5
  26. package/src/components/card/card-header/card-header.md +44 -0
  27. package/src/components/card/card-header/card-header.scss +4 -4
  28. package/src/components/card/card-header/card-header.vue +2 -5
  29. package/src/components/checkbox/checkbox.md +60 -0
  30. package/src/components/checkbox/checkbox.scss +8 -8
  31. package/src/components/checkbox/checkbox.vue +11 -24
  32. package/src/components/collapse/collapse.md +59 -0
  33. package/src/components/collapse/collapse.scss +2 -2
  34. package/src/components/collapse/collapse.vue +1 -1
  35. package/src/components/container/container.md +38 -0
  36. package/src/components/container/container.vue +3 -8
  37. package/src/components/decision-modal/decision-modal.md +79 -0
  38. package/src/components/decision-modal/decision-modal.scss +3 -3
  39. package/src/components/decision-modal/decision-modal.vue +1 -1
  40. package/src/components/divider/divider.md +42 -0
  41. package/src/components/divider/divider.scss +1 -1
  42. package/src/components/divider/divider.vue +3 -6
  43. package/src/components/field/field.md +68 -0
  44. package/src/components/field/outline/outline-field.md +44 -0
  45. package/src/components/field/outline/outline.scss +8 -8
  46. package/src/components/field/outline/outline.vue +2 -2
  47. package/src/components/form-group/form-group.md +41 -0
  48. package/src/components/gesture-indicator/gesture-indicator.md +42 -0
  49. package/src/components/gesture-indicator/gesture-indicator.scss +2 -2
  50. package/src/components/gesture-indicator/gesture-indicator.vue +3 -6
  51. package/src/components/image/image.md +41 -0
  52. package/src/components/modal/modal.md +65 -0
  53. package/src/components/modal/modal.scss +2 -2
  54. package/src/components/modal/modal.vue +1 -1
  55. package/src/components/page/page.md +39 -0
  56. package/src/components/page/page.vue +3 -8
  57. package/src/components/present/present.md +60 -0
  58. package/src/components/present/present.vue +1 -1
  59. package/src/components/radio/radio/radio.md +53 -0
  60. package/src/components/radio/radio/radio.scss +8 -8
  61. package/src/components/radio/radio/radio.vue +7 -11
  62. package/src/components/radio/radio-group/radio-group.md +62 -0
  63. package/src/components/radio/radio-group/radio-group.vue +1 -6
  64. package/src/components/refresher/refresher.md +53 -0
  65. package/src/components/route/route-navigator/route-navigator.md +50 -0
  66. package/src/components/route/route-navigator/route-navigator.scss +1 -1
  67. package/src/components/route/route-navigator/route-navigator.vue +14 -9
  68. package/src/components/route/route-outlet/route-outlet.md +30 -0
  69. package/src/components/route/route-provider/route-provider.md +46 -0
  70. package/src/components/route/route-wrapper/route-wrapper.composable.ts +29 -14
  71. package/src/components/route/route-wrapper/route-wrapper.md +45 -0
  72. package/src/components/route/route-wrapper/route-wrapper.type.ts +4 -0
  73. package/src/components/route/route-wrapper/route-wrapper.vue +13 -5
  74. package/src/components/route/route.type.ts +1 -0
  75. package/src/components/segmented-field/segmented-field.md +58 -0
  76. package/src/components/segmented-field/segmented-field.scss +3 -3
  77. package/src/components/segmented-field/segmented-field.vue +20 -26
  78. package/src/components/skeleton/skeleton.md +47 -0
  79. package/src/components/skeleton/skeleton.scss +3 -3
  80. package/src/components/skeleton/skeleton.vue +1 -1
  81. package/src/components/switch/switch.md +57 -0
  82. package/src/components/switch/switch.scss +8 -8
  83. package/src/components/switch/switch.vue +9 -20
  84. package/src/components/tabs/tab/tab.md +52 -0
  85. package/src/components/tabs/tabs/tabs.md +59 -0
  86. package/src/components/tabs/tabs/tabs.scss +4 -6
  87. package/src/components/tabs/tabs/tabs.vue +4 -6
  88. package/src/components/toast/toast/toast.md +56 -0
  89. package/src/components/toast/toast-content/toast-content.md +41 -0
  90. package/src/components/toast/toast-content/toast-content.scss +4 -4
  91. package/src/components/toast/toast-content/toast-content.vue +5 -11
  92. package/src/components/toolbar/toolbar.md +57 -0
  93. package/src/components/toolbar/toolbar.scss +2 -2
  94. package/src/components/toolbar/toolbar.vue +5 -11
  95. package/src/factory.ts +2 -0
  96. package/src/utils/element.md +33 -0
  97. package/src/utils/events.md +29 -0
  98. package/src/utils/style.md +49 -0
@@ -17,8 +17,10 @@ const props = withDefaults(defineProps<RouteWrapperProps>(), {
17
17
  /// ------------------------------------------------------------
18
18
  watch(
19
19
  () => route.matched,
20
- (matched) => {
21
- updateRoutes(matched);
20
+ () => {
21
+ updateRoutes(route.matched, {
22
+ fullPath: route.fullPath,
23
+ });
22
24
  }
23
25
  );
24
26
 
@@ -27,16 +29,22 @@ onMounted(() => {
27
29
  const homeName = props.homeRouteName;
28
30
 
29
31
  if (route.name === homeName) {
30
- updateRoutes(route.matched);
32
+ updateRoutes(route.matched, {
33
+ fullPath: route.fullPath,
34
+ });
31
35
  } else {
32
36
  const homeLocation = router.resolve({ name: homeName });
33
37
  if (homeLocation.matched.length > 0) {
34
- updateRoutes(homeLocation.matched);
38
+ updateRoutes(homeLocation.matched, {
39
+ fullPath: homeLocation.fullPath,
40
+ });
35
41
  }
36
42
 
37
43
  // Apply current route to stack
38
44
  setTimeout(() => {
39
- updateRoutes(route.matched);
45
+ updateRoutes(route.matched, {
46
+ fullPath: route.fullPath,
47
+ });
40
48
  }, 50);
41
49
  }
42
50
  });
@@ -3,5 +3,6 @@ import { RouteComponent } from "vue-router";
3
3
  export type RouteStack = {
4
4
  name: string;
5
5
  component: RouteComponent;
6
+ fullPath: string;
6
7
  stack: RouteStack[];
7
8
  };
@@ -0,0 +1,58 @@
1
+ # `<t-segmented-field>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ OTP-style segmented input: each segment is a `t-field`; coordinates focus and `v-model` as a character array.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ---------------------------------------- |
13
+ | Vue | ^3.5 |
14
+ | Other | `t-app` recommended; depends on `Field`. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-segmented-field v-model="otp" :length="6" @complete="submit" />
20
+ ```
21
+
22
+ ## Props
23
+
24
+ | Prop | Type | Default | Description |
25
+ | ----------------------- | ---------- | ------------------------ | --------------------------------------------- |
26
+ | `modelValue` | `string[]` | — | Character array (`v-model`). |
27
+ | `value` | `string[]` | — | May be used instead of `modelValue` when set. |
28
+ | `length` | `number` | `6` | Number of segments. |
29
+ | `variant` / `size` | — | Passed to inner `Field`. |
30
+ | `disabled` / `readonly` | `boolean` | `false` | |
31
+ | `type` | `string` | `"text"` | Field input type. |
32
+ | `role` / `shape` | `string` | — | Theme. |
33
+ | `shadow` | `boolean` | — | Default from app. |
34
+ | `message` / `help` | `string` | `""` | Message / help. |
35
+ | `pattern` | `string[]` | `[]` | Reserved for per-cell validation. |
36
+
37
+ **Type source:** `src/components/segmented-field/segmented-field.type.ts`
38
+
39
+ ## Events (emits)
40
+
41
+ | Event | Payload | Description |
42
+ | ------------------- | ------------ | ------------------------------------ |
43
+ | `update:modelValue` | `string[]` | Value update. |
44
+ | `complete` | `string[]` | When `length` characters are filled. |
45
+ | `focus` / `blur` | `FocusEvent` | From inner fields. |
46
+ | `input` | `string[]` | On each change. |
47
+
48
+ ## Slots
49
+
50
+ _None_ — layout is fixed with repeated `Field`.
51
+
52
+ ## `v-model`
53
+
54
+ `modelValue` / `update:modelValue` (`string[]`).
55
+
56
+ ## See also
57
+
58
+ - Source: `src/components/segmented-field`
@@ -9,8 +9,8 @@ $segmented-field-help: sass.fn-naming-prefix("segmented-field-help");
9
9
  // Property name
10
10
  $spacing-x: sass.fn-naming-var("spacing", "x");
11
11
  $transition-duration: sass.fn-naming-var("motion", "duration");
12
- $role-color: sass.fn-naming-var("item", "background-color");
13
- $base-color: sass.fn-naming-var("base", "color");
12
+ $role-color: sass.fn-naming-var("segmented-field", "background-color");
13
+ $app-color: sass.fn-naming-var("app", "color");
14
14
 
15
15
  .#{$segmented-field-wrapper} {
16
16
  .#{$segmented-field-content} {
@@ -33,7 +33,7 @@ $base-color: sass.fn-naming-var("base", "color");
33
33
 
34
34
  // Help
35
35
  .#{$segmented-field-help} {
36
- color: rgb(#{$base-color}, 0.75);
36
+ color: rgb(#{$app-color}, 0.75);
37
37
  font-size: 0.8em;
38
38
  line-height: 1.5;
39
39
  transition:
@@ -33,11 +33,6 @@ const fields = ref<InstanceType<typeof Field>[]>([]);
33
33
 
34
34
  /// Computed
35
35
  /// ------------------------------------------------------------
36
- const role = computed(() => props.role || appState?.role.value || "");
37
- const shape = computed(() => props.shape || appState?.shape.value || "");
38
- const shadow = computed(
39
- () => (props.shadow !== undefined ? props.shadow : appState?.shadow.value) ?? false
40
- );
41
36
  const segments = computed(() => {
42
37
  let value: string[] | undefined = [];
43
38
  if (props.value !== undefined && props.value.length > 0) value = props.value;
@@ -47,12 +42,14 @@ const segments = computed(() => {
47
42
  });
48
43
 
49
44
  const wrapperAttrs = computed(() => {
45
+ const role = props.role || appState?.role.value || "";
46
+ const shape = props.shape || appState?.shape.value || "";
50
47
  return {
51
48
  class: [
52
49
  withPrefix("segmented-field-wrapper"),
53
- withPrefix(["layer", "item"]),
54
- withPrefix(["role", role.value]),
55
- withPrefix(["shape", shape.value]),
50
+ withPrefix(["layer", "segmented-field"]),
51
+ withPrefix(["role", role]),
52
+ withPrefix(["shape", shape]),
56
53
  props.variant,
57
54
  props.size,
58
55
  { disabled: props.disabled },
@@ -60,36 +57,33 @@ const wrapperAttrs = computed(() => {
60
57
  };
61
58
  });
62
59
 
63
- const contentAttrs = computed(() => {
64
- return {
65
- class: [withPrefix("segmented-field-content")],
66
- };
67
- });
60
+ const contentAttrs = {
61
+ class: [withPrefix("segmented-field-content")],
62
+ } as const;
68
63
 
69
64
  const fieldAttrs = computed(() => {
65
+ const role = props.role || appState?.role.value || "";
66
+ const shape = props.shape || appState?.shape.value || "";
67
+ const shadow = (props.shadow !== undefined ? props.shadow : appState?.shadow.value) ?? false;
70
68
  return {
71
69
  variant: props.variant,
72
70
  size: props.size,
73
71
  disabled: props.disabled,
74
72
  readonly: props.readonly,
75
- shadow: shadow.value,
76
- shape: shape.value,
77
- role: role.value,
73
+ shadow,
74
+ shape,
75
+ role,
78
76
  type: props.type,
79
77
  };
80
78
  });
81
79
 
82
- const messageAttrs = computed(() => ({
80
+ const messageAttrs = {
83
81
  class: [withPrefix("segmented-field-message")],
84
- }));
85
-
86
- const helpAttrs = computed(() => ({
87
- class: [
88
- withPrefix("segmented-field-help"),
89
- withPrefix(["layer", "surface"]),
90
- withPrefix(["role", "mode"]),
91
- ],
92
- }));
82
+ } as const;
83
+
84
+ const helpAttrs = {
85
+ class: [withPrefix("segmented-field-help")],
86
+ } as const;
93
87
 
94
88
  const nextIndex = computed(() => {
95
89
  let nextIndex = segments.value.length;
@@ -0,0 +1,47 @@
1
+ # `<t-skeleton>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Loading placeholder block with configurable size (CSS variables), themed from app.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ----------------------------- |
13
+ | Vue | ^3.5 |
14
+ | Other | `t-app` for `role` / `shape`. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-skeleton width="100%" height="12px" />
20
+ ```
21
+
22
+ ## Props
23
+
24
+ | Prop | Type | Default | Description |
25
+ | -------- | ------------------ | -------- | -------------------- |
26
+ | `width` | `string \| number` | `"100%"` | Width (number = px). |
27
+ | `height` | `string \| number` | `"1rem"` | Height. |
28
+ | `role` | `string` | — | Theme. |
29
+ | `shape` | `string` | — | Shape. |
30
+
31
+ **Type source:** `src/components/skeleton/skeleton.type.ts`
32
+
33
+ ## Events (emits)
34
+
35
+ _None._
36
+
37
+ ## Slots
38
+
39
+ _None._
40
+
41
+ ## Style / class notes
42
+
43
+ Variables `--<prefix>-skeleton-width`, `--<prefix>-skeleton-height` via `property(["skeleton","width"])` / `height`.
44
+
45
+ ## See also
46
+
47
+ - Source: `src/components/skeleton`
@@ -3,12 +3,12 @@
3
3
  // Classes
4
4
  $skeleton: sass.fn-naming-prefix("skeleton");
5
5
 
6
- // Properties - layer: item
6
+ // Properties - layer: skeleton
7
7
  $width: sass.fn-naming-var("skeleton", "width");
8
8
  $height: sass.fn-naming-var("skeleton", "height");
9
9
  $border-radius: sass.fn-naming-var("border-radius");
10
- $background-color: sass.fn-naming-var("item", "background-color");
11
- $background-color-subtle: sass.fn-naming-var("item", "background-color", "subtle");
10
+ $background-color: sass.fn-naming-var("skeleton", "background-color");
11
+ $background-color-subtle: sass.fn-naming-var("skeleton", "background-color", "subtle");
12
12
  $transition-duration: sass.fn-naming-var("motion", "duration");
13
13
 
14
14
  .#{$skeleton} {
@@ -22,7 +22,7 @@ const skeletonAttrs = computed(() => {
22
22
 
23
23
  return {
24
24
  class: [
25
- withPrefix(["layer", "item"]),
25
+ withPrefix(["layer", "skeleton"]),
26
26
  withPrefix(["role", role]),
27
27
  withPrefix(["shape", shape]),
28
28
  withPrefix("skeleton"),
@@ -0,0 +1,57 @@
1
+ # `<t-switch>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Boolean toggle with `v-model`, keyboard support, and basic ARIA.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | -------------------- |
13
+ | Vue | ^3.5 |
14
+ | Other | `t-app` recommended. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-switch v-model="on">Notifications</t-switch>
20
+ ```
21
+
22
+ ## Props
23
+
24
+ | Prop | Type | Default | Description |
25
+ | ------------ | --------- | ------- | --------------------- |
26
+ | `modelValue` | `boolean` | `false` | On state. |
27
+ | `role` | `string` | — | Theme when on. |
28
+ | `shape` | `string` | — | Shape. |
29
+ | `disabled` | `boolean` | — | _(optional in types)_ |
30
+ | `readonly` | `boolean` | `false` | Read-only. |
31
+ | `shadow` | `boolean` | — | Default from app. |
32
+
33
+ **Type source:** `src/components/switch/switch.type.ts`
34
+
35
+ ## Events (emits)
36
+
37
+ | Event | Payload | Description |
38
+ | ------------------- | --------- | ------------- |
39
+ | `update:modelValue` | `boolean` | Toggle state. |
40
+
41
+ ## Slots
42
+
43
+ | Slot | Description |
44
+ | --------- | ----------------------- |
45
+ | `default` | Label beside the track. |
46
+
47
+ ## `v-model`
48
+
49
+ `modelValue` / `update:modelValue`.
50
+
51
+ ## Accessibility (a11y)
52
+
53
+ `role="switch"`, `aria-checked`, Space/Enter.
54
+
55
+ ## See also
56
+
57
+ - Source: `src/components/switch`
@@ -7,14 +7,14 @@ $shape-rounded: sass.fn-naming-prefix("shape-rounded");
7
7
  $shape-pill: sass.fn-naming-prefix("shape-pill");
8
8
  $switch-wrapper: sass.fn-naming-prefix("switch-wrapper");
9
9
 
10
- // Properties - switch track: surface (inactive), item (on); switch icon: item
11
- $background-color: sass.fn-naming-var("item", "background-color");
12
- $background-color-hover: sass.fn-naming-var("item", "background-color", "soft");
13
- $background-color-inactive: sass.fn-naming-var("item", "background-color", "subtle");
14
- $background-color-disabled: sass.fn-naming-var("item", "background-color", "subtle");
15
- $background-color-contrast: sass.fn-naming-var("item", "background-color", "contrast");
16
- $border-color: sass.fn-naming-var("item", "border-color");
17
- $color-hover: sass.fn-naming-var("item", "color", "strong");
10
+ // Properties - switch track (inactive), switch icon (on)
11
+ $background-color: sass.fn-naming-var("switch", "background-color");
12
+ $background-color-hover: sass.fn-naming-var("switch", "background-color", "soft");
13
+ $background-color-inactive: sass.fn-naming-var("switch", "background-color", "subtle");
14
+ $background-color-disabled: sass.fn-naming-var("switch", "background-color", "subtle");
15
+ $background-color-contrast: sass.fn-naming-var("switch", "background-color", "contrast");
16
+ $border-color: sass.fn-naming-var("switch", "border-color");
17
+ $color-hover: sass.fn-naming-var("switch", "color", "strong");
18
18
  $transition-duration: sass.fn-naming-var("motion", "duration");
19
19
  $border-radius: sass.fn-naming-var("border-radius");
20
20
  $spacing-x: sass.fn-naming-var("spacing", "x");
@@ -22,22 +22,15 @@ const isFocused = ref(false);
22
22
 
23
23
  /// Computed
24
24
  /// ------------------------------------------------------------
25
- const role = computed(() => {
26
- return props.role || appState?.role.value || "";
27
- });
28
-
29
- const shadow = computed(() => {
30
- return (props?.shadow !== undefined ? props.shadow : appState?.shadow.value) ?? false;
31
- });
32
-
33
25
  const switchWrapperAttrs = computed(() => {
26
+ const shadow = (props?.shadow !== undefined ? props.shadow : appState?.shadow.value) ?? false;
34
27
  return {
35
28
  class: [
36
29
  withPrefix("switch-wrapper"),
37
30
  {
38
31
  disabled: props.disabled,
39
32
  readonly: props.readonly,
40
- shadow: shadow.value,
33
+ shadow,
41
34
  focus: isFocused.value,
42
35
  on: props.modelValue,
43
36
  },
@@ -47,25 +40,21 @@ const switchWrapperAttrs = computed(() => {
47
40
 
48
41
  const switchAttrs = computed(() => {
49
42
  const shape = props.shape || appState?.shape.value || "";
50
-
43
+ const baseRole = appState?.role.value || "";
44
+ const role = props.role || baseRole;
51
45
  return {
52
46
  class: [
53
- withPrefix(["layer", "item"]),
54
- withPrefix([
55
- "role",
56
- props.modelValue && !props.disabled ? role.value : appState?.role.value || "",
57
- ]),
47
+ withPrefix(["layer", "switch"]),
48
+ withPrefix(["role", props.modelValue && !props.disabled ? role : baseRole]),
58
49
  withPrefix(["shape", shape]),
59
50
  withPrefix("switch"),
60
51
  ],
61
52
  };
62
53
  });
63
54
 
64
- const switchIconAttrs = computed(() => {
65
- return {
66
- class: [withPrefix("switch-icon")],
67
- };
68
- });
55
+ const switchIconAttrs = {
56
+ class: [withPrefix("switch-icon")],
57
+ } as const;
69
58
 
70
59
  /// Methods
71
60
  /// ------------------------------------------------------------
@@ -0,0 +1,52 @@
1
+ # `Tab`
2
+
3
+ > **Not** registered by `createToife()` — `import { Tab, Tabs } from "@toife/vue"` (see package README).
4
+
5
+ ## Description
6
+
7
+ One item in `t-tabs`: renders `<li>` + `t-button`; click calls the provider’s `setValue`.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ------------------------ |
13
+ | Vue | ^3.5 |
14
+ | Other | Must be inside `t-tabs`. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <script setup lang="ts">
20
+ import { Tabs, Tab } from "@toife/vue";
21
+ </script>
22
+ <template>
23
+ <Tabs v-model="active">
24
+ <Tab value="1">One</Tab>
25
+ <Tab value="2" disabled>Two</Tab>
26
+ </Tabs>
27
+ </template>
28
+ ```
29
+
30
+ ## Props
31
+
32
+ | Prop | Type | Default | Description |
33
+ | ---------- | --------- | ------- | ------------------------------------- |
34
+ | `value` | `string` | — | Tab id (matches `Tabs` `modelValue`). |
35
+ | `disabled` | `boolean` | `false` | Disables selection. |
36
+
37
+ **Type source:** `src/components/tabs/tab/tab.type.ts`
38
+
39
+ ## Events (emits)
40
+
41
+ _None._
42
+
43
+ ## Slots
44
+
45
+ | Slot | Description |
46
+ | --------- | ---------------------------- |
47
+ | `default` | Tab label (inside `Button`). |
48
+
49
+ ## See also
50
+
51
+ - Source: `src/components/tabs/tab`
52
+ - [tabs.md](../tabs/tabs.md)
@@ -0,0 +1,59 @@
1
+ # `<t-tabs>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Tab bar: `modelValue` is the active `Tab`’s `value`; underline/highlight position is measured from the DOM (`getBoundingClientRect`). Provides state to child `Tab` components.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ---------------------------------------------------------------------- |
13
+ | Vue | ^3.5 |
14
+ | Other | Children should be `Tab` (named export) — see [tab.md](../tab/tab.md). |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-tabs v-model="tab" variant="underline" placement="top-start">
20
+ <Tab value="a">Tab A</Tab>
21
+ <Tab value="b">Tab B</Tab>
22
+ </t-tabs>
23
+ ```
24
+
25
+ ## Props
26
+
27
+ | Prop | Type | Default | Description |
28
+ | ---------------- | --------------- | ------------- | ------------------------------------ |
29
+ | `modelValue` | `string` | `""` | Active tab value (`v-model`). |
30
+ | `placement` | `TabsPlacement` | `"top-start"` | Bar placement + highlight direction. |
31
+ | `variant` | `TabsVariant` | — | `fill` \| `underline` \| `text`. |
32
+ | `role` / `shape` | `string` | — | Theme. |
33
+ | `border` | `number` | `2` | Underline thickness. |
34
+ | `margin` | `number[]` | `[0, 0]` | Margin around highlight. |
35
+ | `divider` | `boolean` | — | Default from app. |
36
+ | `transition` | `boolean` | `true` | Animate highlight. |
37
+
38
+ **Type source:** `src/components/tabs/tabs/tabs.type.ts`
39
+
40
+ ## Events (emits)
41
+
42
+ | Event | Payload | Description |
43
+ | ------------------- | -------- | ----------- |
44
+ | `update:modelValue` | `string` | Tab change. |
45
+
46
+ ## Slots
47
+
48
+ | Slot | Description |
49
+ | --------- | --------------- |
50
+ | `default` | `Tab` children. |
51
+
52
+ ## Provide / inject
53
+
54
+ `TABS_PROVIDER_STATE_KEY`: `activeValue`, `role`, `shape`, `setValue`.
55
+
56
+ ## See also
57
+
58
+ - Source: `src/components/tabs/tabs`
59
+ - [tab.md](../tab/tab.md)
@@ -9,16 +9,14 @@ $button: sass.fn-naming-prefix("button");
9
9
  $space-x: sass.fn-naming-var("spacing", "x");
10
10
  $space-y: sass.fn-naming-var("spacing", "y");
11
11
 
12
- // layer: item
13
- $button-color: sass.fn-naming-var("item", "color");
12
+ // layer: tabs
13
+ $button-color: sass.fn-naming-var("tabs", "color");
14
14
  $border-radius: sass.fn-naming-var("border-radius");
15
15
  $border-width: sass.fn-naming-var("stroke", "width");
16
- $border-color: sass.fn-naming-var("surface", "border-color");
16
+ $border-color: sass.fn-naming-var("tabs", "border-color");
17
17
 
18
18
  $transition-duration: sass.fn-naming-var("motion", "duration");
19
- $background-color: sass.fn-naming-var("item", "background-color");
20
- $color: sass.fn-naming-var("item", "color");
21
- $color-base: sass.fn-naming-var("base", "color");
19
+ $background-color: sass.fn-naming-var("tabs", "background-color");
22
20
 
23
21
  $highlight-top: sass.fn-naming-var("highlight", "top");
24
22
  $highlight-left: sass.fn-naming-var("highlight", "left");
@@ -41,11 +41,9 @@ const activeValue = computed(() => {
41
41
  return props.modelValue || "";
42
42
  });
43
43
 
44
- const divider = computed(() => {
45
- return (props.divider !== undefined ? props.divider : appState?.divider.value || false) ?? false;
46
- });
47
-
48
44
  const tabsAttrs = computed(() => {
45
+ const divider =
46
+ (props.divider !== undefined ? props.divider : appState?.divider.value || false) ?? false;
49
47
  let l = left.value;
50
48
  let t = top.value;
51
49
  let w = width.value;
@@ -86,14 +84,14 @@ const tabsAttrs = computed(() => {
86
84
 
87
85
  return {
88
86
  class: [
89
- withPrefix(["layer", "item"]),
87
+ withPrefix(["layer", "tabs"]),
90
88
  withPrefix(["role", role.value]),
91
89
  withPrefix(["shape", shape.value]),
92
90
  withPrefix("tabs"),
93
91
  props.variant,
94
92
  props.placement,
95
93
  {
96
- divider: divider.value,
94
+ divider,
97
95
  transition: props.transition,
98
96
  },
99
97
  ],
@@ -0,0 +1,56 @@
1
+ # `<t-toast>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Toast region for a given `placement`; messages come from the singleton `useToast()` store. `t-app` mounts several instances with different placements.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ------------------------------------------------------------------ |
13
+ | Vue | ^3.5 |
14
+ | Other | Call `useToast().open()` anywhere to push messages (shared store). |
15
+
16
+ ## Basic usage
17
+
18
+ ```ts
19
+ import { useToast } from "@toife/vue";
20
+
21
+ const toast = useToast();
22
+ toast.open({
23
+ message: "Saved",
24
+ placement: "bottom-center",
25
+ duration: 2000,
26
+ });
27
+ ```
28
+
29
+ ```vue
30
+ <!-- One region; placement must match `open` -->
31
+ <t-toast placement="bottom-center" />
32
+ ```
33
+
34
+ ## Props
35
+
36
+ | Prop | Type | Default | Description |
37
+ | ----------- | ---------------- | -------------- | --------------------------------------- |
38
+ | `placement` | `ToastPlacement` | `"bottom-end"` | Only shows messages for this placement. |
39
+
40
+ **Type source:** `src/components/toast/toast.type.ts`
41
+
42
+ ## Events (emits)
43
+
44
+ _None._
45
+
46
+ ## Slots
47
+
48
+ | Slot | Description |
49
+ | --------- | ----------------------------------------- |
50
+ | `content` | Replaces the default `ToastContent` list. |
51
+
52
+ ## See also
53
+
54
+ - Source: `src/components/toast/toast`
55
+ - `toast.composable.ts` — `useToast`
56
+ - [toast-content.md](../toast-content/toast-content.md)