@fastkit/vui 0.15.0 → 0.16.1

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": "0.15.0",
3
+ "version": "0.16.1",
4
4
  "description": "A simple, extensible UI kit for Vue applications.",
5
5
  "keywords": [
6
6
  "fastkit",
@@ -58,15 +58,15 @@
58
58
  "@fastkit/vue-app-layout": "0.14.0",
59
59
  "@fastkit/vue-body-scroll-lock": "0.1.2",
60
60
  "@fastkit/vue-click-outside": "0.1.2",
61
- "@fastkit/vue-color-scheme": "0.13.6",
61
+ "@fastkit/vue-color-scheme": "0.14.0",
62
62
  "@fastkit/vue-form-control": "0.15.0",
63
63
  "@fastkit/vue-keyboard": "0.1.1",
64
- "@fastkit/vue-loading": "0.14.0",
64
+ "@fastkit/vue-loading": "0.14.1",
65
65
  "@fastkit/vue-location": "0.1.2",
66
66
  "@fastkit/vue-media-match": "0.13.6",
67
67
  "@fastkit/vue-resize": "0.1.2",
68
68
  "@fastkit/vue-scroller": "0.14.0",
69
- "@fastkit/vue-stack": "0.14.0",
69
+ "@fastkit/vue-stack": "0.15.1",
70
70
  "@fastkit/vue-transitions": "0.1.2",
71
71
  "@fastkit/vue-utils": "0.14.0"
72
72
  },
@@ -1,6 +1,6 @@
1
1
  import { defineComponent } from 'vue';
2
2
  import { VAppLayout } from '@fastkit/vue-app-layout';
3
- import { VStackRoot } from '@fastkit/vue-stack';
3
+ import { VStackContainer } from '@fastkit/vue-stack';
4
4
  import { useInjectTheme } from '@fastkit/vue-color-scheme';
5
5
 
