@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
@@ -0,0 +1,79 @@
1
+ # `<t-decision-modal>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Confirmation dialog (title, message, actions) inside `Present`. Often driven with `useDecisionModal()` from `t-app`.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ---------------------------------------------------- |
13
+ | Vue | ^3.5 |
14
+ | Other | `t-app` recommended; depends on `Present`, `Button`. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-decision-modal
20
+ :visible="show"
21
+ title="Confirm"
22
+ message="Are you sure?"
23
+ :actions="[
24
+ { text: 'Cancel', variant: 'text', handler: () => (show = false) },
25
+ { text: 'Delete', variant: 'fill', handler: onDelete },
26
+ ]"
27
+ :dismiss="['backdrop']"
28
+ @close="show = false"
29
+ />
30
+ ```
31
+
32
+ Composable:
33
+
34
+ ```ts
35
+ const modal = useDecisionModal();
36
+ modal.open({
37
+ message: "…",
38
+ actions: […],
39
+ onClose: () => {},
40
+ onChoose: (btn) => {},
41
+ });
42
+ ```
43
+
44
+ ## Props
45
+
46
+ | Prop | Type | Default | Description |
47
+ | ----------- | ----------------------- | ------------ | ---------------------------------- |
48
+ | `visible` | `boolean` | `false` | Visibility. |
49
+ | `title` | `string` | — | Title (`header` slot overrides). |
50
+ | `message` | `string` | _(required)_ | Main copy (`body` slot overrides). |
51
+ | `actions` | `DecisionModalButton[]` | _(required)_ | Footer buttons. |
52
+ | `dismiss` | `string[]` | — | Close reasons that emit `close`. |
53
+ | `placement` | `string` | `"center"` | `Present` placement. |
54
+ | `role` | `string` | — | Theme. |
55
+ | `shape` | `string` | — | Shape. |
56
+ | `divider` | `boolean` | — | Divider; default from app. |
57
+ | `flow` | `"row" \| "column"` | `"row"` | Footer button layout. |
58
+
59
+ **Type source:** `src/components/decision-modal/decision-modal.type.ts`
60
+
61
+ ## Events (emits)
62
+
63
+ | Event | Payload | Description |
64
+ | -------- | -------------------------- | -------------------------------- |
65
+ | `close` | `type?: string` | Valid dismiss (per `dismiss`). |
66
+ | `choose` | `btn: DecisionModalButton` | Button chosen (after `handler`). |
67
+
68
+ ## Slots
69
+
70
+ | Slot | Description |
71
+ | -------- | ---------------------------------------- |
72
+ | `header` | Replaces header (default shows `title`). |
73
+ | `body` | Replaces `message`. |
74
+ | `footer` | Replaces default button row. |
75
+
76
+ ## See also
77
+
78
+ - Source: `src/components/decision-modal`
79
+ - `decision-modal.composable.ts`
@@ -8,9 +8,9 @@ $decision-modal-footer: sass.fn-naming-prefix("decision-modal-footer");
8
8
  $button: sass.fn-naming-prefix("button");
9
9
  $shape-pill: sass.fn-naming-prefix("shape-pill");
10
10
 
11
- // Property name - layer: surface
11
+ // Property name - layer: decision-modal
12
12
  $border-radius: sass.fn-naming-var("border-radius");
13
- $background-color: sass.fn-naming-var("surface", "background-color");
13
+ $background-color: sass.fn-naming-var("decision-modal", "background-color");
14
14
  $width: sass.fn-naming-var("viewport", "width");
15
15
  $max-width: sass.fn-naming-var("overlay", "max-width");
16
16
  $padding-y: sass.fn-naming-var("spacing", "y");
@@ -19,7 +19,7 @@ $margin-y: sass.fn-naming-var("spacing", "y");
19
19
  $margin-x: sass.fn-naming-var("spacing", "x");
20
20
  $animation-duration: sass.fn-naming-var("motion", "duration");
21
21
  $border-width: sass.fn-naming-var("stroke", "width");
22
- $border-color: sass.fn-naming-var("surface", "border-color");
22
+ $border-color: sass.fn-naming-var("decision-modal", "border-color");
23
23
  $transition-duration: sass.fn-naming-var("motion", "duration");
24
24
 
25
25
  .#{$decision-modal} {
@@ -47,7 +47,7 @@ const divider = computed(() => {
47
47
  const decisionModalAttrs = computed(() => {
48
48
  return {
49
49
  class: [
50
- withPrefix(["layer", "surface"]),
50
+ withPrefix(["layer", "decision-modal"]),
51
51
  withPrefix(["role", role.value]),
52
52
  withPrefix(["shape", shape.value]),
53
53
  withPrefix("decision-modal"),
@@ -0,0 +1,42 @@
1
+ # `<t-divider>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Horizontal or vertical divider line following theme.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ------------------- |
13
+ | Vue | ^3.5 |
14
+ | Other | `t-app` for `role`. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-divider orientation="horizontal" />
20
+ <t-divider orientation="vertical" />
21
+ ```
22
+
23
+ ## Props
24
+
25
+ | Prop | Type | Default | Description |
26
+ | ------------- | ---------------------------- | -------------- | ------------------------------- |
27
+ | `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Divider direction. |
28
+ | `role` | `string` | — | Theme stroke; default from app. |
29
+
30
+ **Type source:** `src/components/divider/divider.type.ts`
31
+
32
+ ## Events (emits)
33
+
34
+ _None._
35
+
36
+ ## Slots
37
+
38
+ _None._
39
+
40
+ ## See also
41
+
42
+ - Source: `src/components/divider`
@@ -4,7 +4,7 @@
4
4
  $divider: sass.fn-naming-prefix("divider");
