@toife/vue 3.0.7 → 3.1.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 (63) hide show
  1. package/README.md +4 -2
  2. package/package.json +4 -7
  3. package/src/components/action/action.scss +1 -1
  4. package/src/components/app/app.scss +1 -1
  5. package/src/components/avatar/avatar.scss +1 -1
  6. package/src/components/button/button.scss +1 -1
  7. package/src/components/cable/cable.scss +1 -1
  8. package/src/components/card/card/card.scss +1 -1
  9. package/src/components/card/card-body/card-body.scss +1 -1
  10. package/src/components/card/card-footer/card-footer.scss +1 -1
  11. package/src/components/card/card-header/card-header.scss +1 -1
  12. package/src/components/checkbox/checkbox.scss +1 -1
  13. package/src/components/collapse/collapse.scss +1 -1
  14. package/src/components/container/container.scss +1 -1
  15. package/src/components/decision-modal/decision-modal.scss +6 -1
  16. package/src/components/divider/divider.scss +1 -1
  17. package/src/components/dropdown/dropdown.scss +4 -10
  18. package/src/components/field/outline/outline.html +13 -13
  19. package/src/components/field/outline/outline.scss +97 -36
  20. package/src/components/field/outline/outline.vue +59 -16
  21. package/src/components/form-group/form-group.scss +1 -1
  22. package/src/components/gesture-indicator/gesture-indicator.scss +1 -1
  23. package/src/components/index.ts +1 -0
  24. package/src/components/layout/cell/cell.html +1 -0
  25. package/src/components/layout/cell/cell.md +47 -0
  26. package/src/components/layout/cell/cell.scss +54 -0
  27. package/src/components/layout/cell/cell.type.ts +19 -0
  28. package/src/components/layout/cell/cell.vue +35 -0
  29. package/src/components/layout/cell/index.ts +2 -0
  30. package/src/components/layout/flex/flex.html +1 -0
  31. package/src/components/layout/flex/flex.scss +59 -0
  32. package/src/components/layout/flex/flex.type.ts +13 -0
  33. package/src/components/layout/flex/flex.vue +34 -0
  34. package/src/components/layout/flex/index.ts +2 -0
  35. package/src/components/layout/grid/grid.html +1 -0
  36. package/src/components/layout/grid/grid.md +50 -0
  37. package/src/components/layout/grid/grid.scss +53 -0
  38. package/src/components/layout/grid/grid.type.ts +12 -0
  39. package/src/components/layout/grid/grid.vue +32 -0
  40. package/src/components/layout/grid/index.ts +2 -0
  41. package/src/components/layout/index.ts +3 -0
  42. package/src/components/modal/modal.scss +1 -1
  43. package/src/components/page/page.scss +1 -1
  44. package/src/components/present/present.scss +1 -1
  45. package/src/components/radio/radio/radio.scss +1 -1
  46. package/src/components/radio/radio-group/radio-group.scss +1 -1
  47. package/src/components/refresher/refresher.scss +1 -1
  48. package/src/components/route/route-navigator/route-navigator.scss +5 -5
  49. package/src/components/route/route-navigator/route-navigator.vue +26 -20
  50. package/src/components/segmented-field/segmented-field.scss +1 -1
  51. package/src/components/select/index.ts +1 -1
  52. package/src/components/select/select.html +9 -6
  53. package/src/components/select/select.scss +82 -11
  54. package/src/components/select/select.type.ts +14 -1
  55. package/src/components/select/select.vue +38 -8
  56. package/src/components/skeleton/skeleton.scss +1 -1
  57. package/src/components/switch/switch.scss +1 -1
  58. package/src/components/tabs/tabs/tabs.scss +6 -6
  59. package/src/components/toast/toast/toast.scss +1 -1
  60. package/src/components/toast/toast-content/toast-content.scss +1 -1
  61. package/src/components/toolbar/toolbar.scss +1 -1
  62. package/src/factory.ts +6 -0
  63. package/src/utils/style/index.ts +1 -1
@@ -0,0 +1,47 @@
1
+ # `<t-grid-item>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ Cell inside `<t-grid>`. Placement uses `grid-column` / `grid-row` via props or raw CSS strings.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ------ | ---------------------------------------------- |
13
+ | Vue | ^3.5 |
14
+ | Parent | `<t-grid>` (or any `display: grid` container). |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-grid :columns="3">
20
+ <t-grid-item :column-span="2">Wide</t-grid-item>
21
+ <t-grid-item>Narrow</t-grid-item>
22
+ </t-grid>
23
+ ```
24
+
25
+ ## Props
26
+
27
+ | Prop | Type | Description |
28
+ | ------------- | -------- | --------------------------------------------- |
29
+ | `column` | `string` | Raw `grid-column` (overrides span/start/end). |
30
+ | `row` | `string` | Raw `grid-row`. |
31
+ | `columnSpan` | `number` | `span n` on the column axis. |
32
+ | `rowSpan` | `number` | `span n` on the row axis. |
33
+ | `columnStart` | `number` | Grid line start (column). |
34
+ | `columnEnd` | `number` | Grid line end (column). |
35
+ | `rowStart` | `number` | Grid line start (row). |
36
+ | `rowEnd` | `number` | Grid line end (row). |
37
+
38
+ ## Slots
39
+
40
+ | Slot | Description |
41
+ | --------- | ------------- |
42
+ | `default` | Cell content. |
43
+
44
+ ## See also
45
+
46
+ - Source: `src/components/grid/grid-item`
47
+ - `<t-grid>`
@@ -0,0 +1,54 @@
1
+ @use "@toife/sass-layer" as sass;
2
+ @use "sass:map";
3
+ @use "sass:list";
4
+
5
+ // Class name
6
+ $cell: sass.fn-naming-prefix("cell");
7
+
8
+ // Base tokens (breakpoint "")
9
+ $cell-row: sass.fn-naming-var("cell", "row");
10
+ $cell-column: sass.fn-naming-var("cell", "column");
11
+ $cell-justify: sass.fn-naming-var("cell", "justify");
12
+ $cell-align: sass.fn-naming-var("cell", "align");
13
+ $cell-grow: sass.fn-naming-var("cell", "grow");
14
+ $cell-shrink: sass.fn-naming-var("cell", "shrink");
15
+ $cell-basis: sass.fn-naming-var("cell", "basis");
16
+ $cell-order: sass.fn-naming-var("cell", "order");
17
+
18
+ .#{$cell} {
19
+ display: grid;
20
+ box-sizing: border-box;
21
+ min-width: 0;
22
+ grid-column: #{$cell-column};
23
+ grid-row: #{$cell-row};
24
+ justify-self: #{$cell-justify};
25
+ align-self: #{$cell-align};
26
+ flex-grow: #{$cell-grow};
27
+ flex-shrink: #{$cell-shrink};
28
+ flex-basis: #{$cell-basis};
29
+ order: #{$cell-order};
30
+
31
+ $bp-names: map.keys(sass.$breakpoints);
32
+ $bp-count: list.length($bp-names);
33
+
34
+ @for $i from 1 through $bp-count {
35
+ $bp-name: list.nth($bp-names, $i);
36
+ $bp-min: map.get(sass.$breakpoints, $bp-name);
37
+
38
+ @media (min-width: $bp-min) {
39
+ grid-column: #{sass.fn-naming-cascade-dvar(("cell", "column"), $bp-names, $i, $cell-column)};
40
+ grid-row: #{sass.fn-naming-cascade-dvar(("cell", "row"), $bp-names, $i, $cell-row)};
41
+ justify-self: #{sass.fn-naming-cascade-dvar(
42
+ ("cell", "justify"),
43
+ $bp-names,
44
+ $i,
45
+ $cell-justify
46
+ )};
47
+ align-self: #{sass.fn-naming-cascade-dvar(("cell", "align"), $bp-names, $i, $cell-align)};
48
+ flex-grow: #{sass.fn-naming-cascade-dvar(("cell", "grow"), $bp-names, $i, $cell-grow)};
49
+ flex-shrink: #{sass.fn-naming-cascade-dvar(("cell", "shrink"), $bp-names, $i, $cell-shrink)};
50
+ flex-basis: #{sass.fn-naming-cascade-dvar(("cell", "basis"), $bp-names, $i, $cell-basis)};
51
+ order: #{sass.fn-naming-cascade-dvar(("cell", "order"), $bp-names, $i, $cell-order)};
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,19 @@
1
+ export type CellJustify = "start" | "end" | "center" | "stretch";
2
+ export type CellAlign = "start" | "end" | "center" | "stretch";
3
+
4
+ export type CellOption = {
5
+ breakpoint?: string;
6
+ row?: number;
7
+ column?: number;
8
+ justify?: CellJustify;
9
+ align?: CellAlign;
10
+ grow?: number;
11
+ shrink?: number;
12
+ basis?: string;
13
+ order?: number;
14
+ };
15
+
16
+ // Type definitions
17
+ export type CellProps = {
18
+ options?: CellOption[];
19
+ };
@@ -0,0 +1,35 @@
1
+ <style lang="scss" src="./cell.scss" scoped></style>
2
+ <template src="./cell.html"></template>
3
+ <script lang="ts" setup>
4
+ import { computed } from "vue";
5
+ import { withPrefix, property } from "../../../utils";
6
+ import type { CellProps } from "./cell.type";
7
+
8
+ // Component setup (props, emits, injects)
9
+ // ----------------------------------------------------------------------------
10
+ const props = withDefaults(defineProps<CellProps>(), {
11
+ options: () => [],
12
+ });
13
+
14
+ // Computed properties
15
+ // ----------------------------------------------------------------------------
16
+ const cellAttrs = computed(() => {
17
+ const style = props.options.map((option) => {
18
+ return {
19
+ [property(["cell", "row", option?.breakpoint || ""])]: option.row,
20
+ [property(["cell", "column", option?.breakpoint || ""])]: option.column,
21
+ [property(["cell", "justify", option?.breakpoint || ""])]: option.justify,
22
+ [property(["cell", "align", option?.breakpoint || ""])]: option.align,
23
+ [property(["cell", "flex-grow", option?.breakpoint || ""])]: option.grow,
24
+ [property(["cell", "flex-shrink", option?.breakpoint || ""])]: option.shrink,
25
+ [property(["cell", "flex-basis", option?.breakpoint || ""])]: option.basis,
26
+ [property(["cell", "order", option?.breakpoint || ""])]: option.order,
27
+ };
28
+ });
29
+
30
+ return {
31
+ class: [withPrefix("cell")],
32
+ style,
33
+ };
34
+ });
35
+ </script>
@@ -0,0 +1,2 @@
1
+ export { default as Cell } from "./cell.vue";
2
+ export * from "./cell.type";
@@ -0,0 +1 @@
1
+ <div v-bind="flexAttrs"><slot /></div>
@@ -0,0 +1,59 @@
1
+ @use "@toife/sass-layer" as sass;
2
+ @use "sass:map";
3
+ @use "sass:list";
4
+
5
+ /// Class name
6
+ $flex: sass.fn-naming-prefix("flex");
7
+
8
+ /// Base tokens (breakpoint "")
9
+ $flex-gap: sass.fn-naming-var("flex", "gap");
10
+ $flex-direction: sass.fn-naming-var("flex", "direction");
11
+ $flex-wrap: sass.fn-naming-var("flex", "wrap");
12
+ $flex-justify: sass.fn-naming-var("flex", "justify");
13
+ $flex-align: sass.fn-naming-var("flex", "align");
14
+ $flex-align-content: sass.fn-naming-var("flex", "align-content");
15
+
16
+ .#{$flex} {
17
+ display: flex;
18
+ box-sizing: border-box;
19
+ width: 100%;
20
+ min-height: 0;
21
+ gap: #{$flex-gap};
22
+ flex-direction: #{$flex-direction};
23
+ flex-wrap: #{$flex-wrap};
24
+ justify-content: #{$flex-justify};
25
+ align-items: #{$flex-align};
26
+ align-content: #{$flex-align-content};
27
+
28
+ $bp-names: map.keys(sass.$breakpoints);
29
+ $bp-count: list.length($bp-names);
30
+
31
+ @for $i from 1 through $bp-count {
32
+ $bp-name: list.nth($bp-names, $i);
33
+ $bp-min: map.get(sass.$breakpoints, $bp-name);
34
+
35
+ @media (min-width: $bp-min) {
36
+ gap: #{sass.fn-naming-cascade-dvar(("flex", "gap"), $bp-names, $i, $flex-gap)};
37
+ flex-direction: #{sass.fn-naming-cascade-dvar(
38
+ ("flex", "direction"),
39
+ $bp-names,
40
+ $i,
41
+ $flex-direction
42
+ )};
43
+ flex-wrap: #{sass.fn-naming-cascade-dvar(("flex", "wrap"), $bp-names, $i, $flex-wrap)};
44
+ justify-content: #{sass.fn-naming-cascade-dvar(
45
+ ("flex", "justify"),
46
+ $bp-names,
47
+ $i,
48
+ $flex-justify
49
+ )};
50
+ align-items: #{sass.fn-naming-cascade-dvar(("flex", "align"), $bp-names, $i, $flex-align)};
51
+ align-content: #{sass.fn-naming-cascade-dvar(
52
+ ("flex", "align-content"),
53
+ $bp-names,
54
+ $i,
55
+ $flex-align-content
56
+ )};
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,13 @@
1
+ export type FlexOption = {
2
+ breakpoint?: string;
3
+ gap?: string | number;
4
+ direction?: string;
5
+ wrap?: string;
6
+ justify?: string;
7
+ align?: string;
8
+ alignContent?: string;
9
+ };
10
+
11
+ export type FlexProps = {
12
+ options?: FlexOption[];
13
+ };
@@ -0,0 +1,34 @@
1
+ <style lang="scss" src="./flex.scss" scoped></style>
2
+ <template src="./flex.html"></template>
3
+ <script lang="ts" setup>
4
+ import { computed } from "vue";
5
+ import { withPrefix, property } from "../../../utils";
6
+ import type { FlexProps } from "./flex.type";
7
+
8
+ // Component setup (props, emits, injects)
9
+ // ----------------------------------------------------------------------------
10
+ const props = withDefaults(defineProps<FlexProps>(), {
11
+ options: () => [],
12
+ });
13
+
14
+ // Computed properties
15
+ // ----------------------------------------------------------------------------
16
+ const flexAttrs = computed(() => {
17
+ const style = props.options.map((option) => {
18
+ return {
19
+ [property(["flex", "gap", option?.breakpoint || ""])]:
20
+ typeof option.gap === "number" ? `${option.gap}px` : option.gap,
21
+ [property(["flex", "direction", option?.breakpoint || ""])]: option.direction,
22
+ [property(["flex", "wrap", option?.breakpoint || ""])]: option.wrap,
23
+ [property(["flex", "justify", option?.breakpoint || ""])]: option.justify,
24
+ [property(["flex", "align", option?.breakpoint || ""])]: option.align,
25
+ [property(["flex", "align-content", option?.breakpoint || ""])]: option.alignContent,
26
+ };
27
+ });
28
+
29
+ return {
30
+ class: [withPrefix("flex")],
31
+ style,
32
+ };
33
+ });
34
+ </script>
@@ -0,0 +1,2 @@
1
+ export { default as Flex } from "./flex.vue";
2
+ export * from "./flex.type";
@@ -0,0 +1 @@
1
+ <div v-bind="gridAttrs"><slot /></div>
@@ -0,0 +1,50 @@
1
+ # `<t-grid>`
2
+
3
+ > Default prefix is `t-` — change via `createToife({ prefix: "..." })`.
4
+
5
+ ## Description
6
+
7
+ CSS Grid wrapper with theme-based default gap. Use with `<t-grid-item>` for placement.
8
+
9
+ ## Requirements / dependencies
10
+
11
+ | Item | Notes |
12
+ | ------------------- | ------------------------------- |
13
+ | Vue | ^3.5 |
14
+ | `@toife/sass-layer` | Theme tokens for default `gap`. |
15
+
16
+ ## Basic usage
17
+
18
+ ```vue
19
+ <t-grid :columns="3">
20
+ <t-grid-item>One</t-grid-item>
21
+ <t-grid-item>Two</t-grid-item>
22
+ <t-grid-item>Three</t-grid-item>
23
+ </t-grid>
24
+ ```
25
+
26
+ ## Props
27
+
28
+ | Prop | Type | Default | Description |
29
+ | ---------------- | ------------------ | ------- | --------------------------------------------------------------- |
30
+ | `columns` | `number \| string` | `1` | Column count (`repeat(n, 1fr)`) or raw `grid-template-columns`. |
31
+ | `rows` | `number \| string` | — | `grid-template-rows`. |
32
+ | `gap` | `string` | — | Sets `gap` (overrides SCSS default when non-empty). |
33
+ | `columnGap` | `string` | — | `column-gap`. |
34
+ | `rowGap` | `string` | — | `row-gap`. |
35
+ | `alignItems` | `string` | — | `align-items`. |
36
+ | `justifyItems` | `string` | — | `justify-items`. |
37
+ | `alignContent` | `string` | — | `align-content`. |
38
+ | `justifyContent` | `string` | — | `justify-content`. |
39
+ | `autoFlow` | `string` | — | `grid-auto-flow`. |
40
+
41
+ ## Slots
42
+
43
+ | Slot | Description |
44
+ | --------- | ----------- |
45
+ | `default` | Grid cells. |
46
+
47
+ ## See also
48
+
49
+ - Source: `src/components/grid/grid`
50
+ - `<t-grid-item>`
@@ -0,0 +1,53 @@
1
+ @use "@toife/sass-layer" as sass;
2
+ @use "sass:map";
3
+ @use "sass:list";
4
+
5
+ /// Class name
6
+ $grid: sass.fn-naming-prefix("grid");
7
+
8
+ /// Base tokens (breakpoint "")
9
+ $grid-gap: sass.fn-naming-var("grid", "gap");
10
+ $grid-columns: sass.fn-naming-var("grid", "columns");
11
+ $grid-rows: sass.fn-naming-var("grid", "rows");
12
+ $grid-auto-flow: sass.fn-naming-var("grid", "auto-flow");
13
+
14
+ .#{$grid} {
15
+ display: grid;
16
+ box-sizing: border-box;
17
+ width: 100%;
18
+ min-height: 0;
19
+ gap: #{$grid-gap};
20
+ grid-template-columns: #{$grid-columns};
21
+ grid-template-rows: #{$grid-rows};
22
+ grid-auto-flow: #{$grid-auto-flow};
23
+
24
+ $bp-names: map.keys(sass.$breakpoints);
25
+ $bp-count: list.length($bp-names);
26
+
27
+ @for $i from 1 through $bp-count {
28
+ $bp-name: list.nth($bp-names, $i);
29
+ $bp-min: map.get(sass.$breakpoints, $bp-name);
30
+
31
+ @media (min-width: $bp-min) {
32
+ gap: #{sass.fn-naming-cascade-dvar(("grid", "gap"), $bp-names, $i, $grid-gap)};
33
+ grid-template-columns: #{sass.fn-naming-cascade-dvar(
34
+ ("grid", "columns"),
35
+ $bp-names,
36
+ $i,
37
+ $grid-columns
38
+ )};
39
+ grid-template-rows: #{sass.fn-naming-cascade-dvar(
40
+ ("grid", "rows"),
41
+ $bp-names,
42
+ $i,
43
+ $grid-rows
44
+ )};
45
+ grid-auto-flow: #{sass.fn-naming-cascade-dvar(
46
+ ("grid", "auto-flow"),
47
+ $bp-names,
48
+ $i,
49
+ $grid-auto-flow
50
+ )};
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,12 @@
1
+ export type GridOption = {
2
+ breakpoint?: string;
3
+ gap?: string;
4
+ columns?: string;
5
+ rows?: string;
6
+ autoFlow?: string;
7
+ };
8
+
9
+ // Type definitions
10
+ export type GridProps = {
11
+ options?: GridOption[];
12
+ };
@@ -0,0 +1,32 @@
1
+ <style lang="scss" src="./grid.scss" scoped></style>
2
+ <template src="./grid.html"></template>
3
+ <script lang="ts" setup>
4
+ import { computed } from "vue";
5
+ import { withPrefix, property } from "../../../utils";
6
+ import type { GridProps } from "./grid.type";
7
+
8
+ // Component setup (props, emits, injects)
9
+ // ----------------------------------------------------------------------------
10
+ const props = withDefaults(defineProps<GridProps>(), {
11
+ options: () => [],
12
+ });
13
+
14
+ // Computed properties
15
+ // ----------------------------------------------------------------------------
16
+ const gridAttrs = computed(() => {
17
+ const style = props.options.map((option) => {
18
+ return {
19
+ [property(["grid", "gap", option?.breakpoint || ""])]:
20
+ typeof option.gap === "number" ? `${option.gap}px` : option.gap,
21
+ [property(["grid", "columns", option?.breakpoint || ""])]: option.columns,
22
+ [property(["grid", "rows", option?.breakpoint || ""])]: option.rows,
23
+ [property(["grid", "auto-flow", option?.breakpoint || ""])]: option.autoFlow,
24
+ };
25
+ });
26
+
27
+ return {
28
+ class: [withPrefix("grid")],
29
+ style,
30
+ };
31
+ });
32
+ </script>
@@ -0,0 +1,2 @@
1
+ export { default as Grid } from "./grid.vue";
2
+ export * from "./grid.type";
@@ -0,0 +1,3 @@
1
+ export * from "./grid";
2
+ export * from "./flex";
3
+ export * from "./cell";
@@ -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
  $modal: sass.fn-naming-prefix("modal");
@@ -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
  $page: sass.fn-naming-prefix("page");
@@ -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
  $present: sass.fn-naming-prefix("present");
@@ -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
  $radio: sass.fn-naming-prefix("radio");
@@ -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,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>