@fastkit/vui 1.0.0 → 1.1.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastkit/vui",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "A simple, extensible UI kit for Vue applications.",
5
5
  "keywords": [
6
6
  "fastkit",
@@ -44,32 +44,36 @@
44
44
  "src"
45
45
  ],
46
46
  "dependencies": {
47
- "@fastkit/dom": "^0.2.6",
48
- "@fastkit/color-scheme": "^2.0.10",
49
- "@fastkit/helpers": "^0.14.5",
50
- "@fastkit/media-match": "^2.0.7",
51
- "@fastkit/icon-font": "^2.0.7",
52
- "@fastkit/rules": "^0.14.7",
47
+ "@fastkit/color-scheme": "^2.1.0",
48
+ "@fastkit/color-scheme-gen": "^1.1.0",
49
+ "@fastkit/dom": "^0.3.0",
50
+ "@fastkit/helpers": "^0.15.0",
51
+ "@fastkit/media-match": "^2.1.0",
52
+ "@fastkit/media-match-gen": "^1.1.0",
53
+ "@fastkit/tiny-logger": "^0.15.0",
54
+ "@fastkit/rules": "^0.15.0",
55
+ "@fastkit/vue-body-scroll-lock": "^0.3.0",
56
+ "@fastkit/vue-app-layout": "^0.17.0",
57
+ "@fastkit/vue-action": "^0.4.0",
58
+ "@fastkit/vue-color-scheme": "^0.16.0",
59
+ "@fastkit/vue-click-outside": "^0.3.0",
60
+ "@fastkit/vue-form-control": "^0.22.0",
61
+ "@fastkit/vue-loading": "^0.16.0",
62
+ "@fastkit/vue-keyboard": "^0.3.0",
63
+ "@fastkit/vue-disabled-reason": "^0.1.0",
64
+ "@fastkit/vue-location": "^0.5.0",
65
+ "@fastkit/vue-resize": "^0.3.0",
66
+ "@fastkit/vue-media-match": "^0.15.0",
67
+ "@fastkit/vue-scroller": "^0.16.0",
68
+ "@fastkit/vue-stack": "^0.18.0",
69
+ "@fastkit/icon-font": "^2.1.0",
53
70
  "@fastkit/stylebase": "^0.13.1",
54
- "@fastkit/color-scheme-gen": "^1.0.0",
55
- "@fastkit/vue-action": "^0.3.20",
56
- "@fastkit/media-match-gen": "^1.0.0",
57
- "@fastkit/vue-app-layout": "^0.16.3",
58
- "@fastkit/tiny-logger": "^0.14.5",
59
- "@fastkit/vue-body-scroll-lock": "^0.2.14",
60
- "@fastkit/vue-click-outside": "^0.2.13",
61
- "@fastkit/vue-color-scheme": "^0.15.16",
62
- "@fastkit/vue-disabled-reason": "^0.0.1",
63
- "@fastkit/vue-form-control": "^0.21.1",
64
- "@fastkit/vue-loading": "^0.15.16",
65
- "@fastkit/vue-location": "^0.4.3",
66
- "@fastkit/vue-keyboard": "^0.2.5",
67
- "@fastkit/vue-media-match": "^0.14.10",
68
- "@fastkit/vue-scroller": "^0.15.13",
69
- "@fastkit/vue-resize": "^0.2.13",
70
- "@fastkit/vue-utils": "^0.15.13",
71
- "@fastkit/vue-transitions": "^0.2.14",
72
- "@fastkit/vue-stack": "^0.17.4"
71
+ "@fastkit/vue-transitions": "^0.3.0",
72
+ "@fastkit/vue-utils": "^0.16.0"
73
+ },
74
+ "devDependencies": {
75
+ "vue": "^3.5.21",
76
+ "vue-router": "^4.5.1"
73
77
  },
74
78
  "peerDependencies": {
75
79
  "vue": "^3.4.0",
@@ -2,6 +2,7 @@ import './VCheckable.scss';
2
2
  import { computed, defineComponent } from 'vue';
3
3
  import { defineSlots } from '@fastkit/vue-utils';
4
4
  import { FormNodeErrorSlotsSource } from '@fastkit/vue-form-control';
5
+ import { DISABLED_REASON_CONTAINER_BIND } from '@fastkit/vue-disabled-reason';
5
6
  import { useVuiColorProvider } from '../../injections';
6
7
 
7
8
  export const CHECKABLE_SLOTS = defineSlots<
@@ -44,7 +45,9 @@ export const VCheckable = defineComponent({
44
45
  ]);
45
46
 
46
47
  return () => (
47
- <label class={['v-checkable', classes.value]}>
48
+ <label
49
+ class={['v-checkable', classes.value]}
50
+ {...DISABLED_REASON_CONTAINER_BIND}>
48
51
  <span class="v-checkable__faux">
49
52
  {ctx.slots.input?.()}
50
53
  {ctx.slots.icon ? (
@@ -9,6 +9,7 @@ import {
9
9
  defineSlots,
10
10
  DefineSlotsType,
11
11
  } from '@fastkit/vue-utils';
12
+ import { DISABLED_REASON_CONTAINER_BIND } from '@fastkit/vue-disabled-reason';
12
13
  import {
13
14
  createControlProps,
14
15
  useControl,
@@ -146,7 +147,8 @@ export const VControlField = defineComponent({
146
147
  class={classes.value}
147
148
  onClick={handleClick}
148
149
  // tabindex={this.computedTabindex}
149
- ref={hostElRef}>
150
+ ref={hostElRef}
151
+ {...DISABLED_REASON_CONTAINER_BIND}>
150
152
  {renderAdornment('start')}
151
153
  <div class="v-control-field__body">{ctx.slots.default?.()}</div>
152
154
  {renderAdornment('end')}
@@ -1,7 +1,20 @@
1
1
  import './VDisabledReason.scss';
2
- import { type PropType } from 'vue';
3
- import { defineDisabledReasonComponent } from '@fastkit/vue-disabled-reason';
2
+ import {
3
+ type PropType,
4
+ type ExtractPublicPropTypes,
5
+ type VNodeChild,
6
+ } from 'vue';
7
+ import {
8
+ defineDisabledReasonComponent,
9
+ DISABLED_REASON_BASE_PROPS,
10
+ } from '@fastkit/vue-disabled-reason';
4
11
  import { createMenuProps } from '@fastkit/vue-stack';
12
+ import { createPropsOptions } from '@fastkit/vue-utils';
13
+ import {
14
+ registerActionableAttrsResolver,
15
+ registerActionableRenderWrapper,
16
+ type ActionableCustomProps as _ActionableCustomProps,
17
+ } from '@fastkit/vue-action';
5
18
  import { VTooltip } from '../VTooltip';
6
19
 
7
20
  const menuProps = createMenuProps();
@@ -13,10 +26,9 @@ const menuProps = createMenuProps();
13
26
  */
14
27
  export type DisabledReasonType = 'tooltip';
15
28
 
16
- export const VDisabledReason = defineDisabledReasonComponent({
17
- name: 'VDisabledReason',
18
- props: {
19
- ...menuProps,
29
+ export const DISABLED_REASON_PROPS = {
30
+ ...menuProps,
31
+ ...createPropsOptions({
20
32
  /**
21
33
  * Display type
22
34
  *
@@ -28,7 +40,17 @@ export const VDisabledReason = defineDisabledReasonComponent({
28
40
  type: String as PropType<DisabledReasonType>,
29
41
  default: 'tooltip' satisfies DisabledReasonType,
30
42
  },
31
- },
43
+ }),
44
+ };
45
+
46
+ export interface DisabledReasonInput
47
+ extends ExtractPublicPropTypes<
48
+ typeof DISABLED_REASON_PROPS & typeof DISABLED_REASON_BASE_PROPS
49
+ > {}
50
+
51
+ export const VDisabledReason = defineDisabledReasonComponent({
52
+ name: 'VDisabledReason',
53
+ props: DISABLED_REASON_PROPS,
32
54
  setup(api) {
33
55
  return (reason) => {
34
56
  const { type: _type, ...tooltipProps } = api.props;
@@ -52,3 +74,52 @@ export const VDisabledReason = defineDisabledReasonComponent({
52
74
  };
53
75
  },
54
76
  });
77
+
78
+ // Customize '@fastkit/vue-action' so that when the custom attribute
79
+ // "disabledReason" is set, it wraps the element with `VDisabledReason`
80
+ // to display the reason for being disabled.
81
+
82
+ // 1. Extend the '@fastkit/vue-action' interface
83
+ declare module '@fastkit/vue-action' {
84
+ interface ActionableCustomProps {
85
+ /**
86
+ * Reason why this element is disabled.
87
+ *
88
+ * If set, hovering over the disabled element will display the reason
89
+ * using `VDisabledReason`.
90
+ */
91
+ disabledReason: PropType<string | (() => VNodeChild) | DisabledReasonInput>;
92
+ }
93
+ }
94
+
95
+ // 2. Handle `disabledReason` as a custom attribute of '@fastkit/vue-action'
96
+ registerActionableAttrsResolver((attrs, ctx) => {
97
+ const disabledReason = ctx.getAttr('disabledReason');
98
+ if (disabledReason) {
99
+ // Remove disabledReason from the original attrs
100
+ // (to prevent adding unnecessary attributes to the element)
101
+ delete attrs.disabledReason;
102
+ return [
103
+ undefined,
104
+ {
105
+ disabledReason,
106
+ },
107
+ ];
108
+ }
109
+ });
110
+
111
+ // 3. Register a custom render wrapper for '@fastkit/vue-action'
112
+ registerActionableRenderWrapper((customProps, currentNode) => {
113
+ const { disabledReason } = customProps;
114
+ const disabledReasonInput =
115
+ typeof disabledReason === 'string' || typeof disabledReason === 'function'
116
+ ? { reason: disabledReason }
117
+ : disabledReason;
118
+
119
+ if (disabledReasonInput) {
120
+ return (
121
+ <VDisabledReason {...disabledReasonInput}>{currentNode}</VDisabledReason>
122
+ );
123
+ }
124
+ return currentNode;
125
+ });
@@ -1,3 +1,5 @@
1
+ @use 'sass:string';
2
+
1
3
  @mixin hidden-input-element {
2
4
  position: absolute;
3
5
  width: 1px;
@@ -25,7 +27,8 @@
25
27
  box-shadow:
26
28
  var(--shadow-key-umbra-#{$z}),
27
29
  var(--shadow-key-penumbra-#{$z}),
28
- var(--shadow-key-ambient-#{$z}) if($important, unquote('!important'), null);
30
+ var(--shadow-key-ambient-#{$z})
31
+ if($important, string.unquote('!important'), null);
29
32
  }
30
33
 
31
34
  @mixin elevation-transition(
@@ -18,11 +18,12 @@
18
18
  // =============================================
19
19
  // typographies
20
20
  // =============================================
21
- --typo-fallback-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
22
- 'Helvetica Neue', Arial, sans-serif;
21
+ --typo-fallback-font:
22
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
23
+ Arial, sans-serif;
23
24
  --type-emoji-font: 'Apple Color Emoji', 'Segoe UI Emoji';
24
- --typo-font: var(--typo-base-font), var(--typo-fallback-font),
25
- var(--type-emoji-font);
25
+ --typo-font:
26
+ var(--typo-base-font), var(--typo-fallback-font), var(--type-emoji-font);
26
27
 
27
28
  // base
28
29
  --typo-base-size: 1rem;
@@ -333,20 +334,23 @@
333
334
  // =============================================
334
335
  // snackbar
335
336
  // =============================================
336
- --snackbar-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2),
337
- 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12);
337
+ --snackbar-shadow:
338
+ 0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14),
339
+ 0 1px 18px 0 rgba(0, 0, 0, 0.12);
338
340
 
339
341
  // =============================================
340
342
  // dialogs
341
343
  // =============================================
342
- --dialog-shadow: 0 11px 15px -7px rgba(0, 0, 0, 0.2),
343
- 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12);
344
+ --dialog-shadow:
345
+ 0 11px 15px -7px rgba(0, 0, 0, 0.2), 0 24px 38px 3px rgba(0, 0, 0, 0.14),
346
+ 0 9px 46px 8px rgba(0, 0, 0, 0.12);
344
347
 
345
348
  // =============================================
346
349
  // menus
347
350
  // =============================================
348
- --menu-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
349
- 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
351
+ --menu-shadow:
352
+ 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14),
353
+ 0 3px 14px 2px rgba(0, 0, 0, 0.12);
350
354
 
351
355
  // =============================================
352
356
  // tooltips
@@ -356,8 +360,9 @@
356
360
  --tooltip-radius: 4px;
357
361
  --tooltip-padding: 5px 16px;
358
362
  --tooltip-font-size: calc(var(--root-em) * 0.875);
359
- --tooltip-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
360
- 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
363
+ --tooltip-shadow:
364
+ 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14),
365
+ 0 1px 5px 0 rgba(0, 0, 0, 0.12);
361
366
  }
362
367
 
363
368
  :root,