5
5
 
6
6
  // Property - layer: stroke
7
- $border-color: sass.fn-naming-var("stroke", "border-color");
7
+ $border-color: sass.fn-naming-var("divider", "border-color");
8
8
  $border-width: sass.fn-naming-var("stroke", "width");
9
9
  $transition-duration: sass.fn-naming-var("motion", "duration");
10
10
 
@@ -15,15 +15,12 @@ const appState = inject<AppProviderState>(APP_PROVIDER_STATE_KEY);
15
15
 
16
16
  /// Computed
17
17
  /// ------------------------------------------------------------
18
- const role = computed(() => {
19
- return props.role || appState?.role.value || "";
20
- });
21
-
22
18
  const dividerAttrs = computed(() => {
19
+ const role = props.role || appState?.role.value || "";
23
20
  return {
24
21
  class: [
25
- withPrefix(["layer", "stroke"]),
26
- withPrefix(["role", role.value]),
22
+ withPrefix(["layer", "divider"]),
23
+ withPrefix(["role", role]),
27
24
  withPrefix("divider"),
28
25
  {
29
26
  [props.orientation]: true,
@@ -0,0 +1,68 @@
1
+ # `<t-field>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Text input field. The current implementation only renders `OutlineField` when `variant === 'outline'`. Supports `v-model`, validation message, help text, and many input options.
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-field v-model="text" placeholder="Type…" />
20
+ ```
21
+
22
+ ## Props
23
+
24
+ | Prop | Type | Default | Description |
25
+ | ----------------------- | ------------------ | ------------ | ----------------------------------------------------------------- |
26
+ | `modelValue` | `string` | `""` | Value (`v-model`). |
27
+ | `name` | `string` | — | Input `name`. |
28
+ | `variant` | `FieldVariant` | `"outline"` | Only `outline` is wired in the current UI. |
29
+ | `role` / `shape` | `string` | — | Theme; default from app. |
30
+ | `size` | `FieldSize` | `"standard"` | Field size. |
31
+ | `shadow` | `boolean` | — | Default from app. |
32
+ | `direction` | `AppDirection` | — | Default from app or `left`. |
33
+ | `id` | `string` | — | Element id. |
34
+ | `value` | `string` | — | May mirror model (`OutlineField` uses `value \|\| modelValue`). |
35
+ | `placeholder` | `string` | `""` | Placeholder. |
36
+ | `disabled` / `readonly` | `boolean` | `false` | |
37
+ | `autocomplete` | `string` | — | |
38
+ | `maxLength` | `number \| string` | — | |
39
+ | `tabindex` | `number \| string` | — | |
40
+ | `type` | `FieldType` | `"text"` | `text`, `number`, `email`, `password`, `tel`, `url`, `paragraph`. |
41
+ | `line` / `maxLine` | `number \| string` | `1` / — | Lines (paragraph). |
42
+ | `message` | `string` | `""` | Validation / warning message. |
43
+ | `help` | `string` | `""` | Help hint. |
44
+
45
+ **Type source:** `src/components/field/field.type.ts`
46
+
47
+ ## Events (emits)
48
+
49
+ | Event | Payload | Description |
50
+ | ------------------- | ------------ | ------------- |
51
+ | `update:modelValue` | `string` | Model update. |
52
+ | `focus` | `FocusEvent` | |
53
+ | `blur` | `FocusEvent` | |
54
+ | `input` | `Event` | |
55
+ | `beforeinput` | `Event` | |
56
+
57
+ ## Slots
58
+
59
+ _None_ — content is owned by `OutlineField` (which may expose a default slot in the implementation).
60
+
61
+ ## `v-model`
62
+
63
+ `modelValue` / `update:modelValue`.
64
+
65
+ ## See also
66
+
67
+ - Source: `src/components/field`
68
+ - [outline-field.md](./outline/outline-field.md) — implementation detail when `variant="outline"`
@@ -0,0 +1,44 @@
1
+ # `OutlineField`
2
+
3
+ > **Not** registered by `createToife()` — named import: `import { OutlineField } from "@toife/vue"` or register manually: `app.component("t-outline-field", OutlineField)`.
4
+
5
+ ## Description
6
+
7
+ Outline field implementation (contenteditable or password `<input>`), used internally by `t-field` when `variant === 'outline'`. Import directly if you need it without the `Field` wrapper.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | --------------------------------------------------- |
13
+ | Vue | ^3.5 |
14
+ | Other | Same `FieldProps` / `FieldEmit` as `field.type.ts`. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <script setup lang="ts">
20
+ import { OutlineField } from "@toife/vue";
21
+ </script>
22
+ <template>
23
+ <OutlineField v-model="x" variant="outline" type="text" />
24
+ </template>
25
+ ```
26
+
27
+ ## Props / events
28
+
29
+ Same as `FieldProps` / `FieldEmit` — see [field.md](../field.md) and `field.type.ts`.
30
+
31
+ ## Slots
32
+
33
+ | Slot | Description |
34
+ | --------- | ------------------------------------------------------- |
35
+ | `default` | Extra content after help (see `outline.html` template). |
36
+
37
+ ## Behavior notes
38
+
39
+ - When `type !== 'password'`: contenteditable region with `v-text` and caret handling.
40
+ - When `password`: native `<input type="password">`.
41
+
42
+ ## See also
43
+
44
+ - Source: `src/components/field/outline`
@@ -12,9 +12,9 @@ $field-direction-right: sass.fn-naming-prefix("direction", "right");
12
12
  // Property name
13
13
  $border-radius: sass.fn-naming-var("border-radius");
14
14
  $border-width: sass.fn-naming-var("stroke", "width");
15
- $border-color: sass.fn-naming-var("item", "border-color");
16
- $role-color: sass.fn-naming-var("item", "background-color");
17
- $base-color: sass.fn-naming-var("base", "color");
15
+ $border-color: sass.fn-naming-var("field", "border-color");
16
+ $role-color: sass.fn-naming-var("field", "background-color");
17
+ $app-color: sass.fn-naming-var("app", "color");
18
18
  $line: sass.fn-naming-var("field", "line");
19
19
  $max-line: sass.fn-naming-var("field", "max-line");
20
20
 
@@ -60,8 +60,8 @@ $transition-duration: sass.fn-naming-var("motion", "duration");
60
60
  z-index: 2;
61
61
  min-height: calc(#{$line} * #{$size-height} - 2 * #{$border-width});
62
62
  max-height: calc(#{$max-line} * #{$size-height} - 2 * #{$border-width});
63
- color: rgb(#{$base-color});
64
- caret-color: rgb(#{$base-color});
63
+ color: rgb(#{$app-color});
64
+ caret-color: rgb(#{$app-color});
65
65
  border: none;
66
66
  user-select: all;
67
67
  font-size: #{$size-font-size};
@@ -93,7 +93,7 @@ $transition-duration: sass.fn-naming-var("motion", "duration");
93
93
  }
94
94
 
95
95
  &::placeholder {
96
- color: rgba(#{$base-color}, 0.5);
96
+ color: rgba(#{$app-color}, 0.5);
97
97
  }
98
98
  }
99
99
 
@@ -112,7 +112,7 @@ $transition-duration: sass.fn-naming-var("motion", "duration");
112
112
 
113
113
  // Help
114
114
  .#{$field-help} {
115
- color: rgb(#{$base-color}, 0.75);
115
+ color: rgb(#{$app-color}, 0.75);
116
116
  font-size: 0.8em;
117
117
  line-height: 1.5;
118
118
  transition:
@@ -152,7 +152,7 @@ $transition-duration: sass.fn-naming-var("motion", "duration");
152
152
  .#{$field-input} {
153
153
  &::before {
154
154
  content: attr(placeholder);
155
- color: rgba(#{$base-color}, 0.5);
155
+ color: rgba(#{$app-color}, 0.5);
156
156
  transition: color #{$transition-duration} ease;
157
157
  position: absolute;
158
158
  height: calc(#{$size-height} - #{$border-width} * 2);
@@ -38,7 +38,7 @@ const content = computed(() => {
38
38
  const fieldAttrs = computed(() => {
39
39
  return {
40
40
  class: [
41
- withPrefix(["layer", "item"]),
41
+ withPrefix(["layer", "field"]),
42
42
  withPrefix(["role", props.role || ""]),
43
43
  withPrefix(["shape", props.shape || ""]),
44
44
  withPrefix("field"),
@@ -84,7 +84,7 @@ const fieldMessageAttrs = computed(() => ({
84
84
  }));
85
85
 
86
86
  const fieldHelpAttrs = computed(() => ({
87
- class: [withPrefix("field-help"), withPrefix(["layer", "surface"]), withPrefix(["role", "mode"])],
87
+ class: [withPrefix("field-help")],
88
88
  }));
89
89
 
90
90
  /// Methods
@@ -0,0 +1,41 @@
1
+ # `<t-form-group>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Groups controls in a horizontal or vertical flex layout; used by `Action` to stack button rows.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ----- |
13
+ | Vue | ^3.5 |
14
+ | Other | None. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-form-group orientation="vertical">
20
+ <t-button>A</t-button>
21
+ <t-button>B</t-button>
22
+ </t-form-group>
23
+ ```
24
+
25
+ ## Props
26
+
27
+ | Prop | Type | Default | Description |
28
+ | ------------- | ---------------------------- | -------------- | ------------ |
29
+ | `orientation` | `"horizontal" \| "vertical"` | `"horizontal"` | Layout axis. |
30
+
31
+ **Type source:** `src/components/form-group/form-group.type.ts`
32
+
33
+ ## Slots
34
+
35
+ | Slot | Description |
36
+ | --------- | --------------- |
37
+ | `default` | Child controls. |
38
+
39
+ ## See also
40
+
41
+ - Source: `src/components/form-group`
@@ -0,0 +1,42 @@
1
+ # `<t-gesture-indicator>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Small visual stroke hint for swipe placement; usually rendered inside `Modal` when swipe-to-dismiss is enabled.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ------------------- |
13
+ | Vue | ^3.5 |
14
+ | Other | `t-app` for `role`. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <!-- Rarely used standalone; Modal renders it when gesture + indicator -->
20
+ <t-gesture-indicator placement="bottom" />
21
+ ```
22
+
23
+ ## Props
24
+
25
+ | Prop | Type | Default | Description |
26
+ | ----------- | -------- | ---------- | --------------------------------------- |
27
+ | `placement` | `string` | `"bottom"` | Placement class (e.g. `bottom`, `top`). |
28
+
29
+ **Type source:** `src/components/gesture-indicator/gesture-indicator.type.ts`
30
+
31
+ ## Events (emits)
32
+
33
+ _None._
34
+
35
+ ## Slots
36
+
37
+ _None_ — decorative empty element.
38
+
39
+ ## See also
40
+
41
+ - Source: `src/components/gesture-indicator`
42
+ - [modal.md](../../modal/modal.md)
@@ -3,8 +3,8 @@
3
3
  // Class name
4
4
  $gesture-indicator: sass.fn-naming-prefix("gesture-indicator");
5
5
 
6
- // Property name - layer: stroke
7
- $border-color: sass.fn-naming-var("stroke", "border-color");
6
+ // Property name - layer: gesture-indicator
7
+ $border-color: sass.fn-naming-var("gesture-indicator", "border-color");
8
8
  $transition-duration: sass.fn-naming-var("motion", "duration");
9
9
 
10
10
  .#{$gesture-indicator} {
@@ -15,15 +15,12 @@ const props = withDefaults(defineProps<GestureIndicatorProps>(), {
15
15
 
16
16
  /// Computed
17
17
  /// ------------------------------------------------------------
18
- const role = computed(() => {
19
- return appState?.role.value || "";
20
- });
21
-
22
18
  const gestureIndicatorAttrs = computed(() => {
19
+ const role = appState?.role.value || "";
23
20
  return {
24
21
  class: [
25
- withPrefix(["layer", "stroke"]),
26
- withPrefix(["role", role.value]),
22
+ withPrefix(["layer", "gesture-indicator"]),
23
+ withPrefix(["role", role]),
27
24
  withPrefix("gesture-indicator"),
28
25
  props.placement,
29
26
  ],
@@ -0,0 +1,41 @@
1
+ # `<t-image>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ `<img>` with fallback to `defaultSrc` on load error.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ----- |
13
+ | Vue | ^3.5 |
14
+ | Other | None. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-image src="/a.webp" default-src="/placeholder.png" />
20
+ ```
21
+
22
+ ## Props
23
+
24
+ | Prop | Type | Default | Description |
25
+ | ------------ | -------- | ------- | -------------------------------------- |
26
+ | `src` | `string` | — | Primary image URL (assigned on mount). |
27
+ | `defaultSrc` | `string` | — | Fallback URL on `@error`. |
28
+
29
+ **Type source:** `src/components/image/image.type.ts`
30
+
31
+ ## Events (emits)
32
+
33
+ _None declared_ — internal `@error` handler.
34
+
35
+ ## Slots
36
+
37
+ _None._
38
+
39
+ ## See also
40
+
41
+ - Source: `src/components/image`
@@ -0,0 +1,65 @@
1
+ # `<t-modal>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Modal content inside `Present`, integrated with `@toife/gesture` for swipe-to-dismiss along `placement` (except `center`). Optional fullscreen and gesture indicator.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ------------------------------------ |
13
+ | Vue | ^3.5 |
14
+ | Other | `@toife/gesture`; `t-app` for theme. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-modal :visible="open" placement="bottom" @close="() => (open = false)">
20
+ <p>Content</p>
21
+ </t-modal>
22
+ ```
23
+
24
+ ## Props
25
+
26
+ | Prop | Type | Default | Description |
27
+ | ----------------- | -------------------------------------- | ----------- | -------------------------------------------- |
28
+ | `visible` | `boolean` | `false` | Visibility. |
29
+ | `placement` | `PresentPlacement` | `"bottom"` | Position + gesture direction. |
30
+ | `backdrop` | `"display" \| "none" \| "transparent"` | `"display"` | Backdrop. |
31
+ | `keepalive` | `boolean` | `true` | Keep DOM when closed (`Present`). |
32
+ | `gesture` | `boolean` | `true` | Enable swipe to close. |
33
+ | `fullscreen` | `boolean` | `false` | Full-screen panel. |
34
+ | `indicator` | `boolean` | `true` | Show `GestureIndicator` (when not `center`). |
35
+ | `duration` | `number` | `200` | `Present` transition (ms). |
36
+ | `bounce` | `number \| string` | `0` | `Present` bounce. |
37
+ | `role` / `shape` | `string` | — | Theme. |
38
+ | `class` / `style` | `unknown` | — | Passed to `Present` / root. |
39
+
40
+ **Type source:** `src/components/modal/modal.type.ts`
41
+
42
+ ## Events (emits)
43
+
44
+ | Event | Payload | Description |
45
+ | ------- | --------------- | ----------------------------------------------------- |
46
+ | `close` | `type?: string` | From `Present` or gesture (`backdrop`, `gesture`, …). |
47
+
48
+ ## Slots
49
+
50
+ | Slot | Description |
51
+ | --------- | ----------- |
52
+ | `default` | Modal body. |
53
+
54
+ ## Expose
55
+
56
+ Nothing public (internal refs to `Present` / gesture).
57
+
58
+ ## Accessibility (a11y)
59
+
60
+ Add focus trap / `aria-modal` at the app layer if you need strict WCAG compliance.
61
+
62
+ ## See also
63
+
64
+ - Source: `src/components/modal`
65
+ - [present.md](../../present/present.md)
@@ -3,8 +3,8 @@
3
3
  // Class name
4
4
  $modal: sass.fn-naming-prefix("modal");
5
5
 
6
- // Property name - layer: surface
7
- $background-color: sass.fn-naming-var("surface", "background-color");
6
+ // Property name - layer: modal
7
+ $background-color: sass.fn-naming-var("modal", "background-color");
8
8
  $viewport-width: sass.fn-naming-var("viewport", "width");
9
9
  $viewport-max-width: sass.fn-naming-var("viewport", "max-width");
10
10
  $viewport-height: sass.fn-naming-var("viewport", "height");
@@ -47,7 +47,7 @@ const modalAttrs = computed(() => {
47
47
 
48
48
  return {
49
49
  class: [
50
- withPrefix(["layer", "surface"]),
50
+ withPrefix(["layer", "modal"]),
51
51
  withPrefix(["role", role]),
52
52
  withPrefix(["shape", shape]),
53
53
  withPrefix("modal"),
@@ -0,0 +1,39 @@
1
+ # `<t-page>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Simple page wrapper with the themed `page` class.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ----- | ----- |
13
+ | Vue | ^3.5 |
14
+ | Other | None. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-app>
20
+ <t-page>
21
+ <t-toolbar />
22
+ <t-container>Content</t-container>
23
+ </t-page>
24
+ </t-app>
25
+ ```
26
+
27
+ ## Props
28
+
29
+ _None._
30
+
31
+ ## Slots
32
+
33
+ | Slot | Description |
34
+ | --------- | --------------- |
35
+ | `default` | Page structure. |
36
+
37
+ ## See also
38
+
39
+ - Source: `src/components/page`
@@ -2,13 +2,8 @@
2
2
  <style lang="scss" src="./page.scss" scoped></style>
3
3
  <script lang="ts" setup>
4
4
  import { withPrefix } from "@/utils";
5
- import { computed } from "vue";
6
5
 
7
- /// Computed
8
- /// ------------------------------------------------------------
9
- const pageAttrs = computed(() => {
10
- return {
11
- class: [withPrefix("page")],
12
- };
13
- });
6
+ const pageAttrs = {
7
+ class: [withPrefix("page")],
8
+ } as const;
14
9
  </script>