6
6
  export const VApp = defineComponent({
@@ -10,9 +10,9 @@ export const VApp = defineComponent({
10
10
 
11
11
  return () => {
12
12
  return (
13
- <VStackRoot>
13
+ <VStackContainer>
14
14
  <VAppLayout v-slots={ctx.slots} />
15
- </VStackRoot>
15
+ </VStackContainer>
16
16
  );
17
17
  };
18
18
  },
@@ -26,7 +26,6 @@
26
26
  border-style: solid;
27
27
  border-width: 1px;
28
28
  border-radius: var(--avatar-radius);
29
- // border-radius: var(--control-field-radius);
30
29
 
31
30
  --shadow-color: rgba(0, 0, 0, 0) !important; // @TODO layer supports
32
31
  --focusShadow-color: rgba(0, 0, 0, 0) !important; // @TODO layer supports
@@ -138,32 +138,20 @@ export const VControlField = defineComponent({
138
138
  );
139
139
  };
140
140
 
141
- const handleClick = (ev: MouseEvent) => {
142
- ctx.emit('click', ev);
143
- // if (ev.target === hostElRef.value) {
144
- // ctx.emit('clickHost', ev);
145
- // }
146
- };
141
+ const handleClick = (ev: MouseEvent) => ctx.emit('click', ev);
147
142
 
148
- return {
149
- classes,
150
- renderAdornment,
151
- hostElRef: () => hostElRef,
152
- handleClick,
153
- // computedTabindex,
143
+ return () => {
144
+ return (
145
+ <div
146
+ class={classes.value}
147
+ onClick={handleClick}
148
+ // tabindex={this.computedTabindex}
149
+ ref={hostElRef}>
150
+ {renderAdornment('start')}
151
+ <div class="v-control-field__body">{ctx.slots.default?.()}</div>
152
+ {renderAdornment('end')}
153
+ </div>
154
+ );
154
155
  };
155
156
  },
156
- render() {
157
- return (
158
- <div
159
- class={this.classes}
160
- onClick={this.handleClick}
161
- // tabindex={this.computedTabindex}
162
- ref={this.hostElRef()}>
163
- {this.renderAdornment('start')}
164
- <div class="v-control-field__body">{this.$slots.default?.()}</div>
165
- {this.renderAdornment('end')}
166
- </div>
167
- );
168
- },
169
157
  });
@@ -0,0 +1,41 @@
1
+ .v-dialog {
2
+ position: relative;
3
+ display: inline-block;
4
+ min-width: 280px;
5
+ margin: 24px;
6
+ text-align: left;
7
+ pointer-events: auto;
8
+ border-radius: 2px;
9
+ outline: 0;
10
+ box-shadow: var(--dialog-shadow);
11
+
12
+ &__header {
13
+ box-sizing: border-box;
14
+ padding: 16px;
15
+ font-size: 24px;
16
+ line-height: 1.4;
17
+ }
18
+
19
+ &__body {
20
+ box-sizing: border-box;
21
+ padding: 16px;
22
+ font-size: 16px;
23
+ line-height: 1.5;
24
+ }
25
+
26
+ &--dense &__body {
27
+ padding-bottom: 0;
28
+ }
29
+
30
+ &__actions {
31
+ box-sizing: border-box;
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: flex-end;
35
+ padding: 8px;
36
+ }
37
+
38
+ &--dense &__actions {
39
+ padding-top: 0;
40
+ }
41
+ }
@@ -0,0 +1,51 @@
1
+ import './VDialog.scss';
2
+
3
+ import {
4
+ defineDialogComponent,
5
+ createStackActionProps,
6
+ useStackAction,
7
+ } from '@fastkit/vue-stack';
8
+ import { colorSchemeProps, useColorClasses } from '@fastkit/vue-color-scheme';
9
+ import { useVui } from '../../injections';
10
+
11
+ const colorProps = colorSchemeProps();
12
+
13
+ export const VDialog = defineDialogComponent({
14
+ name: 'VDialog',
15
+ props: {
16
+ ...createStackActionProps(),
17
+ ...colorProps,
18
+ dense: Boolean,
19
+ },
20
+ setup(ctx) {
21
+ const { props, control } = ctx;
22
+ const vui = useVui();
23
+ const actionControl = useStackAction(props, control, {
24
+ resolver: (actions) => {
25
+ if (actions.length === 0) {
26
+ return [vui.stackAction('close')];
27
+ } else {
28
+ return actions;
29
+ }
30
+ },
31
+ });
32
+ const color = useColorClasses(props, { useRootThemeDefault: true });
33
+
34
+ return (children) => {
35
+ const { $actions } = actionControl;
36
+ return (
37
+ <div
38
+ class={[
39
+ 'v-dialog',
40
+ color.colorClasses.value,
41
+ props.dense && 'v-dialog--dense',
42
+ ]}>
43
+ <div class="v-dialog__body">{children}</div>
44
+ {$actions.length > 0 && (
45
+ <div class="v-dialog__actions">{$actions}</div>
46
+ )}
47
+ </div>
48
+ );
49
+ };
50
+ },
51
+ });
@@ -0,0 +1 @@
1
+ export * from './VDialog';
@@ -11,7 +11,7 @@ import { defineSlots } from '@fastkit/vue-utils';
11
11
  import { useVuiColorProvider, useVui } from '../../injections';
12
12
  import type { VuiService } from '../../service';
13
13
  import { VIcon } from '../VIcon';
14
- import { VTooltip } from '../kits';
14
+ import { VTooltip } from '../VTooltip';
15
15
 
16
16
  const { props, emits } = createFormControlSettings();
17
17
 
@@ -111,6 +111,8 @@ export const VFormControl = defineComponent({
111
111
  vui,
112
112
  );
113
113
 
114
+ const handleClick = (ev: MouseEvent) => ctx.emit('clickLabel', ev, control);
115
+
114
116
  return () => {
115
117
  const label = control.renderLabel();
116
118
  const message = control.renderMessage();
@@ -121,11 +123,7 @@ export const VFormControl = defineComponent({
121
123
  return (
122
124
  <div class={['v-form-control', classes.value]}>
123
125
  {label && (
124
- <label
125
- class="v-form-control__label"
126
- onClick={(ev) => {
127
- ctx.emit('clickLabel', ev, control);
128
- }}>
126
+ <label class="v-form-control__label" onClick={handleClick}>
129
127
  {label}
130
128
  {getRequiredChip()}
131
129
  {hinttip && (
@@ -0,0 +1,4 @@
1
+ .v-menu {
2
+ border-radius: 2px;
3
+ box-shadow: var(--menu-shadow);
4
+ }
@@ -0,0 +1,31 @@
1
+ import './VMenu.scss';
2
+
3
+ import { defineMenuComponent } from '@fastkit/vue-stack';
4
+ import { colorSchemeProps, useColorClasses } from '@fastkit/vue-color-scheme';
5
+
6
+ const colorProps = colorSchemeProps();
7
+
8
+ export const VMenu = defineMenuComponent({
9
+ name: 'VMenu',
10
+ attrs: {
11
+ class: 'v-menu',
12
+ },
13
+ props: {
14
+ ...colorProps,
15
+ },
16
+ setup(ctx) {
17
+ const color = useColorClasses(ctx.props, { useRootThemeDefault: true });
18
+
19
+ ctx.setupContext.expose({
20
+ menu: ctx,
21
+ });
22
+
23
+ return (children) => {
24
+ return (
25
+ <div class={['v-menu__body', color.colorClasses.value]} {...ctx.attrs}>
26
+ {children}
27
+ </div>
28
+ );
29
+ };
30
+ },
31
+ });
@@ -0,0 +1 @@
1
+ export * from './VMenu';
@@ -36,11 +36,11 @@ import {
36
36
  } from '../../composables';
37
37
  import { VUI_SELECT_SYMBOL, useVui } from '../../injections';
38
38
  import { VIcon } from '../VIcon';
39
- import { VMenu } from '../kits';
39
+ import { VMenu } from '../VMenu';
40
40
  import { VOptionGroup } from '../VOptionGroup';
41
41
  import { VOption } from '../VOption';
42
42
  import { VButton } from '../VButton';
43
- import { VMenuControl } from '@fastkit/vue-stack';
43
+ import { MenuAPI } from '@fastkit/vue-stack';
44
44
 
45
45
  export const ARROW_KEY_TYPES = useKeyboard.Key(['ArrowUp', 'ArrowDown']);
46
46
 
@@ -82,7 +82,7 @@ export const VSelect = defineComponent({
82
82
  slots,
83
83
  emits,
84
84
  setup(props, ctx) {
85
- const menuRef: Ref<{ stackMenuControl: VMenuControl } | null> = ref(null);
85
+ const menuRef: Ref<{ menu: MenuAPI } | null> = ref(null);
86
86
  const menuOpened = ref(false);
87
87
  const showMenu = () => {
88
88
  menuOpened.value = true;
@@ -119,7 +119,7 @@ export const VSelect = defineComponent({
119
119
  });
120
120
 
121
121
  const focus = (opts?: FocusOptions): void => {
122
- fieldRef.value && fieldRef.value.focus(opts);
122
+ fieldRef.value?.focus?.(opts);
123
123
  };
124
124
 
125
125
  const renderSelections = (selectedItems: FormSelectorItemControl[]) => {
@@ -155,9 +155,9 @@ export const VSelect = defineComponent({
155
155
  };
156
156
 
157
157
  const clearKeyFocused = () => {
158
- const menu = menuRef.value;
158
+ const menu = menuRef.value?.menu;
159
159
  if (!menu) return;
160
- const bodyEl = menu.stackMenuControl.bodyRef.value;
160
+ const bodyEl = menu.bodyRef.value;
161
161
  if (!bodyEl) return;
162
162
 
163
163
  const els = Array.from(
@@ -168,10 +168,10 @@ export const VSelect = defineComponent({
168
168
  };
169
169
 
170
170
  const getItemElements = (): HTMLElement[] | void => {
171
- const menu = menuRef.value;
171
+ const menu = menuRef.value?.menu;
172
172
  if (!menu) return;
173
173
 
174
- const bodyEl = menu.stackMenuControl.bodyRef.value;
174
+ const bodyEl = menu.bodyRef.value;
175
175
 
176
176
  if (!bodyEl) return;
177
177
 
@@ -0,0 +1,48 @@
1
+ .v-sheet-modal {
2
+ --v-sheet-modal-width: 90vw;
3
+ --v-sheet-modal-max-width: none;
4
+ --v-sheet-background: var(--palette-foundation);
5
+
6
+ position: fixed;
7
+ top: 0;
8
+ right: 0;
9
+ bottom: 0;
10
+ box-sizing: border-box;
11
+ display: flex;
12
+ flex-direction: column;
13
+ width: var(--v-sheet-modal-width);
14
+ max-width: var(--v-sheet-modal-max-width);
15
+ padding: 0;
16
+ outline: 0;
17
+ box-shadow: var(--dialog-shadow);
18
+ transition: transform var(--v-stack-transition-slowly);
19
+
20
+ &__header {
21
+ position: relative;
22
+ z-index: 1;
23
+ flex: 0 0;
24
+ background-color: var(--v-sheet-background);
25
+ }
26
+
27
+ &__scroller {
28
+ flex: 1 1;
29
+ -webkit-overflow-scrolling: touch;
30
+ height: 100%;
31
+ overflow-y: auto;
32
+ background-color: var(--v-sheet-background);
33
+ }
34
+
35
+ &--has-active-child {
36
+ transform: translateX(calc(-100vw + var(--v-sheet-modal-width)));
37
+ }
38
+
39
+ &-enter-active,
40
+ &-leave-active {
41
+ transition: transform var(--v-stack-transition-slowly);
42
+ }
43
+
44
+ &-enter-from,
45
+ &-leave-to {
46
+ transform: translateX(var(--v-sheet-modal-width));
47
+ }
48
+ }
@@ -0,0 +1,88 @@
1
+ import './VSheetModal.scss';
2
+ import {
3
+ defineComponent,
4
+ // ExtractPropTypes,
5
+ PropType,
6
+ VNodeChild,
7
+ computed,
8
+ } from 'vue';
9
+ import {
10
+ createStackableDefine,
11
+ VStackSlots,
12
+ VStackControl,
13
+ useStackControl,
14
+ } from '@fastkit/vue-stack';
15
+ // import { } from '../schemes';
16
+ // import { useStackControl } from '../composables';
17
+ // import { ExtractPropInput } from '@fastkit/vue-utils';
18
+
19
+ const { props, emits } = createStackableDefine({
20
+ defaultTransition: 'v-sheet-modal',
21
+ defaultFocusTrap: true,
22
+ defaultFocusRestorable: true,
23
+ defaultScrollLock: true,
24
+ });
25
+
26
+ export interface VSheetModalSlots extends VStackSlots {
27
+ header?: (control: VStackControl) => VNodeChild;
28
+ }
29
+
30
+ export const sheetModalProps = {
31
+ ...props,
32
+ header: Function as PropType<(control: VStackControl) => VNodeChild>,
33
+ 'v-slots': undefined as unknown as PropType<VSheetModalSlots>,
34
+ };
35
+
36
+ const SHEET_STACK_TYPE = Symbol('VSheetModal');
37
+
38
+ export const VSheetModal = defineComponent({
39
+ name: 'VSheetModal',
40
+ inheritAttrs: false,
41
+ props: sheetModalProps,
42
+ emits,
43
+ setup(props, ctx) {
44
+ const stackControl = useStackControl(props, ctx, {
45
+ stackType: SHEET_STACK_TYPE,
46
+ });
47
+ const hasActiveChild = computed(() => {
48
+ const myIndex = stackControl.zIndex;
49
+ const stacks = stackControl.$service
50
+ .getActiveStacks()
51
+ .filter((stack) => stack.stackType === SHEET_STACK_TYPE);
52
+ return stacks.some((stack) => stack.zIndex > myIndex);
53
+ });
54
+ return {
55
+ stackControl,
56
+ hasActiveChild,
57
+ };
58
+ },
59
+ render() {
60
+ const {
61
+ render,
62
+ // color,
63
+ } = this.stackControl;
64
+ const headerSlot = this.$slots.header || this.header;
65
+ return render((children) => {
66
+ return (
67
+ <div
68
+ class={[
69
+ 'v-sheet-modal',
70
+ {
71
+ 'v-sheet-modal--has-active-child': this.hasActiveChild,
72
+ },
73
+ // color.colorClasses.value,
74
+ ]}
75
+ tabindex="0">
76
+ {headerSlot && (
77
+ <div class="v-sheet-modal__header">
78
+ {headerSlot(this.stackControl)}
79
+ </div>
80
+ )}
81
+ <div class="v-sheet-modal__scroller">{children}</div>
82
+ </div>
83
+ );
84
+ });
85
+ },
86
+ });
87
+
88
+ // export type VSheetModalStatic = typeof VSheetModal;
@@ -0,0 +1 @@
1
+ export * from './VSheetModal';
@@ -0,0 +1,33 @@
1
+ .v-snackbar {
2
+ font-size: 14px;
3
+ box-shadow: var(--snackbar-shadow);
4
+
5
+ &__inner {
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: space-between;
9
+ width: auto;
10
+ min-width: 288px;
11
+ max-width: calc(100vw - 96px);
12
+ padding: 8px 4px 8px 16px;
13
+ color: var(--text-color);
14
+ background-color: var(--main-color);
15
+ border-color: var(--border-color);
16
+ border-radius: inherit;
17
+ }
18
+
19
+ &__body {
20
+ flex: 1 1 100%;
21
+ word-break: break-all;
22
+ }
23
+
24
+ &__actions {
25
+ flex: 0 0 auto;
26
+ padding-left: 20px;
27
+ white-space: nowrap;
28
+ }
29
+
30
+ &__close {
31
+ margin: 0;
32
+ }
33
+ }
@@ -0,0 +1,48 @@
1
+ import './VSnackbar.scss';
2
+
3
+ import {
4
+ defineSnackbarComponent,
5
+ createStackActionProps,
6
+ useStackAction,
7
+ } from '@fastkit/vue-stack';
8
+ import { colorSchemeProps } from '@fastkit/vue-color-scheme';
9
+ import { useVui } from '../../injections';
10
+ import { useColorClasses } from '@fastkit/vue-color-scheme';
11
+
12
+ const colorProps = colorSchemeProps();
13
+
14
+ export const VSnackbar = defineSnackbarComponent({
15
+ name: 'VSnackbar',
16
+ props: {
17
+ ...createStackActionProps(),
18
+ ...colorProps,
19
+ },
20
+ setup(ctx) {
21
+ const { props, control } = ctx;
22
+ const vui = useVui();
23
+ const actionControl = useStackAction(props, control, {
24
+ resolver: (actions) => {
25
+ if (actions.length === 0) {
26
+ return [vui.stackAction('close')];
27
+ } else {
28
+ return actions;
29
+ }
30
+ },
31
+ });
32
+ const color = useColorClasses(props, { useRootThemeDefault: true });
33
+
34
+ return (children) => {
35
+ const { $actions } = actionControl;
36
+ return (
37
+ <div class={['v-snackbar', color.colorClasses.value]} {...ctx.attrs}>
38
+ <div class="v-snackbar__inner">
39
+ <div class="v-snackbar__body">{children}</div>
40
+ {$actions.length > 0 && (
41
+ <div class="v-snackbar__actions">{$actions}</div>
42
+ )}
43
+ </div>
44
+ </div>
45
+ );
46
+ };
47
+ },
48
+ });
@@ -0,0 +1 @@
1
+ export * from './VSnackbar';
@@ -41,7 +41,6 @@ export const VSwitch = defineComponent({
41
41
  {
42
42
  'v-switch--selected': selectorItemControl.selected,
43
43
  'v-switch--disabled': selectorItemControl.isDisabled,
44
- xxxxx: selectorItemControl.booted,
45
44
  },
46
45
  this.classes,
47
46
  ]}
@@ -0,0 +1,18 @@
1
+ .v-tooltip {
2
+ --menu-shadow: var(--tooltip-shadow);
3
+
4
+ font-size: var(--tooltip-font-size);
5
+
6
+ .v-menu__body {
7
+ color: var(--tooltip-color) !important;
8
+ background: var(--tooltip-background) !important;
9
+ }
10
+
11
+ border-radius: var(--tooltip-radius);
12
+ // opacity: var(--tooltip-opacity);
13
+
14
+ &__inner {
15
+ display: inline-block;
16
+ padding: var(--tooltip-padding);
17
+ }
18
+ }
@@ -0,0 +1,42 @@
1
+ import './VTooltip.scss';
2
+
3
+ import { defineComponent } from 'vue';
4
+ import { VMenu } from '../VMenu';
5
+
6
+ export const VTooltip = defineComponent({
7
+ name: 'VTooltip',
8
+ inheritAttrs: false,
9
+ setup(_props, ctx) {
10
+ return () => {
11
+ const attrs = {
12
+ ...ctx.attrs,
13
+ };
14
+
15
+ const defaultSlot = ctx.slots.default;
16
+ if (attrs.openOnHover == null) {
17
+ attrs.openOnHover = true;
18
+ }
19
+ if (attrs.openDelay == null) {
20
+ attrs.openDelay = 200;
21
+ }
22
+
23
+ return (
24
+ <VMenu
25
+ {...attrs}
26
+ scrollLock={false}
27
+ class="v-tooltip"
28
+ v-slots={{
29
+ ...ctx.slots,
30
+ default: (payload) => {
31
+ return [
32
+ <span class="v-tooltip__inner">
33
+ {defaultSlot && defaultSlot(payload)}
34
+ </span>,
35
+ ];
36
+ },
37
+ }}
38
+ />
39
+ );
40
+ };
41
+ },
42
+ }) as typeof VMenu;
@@ -0,0 +1 @@
1
+ export * from './VTooltip';
@@ -1,5 +1,9 @@
1
1
  export * from './loading';
2
- export * from './kits';
2
+ export * from './VDialog';
3
+ export * from './VMenu';
4
+ export * from './VSnackbar';
5
+ export * from './VTooltip';
6
+ export * from './VSheetModal';
3
7
  export * from './VSkeltonLoader';
4
8
  export * from './VBusyImage';
5
9
  export * from './VGrid';