@antify/ui 2.4.3 → 2.4.5

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.
@@ -62,7 +62,7 @@ onKeyStroke('Escape', (e: KeyboardEvent) => {
62
62
  });
63
63
 
64
64
  const onClickOutside = [
65
- (ev) => {
65
+ () => {
66
66
  emit('update:showDropdown', false);
67
67
  },
68
68
  {
@@ -81,7 +81,6 @@ const onClickOutside = [
81
81
  <div
82
82
  ref="reference"
83
83
  v-on-click-outside="onClickOutside"
84
- class="h-full w-full"
85
84
  >
86
85
  <slot />
87
86
  </div>
@@ -39,6 +39,7 @@ import AntTextarea from './inputs/AntTextarea.vue';
39
39
  import AntTextInput from './inputs/AntTextInput.vue';
40
40
  import AntUnitInput from './inputs/AntUnitInput.vue';
41
41
  import AntImageInput from './inputs/AntImageInput.vue';
42
+ import AntColorInput from './inputs/AntColorInput/AntColorInput.vue';
42
43
  import AntNavLeftLayout from './layouts/AntNavLeftLayout.vue';
43
44
  import AntNavbar from './navbar/AntNavbar.vue';
44
45
  import AntNavbarItem from './navbar/AntNavbarItem.vue';
@@ -64,4 +65,4 @@ import AntTag from './AntTag.vue';
64
65
  import AntToast from './AntToast.vue';
65
66
  import AntToaster from './AntToaster.vue';
66
67
  import AntTooltip from './AntTooltip.vue';
67
- export { AntActionButton, AntButton, AntCreateButton, AntDeleteButton, AntDuplicateButton, AntEditButton, AntSaveAndNewButton, AntSaveButton, AntCrud, AntCrudDetail, AntCrudDetailActions, AntCrudDetailNav, AntCrudTableFilter, AntCrudTableNav, AntDeleteDialog, AntDialog, AntField, AntFormGroup, AntFormGroupLabel, AntBaseInput, AntSelectMenu, AntInputDescription, AntInputLabel, AntInputLimiter, AntCheckbox, AntCheckboxGroup, AntDateInput, AntNumberInput, AntPasswordInput, AntRadio, AntRadioGroup, AntRangeSlider, AntSearch, AntSelect, AntSwitch, AntSwitcher, AntTagInput, AntTextarea, AntTextInput, AntUnitInput, AntImageInput, AntNavLeftLayout, AntNavbar, AntNavbarItem, AntTable, AntTabs, AntTransitionCollapseHeight, AntAccordion, AntAccordionItem, AntAlert, AntCard, AntContent, AntDropdown, AntIcon, AntKeycap, AntListGroup, AntListGroupItem, AntModal, AntPagination, AntPopover, AntSkeleton, AntSpinner, AntTag, AntToast, AntToaster, AntTooltip, };
68
+ export { AntActionButton, AntButton, AntCreateButton, AntDeleteButton, AntDuplicateButton, AntEditButton, AntSaveAndNewButton, AntSaveButton, AntCrud, AntCrudDetail, AntCrudDetailActions, AntCrudDetailNav, AntCrudTableFilter, AntCrudTableNav, AntDeleteDialog, AntDialog, AntField, AntFormGroup, AntFormGroupLabel, AntBaseInput, AntSelectMenu, AntInputDescription, AntInputLabel, AntInputLimiter, AntCheckbox, AntCheckboxGroup, AntDateInput, AntNumberInput, AntPasswordInput, AntRadio, AntRadioGroup, AntRangeSlider, AntSearch, AntSelect, AntSwitch, AntSwitcher, AntTagInput, AntTextarea, AntTextInput, AntUnitInput, AntImageInput, AntNavLeftLayout, AntNavbar, AntNavbarItem, AntTable, AntTabs, AntTransitionCollapseHeight, AntAccordion, AntAccordionItem, AntAlert, AntCard, AntContent, AntDropdown, AntIcon, AntKeycap, AntListGroup, AntListGroupItem, AntModal, AntPagination, AntPopover, AntSkeleton, AntSpinner, AntTag, AntToast, AntToaster, AntTooltip, AntColorInput, };
@@ -57,6 +57,12 @@ Object.defineProperty(exports, "AntCheckboxGroup", {
57
57
  return _AntCheckboxGroup.default;
58
58
  }
59
59
  });
60
+ Object.defineProperty(exports, "AntColorInput", {
61
+ enumerable: true,
62
+ get: function () {
63
+ return _AntColorInput.default;
64
+ }
65
+ });
60
66
  Object.defineProperty(exports, "AntContent", {
61
67
  enumerable: true,
62
68
  get: function () {
@@ -440,6 +446,7 @@ var _AntTextarea = _interopRequireDefault(require("./inputs/AntTextarea.vue"));
440
446
  var _AntTextInput = _interopRequireDefault(require("./inputs/AntTextInput.vue"));
441
447
  var _AntUnitInput = _interopRequireDefault(require("./inputs/AntUnitInput.vue"));
442
448
  var _AntImageInput = _interopRequireDefault(require("./inputs/AntImageInput.vue"));
449
+ var _AntColorInput = _interopRequireDefault(require("./inputs/AntColorInput/AntColorInput.vue"));
443
450
  var _AntNavLeftLayout = _interopRequireDefault(require("./layouts/AntNavLeftLayout.vue"));
444
451
  var _AntNavbar = _interopRequireDefault(require("./navbar/AntNavbar.vue"));
445
452
  var _AntNavbarItem = _interopRequireDefault(require("./navbar/AntNavbarItem.vue"));
@@ -39,6 +39,7 @@ import AntTextarea from "./inputs/AntTextarea.vue";
39
39
  import AntTextInput from "./inputs/AntTextInput.vue";
40
40
  import AntUnitInput from "./inputs/AntUnitInput.vue";
41
41
  import AntImageInput from "./inputs/AntImageInput.vue";
42
+ import AntColorInput from "./inputs/AntColorInput/AntColorInput.vue";
42
43
  import AntNavLeftLayout from "./layouts/AntNavLeftLayout.vue";
43
44
  import AntNavbar from "./navbar/AntNavbar.vue";
44
45
  import AntNavbarItem from "./navbar/AntNavbarItem.vue";
@@ -130,5 +131,6 @@ export {
130
131
  AntTag,
131
132
  AntToast,
132
133
  AntToaster,
133
- AntTooltip
134
+ AntTooltip,
135
+ AntColorInput
134
136
  };
@@ -0,0 +1,7 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3';
2
+ import AntColorInput from './AntColorInput.vue';
3
+ declare const meta: Meta<typeof AntColorInput>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof AntColorInput>;
6
+ export declare const Docs: Story;
7
+ export declare const Summary: Story;
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ module.exports = exports.Summary = exports.Docs = void 0;
7
+ var _vue = require("vue");
8
+ var _enums = require("../../../enums");
9
+ var _AntColorInput = _interopRequireDefault(require("./AntColorInput.vue"));
10
+ var _AntFormGroup = _interopRequireDefault(require("../../forms/AntFormGroup.vue"));
11
+ var _AntFormGroupLabel = _interopRequireDefault(require("../../forms/AntFormGroupLabel.vue"));
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ const meta = {
14
+ title: "Inputs/ColorInput",
15
+ component: _AntColorInput.default,
16
+ argTypes: {
17
+ modelValue: {
18
+ control: "text"
19
+ },
20
+ state: {
21
+ control: {
22
+ type: "select"
23
+ },
24
+ options: Object.values(_enums.InputState)
25
+ },
26
+ size: {
27
+ control: {
28
+ type: "select"
29
+ },
30
+ options: Object.values(_enums.Size)
31
+ }
32
+ }
33
+ };
34
+ module.exports = meta;
35
+ const defaultOptions = ["primary-500", "red-500", "green-500", "blue-500", "yellow-500", "purple-500", "pink-500", "orange-500"];
36
+ const Docs = exports.Docs = {
37
+ render: args => ({
38
+ components: {
39
+ AntColorInput: _AntColorInput.default
40
+ },
41
+ setup() {
42
+ const modelValue = (0, _vue.computed)({
43
+ get: () => args.modelValue,
44
+ // @ts-expect-error expect read only
45
+ set: val => args.modelValue = val
46
+ });
47
+ return {
48
+ modelValue,
49
+ args
50
+ };
51
+ },
52
+ template: `
53
+ <AntColorInput v-bind="args" v-model="modelValue" />
54
+ `
55
+ }),
56
+ args: {
57
+ label: "Label",
58
+ description: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod",
59
+ options: defaultOptions,
60
+ modelValue: "entry-1"
61
+ }
62
+ };
63
+ const Summary = exports.Summary = {
64
+ parameters: {
65
+ chromatic: {
66
+ disableSnapshot: false
67
+ }
68
+ },
69
+ render: args => ({
70
+ components: {
71
+ AntColorInput: _AntColorInput.default,
72
+ AntFormGroup: _AntFormGroup.default,
73
+ AntFormGroupLabel: _AntFormGroupLabel.default
74
+ },
75
+ setup() {
76
+ const modelValue = (0, _vue.computed)({
77
+ get: () => args.modelValue,
78
+ // @ts-expect-error expect read only
79
+ set: val => args.modelValue = val
80
+ });
81
+ const skeleton = (0, _vue.ref)(true);
82
+ return {
83
+ args,
84
+ modelValue,
85
+ InputState: _enums.InputState,
86
+ skeleton,
87
+ Size: _enums.Size
88
+ };
89
+ },
90
+ template: `
91
+ <AntFormGroup>
92
+ <AntFormGroupLabel>States</AntFormGroupLabel>
93
+ <AntFormGroup direction="row">
94
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
95
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
96
+ :state="InputState.base"/>
97
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
98
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
99
+ :state="InputState.info"/>
100
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
101
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
102
+ :state="InputState.success"/>
103
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
104
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
105
+ :state="InputState.warning"/>
106
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
107
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
108
+ :state="InputState.danger"/>
109
+ </AntFormGroup>
110
+ <AntFormGroupLabel>Sizes</AntFormGroupLabel>
111
+ <AntFormGroup direction="row">
112
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.lg"
113
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
114
+ />
115
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.md"
116
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
117
+ />
118
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.sm"
119
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
120
+ />
121
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.xs"
122
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
123
+ />
124
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.xs2"
125
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
126
+ />
127
+ </AntFormGroup>
128
+ <AntFormGroup direction="row">
129
+ <AntFormGroup>
130
+ <AntFormGroupLabel>Disabled</AntFormGroupLabel>
131
+ <AntColorInput v-bind="args" v-model="modelValue" :disabled="true" label="Label"
132
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
133
+ />
134
+ </AntFormGroup>
135
+ <AntFormGroup>
136
+ <AntFormGroupLabel>Readonly</AntFormGroupLabel>
137
+ <AntColorInput v-bind="args" v-model="modelValue" :readonly="true" label="Label"
138
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
139
+ />
140
+ </AntFormGroup>
141
+ <AntFormGroup>
142
+ <AntFormGroupLabel>Skeleton</AntFormGroupLabel>
143
+ <AntColorInput v-bind="args" v-model="modelValue" :skeleton="true" label="Label"
144
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
145
+ />
146
+ </AntFormGroup>
147
+ </AntFormGroup>
148
+ <AntFormGroupLabel>Plain</AntFormGroupLabel>
149
+ <AntColorInput v-bind="args" v-model="modelValue"/>
150
+ <AntFormGroupLabel>Nullable</AntFormGroupLabel>
151
+ <AntColorInput v-bind="args" v-model="modelValue" nullable/>
152
+ <AntFormGroupLabel>With label</AntFormGroupLabel>
153
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"/>
154
+ <AntFormGroupLabel>With description</AntFormGroupLabel>
155
+ <AntColorInput v-bind="args" v-model="modelValue"
156
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"/>
157
+ <AntFormGroupLabel>With label + description</AntFormGroupLabel>
158
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
159
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"/>
160
+ </AntFormGroup>
161
+ `
162
+ }),
163
+ args: {
164
+ options: defaultOptions,
165
+ modelValue: "primary-500"
166
+ }
167
+ };
@@ -0,0 +1,177 @@
1
+ import {
2
+ ref,
3
+ computed
4
+ } from "vue";
5
+ import {
6
+ Size
7
+ } from "../../../enums/index.mjs";
8
+ import {
9
+ InputState
10
+ } from "../../../enums/index.mjs";
11
+ import AntColorInput from "./AntColorInput.vue";
12
+ import AntFormGroup from "../../forms/AntFormGroup.vue";
13
+ import AntFormGroupLabel from "../../forms/AntFormGroupLabel.vue";
14
+ const meta = {
15
+ title: "Inputs/ColorInput",
16
+ component: AntColorInput,
17
+ argTypes: {
18
+ modelValue: {
19
+ control: "text"
20
+ },
21
+ state: {
22
+ control: {
23
+ type: "select"
24
+ },
25
+ options: Object.values(InputState)
26
+ },
27
+ size: {
28
+ control: {
29
+ type: "select"
30
+ },
31
+ options: Object.values(Size)
32
+ }
33
+ }
34
+ };
35
+ export default meta;
36
+ const defaultOptions = [
37
+ "primary-500",
38
+ "red-500",
39
+ "green-500",
40
+ "blue-500",
41
+ "yellow-500",
42
+ "purple-500",
43
+ "pink-500",
44
+ "orange-500"
45
+ ];
46
+ export const Docs = {
47
+ render: (args) => ({
48
+ components: {
49
+ AntColorInput
50
+ },
51
+ setup() {
52
+ const modelValue = computed({
53
+ get: () => args.modelValue,
54
+ // @ts-expect-error expect read only
55
+ set: (val) => args.modelValue = val
56
+ });
57
+ return {
58
+ modelValue,
59
+ args
60
+ };
61
+ },
62
+ template: `
63
+ <AntColorInput v-bind="args" v-model="modelValue" />
64
+ `
65
+ }),
66
+ args: {
67
+ label: "Label",
68
+ description: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod",
69
+ options: defaultOptions,
70
+ modelValue: "entry-1"
71
+ }
72
+ };
73
+ export const Summary = {
74
+ parameters: {
75
+ chromatic: {
76
+ disableSnapshot: false
77
+ }
78
+ },
79
+ render: (args) => ({
80
+ components: {
81
+ AntColorInput,
82
+ AntFormGroup,
83
+ AntFormGroupLabel
84
+ },
85
+ setup() {
86
+ const modelValue = computed({
87
+ get: () => args.modelValue,
88
+ // @ts-expect-error expect read only
89
+ set: (val) => args.modelValue = val
90
+ });
91
+ const skeleton = ref(true);
92
+ return {
93
+ args,
94
+ modelValue,
95
+ InputState,
96
+ skeleton,
97
+ Size
98
+ };
99
+ },
100
+ template: `
101
+ <AntFormGroup>
102
+ <AntFormGroupLabel>States</AntFormGroupLabel>
103
+ <AntFormGroup direction="row">
104
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
105
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
106
+ :state="InputState.base"/>
107
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
108
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
109
+ :state="InputState.info"/>
110
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
111
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
112
+ :state="InputState.success"/>
113
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
114
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
115
+ :state="InputState.warning"/>
116
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
117
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
118
+ :state="InputState.danger"/>
119
+ </AntFormGroup>
120
+ <AntFormGroupLabel>Sizes</AntFormGroupLabel>
121
+ <AntFormGroup direction="row">
122
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.lg"
123
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
124
+ />
125
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.md"
126
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
127
+ />
128
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.sm"
129
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
130
+ />
131
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.xs"
132
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
133
+ />
134
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label" :size="Size.xs2"
135
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
136
+ />
137
+ </AntFormGroup>
138
+ <AntFormGroup direction="row">
139
+ <AntFormGroup>
140
+ <AntFormGroupLabel>Disabled</AntFormGroupLabel>
141
+ <AntColorInput v-bind="args" v-model="modelValue" :disabled="true" label="Label"
142
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
143
+ />
144
+ </AntFormGroup>
145
+ <AntFormGroup>
146
+ <AntFormGroupLabel>Readonly</AntFormGroupLabel>
147
+ <AntColorInput v-bind="args" v-model="modelValue" :readonly="true" label="Label"
148
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
149
+ />
150
+ </AntFormGroup>
151
+ <AntFormGroup>
152
+ <AntFormGroupLabel>Skeleton</AntFormGroupLabel>
153
+ <AntColorInput v-bind="args" v-model="modelValue" :skeleton="true" label="Label"
154
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"
155
+ />
156
+ </AntFormGroup>
157
+ </AntFormGroup>
158
+ <AntFormGroupLabel>Plain</AntFormGroupLabel>
159
+ <AntColorInput v-bind="args" v-model="modelValue"/>
160
+ <AntFormGroupLabel>Nullable</AntFormGroupLabel>
161
+ <AntColorInput v-bind="args" v-model="modelValue" nullable/>
162
+ <AntFormGroupLabel>With label</AntFormGroupLabel>
163
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"/>
164
+ <AntFormGroupLabel>With description</AntFormGroupLabel>
165
+ <AntColorInput v-bind="args" v-model="modelValue"
166
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"/>
167
+ <AntFormGroupLabel>With label + description</AntFormGroupLabel>
168
+ <AntColorInput v-bind="args" v-model="modelValue" label="Label"
169
+ description="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod"/>
170
+ </AntFormGroup>
171
+ `
172
+ }),
173
+ args: {
174
+ options: defaultOptions,
175
+ modelValue: "primary-500"
176
+ }
177
+ };
@@ -0,0 +1,9 @@
1
+ export declare enum ColorInputSize {
2
+ xl2 = "2xl",
3
+ xl = "xl",
4
+ lg = "lg",
5
+ md = "md",
6
+ sm = "sm",
7
+ xs = "xs",
8
+ xs2 = "2xs"
9
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ColorInputSize = void 0;
7
+ var ColorInputSize = exports.ColorInputSize = /* @__PURE__ */(ColorInputSize2 => {
8
+ ColorInputSize2["xl2"] = "2xl";
9
+ ColorInputSize2["xl"] = "xl";
10
+ ColorInputSize2["lg"] = "lg";
11
+ ColorInputSize2["md"] = "md";
12
+ ColorInputSize2["sm"] = "sm";
13
+ ColorInputSize2["xs"] = "xs";
14
+ ColorInputSize2["xs2"] = "2xs";
15
+ return ColorInputSize2;
16
+ })(ColorInputSize || {});
@@ -0,0 +1,10 @@
1
+ export var ColorInputSize = /* @__PURE__ */ ((ColorInputSize2) => {
2
+ ColorInputSize2["xl2"] = "2xl";
3
+ ColorInputSize2["xl"] = "xl";
4
+ ColorInputSize2["lg"] = "lg";
5
+ ColorInputSize2["md"] = "md";
6
+ ColorInputSize2["sm"] = "sm";
7
+ ColorInputSize2["xs"] = "xs";
8
+ ColorInputSize2["xs2"] = "2xs";
9
+ return ColorInputSize2;
10
+ })(ColorInputSize || {});
@@ -0,0 +1,209 @@
1
+ <script setup lang="ts">
2
+ import AntField from '../../forms/AntField.vue';
3
+ import AntButton from '../../buttons/AntButton.vue';
4
+ import {
5
+ faMultiply,
6
+ } from '@fortawesome/free-solid-svg-icons';
7
+ import AntSkeleton from '../../AntSkeleton.vue';
8
+ import {
9
+ Size,
10
+ State,
11
+ Grouped,
12
+ InputState,
13
+ } from '../../../enums';
14
+ import {
15
+ ref,
16
+ watch,
17
+ computed,
18
+ onMounted, nextTick,
19
+ } from 'vue';
20
+ import Color from './Color.vue';
21
+ import AntDropdown from '../../AntDropdown.vue';
22
+ import ColorSelection from './ColorSelection.vue';
23
+ import type {
24
+ ColorInputSize,
25
+ } from './AntColorInput.types';
26
+
27
+ const emit = defineEmits([
28
+ 'update:modelValue',
29
+ 'validate',
30
+ 'blur',
31
+ ]);
32
+ const props = withDefaults(defineProps<{
33
+ modelValue: string | null;
34
+ options: string[];
35
+ label?: string;
36
+ description?: string;
37
+ skeleton?: boolean;
38
+ readonly?: boolean;
39
+ disabled?: boolean;
40
+ state?: InputState;
41
+ size?: Size;
42
+ messages?: string[];
43
+ nullable?: boolean;
44
+ }>(), {
45
+ state: InputState.base,
46
+ size: Size.md,
47
+ messages: () => [],
48
+ nullable: false,
49
+ });
50
+ const _value = computed({
51
+ get() {
52
+ const found = props.options.find((option: string | ColorOption) => typeof option === 'string' ? option === props.modelValue : option.value === props.modelValue);
53
+
54
+ if (!found) {
55
+ return props.options[0];
56
+ }
57
+
58
+ return found;
59
+ },
60
+ set(val: string | ColorOption) {
61
+ emit('update:modelValue', typeof val === 'string' ? val : val.value);
62
+ },
63
+ });
64
+ const hasInputState = computed(() => props.skeleton || props.readonly || props.disabled);
65
+ const containerClasses = computed(() => {
66
+ const classes: {
67
+ [key: string]: boolean;
68
+ } = {
69
+ 'flex relative w-fit ring-primary/25 rounded-md outline-hidden': true,
70
+ 'focus-within:ring-2': (props.size === Size.xs2 || props.size === Size.xs || props.size === Size.sm) && !hasInputState.value,
71
+ 'focus-within:ring-4': (props.size === Size.md || props.size === Size.lg) && !hasInputState.value,
72
+ };
73
+ const colorVariant = {
74
+ [InputState.base]: 'focus-within:ring-primary-200',
75
+ [InputState.danger]: 'focus-within:ring-danger-200',
76
+ [InputState.info]: 'focus-within:ring-info-200',
77
+ [InputState.success]: 'focus-within:ring-success-200',
78
+ [InputState.warning]: 'focus-within:ring-warning-200',
79
+ };
80
+
81
+ classes[colorVariant[props.state]] = true;
82
+
83
+ return classes;
84
+ });
85
+ const hasRemoveButton = computed<boolean>(() => {
86
+ if (props.nullable) {
87
+ return props.modelValue !== null;
88
+ }
89
+
90
+ return false;
91
+ });
92
+ const itemClasses = computed(() => {
93
+ const classes: {
94
+ [key: string]: boolean;
95
+ } = {
96
+ 'relative outline outline-1 -outline-offset-1 rounded-l-md cursor-pointer': true,
97
+ 'rounded-r-md': !hasRemoveButton.value,
98
+ 'p-1': props.size === Size.xs2,
99
+ 'p-1.5': props.size === Size.xs || props.size === Size.sm,
100
+ 'p-2': props.size === Size.md,
101
+ 'p-2.5': props.size === Size.lg,
102
+ invisible: props.skeleton,
103
+ 'opacity-50 cursor-not-allowed': props.disabled,
104
+ };
105
+
106
+ const colorVariant = {
107
+ [InputState.danger]: 'outline-danger-500 bg-danger-100',
108
+ [InputState.base]: 'outline-base-300 bg-white',
109
+ [InputState.info]: 'outline-info-500 bg-info-100',
110
+ [InputState.success]: 'outline-success-500 bg-success-100',
111
+ [InputState.warning]: 'outline-warning-500 bg-warning-100',
112
+ };
113
+
114
+ classes[colorVariant[props.state]] = true;
115
+
116
+ return classes;
117
+ });
118
+ const showDropdown = ref<boolean>(false);
119
+
120
+ /**
121
+ * Validate default value if given after delayed data fetching.
122
+ */
123
+ watch(() => props.skeleton, (val) => {
124
+ if (!val && props.modelValue !== null) {
125
+ emit('validate', props.modelValue);
126
+ }
127
+ });
128
+ watch(_value, () => {
129
+ if (props.messages.length > 0) {
130
+ emit('validate', props.modelValue);
131
+ }
132
+ });
133
+
134
+ function onBlur(e: FocusEvent) {
135
+ emit('validate', props.modelValue);
136
+ emit('blur', e);
137
+ }
138
+
139
+ onMounted(() => {
140
+ if (!props.skeleton && props.modelValue !== null) {
141
+ emit('validate', props.modelValue);
142
+ }
143
+ });
144
+ </script>
145
+
146
+ <template>
147
+ <AntField
148
+ :label="label"
149
+ :size="size"
150
+ :skeleton="skeleton"
151
+ :description="description"
152
+ :state="state"
153
+ :messages="messages"
154
+ label-for="noop"
155
+ >
156
+ <AntDropdown
157
+ v-model:show-dropdown="showDropdown"
158
+ :content-padding="false"
159
+ >
160
+ <div
161
+ :class="containerClasses"
162
+ tabindex="0"
163
+ @blur="onBlur"
164
+ >
165
+ <div class="relative">
166
+ <div :class="itemClasses">
167
+ <Color
168
+ :value="modelValue"
169
+ :size="size as unknown as ColorInputSize"
170
+ @click="showDropdown = true"
171
+ />
172
+ </div>
173
+
174
+ <AntSkeleton
175
+ v-if="skeleton"
176
+ absolute
177
+ :grouped="hasRemoveButton ? Grouped.left : Grouped.none"
178
+ rounded
179
+ />
180
+ </div>
181
+
182
+ <AntButton
183
+ v-if="hasRemoveButton"
184
+ :icon-left="faMultiply"
185
+ :grouped="Grouped.right"
186
+ :no-focus="true"
187
+ :state="state as unknown as State"
188
+ :size="size"
189
+ :skeleton="skeleton"
190
+ :readonly="readonly"
191
+ :disabled="disabled"
192
+ @click="() => emit('update:modelValue', null)"
193
+ @blur="onBlur"
194
+ />
195
+ </div>
196
+
197
+ <template #content>
198
+ <ColorSelection
199
+ :value="modelValue"
200
+ :colors="props.options"
201
+ @select="(val) => {
202
+ $emit('update:modelValue', val);
203
+ nextTick(() => showDropdown = false);
204
+ }"
205
+ />
206
+ </template>
207
+ </AntDropdown>
208
+ </AntField>
209
+ </template>
@@ -0,0 +1,49 @@
1
+ <script lang="ts" setup>
2
+ import {
3
+ faCheck,
4
+ } from '@fortawesome/free-solid-svg-icons';
5
+ import AntIcon from '../../AntIcon.vue';
6
+ import {
7
+ ColorInputSize,
8
+ } from './AntColorInput.types';
9
+
10
+ defineEmits([
11
+ 'select',
12
+ ]);
13
+
14
+ withDefaults(defineProps<{
15
+ /**
16
+ * Value needs to be a variable name which exists in
17
+ * document computed style as CSS variable like --color-{value}
18
+ */
19
+ value: string | null;
20
+ selected?: boolean;
21
+ size?: ColorInputSize;
22
+ }>(), {
23
+ selected: false,
24
+ size: ColorInputSize.xl,
25
+ });
26
+ </script>
27
+
28
+ <template>
29
+ <div
30
+ class="rounded-sm cursor-pointer flex items-center justify-center"
31
+ :class="{
32
+ 'h-4 w-4': [ColorInputSize.xs, ColorInputSize.xs2].includes(size),
33
+ 'h-5 w-5': [ColorInputSize.lg, ColorInputSize.md, ColorInputSize.sm].includes(size),
34
+ 'h-8 w-8': ColorInputSize.xl === size,
35
+ 'h-10 w-10': ColorInputSize.xl2 === size,
36
+ }"
37
+ :style="{
38
+ backgroundColor: `var(--color-${value})`,
39
+ outlineColor: `var(--color-${value})`,
40
+ }"
41
+ @click="$emit('select', value)"
42
+ >
43
+ <AntIcon
44
+ v-if="selected"
45
+ :icon="faCheck"
46
+ class="text-white"
47
+ />
48
+ </div>
49
+ </template>
@@ -0,0 +1,43 @@
1
+ <script lang="ts" setup>
2
+ import {
3
+ Size,
4
+ } from '../../../enums';
5
+ import Color from './Color.vue';
6
+ import {
7
+ ColorInputSize,
8
+ } from './AntColorInput.types';
9
+
10
+ defineEmits([
11
+ 'select',
12
+ ]);
13
+
14
+ withDefaults(defineProps<{
15
+ // The selected color value
16
+ value: string | null;
17
+ colors: string[];
18
+ size?: Size;
19
+ }>(), {
20
+ size: Size.md,
21
+ });
22
+ </script>
23
+
24
+ <template>
25
+ <div
26
+ class="grid grid-cols-4 gap-1.5"
27
+ :class="{
28
+ 'p-1': size === Size.xs2,
29
+ 'p-1.5': size === Size.xs || size === Size.sm,
30
+ 'p-2': size === Size.md,
31
+ 'p-2.5': size === Size.lg,
32
+ }"
33
+ >
34
+ <Color
35
+ v-for="color in colors"
36
+ :key="color"
37
+ :value="color"
38
+ :selected="color === value"
39
+ :size="ColorInputSize.xl2"
40
+ @select="(val) => $emit('select', val)"
41
+ />
42
+ </div>
43
+ </template>
@@ -121,7 +121,7 @@ watch(isOpen, () => {
121
121
  focusedDropDownItem.value =
122
122
  typeof _modelValue.value === 'string' || typeof _modelValue.value === 'number' ? _modelValue.value :
123
123
  Array.isArray(_modelValue.value) ? _modelValue.value[0] :
124
- props.options[0].value;
124
+ (props.options[0].value || null);
125
125
  } else {
126
126
  focusedDropDownItem.value = null;
127
127
  }
@@ -138,6 +138,56 @@ onUnmounted(() => {
138
138
  reference.value?.removeEventListener('keydown', onKeyDownDropDown);
139
139
  });
140
140
 
141
+ /**
142
+ * Get the next focusable select option.
143
+ * It skips group labels and goes to beginning of the list if it reaches the end.
144
+ *
145
+ * @param currentOptionIndex
146
+ */
147
+ function getNextFocusableSelectOption(currentOptionIndex: number): number | null {
148
+ for (let i = currentOptionIndex + 1; i < props.options.length; i++) {
149
+ if (!props.options[i].isGroupLabel) {
150
+ return i;
151
+ }
152
+ }
153
+
154
+ // If no next option is found, return the first option, but make sure
155
+ // to skip group labels again.
156
+ for (let i = 0; i < props.options.length; i++) {
157
+ if (!props.options[i].isGroupLabel) {
158
+ return i;
159
+ }
160
+ }
161
+
162
+ // Seems that the option list is empty or all options are group labels.
163
+ return null;
164
+ }
165
+
166
+ /**
167
+ * Get the prev focusable select option.
168
+ * It skips group labels and goes to end of the list if it reaches the end.
169
+ *
170
+ * @param currentOptionIndex
171
+ */
172
+ function getPrevFocusableSelectOption(currentOptionIndex: number): number | null {
173
+ for (let i = currentOptionIndex - 1; i >= 0; i--) {
174
+ if (!props.options[i].isGroupLabel) {
175
+ return i;
176
+ }
177
+ }
178
+
179
+ // If no previous option is found, return the last option, but make sure
180
+ // to skip group labels again.
181
+ for (let i = props.options.length - 1; i >= 0; i--) {
182
+ if (!props.options[i].isGroupLabel) {
183
+ return i;
184
+ }
185
+ }
186
+
187
+ // Seems that the option list is empty or all options are group labels.
188
+ return null;
189
+ }
190
+
141
191
  function onKeyDownDropDown(e: KeyboardEvent) {
142
192
  if (e.key === 'Enter') {
143
193
  if (props.closeOnEnter) {
@@ -160,12 +210,10 @@ function onKeyDownDropDown(e: KeyboardEvent) {
160
210
  isOpen.value = true;
161
211
 
162
212
  const index = props.options.findIndex(option => option.value === focusedDropDownItem.value);
163
- const option = props.options[index + 1];
213
+ const nextOptionIndex = getNextFocusableSelectOption(index);
164
214
 
165
- if (index === -1) {
166
- focusedDropDownItem.value = props.options[0].value;
167
- } else if (option !== undefined) {
168
- focusedDropDownItem.value = option.value;
215
+ if (nextOptionIndex !== null) {
216
+ focusedDropDownItem.value = props.options[nextOptionIndex].value || null;
169
217
  }
170
218
  }
171
219
 
@@ -174,10 +222,10 @@ function onKeyDownDropDown(e: KeyboardEvent) {
174
222
  isOpen.value = true;
175
223
 
176
224
  const index = props.options.findIndex(option => option.value === focusedDropDownItem.value);
177
- const option = props.options[index - 1];
225
+ const prevOptionIndex = getPrevFocusableSelectOption(index);
178
226
 
179
- if (option !== undefined) {
180
- focusedDropDownItem.value = option.value;
227
+ if (prevOptionIndex !== null) {
228
+ focusedDropDownItem.value = props.options[prevOptionIndex].value || null;
181
229
  }
182
230
  }
183
231
 
@@ -187,6 +235,10 @@ function onKeyDownDropDown(e: KeyboardEvent) {
187
235
  }
188
236
 
189
237
  function getActiveDropDownItemClasses(option: SelectOption) {
238
+ if (option.isGroupLabel) {
239
+ return {};
240
+ }
241
+
190
242
  const variants: Record<InputState, string> = {
191
243
  [InputState.base]: '!bg-base-100',
192
244
  [InputState.success]: 'bg-success-200',
@@ -201,16 +253,21 @@ function getActiveDropDownItemClasses(option: SelectOption) {
201
253
  } : {};
202
254
  }
203
255
 
204
- function onClickDropDownItem(e: MouseEvent, value: string | number | null) {
256
+ function onClickDropDownItem(e: MouseEvent, option: SelectOption) {
205
257
  e.preventDefault();
258
+
259
+ if (option.isGroupLabel) {
260
+ return;
261
+ }
262
+
206
263
  reference.value?.focus();
207
264
 
208
265
  if (props.closeOnSelectItem) {
209
266
  isOpen.value = false;
210
267
  }
211
268
 
212
- emit('selectElement', value);
213
- _modelValue.value = value;
269
+ emit('selectElement', option.value);
270
+ _modelValue.value = option.value || null;
214
271
  }
215
272
 
216
273
  watch(_modelValue, (val) => {
@@ -236,9 +293,13 @@ watch(_modelValue, (val) => {
236
293
  <div
237
294
  v-for="(option, index) in options"
238
295
  :key="`option-${index}`"
239
- :class="{...dropDownItemClasses, ...getActiveDropDownItemClasses(option)}"
240
- @mousedown="(e) => onClickDropDownItem(e, option.value)"
241
- @mouseover="() => focusedDropDownItem = option.value"
296
+ :class="{
297
+ ...dropDownItemClasses,
298
+ ...getActiveDropDownItemClasses(option),
299
+ 'font-bold': option.isGroupLabel,
300
+ }"
301
+ @mousedown="(e) => onClickDropDownItem(e, option)"
302
+ @mouseover="() => focusedDropDownItem = !option.isGroupLabel && option.value !== undefined ? option.value : null"
242
303
  >
243
304
  <slot
244
305
  name="contentLeft"
@@ -9,6 +9,7 @@ export declare const manyOptions: Story;
9
9
  export declare const nullable: Story;
10
10
  export declare const skeleton: Story;
11
11
  export declare const disabled: Story;
12
+ export declare const grouped: Story;
12
13
  export declare const withPlaceholder: Story;
13
14
  export declare const ellipsisText: Story;
14
15
  export declare const summary: Story;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.withPlaceholder = exports.summary = exports.skeleton = exports.nullable = exports.manyOptions = exports.ellipsisText = exports.disabled = exports.default = exports.WithSlots = exports.Docs = void 0;
6
+ exports.withPlaceholder = exports.summary = exports.skeleton = exports.nullable = exports.manyOptions = exports.grouped = exports.ellipsisText = exports.disabled = exports.default = exports.WithSlots = exports.Docs = void 0;
7
7
  var _Size = require("../../../enums/Size.enum");
8
8
  var _AntSelect = _interopRequireDefault(require("../AntSelect.vue"));
9
9
  var _AntIcon = _interopRequireDefault(require("../../AntIcon.vue"));
@@ -230,6 +230,45 @@ const disabled = exports.disabled = {
230
230
  disabled: true
231
231
  }
232
232
  };
233
+ const grouped = exports.grouped = {
234
+ render: (args, ctx) => ({
235
+ // @ts-ignore
236
+ components: Docs.render(args, ctx).components,
237
+ // @ts-ignore
238
+ setup: Docs.render(args, ctx).setup,
239
+ template: `
240
+ <AntSelect v-bind="args" v-model="modelValue"/>
241
+ `
242
+ }),
243
+ args: {
244
+ label: "Label",
245
+ description: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod",
246
+ options: [{
247
+ label: "Group 1",
248
+ isGroupLabel: true
249
+ }, {
250
+ label: "Option 1.1",
251
+ value: 1,
252
+ imgUrl: "https://fastly.picsum.photos/id/972/200/200.jpg?hmac=TeAvfwW2T9YMpPW-sWWTeAiseERb12wSeR3mYzuG6TE"
253
+ }, {
254
+ label: "Option 2.1",
255
+ value: 2,
256
+ imgUrl: "https://fastly.picsum.photos/id/314/200/200.jpg?hmac=bCAc2iO5ovLPrvwDQV31aBPS13QTyv33ut2H2wY4QXU"
257
+ }, {
258
+ label: "Group 2",
259
+ isGroupLabel: true
260
+ }, {
261
+ label: "Option 2.1",
262
+ value: 3,
263
+ imgUrl: "https://fastly.picsum.photos/id/972/200/200.jpg?hmac=TeAvfwW2T9YMpPW-sWWTeAiseERb12wSeR3mYzuG6TE"
264
+ }, {
265
+ label: "Option 2.2",
266
+ value: 4,
267
+ imgUrl: "https://fastly.picsum.photos/id/165/200/200.jpg?hmac=tQGrY9pm5ze9soSsZ5CNBt87zqnHfFwdPv_khau12Sw"
268
+ }],
269
+ modelValue: 1
270
+ }
271
+ };
233
272
  const withPlaceholder = exports.withPlaceholder = {
234
273
  render: Docs.render,
235
274
  args: {
@@ -245,6 +245,52 @@ export const disabled = {
245
245
  disabled: true
246
246
  }
247
247
  };
248
+ export const grouped = {
249
+ render: (args, ctx) => ({
250
+ // @ts-ignore
251
+ components: Docs.render(args, ctx).components,
252
+ // @ts-ignore
253
+ setup: Docs.render(args, ctx).setup,
254
+ template: `
255
+ <AntSelect v-bind="args" v-model="modelValue"/>
256
+ `
257
+ }),
258
+ args: {
259
+ label: "Label",
260
+ description: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod",
261
+ options: [
262
+ {
263
+ label: "Group 1",
264
+ isGroupLabel: true
265
+ },
266
+ {
267
+ label: "Option 1.1",
268
+ value: 1,
269
+ imgUrl: "https://fastly.picsum.photos/id/972/200/200.jpg?hmac=TeAvfwW2T9YMpPW-sWWTeAiseERb12wSeR3mYzuG6TE"
270
+ },
271
+ {
272
+ label: "Option 2.1",
273
+ value: 2,
274
+ imgUrl: "https://fastly.picsum.photos/id/314/200/200.jpg?hmac=bCAc2iO5ovLPrvwDQV31aBPS13QTyv33ut2H2wY4QXU"
275
+ },
276
+ {
277
+ label: "Group 2",
278
+ isGroupLabel: true
279
+ },
280
+ {
281
+ label: "Option 2.1",
282
+ value: 3,
283
+ imgUrl: "https://fastly.picsum.photos/id/972/200/200.jpg?hmac=TeAvfwW2T9YMpPW-sWWTeAiseERb12wSeR3mYzuG6TE"
284
+ },
285
+ {
286
+ label: "Option 2.2",
287
+ value: 4,
288
+ imgUrl: "https://fastly.picsum.photos/id/165/200/200.jpg?hmac=tQGrY9pm5ze9soSsZ5CNBt87zqnHfFwdPv_khau12Sw"
289
+ }
290
+ ],
291
+ modelValue: 1
292
+ }
293
+ };
248
294
  export const withPlaceholder = {
249
295
  render: Docs.render,
250
296
  args: {
@@ -1,4 +1,5 @@
1
1
  export type SelectOption = {
2
2
  label: string;
3
- value: string | number;
3
+ value?: string | number;
4
+ isGroupLabel?: boolean;
4
5
  } & Record<string, unknown>;
@@ -5,3 +5,4 @@ export * from './AntSelect.types';
5
5
  export * from './AntSwitcher.types';
6
6
  export * from './AntTagInput.types';
7
7
  export * from './AntTextInput.types';
8
+ export * from '../AntColorInput/AntColorInput.types';
@@ -79,4 +79,15 @@ Object.keys(_AntTextInput).forEach(function (key) {
79
79
  return _AntTextInput[key];
80
80
  }
81
81
  });
82
+ });
83
+ var _AntColorInput = require("../AntColorInput/AntColorInput.types");
84
+ Object.keys(_AntColorInput).forEach(function (key) {
85
+ if (key === "default" || key === "__esModule") return;
86
+ if (key in exports && exports[key] === _AntColorInput[key]) return;
87
+ Object.defineProperty(exports, key, {
88
+ enumerable: true,
89
+ get: function () {
90
+ return _AntColorInput[key];
91
+ }
92
+ });
82
93
  });
@@ -5,3 +5,4 @@ export * from "./AntSelect.types.mjs";
5
5
  export * from "./AntSwitcher.types.mjs";
6
6
  export * from "./AntTagInput.types.mjs";
7
7
  export * from "./AntTextInput.types.mjs";
8
+ export * from "../AntColorInput/AntColorInput.types.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antify/ui",
3
- "version": "2.4.3",
3
+ "version": "2.4.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {